@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 );
}