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