GPU_Gems-物理模型的水模拟

创建一个多网格的平面

void GraphicsWindowBase::RenderPlane() {
    constexpr int width = 150;
    constexpr int depth = 150;
    constexpr int vertNum = width * depth;
    float length = 60.f;
    if (quadVAO == 0)
    {
        float planeVert[vertNum * 5];
        float offsetX = length / (width - 1.f);
        float offsetZ = length / (depth - 1.f);

        float offsetU = 1 / (width - 1.f);
        float offsetV = 1 / (depth - 1.f);

        for (int z = 0; z < depth; z++) {
            for (int x = 0; x < width; x++) {
                int vIdx = (x + z * width) * 5;
                planeVert[vIdx] = x * offsetX - length / 2;
                planeVert[vIdx + 1] = 0.f;
                planeVert[vIdx + 2] = -z * offsetZ;
                planeVert[vIdx + 3] = x * offsetU;
                planeVert[vIdx + 4] = z * offsetV;
            }
        }

        int planeIndices[(width - 1) * (depth - 1) * 2 * 3];
        for (int z = 0; z < depth - 1; z++) {
            for(int x = 0; x < width - 1; x++) {
                int leftBottomIdx = x + z * width;
                int leftTopIdx = x + z * width + width;
                int rightTopIdx = leftTopIdx + 1;
                int rightBottomIdx = leftBottomIdx + 1;
                int triangleIdx = (x + z * (width - 1)) * 2 * 3;
                planeIndices[triangleIdx] = leftTopIdx;
                planeIndices[triangleIdx + 1] = leftBottomIdx;
                planeIndices[triangleIdx + 2] = rightTopIdx;
                planeIndices[triangleIdx + 3] = leftBottomIdx;
                planeIndices[triangleIdx + 4] = rightBottomIdx;
                planeIndices[triangleIdx + 5] = rightTopIdx;
            }
        }

        glGenVertexArrays(1, &quadVAO);
        glGenBuffers(1, &quadVBO);
        glGenBuffers(1, &quadIBO);
        glBindVertexArray(quadVAO);
        glBindBuffer(GL_ARRAY_BUFFER, quadVBO);
        glBufferData(GL_ARRAY_BUFFER, sizeof(planeVert), &planeVert, GL_STATIC_DRAW);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quadIBO);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(planeIndices), planeIndices, GL_STATIC_DRAW);
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
        glEnableVertexAttribArray(1);
        glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
    }
    glBindVertexArray(quadVAO);
    glDrawElements(GL_TRIANGLES, (width - 1) * (depth - 1) * 2 * 3, GL_UNSIGNED_INT, 0);
    glBindVertexArray(0);
}

直接输出看效果
vs

void main()
{
	gl_Position = projection*view*model*vec4(aPos, 1.0);
}

fs

void main()
{
    FragColor = vec3(0.196,0.346,0.654);
}

在这里插入图片描述

正弦波叠加模拟

D:波方向
L:波长/周期
S:波速
A:振幅

vs

layout (location = 0) in vec3 aPos;
//...
vec3 pos = aPos;
float nx = 0;
float nz = 0;
float ny = 0;
vec3 n;
for(int i = 0; i < waveNum; i++){
	float w =2 * PI / L[i];
	float phi = S[i] * w;
	
	vec2 D = getDirect(i, vec2(aPos.x, aPos.z));
	pos.y += 2 * A[i] * pow((sin(w * dot(D, vec2(aPos.x, aPos.z)) + iTime * phi)) * 0.5 + 0.5, k);
	
	nx += k * w * D.x * A[i] * pow((sin(w * dot(D, vec2(aPos.x, aPos.z)) + iTime * phi)) * 0.5 + 0.5, k-1) * cos(dot(D, vec2(aPos.x, aPos.z)) * w + iTime * phi);
	nz += k * w * D.y * A[i] * pow((sin(w * dot(D, vec2(aPos.x, aPos.z)) + iTime * phi)) * 0.5 + 0.5, k-1) * cos(dot(D, vec2(aPos.x, aPos.z)) * w + iTime * phi);
}
n = vec3(-nx, 1, -nz);
//...
gl_Position = projection*view*model*vec4(pos, 1.0);
vs_out.Position =vec3(model * vec4(pos, 1.0));
n = mat3(transpose(inverse(model))) * n;
vs_out.Normal = normalize(n);

fs

out vec4 FragColor;
//...
vec3 lightDir = vec3(0,1,0);
float diff = clamp(dot(fs_in.Normal, lightDir), 0, 1);
vec3 waterColor = vec3(0.196,0.346,0.654);
FragColor = vec4(waterColor * diff, 1);

在这里插入图片描述

Gerstner波叠加模拟

Q:波陡峭的参数,控制波峰尖锐情况
vs

layout (location = 0) in vec3 aPos;
//...
vec3 pos = aPos;
float nx = 0;
float nz = 0;
float ny = 0;
vec3 n;
for(int i = 0; i < waveNum; i++){
	float w = 2 * PI / L[i];
	float phi = S[i] * w;
	vec2 D = getDirect(i, vec2(aPos.x, aPos.z));
	float Q = clamp(Q[i] / (w * A[i] * waveNum), 0, 1);

	float arg = w * dot(D, vec2(aPos.x, aPos.z)) + iTime * phi;

	pos.x += Q * A[i] * D.x * cos(arg);
	pos.z += Q * A[i] * D.y * cos(arg);
	pos.y += A[i] * sin(arg);

	nx += D.x * w * A[i] * cos(arg);
	nz += D.y * w * A[i] * cos(arg);
	ny += Q * w * A[i] * sin(arg);
}
n = vec3(-nx, 1 - ny, -nz);
//...
gl_Position = projection*view*model*vec4(pos, 1.0);
vs_out.Position =vec3(model * vec4(pos, 1.0));
n = mat3(transpose(inverse(model))) * n;
vs_out.Normal = normalize(n);

fs

out vec4 FragColor;
//...
vec3 lightDir = vec3(0,1,0);
float diff = clamp(dot(fs_in.Normal, lightDir), 0, 1);
vec3 waterColor = vec3(0.196,0.346,0.654);
FragColor = vec4(waterColor * diff, 1);

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值