创建一个多网格的平面
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);