Browse Source

Improved Sphere lights

dragonCASTjosh 8 years ago
parent
commit
e0cd084c74
3 changed files with 92 additions and 37 deletions
  1. 6 6
      bin/CoreData/Shaders/HLSL/IBL.hlsl
  2. 74 20
      bin/CoreData/Shaders/HLSL/PBR.hlsl
  3. 12 11
      bin/Data/Scenes/PBRExample.xml

+ 6 - 6
bin/CoreData/Shaders/HLSL/IBL.hlsl

@@ -220,12 +220,12 @@
     ///     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);
-    }
+    // 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 GetMipFromRoughness(float roughness)
     {

+ 74 - 20
bin/CoreData/Shaders/HLSL/PBR.hlsl

@@ -1,34 +1,86 @@
 #include "BRDF.hlsl"
 #ifdef COMPILEPS
 
-    
+    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);
+    }
 
-    float3 SphereLight(float3 worldPos, float3 lightVec, float3 normal, float3 toCamera, float roughness, float3 specColor, out float ndl)
+    float3 SphereLight(float3 worldPos, float3 lightVec, float3 normal, float3 toCamera, float roughness, float3 specColor, float3 diffColor, out float ndl)
     {
-        float3 pos   = (cLightPosPS.xyz - worldPos);
-        float radius = cLightRad;
+        // float3 pos   = (cLightPosPS.xyz - worldPos);
+        // float radius = cLightRad;
 
-        float3 reflectVec   = reflect(-toCamera, normal);
-        float3 centreToRay  = dot(pos, reflectVec) * reflectVec - pos;
-        float3 closestPoint = pos + centreToRay * saturate(radius / length(centreToRay));
+        // float3 reflectVec   = reflect(-toCamera, normal);
+        // float3 centreToRay  = dot(pos, reflectVec) * reflectVec - pos;
+        // float3 closestPoint = pos + centreToRay * saturate(radius / length(centreToRay));
 
-        float3 l = normalize(closestPoint);
-        float3 h = normalize(toCamera + l);
+        // float3 l = normalize(closestPoint);
+        // float3 h = normalize(toCamera + l);
+
+        // ndl       = saturate(dot(normal, l));
+        // float hdn = saturate(dot(h, normal));
+        // float hdv = dot(h, toCamera);
+        // float ndv = saturate(dot(normal, toCamera));
+
+        // float distL      = length(pos);
+        // float alpha      = roughness * roughness;
+        // float alphaPrime = saturate(radius / (distL * 2.0) + alpha);
+
+        // const float3 fresnelTerm = Fresnel(specColor, hdv) ;
+        // const float distTerm     = Distribution(hdn, alphaPrime);
+        // const float visTerm      = Visibility(ndl, ndv, roughness);
+
+        // return distTerm * visTerm * fresnelTerm ;
+        float specEnergy = 1.0f;
+
+        float radius = cLightRad / 100;
+
+        float radius2           = radius * radius;
+        float distToLightSqrd   = dot(lightVec,lightVec);
+        float invDistToLight    = rsqrt(distToLightSqrd);
+        float sinAlphaSqr       = saturate(radius2 / distToLightSqrd);
+        float sinAlpha          = sqrt(sinAlphaSqr);
+
+        ndl       = dot(normal, (lightVec * invDistToLight));
+
+        if(ndl < sinAlpha)
+        {
+            ndl = max(ndl, -sinAlpha);
+            ndl = ((sinAlpha + ndl) * (sinAlpha + ndl)) / (4 * sinAlpha);
+        }
 
-        ndl       = saturate(dot(normal, l));
+        float sphereAngle = saturate(radius * invDistToLight);
+                            
+        specEnergy = (roughness * roughness) / saturate((roughness * roughness) + 0.5f * sphereAngle);
+        specEnergy *= specEnergy;                           
+
+        float3 R = 2 * dot(toCamera, normal) * normal - toCamera;
+        R = GetSpecularDominantDir(normal, R, roughness);
+
+        // Find closest point on sphere to ray
+        float3 closestPointOnRay = dot(lightVec, R) * R;
+        float3 centerToRay = closestPointOnRay - lightVec;
+        float invDistToRay = rsqrt(dot(centerToRay, centerToRay));
+        float3 closestPointOnSphere = lightVec + centerToRay * saturate(radius * invDistToRay);
+
+        lightVec = closestPointOnSphere;
+        float3 L = normalize(lightVec);
+
+        float3 h = normalize(toCamera + L);
         float hdn = saturate(dot(h, normal));
         float hdv = dot(h, toCamera);
         float ndv = saturate(dot(normal, toCamera));
 
-        float distL      = length(pos);
-        float alpha      = roughness * roughness;
-        float alphaPrime = saturate(radius / (distL * 2.0) + alpha);
-
+        const float3 diffuseFactor = Diffuse(diffColor, roughness, ndv, ndl, hdv)  * ndl;
         const float3 fresnelTerm = Fresnel(specColor, hdv) ;
-        const float distTerm     = Distribution(hdn, alphaPrime);
-        const float visTerm      = Visibility(ndl, ndv, roughness);
+        const float distTerm = Distribution(hdn, roughness);
+        const float visTerm = Visibility(ndl, ndv, roughness);
+        float3 specularFactor = distTerm * visTerm * fresnelTerm * ndl/ M_PI;
+        return diffuseFactor + specularFactor;
 
-        return distTerm * visTerm * fresnelTerm ;
     }
 
     float3 TubeLight(float3 worldPos, float3 lightVec, float3 normal, float3 toCamera, float roughness, float3 specColor, out float ndl)
@@ -103,13 +155,14 @@
             {
                 if(cLightLength > 0.0)
                 {
-                    specularFactor = TubeLight(worldPos, lightVec, normal, toCamera, roughness, specColor, ndl);
-                    specularFactor *= ndl;
+                    return TubeLight(worldPos, lightVec, normal, toCamera, roughness, specColor, ndl);
+                    
                 }
                 else
                 {
-                    specularFactor = SphereLight(worldPos, lightVec, normal, toCamera, roughness, specColor, ndl);
+                    specularFactor = SphereLight(worldPos, lightVec, normal, toCamera, roughness, specColor, diffColor, ndl);
                     specularFactor *= ndl;
+                    return diffuseFactor + specularFactor;
                 }
             }
             else
@@ -118,6 +171,7 @@
                 const float distTerm = Distribution(ndh, roughness);
                 const float visTerm = Visibility(ndl, ndv, roughness);
                 specularFactor = distTerm * visTerm * fresnelTerm * ndl/ M_PI;
+                return diffuseFactor + specularFactor;
             }
 
         #endif

+ 12 - 11
bin/Data/Scenes/PBRExample.xml

@@ -7,8 +7,8 @@
 	<attribute name="Elapsed Time" value="152.788" />
 	<attribute name="Next Replicated Node ID" value="408" />
 	<attribute name="Next Replicated Component ID" value="428" />
-	<attribute name="Next Local Node ID" value="16777274" />
-	<attribute name="Next Local Component ID" value="16777889" />
+	<attribute name="Next Local Node ID" value="16777275" />
+	<attribute name="Next Local Component ID" value="16777901" />
 	<attribute name="Variables" />
 	<attribute name="Variable Names" value="" />
 	<component type="Octree" id="1" />
@@ -925,7 +925,7 @@
 				<attribute name="Font" value="Font;Fonts/BlueHighway.ttf" />
 				<attribute name="Font Size" value="15" />
 				<attribute name="Text" value="Low Roughness" />
-				<attribute name="Width" value="134" />
+				<attribute name="Width" value="135" />
 			</component>
 		</node>
 		<node id="138">
@@ -970,7 +970,7 @@
 				<attribute name="Font" value="Font;Fonts/BlueHighway.ttf" />
 				<attribute name="Font Size" value="15" />
 				<attribute name="Text" value="High Roughness" />
-				<attribute name="Width" value="136" />
+				<attribute name="Width" value="137" />
 			</component>
 		</node>
 		<node id="195">
@@ -1190,7 +1190,8 @@
 				<attribute name="Variables" />
 				<component type="Light" id="4">
 					<attribute name="Light Type" value="Directional" />
-					<attribute name="Brightness Multiplier" value="2" />
+					<attribute name="Brightness Multiplier" value="340" />
+					<attribute name="Use Physical Values" value="true" />
 					<attribute name="Cast Shadows" value="true" />
 					<attribute name="CSM Splits" value="10 20 30 40" />
 				</component>
@@ -1582,7 +1583,7 @@
 			<attribute name="Font" value="Font;Fonts/BlueHighway.ttf" />
 			<attribute name="Font Size" value="15" />
 			<attribute name="Text" value="Roughness Value    &lt;-1.0  -&gt;0.0" />
-			<attribute name="Width" value="262" />
+			<attribute name="Width" value="264" />
 		</component>
 	</node>
 	<node id="215">
@@ -1832,7 +1833,7 @@
 		<attribute name="Scale" value="0.648644 0.648644 0.648644" />
 		<attribute name="Variables" />
 		<component type="Light" id="251">
-			<attribute name="Brightness Multiplier" value="800" />
+			<attribute name="Brightness Multiplier" value="1700" />
 			<attribute name="Use Physical Values" value="true" />
 			<attribute name="Radius" value="0.11" />
 			<attribute name="Length" value="6.53" />
@@ -2764,7 +2765,7 @@
 			<attribute name="Font" value="Font;Fonts/BlueHighway.ttf" />
 			<attribute name="Font Size" value="15" />
 			<attribute name="Text" value="Metallic Value    &lt;-0.0  -&gt;1.0" />
-			<attribute name="Width" value="236" />
+			<attribute name="Width" value="237" />
 		</component>
 	</node>
 	<node id="307">
@@ -3190,7 +3191,7 @@
 			<attribute name="Font" value="Font;Fonts/BlueHighway.ttf" />
 			<attribute name="Font Size" value="15" />
 			<attribute name="Text" value="Sphere Lighting" />
-			<attribute name="Width" value="135" />
+			<attribute name="Width" value="134" />
 		</component>
 	</node>
 	<node id="338">
@@ -3999,9 +4000,9 @@
 		<attribute name="Scale" value="0.648644 0.648644 0.648644" />
 		<attribute name="Variables" />
 		<component type="Light" id="416">
-			<attribute name="Brightness Multiplier" value="800" />
+			<attribute name="Brightness Multiplier" value="1700" />
 			<attribute name="Use Physical Values" value="true" />
-			<attribute name="Radius" value="0.61" />
+			<attribute name="Radius" value="25.6" />
 			<attribute name="Range" value="7.61" />
 			<attribute name="Spot FOV" value="62.08" />
 			<attribute name="Light Shape Texture" value="TextureCube;" />