在着色器中创建波浪表面
Creating a waving surface in a shader
我在顶点着色器中创建了一个波浪形表面。
顶点着色器:
#version 300 es
precision lowp float;
uniform mat4 u_mvpMatrix;
uniform sampler2D s_texture;
in vec4 a_position;
out vec2 v_textureCoordinates;
const float pi = 3.14285714286;
void main() {
vec4 vertexCoord = a_position;
float distance = length(vertexCoord);
vertexCoord.y += sin(3.0 * pi * distance * 0.3 + u_lastTime) * 0.5;
v_textureCoordinates = a_textureCoordinates;
gl_Position = u_mvpMatrix * vertexCoord;
}
片段着色器:
#version 300 es
precision lowp float;
in vec2 v_textureCoordinates;
out vec4 outColor;
uniform sampler2D s_texture;
void main() {
outColor = texture(s_texture, v_textureCoordinates);
}
结果:
但是在表面上只有一个来自中心的径向波。是否可以使用着色器创建具有多个波浪的表面?也就是让表面看起来像冒泡的水。
解决方案
谢谢@vtastek!根据他的回答,我更改了vertex shader:
#version 300 es
precision lowp float;
uniform mat4 u_mvpMatrix;
uniform sampler2D s_texture;
in vec4 a_position;
out vec2 v_textureCoordinates;
const float pi = 3.14285714286;
void main() {
vec4 vertexCoord = a_position;
vec2 origin1 = vertexCoord.xz + vec2(300.0, 300.0);
vec2 origin2 = vertexCoord.xz + vec2(-300.0, 300.0);
vec2 origin3 = vertexCoord.xz + vec2(300.0, -300.0);
vec2 origin4 = vertexCoord.xz + vec2(-300.0, -300.0);
float distance1 = length(origin1);
float distance2 = length(origin2);
float distance3 = length(origin3);
float distance4 = length(origin4);
float wave = sin(3.3 * pi * distance1 * 0.13 + u_lastTime) * 0.125 +
sin(3.2 * pi * distance2 * 0.12 + u_lastTime) * 0.125 +
sin(3.1 * pi * distance3 * 0.24 + u_lastTime) * 0.125 +
sin(3.5 * pi * distance4 * 0.32 + u_lastTime) * 0.125;
vertexCoord.y += wave;
v_textureCoordinates = a_textureCoordinates;
gl_Position = u_mvpMatrix * vertexCoord;
}
结果:
在大多数示例中,它是多个单向波。不过我喜欢你的圆波想法。我只会偏移和复制。
vec2 origin1 = vertexCoord.xz + vec2(300.0, 300.0);
vec2 origin2 = vertexCoord.xz + vec2(-300.0, 300.0);
vec2 origin3 = vertexCoord.xz + vec2(300.0, -300.0);
vec2 origin4 = vertexCoord.xz + vec2(-300.0, -300.0); // random or 4 corners
float distance1 = length(origin1);
float distance2 = length(origin2);
float distance3 = length(origin3);
float distance4 = length(origin4);
float wave = sin(3.3 * PI * distance1 * 0.13 + time) * 0.125 +
sin(3.2 * PI * distance2 * 0.12 + time) * 0.125 +
sin(3.1 * PI * distance3 * 0.24 + time) * 0.125 +
sin(3.5 * PI * distance4 * 0.32 + time) * 0.125;
vertexCoord.y += wave;
或者,您可以添加具有不同方向的单向波(与随机 vec2 相乘)。您可以查找 Gerstner 波浪以获得更逼真的波浪。核心思想是将正弦波加在一起。
我在顶点着色器中创建了一个波浪形表面。
顶点着色器:
#version 300 es
precision lowp float;
uniform mat4 u_mvpMatrix;
uniform sampler2D s_texture;
in vec4 a_position;
out vec2 v_textureCoordinates;
const float pi = 3.14285714286;
void main() {
vec4 vertexCoord = a_position;
float distance = length(vertexCoord);
vertexCoord.y += sin(3.0 * pi * distance * 0.3 + u_lastTime) * 0.5;
v_textureCoordinates = a_textureCoordinates;
gl_Position = u_mvpMatrix * vertexCoord;
}
片段着色器:
#version 300 es
precision lowp float;
in vec2 v_textureCoordinates;
out vec4 outColor;
uniform sampler2D s_texture;
void main() {
outColor = texture(s_texture, v_textureCoordinates);
}
结果:
但是在表面上只有一个来自中心的径向波。是否可以使用着色器创建具有多个波浪的表面?也就是让表面看起来像冒泡的水。
解决方案
谢谢@vtastek!根据他的回答,我更改了vertex shader:
#version 300 es
precision lowp float;
uniform mat4 u_mvpMatrix;
uniform sampler2D s_texture;
in vec4 a_position;
out vec2 v_textureCoordinates;
const float pi = 3.14285714286;
void main() {
vec4 vertexCoord = a_position;
vec2 origin1 = vertexCoord.xz + vec2(300.0, 300.0);
vec2 origin2 = vertexCoord.xz + vec2(-300.0, 300.0);
vec2 origin3 = vertexCoord.xz + vec2(300.0, -300.0);
vec2 origin4 = vertexCoord.xz + vec2(-300.0, -300.0);
float distance1 = length(origin1);
float distance2 = length(origin2);
float distance3 = length(origin3);
float distance4 = length(origin4);
float wave = sin(3.3 * pi * distance1 * 0.13 + u_lastTime) * 0.125 +
sin(3.2 * pi * distance2 * 0.12 + u_lastTime) * 0.125 +
sin(3.1 * pi * distance3 * 0.24 + u_lastTime) * 0.125 +
sin(3.5 * pi * distance4 * 0.32 + u_lastTime) * 0.125;
vertexCoord.y += wave;
v_textureCoordinates = a_textureCoordinates;
gl_Position = u_mvpMatrix * vertexCoord;
}
结果:
在大多数示例中,它是多个单向波。不过我喜欢你的圆波想法。我只会偏移和复制。
vec2 origin1 = vertexCoord.xz + vec2(300.0, 300.0);
vec2 origin2 = vertexCoord.xz + vec2(-300.0, 300.0);
vec2 origin3 = vertexCoord.xz + vec2(300.0, -300.0);
vec2 origin4 = vertexCoord.xz + vec2(-300.0, -300.0); // random or 4 corners
float distance1 = length(origin1);
float distance2 = length(origin2);
float distance3 = length(origin3);
float distance4 = length(origin4);
float wave = sin(3.3 * PI * distance1 * 0.13 + time) * 0.125 +
sin(3.2 * PI * distance2 * 0.12 + time) * 0.125 +
sin(3.1 * PI * distance3 * 0.24 + time) * 0.125 +
sin(3.5 * PI * distance4 * 0.32 + time) * 0.125;
vertexCoord.y += wave;
或者,您可以添加具有不同方向的单向波(与随机 vec2 相乘)。您可以查找 Gerstner 波浪以获得更逼真的波浪。核心思想是将正弦波加在一起。