@shome
This is the GLSL code for this demo, which uses vertex shaders and fragment shaders.
vert
// 输入变量 attribute vec4 rawVertex; attribute vec3 rawNormal; attribute vec3 rawTangent; attribute vec2 rawTexture; // 输出变量 varying vec4 currentVertex; varying vec3 currentNormal; varying vec3 currentTangent; varying vec2 currentTexture; varying float currentDepth; // 绘制参数 uniform mat4 paintMatrix; uniform sampler2D waveTexture; uniform float timeOffset; void main() { currentDepth = 1.0 - ( rawVertex.z / -0.6 ); vec4 wave = texture2D( waveTexture, rawTexture + vec2( timeOffset, -timeOffset ) * 0.0001 ); vec4 newVertex = rawVertex; const float amplitude = 0.05; const float frequency = 6.0; newVertex.x += ( wave.r * 0.05 ) * currentDepth; newVertex.y += ( wave.b * 0.05 ) * currentDepth; newVertex.z += amplitude * sin( frequency * ( newVertex.x - newVertex.y ) + timeOffset * 0.001 ) * currentDepth; currentVertex = paintMatrix * newVertex; currentNormal = normalize( mat3( paintMatrix[ 0 ].xyz, paintMatrix[ 1 ].xyz, paintMatrix[ 2 ].xyz ) * rawNormal ); currentTangent = normalize( mat3( paintMatrix[ 0 ].xyz, paintMatrix[ 1 ].xyz, paintMatrix[ 2 ].xyz ) * rawTangent ); currentTexture = rawTexture; gl_Position = currentVertex; gl_Position.z /= 5.0; // 防止被视景体裁剪 }frag
// 输入参数 varying vec4 currentVertex; varying vec3 currentNormal; varying vec3 currentTangent; varying vec2 currentTexture; varying float currentDepth; // 绘制参数 uniform sampler2D normalTexture; uniform sampler2D foamTexture; uniform sampler2D specularTexture; uniform mat4 paintMatrix; vec3 processColor1(vec3 color, vec3 normal) { const vec3 ambientColor = vec3( 1.0, 1.0, 1.0 ); // 环境光参数 const vec3 lightPos = vec3( 0.0, 0.4, 1.4 ); // 光源位置 const vec3 viewPos = vec3( 0.0, 0.0, 1.0 ); // 观察位置 const vec3 lightColor = vec3( 0.5, 0.5, 0.5 ); // 光源颜色 const float shininess = 48.0; // 镜面反射强度 float specularStrength = texture2D( specularTexture, currentTexture ).x; // 镜面反射颜色系数 // 计算方向向量 vec3 lightDir = normalize( lightPos - viewPos ); vec3 viewDir = normalize( -viewPos ); // 环境光照 vec3 ambient = ambientColor * color; // 漫反射光照 float diff = max( dot( normal, lightDir ), 0.0 ); vec3 diffuse = diff * lightColor * color; // 镜面反射光照 vec3 reflectDir = reflect( -lightDir, normal ); float spec = pow( max( dot( viewDir, reflectDir ), 0.0 ), shininess ); vec3 specular = specularStrength * spec * lightColor; vec3 result = ambient + diffuse + ( ( spec <= 1.0 ) ? ( specular ) : ( vec3( 0.0, 0.0, 0.0 ) ) ); // 合并光照效果 return result; } void main() { const vec3 defaultColor = vec3( 0.15, 0.35, 0.50 ); if ( currentDepth < 0.999 ) { gl_FragColor = vec4( defaultColor * currentDepth * 1.5, 1.0 ); return; } vec4 foamColor = texture2D( foamTexture, currentTexture ); vec3 currentColor = defaultColor + foamColor.xyz / 3.5; vec3 normalFromTexture = texture2D( normalTexture, currentTexture ).xyz * 2.0 - 1.0; vec3 currentBitangent = cross( currentTangent, currentNormal ); mat3 TBN = mat3( currentTangent, currentBitangent, currentNormal ); vec3 normal = normalize( TBN * normalFromTexture ); gl_FragColor = vec4( processColor1( currentColor, normal ) * currentDepth, 1.0 ); }