Browse Source

Shader and CoreData delta

Josh Engebretson 9 years ago
parent
commit
5b229af1da
84 changed files with 3030 additions and 331 deletions
  1. 8 8
      Resources/CoreData/Materials/DefaultGrey.xml
  2. 1 1
      Resources/CoreData/PostProcess/BloomHDR.xml
  3. 30 0
      Resources/CoreData/RenderPaths/ForwardHWDepth.xml
  4. 29 0
      Resources/CoreData/RenderPaths/PBRDeferredHWDepth.xml
  5. 135 0
      Resources/CoreData/RenderPaths/Prepass.xml
  6. 13 13
      Resources/CoreData/Shaders/GLSL/Bloom.glsl
  7. 7 0
      Resources/CoreData/Shaders/GLSL/Constants.glsl
  8. 6 2
      Resources/CoreData/Shaders/GLSL/DeferredLight.glsl
  9. 300 0
      Resources/CoreData/Shaders/GLSL/IBL.glsl
  10. 161 62
      Resources/CoreData/Shaders/GLSL/Lighting.glsl
  11. 6 2
      Resources/CoreData/Shaders/GLSL/LitParticle.glsl
  12. 11 7
      Resources/CoreData/Shaders/GLSL/LitSolid.glsl
  13. 33 0
      Resources/CoreData/Shaders/GLSL/PBR.glsl
  14. 117 0
      Resources/CoreData/Shaders/GLSL/PBRDeferred.glsl
  15. 252 0
      Resources/CoreData/Shaders/GLSL/PBRLitSolid.glsl
  16. 0 6
      Resources/CoreData/Shaders/GLSL/PostProcess.glsl
  17. 6 2
      Resources/CoreData/Shaders/GLSL/PrepassLight.glsl
  18. 6 2
      Resources/CoreData/Shaders/GLSL/Samplers.glsl
  19. 10 3
      Resources/CoreData/Shaders/GLSL/ScreenPos.glsl
  20. 17 4
      Resources/CoreData/Shaders/GLSL/Shadow.glsl
  21. 34 0
      Resources/CoreData/Shaders/GLSL/ShadowBlur.glsl
  22. 5 7
      Resources/CoreData/Shaders/GLSL/Skybox.glsl
  23. 22 0
      Resources/CoreData/Shaders/GLSL/Skydome.glsl
  24. 8 4
      Resources/CoreData/Shaders/GLSL/TerrainBlend.glsl
  25. 79 9
      Resources/CoreData/Shaders/GLSL/Transform.glsl
  26. 29 10
      Resources/CoreData/Shaders/GLSL/Uniforms.glsl
  27. 4 0
      Resources/CoreData/Shaders/GLSL/Unlit.glsl
  28. 23 0
      Resources/CoreData/Shaders/GLSL/Urho2D.glsl
  29. 14 3
      Resources/CoreData/Shaders/GLSL/Vegetation.glsl
  30. 135 0
      Resources/CoreData/Shaders/HLSL/BRDF.hlsl
  31. 8 2
      Resources/CoreData/Shaders/HLSL/Basic.hlsl
  32. 9 9
      Resources/CoreData/Shaders/HLSL/Bloom.hlsl
  33. 22 26
      Resources/CoreData/Shaders/HLSL/Blur.hlsl
  34. 7 0
      Resources/CoreData/Shaders/HLSL/Constants.hlsl
  35. 7 3
      Resources/CoreData/Shaders/HLSL/DeferredLight.hlsl
  36. 9 2
      Resources/CoreData/Shaders/HLSL/Depth.hlsl
  37. 282 0
      Resources/CoreData/Shaders/HLSL/IBL.hlsl
  38. 148 47
      Resources/CoreData/Shaders/HLSL/Lighting.hlsl
  39. 8 5
      Resources/CoreData/Shaders/HLSL/LitParticle.hlsl
  40. 34 49
      Resources/CoreData/Shaders/HLSL/LitSolid.hlsl
  41. 34 0
      Resources/CoreData/Shaders/HLSL/PBR.hlsl
  42. 120 0
      Resources/CoreData/Shaders/HLSL/PBRDeferred.hlsl
  43. 337 0
      Resources/CoreData/Shaders/HLSL/PBRLitSolid.hlsl
  44. 6 2
      Resources/CoreData/Shaders/HLSL/PrepassLight.hlsl
  45. 10 1
      Resources/CoreData/Shaders/HLSL/Samplers.hlsl
  46. 9 2
      Resources/CoreData/Shaders/HLSL/ScreenPos.hlsl
  47. 31 7
      Resources/CoreData/Shaders/HLSL/Shadow.hlsl
  48. 48 0
      Resources/CoreData/Shaders/HLSL/ShadowBlur.hlsl
  49. 6 2
      Resources/CoreData/Shaders/HLSL/Skybox.hlsl
  50. 22 0
      Resources/CoreData/Shaders/HLSL/Skydome.hlsl
  51. 8 5
      Resources/CoreData/Shaders/HLSL/TerrainBlend.hlsl
  52. 71 2
      Resources/CoreData/Shaders/HLSL/Transform.hlsl
  53. 24 6
      Resources/CoreData/Shaders/HLSL/Uniforms.hlsl
  54. 9 3
      Resources/CoreData/Shaders/HLSL/Unlit.hlsl
  55. 27 0
      Resources/CoreData/Shaders/HLSL/Urho2D.hlsl
  56. 43 8
      Resources/CoreData/Shaders/HLSL/Vegetation.hlsl
  57. 18 2
      Resources/CoreData/Shaders/HLSL/VegetationDepth.hlsl
  58. 18 2
      Resources/CoreData/Shaders/HLSL/VegetationShadow.hlsl
  59. 3 0
      Resources/CoreData/Shaders/HLSL/Water.hlsl
  60. 10 0
      Resources/CoreData/Techniques/DiffAlphaMaskTranslucent.xml
  61. 5 0
      Resources/CoreData/Techniques/DiffAlphaTranslucent.xml
  62. 1 1
      Resources/CoreData/Techniques/DiffLightMap.xml
  63. 10 0
      Resources/CoreData/Techniques/DiffNormalAlphaMaskTranslucent.xml
  64. 5 0
      Resources/CoreData/Techniques/DiffNormalAlphaTranslucent.xml
  65. 10 0
      Resources/CoreData/Techniques/DiffNormalPackedAlphaMaskTranslucent.xml
  66. 5 0
      Resources/CoreData/Techniques/DiffNormalPackedAlphaTranslucent.xml
  67. 3 0
      Resources/CoreData/Techniques/DiffSkyboxHDRScale.xml
  68. 3 0
      Resources/CoreData/Techniques/DiffSkydome.xml
  69. 8 0
      Resources/CoreData/Techniques/PBR/DiffNormalSpecEmissive.xml
  70. 5 0
      Resources/CoreData/Techniques/PBR/DiffNormalSpecEmissiveAlpha.xml
  71. 8 0
      Resources/CoreData/Techniques/PBR/PBRDiff.xml
  72. 5 0
      Resources/CoreData/Techniques/PBR/PBRDiffAlpha.xml
  73. 8 0
      Resources/CoreData/Techniques/PBR/PBRDiffNormal.xml
  74. 5 0
      Resources/CoreData/Techniques/PBR/PBRDiffNormalAlpha.xml
  75. 7 0
      Resources/CoreData/Techniques/PBR/PBRDiffNormalEmissive.xml
  76. 5 0
      Resources/CoreData/Techniques/PBR/PBRDiffNormalEmissiveAlpha.xml
  77. 8 0
      Resources/CoreData/Techniques/PBR/PBRMetallicRoughDiffNormalSpec.xml
  78. 8 0
      Resources/CoreData/Techniques/PBR/PBRMetallicRoughDiffNormalSpecEmissive.xml
  79. 5 0
      Resources/CoreData/Techniques/PBR/PBRMetallicRoughDiffNormalSpecEmissiveAlpha.xml
  80. 8 0
      Resources/CoreData/Techniques/PBR/PBRMetallicRoughDiffSpec.xml
  81. 5 0
      Resources/CoreData/Techniques/PBR/PBRMetallicRoughDiffSpecAlpha.xml
  82. 9 0
      Resources/CoreData/Techniques/PBR/PBRNoTexture.xml
  83. 5 0
      Resources/CoreData/Techniques/PBR/PBRNoTextureAlpha.xml
  84. 0 0
      Resources/CoreData/Textures/LUTIdentity.png

+ 8 - 8
Resources/CoreData/Materials/DefaultGrey.xml

@@ -1,19 +1,19 @@
 <renderpath>
 <renderpath>
-    <rendertarget name="vblur" tag="Bloom" sizedivisor="4 4" format="rgb" filter="true" />
-    <rendertarget name="hblur" tag="Bloom" sizedivisor="4 4" format="rgb" filter="true" />
-    <command type="quad" tag="Bloom" vs="Bloom" ps="Bloom" psdefines="BRIGHT" output="vblur">
+    <rendertarget name="blurv" tag="Bloom" sizedivisor="4 4" format="rgb" filter="true" />
+    <rendertarget name="blurh" tag="Bloom" sizedivisor="4 4" format="rgb" filter="true" />
+    <command type="quad" tag="Bloom" vs="Bloom" ps="Bloom" psdefines="BRIGHT" output="blurv">
         <parameter name="BloomThreshold" value="0.3" />
         <parameter name="BloomThreshold" value="0.3" />
         <texture unit="diffuse" name="viewport" />
         <texture unit="diffuse" name="viewport" />
     </command>
     </command>
-    <command type="quad" tag="Bloom" vs="Bloom" ps="Bloom" psdefines="HBLUR" output="hblur">
-        <texture unit="diffuse" name="vblur" />
+    <command type="quad" tag="Bloom" vs="Bloom" ps="Bloom" psdefines="BLURH" output="blurh">
+        <texture unit="diffuse" name="blurv" />
     </command>
     </command>
-    <command type="quad" tag="Bloom" vs="Bloom" ps="Bloom" psdefines="VBLUR" output="vblur">
-        <texture unit="diffuse" name="hblur" />
+    <command type="quad" tag="Bloom" vs="Bloom" ps="Bloom" psdefines="BLURV" output="blurv">
+        <texture unit="diffuse" name="blurh" />
     </command>
     </command>
     <command type="quad" tag="Bloom" vs="Bloom" ps="Bloom" psdefines="COMBINE" output="viewport">
     <command type="quad" tag="Bloom" vs="Bloom" ps="Bloom" psdefines="COMBINE" output="viewport">
         <parameter name="BloomMix" value="0.9 0.4" />
         <parameter name="BloomMix" value="0.9 0.4" />
         <texture unit="diffuse" name="viewport" />
         <texture unit="diffuse" name="viewport" />
-        <texture unit="normal" name="vblur" />
+        <texture unit="normal" name="blurv" />
     </command>
     </command>
 </renderpath>
 </renderpath>

+ 1 - 1
Resources/CoreData/PostProcess/BloomHDR.xml

@@ -2,7 +2,7 @@
     <rendertarget name="depth" sizedivisor="1 1" format="lineardepth" />
     <rendertarget name="depth" sizedivisor="1 1" format="lineardepth" />
     <command type="clear" color="1 1 1 1" depth="1.0" stencil="0" output="depth" />
     <command type="clear" color="1 1 1 1" depth="1.0" stencil="0" output="depth" />
     <command type="scenepass" pass="depth" output="depth" />
     <command type="scenepass" pass="depth" output="depth" />
-    <command type="clear" color="fog" />
+    <command type="clear" color="fog" depth="1.0" stencil="0" />
     <command type="scenepass" pass="base" vertexlights="true" metadata="base" />
     <command type="scenepass" pass="base" vertexlights="true" metadata="base" />
     <command type="forwardlights" pass="light" />
     <command type="forwardlights" pass="light" />
     <command type="scenepass" pass="postopaque" />
     <command type="scenepass" pass="postopaque" />

+ 30 - 0
Resources/CoreData/RenderPaths/ForwardHWDepth.xml

@@ -0,0 +1,30 @@
+<renderpath>
+    <rendertarget name="specular" sizedivisor="1 1" format="rgba16f" />
+    <rendertarget name="albedo" sizedivisor="1 1" format="rgba16f" />
+    <rendertarget name="normal" sizedivisor="1 1" format="rgba16f" />
+    <rendertarget name="depth" sizedivisor="1 1" format="lineardepth" />
+    <command type="clear" color="0 0 0 0" depth="1.0" stencil="0" />
+    <command type="clear" color="0 0 0 0" output="albedo" />
+    <command type="clear" color="0 0 0 0" output="specular" />
+    <command type="clear" color="0 0 0 0" output="normal" />
+    <command type="clear" color="0 0 0 0" depth="1.0" output="depth" />
+    <command type="scenepass" pass="base" vertexlights="true" metadata="base" />
+    <command type="scenepass" pass="deferred" marktostencil="true" vertexlights="true" metadata="gbuffer">
+        <output index="0" name="specular" />
+        <output index="1" name="albedo" />
+        <output index="2" name="normal" />
+        <output index="3" name="depth" />
+    </command>
+    <command type="lightvolumes" vs="PBRDeferred" ps="PBRDeferred" psdefines="PBRDEFERRED PBR" vsdefines="PBR" output="viewport">
+        <texture unit="specular" name="specular" />
+        <texture unit="albedo" name="albedo" />
+        <texture unit="normal" name="normal" />
+        <texture unit="depth" name="depth" />
+    </command>
+    <command type="scenepass" pass="postopaque" />
+    <command type="scenepass" pass="refract">
+        <texture unit="environment" name="viewport" />
+    </command>
+    <command type="scenepass" pass="alpha" vertexlights="true" sort="backtofront" metadata="alpha" />
+    <command type="scenepass" pass="postalpha" sort="backtofront" />
+</renderpath>

+ 29 - 0
Resources/CoreData/RenderPaths/PBRDeferredHWDepth.xml

@@ -0,0 +1,29 @@
+<renderpath>
+    <rendertarget name="specular" sizedivisor="1 1" format="rgba16f" />
+    <rendertarget name="albedo" sizedivisor="1 1" format="rgba16f" />
+    <rendertarget name="normal" sizedivisor="1 1" format="rgba16f" />
+    <rendertarget name="depth" sizedivisor="1 1" format="readabledepth" />
+    <command type="clear" color="0 0 0 0" depth="1.0" stencil="0" depthstencil="depth" />
+    <command type="clear" color="0 0 0 0" output="albedo" depthstencil="depth"/>
+    <command type="clear" color="0 0 0 0" output="specular" depthstencil="depth" />
+    <command type="clear" color="0 0 0 0" output="normal" depthstencil="depth" />
+    <command type="clear" color="0 0 0 0" depth="1.0" output="depth" depthstencil="depth" />
+    <command type="scenepass" pass="base" vertexlights="true" metadata="base" depthstencil="depth" />
+    <command type="scenepass" pass="deferred" marktostencil="true" vertexlights="true" metadata="gbuffer" depthstencil="depth">
+        <output index="0" name="specular" />
+        <output index="1" name="albedo" />
+        <output index="2" name="normal" />
+    </command>
+    <command type="lightvolumes" vs="PBRDeferred" ps="PBRDeferred" psdefines="PBRDEFERRED PBR HWDEPTH" vsdefines="PBR" output="viewport" depthstencil="depth">
+        <texture unit="specular" name="specular" />
+        <texture unit="albedo" name="albedo" />
+        <texture unit="normal" name="normal" />
+        <texture unit="depth" name="depth" />
+    </command>
+    <command type="scenepass" pass="postopaque" depthstencil="depth"/>
+    <command type="scenepass" pass="refract" depthstencil="depth">
+        <texture unit="environment" name="viewport" />
+    </command>
+    <command type="scenepass" pass="alpha" vertexlights="true" sort="backtofront" metadata="alpha" depthstencil="depth" />
+    <command type="scenepass" pass="postalpha" sort="backtofront" depthstencil="depth" />
+</renderpath>

+ 135 - 0
Resources/CoreData/RenderPaths/Prepass.xml

@@ -0,0 +1,135 @@
+#line 20001
+#ifdef COMPILEPS
+  #ifdef PBR
+    // Following BRDF methods are based upon research Frostbite EA
+    //[Lagrade et al. 2014, "Moving Frostbite to Physically Based Rendering"]
+    
+    //Schlick Fresnel
+    //specular  = the rgb specular color value of the pixel
+    //VdotH     = the dot product of the camera view direction and the half vector 
+    vec3 SchlickFresnel(vec3 specular, float VdotH)
+    {
+        return specular + (vec3(1.0, 1.0, 1.0) - specular) * pow(1.0 - VdotH, 5.0);
+    }
+
+    //Schlick Gaussian Fresnel
+    //specular  = the rgb specular color value of the pixel
+    //VdotH     = the dot product of the camera view direction and the half vector 
+    vec3 SchlickGaussianFresnel(in vec3 specular, in float VdotH)
+    {
+        float sphericalGaussian = pow(2.0, (-5.55473 * VdotH - 6.98316) * VdotH);
+        return specular + (vec3(1.0, 1.0, 1.0) - specular) * sphericalGaussian;
+    }
+
+    //Get Fresnel
+    //specular  = the rgb specular color value of the pixel
+    //VdotH     = the dot product of the camera view direction and the half vector 
+    vec3 Fresnel(vec3 specular, float VdotH)
+    {
+        return SchlickFresnel(specular, VdotH);
+    }
+
+    // Smith GGX corrected Visibility
+    // NdotL        = the dot product of the normal and direction to the light
+    // NdotV        = the dot product of the normal and the camera view direction
+    // roughness    = the roughness of the pixel
+    float SmithGGXSchlickVisibility(float NdotL, float NdotV, float roughness)
+    {
+        float rough2 = roughness * roughness;
+        float lambdaV = NdotL  * sqrt((-NdotV * rough2 + NdotV) * NdotV + rough2);   
+        float lambdaL = NdotV  * sqrt((-NdotL * rough2 + NdotL) * NdotL + rough2);
+    
+        return 0.5 / (lambdaV + lambdaL);
+    }
+
+    // Get Visibility
+    // NdotL        = the dot product of the normal and direction to the light
+    // NdotV        = the dot product of the normal and the camera view direction
+    // roughness    = the roughness of the pixel
+    float Visibility(float NdotL, float NdotV, float roughness)
+    {
+        return SmithGGXSchlickVisibility(NdotL, NdotV, roughness);
+    }
+
+    // Blinn Distribution
+    // NdotH        = the dot product of the normal and the half vector
+    // roughness    = the roughness of the pixel
+    float BlinnPhongDistribution(in float NdotH, in float roughness)
+    {
+        float specPower = max((2.0 / (roughness * roughness)) - 2.0, 1e-4); // Calculate specular power from roughness
+        return pow(clamp(NdotH, 0.0, 1.0), specPower);
+    }
+
+    // Beckmann Distribution
+    // NdotH        = the dot product of the normal and the half vector
+    // roughness    = the roughness of the pixel
+    float BeckmannDistribution(in float NdotH, in float roughness)
+    {
+        float rough2 = roughness * roughness;
+        float roughnessA = 1.0 / (4.0 * rough2 * pow(NdotH, 4.0));
+        float roughnessB = NdotH * NdotH - 1.0;
+        float roughnessC = rough2 * NdotH * NdotH;
+        return roughnessA * exp(roughnessB / roughnessC);
+    }
+
+    // GGX Distribution
+    // NdotH        = the dot product of the normal and the half vector
+    // roughness    = the roughness of the pixel
+    float GGXDistribution(float NdotH, float roughness)
+    {
+        float rough2 = roughness * roughness;
+        float tmp =  (NdotH * rough2 - NdotH) * NdotH + 1.0;
+        return rough2 / (tmp * tmp);
+    }
+
+    // Get Distribution
+    // NdotH        = the dot product of the normal and the half vector
+    // roughness    = the roughness of the pixel
+    float Distribution(float NdotH, float roughness)
+    {
+        return GGXDistribution(NdotH, roughness);
+    }
+
+    // Lambertian Diffuse
+    // diffuseColor = the rgb color value of the pixel
+    // roughness    = the roughness of the pixel
+    // NdotV        = the normal dot with the camera view direction
+    // NdotL        = the normal dot with the light direction
+    // VdotH        = the camera view direction dot with the half vector
+    vec3 LambertianDiffuse(vec3 diffuseColor, float NdotL)
+    {
+        return diffuseColor * NdotL;
+    }
+
+    // Burley Diffuse
+    // diffuseColor = the rgb color value of the pixel
+    // roughness    = the roughness of the pixel
+    // NdotV        = the normal dot with the camera view direction
+    // NdotL        = the normal dot with the light direction
+    // VdotH        = the camera view direction dot with the half vector
+    vec3 BurleyDiffuse(vec3 diffuseColor, float roughness, float NdotV, float NdotL, float VdotH)
+    {
+        float energyBias = mix(roughness, 0.0, 0.5);
+        float energyFactor = mix(roughness, 1.0, 1.0 / 1.51);
+        float fd90 = energyBias + 2.0 * VdotH * VdotH * roughness;
+        float f0 = 1.0;
+        float lightScatter = f0 + (fd90 - f0) * pow(1.0f - NdotL, 5.0f);
+        float viewScatter = f0 + (fd90 - f0) * pow(1.0f - NdotV, 5.0f);
+
+        return diffuseColor * lightScatter * viewScatter * energyFactor;
+    }
+
+    //Get Diffuse
+    // diffuseColor = the rgb color value of the pixel
+    // roughness    = the roughness of the pixel
+    // NdotV        = the normal dot with the camera view direction
+    // NdotL        = the normal dot with the light direction
+    // VdotH        = the camera view direction dot with the half vector
+    vec3 Diffuse(vec3 diffuseColor, float roughness, float NdotV, float NdotL, float VdotH)
+    {
+        //return LambertianDiffuse(diffuseColor, NdotL);
+        return BurleyDiffuse(diffuseColor, roughness, NdotV, NdotL, VdotH);
+    }
+
+  #endif
+#endif

+ 13 - 13
Resources/CoreData/Shaders/GLSL/Bloom.glsl

@@ -9,7 +9,7 @@ varying vec2 vScreenPos;
 #ifdef COMPILEPS
 #ifdef COMPILEPS
 uniform float cBloomThreshold;
 uniform float cBloomThreshold;
 uniform vec2 cBloomMix;
 uniform vec2 cBloomMix;
-uniform vec2 cHBlurInvSize;
+uniform vec2 cBlurHInvSize;
 #endif
 #endif
 
 
 void VS()
 void VS()
@@ -28,21 +28,21 @@ void PS()
     gl_FragColor = vec4((rgb - vec3(cBloomThreshold, cBloomThreshold, cBloomThreshold)) / (1.0 - cBloomThreshold), 1.0);
     gl_FragColor = vec4((rgb - vec3(cBloomThreshold, cBloomThreshold, cBloomThreshold)) / (1.0 - cBloomThreshold), 1.0);
     #endif
     #endif
 
 
-    #ifdef HBLUR
-    vec3 rgb = texture2D(sDiffMap, vTexCoord + vec2(-2.0, 0.0) * cHBlurInvSize).rgb * 0.1;
-    rgb += texture2D(sDiffMap, vTexCoord + vec2(-1.0, 0.0) * cHBlurInvSize).rgb * 0.25;
-    rgb += texture2D(sDiffMap, vTexCoord + vec2(0.0, 0.0) * cHBlurInvSize).rgb * 0.3;
-    rgb += texture2D(sDiffMap, vTexCoord + vec2(1.0, 0.0) * cHBlurInvSize).rgb * 0.25;
-    rgb += texture2D(sDiffMap, vTexCoord + vec2(2.0, 0.0) * cHBlurInvSize).rgb * 0.1;
+    #ifdef BLURH
+    vec3 rgb = texture2D(sDiffMap, vTexCoord + vec2(-2.0, 0.0) * cBlurHInvSize).rgb * 0.1;
+    rgb += texture2D(sDiffMap, vTexCoord + vec2(-1.0, 0.0) * cBlurHInvSize).rgb * 0.25;
+    rgb += texture2D(sDiffMap, vTexCoord + vec2(0.0, 0.0) * cBlurHInvSize).rgb * 0.3;
+    rgb += texture2D(sDiffMap, vTexCoord + vec2(1.0, 0.0) * cBlurHInvSize).rgb * 0.25;
+    rgb += texture2D(sDiffMap, vTexCoord + vec2(2.0, 0.0) * cBlurHInvSize).rgb * 0.1;
     gl_FragColor = vec4(rgb, 1.0);
     gl_FragColor = vec4(rgb, 1.0);
     #endif
     #endif
 
 
-    #ifdef VBLUR
-    vec3 rgb = texture2D(sDiffMap, vTexCoord + vec2(0.0, -2.0) * cHBlurInvSize).rgb * 0.1;
-    rgb += texture2D(sDiffMap, vTexCoord + vec2(0.0, -1.0) * cHBlurInvSize).rgb * 0.25;
-    rgb += texture2D(sDiffMap, vTexCoord + vec2(0.0, 0.0) * cHBlurInvSize).rgb * 0.3;
-    rgb += texture2D(sDiffMap, vTexCoord + vec2(0.0, 1.0) * cHBlurInvSize).rgb * 0.25;
-    rgb += texture2D(sDiffMap, vTexCoord + vec2(0.0, 2.0) * cHBlurInvSize).rgb * 0.1;
+    #ifdef BLURV
+    vec3 rgb = texture2D(sDiffMap, vTexCoord + vec2(0.0, -2.0) * cBlurHInvSize).rgb * 0.1;
+    rgb += texture2D(sDiffMap, vTexCoord + vec2(0.0, -1.0) * cBlurHInvSize).rgb * 0.25;
+    rgb += texture2D(sDiffMap, vTexCoord + vec2(0.0, 0.0) * cBlurHInvSize).rgb * 0.3;
+    rgb += texture2D(sDiffMap, vTexCoord + vec2(0.0, 1.0) * cBlurHInvSize).rgb * 0.25;
+    rgb += texture2D(sDiffMap, vTexCoord + vec2(0.0, 2.0) * cBlurHInvSize).rgb * 0.1;
     gl_FragColor = vec4(rgb, 1.0);
     gl_FragColor = vec4(rgb, 1.0);
     #endif
     #endif
 
 

+ 7 - 0
Resources/CoreData/Shaders/GLSL/Constants.glsl

@@ -0,0 +1,7 @@
+#define M_PI 3.14159265358979323846
+#define M_EPSILON 0.0001
+
+#ifdef PBR
+#define ROUGHNESS_FLOOR 0.003
+#define METALNESS_FLOOR 0.03
+#endif

+ 6 - 2
Resources/CoreData/Shaders/GLSL/DeferredLight.glsl

@@ -66,6 +66,10 @@ void PS()
         vec4 normalInput = texture2DProj(sNormalBuffer, vScreenPos);
         vec4 normalInput = texture2DProj(sNormalBuffer, vScreenPos);
     #endif
     #endif
 
 
+    // Position acquired via near/far ray is relative to camera. Bring position to world space
+    vec3 eyeVec = -worldPos;
+    worldPos += cCameraPosPS;
+    
     vec3 normal = normalize(normalInput.rgb * 2.0 - 1.0);
     vec3 normal = normalize(normalInput.rgb * 2.0 - 1.0);
     vec4 projWorldPos = vec4(worldPos, 1.0);
     vec4 projWorldPos = vec4(worldPos, 1.0);
     vec3 lightColor;
     vec3 lightColor;
@@ -74,7 +78,7 @@ void PS()
     float diff = GetDiffuse(normal, worldPos, lightDir);
     float diff = GetDiffuse(normal, worldPos, lightDir);
 
 
     #ifdef SHADOW
     #ifdef SHADOW
-        diff *= GetShadowDeferred(projWorldPos, depth);
+        diff *= GetShadowDeferred(projWorldPos, normal, depth);
     #endif
     #endif
 
 
     #if defined(SPOTLIGHT)
     #if defined(SPOTLIGHT)
@@ -88,7 +92,7 @@ void PS()
     #endif
     #endif
 
 
     #ifdef SPECULAR
     #ifdef SPECULAR
-        float spec = GetSpecular(normal, -worldPos, lightDir, normalInput.a * 255.0);
+        float spec = GetSpecular(normal, eyeVec, lightDir, normalInput.a * 255.0);
         gl_FragColor = diff * vec4(lightColor * (albedoInput.rgb + spec * cLightColor.a * albedoInput.aaa), 0.0);
         gl_FragColor = diff * vec4(lightColor * (albedoInput.rgb + spec * cLightColor.a * albedoInput.aaa), 0.0);
     #else
     #else
         gl_FragColor = diff * vec4(lightColor * albedoInput.rgb, 0.0);
         gl_FragColor = diff * vec4(lightColor * albedoInput.rgb, 0.0);

+ 300 - 0
Resources/CoreData/Shaders/GLSL/IBL.glsl

@@ -0,0 +1,300 @@
+#line 10001
+#ifdef COMPILEPS
+
+    //
+    // Legacy Importance Sampled IBL
+    //
+
+    // vec3 ImportanceSampleSimple(in vec2 Xi, in float roughness, in vec3 T, in vec3 B, in vec3 N)
+    // {
+    //     float a = roughness * roughness;
+    //     mat3 tbn = mat3(T, B, N);
+    //     #ifdef IBLFAST
+    //         const float blurFactor = 0.0;
+    //     #else
+    //         const float blurFactor = 5.0;
+    //     #endif
+    //     vec2 xx = Xi.xy * blurFactor;
+    //     xx = xx - 1.0 * trunc(xx/1.0); // hlsl style modulo
+    //     vec3 Xi3 = mix(vec3(0,0,1), normalize(vec3(xx, 1.0)), a);
+    //     vec3 XiWS = tbn * Xi3;
+    //     return normalize(N + XiWS);
+    // }
+
+    // // Karis '13
+    // vec3 ImportanceSampleGGX(in vec2 Xi, in float roughness, in vec3 T, in vec3 B, in vec3 N)
+    // {
+    //     float a = roughness * roughness;
+    //     float Phi = 2.0 * M_PI * Xi.x;
+    //     float CosTheta = sqrt((1.0 - Xi.y) / (1.0 + (a*a - 1.0) * Xi.y));
+    //     float SinTheta = sqrt(1.0 - CosTheta * CosTheta);
+    //     vec3 H = vec3(0,0,0);
+    //     H.x = SinTheta * cos(Phi);
+    //     H.y = SinTheta * sin(Phi);
+    //     H.z = CosTheta;
+
+    //     vec3 UpVector = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
+    //     vec3 TangentX = normalize(cross(UpVector, N));
+    //     vec3 TangentY = cross(N, TangentX);
+    //     // Tangent to world space
+    //     return TangentX * H.x + TangentY * H.y + N * H.z;
+    // }
+
+    // #ifdef IBLFAST
+    //     #define IMPORTANCE_SAMPLES 1
+    // #else
+    //     #define IMPORTANCE_SAMPLES 4
+    // #endif
+
+    // #define IMPORTANCE_KERNEL_SIZE 16
+    // vec2 IMPORTANCE_KERNEL[IMPORTANCE_KERNEL_SIZE] = vec2[] (
+    //     vec2(-0.0780436, 0.0558389),
+    //     vec2(0.034318, -0.0635879),
+    //     vec2(0.00230821, 0.0807279),
+    //     vec2(0.0124638, 0.117585),
+    //     vec2(0.093943, -0.0944602),
+    //     vec2(0.139348, -0.109816),
+    //     vec2(-0.181872, -0.129649),
+    //     vec2(0.240066, -0.0494057),
+    //     vec2(0.115965, -0.0374714),
+    //     vec2(-0.294819, -0.100726),
+    //     vec2(-0.149652, 0.37459),
+    //     vec2(0.261695, -0.292813),
+    //     vec2(-0.37944, -0.425145),
+    //     vec2(0.628994, -0.189387),
+    //     vec2(-0.331257, -0.646864),
+    //     vec2(-0.467004, 0.439687)
+    //   );
+
+    //   float GetMipFromRougness(float roughness)
+    //   {
+    //       float smoothness = 1.0 - roughness;
+    //       return (1.0 - smoothness * smoothness) * 10.0;
+    //   }
+
+    // /// Perform importance sampling
+    // ///     reflectVec: calculated vector of reflection
+    // ///     wsNormal: world-space normal of the surface
+    // ///     toCamera: direction from the pixel to the camera
+    // ///     specular: specular color
+    // ///     roughness: surface roughness
+    // ///     reflectionCubeColor: output color for diffuse
+    // // Implementation based on Epics 2013 course notes
+    // vec3 ImportanceSampling(in vec3 reflectVec, in vec3 tangent, in vec3 bitangent, in vec3 wsNormal, in vec3 toCamera,  in vec3 diffColor, in vec3 specColor, in float roughness, inout vec3 reflectionCubeColor)
+    // {
+    //     reflectionCubeColor = vec3(1,1,1);
+
+    //     vec3 reflectSpec = normalize(GetSpecularDominantDir(wsNormal, reflectVec, roughness));
+
+    //     vec3 V = normalize(-toCamera);
+    //     vec3 N = normalize(wsNormal);
+    //     float ndv = clamp(abs(dot(N, V)), 0.0, 1.0);
+
+    //     float specMipLevel = GetMipFromRougness(roughness);
+
+    //     vec3 accumulatedColor = vec3(0,0,0);
+    //     for (int i = 0; i < IMPORTANCE_SAMPLES; ++i)
+    //     {
+    //         vec3 kd = vec3(1,1,1);
+    //         vec3 diffuseFactor = vec3(0,0,0);
+    //         vec3 specularFactor = vec3(0,0,0);
+
+    //         {
+    //             // Diffuse IBL
+    //             const float rough = 1.0;
+    //             const float mipLevel = 9.0;
+
+    //             vec3 H = ImportanceSampleSimple(IMPORTANCE_KERNEL[i], rough, tangent, bitangent, N);
+    //             vec3 L = 2.0 * dot( V, H ) * H - V;
+
+    //             float vdh = clamp(abs(dot(V, H)), 0.0, 1.0);
+    //             float ndh = clamp(abs(dot(N, H)), 0.0, 1.0);
+    //             float ndl = clamp(abs(dot(N, L)), 0.0, 1.0);
+
+    //             vec3 sampledColor = textureLod(sZoneCubeMap, L, mipLevel).rgb;
+
+    //             vec3 diffuseTerm = Diffuse(diffColor, rough, ndv, ndl, vdh);
+    //             vec3 lightTerm = sampledColor;
+
+    //             diffuseFactor = lightTerm * diffuseTerm;
+    //         }
+
+    //         {
+    //             // Specular IBL
+    //             float rough = roughness;
+    //             float mipLevel = specMipLevel;
+
+    //             vec3 H = ImportanceSampleSimple(IMPORTANCE_KERNEL[i], rough, tangent, bitangent, N);
+    //             vec3 L = 2.0 * dot( V, H ) * H - V;
+    //             vec3 sampledColor = textureLod(sZoneCubeMap, L, mipLevel).rgb;
+
+    //             float vdh = clamp(abs(dot(V, H)), 0.0, 1.0);
+    //             float ndh = clamp(abs(dot(N, H)), 0.0, 1.0);
+    //             float ndl = clamp(abs(dot(N, L)), 0.0, 1.0);
+
+    //             vec3 fresnelTerm = Fresnel(specColor, vdh);
+    //             float distTerm = 1.0; // Optimization, this term is mathematically cancelled out  -- Distribution(ndh, roughness);
+    //             float visTerm = Visibility(ndl, ndv, rough);
+
+    //             vec3 lightTerm = sampledColor * ndl;
+
+    //             float pdf = ndl > 0.05 ? ImportanceSamplePDF(distTerm, ndh, vdh) : 4.0; // reduce artifacts at extreme grazing angles
+
+    //             vec3 specularTerm = SpecularBRDF(distTerm, fresnelTerm, visTerm, ndl, ndv);
+
+    //             // energy conservation:
+    //             // Specular conservation:
+    //             specularFactor = lightTerm * specularTerm / pdf;
+    //             specularFactor = max(
+    //               clamp(normalize(specularFactor) * (length(sampledColor * specColor)), 0.0, 1.0),
+    //               specularFactor
+    //             );
+
+    //             // Diffuse conservation:
+    //             //kd = (sampledColor * specColor)/specularFactor; //energy conservation
+    //             kd = 1.0 - specularFactor;
+    //         }
+
+    //         accumulatedColor += specularFactor + diffuseFactor * kd;
+    //     }
+
+    //     return (accumulatedColor / IMPORTANCE_SAMPLES);
+    // }
+
+    // vec3 ImportanceSamplingSimple(in vec3 reflectVec, in vec3 tangent, in vec3 bitangent, in vec3 wsNormal, in vec3 toCamera,  in vec3 diffColor, in vec3 specColor, in float roughness, inout vec3 reflectionCubeColor)
+    // {
+    //     reflectionCubeColor = vec3(1,1,1);
+
+    //     reflectVec = normalize(GetSpecularDominantDir(wsNormal, reflectVec, roughness));
+
+    //     vec3 Hn = normalize(-toCamera + wsNormal);
+    //     float ndv = clamp(dot(-toCamera, wsNormal), 0.0, 1.0);
+    //     float vdh = clamp(dot(-toCamera, Hn), 0.0, 1.0);
+    //     float ndh = clamp(dot(wsNormal, Hn), 0.0, 1.0);
+
+    //     vec3 accumulatedColor = vec3(0,0,0);
+    //     for (int i = 0; i < IMPORTANCE_SAMPLES; ++i)
+    //     {
+    //         vec3 kd = vec3(1,1,1);
+    //         vec3 diffuseFactor = vec3(0,0,0);
+    //         vec3 specularFactor = vec3(0,0,0);
+
+    //         {
+    //             // Diffuse IBL
+    //             const float rough = 1.0;
+    //             const float mipLevel = 9.0;
+
+    //             vec3 perturb = ImportanceSampleGGX(IMPORTANCE_KERNEL[i].xy, rough, tangent, bitangent, wsNormal);
+    //             vec3 sampleVec = wsNormal + perturb; //perturb by the sample vector
+
+    //             vec3 sampledColor = textureLod(sZoneCubeMap, sampleVec, mipLevel).rgb;
+    //             float ndl = clamp(dot(sampleVec, wsNormal), 0.0, 1.0);
+
+    //             vec3 diffuseTerm = Diffuse(diffColor, rough, ndv, ndl, vdh);
+    //             vec3 lightTerm = sampledColor;
+
+    //             diffuseFactor = lightTerm * diffuseTerm;
+    //         }
+
+    //         {
+    //             // Specular IBL
+    //             float rough = roughness;
+    //             float mipLevel =  GetMipFromRougness(rough);
+
+    //             vec3 perturb = ImportanceSampleGGX(IMPORTANCE_KERNEL[i].xy, rough, tangent, bitangent, reflectVec);
+    //             vec3 sampleVec = reflectVec + perturb; //perturb by the sample vector
+
+    //             vec3 sampledColor = textureCube(sZoneCubeMap, sampleVec, mipLevel).rgb;
+    //             float ndl = clamp(dot(sampleVec, wsNormal), 0.0, 1.0);
+
+    //             vec3 fresnelTerm = SchlickFresnel(specColor, ndh) ;
+    //             float distTerm = 1.0; //Optimization, this term is mathematically cancelled out  //Distribution(ndh, roughness);
+    //             float visTerm = SmithGGXVisibility(ndl, ndv, rough);
+    //             vec3 lightTerm = sampledColor * ndl;
+
+    //             float pdf = 1.0; //ImportanceSamplePDF(distTerm, ndh, vdh);
+
+    //             specularFactor = lightTerm * SpecularBRDF(distTerm, fresnelTerm, visTerm, ndl, ndv) / pdf;
+    //             specularFactor *= pdf * ndv * (4.0 * ndl * ndv); // hacks
+    //             kd = (1.0 - clamp(specularFactor, 0.0, 1.0)); //energy conservation
+    //         }
+
+    //         accumulatedColor += specularFactor + diffuseFactor * kd;
+    //     }
+
+    //     return accumulatedColor / IMPORTANCE_SAMPLES;
+    // }
+
+    /// Determine reflection vector based on surface roughness, rougher uses closer to the normal and smoother uses closer to the reflection vector
+    ///     normal: surface normal
+    ///     reflection: vector of reflection off of the surface
+    ///     roughness: surface roughness
+    vec3 GetSpecularDominantDir(vec3 normal, vec3 reflection, float roughness)
+    {
+        float smoothness = 1.0 - roughness;
+        float lerpFactor = smoothness * (sqrt(smoothness) + roughness);
+        return mix(normal, reflection, lerpFactor);
+    }
+
+    float GetMipFromRougness(float roughness)
+    {
+        float smoothness = 1.0 - roughness;
+        return (1.0 - smoothness * smoothness) * 10.0;
+    }
+
+
+    vec3 EnvBRDFApprox (vec3 SpecularColor, float Roughness, float NoV)
+    {
+        vec4 c0 = vec4(-1, -0.0275, -0.572, 0.022 );
+        vec4 c1 = vec4(1, 0.0425, 1.0, -0.04 );
+        vec4 r = Roughness * c0 + c1;
+        float a004 = min( r.x * r.x, exp2( -9.28 * NoV ) ) * r.x + r.y;
+        vec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw;
+        return SpecularColor * AB.x + AB.y;
+    }
+
+    /// Calculate IBL contributation
+    ///     reflectVec: reflection vector for cube sampling
+    ///     wsNormal: surface normal in word space
+    ///     toCamera: normalized direction from surface point to camera
+    ///     roughness: surface roughness
+    ///     ambientOcclusion: ambient occlusion
+    vec3 ImageBasedLighting(vec3 reflectVec, vec3 tangent, vec3 bitangent, vec3 wsNormal, vec3 toCamera, vec3 diffColor, vec3 specColor, float roughness, inout vec3 reflectionCubeColor)
+    {
+        reflectVec = GetSpecularDominantDir(wsNormal, reflectVec, roughness);
+        float ndv = clamp(dot(-toCamera, wsNormal), 0.0, 1.0);
+
+        // PMREM Mipmapmode https://seblagarde.wordpress.com/2012/06/10/amd-cubemapgen-for-physically-based-rendering/
+        //float GlossScale = 16.0;
+        //float GlossBias = 5.0;
+        float mipSelect = roughness * 9.0; //exp2(GlossScale * roughness * roughness + GlossBias) - exp2(GlossBias);
+
+        // OpenGL ES does not support textureLod without extensions and does not have the sZoneCubeMap sampler,
+        // so for now, sample without explicit LOD, and from the environment sampler, where the zone texture will be put
+        // on mobile hardware
+        #ifndef GL_ES
+            vec3 cube = textureLod(sZoneCubeMap, reflectVec, mipSelect).rgb;
+            vec3 cubeD = textureLod(sZoneCubeMap, wsNormal, 9.0).rgb;
+        #else
+            vec3 cube = textureCube(sEnvCubeMap, reflectVec).rgb;
+            vec3 cubeD = textureCube(sEnvCubeMap, wsNormal).rgb;
+        #endif
+
+        // Fake the HDR texture
+        float brightness = clamp(cAmbientColor.a, 0.0, 1.0);
+        float darknessCutoff = clamp((cAmbientColor.a - 1.0) * 0.1, 0.0, 0.25);
+
+        const float hdrMaxBrightness = 5.0;
+        vec3 hdrCube = pow(cube + darknessCutoff, vec3(max(1.0, cAmbientColor.a)));
+        hdrCube += max(vec3(0.0), hdrCube - vec3(1.0)) * hdrMaxBrightness;
+
+        vec3 hdrCubeD = pow(cubeD + darknessCutoff, vec3(max(1.0, cAmbientColor.a)));
+        hdrCubeD += max(vec3(0.0), hdrCubeD - vec3(1.0)) * hdrMaxBrightness;
+
+        vec3 environmentSpecular = EnvBRDFApprox(specColor, roughness, ndv);
+        vec3 environmentDiffuse = EnvBRDFApprox(diffColor, 1.0, ndv);
+
+        return (hdrCube * environmentSpecular + hdrCubeD * environmentDiffuse) * brightness;
+        //return ImportanceSampling(reflectVec, tangent, bitangent, wsNormal, toCamera, diffColor, specColor, roughness, reflectionCubeColor);
+    }
+#endif

+ 161 - 62
Resources/CoreData/Shaders/GLSL/Lighting.glsl

@@ -16,7 +16,11 @@ float GetVertexLight(int index, vec3 worldPos, vec3 normal)
     // Directional light
     // Directional light
     if (invRange == 0.0)
     if (invRange == 0.0)
     {
     {
-        float NdotL = max(dot(normal, lightDir), 0.0);
+        #ifdef TRANSLUCENT
+            float NdotL = abs(dot(normal, lightDir));
+        #else
+            float NdotL = max(dot(normal, lightDir), 0.0);
+        #endif
         return NdotL;
         return NdotL;
     }
     }
     // Point/spot light
     // Point/spot light
@@ -25,7 +29,11 @@ float GetVertexLight(int index, vec3 worldPos, vec3 normal)
         vec3 lightVec = (lightPos - worldPos) * invRange;
         vec3 lightVec = (lightPos - worldPos) * invRange;
         float lightDist = length(lightVec);
         float lightDist = length(lightVec);
         vec3 localDir = lightVec / lightDist;
         vec3 localDir = lightVec / lightDist;
-        float NdotL = max(dot(normal, localDir), 0.0);
+        #ifdef TRANSLUCENT
+            float NdotL = abs(dot(normal, localDir));
+        #else
+            float NdotL = max(dot(normal, localDir), 0.0);
+        #endif
         float atten = clamp(1.0 - lightDist * lightDist, 0.0, 1.0);
         float atten = clamp(1.0 - lightDist * lightDist, 0.0, 1.0);
         float spotEffect = dot(localDir, lightDir);
         float spotEffect = dot(localDir, lightDir);
         float spotAtten = clamp((spotEffect - cutoff) * invCutoff, 0.0, 1.0);
         float spotAtten = clamp((spotEffect - cutoff) * invCutoff, 0.0, 1.0);
@@ -66,8 +74,23 @@ float GetVertexLightVolumetric(int index, vec3 worldPos)
     #define NUMCASCADES 1
     #define NUMCASCADES 1
 #endif
 #endif
 
 
-vec4 GetShadowPos(int index, vec4 projWorldPos)
+vec4 GetShadowPos(int index, vec3 normal, vec4 projWorldPos)
 {
 {
+    #ifdef NORMALOFFSET
+        float normalOffsetScale[4];
+        normalOffsetScale[0] = cNormalOffsetScale.x;
+        normalOffsetScale[1] = cNormalOffsetScale.y;
+        normalOffsetScale[2] = cNormalOffsetScale.z;
+        normalOffsetScale[3] = cNormalOffsetScale.w;
+
+        #ifdef DIRLIGHT
+            float cosAngle = clamp(1.0 - dot(normal, cLightDir), 0.0, 1.0);
+        #else
+            float cosAngle = clamp(1.0 - dot(normal, normalize(cLightPos - projWorldPos.xyz)), 0.0, 1.0);
+        #endif
+        projWorldPos.xyz += cosAngle * normalOffsetScale[index] * normal;
+    #endif
+
     #if defined(DIRLIGHT)
     #if defined(DIRLIGHT)
         return projWorldPos * cLightMatrices[index];
         return projWorldPos * cLightMatrices[index];
     #elif defined(SPOTLIGHT)
     #elif defined(SPOTLIGHT)
@@ -85,12 +108,35 @@ float GetDiffuse(vec3 normal, vec3 worldPos, out vec3 lightDir)
 {
 {
     #ifdef DIRLIGHT
     #ifdef DIRLIGHT
         lightDir = cLightDirPS;
         lightDir = cLightDirPS;
-        return max(dot(normal, lightDir), 0.0);
+        #ifdef TRANSLUCENT
+            return abs(dot(normal, lightDir));
+        #else
+            return max(dot(normal, lightDir), 0.0);
+        #endif
     #else
     #else
         vec3 lightVec = (cLightPosPS.xyz - worldPos) * cLightPosPS.w;
         vec3 lightVec = (cLightPosPS.xyz - worldPos) * cLightPosPS.w;
         float lightDist = length(lightVec);
         float lightDist = length(lightVec);
         lightDir = lightVec / lightDist;
         lightDir = lightVec / lightDist;
-        return max(dot(normal, lightDir), 0.0) * texture2D(sLightRampMap, vec2(lightDist, 0.0)).r;
+        #ifdef TRANSLUCENT
+            return abs(dot(normal, lightDir)) * texture2D(sLightRampMap, vec2(lightDist, 0.0)).r;
+        #else
+            return max(dot(normal, lightDir), 0.0) * texture2D(sLightRampMap, vec2(lightDist, 0.0)).r;
+        #endif
+    #endif
+}
+
+float GetAtten(vec3 normal, vec3 worldPos, out vec3 lightDir)
+{
+     #ifdef DIRLIGHT
+        lightDir = cLightDirPS;
+        return clamp(dot(normal, lightDir), 0.0, 1.0);
+    #else
+        vec3 lightVec = (cLightPosPS.xyz - worldPos) * cLightPosPS.w;
+        float lightDist = length(lightVec);
+        float falloff = pow(clamp(1.0 - pow(lightDist / 1.0, 4.0), 0.0, 1.0), 2.0) / (pow(lightDist, 2.0) + 1.0);
+
+        lightDir = lightVec / vec3(lightDist, lightDist, lightDist);
+        return clamp(dot(normal, lightDir), 0.0, 1.0) * falloff;
     #endif
     #endif
 }
 }
 
 
@@ -107,7 +153,7 @@ float GetDiffuseVolumetric(vec3 worldPos)
 
 
 float GetSpecular(vec3 normal, vec3 eyeVec, vec3 lightDir, float specularPower)
 float GetSpecular(vec3 normal, vec3 eyeVec, vec3 lightDir, float specularPower)
 {
 {
-    vec3 halfVec = normalize(normalize(eyeVec) + lightDir);
+    vec3 halfVec = normalize(normalize(eyeVec) + lightDir);  
     return pow(max(dot(normal, halfVec), 0.0), specularPower);
     return pow(max(dot(normal, halfVec), 0.0), specularPower);
 }
 }
 
 
@@ -124,54 +170,88 @@ float GetIntensity(vec3 color)
     #define NUMCASCADES 1
     #define NUMCASCADES 1
 #endif
 #endif
 
 
+#ifdef VSM_SHADOW
+float ReduceLightBleeding(float min, float p_max)  
+{  
+    return clamp((p_max - min) / (1.0 - min), 0.0, 1.0);  
+}
+
+float Chebyshev(vec2 Moments, float depth)  
+{  
+    //One-tailed inequality valid if depth > Moments.x  
+    float p = float(depth <= Moments.x);  
+    //Compute variance.  
+    float Variance = Moments.y - (Moments.x * Moments.x); 
+
+    float minVariance = cVSMShadowParams.x;
+    Variance = max(Variance, minVariance);
+    //Compute probabilistic upper bound.  
+    float d = depth - Moments.x;  
+    float p_max = Variance / (Variance + d*d); 
+    // Prevent light bleeding
+    p_max = ReduceLightBleeding(cVSMShadowParams.y, p_max);
+
+    return max(p, p_max);
+}
+#endif
+
+#ifndef GL_ES
 float GetShadow(vec4 shadowPos)
 float GetShadow(vec4 shadowPos)
 {
 {
-    #ifndef GL_ES
-        #ifndef LQSHADOW
-            // Take four samples and average them
-            // Note: in case of sampling a point light cube shadow, we optimize out the w divide as it has already been performed
-            #ifndef POINTLIGHT
-                vec2 offsets = cShadowMapInvSize * shadowPos.w;
-            #else
-                vec2 offsets = cShadowMapInvSize;
-            #endif
-            #ifndef GL3
-                return cShadowIntensity.y + cShadowIntensity.x * (shadow2DProj(sShadowMap, shadowPos).r +
-                    shadow2DProj(sShadowMap, vec4(shadowPos.x + offsets.x, shadowPos.yzw)).r +
-                    shadow2DProj(sShadowMap, vec4(shadowPos.x, shadowPos.y + offsets.y, shadowPos.zw)).r +
-                    shadow2DProj(sShadowMap, vec4(shadowPos.xy + offsets.xy, shadowPos.zw)).r);
-            #else
-                return cShadowIntensity.y + cShadowIntensity.x * (textureProj(sShadowMap, shadowPos) +
-                    textureProj(sShadowMap, vec4(shadowPos.x + offsets.x, shadowPos.yzw)) +
-                    textureProj(sShadowMap, vec4(shadowPos.x, shadowPos.y + offsets.y, shadowPos.zw)) +
-                    textureProj(sShadowMap, vec4(shadowPos.xy + offsets.xy, shadowPos.zw)));
-            #endif
+    #if defined(SIMPLE_SHADOW)
+        // Take one sample
+        #ifndef GL3
+            float inLight = shadow2DProj(sShadowMap, shadowPos).r;
         #else
         #else
-            // Take one sample
-            #ifndef GL3
-                float inLight = shadow2DProj(sShadowMap, shadowPos).r;
-            #else
-                float inLight = textureProj(sShadowMap, shadowPos);
-            #endif
-            return cShadowIntensity.y + cShadowIntensity.x * inLight;
+            float inLight = textureProj(sShadowMap, shadowPos);
         #endif
         #endif
-    #else
-        #ifndef LQSHADOW
-            // Take four samples and average them
+        return cShadowIntensity.y + cShadowIntensity.x * inLight;
+    #elif defined(PCF_SHADOW)
+        // Take four samples and average them
+        // Note: in case of sampling a point light cube shadow, we optimize out the w divide as it has already been performed
+        #ifndef POINTLIGHT
             vec2 offsets = cShadowMapInvSize * shadowPos.w;
             vec2 offsets = cShadowMapInvSize * shadowPos.w;
-            vec4 inLight = vec4(
-                texture2DProj(sShadowMap, shadowPos).r * shadowPos.w > shadowPos.z,
-                texture2DProj(sShadowMap, vec4(shadowPos.x + offsets.x, shadowPos.yzw)).r * shadowPos.w > shadowPos.z,
-                texture2DProj(sShadowMap, vec4(shadowPos.x, shadowPos.y + offsets.y, shadowPos.zw)).r * shadowPos.w > shadowPos.z,
-                texture2DProj(sShadowMap, vec4(shadowPos.xy + offsets.xy, shadowPos.zw)).r * shadowPos.w > shadowPos.z
-            );
-            return cShadowIntensity.y + dot(inLight, vec4(cShadowIntensity.x));
         #else
         #else
-            // Take one sample
-            return cShadowIntensity.y + (texture2DProj(sShadowMap, shadowPos).r * shadowPos.w > shadowPos.z ? cShadowIntensity.x : 0.0);
+            vec2 offsets = cShadowMapInvSize;
+        #endif
+        #ifndef GL3
+            return cShadowIntensity.y + cShadowIntensity.x * (shadow2DProj(sShadowMap, shadowPos).r +
+                shadow2DProj(sShadowMap, vec4(shadowPos.x + offsets.x, shadowPos.yzw)).r +
+                shadow2DProj(sShadowMap, vec4(shadowPos.x, shadowPos.y + offsets.y, shadowPos.zw)).r +
+                shadow2DProj(sShadowMap, vec4(shadowPos.xy + offsets.xy, shadowPos.zw)).r);
+        #else
+            return cShadowIntensity.y + cShadowIntensity.x * (textureProj(sShadowMap, shadowPos) +
+                textureProj(sShadowMap, vec4(shadowPos.x + offsets.x, shadowPos.yzw)) +
+                textureProj(sShadowMap, vec4(shadowPos.x, shadowPos.y + offsets.y, shadowPos.zw)) +
+                textureProj(sShadowMap, vec4(shadowPos.xy + offsets.xy, shadowPos.zw)));
         #endif
         #endif
+    #elif defined(VSM_SHADOW)
+        vec2 samples = texture2D(sShadowMap, shadowPos.xy / shadowPos.w).rg; 
+        return cShadowIntensity.y + cShadowIntensity.x * Chebyshev(samples, shadowPos.z / shadowPos.w);
     #endif
     #endif
 }
 }
+#else
+float GetShadow(highp vec4 shadowPos)
+{
+    #if defined(SIMPLE_SHADOW)
+        // Take one sample
+        return cShadowIntensity.y + (texture2DProj(sShadowMap, shadowPos).r * shadowPos.w > shadowPos.z ? cShadowIntensity.x : 0.0);
+    #elif defined(PCF_SHADOW)
+        // Take four samples and average them
+        vec2 offsets = cShadowMapInvSize * shadowPos.w;
+        vec4 inLight = vec4(
+            texture2DProj(sShadowMap, shadowPos).r * shadowPos.w > shadowPos.z,
+            texture2DProj(sShadowMap, vec4(shadowPos.x + offsets.x, shadowPos.yzw)).r * shadowPos.w > shadowPos.z,
+            texture2DProj(sShadowMap, vec4(shadowPos.x, shadowPos.y + offsets.y, shadowPos.zw)).r * shadowPos.w > shadowPos.z,
+            texture2DProj(sShadowMap, vec4(shadowPos.xy + offsets.xy, shadowPos.zw)).r * shadowPos.w > shadowPos.z
+        );
+        return cShadowIntensity.y + dot(inLight, vec4(cShadowIntensity.x));
+    #elif defined(VSM_SHADOW)
+        vec2 samples = texture2D(sShadowMap, shadowPos.xy / shadowPos.w).rg; 
+        return cShadowIntensity.y + cShadowIntensity.x * Chebyshev(samples, shadowPos.z / shadowPos.w);
+    #endif
+}
+#endif
 
 
 #ifdef POINTLIGHT
 #ifdef POINTLIGHT
 float GetPointShadow(vec3 lightVec)
 float GetPointShadow(vec3 lightVec)
@@ -225,18 +305,30 @@ float GetDirShadow(const vec4 iShadowPos[NUMCASCADES], float depth)
 #endif
 #endif
 
 
 #ifndef GL_ES
 #ifndef GL_ES
-float GetDirShadowDeferred(vec4 projWorldPos, float depth)
+float GetDirShadowDeferred(vec4 projWorldPos, vec3 normal, float depth)
 {
 {
     vec4 shadowPos;
     vec4 shadowPos;
 
 
-    if (depth < cShadowSplits.x)
-        shadowPos = projWorldPos * cLightMatricesPS[0];
-    else if (depth < cShadowSplits.y)
-        shadowPos = projWorldPos * cLightMatricesPS[1];
-    else if (depth < cShadowSplits.z)
-        shadowPos = projWorldPos * cLightMatricesPS[2];
-    else
-        shadowPos = projWorldPos * cLightMatricesPS[3];
+    #ifdef NORMALOFFSET
+        float cosAngle = clamp(1.0 - dot(normal, cLightDirPS), 0.0, 1.0);
+        if (depth < cShadowSplits.x)
+            shadowPos = vec4(projWorldPos.xyz + cosAngle * cNormalOffsetScalePS.x * normal, 1.0) * cLightMatricesPS[0];
+        else if (depth < cShadowSplits.y)
+            shadowPos = vec4(projWorldPos.xyz + cosAngle * cNormalOffsetScalePS.y * normal, 1.0) * cLightMatricesPS[1];
+        else if (depth < cShadowSplits.z)
+            shadowPos = vec4(projWorldPos.xyz + cosAngle * cNormalOffsetScalePS.z * normal, 1.0) * cLightMatricesPS[2];
+        else
+            shadowPos = vec4(projWorldPos.xyz + cosAngle * cNormalOffsetScalePS.w * normal, 1.0) * cLightMatricesPS[3];
+    #else
+        if (depth < cShadowSplits.x)
+            shadowPos = projWorldPos * cLightMatricesPS[0];
+        else if (depth < cShadowSplits.y)
+            shadowPos = projWorldPos * cLightMatricesPS[1];
+        else if (depth < cShadowSplits.z)
+            shadowPos = projWorldPos * cLightMatricesPS[2];
+        else
+            shadowPos = projWorldPos * cLightMatricesPS[3];
+    #endif
 
 
     return GetDirShadowFade(GetShadow(shadowPos), depth);
     return GetDirShadowFade(GetShadow(shadowPos), depth);
 }
 }
@@ -255,16 +347,23 @@ float GetShadow(vec4 iShadowPos[NUMCASCADES], float depth)
 }
 }
 
 
 #ifndef GL_ES
 #ifndef GL_ES
-float GetShadowDeferred(vec4 projWorldPos, float depth)
+float GetShadowDeferred(vec4 projWorldPos, vec3 normal, float depth)
 {
 {
-    #if defined(DIRLIGHT)
-        return GetDirShadowDeferred(projWorldPos, depth);
-    #elif defined(SPOTLIGHT)
-        vec4 shadowPos = projWorldPos * cLightMatricesPS[1];
-        return GetShadow(shadowPos);
+    #ifdef DIRLIGHT
+        return GetDirShadowDeferred(projWorldPos, normal, depth);
     #else
     #else
-        vec3 shadowPos = projWorldPos.xyz - cLightPosPS.xyz;
-        return GetPointShadow(shadowPos);
+        #ifdef NORMALOFFSET
+            float cosAngle = clamp(1.0 - dot(normal, normalize(cLightPosPS - projWorldPos.xyz)), 0.0, 1.0);
+            projWorldPos.xyz += cosAngle * cNormalOffsetScalePS.x * normal;
+        #endif
+
+        #ifdef SPOTLIGHT
+            vec4 shadowPos = projWorldPos * cLightMatricesPS[1];
+            return GetShadow(shadowPos);
+        #else
+            vec3 shadowPos = projWorldPos.xyz - cLightPosPS.xyz;
+            return GetPointShadow(shadowPos);
+        #endif
     #endif
     #endif
 }
 }
 #endif
 #endif

+ 6 - 2
Resources/CoreData/Shaders/GLSL/LitParticle.glsl

@@ -11,7 +11,11 @@ varying vec4 vWorldPos;
 #endif
 #endif
 #ifdef PERPIXEL
 #ifdef PERPIXEL
     #ifdef SHADOW
     #ifdef SHADOW
-        varying vec4 vShadowPos[NUMCASCADES];
+        #ifndef GL_ES
+            varying vec4 vShadowPos[NUMCASCADES];
+        #else
+            varying highp vec4 vShadowPos[NUMCASCADES];
+        #endif
     #endif
     #endif
     #ifdef SPOTLIGHT
     #ifdef SPOTLIGHT
         varying vec4 vSpotPos;
         varying vec4 vSpotPos;
@@ -42,7 +46,7 @@ void VS()
         #ifdef SHADOW
         #ifdef SHADOW
             // Shadow projection: transform from world space to shadow space
             // Shadow projection: transform from world space to shadow space
             for (int i = 0; i < NUMCASCADES; i++)
             for (int i = 0; i < NUMCASCADES; i++)
-                vShadowPos[i] = GetShadowPos(i, projWorldPos);
+                vShadowPos[i] = GetShadowPos(i, vec3(0, 0, 0), projWorldPos);
         #endif
         #endif
 
 
         #ifdef SPOTLIGHT
         #ifdef SPOTLIGHT

+ 11 - 7
Resources/CoreData/Shaders/GLSL/LitSolid.glsl

@@ -18,7 +18,11 @@ varying vec4 vWorldPos;
 #endif
 #endif
 #ifdef PERPIXEL
 #ifdef PERPIXEL
     #ifdef SHADOW
     #ifdef SHADOW
-        varying vec4 vShadowPos[NUMCASCADES];
+        #ifndef GL_ES
+            varying vec4 vShadowPos[NUMCASCADES];
+        #else
+            varying highp vec4 vShadowPos[NUMCASCADES];
+        #endif
     #endif
     #endif
     #ifdef SPOTLIGHT
     #ifdef SPOTLIGHT
         varying vec4 vSpotPos;
         varying vec4 vSpotPos;
@@ -65,12 +69,12 @@ void VS()
         #ifdef SHADOW
         #ifdef SHADOW
             // Shadow projection: transform from world space to shadow space
             // Shadow projection: transform from world space to shadow space
             for (int i = 0; i < NUMCASCADES; i++)
             for (int i = 0; i < NUMCASCADES; i++)
-                vShadowPos[i] = GetShadowPos(i, projWorldPos);
+                vShadowPos[i] = GetShadowPos(i, vNormal, projWorldPos);
         #endif
         #endif
 
 
         #ifdef SPOTLIGHT
         #ifdef SPOTLIGHT
             // Spotlight projection: transform from world space to projector texture coordinates
             // Spotlight projection: transform from world space to projector texture coordinates
-            vSpotPos =  projWorldPos * cLightMatrices[0];
+            vSpotPos = projWorldPos * cLightMatrices[0];
         #endif
         #endif
     
     
         #ifdef POINTLIGHT
         #ifdef POINTLIGHT
@@ -82,7 +86,7 @@ void VS()
             // If using lightmap, disregard zone ambient light
             // If using lightmap, disregard zone ambient light
             // If using AO, calculate ambient in the PS
             // If using AO, calculate ambient in the PS
             vVertexLight = vec3(0.0, 0.0, 0.0);
             vVertexLight = vec3(0.0, 0.0, 0.0);
-            vTexCoord2 = iTexCoord2;
+            vTexCoord2 = iTexCoord1;
         #else
         #else
             vVertexLight = GetAmbient(GetZonePos(worldPos));
             vVertexLight = GetAmbient(GetZonePos(worldPos));
         #endif
         #endif
@@ -168,7 +172,7 @@ void PS()
         #endif
         #endif
 
 
         #ifdef AMBIENT
         #ifdef AMBIENT
-            finalColor += cAmbientColor * diffColor.rgb;
+            finalColor += cAmbientColor.rgb * diffColor.rgb;
             finalColor += cMatEmissiveColor;
             finalColor += cMatEmissiveColor;
             gl_FragColor = vec4(GetFog(finalColor, fogFactor), diffColor.a);
             gl_FragColor = vec4(GetFog(finalColor, fogFactor), diffColor.a);
         #else
         #else
@@ -188,7 +192,7 @@ void PS()
         vec3 finalColor = vVertexLight * diffColor.rgb;
         vec3 finalColor = vVertexLight * diffColor.rgb;
         #ifdef AO
         #ifdef AO
             // If using AO, the vertex light ambient is black, calculate occluded ambient here
             // If using AO, the vertex light ambient is black, calculate occluded ambient here
-            finalColor += texture2D(sEmissiveMap, vTexCoord2).rgb * cAmbientColor * diffColor.rgb;
+            finalColor += texture2D(sEmissiveMap, vTexCoord2).rgb * cAmbientColor.rgb * diffColor.rgb;
         #endif
         #endif
 
 
         #ifdef ENVCUBEMAP
         #ifdef ENVCUBEMAP
@@ -212,7 +216,7 @@ void PS()
         vec3 finalColor = vVertexLight * diffColor.rgb;
         vec3 finalColor = vVertexLight * diffColor.rgb;
         #ifdef AO
         #ifdef AO
             // If using AO, the vertex light ambient is black, calculate occluded ambient here
             // If using AO, the vertex light ambient is black, calculate occluded ambient here
-            finalColor += texture2D(sEmissiveMap, vTexCoord2).rgb * cAmbientColor * diffColor.rgb;
+            finalColor += texture2D(sEmissiveMap, vTexCoord2).rgb * cAmbientColor.rgb * diffColor.rgb;
         #endif
         #endif
         
         
         #ifdef MATERIAL
         #ifdef MATERIAL

+ 33 - 0
Resources/CoreData/Shaders/GLSL/PBR.glsl

@@ -0,0 +1,33 @@
+#include "BRDF.glsl"
+#ifdef COMPILEPS
+
+	//Return the PBR BRDF value
+	// lightDir  = the vector to the light
+	// lightVev  = normalised lightDir
+	// toCamera  = vector to the camera
+	// normal    = surface normal of the pixel
+	// roughness = roughness of the pixel
+	// diffColor = the rgb color of the pixel
+	// specColor = the rgb specular color of the pixel
+	vec3 GetBRDF(vec3 lightDir, vec3 lightVec, vec3 toCamera, vec3 normal, float roughness, vec3 diffColor, vec3 specColor)
+	{
+        vec3 Hn = normalize(toCamera + lightDir);
+        float vdh = clamp((dot(toCamera, Hn)), M_EPSILON, 1.0);
+        float ndh = clamp((dot(normal, Hn)), M_EPSILON, 1.0);
+        float ndl = clamp((dot(normal, lightVec)), M_EPSILON, 1.0);
+        float ndv = clamp((dot(normal, toCamera)), M_EPSILON, 1.0);
+
+        vec3 diffuseFactor = Diffuse(diffColor, roughness, ndv, ndl, vdh);
+        vec3 specularFactor = vec3(0.0, 0.0, 0.0);
+
+        #ifdef SPECULAR
+            vec3 fresnelTerm = Fresnel(specColor, vdh) ;
+            float distTerm = Distribution(ndh, roughness);
+            float visTerm = Visibility(ndl, ndv, roughness);
+
+            specularFactor = fresnelTerm * distTerm * visTerm  / M_PI;
+        #endif
+
+        return diffuseFactor + specularFactor;
+	}
+#endif

+ 117 - 0
Resources/CoreData/Shaders/GLSL/PBRDeferred.glsl

@@ -0,0 +1,117 @@
+#include "Uniforms.glsl"
+#include "Samplers.glsl"
+#include "Transform.glsl"
+#include "ScreenPos.glsl"
+#include "Lighting.glsl"
+#include "Constants.glsl"
+#include "PBR.glsl"
+#line 40007
+
+#ifdef DIRLIGHT
+    varying vec2 vScreenPos;
+#else
+    varying vec4 vScreenPos;
+#endif
+varying vec3 vFarRay;
+#ifdef ORTHO
+    varying vec3 vNearRay;
+#endif
+
+void VS()
+{
+    mat4 modelMatrix = iModelMatrix;
+    vec3 worldPos = GetWorldPos(modelMatrix);
+    gl_Position = GetClipPos(worldPos);
+    #ifdef DIRLIGHT
+        vScreenPos = GetScreenPosPreDiv(gl_Position);
+        vFarRay = GetFarRay(gl_Position);
+        #ifdef ORTHO
+            vNearRay = GetNearRay(gl_Position);
+        #endif
+    #else
+        vScreenPos = GetScreenPos(gl_Position);
+        vFarRay = GetFarRay(gl_Position) * gl_Position.w;
+        #ifdef ORTHO
+            vNearRay = GetNearRay(gl_Position) * gl_Position.w;
+        #endif
+    #endif
+}
+
+
+void PS()
+{
+    // If rendering a directional light quad, optimize out the w divide
+    #ifdef DIRLIGHT
+        vec4 depthInput = texture2D(sDepthBuffer, vScreenPos);
+        #ifdef HWDEPTH
+            float depth = ReconstructDepth(depthInput.r);
+        #else
+            float depth = DecodeDepth(depthInput.rgb);
+        #endif
+        #ifdef ORTHO
+            vec3 worldPos = mix(vNearRay, vFarRay, depth);
+        #else
+            vec3 worldPos = vFarRay * depth;
+        #endif
+        vec4 albedoInput = texture2D(sAlbedoBuffer, vScreenPos);
+        vec4 normalInput = texture2D(sNormalBuffer, vScreenPos);
+        vec4 specularInput = texture2D(sSpecMap, vScreenPos);
+    #else
+        vec4 depthInput = texture2DProj(sDepthBuffer, vScreenPos);
+        #ifdef HWDEPTH
+            float depth = ReconstructDepth(depthInput.r);
+        #else
+            float depth = DecodeDepth(depthInput.rgb);
+        #endif
+        #ifdef ORTHO
+            vec3 worldPos = mix(vNearRay, vFarRay, depth) / vScreenPos.w;
+        #else
+            vec3 worldPos = vFarRay * depth / vScreenPos.w;
+        #endif
+        vec4 albedoInput = texture2DProj(sAlbedoBuffer, vScreenPos);
+        vec4 normalInput = texture2DProj(sNormalBuffer, vScreenPos);
+        vec4 specularInput = texture2DProj(sSpecMap, vScreenPos);
+    #endif
+
+    // Position acquired via near/far ray is relative to camera. Bring position to world space
+    vec3 eyeVec = -worldPos;
+    worldPos += cCameraPosPS;
+
+    vec3 normal = normalInput.rgb;
+    float roughness = length(normal);
+    normal = normalize(normal);
+
+    vec3 specColor = specularInput.rgb;
+
+    vec4 projWorldPos = vec4(worldPos, 1.0);
+
+    vec3 lightDir;
+    float atten = GetAtten(normal, worldPos, lightDir);
+
+    float shadow = 1;
+    #ifdef SHADOW
+        shadow *= GetShadowDeferred(projWorldPos, normal, depth);
+    #endif
+
+    #if defined(SPOTLIGHT)
+        vec4 spotPos = projWorldPos * cLightMatricesPS[0];
+        vec3 lightColor = spotPos.w > 0.0 ? texture2DProj(sLightSpotMap, spotPos).rgb * cLightColor.rgb : vec3(0.0);
+    #elif defined(CUBEMASK)
+        mat3 lightVecRot = mat3(cLightMatricesPS[0][0].xyz, cLightMatricesPS[0][1].xyz, cLightMatricesPS[0][2].xyz);
+        vec3 lightColor = textureCube(sLightCubeMap, (worldPos - cLightPosPS.xyz) * lightVecRot).rgb * cLightColor.rgb;
+    #else
+        vec3 lightColor = cLightColor.rgb;
+    #endif
+
+    vec3 toCamera = normalize(eyeVec);
+    vec3 lightVec = normalize(lightDir);
+
+    float ndl = clamp(abs(dot(normal, lightVec)), M_EPSILON, 1.0);
+
+
+    vec3 BRDF = GetBRDF(lightDir, lightVec, toCamera, normal, roughness, albedoInput.rgb, specColor);
+
+    gl_FragColor.a = 1.0;
+    gl_FragColor.rgb = BRDF * lightColor * (atten * shadow) / M_PI;
+
+}

+ 252 - 0
Resources/CoreData/Shaders/GLSL/PBRLitSolid.glsl

@@ -0,0 +1,252 @@
+#include "Uniforms.glsl"
+#include "Samplers.glsl"
+#include "Transform.glsl"
+#include "ScreenPos.glsl"
+#include "Lighting.glsl"
+#include "Constants.glsl"
+#include "Fog.glsl"
+#include "PBR.glsl"
+#include "IBL.glsl"
+#line 30010
+
+#if defined(NORMALMAP) || defined(IBL)
+    varying vec4 vTexCoord;
+    varying vec4 vTangent;
+#else
+    varying vec2 vTexCoord;
+#endif
+varying vec3 vNormal;
+varying vec4 vWorldPos;
+#ifdef VERTEXCOLOR
+    varying vec4 vColor;
+#endif
+#ifdef PERPIXEL
+    #ifdef SHADOW
+        #ifndef GL_ES
+            varying vec4 vShadowPos[NUMCASCADES];
+        #else
+            varying highp vec4 vShadowPos[NUMCASCADES];
+        #endif
+    #endif
+    #ifdef SPOTLIGHT
+        varying vec4 vSpotPos;
+    #endif
+    #ifdef POINTLIGHT
+        varying vec3 vCubeMaskVec;
+    #endif
+#else
+    varying vec3 vVertexLight;
+    varying vec4 vScreenPos;
+    #ifdef ENVCUBEMAP
+        varying vec3 vReflectionVec;
+    #endif
+    #if defined(LIGHTMAP) || defined(AO)
+        varying vec2 vTexCoord2;
+    #endif
+#endif
+
+void VS()
+{
+    mat4 modelMatrix = iModelMatrix;
+    vec3 worldPos = GetWorldPos(modelMatrix);
+    gl_Position = GetClipPos(worldPos);
+    vNormal = GetWorldNormal(modelMatrix);
+    vWorldPos = vec4(worldPos, GetDepth(gl_Position));
+
+    #ifdef VERTEXCOLOR
+        vColor = iColor;
+    #endif
+
+    #if defined(NORMALMAP) || defined(DIRBILLBOARD) || defined(IBL)
+        vec3 tangent = GetWorldTangent(modelMatrix);
+        vec3 bitangent = cross(tangent, vNormal) * iTangent.w;
+        vTexCoord = vec4(GetTexCoord(iTexCoord), bitangent.xy);
+        vTangent = vec4(tangent, bitangent.z);
+    #else
+        vTexCoord = GetTexCoord(iTexCoord);
+    #endif
+
+    #ifdef PERPIXEL
+        // Per-pixel forward lighting
+        vec4 projWorldPos = vec4(worldPos, 1.0);
+
+        #ifdef SHADOW
+            // Shadow projection: transform from world space to shadow space
+            for (int i = 0; i < NUMCASCADES; i++)
+                vShadowPos[i] = GetShadowPos(i, vNormal, projWorldPos);
+        #endif
+
+        #ifdef SPOTLIGHT
+            // Spotlight projection: transform from world space to projector texture coordinates
+            vSpotPos = projWorldPos * cLightMatrices[0];
+        #endif
+
+        #ifdef POINTLIGHT
+            vCubeMaskVec = (worldPos - cLightPos.xyz) * mat3(cLightMatrices[0][0].xyz, cLightMatrices[0][1].xyz, cLightMatrices[0][2].xyz);
+        #endif
+    #else
+        // Ambient & per-vertex lighting
+        #if defined(LIGHTMAP) || defined(AO)
+            // If using lightmap, disregard zone ambient light
+            // If using AO, calculate ambient in the PS
+            vVertexLight = vec3(0.0, 0.0, 0.0);
+            vTexCoord2 = iTexCoord1;
+        #else
+            vVertexLight = GetAmbient(GetZonePos(worldPos));
+        #endif
+
+        #ifdef NUMVERTEXLIGHTS
+            for (int i = 0; i < NUMVERTEXLIGHTS; ++i)
+                vVertexLight += GetVertexLight(i, worldPos, vNormal) * cVertexLights[i * 3].rgb;
+        #endif
+
+        vScreenPos = GetScreenPos(gl_Position);
+
+        #ifdef ENVCUBEMAP
+            vReflectionVec = worldPos - cCameraPos;
+        #endif
+    #endif
+}
+
+void PS()
+{
+    // Get material diffuse albedo
+    #ifdef DIFFMAP
+        vec4 diffInput = texture2D(sDiffMap, vTexCoord.xy);
+        #ifdef ALPHAMASK
+            if (diffInput.a < 0.5)
+                discard;
+        #endif
+        vec4 diffColor = cMatDiffColor * diffInput;
+    #else
+        vec4 diffColor = cMatDiffColor;
+    #endif
+
+    #ifdef VERTEXCOLOR
+        diffColor *= vColor;
+    #endif
+
+    #ifdef METALLIC
+        vec4 roughMetalSrc = texture2D(sSpecMap, vTexCoord.xy);
+
+        float roughness = roughMetalSrc.r + cRoughness;
+        float metalness = roughMetalSrc.g + cMetallic;
+    #else
+        float roughness = cRoughness;
+        float metalness = cMetallic;
+    #endif
+
+    roughness *= roughness;
+
+    roughness = clamp(roughness, ROUGHNESS_FLOOR, 1.0);
+    metalness = clamp(metalness, METALNESS_FLOOR, 1.0);
+
+    vec3 specColor = mix(0.08 * cMatSpecColor.rgb, diffColor.rgb, metalness);
+    diffColor.rgb = diffColor.rgb - diffColor.rgb * metalness;
+
+    // Get normal
+    #if defined(NORMALMAP) || defined(DIRBILLBOARD) || defined(IBL)
+        vec3 tangent = vTangent.xyz;
+        vec3 bitangent = vec3(vTexCoord.zw, vTangent.w);
+        mat3 tbn = mat3(tangent, bitangent, vNormal);
+    #endif
+
+    #ifdef NORMALMAP
+        vec3 nn = DecodeNormal(texture2D(sNormalMap, vTexCoord.xy));
+        //nn.rg *= 2.0;
+        vec3 normal = normalize(tbn * nn);
+    #else
+        vec3 normal = normalize(vNormal);
+    #endif
+
+    // Get fog factor
+    #ifdef HEIGHTFOG
+        float fogFactor = GetHeightFogFactor(vWorldPos.w, vWorldPos.y);
+    #else
+        float fogFactor = GetFogFactor(vWorldPos.w);
+    #endif
+
+    #if defined(PERPIXEL)
+        // Per-pixel forward lighting
+        vec3 lightColor;
+        vec3 lightDir;
+        vec3 finalColor;
+
+        float atten = GetAtten(normal, vWorldPos.xyz, lightDir);
+        float shadow = 1.0;
+        #ifdef SHADOW
+            shadow = GetShadow(vShadowPos, vWorldPos.w);
+        #endif
+
+        #if defined(SPOTLIGHT)
+            lightColor = vSpotPos.w > 0.0 ? texture2DProj(sLightSpotMap, vSpotPos).rgb * cLightColor.rgb : vec3(0.0, 0.0, 0.0);
+        #elif defined(CUBEMASK)
+            lightColor = textureCube(sLightCubeMap, vCubeMaskVec).rgb * cLightColor.rgb;
+        #else
+            lightColor = cLightColor.rgb;
+        #endif
+        vec3 toCamera = normalize(cCameraPosPS - vWorldPos.xyz);
+        vec3 lightVec = normalize(lightDir);
+        float ndl = clamp((dot(normal, lightVec)), M_EPSILON, 1.0);
+
+        vec3 BRDF = GetBRDF(lightDir, lightVec, toCamera, normal, roughness, diffColor.rgb, specColor);
+
+        finalColor.rgb = BRDF * lightColor * (atten * shadow) / M_PI;
+
+        #ifdef AMBIENT
+            finalColor += cAmbientColor.rgb * diffColor.rgb;
+            finalColor += cMatEmissiveColor;
+            gl_FragColor = vec4(GetFog(finalColor, fogFactor), diffColor.a);
+        #else
+            gl_FragColor = vec4(GetLitFog(finalColor, fogFactor), diffColor.a);
+        #endif
+    #elif defined(DEFERRED)
+        // Fill deferred G-buffer
+        const vec3 spareData = vec3(0,0,0); // Can be used to pass more data to deferred renderer
+        gl_FragData[0] = vec4(specColor, spareData.r);
+        gl_FragData[1] = vec4(diffColor.rgb, spareData.g);
+        gl_FragData[2] = vec4(normal * roughness, spareData.b);
+        gl_FragData[3] = vec4(EncodeDepth(vWorldPos.w), 0.0);
+    #else
+        // Ambient & per-vertex lighting
+        vec3 finalColor = vVertexLight * diffColor.rgb;
+        #ifdef AO
+            // If using AO, the vertex light ambient is black, calculate occluded ambient here
+            finalColor += texture2D(sEmissiveMap, vTexCoord2).rgb * cAmbientColor.rgb * diffColor.rgb;
+        #endif
+
+        #ifdef MATERIAL
+            // Add light pre-pass accumulation result
+            // Lights are accumulated at half intensity. Bring back to full intensity now
+            vec4 lightInput = 2.0 * texture2DProj(sLightBuffer, vScreenPos);
+            vec3 lightSpecColor = lightInput.a * lightInput.rgb / max(GetIntensity(lightInput.rgb), 0.001);
+
+            finalColor += lightInput.rgb * diffColor.rgb + lightSpecColor * specColor;
+        #endif
+
+        vec3 toCamera = normalize(vWorldPos.xyz - cCameraPosPS);
+        vec3 reflection = normalize(reflect(toCamera, normal));
+
+        vec3 cubeColor = vVertexLight.rgb;
+
+        #ifdef IBL
+          vec3 iblColor = ImageBasedLighting(reflection, tangent, bitangent, normal, toCamera, diffColor.rgb, specColor.rgb, roughness, cubeColor);
+          float gamma = 0.0;
+          finalColor.rgb += iblColor;
+        #endif
+
+        #ifdef ENVCUBEMAP
+            finalColor += cMatEnvMapColor * textureCube(sEnvCubeMap, reflect(vReflectionVec, normal)).rgb;
+        #endif
+        #ifdef LIGHTMAP
+            finalColor += texture2D(sEmissiveMap, vTexCoord2).rgb * diffColor.rgb;
+        #endif
+        #ifdef EMISSIVEMAP
+            finalColor += cMatEmissiveColor * texture2D(sEmissiveMap, vTexCoord.xy).rgb;
+        #else
+            finalColor += cMatEmissiveColor;
+        #endif
+
+        gl_FragColor = vec4(GetFog(finalColor, fogFactor), diffColor.a);
+    #endif
+}

+ 0 - 6
Resources/CoreData/Shaders/GLSL/PostProcess.glsl

@@ -11,13 +11,7 @@ vec2 Noise(vec2 coord)
 // Adapted: http://callumhay.blogspot.com/2010/09/gaussian-blur-shader-glsl.html
 // Adapted: http://callumhay.blogspot.com/2010/09/gaussian-blur-shader-glsl.html
 vec4 GaussianBlur(int blurKernelSize, vec2 blurDir, vec2 blurRadius, float sigma, sampler2D texSampler, vec2 texCoord)
 vec4 GaussianBlur(int blurKernelSize, vec2 blurDir, vec2 blurRadius, float sigma, sampler2D texSampler, vec2 texCoord)
 {
 {
-
-#if defined(GL_ES)
-    // hardcoded for GL_ES to avoid loop comparison issue below
-    const int blurKernelSizeHalfSize = 3 / 2;
-#else
     int blurKernelSizeHalfSize = blurKernelSize / 2;
     int blurKernelSizeHalfSize = blurKernelSize / 2;
-#endif
 
 
     // Incremental Gaussian Coefficent Calculation (See GPU Gems 3 pp. 877 - 889)
     // Incremental Gaussian Coefficent Calculation (See GPU Gems 3 pp. 877 - 889)
     vec3 gaussCoeff;
     vec3 gaussCoeff;

+ 6 - 2
Resources/CoreData/Shaders/GLSL/PrepassLight.glsl

@@ -63,6 +63,10 @@ void PS()
         vec4 normalInput = texture2DProj(sNormalBuffer, vScreenPos);
         vec4 normalInput = texture2DProj(sNormalBuffer, vScreenPos);
     #endif
     #endif
 
 
+    // Position acquired via near/far ray is relative to camera. Bring position to world space
+    vec3 eyeVec = -worldPos;
+    worldPos += cCameraPosPS;
+
     vec3 normal = normalize(normalInput.rgb * 2.0 - 1.0);
     vec3 normal = normalize(normalInput.rgb * 2.0 - 1.0);
     vec4 projWorldPos = vec4(worldPos, 1.0);
     vec4 projWorldPos = vec4(worldPos, 1.0);
     vec3 lightColor;
     vec3 lightColor;
@@ -72,7 +76,7 @@ void PS()
     float diff = 0.5 * GetDiffuse(normal, worldPos, lightDir);
     float diff = 0.5 * GetDiffuse(normal, worldPos, lightDir);
 
 
     #ifdef SHADOW
     #ifdef SHADOW
-        diff *= GetShadowDeferred(projWorldPos, depth);
+        diff *= GetShadowDeferred(projWorldPos, normal, depth);
     #endif
     #endif
     
     
     #if defined(SPOTLIGHT)
     #if defined(SPOTLIGHT)
@@ -86,7 +90,7 @@ void PS()
     #endif
     #endif
 
 
     #ifdef SPECULAR
     #ifdef SPECULAR
-        float spec = lightColor.g * GetSpecular(normal, -worldPos, lightDir, normalInput.a * 255.0);
+        float spec = lightColor.g * GetSpecular(normal, eyeVec, lightDir, normalInput.a * 255.0);
         gl_FragColor = diff * vec4(lightColor, spec * cLightColor.a);
         gl_FragColor = diff * vec4(lightColor, spec * cLightColor.a);
     #else
     #else
         gl_FragColor = diff * vec4(lightColor, 0.0);
         gl_FragColor = diff * vec4(lightColor, 0.0);

+ 6 - 2
Resources/CoreData/Shaders/GLSL/Samplers.glsl

@@ -15,13 +15,17 @@ uniform samplerCube sLightCubeMap;
     uniform sampler2D sNormalBuffer;
     uniform sampler2D sNormalBuffer;
     uniform sampler2D sDepthBuffer;
     uniform sampler2D sDepthBuffer;
     uniform sampler2D sLightBuffer;
     uniform sampler2D sLightBuffer;
-    uniform sampler2DShadow sShadowMap;
+    #ifdef VSM_SHADOW
+        uniform sampler2D sShadowMap;
+    #else
+        uniform sampler2DShadow sShadowMap;
+    #endif
     uniform samplerCube sFaceSelectCubeMap;
     uniform samplerCube sFaceSelectCubeMap;
     uniform samplerCube sIndirectionCubeMap;
     uniform samplerCube sIndirectionCubeMap;
     uniform samplerCube sZoneCubeMap;
     uniform samplerCube sZoneCubeMap;
     uniform sampler3D sZoneVolumeMap;
     uniform sampler3D sZoneVolumeMap;
 #else
 #else
-    uniform sampler2D sShadowMap;
+    uniform highp sampler2D sShadowMap;
 #endif
 #endif
 
 
 #ifdef GL3
 #ifdef GL3

+ 10 - 3
Resources/CoreData/Shaders/GLSL/ScreenPos.glsl

@@ -1,4 +1,11 @@
 #ifdef COMPILEVS
 #ifdef COMPILEVS
+mat3 GetCameraRot()
+{
+    return mat3(cViewInv[0][0], cViewInv[0][1], cViewInv[0][2],
+        cViewInv[1][0], cViewInv[1][1], cViewInv[1][2],
+        cViewInv[2][0], cViewInv[2][1], cViewInv[2][2]);
+}
+
 vec4 GetScreenPos(vec4 clipPos)
 vec4 GetScreenPos(vec4 clipPos)
 {
 {
     return vec4(
     return vec4(
@@ -36,7 +43,7 @@ vec3 GetFarRay(vec4 clipPos)
         clipPos.y / clipPos.w * cFrustumSize.y,
         clipPos.y / clipPos.w * cFrustumSize.y,
         cFrustumSize.z);
         cFrustumSize.z);
 
 
-    return viewRay * cCameraRot;
+    return viewRay * GetCameraRot();
 }
 }
 
 
 vec3 GetNearRay(vec4 clipPos)
 vec3 GetNearRay(vec4 clipPos)
@@ -45,7 +52,7 @@ vec3 GetNearRay(vec4 clipPos)
         clipPos.x / clipPos.w * cFrustumSize.x,
         clipPos.x / clipPos.w * cFrustumSize.x,
         clipPos.y / clipPos.w * cFrustumSize.y,
         clipPos.y / clipPos.w * cFrustumSize.y,
         0.0);
         0.0);
-    
-    return (viewRay * cCameraRot) * cDepthMode.x;
+
+    return (viewRay * GetCameraRot()) * cDepthMode.x;
 }
 }
 #endif
 #endif

+ 17 - 4
Resources/CoreData/Shaders/GLSL/Shadow.glsl

@@ -2,23 +2,36 @@
 #include "Samplers.glsl"
 #include "Samplers.glsl"
 #include "Transform.glsl"
 #include "Transform.glsl"
 
 
-varying vec2 vTexCoord;
+#ifdef VSM_SHADOW
+    varying vec3 vTexCoord;
+#else
+    varying vec2 vTexCoord;
+#endif
 
 
 void VS()
 void VS()
 {
 {
     mat4 modelMatrix = iModelMatrix;
     mat4 modelMatrix = iModelMatrix;
     vec3 worldPos = GetWorldPos(modelMatrix);
     vec3 worldPos = GetWorldPos(modelMatrix);
     gl_Position = GetClipPos(worldPos);
     gl_Position = GetClipPos(worldPos);
-    vTexCoord = GetTexCoord(iTexCoord);
+    #ifdef VSM_SHADOW
+        vTexCoord = vec3(GetTexCoord(iTexCoord), gl_Position.z / gl_Position.w * 0.5 + 0.5);
+    #else
+        vTexCoord = GetTexCoord(iTexCoord);
+    #endif
 }
 }
 
 
 void PS()
 void PS()
 {
 {
     #ifdef ALPHAMASK
     #ifdef ALPHAMASK
-        float alpha = texture2D(sDiffMap, vTexCoord).a;
+        float alpha = texture2D(sDiffMap, vTexCoord.xy).a;
         if (alpha < 0.5)
         if (alpha < 0.5)
             discard;
             discard;
     #endif
     #endif
 
 
-    gl_FragColor = vec4(1.0);
+    #ifdef VSM_SHADOW
+        float depth = vTexCoord.z;
+        gl_FragColor = vec4(depth, depth * depth, 1.0, 1.0);
+    #else
+        gl_FragColor = vec4(1.0);
+    #endif
 }
 }

+ 34 - 0
Resources/CoreData/Shaders/GLSL/ShadowBlur.glsl

@@ -0,0 +1,34 @@
+#include "Uniforms.glsl"
+#include "Samplers.glsl"
+#include "Transform.glsl"
+#include "ScreenPos.glsl"
+
+#ifdef COMPILEPS
+uniform vec2 cBlurOffsets;
+#endif
+
+varying vec2 vScreenPos;
+
+void VS()
+{
+    mat4 modelMatrix = iModelMatrix;
+    vec3 worldPos = GetWorldPos(modelMatrix);
+    gl_Position = GetClipPos(worldPos);
+    vScreenPos = GetScreenPosPreDiv(gl_Position);
+}
+
+void PS()
+{
+    vec2 color = vec2(0.0);
+    
+    color += 0.015625 * texture2D(sDiffMap, vScreenPos + vec2(-3.0) * cBlurOffsets).rg;
+    color += 0.09375 * texture2D(sDiffMap, vScreenPos + vec2(-2.0) * cBlurOffsets).rg;
+    color += 0.234375 * texture2D(sDiffMap, vScreenPos + vec2(-1.0) * cBlurOffsets).rg;
+    color += 0.3125 * texture2D(sDiffMap, vScreenPos).rg;
+    color += 0.234375 * texture2D(sDiffMap, vScreenPos + vec2(1.0) * cBlurOffsets).rg;
+    color += 0.09375 * texture2D(sDiffMap, vScreenPos + vec2(2.0) * cBlurOffsets).rg;
+    color += 0.015625 * texture2D(sDiffMap, vScreenPos + vec2(3.0) * cBlurOffsets).rg;
+    
+    gl_FragColor = vec4(color, 0.0, 0.0);
+}
+

+ 5 - 7
Resources/CoreData/Shaders/GLSL/Skybox.glsl

@@ -9,17 +9,15 @@ void VS()
     mat4 modelMatrix = iModelMatrix;
     mat4 modelMatrix = iModelMatrix;
     vec3 worldPos = GetWorldPos(modelMatrix);
     vec3 worldPos = GetWorldPos(modelMatrix);
     gl_Position = GetClipPos(worldPos);
     gl_Position = GetClipPos(worldPos);
-
-    #ifndef GL_ES
     gl_Position.z = gl_Position.w;
     gl_Position.z = gl_Position.w;
-    #else
-    // On OpenGL ES force Z slightly in front of far plane to avoid clipping artifacts due to inaccuracy
-    gl_Position.z = 0.999 * gl_Position.w;
-    #endif
     vTexCoord = iPos.xyz;
     vTexCoord = iPos.xyz;
 }
 }
 
 
 void PS()
 void PS()
 {
 {
-    gl_FragColor = cMatDiffColor * textureCube(sDiffCubeMap, vTexCoord);
+    vec4 sky = cMatDiffColor * textureCube(sDiffCubeMap, vTexCoord);
+    #ifdef HDRSCALE
+        sky = pow(sky + clamp((cAmbientColor.a - 1.0) * 0.1, 0.0, 0.25), max(vec4(cAmbientColor.a), 1.0)) * clamp(cAmbientColor.a, 0.0, 1.0);
+    #endif
+    gl_FragColor = sky;
 }
 }

+ 22 - 0
Resources/CoreData/Shaders/GLSL/Skydome.glsl

@@ -0,0 +1,22 @@
+#include "Uniforms.glsl"
+#include "Samplers.glsl"
+#include "Transform.glsl"
+
+varying vec2 vTexCoord;
+
+uniform mat4 gl_ModelViewMatrix;
+uniform mat4 gl_ProjectionMatrix;
+
+void VS()
+{
+    mat4 modelMatrix = iModelMatrix;
+    vec3 worldPos = GetWorldPos(modelMatrix);
+    gl_Position = GetClipPos(worldPos);
+    gl_Position.z = gl_Position.w;
+    vTexCoord = iTexCoord.xy;
+}
+
+void PS()
+{   
+    gl_FragColor = texture2D(sDiffMap, vTexCoord);       
+}

+ 8 - 4
Resources/CoreData/Shaders/GLSL/TerrainBlend.glsl

@@ -17,7 +17,11 @@ varying vec3 vNormal;
 varying vec4 vWorldPos;
 varying vec4 vWorldPos;
 #ifdef PERPIXEL
 #ifdef PERPIXEL
     #ifdef SHADOW
     #ifdef SHADOW
-        varying vec4 vShadowPos[NUMCASCADES];
+        #ifndef GL_ES
+            varying vec4 vShadowPos[NUMCASCADES];
+        #else
+            varying highp vec4 vShadowPos[NUMCASCADES];
+        #endif
     #endif
     #endif
     #ifdef SPOTLIGHT
     #ifdef SPOTLIGHT
         varying vec4 vSpotPos;
         varying vec4 vSpotPos;
@@ -64,7 +68,7 @@ void VS()
         #ifdef SHADOW
         #ifdef SHADOW
             // Shadow projection: transform from world space to shadow space
             // Shadow projection: transform from world space to shadow space
             for (int i = 0; i < NUMCASCADES; i++)
             for (int i = 0; i < NUMCASCADES; i++)
-                vShadowPos[i] = GetShadowPos(i, projWorldPos);
+                vShadowPos[i] = GetShadowPos(i, vNormal, projWorldPos);
         #endif
         #endif
 
 
         #ifdef SPOTLIGHT
         #ifdef SPOTLIGHT
@@ -81,7 +85,7 @@ void VS()
             // If using lightmap, disregard zone ambient light
             // If using lightmap, disregard zone ambient light
             // If using AO, calculate ambient in the PS
             // If using AO, calculate ambient in the PS
             vVertexLight = vec3(0.0, 0.0, 0.0);
             vVertexLight = vec3(0.0, 0.0, 0.0);
-            vTexCoord2 = iTexCoord2;
+            vTexCoord2 = iTexCoord1;
         #else
         #else
             vVertexLight = GetAmbient(GetZonePos(worldPos));
             vVertexLight = GetAmbient(GetZonePos(worldPos));
         #endif
         #endif
@@ -152,7 +156,7 @@ void PS()
         #endif
         #endif
 
 
         #ifdef AMBIENT
         #ifdef AMBIENT
-            finalColor += cAmbientColor * diffColor.rgb;
+            finalColor += cAmbientColor.rgb * diffColor.rgb;
             finalColor += cMatEmissiveColor;
             finalColor += cMatEmissiveColor;
             gl_FragColor = vec4(GetFog(finalColor, fogFactor), diffColor.a);
             gl_FragColor = vec4(GetFog(finalColor, fogFactor), diffColor.a);
         #else
         #else

+ 79 - 9
Resources/CoreData/Shaders/GLSL/Transform.glsl

@@ -10,17 +10,18 @@ attribute vec4 iPos;
 attribute vec3 iNormal;
 attribute vec3 iNormal;
 attribute vec4 iColor;
 attribute vec4 iColor;
 attribute vec2 iTexCoord;
 attribute vec2 iTexCoord;
-attribute vec2 iTexCoord2;
+attribute vec2 iTexCoord1;
 attribute vec4 iTangent;
 attribute vec4 iTangent;
 attribute vec4 iBlendWeights;
 attribute vec4 iBlendWeights;
 attribute vec4 iBlendIndices;
 attribute vec4 iBlendIndices;
 attribute vec3 iCubeTexCoord;
 attribute vec3 iCubeTexCoord;
-attribute vec4 iCubeTexCoord2;
-#ifndef GL_ES
-    attribute vec4 iInstanceMatrix1;
-    attribute vec4 iInstanceMatrix2;
-    attribute vec4 iInstanceMatrix3;
+attribute vec4 iCubeTexCoord1;
+#ifdef INSTANCED
+    attribute vec4 iTexCoord4;
+    attribute vec4 iTexCoord5;
+    attribute vec4 iTexCoord6;
 #endif
 #endif
+attribute float iObjectIndex;
 
 
 #ifdef SKINNED
 #ifdef SKINNED
 mat4 GetSkinMatrix(vec4 blendWeights, vec4 blendIndices)
 mat4 GetSkinMatrix(vec4 blendWeights, vec4 blendIndices)
@@ -38,7 +39,7 @@ mat4 GetSkinMatrix(vec4 blendWeights, vec4 blendIndices)
 mat4 GetInstanceMatrix()
 mat4 GetInstanceMatrix()
 {
 {
     const vec4 lastColumn = vec4(0.0, 0.0, 0.0, 1.0);
     const vec4 lastColumn = vec4(0.0, 0.0, 0.0, 1.0);
-    return mat4(iInstanceMatrix1, iInstanceMatrix2, iInstanceMatrix3, lastColumn);
+    return mat4(iTexCoord4, iTexCoord5, iTexCoord6, lastColumn);
 }
 }
 #endif
 #endif
 
 
@@ -86,6 +87,63 @@ vec3 GetBillboardNormal()
 }
 }
 #endif
 #endif
 
 
+#ifdef DIRBILLBOARD
+mat3 GetFaceCameraRotation(vec3 position, vec3 direction)
+{
+    vec3 cameraDir = normalize(position - cCameraPos);
+    vec3 front = normalize(direction);
+    vec3 right = normalize(cross(front, cameraDir));
+    vec3 up = normalize(cross(front, right));
+
+    return mat3(
+        right.x, up.x, front.x,
+        right.y, up.y, front.y,
+        right.z, up.z, front.z
+    );
+}
+
+vec3 GetBillboardPos(vec4 iPos, vec3 iDirection, mat4 modelMatrix)
+{
+    vec3 worldPos = (iPos * modelMatrix).xyz;
+    return worldPos + vec3(iTexCoord1.x, 0.0, iTexCoord1.y) * GetFaceCameraRotation(worldPos, iDirection);
+}
+
+vec3 GetBillboardNormal(vec4 iPos, vec3 iDirection, mat4 modelMatrix)
+{
+    vec3 worldPos = (iPos * modelMatrix).xyz;
+    return vec3(0.0, 1.0, 0.0) * GetFaceCameraRotation(worldPos, iDirection);
+}
+#endif
+
+#ifdef TRAILFACECAM
+vec3 GetTrailPos(vec4 iPos, vec3 iFront, float iScale, mat4 modelMatrix)
+{
+    vec3 up = normalize(cCameraPos - iPos.xyz);
+    vec3 right = normalize(cross(iFront, up));
+    return (vec4((iPos.xyz + right * iScale), 1.0) * modelMatrix).xyz;
+}
+
+vec3 GetTrailNormal(vec4 iPos)
+{
+    return normalize(cCameraPos - iPos.xyz);
+}
+#endif
+
+#ifdef TRAILBONE
+vec3 GetTrailPos(vec4 iPos, vec3 iParentPos, float iScale, mat4 modelMatrix)
+{
+    vec3 right = iParentPos - iPos.xyz;
+    return (vec4((iPos.xyz + right * iScale), 1.0) * modelMatrix).xyz;
+}
+
+vec3 GetTrailNormal(vec4 iPos, vec3 iParentPos, vec3 iForward)
+{
+    vec3 left = normalize(iPos.xyz - iParentPos);
+    vec3 up = normalize(cross(normalize(iForward), left));
+    return up;
+}
+#endif
+
 #if defined(SKINNED)
 #if defined(SKINNED)
     #define iModelMatrix GetSkinMatrix(iBlendWeights, iBlendIndices)
     #define iModelMatrix GetSkinMatrix(iBlendWeights, iBlendIndices)
 #elif defined(INSTANCED)
 #elif defined(INSTANCED)
@@ -97,7 +155,13 @@ vec3 GetBillboardNormal()
 vec3 GetWorldPos(mat4 modelMatrix)
 vec3 GetWorldPos(mat4 modelMatrix)
 {
 {
     #if defined(BILLBOARD)
     #if defined(BILLBOARD)
-        return GetBillboardPos(iPos, iTexCoord2, modelMatrix);
+        return GetBillboardPos(iPos, iTexCoord1, modelMatrix);
+    #elif defined(DIRBILLBOARD)
+        return GetBillboardPos(iPos, iNormal, modelMatrix);
+    #elif defined(TRAILFACECAM)
+        return GetTrailPos(iPos, iTangent.xyz, iTangent.w, modelMatrix);
+    #elif defined(TRAILBONE)
+        return GetTrailPos(iPos, iTangent.xyz, iTangent.w, modelMatrix);
     #else
     #else
         return (iPos * modelMatrix).xyz;
         return (iPos * modelMatrix).xyz;
     #endif
     #endif
@@ -107,6 +171,12 @@ vec3 GetWorldNormal(mat4 modelMatrix)
 {
 {
     #if defined(BILLBOARD)
     #if defined(BILLBOARD)
         return GetBillboardNormal();
         return GetBillboardNormal();
+    #elif defined(DIRBILLBOARD)
+        return GetBillboardNormal(iPos, iNormal, modelMatrix);
+    #elif defined(TRAILFACECAM)
+        return GetTrailNormal(iPos);
+    #elif defined(TRAILBONE)
+        return GetTrailNormal(iPos, iTangent.xyz, iNormal);
     #else
     #else
         return normalize(iNormal * GetNormalMatrix(modelMatrix));
         return normalize(iNormal * GetNormalMatrix(modelMatrix));
     #endif
     #endif
@@ -136,4 +206,4 @@ out vec4 fragData[1];
 #define gl_FragData fragData
 #define gl_FragData fragData
 #endif
 #endif
 
 
-#endif
+#endif

+ 29 - 10
Resources/CoreData/Shaders/GLSL/Uniforms.glsl

@@ -6,13 +6,12 @@
 // OpenGL 2 uniforms (no constant buffers)
 // OpenGL 2 uniforms (no constant buffers)
 
 
 #ifdef COMPILEVS
 #ifdef COMPILEVS
-          
+
 // Vertex shader uniforms
 // Vertex shader uniforms
 uniform vec3 cAmbientStartColor;
 uniform vec3 cAmbientStartColor;
 uniform vec3 cAmbientEndColor;
 uniform vec3 cAmbientEndColor;
 uniform mat3 cBillboardRot;
 uniform mat3 cBillboardRot;
 uniform vec3 cCameraPos;
 uniform vec3 cCameraPos;
-uniform mat3 cCameraRot;
 uniform float cNearClip;
 uniform float cNearClip;
 uniform float cFarClip;
 uniform float cFarClip;
 uniform vec4 cDepthMode;
 uniform vec4 cDepthMode;
@@ -20,9 +19,12 @@ uniform vec3 cFrustumSize;
 uniform float cDeltaTime;
 uniform float cDeltaTime;
 uniform float cElapsedTime;
 uniform float cElapsedTime;
 uniform vec4 cGBufferOffsets;
 uniform vec4 cGBufferOffsets;
-uniform vec3 cLightDir;
 uniform vec4 cLightPos;
 uniform vec4 cLightPos;
+uniform vec3 cLightDir;
+uniform vec4 cNormalOffsetScale;
 uniform mat4 cModel;
 uniform mat4 cModel;
+uniform mat4 cView;
+uniform mat4 cViewInv;
 uniform mat4 cViewProj;
 uniform mat4 cViewProj;
 uniform vec4 cUOffset;
 uniform vec4 cUOffset;
 uniform vec4 cVOffset;
 uniform vec4 cVOffset;
@@ -30,7 +32,7 @@ uniform mat4 cZone;
 #if !defined(GL_ES) || defined(WEBGL)
 #if !defined(GL_ES) || defined(WEBGL)
     uniform mat4 cLightMatrices[4];
     uniform mat4 cLightMatrices[4];
 #else
 #else
-    uniform mat4 cLightMatrices[2];
+    uniform highp mat4 cLightMatrices[2];
 #endif
 #endif
 #ifdef SKINNED
 #ifdef SKINNED
     uniform vec4 cSkinMatrices[MAXBONES*3];
     uniform vec4 cSkinMatrices[MAXBONES*3];
@@ -50,7 +52,7 @@ uniform mat4 cZone;
     precision mediump float;
     precision mediump float;
 #endif
 #endif
 
 
-uniform vec3 cAmbientColor;
+uniform vec4 cAmbientColor;
 uniform vec3 cCameraPosPS;
 uniform vec3 cCameraPosPS;
 uniform float cDeltaTimePS;
 uniform float cDeltaTimePS;
 uniform vec4 cDepthReconstruct;
 uniform vec4 cDepthReconstruct;
@@ -59,12 +61,17 @@ uniform vec4 cFogParams;
 uniform vec3 cFogColor;
 uniform vec3 cFogColor;
 uniform vec2 cGBufferInvSize;
 uniform vec2 cGBufferInvSize;
 uniform vec4 cLightColor;
 uniform vec4 cLightColor;
-uniform vec3 cLightDirPS;
 uniform vec4 cLightPosPS;
 uniform vec4 cLightPosPS;
+uniform vec3 cLightDirPS;
+uniform vec4 cNormalOffsetScalePS;
 uniform vec4 cMatDiffColor;
 uniform vec4 cMatDiffColor;
 uniform vec3 cMatEmissiveColor;
 uniform vec3 cMatEmissiveColor;
 uniform vec3 cMatEnvMapColor;
 uniform vec3 cMatEnvMapColor;
 uniform vec4 cMatSpecColor;
 uniform vec4 cMatSpecColor;
+#ifdef PBR
+    uniform float cRoughness;
+    uniform float cMetallic;
+#endif
 uniform float cNearClipPS;
 uniform float cNearClipPS;
 uniform float cFarClipPS;
 uniform float cFarClipPS;
 uniform vec4 cShadowCubeAdjust;
 uniform vec4 cShadowCubeAdjust;
@@ -73,7 +80,9 @@ uniform vec2 cShadowIntensity;
 uniform vec2 cShadowMapInvSize;
 uniform vec2 cShadowMapInvSize;
 uniform vec4 cShadowSplits;
 uniform vec4 cShadowSplits;
 uniform mat4 cLightMatricesPS[4];
 uniform mat4 cLightMatricesPS[4];
-
+#ifdef VSM_SHADOW
+uniform vec2 cVSMShadowParams;
+#endif
 #endif
 #endif
 
 
 #else
 #else
@@ -91,12 +100,13 @@ uniform FrameVS
 uniform CameraVS
 uniform CameraVS
 {
 {
     vec3 cCameraPos;
     vec3 cCameraPos;
-    mat3 cCameraRot;
     float cNearClip;
     float cNearClip;
     float cFarClip;
     float cFarClip;
     vec4 cDepthMode;
     vec4 cDepthMode;
     vec3 cFrustumSize;
     vec3 cFrustumSize;
     vec4 cGBufferOffsets;
     vec4 cGBufferOffsets;
+    mat4 cView;
+    mat4 cViewInv;
     mat4 cViewProj;
     mat4 cViewProj;
     vec4 cClipPlane;
     vec4 cClipPlane;
 };
 };
@@ -110,8 +120,9 @@ uniform ZoneVS
 
 
 uniform LightVS
 uniform LightVS
 {
 {
-    vec3 cLightDir;
     vec4 cLightPos;
     vec4 cLightPos;
+    vec3 cLightDir;
+    vec4 cNormalOffsetScale;
 #ifdef NUMVERTEXLIGHTS
 #ifdef NUMVERTEXLIGHTS
     vec4 cVertexLights[4 * 3];
     vec4 cVertexLights[4 * 3];
 #else
 #else
@@ -160,7 +171,7 @@ uniform CameraPS
 
 
 uniform ZonePS
 uniform ZonePS
 {
 {
-    vec3 cAmbientColor;
+    vec4 cAmbientColor;
     vec4 cFogParams;
     vec4 cFogParams;
     vec3 cFogColor;
     vec3 cFogColor;
 };
 };
@@ -170,12 +181,16 @@ uniform LightPS
     vec4 cLightColor;
     vec4 cLightColor;
     vec4 cLightPosPS;
     vec4 cLightPosPS;
     vec3 cLightDirPS;
     vec3 cLightDirPS;
+    vec4 cNormalOffsetScalePS;
     vec4 cShadowCubeAdjust;
     vec4 cShadowCubeAdjust;
     vec4 cShadowDepthFade;
     vec4 cShadowDepthFade;
     vec2 cShadowIntensity;
     vec2 cShadowIntensity;
     vec2 cShadowMapInvSize;
     vec2 cShadowMapInvSize;
     vec4 cShadowSplits;
     vec4 cShadowSplits;
     mat4 cLightMatricesPS[4];
     mat4 cLightMatricesPS[4];
+#ifdef VSM_SHADOW
+    vec2 cVSMShadowParams;
+#endif
 };
 };
 
 
 #ifndef CUSTOM_MATERIAL_CBUFFER
 #ifndef CUSTOM_MATERIAL_CBUFFER
@@ -185,6 +200,10 @@ uniform MaterialPS
     vec3 cMatEmissiveColor;
     vec3 cMatEmissiveColor;
     vec3 cMatEnvMapColor;
     vec3 cMatEnvMapColor;
     vec4 cMatSpecColor;
     vec4 cMatSpecColor;
+    #ifdef PBR
+        float cRoughness;
+        float cMetallic;
+    #endif
 };
 };
 #endif
 #endif
 
 

+ 4 - 0
Resources/CoreData/Shaders/GLSL/Unlit.glsl

@@ -20,7 +20,11 @@ void VS()
 
 
     #ifdef VERTEXCOLOR
     #ifdef VERTEXCOLOR
         vColor = iColor;
         vColor = iColor;
+        //#ifdef TRAIL
+        //    vColor = vec4(normalize(cCameraPos), 1.0);
+        //#endif
     #endif
     #endif
+
 }
 }
 
 
 void PS()
 void PS()

+ 23 - 0
Resources/CoreData/Shaders/GLSL/Urho2D.glsl

@@ -0,0 +1,23 @@
+#include "Uniforms.glsl"
+#include "Samplers.glsl"
+#include "Transform.glsl"
+
+varying vec2 vTexCoord;
+varying vec4 vColor;
+
+void VS()
+{
+    mat4 modelMatrix = iModelMatrix;
+    vec3 worldPos = GetWorldPos(modelMatrix);
+    gl_Position = GetClipPos(worldPos);
+    
+    vTexCoord = iTexCoord;
+    vColor = iColor;
+}
+
+void PS()
+{
+    vec4 diffColor = cMatDiffColor * vColor;
+    vec4 diffInput = texture2D(sDiffMap, vTexCoord);
+    gl_FragColor = diffColor * diffInput;
+}

+ 14 - 3
Resources/CoreData/Shaders/GLSL/Vegetation.glsl

@@ -16,9 +16,16 @@ uniform vec2 cWindWorldSpacing;
 #endif
 #endif
 varying vec3 vNormal;
 varying vec3 vNormal;
 varying vec4 vWorldPos;
 varying vec4 vWorldPos;
+#ifdef VERTEXCOLOR
+    varying vec4 vColor;
+#endif
 #ifdef PERPIXEL
 #ifdef PERPIXEL
     #ifdef SHADOW
     #ifdef SHADOW
-        varying vec4 vShadowPos[NUMCASCADES];
+        #ifndef GL_ES
+            varying vec4 vShadowPos[NUMCASCADES];
+        #else
+            varying highp vec4 vShadowPos[NUMCASCADES];
+        #endif
     #endif
     #endif
     #ifdef SPOTLIGHT
     #ifdef SPOTLIGHT
         varying vec4 vSpotPos;
         varying vec4 vSpotPos;
@@ -52,6 +59,10 @@ void VS()
     vNormal = GetWorldNormal(modelMatrix);
     vNormal = GetWorldNormal(modelMatrix);
     vWorldPos = vec4(worldPos, GetDepth(gl_Position));
     vWorldPos = vec4(worldPos, GetDepth(gl_Position));
 
 
+    #ifdef VERTEXCOLOR
+        vColor = iColor;
+    #endif
+
     #ifdef NORMALMAP
     #ifdef NORMALMAP
         vec3 tangent = GetWorldTangent(modelMatrix);
         vec3 tangent = GetWorldTangent(modelMatrix);
         vec3 bitangent = cross(tangent, vNormal) * iTangent.w;
         vec3 bitangent = cross(tangent, vNormal) * iTangent.w;
@@ -68,7 +79,7 @@ void VS()
         #ifdef SHADOW
         #ifdef SHADOW
             // Shadow projection: transform from world space to shadow space
             // Shadow projection: transform from world space to shadow space
             for (int i = 0; i < NUMCASCADES; i++)
             for (int i = 0; i < NUMCASCADES; i++)
-                vShadowPos[i] = GetShadowPos(i, projWorldPos);
+                vShadowPos[i] = GetShadowPos(i, vNormal, projWorldPos);
         #endif
         #endif
 
 
         #ifdef SPOTLIGHT
         #ifdef SPOTLIGHT
@@ -85,7 +96,7 @@ void VS()
             // If using lightmap, disregard zone ambient light
             // If using lightmap, disregard zone ambient light
             // If using AO, calculate ambient in the PS
             // If using AO, calculate ambient in the PS
             vVertexLight = vec3(0.0, 0.0, 0.0);
             vVertexLight = vec3(0.0, 0.0, 0.0);
-            vTexCoord2 = iTexCoord2;
+            vTexCoord2 = iTexCoord1;
         #else
         #else
             vVertexLight = GetAmbient(GetZonePos(worldPos));
             vVertexLight = GetAmbient(GetZonePos(worldPos));
         #endif
         #endif

+ 135 - 0
Resources/CoreData/Shaders/HLSL/BRDF.hlsl

@@ -0,0 +1,135 @@
+#ifdef COMPILEPS
+  #ifdef PBR
+
+    // Following BRDF methods are based upon research Frostbite EA
+    //[Lagrade et al. 2014, "Moving Frostbite to Physically Based Rendering"]
+    
+    //Schlick Fresnel
+    //specular  = the rgb specular color value of the pixel
+    //VdotH     = the dot product of the camera view direction and the half vector 
+    float3 SchlickFresnel(float3 specular, float VdotH)
+    {
+        return specular + (float3(1.0, 1.0, 1.0) - specular) * pow(1.0 - VdotH, 5.0);
+    }
+
+    //Schlick Gaussian Fresnel 
+    //specular  = the rgb specular color value of the pixel
+    //VdotH     = the dot product of the camera view direction and the half vector 
+    float3 SchlickGaussianFresnel(in float3 specular, in float VdotH)
+    {
+        float sphericalGaussian = pow(2.0, (-5.55473 * VdotH - 6.98316) * VdotH);
+        return specular + (float3(1.0, 1.0, 1.0) - specular) * sphericalGaussian;
+    }
+
+    //Get Fresnel
+    //specular  = the rgb specular color value of the pixel
+    //VdotH     = the dot product of the camera view direction and the half vector 
+    float3 Fresnel(float3 specular, float VdotH)
+    {
+        return SchlickFresnel(specular, VdotH);
+    }
+
+    // Smith GGX corrected Visibility
+    // NdotL        = the dot product of the normal and direction to the light
+    // NdotV        = the dot product of the normal and the camera view direction
+    // roughness    = the roughness of the pixel
+    float SmithGGXSchlickVisibility(float NdotL, float NdotV, float roughness)
+    {
+        float rough2 = roughness * roughness;
+        float lambdaV = NdotL  * sqrt((-NdotV * rough2 + NdotV) * NdotV + rough2);   
+        float lambdaL = NdotV  * sqrt((-NdotL * rough2 + NdotL) * NdotL + rough2);
+    
+        return 0.5 / (lambdaV + lambdaL);
+    }
+
+    // Get Visibility
+    // NdotL        = the dot product of the normal and direction to the light
+    // NdotV        = the dot product of the normal and the camera view direction
+    // roughness    = the roughness of the pixel
+    float Visibility(float NdotL, float NdotV, float roughness)
+    {
+        return SmithGGXSchlickVisibility(NdotL, NdotV, roughness);
+    }
+
+    // GGX Distribution
+    // NdotH        = the dot product of the normal and the half vector
+    // roughness    = the roughness of the pixel
+    float GGXDistribution(float NdotH, float roughness)
+    {
+        float rough2 = roughness * roughness;
+        float tmp =  (NdotH * rough2 - NdotH) * NdotH + 1;
+        return rough2 / (tmp * tmp);
+    }
+
+    // Blinn Distribution
+    // NdotH        = the dot product of the normal and the half vector
+    // roughness    = the roughness of the pixel
+    float BlinnPhongDistribution(in float NdotH, in float roughness)
+    {
+        const float specPower = max((2.0 / (roughness * roughness)) - 2.0, 1e-4f); // Calculate specular power from roughness
+        return pow(saturate(NdotH), specPower);
+    }
+
+    // Beckmann Distribution
+    // NdotH        = the dot product of the normal and the half vector
+    // roughness    = the roughness of the pixel
+    float BeckmannDistribution(in float NdotH, in float roughness)
+    {
+        const float rough2 = roughness * roughness;
+        const float roughnessA = 1.0 / (4.0 * rough2 * pow(NdotH, 4.0));
+        const float roughnessB = NdotH * NdotH - 1.0;
+        const float roughnessC = rough2 * NdotH * NdotH;
+        return roughnessA * exp(roughnessB / roughnessC);
+    }
+
+    // Get Distribution
+    // NdotH        = the dot product of the normal and the half vector
+    // roughness    = the roughness of the pixel
+    float Distribution(float NdotH, float roughness)
+    {
+        return GGXDistribution(NdotH, roughness);
+    }
+
+    // Lambertian Diffuse
+    // diffuseColor = the rgb color value of the pixel
+    // roughness    = the roughness of the pixel
+    // NdotV        = the normal dot with the camera view direction
+    // NdotL        = the normal dot with the light direction
+    // VdotH        = the camera view direction dot with the half vector
+    float3 LambertianDiffuse(float3 diffuseColor, float NdotL)
+    {
+        return diffuseColor * NdotL;
+    }
+
+    // Burley Diffuse
+    // diffuseColor = the rgb color value of the pixel
+    // roughness    = the roughness of the pixel
+    // NdotV        = the normal dot with the camera view direction
+    // NdotL        = the normal dot with the light direction
+    // VdotH        = the camera view direction dot with the half vector
+    float3 BurleyDiffuse(float3 diffuseColor, float roughness, float NdotV, float NdotL, float VdotH)
+    {
+        const float energyBias = lerp(0, 0.5, roughness);
+        const float energyFactor = lerp(1.0, 1.0 / 1.51, roughness);
+        const float fd90 = energyBias + 2.0 * VdotH * VdotH * roughness;
+        const float f0 = 1.0;
+        const float lightScatter = f0 + (fd90 - f0) * pow(1.0f - NdotL, 5.0f);
+        const float viewScatter = f0 + (fd90 - f0) * pow(1.0f - NdotV, 5.0f);
+
+        return diffuseColor * lightScatter * viewScatter * energyFactor;
+    }
+
+    //Get Diffuse
+    // diffuseColor = the rgb color value of the pixel
+    // roughness    = the roughness of the pixel
+    // NdotV        = the normal dot with the camera view direction
+    // NdotL        = the normal dot with the light direction
+    // VdotH        = the camera view direction dot with the half vector
+    float3 Diffuse(float3 diffuseColor, float roughness, float NdotV, float NdotL, float VdotH)
+    {
+        //return LambertianDiffuse(diffuseColor, NdotL);
+        return BurleyDiffuse(diffuseColor, roughness, NdotV, NdotL, VdotH);
+    }
+
+  #endif
+#endif

+ 8 - 2
Resources/CoreData/Shaders/HLSL/Basic.hlsl

@@ -14,11 +14,17 @@ void VS(float4 iPos : POSITION,
         int4 iBlendIndices : BLENDINDICES,
         int4 iBlendIndices : BLENDINDICES,
     #endif
     #endif
     #ifdef INSTANCED
     #ifdef INSTANCED
-        float4x3 iModelInstance : TEXCOORD2,
+        float4x3 iModelInstance : TEXCOORD4,
     #endif
     #endif
-    #ifdef BILLBOARD
+    #if defined(BILLBOARD) || defined(DIRBILLBOARD)
         float2 iSize : TEXCOORD1,
         float2 iSize : TEXCOORD1,
     #endif
     #endif
+    #if defined(DIRBILLBOARD) || defined(TRAILBONE)
+        float3 iNormal : NORMAL,
+    #endif
+    #if defined(TRAILFACECAM) || defined(TRAILBONE)
+        float4 iTangent : TANGENT,
+    #endif
     #ifdef DIFFMAP
     #ifdef DIFFMAP
         out float2 oTexCoord : TEXCOORD0,
         out float2 oTexCoord : TEXCOORD0,
     #endif
     #endif

+ 9 - 9
Resources/CoreData/Shaders/HLSL/Bloom.hlsl

@@ -8,8 +8,8 @@
 // D3D9 uniforms
 // D3D9 uniforms
 uniform float cBloomThreshold;
 uniform float cBloomThreshold;
 uniform float2 cBloomMix;
 uniform float2 cBloomMix;
-uniform float2 cHBlurOffsets;
-uniform float2 cHBlurInvSize;
+uniform float2 cBlurHOffsets;
+uniform float2 cBlurHInvSize;
 
 
 #else
 #else
 
 
@@ -17,14 +17,14 @@ uniform float2 cHBlurInvSize;
 #ifdef COMPILEVS
 #ifdef COMPILEVS
 cbuffer CustomVS : register(b6)
 cbuffer CustomVS : register(b6)
 {
 {
-    float2 cHBlurOffsets;
+    float2 cBlurHOffsets;
 }
 }
 #else
 #else
 cbuffer CustomPS : register(b6)
 cbuffer CustomPS : register(b6)
 {
 {
     float cBloomThreshold;
     float cBloomThreshold;
     float2 cBloomMix;
     float2 cBloomMix;
-    float2 cHBlurInvSize;
+    float2 cBlurHInvSize;
 }
 }
 #endif
 #endif
 
 
@@ -54,7 +54,7 @@ void VS(float4 iPos : POSITION,
     float4x3 modelMatrix = iModelMatrix;
     float4x3 modelMatrix = iModelMatrix;
     float3 worldPos = GetWorldPos(modelMatrix);
     float3 worldPos = GetWorldPos(modelMatrix);
     oPos = GetClipPos(worldPos);
     oPos = GetClipPos(worldPos);
-    oTexCoord = GetQuadTexCoord(oPos) + cHBlurOffsets;
+    oTexCoord = GetQuadTexCoord(oPos) + cBlurHOffsets;
     oScreenPos = GetScreenPosPreDiv(oPos);
     oScreenPos = GetScreenPosPreDiv(oPos);
 }
 }
 
 
@@ -67,17 +67,17 @@ void PS(float2 iTexCoord : TEXCOORD0,
     oColor = float4((rgb - cBloomThreshold) / (1.0 - cBloomThreshold), 1.0);
     oColor = float4((rgb - cBloomThreshold) / (1.0 - cBloomThreshold), 1.0);
     #endif
     #endif
 
 
-    #ifdef HBLUR
+    #ifdef BLURH
     float3 rgb = 0.0;
     float3 rgb = 0.0;
     for (int i = 0; i < 5; ++i)
     for (int i = 0; i < 5; ++i)
-        rgb += Sample2D(DiffMap, iTexCoord + (float2(offsets[i], 0.0)) * cHBlurInvSize).rgb * weights[i];
+        rgb += Sample2D(DiffMap, iTexCoord + (float2(offsets[i], 0.0)) * cBlurHInvSize).rgb * weights[i];
     oColor = float4(rgb, 1.0);
     oColor = float4(rgb, 1.0);
     #endif
     #endif
 
 
-    #ifdef VBLUR
+    #ifdef BLURV
     float3 rgb = 0.0;
     float3 rgb = 0.0;
     for (int i = 0; i < 5; ++i)
     for (int i = 0; i < 5; ++i)
-        rgb += Sample2D(DiffMap, iTexCoord + (float2(0.0, offsets[i])) * cHBlurInvSize).rgb * weights[i];
+        rgb += Sample2D(DiffMap, iTexCoord + (float2(0.0, offsets[i])) * cBlurHInvSize).rgb * weights[i];
     oColor = float4(rgb, 1.0);
     oColor = float4(rgb, 1.0);
     #endif
     #endif
 
 

+ 22 - 26
Resources/CoreData/Shaders/HLSL/Blur.hlsl

@@ -11,9 +11,9 @@ uniform float2 cBlurHOffsets;
 uniform float2 cBlurHInvSize;
 uniform float2 cBlurHInvSize;
 
 
 void VS(float4 iPos : POSITION,
 void VS(float4 iPos : POSITION,
-    out float4 oPos : POSITION,
     out float2 oTexCoord : TEXCOORD0,
     out float2 oTexCoord : TEXCOORD0,
-    out float2 oScreenPos : TEXCOORD1)
+    out float2 oScreenPos : TEXCOORD1,
+    out float4 oPos : OUTPOSITION)
 {
 {
     float4x3 modelMatrix = iModelMatrix;
     float4x3 modelMatrix = iModelMatrix;
     float3 worldPos = GetWorldPos(modelMatrix);
     float3 worldPos = GetWorldPos(modelMatrix);
@@ -26,39 +26,35 @@ void PS(float2 iTexCoord : TEXCOORD0,
     float2 iScreenPos : TEXCOORD1,
     float2 iScreenPos : TEXCOORD1,
     out float4 oColor : OUTCOLOR0)
     out float4 oColor : OUTCOLOR0)
 {
 {
-
-#ifndef D3D11
-    #ifdef BLUR3
-        oColor = GaussianBlur(3, cBlurDir, cBlurHInvSize * cBlurRadius, cBlurSigma, sDiffMap, iTexCoord);
-    #endif
-
-    #ifdef BLUR5
-        oColor = GaussianBlur(5, cBlurDir, cBlurHInvSize * cBlurRadius, cBlurSigma, sDiffMap, iTexCoord);
-    #endif
-
-    #ifdef BLUR7
-        oColor = GaussianBlur(7, cBlurDir, cBlurHInvSize * cBlurRadius, cBlurSigma, sDiffMap, iTexCoord);
-    #endif
-
-    #ifdef BLUR9
-        oColor = GaussianBlur(9, cBlurDir, cBlurHInvSize * cBlurRadius, cBlurSigma, sDiffMap, iTexCoord);
-    #endif
-
-#else
     #ifdef BLUR3
     #ifdef BLUR3
-        oColor = GaussianBlur(3, cBlurDir, cBlurHInvSize * cBlurRadius, cBlurSigma, tDiffMap, sDiffMap, iTexCoord);
+        #ifndef D3D11 
+            oColor = GaussianBlur(3, cBlurDir, cBlurHInvSize * cBlurRadius, cBlurSigma, sDiffMap, iTexCoord);
+        #else
+            oColor = GaussianBlur(3, cBlurDir, cBlurHInvSize * cBlurRadius, cBlurSigma, tDiffMap, sDiffMap, iTexCoord);
+        #endif
     #endif
     #endif
 
 
     #ifdef BLUR5
     #ifdef BLUR5
-        oColor = GaussianBlur(5, cBlurDir, cBlurHInvSize * cBlurRadius, cBlurSigma, tDiffMap, sDiffMap, iTexCoord);
+        #ifndef D3D11
+            oColor = GaussianBlur(5, cBlurDir, cBlurHInvSize * cBlurRadius, cBlurSigma, sDiffMap, iTexCoord);
+        #else
+            oColor = GaussianBlur(5, cBlurDir, cBlurHInvSize * cBlurRadius, cBlurSigma, tDiffMap, sDiffMap, iTexCoord);
+        #endif
     #endif
     #endif
 
 
     #ifdef BLUR7
     #ifdef BLUR7
-        oColor = GaussianBlur(7, cBlurDir, cBlurHInvSize * cBlurRadius, cBlurSigma, tDiffmap, sDiffMap, iTexCoord);
+        #ifndef D3D11
+            oColor = GaussianBlur(7, cBlurDir, cBlurHInvSize * cBlurRadius, cBlurSigma, sDiffMap, iTexCoord);
+        #else
+            oColor = GaussianBlur(7, cBlurDir, cBlurHInvSize * cBlurRadius, cBlurSigma, tDiffMap, sDiffMap, iTexCoord);
+        #endif
     #endif
     #endif
 
 
     #ifdef BLUR9
     #ifdef BLUR9
-        oColor = GaussianBlur(9, cBlurDir, cBlurHInvSize * cBlurRadius, cBlurSigma, tDiffMap, sDiffMap, iTexCoord);
+        #ifndef D3D11
+            oColor = GaussianBlur(9, cBlurDir, cBlurHInvSize * cBlurRadius, cBlurSigma, sDiffMap, iTexCoord);
+        #else
+            oColor = GaussianBlur(9, cBlurDir, cBlurHInvSize * cBlurRadius, cBlurSigma, tDiffMap, sDiffMap, iTexCoord);
+        #endif
     #endif
     #endif
-#endif
 }
 }

+ 7 - 0
Resources/CoreData/Shaders/HLSL/Constants.hlsl

@@ -0,0 +1,7 @@
+#define M_PI 3.14159265358979323846
+#define M_EPSILON 0.0001
+
+#ifdef PBR
+#define ROUGHNESS_FLOOR 0.003
+#define METALNESS_FLOOR 0.03
+#endif

+ 7 - 3
Resources/CoreData/Shaders/HLSL/DeferredLight.hlsl

@@ -72,7 +72,11 @@ void PS(
         float4 albedoInput = Sample2DProj(AlbedoBuffer, iScreenPos);
         float4 albedoInput = Sample2DProj(AlbedoBuffer, iScreenPos);
         float4 normalInput = Sample2DProj(NormalBuffer, iScreenPos);
         float4 normalInput = Sample2DProj(NormalBuffer, iScreenPos);
     #endif
     #endif
-    
+
+    // Position acquired via near/far ray is relative to camera. Bring position to world space
+    float3 eyeVec = -worldPos;
+    worldPos += cCameraPosPS;
+
     float3 normal = normalize(normalInput.rgb * 2.0 - 1.0);
     float3 normal = normalize(normalInput.rgb * 2.0 - 1.0);
     float4 projWorldPos = float4(worldPos, 1.0);
     float4 projWorldPos = float4(worldPos, 1.0);
     float3 lightColor;
     float3 lightColor;
@@ -81,7 +85,7 @@ void PS(
     float diff = GetDiffuse(normal, worldPos, lightDir);
     float diff = GetDiffuse(normal, worldPos, lightDir);
 
 
     #ifdef SHADOW
     #ifdef SHADOW
-        diff *= GetShadowDeferred(projWorldPos, depth);
+        diff *= GetShadowDeferred(projWorldPos, normal, depth);
     #endif
     #endif
 
 
     #if defined(SPOTLIGHT)
     #if defined(SPOTLIGHT)
@@ -94,7 +98,7 @@ void PS(
     #endif
     #endif
 
 
     #ifdef SPECULAR
     #ifdef SPECULAR
-        float spec = GetSpecular(normal, -worldPos, lightDir, normalInput.a * 255.0);
+        float spec = GetSpecular(normal, eyeVec, lightDir, normalInput.a * 255.0);
         oColor = diff * float4(lightColor * (albedoInput.rgb + spec * cLightColor.a * albedoInput.aaa), 0.0);
         oColor = diff * float4(lightColor * (albedoInput.rgb + spec * cLightColor.a * albedoInput.aaa), 0.0);
     #else
     #else
         oColor = diff * float4(lightColor * albedoInput.rgb, 0.0);
         oColor = diff * float4(lightColor * albedoInput.rgb, 0.0);

+ 9 - 2
Resources/CoreData/Shaders/HLSL/Depth.hlsl

@@ -8,12 +8,19 @@ void VS(float4 iPos : POSITION,
         int4 iBlendIndices : BLENDINDICES,
         int4 iBlendIndices : BLENDINDICES,
     #endif
     #endif
     #ifdef INSTANCED
     #ifdef INSTANCED
-        float4x3 iModelInstance : TEXCOORD2,
+        float4x3 iModelInstance : TEXCOORD4,
+    #endif
+    #ifndef NOUV
+        float2 iTexCoord : TEXCOORD0,
     #endif
     #endif
-    float2 iTexCoord : TEXCOORD0,
     out float3 oTexCoord : TEXCOORD0,
     out float3 oTexCoord : TEXCOORD0,
     out float4 oPos : OUTPOSITION)
     out float4 oPos : OUTPOSITION)
 {
 {
+    // Define a 0,0 UV coord if not expected from the vertex data
+    #ifdef NOUV
+    float2 iTexCoord = float2(0.0, 0.0);
+    #endif
+    
     float4x3 modelMatrix = iModelMatrix;
     float4x3 modelMatrix = iModelMatrix;
     float3 worldPos = GetWorldPos(modelMatrix);
     float3 worldPos = GetWorldPos(modelMatrix);
     oPos = GetClipPos(worldPos);
     oPos = GetClipPos(worldPos);

+ 282 - 0
Resources/CoreData/Shaders/HLSL/IBL.hlsl

@@ -0,0 +1,282 @@
+#ifdef COMPILEPS
+
+    //  float3 ImportanceSampleSimple(in float2 Xi, in float roughness, in float3 T, in float3 B, in float3 N)
+    // {
+    //     const float a = roughness * roughness;
+    //     const float3x3 tbn = float3x3(T, B, N);
+    //     #ifdef IBLFAST
+    //         const float blurFactor = 0.0;
+    //     #else
+    //         const float blurFactor = 5.0;
+    //     #endif
+    //     const float3 Xi3 = lerp(float3(0,0,1), normalize(float3(Xi.xy * blurFactor % 1.0 , 1.0)), a);
+    //     const float3 XiWS = mul(Xi3, tbn);
+    //     return normalize(N + XiWS);
+    // }
+
+    // // Karis '13
+    // float3 ImportanceSampleGGX(in float2 Xi, in float roughness, in float3 T, in float3 B, in float3 N)
+    // {
+    //     float a = roughness * roughness;
+    //     float Phi = 2.0 * M_PI * Xi.x;
+    //     float CosTheta = (sqrt((1.0 - Xi.y) / (1.0 + (a*a - 1.0) * Xi.y)));
+    //     float SinTheta = sqrt(1.0 - CosTheta * CosTheta);
+    //     float3 H = 0;
+    //     H.x = SinTheta * cos(Phi);
+    //     H.y = SinTheta * sin(Phi);
+    //     H.z = CosTheta;
+
+    //     float3 UpVector = abs(N.z) < 0.999 ? float3(0, 0, 1) : float3(1, 0, 0);
+    //     float3 TangentX = normalize(cross(UpVector, N));
+    //     float3 TangentY = cross(N, TangentX);
+    //     // Tangent to world space
+    //     return TangentX * H.x + TangentY * H.y + N * H.z;
+    // }
+
+    // #ifdef IBLFAST
+    //     #define IMPORTANCE_SAMPLES 1
+    // #else
+    //     #define IMPORTANCE_SAMPLES 16
+    // #endif
+
+    // #define IMPORTANCE_KERNEL_SIZE 16
+    // static const float2 IMPORTANCE_KERNEL[IMPORTANCE_KERNEL_SIZE] =
+    // {
+    //     float2(-0.0780436, 0.0558389),
+    //     float2(0.034318, -0.0635879),
+    //     float2(0.00230821, 0.0807279),
+    //     float2(0.0124638, 0.117585),
+    //     float2(0.093943, -0.0944602),
+    //     float2(0.139348, -0.109816),
+    //     float2(-0.181872, -0.129649),
+    //     float2(0.240066, -0.0494057),
+    //     float2(0.115965, -0.0374714),
+    //     float2(-0.294819, -0.100726),
+    //     float2(-0.149652, 0.37459),
+    //     float2(0.261695, -0.292813),
+    //     float2(-0.37944, -0.425145),
+    //     float2(0.628994, -0.189387),
+    //     float2(-0.331257, -0.646864),
+    //     float2(-0.467004, 0.439687),
+    // };
+
+    // float GetMipFromRougness(float roughness)
+    // {
+    //     const float smoothness = 1.0 - roughness;
+    //     return (1.0 - smoothness * smoothness) * 10.0;
+    // }
+
+    // /// Perform importance sampling
+    // ///     reflectVec: calculated vector of reflection
+    // ///     wsNormal: world-space normal of the surface
+    // ///     toCamera: direction from the pixel to the camera
+    // ///     specular: specular color
+    // ///     roughness: surface roughness
+    // ///     reflectionCubeColor: output color for diffuse
+
+    // // Implementation based on Epics 2013 course notes
+    // float3 ImportanceSampling(in float3 reflectVec, in float3 tangent, in float3 bitangent, in float3 wsNormal, in float3 toCamera,  in float3 diffColor, in float3 specColor, in float roughness, inout float3 reflectionCubeColor)
+    // {
+    //     reflectionCubeColor = 1.0;
+
+    //     const float3 reflectSpec = normalize(GetSpecularDominantDir(wsNormal, reflectVec, roughness));
+
+    //     const float3 V = normalize(-toCamera);
+    //     const float3 N = normalize(wsNormal);
+    //     const float ndv = saturate(abs(dot(N, V)));
+
+    //     const float specMipLevel = GetMipFromRougness(roughness);
+
+    //     float3 accumulatedColor = float3(0,0,0);
+    //     for (int i = 0; i < IMPORTANCE_SAMPLES; ++i)
+    //     {
+    //         float3 kd = 1.0;
+    //         float3 diffuseFactor = 0.0;
+    //         float3 specularFactor = 0.0;
+
+    //         {
+    //             // Diffuse IBL
+    //             const float rough = 1.0;
+    //             const float mipLevel = 9.0;
+
+    //             const float3 H = ImportanceSampleSimple(IMPORTANCE_KERNEL[i], rough, tangent, bitangent, N);
+    //             const float3 L = 2.0 * dot( V, H ) * H - V;
+
+    //             const float vdh = saturate(abs(dot(V, H)));
+    //             const float ndh = saturate(abs(dot(N, H)));
+    //             const float ndl = saturate(abs(dot(N, L)));
+
+    //             const float3 sampledColor = SampleCubeLOD(ZoneCubeMap, float4(L, mipLevel));
+
+    //             const float3 diffuseTerm = Diffuse(diffColor, rough, ndv, ndl, vdh);
+    //             const float3 lightTerm = sampledColor;
+
+    //             diffuseFactor = lightTerm * diffuseTerm;
+    //         }
+
+    //         {
+    //             // Specular IBL
+    //             const float rough = roughness;
+    //             const float mipLevel = specMipLevel;
+
+    //             const float3 H = ImportanceSampleSimple(IMPORTANCE_KERNEL[i], rough, tangent, bitangent, N);
+    //             const float3 L = 2.0 * dot( V, H ) * H - V;
+    //             const float3 sampledColor = SampleCubeLOD(ZoneCubeMap, float4(L, mipLevel));
+
+    //             const float vdh = saturate(abs(dot(V, H)));
+    //             const float ndh = saturate(abs(dot(N, H)));
+    //             const float ndl = saturate(abs(dot(N, L)));
+
+    //             const float3 fresnelTerm = Fresnel(specColor, vdh);
+    //             const float distTerm = 1.0;//Distribution(ndh_, roughness);
+    //             const float visTerm = Visibility(ndl, ndv, rough);
+    //             const float3 lightTerm = sampledColor * ndl;
+
+    //             const float pdf = ndl > 0.05 ? ImportanceSamplePDF(distTerm, ndh, vdh) : 4.0; // reduce artifacts at extreme grazing angles
+
+    //             const float3 specularTerm = SpecularBRDF(distTerm, fresnelTerm, visTerm, ndl, ndv);
+
+    //             // Energy conservation:
+    //             // Specular conservation:
+    //             specularFactor = lightTerm * specularTerm / pdf;
+    //             specularFactor = max(saturate(normalize(specularFactor) * (length(sampledColor * specColor))), specularFactor);
+
+    //             // Diffuse conservation:
+    //             kd = 1.0 - specularFactor;
+    //         }
+
+    //         accumulatedColor += specularFactor + diffuseFactor * kd;
+    //     }
+
+    //     return (accumulatedColor / IMPORTANCE_SAMPLES);
+    // }
+
+
+    // float3 ImportanceSamplingSimple(in float3 reflectVec, in float3 tangent, in float3 bitangent, in float3 wsNormal, in float3 toCamera,  in float3 diffColor, in float3 specColor, in float roughness, inout float3 reflectionCubeColor)
+    // {
+    //     reflectionCubeColor = 1.0;
+
+    //     reflectVec = normalize(GetSpecularDominantDir(wsNormal, reflectVec, roughness));
+
+    //     const float3 Hn = normalize(-toCamera + wsNormal);
+    //     const float ndv = saturate(dot(-toCamera, wsNormal));
+    //     const float vdh = saturate(dot(-toCamera, Hn));
+    //     const float ndh = saturate(dot(wsNormal, Hn));
+
+    //     float3 accumulatedColor = float3(0,0,0);
+    //     for (int i = 0; i < IMPORTANCE_SAMPLES; ++i)
+    //     {
+    //         float3 kd = 1.0;
+    //         float3 diffuseFactor = 0.0;
+    //         float3 specularFactor = 0.0;
+
+    //         {
+    //             // Diffuse IBL
+    //             const float rough = 1.0;
+    //             const float mipLevel = 9.0;
+
+    //             const float3 perturb = ImportanceSampleGGX(IMPORTANCE_KERNEL[i].xy, rough, tangent, bitangent, wsNormal);
+    //             const float3 sampleVec = wsNormal + perturb; //perturb by the sample vector
+
+    //             const float3 sampledColor = SampleCubeLOD(ZoneCubeMap, float4(sampleVec, mipLevel));
+    //             const float ndl = saturate(dot(sampleVec, wsNormal));
+
+    //             const float3 diffuseTerm = Diffuse(diffColor, rough, ndv, ndl, vdh);
+    //             const float3 lightTerm = sampledColor;
+
+    //             diffuseFactor = lightTerm * diffuseTerm;
+    //         }
+
+    //         {
+    //             // Specular IBL
+    //             const float rough = roughness;
+    //             const float mipLevel =  GetMipFromRougness(rough);
+
+    //             const float3 perturb = ImportanceSampleGGX(IMPORTANCE_KERNEL[i].xy, rough, tangent, bitangent, reflectVec);
+    //             const float3 sampleVec = reflectVec + perturb; //perturb by the sample vector
+
+    //             const float3 sampledColor = SampleCubeLOD(ZoneCubeMap, float4(sampleVec, mipLevel));
+    //             const float ndl = saturate(dot(sampleVec, wsNormal));
+
+    //             const float3 fresnelTerm = SchlickFresnel(specColor, ndh) ;
+    //             const float distTerm = 1.0; //Optimization, this term is mathematically cancelled out  //Distribution(ndh, roughness);
+    //             const float visTerm = SmithGGXVisibility(ndl, ndv, rough);
+    //             const float3 lightTerm = sampledColor * ndl;
+
+    //             const float pdf = 1.0;//ImportanceSamplePDF(distTerm, ndh, vdh);
+
+    //             specularFactor = lightTerm * SpecularBRDF(distTerm, fresnelTerm, visTerm, ndl, ndv) / pdf;
+    //             specularFactor *= pdf * ndv * (4.0 * ndl * ndv); // hacks
+    //             kd = (1.0 - saturate(specularFactor)); //energy conservation
+    //         }
+
+    //         accumulatedColor += specularFactor + diffuseFactor * kd;
+    //     }
+
+    //     return accumulatedColor / IMPORTANCE_SAMPLES;
+    // }
+
+    /// Determine reflection vector based on surface roughness, rougher uses closer to the normal and smoother uses closer to the reflection vector
+    ///     normal: surface normal
+    ///     reflection: vector of reflection off of the surface
+    ///     roughness: surface roughness
+    float3 GetSpecularDominantDir(float3 normal, float3 reflection, float roughness)
+    {
+        const float smoothness = 1.0 - roughness;
+        const float lerpFactor = smoothness * (sqrt(smoothness) + roughness);
+        return lerp(normal, reflection, lerpFactor);
+    }
+
+    float GetMipFromRougness(float roughness)
+    {
+        const float smoothness = 1.0 - roughness;
+        return (1.0 - smoothness * smoothness) * 10.0;
+    }
+
+
+    float3 EnvBRDFApprox (float3 SpecularColor, float Roughness, float NoV)
+    {
+        const float4 c0 = float4(-1, -0.0275, -0.572, 0.022 );
+        const float4 c1 = float4(1, 0.0425, 1.0, -0.04 );
+        float4 r = Roughness * c0 + c1;
+        float a004 = min( r.x * r.x, exp2( -9.28 * NoV ) ) * r.x + r.y;
+        float2 AB = float2( -1.04, 1.04 ) * a004 + r.zw;
+        return SpecularColor * AB.x + AB.y;
+    }
+
+    /// Calculate IBL contributation
+    ///     reflectVec: reflection vector for cube sampling
+    ///     wsNormal: surface normal in word space
+    ///     toCamera: normalized direction from surface point to camera
+    ///     roughness: surface roughness
+    ///     ambientOcclusion: ambient occlusion
+    float3 ImageBasedLighting(in float3 reflectVec, in float3 tangent, in float3 bitangent, in float3 wsNormal, in float3 toCamera, in float3 diffColor, in float3 specColor, in float roughness, inout float3 reflectionCubeColor)
+    {
+        reflectVec = GetSpecularDominantDir(wsNormal, reflectVec, roughness);
+        const float ndv = saturate(dot(-toCamera, wsNormal));
+
+        // PMREM Mipmapmode https://seblagarde.wordpress.com/2012/06/10/amd-cubemapgen-for-physically-based-rendering/
+        //const float GlossScale = 16.0;
+        //const float GlossBias = 5.0;
+        const float mipSelect = roughness * 9.0;// exp2(GlossScale * roughness + GlossBias) - exp2(GlossBias);
+
+        float3 cube = SampleCubeLOD(ZoneCubeMap, float4(reflectVec, mipSelect)).rgb;
+        float3 cubeD = SampleCubeLOD(ZoneCubeMap, float4(wsNormal, 9.0)).rgb;
+        // Fake the HDR texture
+        float brightness = clamp(cAmbientColor.a, 0.0, 1.0);
+        float darknessCutoff = clamp((cAmbientColor.a - 1.0) * 0.1, 0.0, 0.25);
+
+        const float hdrMaxBrightness = 5.0;
+        float3 hdrCube = pow(cube + darknessCutoff, max(1.0, cAmbientColor.a));
+        hdrCube += max(0.0, hdrCube - 1.0) * hdrMaxBrightness;
+
+        float3 hdrCubeD = pow(cubeD + darknessCutoff, max(1.0, cAmbientColor.a));
+        hdrCubeD += max(0.0, hdrCubeD - 1.0) * hdrMaxBrightness;
+
+        const float3 environmentSpecular = EnvBRDFApprox(specColor, roughness, ndv);
+        const float3 environmentDiffuse = EnvBRDFApprox(diffColor, 1.0, ndv);
+
+        return (hdrCube * environmentSpecular + hdrCubeD * environmentDiffuse) * brightness;
+        //return ImportanceSampling(reflectVec, tangent, bitangent, wsNormal, toCamera, diffColor, specColor, roughness, reflectionCubeColor);
+    }
+#endif

+ 148 - 47
Resources/CoreData/Shaders/HLSL/Lighting.hlsl

@@ -18,7 +18,11 @@ float GetVertexLight(int index, float3 worldPos, float3 normal)
     // Directional light
     // Directional light
     if (invRange == 0.0)
     if (invRange == 0.0)
     {
     {
-        float NdotL = max(dot(normal, lightDir), 0.0);
+        #ifdef TRANSLUCENT
+            float NdotL = abs(dot(normal, lightDir));
+        #else
+            float NdotL = max(dot(normal, lightDir), 0.0);
+        #endif
         return NdotL;
         return NdotL;
     }
     }
     // Point/spot light
     // Point/spot light
@@ -27,7 +31,11 @@ float GetVertexLight(int index, float3 worldPos, float3 normal)
         float3 lightVec = (lightPos - worldPos) * invRange;
         float3 lightVec = (lightPos - worldPos) * invRange;
         float lightDist = length(lightVec);
         float lightDist = length(lightVec);
         float3 localDir = lightVec / lightDist;
         float3 localDir = lightVec / lightDist;
-        float NdotL = max(dot(normal, localDir), 0.0);
+        #ifdef TRANSLUCENT
+            float NdotL = abs(dot(normal, localDir));
+        #else
+            float NdotL = max(dot(normal, localDir), 0.0);
+        #endif
         float atten = saturate(1.0 - lightDist * lightDist);
         float atten = saturate(1.0 - lightDist * lightDist);
         float spotEffect = dot(localDir, lightDir);
         float spotEffect = dot(localDir, lightDir);
         float spotAtten = saturate((spotEffect - cutoff) * invCutoff);
         float spotAtten = saturate((spotEffect - cutoff) * invCutoff);
@@ -70,18 +78,37 @@ float GetVertexLightVolumetric(int index, float3 worldPos)
     #define NUMCASCADES 1
     #define NUMCASCADES 1
 #endif
 #endif
 
 
-void GetShadowPos(float4 projWorldPos, out float4 shadowPos[NUMCASCADES])
+void GetShadowPos(float4 projWorldPos, float3 normal, out float4 shadowPos[NUMCASCADES])
 {
 {
     // Shadow projection: transform from world space to shadow space
     // Shadow projection: transform from world space to shadow space
-    #if defined(DIRLIGHT)
-        shadowPos[0] = mul(projWorldPos, cLightMatrices[0]);
-        shadowPos[1] = mul(projWorldPos, cLightMatrices[1]);
-        shadowPos[2] = mul(projWorldPos, cLightMatrices[2]);
-        shadowPos[3] = mul(projWorldPos, cLightMatrices[3]);
-    #elif defined(SPOTLIGHT)
-        shadowPos[0] = mul(projWorldPos, cLightMatrices[1]);
+    #ifdef NORMALOFFSET
+        #ifdef DIRLIGHT
+            float cosAngle = saturate(1.0 - dot(normal, cLightDir));
+        #else
+            float cosAngle = saturate(1.0 - dot(normal, normalize(cLightPos - projWorldPos.xyz)));
+        #endif
+
+        #if defined(DIRLIGHT)
+            shadowPos[0] = mul(float4(projWorldPos.xyz + cosAngle * cNormalOffsetScale.x * normal, 1.0), cLightMatrices[0]);
+            shadowPos[1] = mul(float4(projWorldPos.xyz + cosAngle * cNormalOffsetScale.y * normal, 1.0), cLightMatrices[1]);
+            shadowPos[2] = mul(float4(projWorldPos.xyz + cosAngle * cNormalOffsetScale.z * normal, 1.0), cLightMatrices[2]);
+            shadowPos[3] = mul(float4(projWorldPos.xyz + cosAngle * cNormalOffsetScale.w * normal, 1.0), cLightMatrices[3]);
+        #elif defined(SPOTLIGHT)
+            shadowPos[0] = mul(float4(projWorldPos.xyz + cosAngle * cNormalOffsetScale.x * normal, 1.0), cLightMatrices[1]);
+        #else
+            shadowPos[0] = float4(projWorldPos.xyz + cosAngle * cNormalOffsetScale.x * normal - cLightPos.xyz, 0.0);
+        #endif
     #else
     #else
-        shadowPos[0] = float4(projWorldPos.xyz - cLightPos.xyz, 0.0);
+        #if defined(DIRLIGHT)
+            shadowPos[0] = mul(projWorldPos, cLightMatrices[0]);
+            shadowPos[1] = mul(projWorldPos, cLightMatrices[1]);
+            shadowPos[2] = mul(projWorldPos, cLightMatrices[2]);
+            shadowPos[3] = mul(projWorldPos, cLightMatrices[3]);
+        #elif defined(SPOTLIGHT)
+            shadowPos[0] = mul(projWorldPos, cLightMatrices[1]);
+        #else
+            shadowPos[0] = float4(projWorldPos.xyz - cLightPos.xyz, 0.0);
+        #endif
     #endif
     #endif
 }
 }
 #endif
 #endif
@@ -91,13 +118,36 @@ void GetShadowPos(float4 projWorldPos, out float4 shadowPos[NUMCASCADES])
 float GetDiffuse(float3 normal, float3 worldPos, out float3 lightDir)
 float GetDiffuse(float3 normal, float3 worldPos, out float3 lightDir)
 {
 {
     #ifdef DIRLIGHT
     #ifdef DIRLIGHT
+        lightDir = cLightDirPS;
+        #ifdef TRANSLUCENT
+            return abs(dot(normal, lightDir));
+        #else
+            return saturate(dot(normal, lightDir));
+        #endif
+    #else
+        float3 lightVec = (cLightPosPS.xyz - worldPos) * cLightPosPS.w;
+        float lightDist = length(lightVec);
+        lightDir = lightVec / lightDist;
+        #ifdef TRANSLUCENT
+            return abs(dot(normal, lightDir)) * Sample2D(LightRampMap, float2(lightDist, 0.0)).r;
+        #else
+            return saturate(dot(normal, lightDir)) * Sample2D(LightRampMap, float2(lightDist, 0.0)).r;
+        #endif
+    #endif
+}
+
+float GetAtten(float3 normal, float3 worldPos, out float3 lightDir)
+{
+     #ifdef DIRLIGHT
         lightDir = cLightDirPS;
         lightDir = cLightDirPS;
         return saturate(dot(normal, lightDir));
         return saturate(dot(normal, lightDir));
     #else
     #else
         float3 lightVec = (cLightPosPS.xyz - worldPos) * cLightPosPS.w;
         float3 lightVec = (cLightPosPS.xyz - worldPos) * cLightPosPS.w;
         float lightDist = length(lightVec);
         float lightDist = length(lightVec);
+        float falloff = pow(saturate(1.0 - pow(lightDist / 1.0, 4.0)), 2.0) / (pow(lightDist, 2.0) + 1.0);
+
         lightDir = lightVec / lightDist;
         lightDir = lightVec / lightDist;
-        return saturate(dot(normal, lightDir)) * Sample2D(LightRampMap, float2(lightDist, 0.0)).r;
+        return saturate(dot(normal, lightDir)) * falloff;
     #endif
     #endif
 }
 }
 
 
@@ -131,15 +181,55 @@ float GetIntensity(float3 color)
     #define NUMCASCADES 1
     #define NUMCASCADES 1
 #endif
 #endif
 
 
+#ifdef VSM_SHADOW
+float ReduceLightBleeding(float min, float p_max)  
+{  
+    return clamp((p_max - min) / (1.0 - min), 0.0, 1.0);  
+}
+
+float Chebyshev(float2 Moments, float depth)  
+{  
+    //One-tailed inequality valid if depth > Moments.x  
+    float p = float(depth <= Moments.x);  
+    //Compute variance.  
+    float Variance = Moments.y - (Moments.x * Moments.x); 
+
+    float minVariance = cVSMShadowParams.x;
+    Variance = max(Variance, minVariance);  
+    //Compute probabilistic upper bound.  
+    float d = depth - Moments.x;  
+    float p_max = Variance / (Variance + d*d); 
+    // Prevent light bleeding
+    p_max = ReduceLightBleeding(cVSMShadowParams.y, p_max);
+
+    return max(p, p_max);
+}
+#endif
+
 float GetShadow(float4 shadowPos)
 float GetShadow(float4 shadowPos)
 {
 {
-    #ifdef D3D11
-        shadowPos.xyz /= shadowPos.w;
-    #endif
-
-    #ifndef LQSHADOW
+    #if defined(SIMPLE_SHADOW)
+        // Take one sample
+        #ifdef D3D11
+            shadowPos.xyz /= shadowPos.w;
+        #endif
+        float inLight = SampleShadow(ShadowMap, shadowPos).r;
+        #ifndef SHADOWCMP
+            return cShadowIntensity.y + cShadowIntensity.x * inLight;
+        #else
+            #ifndef POINTLIGHT
+                return cShadowIntensity.y + cShadowIntensity.x * (inLight * shadowPos.w > shadowPos.z);
+            #else
+                return cShadowIntensity.y + cShadowIntensity.x * (inLight > shadowPos.z);
+            #endif
+        #endif
+    
+    #elif defined(PCF_SHADOW)
         // Take four samples and average them
         // Take four samples and average them
         // Note: in case of sampling a point light cube shadow, we optimize out the w divide as it has already been performed
         // Note: in case of sampling a point light cube shadow, we optimize out the w divide as it has already been performed
+        #ifdef D3D11
+            shadowPos.xyz /= shadowPos.w;
+        #endif
         #if !defined(POINTLIGHT) && !defined(D3D11)
         #if !defined(POINTLIGHT) && !defined(D3D11)
             float2 offsets = cShadowMapInvSize * shadowPos.w;
             float2 offsets = cShadowMapInvSize * shadowPos.w;
         #else
         #else
@@ -164,18 +254,10 @@ float GetShadow(float4 shadowPos)
                 return cShadowIntensity.y + dot(inLight > shadowPos.z, cShadowIntensity.x);
                 return cShadowIntensity.y + dot(inLight > shadowPos.z, cShadowIntensity.x);
             #endif
             #endif
         #endif
         #endif
-    #else
-        // Take one sample
-        float inLight = SampleShadow(ShadowMap, shadowPos).r;
-        #ifndef SHADOWCMP
-            return cShadowIntensity.y + cShadowIntensity.x * inLight;
-        #else
-            #ifndef POINTLIGHT
-                return cShadowIntensity.y + cShadowIntensity.x * (inLight * shadowPos.w > shadowPos.z);
-            #else
-                return cShadowIntensity.y + cShadowIntensity.x * (inLight > shadowPos.z);
-            #endif
-        #endif
+    
+    #elif defined(VSM_SHADOW)
+        float2 samples = Sample2D(ShadowMap, shadowPos.xy / shadowPos.w).rg;
+        return cShadowIntensity.y + cShadowIntensity.x * Chebyshev(samples, shadowPos.z/shadowPos.w);
     #endif
     #endif
 }
 }
 
 
@@ -223,19 +305,31 @@ float GetDirShadow(const float4 iShadowPos[NUMCASCADES], float depth)
     return GetDirShadowFade(GetShadow(shadowPos), depth);
     return GetDirShadowFade(GetShadow(shadowPos), depth);
 }
 }
 
 
-float GetDirShadowDeferred(float4 projWorldPos, float depth)
+float GetDirShadowDeferred(float4 projWorldPos, float3 normal, float depth)
 {
 {
     float4 shadowPos;
     float4 shadowPos;
 
 
-    if (depth < cShadowSplits.x)
-        shadowPos = mul(projWorldPos, cLightMatricesPS[0]);
-    else if (depth < cShadowSplits.y)
-        shadowPos = mul(projWorldPos, cLightMatricesPS[1]);
-    else if (depth < cShadowSplits.z)
-        shadowPos = mul(projWorldPos, cLightMatricesPS[2]);
-    else
-        shadowPos = mul(projWorldPos, cLightMatricesPS[3]);
-
+    #ifdef NORMALOFFSET
+        float cosAngle = saturate(1.0 - dot(normal, cLightDirPS));
+        if (depth < cShadowSplits.x)
+            shadowPos = mul(float4(projWorldPos.xyz + cosAngle * cNormalOffsetScalePS.x * normal, 1.0), cLightMatricesPS[0]);
+        else if (depth < cShadowSplits.y)
+            shadowPos = mul(float4(projWorldPos.xyz + cosAngle * cNormalOffsetScalePS.y * normal, 1.0), cLightMatricesPS[1]);
+        else if (depth < cShadowSplits.z)
+            shadowPos = mul(float4(projWorldPos.xyz + cosAngle * cNormalOffsetScalePS.z * normal, 1.0), cLightMatricesPS[2]);
+        else
+            shadowPos = mul(float4(projWorldPos.xyz + cosAngle * cNormalOffsetScalePS.w * normal, 1.0), cLightMatricesPS[3]);
+    #else
+        if (depth < cShadowSplits.x)
+            shadowPos = mul(projWorldPos, cLightMatricesPS[0]);
+        else if (depth < cShadowSplits.y)
+            shadowPos = mul(projWorldPos, cLightMatricesPS[1]);
+        else if (depth < cShadowSplits.z)
+            shadowPos = mul(projWorldPos, cLightMatricesPS[2]);
+        else
+            shadowPos = mul(projWorldPos, cLightMatricesPS[3]);
+    #endif
+    
     return GetDirShadowFade(GetShadow(shadowPos), depth);
     return GetDirShadowFade(GetShadow(shadowPos), depth);
 }
 }
 #endif
 #endif
@@ -251,16 +345,23 @@ float GetShadow(float4 iShadowPos[NUMCASCADES], float depth)
     #endif
     #endif
 }
 }
 
 
-float GetShadowDeferred(float4 projWorldPos, float depth)
+float GetShadowDeferred(float4 projWorldPos, float3 normal, float depth)
 {
 {
-    #if defined(DIRLIGHT)
-        return GetDirShadowDeferred(projWorldPos, depth);
-    #elif defined(SPOTLIGHT)
-        float4 shadowPos = mul(projWorldPos, cLightMatricesPS[1]);
-        return GetShadow(shadowPos);
+    #ifdef DIRLIGHT
+        return GetDirShadowDeferred(projWorldPos, normal, depth);
     #else
     #else
-        float3 shadowPos = projWorldPos.xyz - cLightPosPS.xyz;
-        return GetPointShadow(shadowPos);
+        #ifdef NORMALOFFSET
+            float cosAngle = saturate(1.0 - dot(normal, normalize(cLightPosPS - projWorldPos.xyz)));
+            projWorldPos.xyz += cosAngle * cNormalOffsetScalePS.x * normal;
+        #endif
+
+        #ifdef SPOTLIGHT
+            float4 shadowPos = mul(projWorldPos, cLightMatricesPS[1]);
+            return GetShadow(shadowPos);
+        #else
+            float3 shadowPos = projWorldPos.xyz - cLightPosPS.xyz;
+            return GetPointShadow(shadowPos);
+        #endif
     #endif
     #endif
 }
 }
 #endif
 #endif

+ 8 - 5
Resources/CoreData/Shaders/HLSL/LitParticle.hlsl

@@ -5,7 +5,7 @@
 #include "Fog.hlsl"
 #include "Fog.hlsl"
 
 
 void VS(float4 iPos : POSITION,
 void VS(float4 iPos : POSITION,
-    #ifndef BILLBOARD
+    #if !defined(BILLBOARD) && !defined(TRAILFACECAM)
         float3 iNormal : NORMAL,
         float3 iNormal : NORMAL,
     #endif
     #endif
     #ifndef NOUV
     #ifndef NOUV
@@ -19,11 +19,14 @@ void VS(float4 iPos : POSITION,
         int4 iBlendIndices : BLENDINDICES,
         int4 iBlendIndices : BLENDINDICES,
     #endif
     #endif
     #ifdef INSTANCED
     #ifdef INSTANCED
-        float4x3 iModelInstance : TEXCOORD2,
+        float4x3 iModelInstance : TEXCOORD4,
     #endif
     #endif
-    #ifdef BILLBOARD
+    #if defined(BILLBOARD) || defined(DIRBILLBOARD)
         float2 iSize : TEXCOORD1,
         float2 iSize : TEXCOORD1,
     #endif
     #endif
+    #if defined(TRAILFACECAM) || defined(TRAILBONE)
+        float4 iTangent : TANGENT,
+    #endif
     out float2 oTexCoord : TEXCOORD0,
     out float2 oTexCoord : TEXCOORD0,
     out float4 oWorldPos : TEXCOORD3,
     out float4 oWorldPos : TEXCOORD3,
     #if PERPIXEL
     #if PERPIXEL
@@ -72,7 +75,7 @@ void VS(float4 iPos : POSITION,
 
 
         #ifdef SHADOW
         #ifdef SHADOW
             // Shadow projection: transform from world space to shadow space
             // Shadow projection: transform from world space to shadow space
-            GetShadowPos(projWorldPos, oShadowPos);
+            GetShadowPos(projWorldPos, float3(0, 0, 0), oShadowPos);
         #endif
         #endif
 
 
         #ifdef SPOTLIGHT
         #ifdef SPOTLIGHT
@@ -103,7 +106,7 @@ void PS(float2 iTexCoord : TEXCOORD0,
         #ifdef SPOTLIGHT
         #ifdef SPOTLIGHT
             float4 iSpotPos : TEXCOORD5,
             float4 iSpotPos : TEXCOORD5,
         #endif
         #endif
-        #ifdef CUBEMASK
+        #ifdef POINTLIGHT
             float3 iCubeMaskVec : TEXCOORD5,
             float3 iCubeMaskVec : TEXCOORD5,
         #endif
         #endif
     #else
     #else

+ 34 - 49
Resources/CoreData/Shaders/HLSL/LitSolid.hlsl

@@ -6,7 +6,7 @@
 #include "Fog.hlsl"
 #include "Fog.hlsl"
 
 
 void VS(float4 iPos : POSITION,
 void VS(float4 iPos : POSITION,
-    #ifndef BILLBOARD
+    #if !defined(BILLBOARD) && !defined(TRAILFACECAM)
         float3 iNormal : NORMAL,
         float3 iNormal : NORMAL,
     #endif
     #endif
     #ifndef NOUV
     #ifndef NOUV
@@ -18,7 +18,7 @@ void VS(float4 iPos : POSITION,
     #if defined(LIGHTMAP) || defined(AO)
     #if defined(LIGHTMAP) || defined(AO)
         float2 iTexCoord2 : TEXCOORD1,
         float2 iTexCoord2 : TEXCOORD1,
     #endif
     #endif
-    #ifdef NORMALMAP
+    #if defined(NORMALMAP) || defined(TRAILFACECAM) || defined(TRAILBONE)
         float4 iTangent : TANGENT,
         float4 iTangent : TANGENT,
     #endif
     #endif
     #ifdef SKINNED
     #ifdef SKINNED
@@ -26,9 +26,9 @@ void VS(float4 iPos : POSITION,
         int4 iBlendIndices : BLENDINDICES,
         int4 iBlendIndices : BLENDINDICES,
     #endif
     #endif
     #ifdef INSTANCED
     #ifdef INSTANCED
-        float4x3 iModelInstance : TEXCOORD2,
+        float4x3 iModelInstance : TEXCOORD4,
     #endif
     #endif
-    #ifdef BILLBOARD
+    #if defined(BILLBOARD) || defined(DIRBILLBOARD)
         float2 iSize : TEXCOORD1,
         float2 iSize : TEXCOORD1,
     #endif
     #endif
     #ifndef NORMALMAP
     #ifndef NORMALMAP
@@ -101,7 +101,7 @@ void VS(float4 iPos : POSITION,
 
 
         #ifdef SHADOW
         #ifdef SHADOW
             // Shadow projection: transform from world space to shadow space
             // Shadow projection: transform from world space to shadow space
-            GetShadowPos(projWorldPos, oShadowPos);
+            GetShadowPos(projWorldPos, oNormal, oShadowPos);
         #endif
         #endif
 
 
         #ifdef SPOTLIGHT
         #ifdef SPOTLIGHT
@@ -152,7 +152,7 @@ void PS(
         #ifdef SPOTLIGHT
         #ifdef SPOTLIGHT
             float4 iSpotPos : TEXCOORD5,
             float4 iSpotPos : TEXCOORD5,
         #endif
         #endif
-        #ifdef CUBEMASK
+        #ifdef POINTLIGHT
             float3 iCubeMaskVec : TEXCOORD5,
             float3 iCubeMaskVec : TEXCOORD5,
         #endif
         #endif
     #else
     #else
@@ -225,43 +225,33 @@ void PS(
         float3 lightColor;
         float3 lightColor;
         float3 finalColor;
         float3 finalColor;
 
 
-        #if defined(LIGHTMAP) && defined(SHADOW)
-            float diff = 1-GetShadow(iShadowPos, iWorldPos.w);
+        float diff = GetDiffuse(normal, iWorldPos.xyz, lightDir);
 
 
-            finalColor = diff * diffColor.rgb * cAmbientColor;
+        #ifdef SHADOW
+            diff *= GetShadow(iShadowPos, iWorldPos.w);
+        #endif
 
 
-            oColor = float4(GetLitFog(finalColor, fogFactor), diffColor.a);
-		#elif defined(LIGHTMAP)            
-            oColor = float4(0.0, 0.0, 0.0, 0.0);
+        #if defined(SPOTLIGHT)
+            lightColor = iSpotPos.w > 0.0 ? Sample2DProj(LightSpotMap, iSpotPos).rgb * cLightColor.rgb : 0.0;
+        #elif defined(CUBEMASK)
+            lightColor = SampleCube(LightCubeMap, iCubeMaskVec).rgb * cLightColor.rgb;
         #else
         #else
-            float diff = GetDiffuse(normal, iWorldPos.xyz, lightDir);
-
-            #ifdef SHADOW
-                diff *= GetShadow(iShadowPos, iWorldPos.w);
-            #endif
-
-            #if defined(SPOTLIGHT)
-                lightColor = iSpotPos.w > 0.0 ? Sample2DProj(LightSpotMap, iSpotPos).rgb * cLightColor.rgb : 0.0;
-            #elif defined(CUBEMASK)
-                lightColor = SampleCube(LightCubeMap, iCubeMaskVec).rgb * cLightColor.rgb;
-            #else
-                lightColor = cLightColor.rgb;
-            #endif
-        
-            #ifdef SPECULAR
-                float spec = GetSpecular(normal, cCameraPosPS - iWorldPos.xyz, lightDir, cMatSpecColor.a);
-                finalColor = diff * lightColor * (diffColor.rgb + spec * specColor * cLightColor.a);
-            #else
-                finalColor = diff * lightColor * diffColor.rgb;
-            #endif
+            lightColor = cLightColor.rgb;
+        #endif
+    
+        #ifdef SPECULAR
+            float spec = GetSpecular(normal, cCameraPosPS - iWorldPos.xyz, lightDir, cMatSpecColor.a);
+            finalColor = diff * lightColor * (diffColor.rgb + spec * specColor * cLightColor.a);
+        #else
+            finalColor = diff * lightColor * diffColor.rgb;
+        #endif
 
 
-            #ifdef AMBIENT
-                finalColor += cAmbientColor * diffColor.rgb;
-                finalColor += cMatEmissiveColor;
-                oColor = float4(GetFog(finalColor, fogFactor), diffColor.a);
-            #else
-                oColor = float4(GetLitFog(finalColor, fogFactor), diffColor.a);
-            #endif
+        #ifdef AMBIENT
+            finalColor += cAmbientColor.rgb * diffColor.rgb;
+            finalColor += cMatEmissiveColor;
+            oColor = float4(GetFog(finalColor, fogFactor), diffColor.a);
+        #else
+            oColor = float4(GetLitFog(finalColor, fogFactor), diffColor.a);
         #endif
         #endif
     #elif defined(PREPASS)
     #elif defined(PREPASS)
         // Fill light pre-pass G-Buffer
         // Fill light pre-pass G-Buffer
@@ -277,7 +267,7 @@ void PS(
         float3 finalColor = iVertexLight * diffColor.rgb;
         float3 finalColor = iVertexLight * diffColor.rgb;
         #ifdef AO
         #ifdef AO
             // If using AO, the vertex light ambient is black, calculate occluded ambient here
             // If using AO, the vertex light ambient is black, calculate occluded ambient here
-            finalColor += Sample2D(EmissiveMap, iTexCoord2).rgb * cAmbientColor * diffColor.rgb;
+            finalColor += Sample2D(EmissiveMap, iTexCoord2).rgb * cAmbientColor.rgb * diffColor.rgb;
         #endif
         #endif
         #ifdef ENVCUBEMAP
         #ifdef ENVCUBEMAP
             finalColor += cMatEnvMapColor * SampleCube(EnvCubeMap, reflect(iReflectionVec, normal)).rgb;
             finalColor += cMatEnvMapColor * SampleCube(EnvCubeMap, reflect(iReflectionVec, normal)).rgb;
@@ -300,7 +290,7 @@ void PS(
         float3 finalColor = iVertexLight * diffColor.rgb;
         float3 finalColor = iVertexLight * diffColor.rgb;
         #ifdef AO
         #ifdef AO
             // If using AO, the vertex light ambient is black, calculate occluded ambient here
             // If using AO, the vertex light ambient is black, calculate occluded ambient here
-            finalColor += Sample2D(EmissiveMap, iTexCoord2).rgb * cAmbientColor * diffColor.rgb;
+            finalColor += Sample2D(EmissiveMap, iTexCoord2).rgb * cAmbientColor.rgb * diffColor.rgb;
         #endif
         #endif
 
 
         #ifdef MATERIAL
         #ifdef MATERIAL
@@ -312,16 +302,11 @@ void PS(
             finalColor += lightInput.rgb * diffColor.rgb + lightSpecColor * specColor;
             finalColor += lightInput.rgb * diffColor.rgb + lightSpecColor * specColor;
         #endif
         #endif
 
 
+        #ifdef ENVCUBEMAP
+            finalColor += cMatEnvMapColor * SampleCube(EnvCubeMap, reflect(iReflectionVec, normal)).rgb;
+        #endif
         #ifdef LIGHTMAP
         #ifdef LIGHTMAP
             finalColor += Sample2D(EmissiveMap, iTexCoord2).rgb * diffColor.rgb;
             finalColor += Sample2D(EmissiveMap, iTexCoord2).rgb * diffColor.rgb;
-			
-			#ifdef ENVCUBEMAP
-				finalColor += cMatEnvMapColor * SampleCube(EnvCubeMap, reflect(iReflectionVec, normal)).rgb * Sample2D(EmissiveMap, iTexCoord2).rgb;
-			#endif
-		#else
-			#ifdef ENVCUBEMAP
-				finalColor += cMatEnvMapColor * SampleCube(EnvCubeMap, reflect(iReflectionVec, normal)).rgb;
-			#endif
         #endif
         #endif
         #ifdef EMISSIVEMAP
         #ifdef EMISSIVEMAP
             finalColor += cMatEmissiveColor * Sample2D(EmissiveMap, iTexCoord.xy).rgb;
             finalColor += cMatEmissiveColor * Sample2D(EmissiveMap, iTexCoord.xy).rgb;

+ 34 - 0
Resources/CoreData/Shaders/HLSL/PBR.hlsl

@@ -0,0 +1,34 @@
+#include "BRDF.hlsl"
+#ifdef COMPILEPS
+
+	//Return the PBR BRDF value
+	// lightDir  = the vector to the light
+	// lightVev  = normalised lightDir
+	// toCamera  = vector to the camera
+	// normal    = surface normal of the pixel
+	// roughness = roughness of the pixel
+	// diffColor = the rgb color of the pixel
+	// specColor = the rgb specular color of the pixel
+	float3 GetBRDF(float3 lightDir, float3 lightVec, float3 toCamera, float3 normal, float roughness, float3 diffColor, float3 specColor)
+	{
+
+        const float3 Hn = normalize(toCamera + lightDir);
+        const float vdh = clamp((dot(toCamera, Hn)), M_EPSILON, 1.0);
+        const float ndh = clamp((dot(normal, Hn)), M_EPSILON, 1.0);
+        const float ndl = clamp((dot(normal, lightVec)), M_EPSILON, 1.0);
+        const float ndv = clamp((dot(normal, toCamera)), M_EPSILON, 1.0);
+
+        const float3 diffuseFactor = Diffuse(diffColor, roughness, ndv, ndl, vdh);
+        float3 specularFactor = 0;
+
+        #ifdef SPECULAR
+            const float3 fresnelTerm = Fresnel(specColor, vdh) ;
+            const float distTerm = Distribution(ndh, roughness);
+            const float visTerm = Visibility(ndl, ndv, roughness);
+
+            specularFactor = distTerm * visTerm * fresnelTerm / M_PI;
+        #endif
+
+        return diffuseFactor + specularFactor;
+	}
+#endif

+ 120 - 0
Resources/CoreData/Shaders/HLSL/PBRDeferred.hlsl

@@ -0,0 +1,120 @@
+#include "Uniforms.hlsl"
+#include "Samplers.hlsl"
+#include "Transform.hlsl"
+#include "ScreenPos.hlsl"
+#include "Lighting.hlsl"
+#include "Constants.hlsl"
+#include "PBR.hlsl"
+#line 9
+
+void VS(float4 iPos : POSITION,
+    #ifdef DIRLIGHT
+        out float2 oScreenPos : TEXCOORD0,
+    #else
+        out float4 oScreenPos : TEXCOORD0,
+    #endif
+    out float3 oFarRay : TEXCOORD1,
+    #ifdef ORTHO
+        out float3 oNearRay : TEXCOORD2,
+    #endif
+    out float4 oPos : OUTPOSITION)
+{
+    float4x3 modelMatrix = iModelMatrix;
+    float3 worldPos = GetWorldPos(modelMatrix);
+    oPos = GetClipPos(worldPos);
+    #ifdef DIRLIGHT
+        oScreenPos = GetScreenPosPreDiv(oPos);
+        oFarRay = GetFarRay(oPos);
+        #ifdef ORTHO
+            oNearRay = GetNearRay(oPos);
+        #endif
+    #else
+        oScreenPos = GetScreenPos(oPos);
+        oFarRay = GetFarRay(oPos) * oPos.w;
+        #ifdef ORTHO
+            oNearRay = GetNearRay(oPos) * oPos.w;
+        #endif
+    #endif
+}
+
+void PS(
+    #ifdef DIRLIGHT
+        float2 iScreenPos : TEXCOORD0,
+    #else
+        float4 iScreenPos : TEXCOORD0,
+    #endif
+    float3 iFarRay : TEXCOORD1,
+    #ifdef ORTHO
+        float3 iNearRay : TEXCOORD2,
+    #endif
+
+    float2 iFragPos : VPOS,
+    out float4 oColor : OUTCOLOR0)
+{
+    // If rendering a directional light quad, optimize out the w divide
+    #ifdef DIRLIGHT
+        float3 depth = Sample2DLod0(DepthBuffer, iScreenPos).r;
+        #ifdef HWDEPTH
+            depth = ReconstructDepth(depth);
+        #endif
+        #ifdef ORTHO
+            float3 worldPos = lerp(iNearRay, iFarRay, depth);
+        #else
+            float3 worldPos = iFarRay * depth;
+        #endif
+        const float4 albedoInput = Sample2DLod0(AlbedoBuffer, iScreenPos);
+        const float4 normalInput = Sample2DLod0(NormalBuffer, iScreenPos);
+        const float4 specularInput = Sample2DLod0(SpecMap, iScreenPos);
+    #else
+        float depth = Sample2DProj(DepthBuffer, iScreenPos).r;
+        #ifdef HWDEPTH
+            depth = ReconstructDepth(depth);
+        #endif
+        #ifdef ORTHO
+            float3 worldPos = lerp(iNearRay, iFarRay, depth) / iScreenPos.w;
+        #else
+            float3 worldPos = iFarRay * depth / iScreenPos.w;
+        #endif
+        const float4 albedoInput = Sample2DProj(AlbedoBuffer, iScreenPos);
+        const float4 normalInput = Sample2DProj(NormalBuffer, iScreenPos);
+        const float4 specularInput = Sample2DProj(SpecMap, iScreenPos);
+    #endif
+
+    // Position acquired via near/far ray is relative to camera. Bring position to world space
+    float3 eyeVec = -worldPos;
+    worldPos += cCameraPosPS;
+
+    float3 normal = normalInput.rgb;
+    const float roughness = length(normal);
+    normal = normalize(normal);
+
+    const float3 specColor = specularInput.rgb;
+
+    const float4 projWorldPos = float4(worldPos, 1.0);
+
+    float3 lightDir;
+    float atten = GetAtten(normal, worldPos, lightDir);
+
+    float shadow = 1;
+    #ifdef SHADOW
+        shadow *= GetShadowDeferred(projWorldPos, normal, depth);
+    #endif
+
+    #if defined(SPOTLIGHT)
+        const float4 spotPos = mul(projWorldPos, cLightMatricesPS[0]);
+        const float3 lightColor = spotPos.w > 0.0 ? Sample2DProj(LightSpotMap, spotPos).rgb * cLightColor.rgb : 0.0;
+    #elif defined(CUBEMASK)
+        const float3 lightColor = texCUBE(sLightCubeMap, mul(worldPos - cLightPosPS.xyz, (float3x3)cLightMatricesPS[0])).rgb * cLightColor.rgb;
+    #else
+        const float3 lightColor = cLightColor.rgb;
+    #endif
+
+    const float3 toCamera = normalize(eyeVec);
+    const float3 lightVec = normalize(lightDir);
+    const float ndl = clamp(abs(dot(normal, lightVec)), M_EPSILON, 1.0);
+
+    float3 BRDF = GetBRDF(lightDir, lightVec, toCamera, normal, roughness, albedoInput.rgb, specColor);
+
+    oColor.a = 1;
+    oColor.rgb  = BRDF * lightColor * shadow * atten / M_PI;
+}

+ 337 - 0
Resources/CoreData/Shaders/HLSL/PBRLitSolid.hlsl

@@ -0,0 +1,337 @@
+#include "Uniforms.hlsl"
+#include "Samplers.hlsl"
+#include "Transform.hlsl"
+#include "ScreenPos.hlsl"
+#include "Lighting.hlsl"
+#include "Constants.hlsl"
+#include "Fog.hlsl"
+#include "PBR.hlsl"
+#include "IBL.hlsl"
+
+void VS(float4 iPos : POSITION,
+    #if !defined(BILLBOARD) && !defined(TRAILFACECAM)
+        float3 iNormal : NORMAL,
+    #endif
+    #ifndef NOUV
+        float2 iTexCoord : TEXCOORD0,
+    #endif
+    #ifdef VERTEXCOLOR
+        float4 iColor : COLOR0,
+    #endif
+    #if defined(LIGHTMAP) || defined(AO)
+        float2 iTexCoord2 : TEXCOORD1,
+    #endif
+    #if defined(NORMALMAP)|| defined(IBL) || defined(TRAILFACECAM) || defined(TRAILBONE)
+        float4 iTangent : TANGENT,
+    #endif
+    #ifdef SKINNED
+        float4 iBlendWeights : BLENDWEIGHT,
+        int4 iBlendIndices : BLENDINDICES,
+    #endif
+    #ifdef INSTANCED
+        float4x3 iModelInstance : TEXCOORD4,
+    #endif
+    #if defined(BILLBOARD) || defined(DIRBILLBOARD)
+        float2 iSize : TEXCOORD1,
+    #endif
+    #if defined(NORMALMAP) || defined(IBL)
+        out float4 oTexCoord : TEXCOORD0,
+        out float4 oTangent : TEXCOORD3,
+    #else
+        out float2 oTexCoord : TEXCOORD0,
+    #endif
+    out float3 oNormal : TEXCOORD1,
+    out float4 oWorldPos : TEXCOORD2,
+    #ifdef PERPIXEL
+        #ifdef SHADOW
+            out float4 oShadowPos[NUMCASCADES] : TEXCOORD4,
+        #endif
+        #ifdef SPOTLIGHT
+            out float4 oSpotPos : TEXCOORD5,
+        #endif
+        #ifdef POINTLIGHT
+            out float3 oCubeMaskVec : TEXCOORD5,
+        #endif
+    #else
+        out float3 oVertexLight : TEXCOORD4,
+        out float4 oScreenPos : TEXCOORD5,
+        #ifdef ENVCUBEMAP
+            out float3 oReflectionVec : TEXCOORD6,
+        #endif
+        #if defined(LIGHTMAP) || defined(AO)
+            out float2 oTexCoord2 : TEXCOORD7,
+        #endif
+    #endif
+    #ifdef VERTEXCOLOR
+        out float4 oColor : COLOR0,
+    #endif
+    #if defined(D3D11) && defined(CLIPPLANE)
+        out float oClip : SV_CLIPDISTANCE0,
+    #endif
+    out float4 oPos : OUTPOSITION)
+{
+    // Define a 0,0 UV coord if not expected from the vertex data
+    #ifdef NOUV
+        const float2 iTexCoord = float2(0.0, 0.0);
+    #endif
+
+    const float4x3 modelMatrix = iModelMatrix;
+    const float3 worldPos = GetWorldPos(modelMatrix);
+    oPos = GetClipPos(worldPos);
+    oNormal = GetWorldNormal(modelMatrix);
+    oWorldPos = float4(worldPos, GetDepth(oPos));
+
+    #if defined(D3D11) && defined(CLIPPLANE)
+        oClip = dot(oPos, cClipPlane);
+    #endif
+
+    #ifdef VERTEXCOLOR
+        oColor = iColor;
+    #endif
+
+    #if defined(NORMALMAP) || defined(IBL)
+        const float3 tangent = GetWorldTangent(modelMatrix);
+        const float3 bitangent = cross(tangent, oNormal) * iTangent.w;
+        oTexCoord = float4(GetTexCoord(iTexCoord), bitangent.xy);
+        oTangent = float4(tangent, bitangent.z);
+    #else
+        oTexCoord = GetTexCoord(iTexCoord);
+    #endif
+
+    #ifdef PERPIXEL
+        // Per-pixel forward lighting
+        const float4 projWorldPos = float4(worldPos.xyz, 1.0);
+
+        #ifdef SHADOW
+            // Shadow projection: transform from world space to shadow space
+            GetShadowPos(projWorldPos, oNormal, oShadowPos);
+        #endif
+
+        #ifdef SPOTLIGHT
+            // Spotlight projection: transform from world space to projector texture coordinates
+            oSpotPos = mul(projWorldPos, cLightMatrices[0]);
+        #endif
+
+        #ifdef POINTLIGHT
+            oCubeMaskVec = mul(worldPos - cLightPos.xyz, (float3x3)cLightMatrices[0]);
+        #endif
+    #else
+        // Ambient & per-vertex lighting
+        #if defined(LIGHTMAP) || defined(AO)
+            // If using lightmap, disregard zone ambient light
+            // If using AO, calculate ambient in the PS
+            oVertexLight = float3(0.0, 0.0, 0.0);
+            oTexCoord2 = iTexCoord2;
+        #else
+            oVertexLight = GetAmbient(GetZonePos(worldPos));
+        #endif
+
+        #ifdef NUMVERTEXLIGHTS
+            for (int i = 0; i < NUMVERTEXLIGHTS; ++i)
+                oVertexLight += GetVertexLight(i, worldPos, oNormal) * cVertexLights[i * 3].rgb;
+        #endif
+
+        oScreenPos = GetScreenPos(oPos);
+
+        #ifdef ENVCUBEMAP
+            oReflectionVec = worldPos - cCameraPos;
+        #endif
+    #endif
+}
+
+void PS(
+    #if defined(NORMALMAP) || defined(IBL)
+        float4 iTexCoord : TEXCOORD0,
+        float4 iTangent : TEXCOORD3,
+    #else
+        float2 iTexCoord : TEXCOORD0,
+    #endif
+    float3 iNormal : TEXCOORD1,
+    float4 iWorldPos : TEXCOORD2,
+    #ifdef PERPIXEL
+        #ifdef SHADOW
+            float4 iShadowPos[NUMCASCADES] : TEXCOORD4,
+        #endif
+        #ifdef SPOTLIGHT
+            float4 iSpotPos : TEXCOORD5,
+        #endif
+        #ifdef POINTLIGHT
+            float3 iCubeMaskVec : TEXCOORD5,
+        #endif
+    #else
+        float3 iVertexLight : TEXCOORD4,
+        float4 iScreenPos : TEXCOORD5,
+        #ifdef ENVCUBEMAP
+            float3 iReflectionVec : TEXCOORD6,
+        #endif
+        #if defined(LIGHTMAP) || defined(AO)
+            float2 iTexCoord2 : TEXCOORD7,
+        #endif
+    #endif
+    #ifdef VERTEXCOLOR
+        float4 iColor : COLOR0,
+    #endif
+    #if defined(D3D11) && defined(CLIPPLANE)
+        float iClip : SV_CLIPDISTANCE0,
+    #endif
+    #ifdef PREPASS
+        out float4 oDepth : OUTCOLOR1,
+    #endif
+    #ifdef DEFERRED
+        out float4 oAlbedo : OUTCOLOR1,
+        out float4 oNormal : OUTCOLOR2,
+        out float4 oDepth : OUTCOLOR3,
+        #ifndef D3D11
+            float2 iFragPos : VPOS,
+        #else
+            float4 iFragPos : SV_Position,
+        #endif
+    #endif
+    out float4 oColor : OUTCOLOR0)
+{
+    // Get material diffuse albedo
+    #ifdef DIFFMAP
+        const float4 diffInput = Sample2D(DiffMap, iTexCoord.xy);
+        #ifdef ALPHAMASK
+            if (diffInput.a < 0.5)
+                discard;
+        #endif
+        float4 diffColor = cMatDiffColor * diffInput;
+    #else
+        float4 diffColor = cMatDiffColor;
+    #endif
+
+    #ifdef VERTEXCOLOR
+        diffColor *= iColor;
+    #endif
+
+    // Get material specular albedo
+    #ifdef METALLIC // METALNESS
+        float4 roughMetalSrc = Sample2D(RoughMetalFresnel, iTexCoord.xy);
+
+        float roughness = roughMetalSrc.r + cRoughness;
+        float metalness = roughMetalSrc.g + cMetallic;
+    #else
+        float roughness = cRoughness;
+        float metalness = cMetallic;
+    #endif
+
+    roughness *= roughness;
+
+    roughness = clamp(roughness, ROUGHNESS_FLOOR, 1.0);
+    metalness = clamp(metalness, METALNESS_FLOOR, 1.0);
+
+    float3 specColor = lerp(0.08 * cMatSpecColor.rgb, diffColor.rgb, metalness);
+    specColor *= cMatSpecColor.rgb;
+    diffColor.rgb = diffColor.rgb - diffColor.rgb * metalness; // Modulate down the diffuse
+
+    // Get normal
+    #if defined(NORMALMAP) || defined(DIRBILLBOARD) || defined(IBL)
+        const float3 tangent = normalize(iTangent.xyz);
+        const float3 bitangent = normalize(float3(iTexCoord.zw, iTangent.w));
+        const float3x3 tbn = float3x3(tangent, bitangent, iNormal);
+    #endif
+
+    #ifdef NORMALMAP
+        const float3 nn = DecodeNormal(Sample2D(NormalMap, iTexCoord.xy));
+        //nn.rg *= 2.0;
+        const float3 normal = normalize(mul(nn, tbn));
+    #else
+        const float3 normal = normalize(iNormal);
+    #endif
+
+    // Get fog factor
+    #ifdef HEIGHTFOG
+        const float fogFactor = GetHeightFogFactor(iWorldPos.w, iWorldPos.y);
+    #else
+        const float fogFactor = GetFogFactor(iWorldPos.w);
+    #endif
+
+    #if defined(PERPIXEL)
+        // Per-pixel forward lighting
+        float3 lightDir;
+        float3 lightColor;
+        float3 finalColor;
+
+        float atten = GetAtten(normal, iWorldPos.xyz, lightDir);
+
+        float shadow = 1.0;
+
+        #ifdef SHADOW
+            shadow *= GetShadow(iShadowPos, iWorldPos.w);
+        #endif
+
+        #if defined(SPOTLIGHT)
+            lightColor = iSpotPos.w > 0.0 ? Sample2DProj(LightSpotMap, iSpotPos).rgb * cLightColor.rgb : 0.0;
+        #elif defined(CUBEMASK)
+            lightColor = SampleCube(LightCubeMap, iCubeMaskVec).rgb * cLightColor.rgb;
+        #else
+            lightColor = cLightColor.rgb;
+        #endif
+
+        const float3 toCamera = normalize(cCameraPosPS - iWorldPos.xyz);
+
+        const float3 lightVec = normalize(lightDir);
+        const float ndl = clamp((dot(normal, lightVec)), M_EPSILON, 1.0);
+
+
+        float3 BRDF = GetBRDF(lightDir, lightVec, toCamera, normal, roughness, diffColor.rgb, specColor);
+        finalColor.rgb = BRDF * lightColor * (atten * shadow) / M_PI;
+
+        #ifdef AMBIENT
+            finalColor += cAmbientColor.rgb * diffColor.rgb;
+            finalColor += cMatEmissiveColor;
+            oColor = float4(GetFog(finalColor, fogFactor), diffColor.a);
+        #else
+            oColor = float4(GetLitFog(finalColor, fogFactor), diffColor.a);
+        #endif
+    #elif defined(DEFERRED)
+        // Fill deferred G-buffer
+        const float3 spareData = 0; // Can be used to pass more data to deferred renderer
+        oColor = float4(specColor, spareData.r);
+        oAlbedo = float4(diffColor.rgb, spareData.g);
+        oNormal = float4(normalize(normal) * roughness, spareData.b);
+        oDepth = iWorldPos.w;
+    #else
+        // Ambient & per-vertex lighting
+        float3 finalColor = iVertexLight * diffColor.rgb;
+        #ifdef AO
+            // If using AO, the vertex light ambient is black, calculate occluded ambient here
+            finalColor += Sample2D(EmissiveMap, iTexCoord2).rgb * cAmbientColor.rgb * diffColor.rgb;
+        #endif
+
+        #ifdef MATERIAL
+            // Add light pre-pass accumulation result
+            // Lights are accumulated at half intensity. Bring back to full intensity now
+            float4 lightInput = 2.0 * Sample2DProj(LightBuffer, iScreenPos);
+            float3 lightSpecColor = lightInput.a * lightInput.rgb / max(GetIntensity(lightInput.rgb), 0.001);
+
+            finalColor += lightInput.rgb * diffColor.rgb + lightSpecColor * specColor;
+        #endif
+
+        const float3 toCamera = normalize(iWorldPos.xyz - cCameraPosPS);
+
+        const float3 reflection = normalize(reflect(toCamera, normal));
+        float3 cubeColor = iVertexLight.rgb;
+
+        #ifdef IBL
+            const float3 iblColor = ImageBasedLighting(reflection, tangent, bitangent, normal, toCamera, diffColor, specColor, roughness, cubeColor);
+            const float gamma = 0;
+            finalColor += iblColor;
+        #endif
+
+        #ifdef ENVCUBEMAP
+            finalColor += cMatEnvMapColor * SampleCube(EnvCubeMap, reflect(iReflectionVec, normal)).rgb;
+        #endif
+        #ifdef LIGHTMAP
+            finalColor += Sample2D(EmissiveMap, iTexCoord2).rgb * diffColor.rgb;
+        #endif
+        #ifdef EMISSIVEMAP
+            finalColor += cMatEmissiveColor * Sample2D(EmissiveMap, iTexCoord.xy).rgb;
+        #else
+            finalColor += cMatEmissiveColor;
+        #endif
+
+        oColor = float4(GetFog(finalColor, fogFactor), diffColor.a);
+    #endif
+}

+ 6 - 2
Resources/CoreData/Shaders/HLSL/PrepassLight.hlsl

@@ -71,6 +71,10 @@ void PS(
         float4 normalInput = Sample2DProj(NormalBuffer, iScreenPos);
         float4 normalInput = Sample2DProj(NormalBuffer, iScreenPos);
     #endif
     #endif
 
 
+    // Position acquired via near/far ray is relative to camera. Bring position to world space
+    float3 eyeVec = -worldPos;
+    worldPos += cCameraPosPS;
+
     float3 normal = normalize(normalInput.rgb * 2.0 - 1.0);
     float3 normal = normalize(normalInput.rgb * 2.0 - 1.0);
     float4 projWorldPos = float4(worldPos, 1.0);
     float4 projWorldPos = float4(worldPos, 1.0);
     float3 lightColor;
     float3 lightColor;
@@ -80,7 +84,7 @@ void PS(
     float diff = 0.5 * GetDiffuse(normal, worldPos, lightDir);
     float diff = 0.5 * GetDiffuse(normal, worldPos, lightDir);
 
 
     #ifdef SHADOW
     #ifdef SHADOW
-        diff *= GetShadowDeferred(projWorldPos, depth);
+        diff *= GetShadowDeferred(projWorldPos, normal, depth);
     #endif
     #endif
 
 
     #if defined(SPOTLIGHT)
     #if defined(SPOTLIGHT)
@@ -93,7 +97,7 @@ void PS(
     #endif
     #endif
 
 
     #ifdef SPECULAR
     #ifdef SPECULAR
-        float spec = lightColor.g * GetSpecular(normal, -worldPos, lightDir, normalInput.a * 255.0);
+        float spec = lightColor.g * GetSpecular(normal, eyeVec, lightDir, normalInput.a * 255.0);
         oColor = diff * float4(lightColor, spec * cLightColor.a);
         oColor = diff * float4(lightColor, spec * cLightColor.a);
     #else
     #else
         oColor = diff * float4(lightColor, 0.0);
         oColor = diff * float4(lightColor, 0.0);

+ 10 - 1
Resources/CoreData/Shaders/HLSL/Samplers.hlsl

@@ -4,6 +4,7 @@
 #define Sample2DProj(tex, uv) t##tex.Sample(s##tex, uv.xy / uv.w)
 #define Sample2DProj(tex, uv) t##tex.Sample(s##tex, uv.xy / uv.w)
 #define Sample2DLod0(tex, uv) t##tex.SampleLevel(s##tex, uv, 0.0)
 #define Sample2DLod0(tex, uv) t##tex.SampleLevel(s##tex, uv, 0.0)
 #define SampleCube(tex, uv) t##tex.Sample(s##tex, uv)
 #define SampleCube(tex, uv) t##tex.Sample(s##tex, uv)
+#define SampleCubeLOD(tex, uv) t##tex.SampleLevel(s##tex, uv.xyz, uv.w)
 #define SampleShadow(tex, uv) t##tex.SampleCmpLevelZero(s##tex, uv.xy, uv.z)
 #define SampleShadow(tex, uv) t##tex.SampleCmpLevelZero(s##tex, uv.xy, uv.z)
 #endif
 #endif
 
 
@@ -18,6 +19,7 @@ sampler2D sAlbedoBuffer : register(s0);
 sampler2D sNormalMap : register(s1);
 sampler2D sNormalMap : register(s1);
 sampler2D sNormalBuffer : register(s1);
 sampler2D sNormalBuffer : register(s1);
 sampler2D sSpecMap : register(s2);
 sampler2D sSpecMap : register(s2);
+sampler2D sRoughMetalFresnel : register(s2); //R: Roughness, G: Metal
 sampler2D sEmissiveMap : register(s3);
 sampler2D sEmissiveMap : register(s3);
 sampler2D sEnvMap : register(s4);
 sampler2D sEnvMap : register(s4);
 sampler3D sVolumeMap : register(s5);
 sampler3D sVolumeMap : register(s5);
@@ -37,6 +39,7 @@ sampler3D sZoneVolumeMap : register(s15);
 #define Sample2DProj(tex, uv) tex2Dproj(s##tex, uv)
 #define Sample2DProj(tex, uv) tex2Dproj(s##tex, uv)
 #define Sample2DLod0(tex, uv) tex2Dlod(s##tex, float4(uv, 0.0, 0.0))
 #define Sample2DLod0(tex, uv) tex2Dlod(s##tex, float4(uv, 0.0, 0.0))
 #define SampleCube(tex, uv) texCUBE(s##tex, uv)
 #define SampleCube(tex, uv) texCUBE(s##tex, uv)
+#define SampleCubeLOD(tex, uv) texCUBElod(s##tex, uv)
 #define SampleShadow(tex, uv) tex2Dproj(s##tex, uv)
 #define SampleShadow(tex, uv) tex2Dproj(s##tex, uv)
 
 
 #else
 #else
@@ -49,6 +52,7 @@ Texture2D tAlbedoBuffer : register(t0);
 Texture2D tNormalMap : register(t1);
 Texture2D tNormalMap : register(t1);
 Texture2D tNormalBuffer : register(t1);
 Texture2D tNormalBuffer : register(t1);
 Texture2D tSpecMap : register(t2);
 Texture2D tSpecMap : register(t2);
+Texture2D tRoughMetalFresnel : register(t2); //R: Roughness, G: Metal
 Texture2D tEmissiveMap : register(t3);
 Texture2D tEmissiveMap : register(t3);
 Texture2D tEnvMap : register(t4);
 Texture2D tEnvMap : register(t4);
 Texture3D tVolumeMap : register(t5);
 Texture3D tVolumeMap : register(t5);
@@ -70,6 +74,7 @@ SamplerState sAlbedoBuffer : register(s0);
 SamplerState sNormalMap : register(s1);
 SamplerState sNormalMap : register(s1);
 SamplerState sNormalBuffer : register(s1);
 SamplerState sNormalBuffer : register(s1);
 SamplerState sSpecMap : register(s2);
 SamplerState sSpecMap : register(s2);
+SamplerState sRoughMetalFresnel : register(s2); //R: Roughness, G: Metal 
 SamplerState sEmissiveMap : register(s3);
 SamplerState sEmissiveMap : register(s3);
 SamplerState sEnvMap : register(s4);
 SamplerState sEnvMap : register(s4);
 SamplerState sVolumeMap : register(s5);
 SamplerState sVolumeMap : register(s5);
@@ -77,7 +82,11 @@ SamplerState sEnvCubeMap : register(s4);
 SamplerState sLightRampMap : register(s8);
 SamplerState sLightRampMap : register(s8);
 SamplerState sLightSpotMap : register(s9);
 SamplerState sLightSpotMap : register(s9);
 SamplerState sLightCubeMap : register(s9);
 SamplerState sLightCubeMap : register(s9);
-SamplerComparisonState sShadowMap : register(s10);
+#ifdef VSM_SHADOW
+    SamplerState sShadowMap : register(s10);
+#else
+    SamplerComparisonState sShadowMap : register(s10);
+#endif
 SamplerState sFaceSelectCubeMap : register(s11);
 SamplerState sFaceSelectCubeMap : register(s11);
 SamplerState sIndirectionCubeMap : register(s12);
 SamplerState sIndirectionCubeMap : register(s12);
 SamplerState sDepthBuffer : register(s13);
 SamplerState sDepthBuffer : register(s13);

+ 9 - 2
Resources/CoreData/Shaders/HLSL/ScreenPos.hlsl

@@ -1,4 +1,11 @@
 #ifdef COMPILEVS
 #ifdef COMPILEVS
+float3x3 GetCameraRot()
+{
+    return float3x3(cViewInv[0][0], cViewInv[0][1], cViewInv[0][2],
+        cViewInv[1][0], cViewInv[1][1], cViewInv[1][2],
+        cViewInv[2][0], cViewInv[2][1], cViewInv[2][2]);
+}
+
 float4 GetScreenPos(float4 clipPos)
 float4 GetScreenPos(float4 clipPos)
 {
 {
     return float4(
     return float4(
@@ -36,7 +43,7 @@ float3 GetFarRay(float4 clipPos)
         clipPos.y / clipPos.w * cFrustumSize.y,
         clipPos.y / clipPos.w * cFrustumSize.y,
         cFrustumSize.z);
         cFrustumSize.z);
 
 
-    return mul(viewRay, cCameraRot);
+    return mul(viewRay, GetCameraRot());
 }
 }
 
 
 float3 GetNearRay(float4 clipPos)
 float3 GetNearRay(float4 clipPos)
@@ -46,6 +53,6 @@ float3 GetNearRay(float4 clipPos)
         clipPos.y / clipPos.w * cFrustumSize.y,
         clipPos.y / clipPos.w * cFrustumSize.y,
         0.0);
         0.0);
 
 
-    return mul(viewRay, cCameraRot) * cDepthMode.z;
+    return mul(viewRay, GetCameraRot()) * cDepthMode.z;
 }
 }
 #endif
 #endif

+ 31 - 7
Resources/CoreData/Shaders/HLSL/Shadow.hlsl

@@ -8,27 +8,51 @@ void VS(float4 iPos : POSITION,
         int4 iBlendIndices : BLENDINDICES,
         int4 iBlendIndices : BLENDINDICES,
     #endif
     #endif
     #ifdef INSTANCED
     #ifdef INSTANCED
-        float4x3 iModelInstance : TEXCOORD2,
+        float4x3 iModelInstance : TEXCOORD4,
+    #endif
+    #ifndef NOUV
+        float2 iTexCoord : TEXCOORD0,
+    #endif
+    #ifdef VSM_SHADOW
+        out float3 oTexCoord : TEXCOORD0,
+    #else
+        out float2 oTexCoord : TEXCOORD0,
     #endif
     #endif
-    float2 iTexCoord : TEXCOORD0,
-    out float2 oTexCoord : TEXCOORD0,
     out float4 oPos : OUTPOSITION)
     out float4 oPos : OUTPOSITION)
 {
 {
+    // Define a 0,0 UV coord if not expected from the vertex data
+    #ifdef NOUV
+    float2 iTexCoord = float2(0.0, 0.0);
+    #endif
+
     float4x3 modelMatrix = iModelMatrix;
     float4x3 modelMatrix = iModelMatrix;
     float3 worldPos = GetWorldPos(modelMatrix);
     float3 worldPos = GetWorldPos(modelMatrix);
     oPos = GetClipPos(worldPos);
     oPos = GetClipPos(worldPos);
-    oTexCoord = GetTexCoord(iTexCoord);
+    #ifdef VSM_SHADOW
+        oTexCoord = float3(GetTexCoord(iTexCoord), oPos.z/oPos.w);
+    #else
+        oTexCoord = GetTexCoord(iTexCoord);
+    #endif
 }
 }
 
 
 void PS(
 void PS(
-    float2 iTexCoord : TEXCOORD0,
+    #ifdef VSM_SHADOW
+        float3 iTexCoord : TEXCOORD0,
+    #else
+        float2 iTexCoord : TEXCOORD0,
+    #endif
     out float4 oColor : OUTCOLOR0)
     out float4 oColor : OUTCOLOR0)
 {
 {
     #ifdef ALPHAMASK
     #ifdef ALPHAMASK
-        float alpha = Sample2D(DiffMap, iTexCoord).a;
+        float alpha = Sample2D(DiffMap, iTexCoord.xy).a;
         if (alpha < 0.5)
         if (alpha < 0.5)
             discard;
             discard;
     #endif
     #endif
 
 
-    oColor = 1.0;
+    #ifdef VSM_SHADOW
+        float depth = iTexCoord.z;
+        oColor = float4(depth, depth * depth, 1.0, 1.0);
+    #else
+        oColor = 1.0;
+    #endif
 }
 }

+ 48 - 0
Resources/CoreData/Shaders/HLSL/ShadowBlur.hlsl

@@ -0,0 +1,48 @@
+#include "Uniforms.hlsl"
+#include "Samplers.hlsl"
+#include "Transform.hlsl"
+#include "ScreenPos.hlsl"
+
+#ifndef D3D11
+
+// D3D9 uniforms
+uniform float2 cBlurOffsets;
+
+#else
+
+#ifdef COMPILEPS
+// D3D11 constant buffers
+cbuffer CustomPS : register(b6)
+{
+    float2 cBlurOffsets;
+}
+#endif
+
+#endif
+
+void VS(float4 iPos : POSITION,
+    out float2 oScreenPos : TEXCOORD0,
+    out float4 oPos : OUTPOSITION)
+{
+    float4x3 modelMatrix = iModelMatrix;
+    float3 worldPos = GetWorldPos(modelMatrix);
+    oPos = GetClipPos(worldPos);
+    oScreenPos = GetScreenPosPreDiv(oPos);
+}
+
+void PS(float2 iScreenPos : TEXCOORD0,
+    out float4 oColor : OUTCOLOR0)
+{  
+    float2 color = 0.0;
+
+    color += 0.015625 * Sample2D(DiffMap, iScreenPos - 3.0 * cBlurOffsets).rg;
+    color += 0.09375 * Sample2D(DiffMap, iScreenPos - 2.0 * cBlurOffsets).rg;
+    color += 0.234375 * Sample2D(DiffMap, iScreenPos - cBlurOffsets).rg;
+    color += 0.3125 * Sample2D(DiffMap, iScreenPos).rg;
+    color += 0.234375 * Sample2D(DiffMap, iScreenPos + cBlurOffsets).rg;
+    color += 0.09375 * Sample2D(DiffMap, iScreenPos + 2.0 * cBlurOffsets).rg;
+    color += 0.015625 * Sample2D(DiffMap, iScreenPos + 3.0 * cBlurOffsets).rg;
+
+    oColor = float4(color, 0.0, 0.0);
+}
+

+ 6 - 2
Resources/CoreData/Shaders/HLSL/Skybox.hlsl

@@ -9,7 +9,7 @@ void VS(float4 iPos : POSITION,
     float4x3 modelMatrix = iModelMatrix;
     float4x3 modelMatrix = iModelMatrix;
     float3 worldPos = GetWorldPos(modelMatrix);
     float3 worldPos = GetWorldPos(modelMatrix);
     oPos = GetClipPos(worldPos);
     oPos = GetClipPos(worldPos);
-    
+
     oPos.z = oPos.w;
     oPos.z = oPos.w;
     oTexCoord = iPos.xyz;
     oTexCoord = iPos.xyz;
 }
 }
@@ -17,5 +17,9 @@ void VS(float4 iPos : POSITION,
 void PS(float3 iTexCoord : TEXCOORD0,
 void PS(float3 iTexCoord : TEXCOORD0,
     out float4 oColor : OUTCOLOR0)
     out float4 oColor : OUTCOLOR0)
 {
 {
-    oColor = cMatDiffColor * SampleCube(DiffCubeMap, iTexCoord);
+    float4 sky = cMatDiffColor * SampleCube(DiffCubeMap, iTexCoord);
+    #ifdef HDRSCALE
+        sky = pow(sky + clamp((cAmbientColor.a - 1.0) * 0.1, 0.0, 0.25), max(cAmbientColor.a, 1.0)) * clamp(cAmbientColor.a, 0.0, 1.0);
+    #endif
+    oColor = sky;
 }
 }

+ 22 - 0
Resources/CoreData/Shaders/HLSL/Skydome.hlsl

@@ -0,0 +1,22 @@
+#include "Uniforms.hlsl"
+#include "Samplers.hlsl"
+#include "Transform.hlsl"
+
+void VS(float4 iPos : POSITION, 
+    float2 iTexCoord: TEXCOORD0,
+    out float2 oTexCoord : TEXCOORD0, 
+    out float4 oPos : OUTPOSITION)
+{
+    float4x3 modelMatrix = iModelMatrix;
+    float3 worldPos = GetWorldPos(modelMatrix);
+    oPos = GetClipPos(worldPos);
+    
+    oPos.z = oPos.w;
+    oTexCoord = iTexCoord;
+}
+
+void PS(float2 iTexCoord : TEXCOORD0, 
+        out float4 oColor : OUTCOLOR0)
+{
+    oColor = cMatDiffColor * Sample2D(DiffMap, iTexCoord);
+}

+ 8 - 5
Resources/CoreData/Shaders/HLSL/TerrainBlend.hlsl

@@ -46,11 +46,14 @@ void VS(float4 iPos : POSITION,
         int4 iBlendIndices : BLENDINDICES,
         int4 iBlendIndices : BLENDINDICES,
     #endif
     #endif
     #ifdef INSTANCED
     #ifdef INSTANCED
-        float4x3 iModelInstance : TEXCOORD2,
+        float4x3 iModelInstance : TEXCOORD4,
     #endif
     #endif
-    #ifdef BILLBOARD
+    #if defined(BILLBOARD) || defined(DIRBILLBOARD)
         float2 iSize : TEXCOORD1,
         float2 iSize : TEXCOORD1,
     #endif
     #endif
+    #if defined(TRAILFACECAM) || defined(TRAILBONE)
+        float4 iTangent : TANGENT,
+    #endif
     out float2 oTexCoord : TEXCOORD0,
     out float2 oTexCoord : TEXCOORD0,
     out float3 oNormal : TEXCOORD1,
     out float3 oNormal : TEXCOORD1,
     out float4 oWorldPos : TEXCOORD2,
     out float4 oWorldPos : TEXCOORD2,
@@ -92,7 +95,7 @@ void VS(float4 iPos : POSITION,
 
 
         #ifdef SHADOW
         #ifdef SHADOW
             // Shadow projection: transform from world space to shadow space
             // Shadow projection: transform from world space to shadow space
-            GetShadowPos(projWorldPos, oShadowPos);
+            GetShadowPos(projWorldPos, oNormal, oShadowPos);
         #endif
         #endif
 
 
         #ifdef SPOTLIGHT
         #ifdef SPOTLIGHT
@@ -127,7 +130,7 @@ void PS(float2 iTexCoord : TEXCOORD0,
         #ifdef SPOTLIGHT
         #ifdef SPOTLIGHT
             float4 iSpotPos : TEXCOORD5,
             float4 iSpotPos : TEXCOORD5,
         #endif
         #endif
-        #ifdef CUBEMASK
+        #ifdef POINTLIGHT
             float3 iCubeMaskVec : TEXCOORD5,
             float3 iCubeMaskVec : TEXCOORD5,
         #endif
         #endif
     #else
     #else
@@ -198,7 +201,7 @@ void PS(float2 iTexCoord : TEXCOORD0,
         #endif
         #endif
 
 
         #ifdef AMBIENT
         #ifdef AMBIENT
-            finalColor += cAmbientColor * diffColor.rgb;
+            finalColor += cAmbientColor.rgb * diffColor.rgb;
             finalColor += cMatEmissiveColor;
             finalColor += cMatEmissiveColor;
             oColor = float4(GetFog(finalColor, fogFactor), diffColor.a);
             oColor = float4(GetFog(finalColor, fogFactor), diffColor.a);
         #else
         #else

+ 71 - 2
Resources/CoreData/Shaders/HLSL/Transform.hlsl

@@ -48,6 +48,63 @@ float3 GetBillboardNormal()
 }
 }
 #endif
 #endif
 
 
+#ifdef DIRBILLBOARD
+float3x3 GetFaceCameraRotation(float3 position, float3 direction)
+{
+    float3 cameraDir = normalize(position - cCameraPos);
+    float3 front = normalize(direction);
+    float3 right = normalize(cross(front, cameraDir));
+    float3 up = normalize(cross(front, right));
+
+    return float3x3(
+        right.x, right.y, right.z,
+        up.x, up.y, up.z,
+        front.x, front.y, front.z
+    );
+}
+
+float3 GetBillboardPos(float4 iPos, float2 iSize, float3 iDirection, float4x3 modelMatrix)
+{
+    float3 worldPos = mul(iPos, modelMatrix);
+    return worldPos + mul(float3(iSize.x, 0.0, iSize.y), GetFaceCameraRotation(worldPos, iDirection));
+}
+
+float3 GetBillboardNormal(float4 iPos, float3 iDirection, float4x3 modelMatrix)
+{
+    float3 worldPos = mul(iPos, modelMatrix);
+    return mul(float3(0.0, 1.0, 0.0), GetFaceCameraRotation(worldPos, iDirection));
+}
+#endif
+
+#ifdef TRAILFACECAM
+float3 GetTrailPos(float4 iPos, float3 iFront, float iScale, float4x3 modelMatrix)
+{
+    float3 up = normalize(cCameraPos - iPos.xyz);
+    float3 left = normalize(cross(iFront, up));
+    return (mul(float4((iPos.xyz + left * iScale), 1.0), modelMatrix)).xyz;
+}
+
+float3 GetTrailNormal(float4 iPos)
+{
+    return normalize(cCameraPos - iPos.xyz);
+}
+#endif
+
+#ifdef TRAILBONE
+float3 GetTrailPos(float4 iPos, float3 iParentPos, float iScale, float4x3 modelMatrix)
+{
+    float3 right = iParentPos - iPos.xyz;
+    return (mul(float4((iPos.xyz + right * iScale), 1.0), modelMatrix)).xyz;
+}
+
+float3 GetTrailNormal(float4 iPos, float3 iParentPos, float3 iForward)
+{
+    float3 left = normalize(iPos.xyz - iParentPos);
+    float3 up = -normalize(cross(normalize(iForward), left));
+    return up;
+}
+#endif
+
 #if defined(SKINNED)
 #if defined(SKINNED)
     #define iModelMatrix GetSkinMatrix(iBlendWeights, iBlendIndices);
     #define iModelMatrix GetSkinMatrix(iBlendWeights, iBlendIndices);
 #elif defined(INSTANCED)
 #elif defined(INSTANCED)
@@ -56,14 +113,26 @@ float3 GetBillboardNormal()
     #define iModelMatrix cModel
     #define iModelMatrix cModel
 #endif
 #endif
 
 
-#ifdef BILLBOARD
+#if defined(BILLBOARD)
     #define GetWorldPos(modelMatrix) GetBillboardPos(iPos, iSize, modelMatrix)
     #define GetWorldPos(modelMatrix) GetBillboardPos(iPos, iSize, modelMatrix)
+#elif defined(DIRBILLBOARD)
+    #define GetWorldPos(modelMatrix) GetBillboardPos(iPos, iSize, iNormal, modelMatrix)
+#elif defined(TRAILFACECAM)
+    #define GetWorldPos(modelMatrix) GetTrailPos(iPos, iTangent.xyz, iTangent.w, modelMatrix)
+#elif defined(TRAILBONE)
+    #define GetWorldPos(modelMatrix) GetTrailPos(iPos, iTangent.xyz, iTangent.w, modelMatrix)
 #else
 #else
     #define GetWorldPos(modelMatrix) mul(iPos, modelMatrix)
     #define GetWorldPos(modelMatrix) mul(iPos, modelMatrix)
 #endif
 #endif
 
 
-#ifdef BILLBOARD
+#if defined(BILLBOARD)
     #define GetWorldNormal(modelMatrix) GetBillboardNormal()
     #define GetWorldNormal(modelMatrix) GetBillboardNormal()
+#elif defined(DIRBILLBOARD)
+    #define GetWorldNormal(modelMatrix) GetBillboardNormal(iPos, iNormal, modelMatrix)
+#elif defined(TRAILFACECAM)
+    #define GetWorldNormal(modelMatrix) GetTrailNormal(iPos)
+#elif defined(TRAILBONE)
+    #define GetWorldNormal(modelMatrix) GetTrailNormal(iPos, iTangent.xyz, iNormal)
 #else
 #else
     #define GetWorldNormal(modelMatrix) normalize(mul(iNormal, (float3x3)modelMatrix))
     #define GetWorldNormal(modelMatrix) normalize(mul(iNormal, (float3x3)modelMatrix))
 #endif
 #endif

+ 24 - 6
Resources/CoreData/Shaders/HLSL/Uniforms.hlsl

@@ -11,7 +11,6 @@ uniform float3 cAmbientEndColor;
 uniform float3x3 cBillboardRot;
 uniform float3x3 cBillboardRot;
 #endif
 #endif
 uniform float3 cCameraPos;
 uniform float3 cCameraPos;
-uniform float3x3 cCameraRot;
 uniform float cNearClip;
 uniform float cNearClip;
 uniform float cFarClip;
 uniform float cFarClip;
 uniform float4 cDepthMode;
 uniform float4 cDepthMode;
@@ -19,9 +18,12 @@ uniform float cDeltaTime;
 uniform float cElapsedTime;
 uniform float cElapsedTime;
 uniform float3 cFrustumSize;
 uniform float3 cFrustumSize;
 uniform float4 cGBufferOffsets;
 uniform float4 cGBufferOffsets;
-uniform float3 cLightDir;
 uniform float4 cLightPos;
 uniform float4 cLightPos;
+uniform float3 cLightDir;
+uniform float4 cNormalOffsetScale;
 uniform float4x3 cModel;
 uniform float4x3 cModel;
+uniform float4x3 cView;
+uniform float4x3 cViewInv;
 uniform float4x4 cViewProj;
 uniform float4x4 cViewProj;
 uniform float4 cUOffset;
 uniform float4 cUOffset;
 uniform float4 cVOffset;
 uniform float4 cVOffset;
@@ -39,7 +41,7 @@ uniform float4x3 cZone;
 #ifdef COMPILEPS
 #ifdef COMPILEPS
 
 
 // Pixel shader uniforms
 // Pixel shader uniforms
-uniform float3 cAmbientColor;
+uniform float4 cAmbientColor;
 uniform float3 cCameraPosPS;
 uniform float3 cCameraPosPS;
 uniform float cDeltaTimePS;
 uniform float cDeltaTimePS;
 uniform float4 cDepthReconstruct;
 uniform float4 cDepthReconstruct;
@@ -50,10 +52,15 @@ uniform float2 cGBufferInvSize;
 uniform float4 cLightColor;
 uniform float4 cLightColor;
 uniform float4 cLightPosPS;
 uniform float4 cLightPosPS;
 uniform float3 cLightDirPS;
 uniform float3 cLightDirPS;
+uniform float4 cNormalOffsetScalePS;
 uniform float4 cMatDiffColor;
 uniform float4 cMatDiffColor;
 uniform float3 cMatEmissiveColor;
 uniform float3 cMatEmissiveColor;
 uniform float3 cMatEnvMapColor;
 uniform float3 cMatEnvMapColor;
 uniform float4 cMatSpecColor;
 uniform float4 cMatSpecColor;
+#ifdef PBR
+    uniform float cRoughness;
+    uniform float cMetallic;
+#endif
 uniform float cNearClipPS;
 uniform float cNearClipPS;
 uniform float cFarClipPS;
 uniform float cFarClipPS;
 uniform float4 cShadowCubeAdjust;
 uniform float4 cShadowCubeAdjust;
@@ -62,6 +69,9 @@ uniform float2 cShadowIntensity;
 uniform float2 cShadowMapInvSize;
 uniform float2 cShadowMapInvSize;
 uniform float4 cShadowSplits;
 uniform float4 cShadowSplits;
 uniform float4x4 cLightMatricesPS[4];
 uniform float4x4 cLightMatricesPS[4];
+#ifdef VSM_SHADOW
+uniform float2 cVSMShadowParams;
+#endif
 #endif
 #endif
 
 
 #else
 #else
@@ -80,12 +90,13 @@ cbuffer FrameVS : register(b0)
 cbuffer CameraVS : register(b1)
 cbuffer CameraVS : register(b1)
 {
 {
     float3 cCameraPos;
     float3 cCameraPos;
-    float3x3 cCameraRot;
     float cNearClip;
     float cNearClip;
     float cFarClip;
     float cFarClip;
     float4 cDepthMode;
     float4 cDepthMode;
     float3 cFrustumSize;
     float3 cFrustumSize;
     float4 cGBufferOffsets;
     float4 cGBufferOffsets;
+    float4x3 cView;
+    float4x3 cViewInv;
     float4x4 cViewProj;
     float4x4 cViewProj;
     float4 cClipPlane;
     float4 cClipPlane;
 }
 }
@@ -99,8 +110,9 @@ cbuffer ZoneVS : register(b2)
 
 
 cbuffer LightVS : register(b3)
 cbuffer LightVS : register(b3)
 {
 {
-    float3 cLightDir;
     float4 cLightPos;
     float4 cLightPos;
+    float3 cLightDir;
+    float4 cNormalOffsetScale;
 #ifdef NUMVERTEXLIGHTS
 #ifdef NUMVERTEXLIGHTS
     float4 cVertexLights[4 * 3];
     float4 cVertexLights[4 * 3];
 #else
 #else
@@ -148,7 +160,7 @@ cbuffer CameraPS : register(b1)
 
 
 cbuffer ZonePS : register(b2)
 cbuffer ZonePS : register(b2)
 {
 {
-    float3 cAmbientColor;
+    float4 cAmbientColor;
     float4 cFogParams;
     float4 cFogParams;
     float3 cFogColor;
     float3 cFogColor;
 }
 }
@@ -158,11 +170,13 @@ cbuffer LightPS : register(b3)
     float4 cLightColor;
     float4 cLightColor;
     float4 cLightPosPS;
     float4 cLightPosPS;
     float3 cLightDirPS;
     float3 cLightDirPS;
+    float4 cNormalOffsetScalePS;
     float4 cShadowCubeAdjust;
     float4 cShadowCubeAdjust;
     float4 cShadowDepthFade;
     float4 cShadowDepthFade;
     float2 cShadowIntensity;
     float2 cShadowIntensity;
     float2 cShadowMapInvSize;
     float2 cShadowMapInvSize;
     float4 cShadowSplits;
     float4 cShadowSplits;
+    float2 cVSMShadowParams;
     float4x4 cLightMatricesPS[4];
     float4x4 cLightMatricesPS[4];
 }
 }
 
 
@@ -173,6 +187,10 @@ cbuffer MaterialPS : register(b4)
     float3 cMatEmissiveColor;
     float3 cMatEmissiveColor;
     float3 cMatEnvMapColor;
     float3 cMatEnvMapColor;
     float4 cMatSpecColor;
     float4 cMatSpecColor;
+    #ifdef PBR
+        float cRoughness;
+        float cMetallic;
+    #endif
 }
 }
 #endif
 #endif
 
 

+ 9 - 3
Resources/CoreData/Shaders/HLSL/Unlit.hlsl

@@ -15,11 +15,17 @@ void VS(float4 iPos : POSITION,
         int4 iBlendIndices : BLENDINDICES,
         int4 iBlendIndices : BLENDINDICES,
     #endif
     #endif
     #ifdef INSTANCED
     #ifdef INSTANCED
-        float4x3 iModelInstance : TEXCOORD2,
+        float4x3 iModelInstance : TEXCOORD4,
     #endif
     #endif
-    #ifdef BILLBOARD
+    #if defined(BILLBOARD) || defined(DIRBILLBOARD)
         float2 iSize : TEXCOORD1,
         float2 iSize : TEXCOORD1,
     #endif
     #endif
+    #if defined(DIRBILLBOARD) || defined(TRAILBONE)
+        float3 iNormal : NORMAL,
+    #endif
+    #if defined(TRAILFACECAM) || defined(TRAILBONE)
+        float4 iTangent : TANGENT,
+    #endif
     out float2 oTexCoord : TEXCOORD0,
     out float2 oTexCoord : TEXCOORD0,
     out float4 oWorldPos : TEXCOORD2,
     out float4 oWorldPos : TEXCOORD2,
     #ifdef VERTEXCOLOR
     #ifdef VERTEXCOLOR
@@ -103,4 +109,4 @@ void PS(float2 iTexCoord : TEXCOORD0,
     #else
     #else
         oColor = float4(GetFog(diffColor.rgb, fogFactor), diffColor.a);
         oColor = float4(GetFog(diffColor.rgb, fogFactor), diffColor.a);
     #endif
     #endif
-}
+}

+ 27 - 0
Resources/CoreData/Shaders/HLSL/Urho2D.hlsl

@@ -0,0 +1,27 @@
+#include "Uniforms.hlsl"
+#include "Samplers.hlsl"
+#include "Transform.hlsl"
+
+void VS(float4 iPos : POSITION,
+    float2 iTexCoord : TEXCOORD0,
+    float4 iColor : COLOR0,
+    out float4 oColor : COLOR0,
+    out float2 oTexCoord : TEXCOORD0,
+    out float4 oPos : OUTPOSITION)
+{
+    float4x3 modelMatrix = iModelMatrix;
+    float3 worldPos = GetWorldPos(modelMatrix);
+    oPos = GetClipPos(worldPos);
+
+    oColor = iColor;
+    oTexCoord = iTexCoord;
+}
+
+void PS(float4 iColor : COLOR0,
+        float2 iTexCoord : TEXCOORD0,
+        out float4 oColor : OUTCOLOR0)
+{
+    float4 diffColor = cMatDiffColor * iColor;
+    float4 diffInput = Sample2D(DiffMap, iTexCoord);
+    oColor = diffColor * diffInput;
+}

+ 43 - 8
Resources/CoreData/Shaders/HLSL/Vegetation.hlsl

@@ -5,18 +5,41 @@
 #include "Lighting.hlsl"
 #include "Lighting.hlsl"
 #include "Fog.hlsl"
 #include "Fog.hlsl"
 
 
+#ifndef D3D11
+
+// D3D9 uniforms
 uniform float cWindHeightFactor;
 uniform float cWindHeightFactor;
 uniform float cWindHeightPivot;
 uniform float cWindHeightPivot;
 uniform float cWindPeriod;
 uniform float cWindPeriod;
 uniform float2 cWindWorldSpacing;
 uniform float2 cWindWorldSpacing;
 
 
+#else
+
+// D3D11 constant buffer
+cbuffer CustomVS : register(b6)
+{
+    float cWindHeightFactor;
+    float cWindHeightPivot;
+    float cWindPeriod;
+    float2 cWindWorldSpacing;
+}
+
+#endif
+
 void VS(float4 iPos : POSITION,
 void VS(float4 iPos : POSITION,
-    float3 iNormal : NORMAL,
-    float2 iTexCoord : TEXCOORD0,
+    #if !defined(BILLBOARD) && !defined(TRAILFACECAM)
+        float3 iNormal : NORMAL,
+    #endif
+    #ifndef NOUV
+        float2 iTexCoord : TEXCOORD0,
+    #endif
+    #ifdef VERTEXCOLOR
+        float4 iColor : COLOR0,
+    #endif
     #if defined(LIGHTMAP) || defined(AO)
     #if defined(LIGHTMAP) || defined(AO)
         float2 iTexCoord2 : TEXCOORD1,
         float2 iTexCoord2 : TEXCOORD1,
     #endif
     #endif
-    #ifdef NORMALMAP
+    #if defined(NORMALMAP) || defined(TRAILFACECAM) || defined(TRAILBONE)
         float4 iTangent : TANGENT,
         float4 iTangent : TANGENT,
     #endif
     #endif
     #ifdef SKINNED
     #ifdef SKINNED
@@ -24,9 +47,9 @@ void VS(float4 iPos : POSITION,
         int4 iBlendIndices : BLENDINDICES,
         int4 iBlendIndices : BLENDINDICES,
     #endif
     #endif
     #ifdef INSTANCED
     #ifdef INSTANCED
-        float4x3 iModelInstance : TEXCOORD2,
+        float4x3 iModelInstance : TEXCOORD4,
     #endif
     #endif
-    #ifdef BILLBOARD
+    #if defined(BILLBOARD) || defined(DIRBILLBOARD)
         float2 iSize : TEXCOORD1,
         float2 iSize : TEXCOORD1,
     #endif
     #endif
     #ifndef NORMALMAP
     #ifndef NORMALMAP
@@ -57,11 +80,19 @@ void VS(float4 iPos : POSITION,
             out float2 oTexCoord2 : TEXCOORD7,
             out float2 oTexCoord2 : TEXCOORD7,
         #endif
         #endif
     #endif
     #endif
+    #ifdef VERTEXCOLOR
+        out float4 oColor : COLOR0,
+    #endif
     #if defined(D3D11) && defined(CLIPPLANE)
     #if defined(D3D11) && defined(CLIPPLANE)
         out float oClip : SV_CLIPDISTANCE0,
         out float oClip : SV_CLIPDISTANCE0,
     #endif
     #endif
     out float4 oPos : OUTPOSITION)
     out float4 oPos : OUTPOSITION)
 {
 {
+    // Define a 0,0 UV coord if not expected from the vertex data
+    #ifdef NOUV
+    float2 iTexCoord = float2(0.0, 0.0);
+    #endif
+
     float4x3 modelMatrix = iModelMatrix;
     float4x3 modelMatrix = iModelMatrix;
     float3 worldPos = GetWorldPos(modelMatrix);
     float3 worldPos = GetWorldPos(modelMatrix);
     float height = worldPos.y - cModel._m31;
     float height = worldPos.y - cModel._m31;
@@ -78,7 +109,11 @@ void VS(float4 iPos : POSITION,
     #if defined(D3D11) && defined(CLIPPLANE)
     #if defined(D3D11) && defined(CLIPPLANE)
         oClip = dot(oPos, cClipPlane);
         oClip = dot(oPos, cClipPlane);
     #endif
     #endif
-    
+
+    #ifdef VERTEXCOLOR
+        oColor = iColor;
+    #endif
+
     #ifdef NORMALMAP
     #ifdef NORMALMAP
         float3 tangent = GetWorldTangent(modelMatrix);
         float3 tangent = GetWorldTangent(modelMatrix);
         float3 bitangent = cross(tangent, oNormal) * iTangent.w;
         float3 bitangent = cross(tangent, oNormal) * iTangent.w;
@@ -94,7 +129,7 @@ void VS(float4 iPos : POSITION,
 
 
         #ifdef SHADOW
         #ifdef SHADOW
             // Shadow projection: transform from world space to shadow space
             // Shadow projection: transform from world space to shadow space
-            GetShadowPos(projWorldPos, oShadowPos);
+            GetShadowPos(projWorldPos, oNormal, oShadowPos);
         #endif
         #endif
 
 
         #ifdef SPOTLIGHT
         #ifdef SPOTLIGHT
@@ -103,7 +138,7 @@ void VS(float4 iPos : POSITION,
         #endif
         #endif
 
 
         #ifdef POINTLIGHT
         #ifdef POINTLIGHT
-            oCubeMaskVec = mul(cLightPos.xyz - worldPos, (float3x3)cLightMatrices[0]);
+            oCubeMaskVec = mul(worldPos - cLightPos.xyz, (float3x3)cLightMatrices[0]);
         #endif
         #endif
     #else
     #else
         // Ambient & per-vertex lighting
         // Ambient & per-vertex lighting

+ 18 - 2
Resources/CoreData/Shaders/HLSL/VegetationDepth.hlsl

@@ -2,22 +2,38 @@
 #include "Samplers.hlsl"
 #include "Samplers.hlsl"
 #include "Transform.hlsl"
 #include "Transform.hlsl"
 
 
+#ifndef D3D11
+
+// D3D9 uniforms
 uniform float cWindHeightFactor;
 uniform float cWindHeightFactor;
 uniform float cWindHeightPivot;
 uniform float cWindHeightPivot;
 uniform float cWindPeriod;
 uniform float cWindPeriod;
 uniform float2 cWindWorldSpacing;
 uniform float2 cWindWorldSpacing;
 
 
+#else
+
+// D3D11 constant buffer
+cbuffer CustomVS : register(b6)
+{
+    float cWindHeightFactor;
+    float cWindHeightPivot;
+    float cWindPeriod;
+    float2 cWindWorldSpacing;
+}
+
+#endif
+
 void VS(float4 iPos : POSITION,
 void VS(float4 iPos : POSITION,
     #ifdef SKINNED
     #ifdef SKINNED
         float4 iBlendWeights : BLENDWEIGHT,
         float4 iBlendWeights : BLENDWEIGHT,
         int4 iBlendIndices : BLENDINDICES,
         int4 iBlendIndices : BLENDINDICES,
     #endif
     #endif
     #ifdef INSTANCED
     #ifdef INSTANCED
-        float4x3 iModelInstance : TEXCOORD2,
+        float4x3 iModelInstance : TEXCOORD4,
     #endif
     #endif
     float2 iTexCoord : TEXCOORD0,
     float2 iTexCoord : TEXCOORD0,
     out float3 oTexCoord : TEXCOORD0,
     out float3 oTexCoord : TEXCOORD0,
-    out float4 oPos : POSITION)
+    out float4 oPos : OUTPOSITION)
 {
 {
     float4x3 modelMatrix = iModelMatrix;
     float4x3 modelMatrix = iModelMatrix;
     float3 worldPos = GetWorldPos(modelMatrix);
     float3 worldPos = GetWorldPos(modelMatrix);

+ 18 - 2
Resources/CoreData/Shaders/HLSL/VegetationShadow.hlsl

@@ -2,22 +2,38 @@
 #include "Samplers.hlsl"
 #include "Samplers.hlsl"
 #include "Transform.hlsl"
 #include "Transform.hlsl"
 
 
+#ifndef D3D11
+
+// D3D9 uniforms
 uniform float cWindHeightFactor;
 uniform float cWindHeightFactor;
 uniform float cWindHeightPivot;
 uniform float cWindHeightPivot;
 uniform float cWindPeriod;
 uniform float cWindPeriod;
 uniform float2 cWindWorldSpacing;
 uniform float2 cWindWorldSpacing;
 
 
+#else
+
+// D3D11 constant buffer
+cbuffer CustomVS : register(b6)
+{
+    float cWindHeightFactor;
+    float cWindHeightPivot;
+    float cWindPeriod;
+    float2 cWindWorldSpacing;
+}
+
+#endif
+
 void VS(float4 iPos : POSITION,
 void VS(float4 iPos : POSITION,
     #ifdef SKINNED
     #ifdef SKINNED
         float4 iBlendWeights : BLENDWEIGHT,
         float4 iBlendWeights : BLENDWEIGHT,
         int4 iBlendIndices : BLENDINDICES,
         int4 iBlendIndices : BLENDINDICES,
     #endif
     #endif
     #ifdef INSTANCED
     #ifdef INSTANCED
-        float4x3 iModelInstance : TEXCOORD2,
+        float4x3 iModelInstance : TEXCOORD4,
     #endif
     #endif
     float2 iTexCoord : TEXCOORD0,
     float2 iTexCoord : TEXCOORD0,
     out float2 oTexCoord : TEXCOORD0,
     out float2 oTexCoord : TEXCOORD0,
-    out float4 oPos : POSITION)
+    out float4 oPos : OUTPOSITION)
 {
 {
     float4x3 modelMatrix = iModelMatrix;
     float4x3 modelMatrix = iModelMatrix;
     float3 worldPos = GetWorldPos(modelMatrix);
     float3 worldPos = GetWorldPos(modelMatrix);

+ 3 - 0
Resources/CoreData/Shaders/HLSL/Water.hlsl

@@ -36,6 +36,9 @@ cbuffer CustomPS : register(b6)
 void VS(float4 iPos : POSITION,
 void VS(float4 iPos : POSITION,
     float3 iNormal: NORMAL,
     float3 iNormal: NORMAL,
     float2 iTexCoord : TEXCOORD0,
     float2 iTexCoord : TEXCOORD0,
+    #ifdef INSTANCED
+        float4x3 iModelInstance : TEXCOORD4,
+    #endif
     out float4 oScreenPos : TEXCOORD0,
     out float4 oScreenPos : TEXCOORD0,
     out float2 oReflectUV : TEXCOORD1,
     out float2 oReflectUV : TEXCOORD1,
     out float2 oWaterUV : TEXCOORD2,
     out float2 oWaterUV : TEXCOORD2,

+ 10 - 0
Resources/CoreData/Techniques/DiffAlphaMaskTranslucent.xml

@@ -0,0 +1,10 @@
+<technique vs="LitSolid" ps="LitSolid" vsdefines="TRANSLUCENT" psdefines="DIFFMAP ALPHAMASK TRANSLUCENT" alphamask="true" >
+    <pass name="base" />
+    <pass name="litbase" psdefines="AMBIENT" />
+    <pass name="light" depthtest="equal" depthwrite="false" blend="add" />
+    <pass name="prepass" psdefines="PREPASS" />
+    <pass name="material" psdefines="MATERIAL" depthtest="equal" depthwrite="false" />
+    <pass name="deferred" psdefines="DEFERRED" />
+    <pass name="depth" vs="Depth" ps="Depth" psdefines="ALPHAMASK" />
+    <pass name="shadow" vs="Shadow" ps="Shadow" psdefines="ALPHAMASK" />
+</technique>

+ 5 - 0
Resources/CoreData/Techniques/DiffAlphaTranslucent.xml

@@ -0,0 +1,5 @@
+<technique vs="LitSolid" ps="LitSolid" vsdefines="TRANSLUCENT" psdefines="DIFFMAP TRANSLUCENT">
+    <pass name="alpha" depthwrite="false" blend="alpha" />
+    <pass name="litalpha" depthwrite="false" blend="addalpha" />
+    <pass name="shadow" vs="Shadow" ps="Shadow" />
+</technique>

+ 1 - 1
Resources/CoreData/Techniques/DiffLightMap.xml

@@ -1,6 +1,6 @@
 <technique vs="LitSolid" ps="LitSolid" psdefines="DIFFMAP">
 <technique vs="LitSolid" ps="LitSolid" psdefines="DIFFMAP">
     <pass name="base" vsdefines="LIGHTMAP" psdefines="LIGHTMAP" />
     <pass name="base" vsdefines="LIGHTMAP" psdefines="LIGHTMAP" />
-    <pass name="light" vsdefines="LIGHTMAP" psdefines="LIGHTMAP" depthtest="equal" depthwrite="false" blend="subtract" />
+    <pass name="light" depthtest="equal" depthwrite="false" blend="add" />
     <pass name="prepass" psdefines="PREPASS" />
     <pass name="prepass" psdefines="PREPASS" />
     <pass name="material" vsdefines="LIGHTMAP" psdefines="MATERIAL LIGHTMAP" depthtest="equal" depthwrite="false" />
     <pass name="material" vsdefines="LIGHTMAP" psdefines="MATERIAL LIGHTMAP" depthtest="equal" depthwrite="false" />
     <pass name="deferred" vsdefines="LIGHTMAP" psdefines="DEFERRED LIGHTMAP" />
     <pass name="deferred" vsdefines="LIGHTMAP" psdefines="DEFERRED LIGHTMAP" />

+ 10 - 0
Resources/CoreData/Techniques/DiffNormalAlphaMaskTranslucent.xml

@@ -0,0 +1,10 @@
+<technique vs="LitSolid" ps="LitSolid" vsdefines="TRANSLUCENT" psdefines="DIFFMAP ALPHAMASK TRANSLUCENT" alphamask="true">
+    <pass name="base" />
+    <pass name="litbase" vsdefines="NORMALMAP" psdefines="AMBIENT NORMALMAP" />
+    <pass name="light" vsdefines="NORMALMAP" psdefines="NORMALMAP" depthtest="equal" depthwrite="false" blend="add" />
+    <pass name="prepass" vsdefines="NORMALMAP" psdefines="PREPASS NORMALMAP" />
+    <pass name="material" psdefines="MATERIAL" depthtest="equal" depthwrite="false" />
+    <pass name="deferred" vsdefines="NORMALMAP" psdefines="DEFERRED NORMALMAP" />
+    <pass name="depth" vs="Depth" ps="Depth" psdefines="ALPHAMASK" />
+    <pass name="shadow" vs="Shadow" ps="Shadow" psdefines="ALPHAMASK" />
+</technique>

+ 5 - 0
Resources/CoreData/Techniques/DiffNormalAlphaTranslucent.xml

@@ -0,0 +1,5 @@
+<technique vs="LitSolid" ps="LitSolid" vsdefines="TRANSLUCENT" psdefines="DIFFMAP TRANSLUCENT">
+    <pass name="alpha" depthwrite="false" blend="alpha" />
+    <pass name="litalpha" vsdefines="NORMALMAP" psdefines="NORMALMAP" depthwrite="false" blend="addalpha" />
+    <pass name="shadow" vs="Shadow" ps="Shadow" />
+</technique>

+ 10 - 0
Resources/CoreData/Techniques/DiffNormalPackedAlphaMaskTranslucent.xml

@@ -0,0 +1,10 @@
+<technique vs="LitSolid" ps="LitSolid" vsdefines="TRANSLUCENT" psdefines="DIFFMAP ALPHAMASK TRANSLUCENT" alphamask="true">
+    <pass name="base" />
+    <pass name="litbase" vsdefines="NORMALMAP" psdefines="AMBIENT NORMALMAP PACKEDNORMAL" />
+    <pass name="light" vsdefines="NORMALMAP" psdefines="NORMALMAP PACKEDNORMAL" depthtest="equal" depthwrite="false" blend="add" />
+    <pass name="prepass" vsdefines="NORMALMAP" psdefines="PREPASS NORMALMAP PACKEDNORMAL" />
+    <pass name="material" psdefines="MATERIAL" depthtest="equal" depthwrite="false" />
+    <pass name="deferred" vsdefines="NORMALMAP" psdefines="DEFERRED NORMALMAP PACKEDNORMAL" />
+    <pass name="depth" vs="Depth" ps="Depth" psdefines="ALPHAMASK" />
+    <pass name="shadow" vs="Shadow" ps="Shadow" psdefines="ALPHAMASK" />
+</technique>

+ 5 - 0
Resources/CoreData/Techniques/DiffNormalPackedAlphaTranslucent.xml

@@ -0,0 +1,5 @@
+<technique vs="LitSolid" ps="LitSolid" vsdefines="TRANSLUCENT" psdefines="DIFFMAP TRANSLUCENT">
+    <pass name="alpha" depthwrite="false" blend="alpha" />
+    <pass name="litalpha" vsdefines="NORMALMAP" psdefines="NORMALMAP PACKEDNORMAL" depthwrite="false" blend="addalpha" />
+    <pass name="shadow" vs="Shadow" ps="Shadow" />
+</technique>

+ 3 - 0
Resources/CoreData/Techniques/DiffSkyboxHDRScale.xml

@@ -0,0 +1,3 @@
+<technique vs="Skybox" ps="Skybox" psdefines="HDRSCALE">
+    <pass name="postopaque" depthwrite="false" />
+</technique>

+ 3 - 0
Resources/CoreData/Techniques/DiffSkydome.xml

@@ -0,0 +1,3 @@
+<technique vs="Skydome" ps="Skydome">
+    <pass name="postopaque" depthwrite="false" />
+</technique>

+ 8 - 0
Resources/CoreData/Techniques/PBR/DiffNormalSpecEmissive.xml

@@ -0,0 +1,8 @@
+<technique vs="PBRLitSolid" ps="PBRLitSolid" psdefines="DIFFMAP NORMALMAP SPECMAP EMISSIVEMAP">
+    <pass name="base" />
+    <pass name="light" depthtest="equal" depthwrite="false" blend="add" />>
+    <pass name="material" psdefines="MATERIAL" depthtest="equal" depthwrite="false" />
+    <pass name="deferred" psdefines="DEFERRED" />
+    <pass name="depth" vs="Depth" ps="Depth" />
+    <pass name="shadow" vs="Shadow" ps="Shadow" />
+</technique>

+ 5 - 0
Resources/CoreData/Techniques/PBR/DiffNormalSpecEmissiveAlpha.xml

@@ -0,0 +1,5 @@
+<technique vs="PBRLitSolid" ps="PBRLitSolid" psdefines="DIFFMAP SPECMAP EMISSIVEMAP NORMALMAP">
+    <pass name="alpha" depthwrite="false" blend="alpha" />
+    <pass name="litalpha" depthwrite="false" blend="addalpha" />
+    <pass name="shadow" vs="Shadow" ps="Shadow" />
+</technique>

+ 8 - 0
Resources/CoreData/Techniques/PBR/PBRDiff.xml

@@ -0,0 +1,8 @@
+<technique vs="PBRLitSolid" ps="PBRLitSolid" vsdefines="IBL" psdefines="DIFFMAP PBR IBL">
+    <pass name="base" />
+    <pass name="light" depthtest="equal" depthwrite="false" blend="add" />
+    <pass name="material" psdefines="MATERIAL" depthtest="equal" depthwrite="false" />
+    <pass name="deferred" psdefines="DEFERRED" blend="add" />
+    <pass name="depth" vs="Depth" ps="Depth" />
+    <pass name="shadow" vs="Shadow" ps="Shadow" />
+</technique>

+ 5 - 0
Resources/CoreData/Techniques/PBR/PBRDiffAlpha.xml

@@ -0,0 +1,5 @@
+<technique vs="PBRLitSolid" ps="PBRLitSolid" vsdefines="IBL" psdefines="DIFFMAP PBR IBL">
+    <pass name="alpha" depthwrite="false" blend="alpha" />
+    <pass name="litalpha" depthwrite="false" blend="addalpha" />
+    <pass name="shadow" vs="Shadow" ps="Shadow" />
+</technique>

+ 8 - 0
Resources/CoreData/Techniques/PBR/PBRDiffNormal.xml

@@ -0,0 +1,8 @@
+<technique vs="PBRLitSolid" ps="PBRLitSolid" vsdefines="IBL" psdefines="DIFFMAP NORMALMAP PBR IBL">
+    <pass name="base" />
+    <pass name="light" depthtest="equal" depthwrite="false" blend="add" />
+    <pass name="material" psdefines="MATERIAL" depthtest="equal" depthwrite="false" />
+    <pass name="deferred" psdefines="DEFERRED" blend="add" />
+    <pass name="depth" vs="Depth" ps="Depth" />
+    <pass name="shadow" vs="Shadow" ps="Shadow" />
+</technique>

+ 5 - 0
Resources/CoreData/Techniques/PBR/PBRDiffNormalAlpha.xml

@@ -0,0 +1,5 @@
+<technique vs="PBRLitSolid" ps="PBRLitSolid" vsdefines="IBL" psdefines="DIFFMAP NORMALMAP PBR IBL">
+    <pass name="alpha" depthwrite="false" blend="alpha" />
+    <pass name="litalpha" depthwrite="false" blend="addalpha" />
+    <pass name="shadow" vs="Shadow" ps="Shadow" />
+</technique>

+ 7 - 0
Resources/CoreData/Techniques/PBR/PBRDiffNormalEmissive.xml

@@ -0,0 +1,7 @@
+<technique vs="PBRLitSolid" ps="PBRLitSolid"  vsdefines="IBL" psdefines="DIFFMAP NORMALMAP EMISSIVEMAP PBR IBL">
+    <pass name="light" depthtest="equal" depthwrite="false" blend="add" />
+    <pass name="material" psdefines="MATERIAL" depthtest="equal" depthwrite="false" />
+    <pass name="deferred" psdefines="DEFERRED" blend="add" />
+    <pass name="depth" vs="Depth" ps="Depth" />
+    <pass name="shadow" vs="Shadow" ps="Shadow" />
+</technique>

+ 5 - 0
Resources/CoreData/Techniques/PBR/PBRDiffNormalEmissiveAlpha.xml

@@ -0,0 +1,5 @@
+<technique vs="PBRLitSolid" ps="PBRLitSolid"  vsdefines="IBL" psdefines="DIFFMAP NORMALMAP EMISSIVEMAP PBR IBL">
+    <pass name="alpha" depthwrite="false" blend="alpha" />
+    <pass name="litalpha" depthwrite="false" blend="addalpha" />
+    <pass name="shadow" vs="Shadow" ps="Shadow" />
+</technique>

+ 8 - 0
Resources/CoreData/Techniques/PBR/PBRMetallicRoughDiffNormalSpec.xml

@@ -0,0 +1,8 @@
+<technique vs="PBRLitSolid" ps="PBRLitSolid" vsdefines="IBL" psdefines="NORMALMAP DIFFMAP METALLIC ROUGHNESS PBR IBL">
+    <pass name="base" />
+    <pass name="light" depthtest="equal" depthwrite="false" blend="add" />
+    <pass name="material" psdefines="MATERIAL" depthtest="equal" depthwrite="false" />
+    <pass name="deferred" psdefines="DEFERRED" blend="add"/>
+    <pass name="depth" vs="Depth" ps="Depth" />
+    <pass name="shadow" vs="Shadow" ps="Shadow" />
+</technique>

+ 8 - 0
Resources/CoreData/Techniques/PBR/PBRMetallicRoughDiffNormalSpecEmissive.xml

@@ -0,0 +1,8 @@
+<technique vs="PBRLitSolid" ps="PBRLitSolid" vsdefines="IBL" psdefines="DIFFMAP NORMALMAP EMISSIVEMAP METALLIC ROUGHNESS PBR IBL">
+    <pass name="base" />
+    <pass name="light" depthtest="equal" depthwrite="false" blend="add" />
+    <pass name="material" psdefines="MATERIAL" depthtest="equal" depthwrite="false" />
+    <pass name="deferred" psdefines="DEFERRED" blend="add"/>
+    <pass name="depth" vs="Depth" ps="Depth" />
+    <pass name="shadow" vs="Shadow" ps="Shadow" />
+</technique>

+ 5 - 0
Resources/CoreData/Techniques/PBR/PBRMetallicRoughDiffNormalSpecEmissiveAlpha.xml

@@ -0,0 +1,5 @@
+<technique vs="PBRLitSolid" ps="PBRLitSolid" vsdefines="IBL" psdefines="DIFFMAP NORMALMAP EMISSIVEMAP PBR IBL METALLIC ROUGHNESS">
+    <pass name="alpha" depthwrite="false" blend="alpha" />
+    <pass name="litalpha" depthwrite="false" blend="addalpha" />
+    <pass name="shadow" vs="Shadow" ps="Shadow" />
+</technique>

+ 8 - 0
Resources/CoreData/Techniques/PBR/PBRMetallicRoughDiffSpec.xml

@@ -0,0 +1,8 @@
+<technique vs="PBRLitSolid" ps="PBRLitSolid" vsdefines="IBL" psdefines="DIFFMAP PBR IBL METALLIC ROUGHNESS">
+    <pass name="base"/>
+    <pass name="light" depthtest="equal" depthwrite="false" blend="add" />
+    <pass name="material" psdefines="MATERIAL" depthtest="equal" depthwrite="false" />
+    <pass name="deferred" psdefines="DEFERRED" blend="add" />
+    <pass name="depth" vs="Depth" ps="Depth" />
+    <pass name="shadow" vs="Shadow" ps="Shadow" />
+</technique>

+ 5 - 0
Resources/CoreData/Techniques/PBR/PBRMetallicRoughDiffSpecAlpha.xml

@@ -0,0 +1,5 @@
+<technique vs="PBRLitSolid" ps="PBRLitSolid" vsdefines="IBL" psdefines="DIFFMAP PBR IBL METALLIC ROUGHNESS">
+    <pass name="alpha" depthwrite="false" blend="alpha" />
+    <pass name="litalpha" depthwrite="false" blend="addalpha" />
+    <pass name="shadow" vs="Shadow" ps="Shadow" />
+</technique>

+ 9 - 0
Resources/CoreData/Techniques/PBR/PBRNoTexture.xml

@@ -0,0 +1,9 @@
+<technique vs="PBRLitSolid" ps="PBRLitSolid" vsdefines="NOUV PBR IBL" psdefines="PBR IBL">
+    <pass name="base" />
+    <pass name="light" depthtest="equal" depthwrite="false" blend="add" />
+    <pass name="prepass" psdefines="PREPASS" />
+    <pass name="material" psdefines="MATERIAL" depthtest="equal" depthwrite="false" />
+    <pass name="deferred" psdefines="DEFERRED" />
+    <pass name="depth" vs="Depth" ps="Depth" />
+    <pass name="shadow" vs="Shadow" ps="Shadow" />
+</technique>

+ 5 - 0
Resources/CoreData/Techniques/PBR/PBRNoTextureAlpha.xml

@@ -0,0 +1,5 @@
+<technique vs="PBRLitSolid" ps="PBRLitSolid" vsdefines="NOUV IBL" psdefines="PBR IBL">
+    <pass name="alpha"  depthwrite="false" blend="alpha" />
+    <pass name="litalpha" depthwrite="false" blend="addalpha" />
+    <pass name="shadow" vs="Shadow" ps="Shadow" />
+</technique>

+ 0 - 0
Resources/CoreData/Textures/LUTIdentity.png