Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //fragment
- #ifdef GL_ES
- #define LOWP lowp
- precision mediump float;
- #else
- #define LOWP
- #endif
- uniform sampler2D u_texture;
- uniform sampler2D u_texture1;
- uniform float invFar; // 1/far
- uniform vec3 camPos;
- uniform float spot;
- uniform vec3 lightDir;
- varying vec2 v_texCoords;
- varying vec3 v_normal;
- varying vec4 shadowCoord;
- varying vec3 v_lightDir;
- varying vec3 v_eye;
- varying vec3 v_lightDis;
- const float shininessFactor = 15.0;
- const vec3 specularColor = vec3(0.575, 0.675, 0.445);
- const vec3 diffuseColor = vec3(0.975, 0.95, 0.925);
- const vec3 ambient = vec3(0.3, 0.3, 0.275);
- const vec4 bitShifts = vec4(1.0 / 256.0, 1.0, 1.0 / 256.0, 1.0);
- vec2 unPack(vec4 zz)
- {
- zz *= bitShifts;
- return vec2((zz.x + zz.y),(zz.z + zz.w));
- }
- const float MIN_VARIANCE = 0.0035;
- const float LIGHT_BLEEDING_DROPPER = 0.75;
- float VSM( vec4 coord, float distance)
- {
- vec2 shadowCoordPostW = (coord.xy / coord.w) * 0.5 + 0.5;
- //retrive the two moments previously stored (depth and depth*depth)
- vec4 momentsPack = texture2D(u_texture1, shadowCoordPostW);
- float depth = distance * invFar;
- vec2 moments = unPack(momentsPack);
- // The fragment is either in shadow or penumbra. We now use chebyshev's upperBound to check
- // How likely this pixel is to be lit (p_max)
- float variance = moments.y - (moments.x * moments.x);
- variance = max(variance, MIN_VARIANCE);
- float d = depth - moments.x;
- float p_max = variance / (variance + d*d);
- float shade = clamp( ((p_max - LIGHT_BLEEDING_DROPPER) / (1.0 - LIGHT_BLEEDING_DROPPER)), 0.0, 1.0);
- shade*=shade;
- // if Surface is fully lit. as the current fragment is before the light occluder return 1 other
- return (depth <= moments.x) ? 1.0: shade;
- }
- void main()
- {
- vec3 tex = texture2D(u_texture, v_texCoords).rgb;
- vec3 surfaceNormal = ( v_normal );
- //intensity
- float dist = length(v_lightDis);
- vec3 lightDirection = v_lightDis / dist;
- float diffuse = dot(surfaceNormal, lightDirection);
- float intensity = clamp( 1.0 - (dist * invFar),0.0, 1.0 );
- intensity = (diffuse >= 0.0) ? intensity : 0.0;
- float lightConeAngle = dot(lightDir, -lightDirection );
- lightConeAngle = clamp( ((lightConeAngle - spot) / (1.0 - spot)), 0.0, 1.0);
- intensity *=lightConeAngle;
- //specular
- vec3 fromEye = normalize(v_eye);
- vec3 halfAngle = normalize(lightDirection + fromEye);
- float specular = pow(clamp(dot(halfAngle, surfaceNormal),0.0,1.0), shininessFactor);
- //shadow
- float shadow = VSM(shadowCoord, dist);
- intensity = intensity * shadow;
- //combine lights+shadow
- vec3 light = intensity * (specularColor * specular * dot( tex, tex) + diffuse * diffuseColor * tex );
- gl_FragColor = vec4( light + (ambient * tex) , 1.0);
- }
- //Vertex
- attribute vec4 a_position;
- attribute vec2 a_texCoord0;
- attribute vec3 a_normal;
- uniform vec3 lightPos;
- uniform vec3 camPos;
- uniform mat4 u_projectionViewMatrix;
- uniform mat4 shadowProjMatrix;
- varying vec2 v_texCoords;
- varying vec3 v_normal;
- varying vec3 v_lightDis;
- varying vec3 v_eye;
- varying vec4 shadowCoord;
- void main()
- {
- shadowCoord = shadowProjMatrix * a_position;
- v_texCoords = a_texCoord0;
- v_normal = a_normal;
- vec3 pos = a_position.xyz;
- v_lightDis = lightPos - pos;
- v_eye = camPos - pos;
- gl_Position = u_projectionViewMatrix * a_position;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement