1 | #version 100 |
---|
2 | |
---|
3 | precision mediump int; |
---|
4 | precision mediump float; |
---|
5 | |
---|
6 | float shadowPCF(sampler2D shadowMap, vec4 shadowMapPos, vec2 offset) |
---|
7 | { |
---|
8 | shadowMapPos = shadowMapPos / shadowMapPos.w; |
---|
9 | vec2 uv = shadowMapPos.xy; |
---|
10 | vec3 o = vec3(offset, -offset.x) * 0.3; |
---|
11 | |
---|
12 | // Note: We using 2x2 PCF. Good enough and is a lot faster. |
---|
13 | float c = (shadowMapPos.z <= texture2D(shadowMap, uv.xy - o.xy).r) ? 1.0 : 0.0; // top left |
---|
14 | c += (shadowMapPos.z <= texture2D(shadowMap, uv.xy + o.xy).r) ? 1.0 : 0.0; // bottom right |
---|
15 | c += (shadowMapPos.z <= texture2D(shadowMap, uv.xy + o.zy).r) ? 1.0 : 0.0; // bottom left |
---|
16 | c += (shadowMapPos.z <= texture2D(shadowMap, uv.xy - o.zy).r) ? 1.0 : 0.0; // top right |
---|
17 | |
---|
18 | return c / 4.0; |
---|
19 | } |
---|
20 | |
---|
21 | uniform vec4 invShadowMapSize0; |
---|
22 | uniform vec4 invShadowMapSize1; |
---|
23 | uniform vec4 invShadowMapSize2; |
---|
24 | uniform vec4 pssmSplitPoints; |
---|
25 | uniform sampler2D diffuse; |
---|
26 | uniform sampler2D specular; |
---|
27 | uniform sampler2D normalMap; |
---|
28 | uniform sampler2D shadowMap0; |
---|
29 | uniform sampler2D shadowMap1; |
---|
30 | uniform sampler2D shadowMap2; |
---|
31 | uniform vec4 lightDiffuse; |
---|
32 | uniform vec4 lightSpecular; |
---|
33 | uniform vec4 ambient; |
---|
34 | |
---|
35 | varying vec4 oUv0; |
---|
36 | varying vec3 oLightDir; |
---|
37 | varying vec3 oHalfAngle; |
---|
38 | varying vec4 oLightPosition0; |
---|
39 | varying vec4 oLightPosition1; |
---|
40 | varying vec4 oLightPosition2; |
---|
41 | varying vec3 oNormal; |
---|
42 | |
---|
43 | // to put it simply, this does 100% per pixel diffuse lighting |
---|
44 | void main() |
---|
45 | { |
---|
46 | // calculate shadow |
---|
47 | float shadowing = 1.0; |
---|
48 | vec4 splitColour; |
---|
49 | if (oUv0.z <= pssmSplitPoints.y) |
---|
50 | { |
---|
51 | splitColour = vec4(0.1, 0.0, 0.0, 1.0); |
---|
52 | shadowing = shadowPCF(shadowMap0, oLightPosition0, invShadowMapSize0.xy); |
---|
53 | } |
---|
54 | else if (oUv0.z <= pssmSplitPoints.z) |
---|
55 | { |
---|
56 | splitColour = vec4(0.0, 0.1, 0.0, 1.0); |
---|
57 | shadowing = shadowPCF(shadowMap1, oLightPosition1, invShadowMapSize1.xy); |
---|
58 | } |
---|
59 | else |
---|
60 | { |
---|
61 | splitColour = vec4(0.1, 0.1, 0.0, 1.0); |
---|
62 | shadowing = shadowPCF(shadowMap2, oLightPosition2, invShadowMapSize2.xy); |
---|
63 | } |
---|
64 | |
---|
65 | // retrieve normalised light vector, expand from range-compressed |
---|
66 | vec3 lightVec = normalize(oLightDir); |
---|
67 | |
---|
68 | // retrieve half angle and normalise through cube map |
---|
69 | vec3 halfAngle = normalize(oHalfAngle); |
---|
70 | |
---|
71 | // get diffuse colour |
---|
72 | vec4 diffuseColour = texture2D(diffuse, oUv0.xy); |
---|
73 | |
---|
74 | // specular |
---|
75 | vec4 specularColour = texture2D(specular, oUv0.xy); |
---|
76 | float shininess = specularColour.w; |
---|
77 | specularColour.w = 1.0; |
---|
78 | |
---|
79 | // calculate lit value. |
---|
80 | float diffuseCoeff = max(dot(oNormal, lightVec), 0.0); |
---|
81 | float specularCoeff = step(0.0, dot(oNormal, lightVec)) * max(dot(oNormal, halfAngle) * (shininess * 128.0), 0.0); |
---|
82 | vec4 lighting; |
---|
83 | lighting.y = diffuseCoeff * shadowing; |
---|
84 | lighting.z = specularCoeff * shadowing; |
---|
85 | // vec4 lighting = lit(dot(oNormal, lightVec), dot(oNormal, halfAngle), shininess * 128.0) * shadowing; |
---|
86 | |
---|
87 | // final lighting with diffuse and spec |
---|
88 | gl_FragColor = (diffuseColour * clamp(ambient + lightDiffuse * lighting.y, 0.0, 1.0)) + (lightSpecular * specularColour * lighting.z); |
---|
89 | gl_FragColor.w = diffuseColour.w; |
---|
90 | |
---|
91 | //oColour += splitColour; |
---|
92 | } |
---|