To see shader use Spector.js
browser extension.
Blend caustic and diffuse by worldNormal.y
.
gl_FragColor.rgb = mix(gl_FragColor.rgb, caustics, smoothstep(0.0, max(0.02, uThreshold), worldNormal.y));
Fragment shader:
float sampleCaustics(float scale, vec2 offset, float speed, vec2 currentVelocity) {
mat3 m = mat3(-2, -1, 2, 3, -2, 1, 1, 2, 2);
vec2 causticsLoc = vec2((vWorldPosition.x+offset.x+uTime*currentVelocity.x)*scale, (vWorldPosition.z+offset.y+uTime*currentVelocity.y)*scale);
vec3 t = vec3(causticsLoc, uTime*speed+uSeed);
vec3 a = vec3(t*m*0.5);
vec3 b = vec3(a*m*0.4);
vec3 c = vec3(b*m*0.3);
return pow(min(min(length(.5-fract(a)), length(.5-fract(b))), length(.5-fract(c))), uCausticsSpreadInverse);
}
vec3 getCausticsColor(float scale, float split, float speed, vec2 currentVelocity) {
float r = sampleCaustics(scale, vec2(split), speed, currentVelocity);
float g = sampleCaustics(scale, vec2(split, -split), speed, currentVelocity);
float b = sampleCaustics(scale, -vec2(split), speed, currentVelocity);
vec3 color = vec3(1.0, 0., 0.)*r+vec3(.0, 1., 0.)*g+vec3(.0, 0., 1.)*b;
return max(vec3(0.), color);
}
vec3 causticsColor1 = getCausticsColor(uCausticsScale, uChromaticAbberration, uCausticsSpeed, uCausticsVelocity);
vec3 causticsColor2 = getCausticsColor(uCausticsScale*uCausticsDetailScale, uChromaticAbberration, uCausticsSpeed*uCausticsDetailSpeed, uCausticsVelocity);
float causticsBase1 = sampleCaustics(uCausticsScale, vec2(0.0), uCausticsSpeed, uCausticsVelocity);
float causticsBase2 = sampleCaustics(uCausticsScale*uCausticsDetailScale, vec2(0.0), uCausticsSpeed*uCausticsDetailSpeed, uCausticsVelocity);
vec3 causticsColor = (min(causticsColor1, causticsColor2)+vec3(min(causticsBase1, causticsBase2)))*uCausticsStrength;
vec3 worldNormal = normalize(vWorldNormal);
vec3 caustics = blendAdd(gl_FragColor.rgb, causticsColor, uCausticsBlendAlpha*vCausticsStrength);
gl_FragColor.rgb = mix(gl_FragColor.rgb, caustics, smoothstep(0.0, max(0.02, uThreshold), worldNormal.y));