Browse Source

point light WIP & moved lighting position/direction to WS

Tim Barnes 6 years ago
parent
commit
c64aee9dcc

+ 5 - 12
Engine/source/lighting/advanced/advancedLightBinManager.cpp

@@ -337,7 +337,7 @@ void AdvancedLightBinManager::render( SceneRenderState *state )
 
 
       // Set up SG data
       // Set up SG data
       setupSGData( sgData, state, sunLight );
       setupSGData( sgData, state, sunLight );
-      vectorMatInfo->setLightParameters( sunLight, state, worldToCameraXfm );
+      vectorMatInfo->setLightParameters( sunLight, state );
 
 
       // Set light holds the active shadow map.       
       // Set light holds the active shadow map.       
       mShadowManager->setLightShadowMapForLight( sunLight );
       mShadowManager->setLightShadowMapForLight( sunLight );
@@ -375,7 +375,7 @@ void AdvancedLightBinManager::render( SceneRenderState *state )
       GFXDEBUGEVENT_SCOPE( AdvancedLightBinManager_Render_Light, ColorI::RED );
       GFXDEBUGEVENT_SCOPE( AdvancedLightBinManager_Render_Light, ColorI::RED );
 
 
       setupSGData( sgData, state, curLightInfo );
       setupSGData( sgData, state, curLightInfo );
-      curLightMat->setLightParameters( curLightInfo, state, worldToCameraXfm );
+      curLightMat->setLightParameters( curLightInfo, state );
       mShadowManager->setLightShadowMap( curEntry.shadowMap );
       mShadowManager->setLightShadowMap( curEntry.shadowMap );
       mShadowManager->setLightDynamicShadowMap( curEntry.dynamicShadowMap );
       mShadowManager->setLightDynamicShadowMap( curEntry.dynamicShadowMap );
 
 
@@ -703,7 +703,7 @@ void AdvancedLightBinManager::LightMaterialInfo::setViewParameters(  const F32 _
    matParams->setSafe( zNearFarInvNearFar, Point4F( _zNear, _zFar, 1.0f / _zNear, 1.0f / _zFar ) );
    matParams->setSafe( zNearFarInvNearFar, Point4F( _zNear, _zFar, 1.0f / _zNear, 1.0f / _zFar ) );
 }
 }
 
 
-void AdvancedLightBinManager::LightMaterialInfo::setLightParameters( const LightInfo *lightInfo, const SceneRenderState* renderState, const MatrixF &worldViewOnly )
+void AdvancedLightBinManager::LightMaterialInfo::setLightParameters( const LightInfo *lightInfo, const SceneRenderState* renderState )
 {
 {
    MaterialParameters *matParams = matInstance->getMaterialParameters();
    MaterialParameters *matParams = matInstance->getMaterialParameters();
 
 
@@ -728,9 +728,7 @@ void AdvancedLightBinManager::LightMaterialInfo::setLightParameters( const Light
    {
    {
    case LightInfo::Vector:
    case LightInfo::Vector:
       {
       {
-         VectorF lightDir = lightInfo->getDirection();
-         worldViewOnly.mulV(lightDir);
-         lightDir.normalize();
+         const VectorF lightDir = lightInfo->getDirection();
          matParams->setSafe( lightDirection, lightDir );
          matParams->setSafe( lightDirection, lightDir );
 
 
          // Set small number for alpha since it represents existing specular in
          // Set small number for alpha since it represents existing specular in
@@ -769,8 +767,6 @@ void AdvancedLightBinManager::LightMaterialInfo::setLightParameters( const Light
          matParams->setSafe( lightSpotParams, spotParams );
          matParams->setSafe( lightSpotParams, spotParams );
 
 
          VectorF lightDir = lightInfo->getDirection();
          VectorF lightDir = lightInfo->getDirection();
-         worldViewOnly.mulV(lightDir);
-         lightDir.normalize();
          matParams->setSafe( lightDirection, lightDir );
          matParams->setSafe( lightDirection, lightDir );
       }
       }
       // Fall through
       // Fall through
@@ -779,10 +775,7 @@ void AdvancedLightBinManager::LightMaterialInfo::setLightParameters( const Light
    {
    {
       const F32 radius = lightInfo->getRange().x;
       const F32 radius = lightInfo->getRange().x;
       matParams->setSafe( lightRange, radius );
       matParams->setSafe( lightRange, radius );
-
-      Point3F lightPos;
-      worldViewOnly.mulP(lightInfo->getPosition(), &lightPos);
-      matParams->setSafe( lightPosition, lightPos );
+      matParams->setSafe( lightPosition, lightInfo->getPosition());
 
 
       // Get the attenuation falloff ratio and normalize it.
       // Get the attenuation falloff ratio and normalize it.
       Point3F attenRatio = lightInfo->getExtended<ShadowMapParams>()->attenuationRatio;
       Point3F attenRatio = lightInfo->getExtended<ShadowMapParams>()->attenuationRatio;

+ 1 - 1
Engine/source/lighting/advanced/advancedLightBinManager.h

@@ -184,7 +184,7 @@ protected:
                               const PlaneF &farPlane,
                               const PlaneF &farPlane,
                               const PlaneF &_vsFarPlane );
                               const PlaneF &_vsFarPlane );
 
 
-      void setLightParameters( const LightInfo *light, const SceneRenderState* renderState, const MatrixF &worldViewOnly );
+      void setLightParameters( const LightInfo *light, const SceneRenderState* renderState );
    };
    };
 
 
 protected:
 protected:

+ 26 - 7
Templates/Full/game/shaders/common/lighting.hlsl

@@ -104,7 +104,7 @@ struct Surface
 		NdotV = abs(dot(N, V)) + 1e-5f; // avoid artifact
 		NdotV = abs(dot(N, V)) + 1e-5f; // avoid artifact
 
 
 		albedo = baseColor.rgb * (1.0 - metalness);
 		albedo = baseColor.rgb * (1.0 - metalness);
-		f0 = lerp(float3_splat(0.04), baseColor.rgb, metalness);
+		f0 = lerp(0.04.xxx, baseColor.rgb, metalness);
 
 
 		R = -reflect(V, N);
 		R = -reflect(V, N);
 		float f90 = saturate(50.0 * dot(f0, 0.33));
 		float f90 = saturate(50.0 * dot(f0, 0.33));
@@ -114,7 +114,7 @@ struct Surface
 
 
 inline Surface CreateSurface(float4 gbuffer0, TORQUE_SAMPLER2D(gbufferTex1), TORQUE_SAMPLER2D(gbufferTex2), in float2 uv, in float3 wsEyePos, in float3 wsEyeRay, in float4x4 invView)
 inline Surface CreateSurface(float4 gbuffer0, TORQUE_SAMPLER2D(gbufferTex1), TORQUE_SAMPLER2D(gbufferTex2), in float2 uv, in float3 wsEyePos, in float3 wsEyeRay, in float4x4 invView)
 {
 {
-	Surface surface;
+	Surface surface = (Surface)0;
 
 
    float4 gbuffer1 = TORQUE_TEX2DLOD(gbufferTex1, float4(uv,0,0));
    float4 gbuffer1 = TORQUE_TEX2DLOD(gbufferTex1, float4(uv,0,0));
    float4 gbuffer2 = TORQUE_TEX2DLOD(gbufferTex2, float4(uv,0,0));
    float4 gbuffer2 = TORQUE_TEX2DLOD(gbufferTex2, float4(uv,0,0));
@@ -125,7 +125,7 @@ inline Surface CreateSurface(float4 gbuffer0, TORQUE_SAMPLER2D(gbufferTex1), TOR
 	surface.V = normalize(wsEyePos - surface.P);
 	surface.V = normalize(wsEyePos - surface.P);
 	surface.baseColor = gbuffer1;
 	surface.baseColor = gbuffer1;
    const float minRoughness=1e-4;
    const float minRoughness=1e-4;
-	surface.roughness = clamp(1.0 - gbuffer2.b, minRoughness, 1.0); //torque uses smoothness so we convert to roughness. Should really clamp during gbuffer pass though
+	surface.roughness = clamp(1.0 - gbuffer2.b, minRoughness, 1.0); //t3d uses smoothness, so we convert to roughness.
 	surface.roughness_brdf = surface.roughness * surface.roughness;
 	surface.roughness_brdf = surface.roughness * surface.roughness;
 	surface.metalness = gbuffer2.a;
 	surface.metalness = gbuffer2.a;
    surface.ao = gbuffer2.g;
    surface.ao = gbuffer2.g;
@@ -146,8 +146,7 @@ struct SurfaceToLight
 
 
 inline SurfaceToLight CreateSurfaceToLight(in Surface surface, in float3 L)
 inline SurfaceToLight CreateSurfaceToLight(in Surface surface, in float3 L)
 {
 {
-	SurfaceToLight surfaceToLight;
-
+	SurfaceToLight surfaceToLight = (SurfaceToLight)0;
 	surfaceToLight.L = normalize(L);
 	surfaceToLight.L = normalize(L);
 	surfaceToLight.H = normalize(surface.V + surfaceToLight.L);
 	surfaceToLight.H = normalize(surface.V + surfaceToLight.L);
 	surfaceToLight.NdotL = saturate(dot(surfaceToLight.L, surface.N));
 	surfaceToLight.NdotL = saturate(dot(surfaceToLight.L, surface.N));
@@ -169,7 +168,7 @@ float3 BRDF_GetSpecular(in Surface surface, in SurfaceToLight surfaceToLight)
 
 
 float BRDF_GetDiffuse(in Surface surface, in SurfaceToLight surfaceToLight)
 float BRDF_GetDiffuse(in Surface surface, in SurfaceToLight surfaceToLight)
 {
 {
-   //getting some banding with disney method, using lambert instead - todo do some futher testing
+   //getting some banding with disney method, using lambert instead - todo futher testing
 	float Fd = 1.0 / M_PI_F;//Fr_DisneyDiffuse(surface.NdotV, surfaceToLight.NdotL, surfaceToLight.HdotV, surface.roughness) / M_PI_F;
 	float Fd = 1.0 / M_PI_F;//Fr_DisneyDiffuse(surface.NdotV, surfaceToLight.NdotL, surfaceToLight.HdotV, surface.roughness) / M_PI_F;
 	return Fd;
 	return Fd;
 }
 }
@@ -182,7 +181,7 @@ struct LightResult
 
 
 inline LightResult GetDirectionalLight(in Surface surface, in SurfaceToLight surfaceToLight, float3 lightColor, float lightIntensity, float shadow)
 inline LightResult GetDirectionalLight(in Surface surface, in SurfaceToLight surfaceToLight, float3 lightColor, float lightIntensity, float shadow)
 {
 {
-   LightResult result;
+   LightResult result = (LightResult)0;
    float3 factor = lightColor * max(surfaceToLight.NdotL, 0) * shadow * lightIntensity;
    float3 factor = lightColor * max(surfaceToLight.NdotL, 0) * shadow * lightIntensity;
    result.diffuse = BRDF_GetDiffuse(surface,surfaceToLight) * factor;
    result.diffuse = BRDF_GetDiffuse(surface,surfaceToLight) * factor;
    result.spec = BRDF_GetSpecular(surface,surfaceToLight) * factor;
    result.spec = BRDF_GetSpecular(surface,surfaceToLight) * factor;
@@ -192,3 +191,23 @@ inline LightResult GetDirectionalLight(in Surface surface, in SurfaceToLight sur
 
 
    return result;
    return result;
 }
 }
+
+inline LightResult GetPointLight(in Surface surface, in SurfaceToLight surfaceToLight, float3 lightColor, float lightIntensity,float distToLight, float radius, float shadow)
+{
+   LightResult result = (LightResult)0;
+
+   // Distance attenuation from Epic Games' paper
+   float distanceByRadius = 1.0f - pow((distToLight / radius), 4);
+   float clamped = pow(clamp(distanceByRadius, 0.0f, 1.0f), 2.0f);
+   float attenuation = clamped / (sqr(distToLight) + 1.0f);
+
+   float3 factor = lightColor * max(surfaceToLight.NdotL, 0) * shadow * lightIntensity * attenuation;
+
+   result.diffuse = BRDF_GetDiffuse(surface,surfaceToLight) * factor;
+   result.spec = BRDF_GetSpecular(surface,surfaceToLight) * factor;
+
+   result.diffuse = max(0.0f, result.diffuse);
+   result.spec = max(0.0f, result.spec);
+
+   return result;
+}

+ 69 - 84
Templates/Full/game/shaders/common/lighting/advanced/pointLightP.hlsl

@@ -131,9 +131,9 @@ uniform float4 lightParams;
 
 
 uniform float  lightRange;
 uniform float  lightRange;
 uniform float shadowSoftness;
 uniform float shadowSoftness;
-uniform float2 lightAttenuation;
-
+uniform float4x4 worldToCamera;
 uniform float3x3 viewToLightProj;
 uniform float3x3 viewToLightProj;
+uniform float3x3 worldToLightProj;
 uniform float3x3 dynamicViewToLightProj;
 uniform float3x3 dynamicViewToLightProj;
 
 
 uniform float3 eyePosWorld;
 uniform float3 eyePosWorld;
@@ -152,25 +152,14 @@ LightTargetOutput main(   ConvexConnectP IN )
    if (normDepth.w>0.9999)
    if (normDepth.w>0.9999)
       return Output;
       return Output;
       
       
-   // Eye ray - Eye -> Pixel
-   float3 eyeRay = getDistanceVectorToPlane( -vsFarPlane.w, IN.vsEyeDir.xyz, vsFarPlane );
-   float3 viewSpacePos = eyeRay * normDepth.w;
-   
-   // Build light vec, get length, clip pixel if needed
-   float3 lightVec = lightPosition - viewSpacePos;
-   float lenLightV = length(lightVec);
-   clip(lightRange - lenLightV);   
+   //eye ray WS/VS
+   float3 vsEyeRay = getDistanceVectorToPlane( -vsFarPlane.w, IN.vsEyeDir.xyz, vsFarPlane );
+   float3 wsEyeRay = mul(cameraToWorld, float4(vsEyeRay, 0)).xyz;
 
 
-   // Get the attenuated falloff.
-   float atten = attenuate(lightColor, lightAttenuation, lenLightV);
-   clip(atten - 1e-6);
-
-   // Normalize lightVec
-   lightVec /= lenLightV;
-   
    //create surface
    //create surface
    Surface surface = CreateSurface( normDepth, TORQUE_SAMPLER2D_MAKEARG(colorBuffer),TORQUE_SAMPLER2D_MAKEARG(matInfoBuffer),
    Surface surface = CreateSurface( normDepth, TORQUE_SAMPLER2D_MAKEARG(colorBuffer),TORQUE_SAMPLER2D_MAKEARG(matInfoBuffer),
-                                    uvScene, eyePosWorld, eyeRay, cameraToWorld);   
+                                    uvScene, eyePosWorld, wsEyeRay, cameraToWorld);
+
    //early out if emissive
    //early out if emissive
    if (getFlag(surface.matFlag, 0))
    if (getFlag(surface.matFlag, 0))
    {   
    {   
@@ -178,80 +167,76 @@ LightTargetOutput main(   ConvexConnectP IN )
       Output.spec = surface.baseColor;
       Output.spec = surface.baseColor;
       return Output;
       return Output;
 	}
 	}
-   
-   // If we can do dynamic branching then avoid wasting
-   // fillrate on pixels that are backfacing to the light.
-   float nDotL = dot( lightVec, normDepth.xyz );
-   //DB_CLIP( nDotL < 0 );
-   //create surface to light 
-   float3 wsLightDir = mul(cameraToWorld, float4(lightVec,0)).xyz;
-   SurfaceToLight surfaceToLight = CreateSurfaceToLight(surface, wsLightDir);//lightPosition - viewSpacePos);
-
-#ifdef NO_SHADOW
-
-   float shadowed = 1.0;
-
-#else
-
-   // Get a linear depth from the light source.
-   float distToLight = lenLightV / lightRange;
-
-#ifdef SHADOW_CUBE
 
 
-   // TODO: We need to fix shadow cube to handle soft shadows!
-   float occ = TORQUE_TEXCUBE(shadowMap, mul(viewToLightProj, -lightVec)).r;
-   float shadowed = saturate(exp(lightParams.y * (occ - distToLight)));
-
-#else
-
-   // Static
-   float2 shadowCoord = decodeShadowCoord(mul(viewToLightProj, -lightVec)).xy;
-   float static_shadowed = softShadow_filter(TORQUE_SAMPLER2D_MAKEARG(shadowMap),
-      ssPos.xy,
-      shadowCoord,
-      shadowSoftness,
-      distToLight,
-      surfaceToLight.NdotL,
-      lightParams.y);
-
-   // Dynamic
-   float2 dynamicShadowCoord = decodeShadowCoord(mul(dynamicViewToLightProj, -lightVec)).xy;
-   float dynamic_shadowed = softShadow_filter(TORQUE_SAMPLER2D_MAKEARG(dynamicShadowMap),
-      ssPos.xy,
-      dynamicShadowCoord,
-      shadowSoftness,
-      distToLight,
-      surfaceToLight.NdotL,
-      lightParams.y);
-
-   float shadowed = min(static_shadowed, dynamic_shadowed);
-
-#endif
-
-#endif // !NO_SHADOW
-
-   float3 lightcol = lightColor.rgb;
-#ifdef USE_COOKIE_TEX
+   //create surface to light 
+   float3 L = lightPosition - surface.P;
+   float dist = length(L);
+   LightResult result = (LightResult)0;
+   [branch]
+	if (dist < lightRange)
+	{     
+      float distToLight = dist / lightRange;
+      SurfaceToLight surfaceToLight = CreateSurfaceToLight(surface, L);
+
+   #ifdef NO_SHADOW
+      float shadowed = 1.0;
+   #else
+
+   #ifdef SHADOW_CUBE
+
+      // TODO: We need to fix shadow cube to handle soft shadows!
+      float occ = TORQUE_TEXCUBE( shadowMap, mul( worldToLightProj, -surfaceToLight.L ) ).r;
+      float shadowed = saturate( exp( lightParams.y * ( occ - distToLight ) ) );
+
+   #else
+      // Static
+      float2 shadowCoord = decodeShadowCoord( mul( worldToLightProj, -surfaceToLight.L ) ).xy;
+      float static_shadowed = softShadow_filter(TORQUE_SAMPLER2D_MAKEARG(shadowMap),
+         ssPos.xy,
+         shadowCoord,
+         shadowSoftness,
+         distToLight,
+         surfaceToLight.NdotL,
+         lightParams.y);
+
+      // Dynamic
+      float dynamic_shadowed = softShadow_filter(TORQUE_SAMPLER2D_MAKEARG(dynamicShadowMap),
+         ssPos.xy,
+         shadowCoord,
+         shadowSoftness,
+         distToLight,
+         surfaceToLight.NdotL,
+         lightParams.y);
+
+      float shadowed = min(static_shadowed, dynamic_shadowed);
+
+   #endif
+   
+   #endif // !NO_SHADOW
+   
+      float3 lightcol = lightColor.rgb;
+   /*#ifdef USE_COOKIE_TEX
 
 
-   // Lookup the cookie sample.
-   float4 cookie = TORQUE_TEXCUBE(cookieMap, mul(viewToLightProj, -lightVec));
+      // Lookup the cookie sample.
+      float4 cookie = TORQUE_TEXCUBE(cookieMap, mul(viewToLightProj, -surfaceToLight.L));
 
 
-   // Multiply the light with the cookie tex.
-   lightcol *= cookie.rgb;
+      // Multiply the light with the cookie tex.
+      lightcol *= cookie.rgb;
 
 
-   // Use a maximum channel luminance to attenuate 
-   // the lighting else we get specular in the dark
-   // regions of the cookie texture.
-   atten *= max(cookie.r, max(cookie.g, cookie.b));
+      // Use a maximum channel luminance to attenuate 
+      // the lighting else we get specular in the dark
+      // regions of the cookie texture.
+      atten *= max(cookie.r, max(cookie.g, cookie.b));
 
 
-#endif
+   #endif*/
 
 
-   //get directional light contribution   
-   LightResult result = GetDirectionalLight(surface, surfaceToLight, lightColor.rgb, lightBrightness, shadowed);
+      //get point light contribution   
+      result = GetPointLight(surface, surfaceToLight, lightcol, lightBrightness, dist, lightRange, shadowed);
+   }
       
       
    //output
    //output
-   Output.diffuse = float4(result.diffuse*atten, 0);
-   Output.spec = float4(result.spec*atten, 0);
+   Output.diffuse = float4(result.diffuse, 0);
+   Output.spec = float4(result.spec, 0);
    
    
    return Output;
    return Output;
 }
 }

+ 2 - 3
Templates/Full/game/shaders/common/lighting/advanced/vectorLightP.hlsl

@@ -203,9 +203,8 @@ LightTargetOutput main(FarFrustumQuadConnectP IN)
       return Output;
       return Output;
 	}
 	}
    
    
-   //create surface to light    
-   float3 wsLightDir = mul(cameraToWorld, float4(lightDirection,0)).xyz;                             
-   SurfaceToLight surfaceToLight = CreateSurfaceToLight(surface, -wsLightDir);
+   //create surface to light                           
+   SurfaceToLight surfaceToLight = CreateSurfaceToLight(surface, -lightDirection);
 
 
    //light color might be changed by PSSM_DEBUG_RENDER
    //light color might be changed by PSSM_DEBUG_RENDER
    float3 lightingColor = lightColor.rgb;
    float3 lightingColor = lightColor.rgb;

+ 0 - 2
Templates/Full/game/shaders/common/torque.hlsl

@@ -346,6 +346,4 @@ float3 getCubeDir(int face, float2 uv)
 }
 }
 
 
 #define sqr(a)		((a)*(a))
 #define sqr(a)		((a)*(a))
-#define float4_splat(a) float4(a,a,a,a)
-#define float3_splat(a) float3(a,a,a)
 #endif // _TORQUE_HLSL_
 #endif // _TORQUE_HLSL_