[12115] | 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 | } |
---|