| 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 | } |
|---|