mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-02-13 19:53:48 +00:00
point light WIP & moved lighting position/direction to WS
This commit is contained in:
parent
d74055619f
commit
f0924c8dcd
6 changed files with 96 additions and 102 deletions
|
|
@ -337,7 +337,7 @@ void AdvancedLightBinManager::render( SceneRenderState *state )
|
|||
|
||||
// Set up SG data
|
||||
setupSGData( sgData, state, sunLight );
|
||||
vectorMatInfo->setLightParameters( sunLight, state, worldToCameraXfm );
|
||||
vectorMatInfo->setLightParameters( sunLight, state );
|
||||
|
||||
// Set light holds the active shadow map.
|
||||
mShadowManager->setLightShadowMapForLight( sunLight );
|
||||
|
|
@ -375,7 +375,7 @@ void AdvancedLightBinManager::render( SceneRenderState *state )
|
|||
GFXDEBUGEVENT_SCOPE( AdvancedLightBinManager_Render_Light, ColorI::RED );
|
||||
|
||||
setupSGData( sgData, state, curLightInfo );
|
||||
curLightMat->setLightParameters( curLightInfo, state, worldToCameraXfm );
|
||||
curLightMat->setLightParameters( curLightInfo, state );
|
||||
mShadowManager->setLightShadowMap( curEntry.shadowMap );
|
||||
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 ) );
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
|
|
@ -728,9 +728,7 @@ void AdvancedLightBinManager::LightMaterialInfo::setLightParameters( const Light
|
|||
{
|
||||
case LightInfo::Vector:
|
||||
{
|
||||
VectorF lightDir = lightInfo->getDirection();
|
||||
worldViewOnly.mulV(lightDir);
|
||||
lightDir.normalize();
|
||||
const VectorF lightDir = lightInfo->getDirection();
|
||||
matParams->setSafe( lightDirection, lightDir );
|
||||
|
||||
// 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 );
|
||||
|
||||
VectorF lightDir = lightInfo->getDirection();
|
||||
worldViewOnly.mulV(lightDir);
|
||||
lightDir.normalize();
|
||||
matParams->setSafe( lightDirection, lightDir );
|
||||
}
|
||||
// Fall through
|
||||
|
|
@ -779,10 +775,7 @@ void AdvancedLightBinManager::LightMaterialInfo::setLightParameters( const Light
|
|||
{
|
||||
const F32 radius = lightInfo->getRange().x;
|
||||
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.
|
||||
Point3F attenRatio = lightInfo->getExtended<ShadowMapParams>()->attenuationRatio;
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ protected:
|
|||
const PlaneF &farPlane,
|
||||
const PlaneF &_vsFarPlane );
|
||||
|
||||
void setLightParameters( const LightInfo *light, const SceneRenderState* renderState, const MatrixF &worldViewOnly );
|
||||
void setLightParameters( const LightInfo *light, const SceneRenderState* renderState );
|
||||
};
|
||||
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ struct Surface
|
|||
NdotV = abs(dot(N, V)) + 1e-5f; // avoid artifact
|
||||
|
||||
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);
|
||||
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)
|
||||
{
|
||||
Surface surface;
|
||||
Surface surface = (Surface)0;
|
||||
|
||||
float4 gbuffer1 = TORQUE_TEX2DLOD(gbufferTex1, 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.baseColor = gbuffer1;
|
||||
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.metalness = gbuffer2.a;
|
||||
surface.ao = gbuffer2.g;
|
||||
|
|
@ -146,8 +146,7 @@ struct SurfaceToLight
|
|||
|
||||
inline SurfaceToLight CreateSurfaceToLight(in Surface surface, in float3 L)
|
||||
{
|
||||
SurfaceToLight surfaceToLight;
|
||||
|
||||
SurfaceToLight surfaceToLight = (SurfaceToLight)0;
|
||||
surfaceToLight.L = normalize(L);
|
||||
surfaceToLight.H = normalize(surface.V + surfaceToLight.L);
|
||||
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)
|
||||
{
|
||||
//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;
|
||||
return Fd;
|
||||
}
|
||||
|
|
@ -182,7 +181,7 @@ struct LightResult
|
|||
|
||||
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;
|
||||
result.diffuse = BRDF_GetDiffuse(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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -131,9 +131,9 @@ uniform float4 lightParams;
|
|||
|
||||
uniform float lightRange;
|
||||
uniform float shadowSoftness;
|
||||
uniform float2 lightAttenuation;
|
||||
|
||||
uniform float4x4 worldToCamera;
|
||||
uniform float3x3 viewToLightProj;
|
||||
uniform float3x3 worldToLightProj;
|
||||
uniform float3x3 dynamicViewToLightProj;
|
||||
|
||||
uniform float3 eyePosWorld;
|
||||
|
|
@ -152,25 +152,14 @@ LightTargetOutput main( ConvexConnectP IN )
|
|||
if (normDepth.w>0.9999)
|
||||
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
|
||||
Surface surface = CreateSurface( normDepth, TORQUE_SAMPLER2D_MAKEARG(colorBuffer),TORQUE_SAMPLER2D_MAKEARG(matInfoBuffer),
|
||||
uvScene, eyePosWorld, eyeRay, cameraToWorld);
|
||||
uvScene, eyePosWorld, wsEyeRay, cameraToWorld);
|
||||
|
||||
//early out if emissive
|
||||
if (getFlag(surface.matFlag, 0))
|
||||
{
|
||||
|
|
@ -178,80 +167,76 @@ LightTargetOutput main( ConvexConnectP IN )
|
|||
Output.spec = surface.baseColor;
|
||||
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);
|
||||
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
|
||||
#ifdef NO_SHADOW
|
||||
float shadowed = 1.0;
|
||||
#else
|
||||
|
||||
float shadowed = 1.0;
|
||||
#ifdef SHADOW_CUBE
|
||||
|
||||
#else
|
||||
// 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 ) ) );
|
||||
|
||||
// Get a linear depth from the light source.
|
||||
float distToLight = lenLightV / lightRange;
|
||||
#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);
|
||||
|
||||
#ifdef SHADOW_CUBE
|
||||
// Dynamic
|
||||
float dynamic_shadowed = softShadow_filter(TORQUE_SAMPLER2D_MAKEARG(dynamicShadowMap),
|
||||
ssPos.xy,
|
||||
shadowCoord,
|
||||
shadowSoftness,
|
||||
distToLight,
|
||||
surfaceToLight.NdotL,
|
||||
lightParams.y);
|
||||
|
||||
// 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)));
|
||||
float shadowed = min(static_shadowed, dynamic_shadowed);
|
||||
|
||||
#else
|
||||
#endif
|
||||
|
||||
#endif // !NO_SHADOW
|
||||
|
||||
float3 lightcol = lightColor.rgb;
|
||||
/*#ifdef USE_COOKIE_TEX
|
||||
|
||||
// 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);
|
||||
// Lookup the cookie sample.
|
||||
float4 cookie = TORQUE_TEXCUBE(cookieMap, mul(viewToLightProj, -surfaceToLight.L));
|
||||
|
||||
// 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);
|
||||
// Multiply the light with the cookie tex.
|
||||
lightcol *= cookie.rgb;
|
||||
|
||||
float shadowed = min(static_shadowed, dynamic_shadowed);
|
||||
// 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*/
|
||||
|
||||
#endif // !NO_SHADOW
|
||||
|
||||
float3 lightcol = lightColor.rgb;
|
||||
#ifdef USE_COOKIE_TEX
|
||||
|
||||
// Lookup the cookie sample.
|
||||
float4 cookie = TORQUE_TEXCUBE(cookieMap, mul(viewToLightProj, -lightVec));
|
||||
|
||||
// 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));
|
||||
|
||||
#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.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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -203,9 +203,8 @@ LightTargetOutput main(FarFrustumQuadConnectP IN)
|
|||
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
|
||||
float3 lightingColor = lightColor.rgb;
|
||||
|
|
|
|||
|
|
@ -346,6 +346,4 @@ float3 getCubeDir(int face, float2 uv)
|
|||
}
|
||||
|
||||
#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_
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue