precision mediump float; uniform vec2 u_resolution; uniform float u_time; float uIorR = 1.0; float uIorY = 1.0; float uIorG = 1.0; float uIorC = 1.0; float uIorB = 1.0; float uIorP = 1.0; float uSaturation = 0.0; float uChromaticAberration = 1.0; float uRefractPower = 0.2; float uFresnelPower = 8.; float uShininess = 15.; float uDiffuseness = 0.2; vec3 uLight = vec3(-1., 0., 1.); uniform sampler2D uTexture; vec3 worldNormal = vec3(0., 0., 1.); vec3 eyeVector = vec3(0., 0., 0.); vec3 sat(vec3 rgb, float adjustment) { const vec3 W = vec3(0.2125, 0.7154, 0.0721); vec3 intensity = vec3(dot(rgb, W)); return mix(intensity, rgb, adjustment); } float fresnel(vec3 eyeVector, vec3 worldNormal, float power) { float fresnelFactor = abs(dot(eyeVector, worldNormal)); float inversefresnelFactor = 1.0 - fresnelFactor; return pow(inversefresnelFactor, power); } float specular(vec3 light, float shininess, float diffuseness) { vec3 normal = worldNormal; vec3 lightVector = normalize(-light); vec3 halfVector = normalize(eyeVector + lightVector); float NdotL = dot(normal, lightVector); float NdotH = dot(normal, halfVector); float kDiffuse = max(0.0, NdotL); float NdotH2 = NdotH * NdotH; float kSpecular = pow(NdotH2, shininess); return kSpecular + kDiffuse * diffuseness; } const int LOOP = 16; void main() { vec2 uv = gl_FragCoord.xy / u_resolution.xy; vec3 normal = worldNormal; vec3 color = vec3(0.0); for ( int i = 0; i < LOOP; i ++ ) { float slide = float(i) / float(LOOP) * 0.1; vec3 refractVecR = refract(eyeVector, normal,(1.0/uIorR)); vec3 refractVecY = refract(eyeVector, normal, (1.0/uIorY)); vec3 refractVecG = refract(eyeVector, normal, (1.0/uIorG)); vec3 refractVecC = refract(eyeVector, normal, (1.0/uIorC)); vec3 refractVecB = refract(eyeVector, normal, (1.0/uIorB)); vec3 refractVecP = refract(eyeVector, normal, (1.0/uIorP)); float r = texture2D(uTexture, uv + refractVecR.xy * (uRefractPower + slide * 1.0) * uChromaticAberration).x * 0.5; float y = (texture2D(uTexture, uv + refractVecY.xy * (uRefractPower + slide * 1.0) * uChromaticAberration).x * 2.0 + texture2D(uTexture, uv + refractVecY.xy * (uRefractPower + slide * 1.0) * uChromaticAberration).y * 2.0 - texture2D(uTexture, uv + refractVecY.xy * (uRefractPower + slide * 1.0) * uChromaticAberration).z) / 6.0; float g = texture2D(uTexture, uv + refractVecG.xy * (uRefractPower + slide * 2.0) * uChromaticAberration).y * 0.5; float c = (texture2D(uTexture, uv + refractVecC.xy * (uRefractPower + slide * 2.5) * uChromaticAberration).y * 2.0 + texture2D(uTexture, uv + refractVecC.xy * (uRefractPower + slide * 2.5) * uChromaticAberration).z * 2.0 - texture2D(uTexture, uv + refractVecC.xy * (uRefractPower + slide * 2.5) * uChromaticAberration).x) / 6.0; float b = texture2D(uTexture, uv + refractVecB.xy * (uRefractPower + slide * 3.0) * uChromaticAberration).z * 0.5; float p = (texture2D(uTexture, uv + refractVecP.xy * (uRefractPower + slide * 1.0) * uChromaticAberration).z * 2.0 + texture2D(uTexture, uv + refractVecP.xy * (uRefractPower + slide * 1.0) * uChromaticAberration).x * 2.0 - texture2D(uTexture, uv + refractVecP.xy * (uRefractPower + slide * 1.0) * uChromaticAberration).y) / 6.0; float R = r + (2.0*p + 2.0*y - c)/3.0; float G = g + (2.0*y + 2.0*c - p)/3.0; float B = b + (2.0*c + 2.0*p - y)/3.0; color.r += R; color.g += G; color.b += B; color = sat(color, uSaturation); } // Divide by the number of layers to normalize colors (rgb values can be worth up to the value of LOOP) color /= float( LOOP ); // Specular float specularLight = specular(uLight, uShininess, uDiffuseness); color += specularLight; // Fresnel float f = fresnel(eyeVector, normal, uFresnelPower); color.rgb += f * vec3(1.0); gl_FragColor = vec4(color, 1.0); }