Guest User

StandardPhong.fsd

a guest
Dec 25th, 2018
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.95 KB | None | 0 0
  1. //This is the default Sprite Lamp shader. It is not optimised for speed but rather, readability,
  2. //so certain things wouldn't make sense in a game environment (for instance you'd probably
  3. //want to pack things into fewer textures).
  4.  
  5. #version 120
  6.  
  7. uniform sampler2D normalMap;
  8. uniform sampler2D diffuseMap;
  9. uniform sampler2D depthMap;
  10. uniform sampler2D specularMap; //Optionally contains glossiness in the alpha channel
  11. uniform sampler2D emissiveMap;
  12. uniform sampler2D aoMap;
  13. uniform sampler2D anisotropyMap; //Not used in this shader.
  14.  
  15. uniform vec3 lightPosition;
  16. uniform vec3 directLightColour;
  17. uniform vec3 ambientLightColour; //Upper ambient colour
  18. uniform vec3 ambientLightColour2; //Lower ambient colour
  19. uniform vec2 textureResolution; //Used for per texel lighting
  20.  
  21. uniform float celShadingLevel;
  22.  
  23. uniform float lightWrap;
  24.  
  25. uniform float amplifyDepth;
  26.  
  27. uniform float shadows; //boolean value - determines whether to use shadows
  28.  
  29. uniform float ambientMapStrength;
  30.  
  31. uniform float normalFlip; //boolean value so the shader knows whether to expect normals with upsidedown Y values
  32.  
  33. uniform float attenuationMultiplier;
  34.  
  35. uniform float glossFromSpecAlpha; //boolean value - determines whether to get specular exponent from the spec map alpha
  36.  
  37. uniform mat2 rotationMatrix; //Simple case of 2D rotation - not suitable for general game engine use
  38.  
  39. void main()
  40. {
  41.  
  42. //This value will be the tex coords at the centre of the nearest texel.
  43. vec2 centredTexCoords = gl_TexCoord[0].xy;
  44.  
  45. centredTexCoords *= textureResolution.xy;
  46. centredTexCoords = floor(centredTexCoords.xy) + vec2(0.5, 0.5);
  47. centredTexCoords /= textureResolution.xy;
  48.  
  49. //All the texture lookups done at the start where possible.
  50. vec4 normalColour = texture2D(normalMap, gl_TexCoord[0].xy);
  51. vec4 diffuseColour = texture2D(diffuseMap, gl_TexCoord[0].xy);
  52. vec4 specularColour = texture2D(specularMap, gl_TexCoord[0].xy);
  53. vec4 emissiveColour = texture2D(emissiveMap, gl_TexCoord[0].xy);
  54. vec4 aoColour = texture2D(aoMap, gl_TexCoord[0].xy);
  55. vec4 anisotropyColour = texture2D(anisotropyMap, gl_TexCoord[0].xy);
  56. float depthColour = texture2D(depthMap, gl_TexCoord[0].xy).x;
  57.  
  58.  
  59. if (diffuseColour.a <= 0.1)
  60. {
  61. discard;
  62. }
  63.  
  64. aoColour *= ambientMapStrength;
  65. aoColour += 1.0 - ambientMapStrength;
  66.  
  67. vec3 fragPos;
  68. fragPos.xy = gl_TexCoord[0].xy;
  69.  
  70.  
  71. //This sets the fragment position at the centre of the nearest texel,
  72. //for per-texel lighting. This unfortunately isn't very reusable in a general game engine sense.
  73. fragPos.xy *= textureResolution.xy;
  74. fragPos.xy = floor(fragPos.xy);
  75. fragPos.xy /= textureResolution.xy;
  76.  
  77.  
  78. fragPos.y = 1.0 - fragPos.y;
  79.  
  80.  
  81. fragPos = fragPos + vec3(-0.5, -0.5, 0.0);
  82. fragPos.x *= (textureResolution.x / textureResolution.y);
  83.  
  84. fragPos.z = depthColour * amplifyDepth;
  85.  
  86. vec3 normal = (normalColour.rgb - 0.5) * 2.0;
  87. normal.y *= normalFlip;
  88. normal.xy *= rotationMatrix;
  89.  
  90.  
  91.  
  92.  
  93.  
  94. vec3 lightVec = lightPosition - fragPos;
  95. lightVec.xy *= rotationMatrix;
  96.  
  97. float lightDistance = length(lightVec) * attenuationMultiplier;
  98.  
  99. //Currently attenuation uses certain fudge factors.
  100. float attenuation = 1.0 / (1.0 + 20.0 * lightDistance + 200.0 * lightDistance * lightDistance);
  101.  
  102. normal = normalize(normal);
  103. lightVec = normalize(lightVec);
  104. float shadowMult = 1.0;
  105. if (shadows > 0.5)
  106. {
  107. //Shadowing in Sprite Lamp works by tracing the light path backwards and checking to see
  108. //how many points on that line are 'inside' the depth map. The more there are, the darker the shadow,
  109. //until it becomes black. This isn't really physically accurate, but it does give reasonably convincing
  110. //soft shadows.
  111. float thisHeight = fragPos.z;
  112. vec3 tapPos = vec3(centredTexCoords, fragPos.z + 0.01);
  113. vec3 moveVec = lightVec.xyz * vec3(1.0, -1.0, 1.0) * 0.006;
  114. moveVec.xy *= rotationMatrix;
  115. moveVec.x *= textureResolution.y / textureResolution.x;
  116. for (int i = 0; i < 16; i++)
  117. {
  118. tapPos += moveVec;
  119. float tapDepth = texture2D(depthMap, tapPos.xy).x * amplifyDepth;
  120. if (tapDepth > tapPos.z)
  121. {
  122. shadowMult -= 0.125;
  123. }
  124. }
  125. }
  126.  
  127. shadowMult = clamp(shadowMult, 0.0, 1.0);
  128. float rawDiffuse = clamp(dot(normal, lightVec) * 1000.0, 0.0, 1.0);
  129.  
  130. //Somewhat confusing calculation to determine the diffuse level modified by the light wrap value.
  131. float diffuseLevel = clamp(dot(normal, lightVec) + lightWrap, 0.0, lightWrap + 1.0) / (lightWrap + 1.0) * attenuation;
  132.  
  133.  
  134.  
  135.  
  136. //Specular calculations
  137. vec3 viewVec = vec3(0.0, 0.0, 1.0); //Orthographic camera makes this nice and simple.
  138. vec3 bounceVec = reflect(-lightVec, normal);
  139. //Add 0.5 to the end of this to avoid raising to the zeroth power.
  140. float glossiness = (5.0 * (1.0 - glossFromSpecAlpha)) + (specularColour.a * 50.0 * glossFromSpecAlpha) + 0.5;
  141. float specLevel = pow(clamp(dot(bounceVec, viewVec), 0.0, 1.0), glossiness) * rawDiffuse * 0.5 * attenuation;
  142.  
  143.  
  144. diffuseLevel *= shadowMult;
  145.  
  146. diffuseLevel *= celShadingLevel;
  147. diffuseLevel = floor(diffuseLevel);
  148. diffuseLevel /= celShadingLevel - 0.5;
  149.  
  150.  
  151. specLevel *= celShadingLevel;
  152. specLevel = floor(specLevel);
  153. specLevel /= celShadingLevel - 0.5;
  154.  
  155.  
  156. //The 'upFactor' is the extent to which the surface normal is pointing up in world space.
  157. //1.0 meaning straight up, 0.0 meaning straight down, and 0.5 meaning horizontal. It is
  158. //then used for mixing the upper and lower amnbient colours.
  159. float upFactor = normal.y * 0.5 + 0.5;
  160. upFactor *= celShadingLevel;
  161. upFactor = floor(upFactor);
  162. upFactor /= celShadingLevel - 0.5;
  163. vec3 ambientResult = ambientLightColour * upFactor + ambientLightColour2 * (1.0 - upFactor);
  164.  
  165. //Everything is comnbined in a big final calculation here.
  166. gl_FragColor.rgb = (diffuseLevel * directLightColour + ambientResult * aoColour.rgb) * diffuseColour.rgb;
  167. gl_FragColor.rgb += vec3(specLevel, specLevel, specLevel) * specularColour.rgb * directLightColour * shadowMult + emissiveColour.rgb;
  168.  
  169. gl_FragColor.a = diffuseColour.a;
  170.  
  171.  
  172. }
Add Comment
Please, Sign In to add comment