Merge pull request #1138 from Azaezel/alha41/luxTargTricks

lighting corrections:
This commit is contained in:
Brian Roberts 2023-11-20 12:03:23 -06:00 committed by GitHub
commit 52e7156436
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 117 additions and 78 deletions

View file

@ -790,7 +790,7 @@ void AdvancedLightBinManager::LightMaterialInfo::setLightParameters( const Light
MaterialParameters *matParams = matInstance->getMaterialParameters(); MaterialParameters *matParams = matInstance->getMaterialParameters();
matParams->setSafe( lightColor, lightInfo->getColor() ); matParams->setSafe( lightColor, lightInfo->getColor() );
matParams->setSafe(lightBrightness, lightInfo->getBrightness() * lightInfo->getFadeAmount()); F32 luxTargMultiplier = 1;
switch( lightInfo->getType() ) switch( lightInfo->getType() )
{ {
@ -804,10 +804,10 @@ void AdvancedLightBinManager::LightMaterialInfo::setLightParameters( const Light
case LightInfo::Spot: case LightInfo::Spot:
{ {
const F32 outerCone = lightInfo->getOuterConeAngle(); const F32 outerCone = lightInfo->getOuterConeAngle();
const F32 innerCone = getMin(lightInfo->getInnerConeAngle(), outerCone); const F32 innerCone = getMin(lightInfo->getInnerConeAngle(), outerCone-0.0001f);
const F32 outerCos = mCos(mDegToRad(outerCone / 2.0f)); const F32 outerCos = mCos(mDegToRad(outerCone / 2.0f));
const F32 innerCos = mCos(mDegToRad(innerCone / 2.0f)); const F32 innerCos = mCos(mDegToRad(innerCone / 2.0f));
Point2F spotParams(outerCos,innerCos - outerCos); Point2F spotParams(outerCos,mMax(innerCos - outerCos,0.001f));
matParams->setSafe( lightSpotParams, spotParams ); matParams->setSafe( lightSpotParams, spotParams );
matParams->setSafe( lightDirection, lightInfo->getDirection()); matParams->setSafe( lightDirection, lightInfo->getDirection());
@ -817,6 +817,9 @@ void AdvancedLightBinManager::LightMaterialInfo::setLightParameters( const Light
const F32 invSqrRadius = 1.0f / mSquared(radius); const F32 invSqrRadius = 1.0f / mSquared(radius);
matParams->setSafe(lightRange, radius); matParams->setSafe(lightRange, radius);
matParams->setSafe(lightInvSqrRange, invSqrRadius); matParams->setSafe(lightInvSqrRange, invSqrRadius);
F32 concentration = 360.0f/ outerCone;
luxTargMultiplier = radius * concentration;
} }
break; break;
@ -828,6 +831,7 @@ void AdvancedLightBinManager::LightMaterialInfo::setLightParameters( const Light
const F32 invSqrRadius = 1.0f / (radius * radius); const F32 invSqrRadius = 1.0f / (radius * radius);
matParams->setSafe( lightRange, radius); matParams->setSafe( lightRange, radius);
matParams->setSafe( lightInvSqrRange, invSqrRadius); matParams->setSafe( lightInvSqrRange, invSqrRadius);
luxTargMultiplier =radius;
} }
break; break;
@ -835,6 +839,7 @@ void AdvancedLightBinManager::LightMaterialInfo::setLightParameters( const Light
AssertFatal( false, "Bad light type!" ); AssertFatal( false, "Bad light type!" );
break; break;
} }
matParams->setSafe(lightBrightness, lightInfo->getBrightness()* lightInfo->getFadeAmount() * luxTargMultiplier);
} }
bool LightMatInstance::setupPass( SceneRenderState *state, const SceneData &sgData ) bool LightMatInstance::setupPass( SceneRenderState *state, const SceneData &sgData )

View file

@ -333,7 +333,7 @@ void LightManager::_update4LightConsts( const SceneData &sgData,
static AlignedArray<Point4F> lightSpotDirs(MAX_FORWARD_LIGHTS, sizeof(Point4F)); static AlignedArray<Point4F> lightSpotDirs(MAX_FORWARD_LIGHTS, sizeof(Point4F));
static AlignedArray<Point4F> lightColors(MAX_FORWARD_LIGHTS, sizeof(Point4F)); static AlignedArray<Point4F> lightColors(MAX_FORWARD_LIGHTS, sizeof(Point4F));
static AlignedArray<Point4F> lightConfigData(MAX_FORWARD_LIGHTS, sizeof(Point4F)); //type, brightness, range, invSqrRange : rgba static AlignedArray<Point4F> lightConfigData(MAX_FORWARD_LIGHTS, sizeof(Point4F)); //type, brightness, range, invSqrRange : rgba
static AlignedArray<Point2F> lightSpotParams(MAX_FORWARD_LIGHTS, sizeof(Point2F)); static AlignedArray<Point2F> lightSpotParams(MAX_FORWARD_LIGHTS, sizeof(Point4F));
dMemset(lightPositions.getBuffer(), 0, lightPositions.getBufferSize()); dMemset(lightPositions.getBuffer(), 0, lightPositions.getBufferSize());
dMemset(lightSpotDirs.getBuffer(), 0, lightSpotDirs.getBufferSize()); dMemset(lightSpotDirs.getBuffer(), 0, lightSpotDirs.getBufferSize());
@ -352,11 +352,12 @@ void LightManager::_update4LightConsts( const SceneData &sgData,
vectorLightDirection = Point4F::Zero; vectorLightDirection = Point4F::Zero;
vectorLightColor = Point4F::Zero; vectorLightColor = Point4F::Zero;
vectorLightAmbientColor = Point4F::Zero; vectorLightAmbientColor = Point4F::Zero;
F32 luxTargMultiplier[MAX_FORWARD_LIGHTS];
// Gather the data for the first 4 lights. // Gather the data for the first 4 lights.
const LightInfo* light; const LightInfo* light;
for (U32 i = 0; i < MAX_FORWARD_LIGHTS; i++) for (U32 i = 0; i < MAX_FORWARD_LIGHTS; i++)
{ {
luxTargMultiplier[i] = 1.0;
light = sgData.lights[i]; light = sgData.lights[i];
if (!light) if (!light)
break; break;
@ -371,48 +372,52 @@ void LightManager::_update4LightConsts( const SceneData &sgData,
vectorLightColor = Point4F(light->getColor()); vectorLightColor = Point4F(light->getColor());
vectorLightAmbientColor = Point4F(light->getAmbient()); vectorLightAmbientColor = Point4F(light->getAmbient());
hasVectorLight = 1; hasVectorLight = 1;
continue;
} }
else
// The light positions and spot directions are
// in SoA order to make optimal use of the GPU.
const Point3F& lightPos = light->getPosition();
lightPositions[i].x = lightPos.x;
lightPositions[i].y = lightPos.y;
lightPositions[i].z = lightPos.z;
lightPositions[i].w = 0;
const VectorF& lightDir = light->getDirection();
lightSpotDirs[i].x = lightDir.x;
lightSpotDirs[i].y = lightDir.y;
lightSpotDirs[i].z = lightDir.z;
lightSpotDirs[i].w = 0;
lightColors[i] = Point4F(light->getColor());
if (light->getType() == LightInfo::Point)
{ {
lightConfigData[i].x = 0; // The light positions and spot directions are
// in SoA order to make optimal use of the GPU.
const Point3F& lightPos = light->getPosition();
lightPositions[i].x = lightPos.x;
lightPositions[i].y = lightPos.y;
lightPositions[i].z = lightPos.z;
lightPositions[i].w = 0;
lightColors[i] = Point4F(light->getColor());
F32 range = light->getRange().x;
lightConfigData[i].z = range;
if (light->getType() == LightInfo::Point)
{
lightConfigData[i].x = 0;
luxTargMultiplier[i] = range;
}
else if (light->getType() == LightInfo::Spot)
{
const VectorF& lightDir = light->getDirection();
lightSpotDirs[i].x = lightDir.x;
lightSpotDirs[i].y = lightDir.y;
lightSpotDirs[i].z = lightDir.z;
lightSpotDirs[i].w = 0;
lightConfigData[i].x = 1;
const F32 outerCone = light->getOuterConeAngle();
const F32 innerCone = getMin(light->getInnerConeAngle(), outerCone - 0.0001f);
const F32 outerCos = mCos(mDegToRad(outerCone / 2.0f));
const F32 innerCos = mCos(mDegToRad(innerCone / 2.0f));
Point2F spotParams(outerCos, mMax(innerCos - outerCos, 0.001f));
lightSpotParams[i].x = spotParams.x;
lightSpotParams[i].y = spotParams.y;
F32 concentration = 360.0f / outerCone;
luxTargMultiplier[i] = range * concentration;
}
lightConfigData[i].y = light->getBrightness() * luxTargMultiplier[i];
lightConfigData[i].w = 1.0f / (range * range);
} }
else if (light->getType() == LightInfo::Spot)
{
lightConfigData[i].x = 1;
const F32 outerCone = light->getOuterConeAngle();
const F32 innerCone = getMin(light->getInnerConeAngle(), outerCone);
const F32 outerCos = mCos(mDegToRad(outerCone / 2.0f));
const F32 innerCos = mCos(mDegToRad(innerCone / 2.0f));
Point2F spotParams(outerCos, innerCos - outerCos);
lightSpotParams[i].x = spotParams.x;
lightSpotParams[i].y = spotParams.y;
}
lightConfigData[i].y = light->getBrightness();
F32 range = light->getRange().x;
lightConfigData[i].z = range;
lightConfigData[i].w = 1.0f / (range * range);
} }
shaderConsts->setSafe(lightPositionSC, lightPositions); shaderConsts->setSafe(lightPositionSC, lightPositions);

View file

@ -71,7 +71,8 @@ void SingleLightShadowMap::_render( RenderPassManager* renderPass,
lightMatrix.inverse(); lightMatrix.inverse();
GFX->setWorldMatrix(lightMatrix); GFX->setWorldMatrix(lightMatrix);
const MatrixF& lightProj = GFX->getProjectionMatrix(); MatrixF lightProj = GFX->getProjectionMatrix();
lightProj.reverseProjection();
mWorldToLightProj = lightProj * lightMatrix; mWorldToLightProj = lightProj * lightMatrix;
// Render the shadowmap! // Render the shadowmap!

View file

@ -73,4 +73,14 @@ float D_GGX(float NdotH, float alphaRoughnessSq)
return alphaRoughnessSq / (M_PI_F * f * f); return alphaRoughnessSq / (M_PI_F * f * f);
} }
float3 Fr_DisneyDiffuse(float3 F0, float NdotV, float NdotL, float LdotH, float linearRoughness)
{
float energyBias = lerp (0 , 0.5 , linearRoughness );
float energyFactor = lerp (1.0 , 1.0 / 1.51 , linearRoughness );
float fd90 = energyBias + 2.0 * LdotH * LdotH * linearRoughness ;
float3 lightScatter = F_Schlick( F0 , fd90 , NdotL );
float3 viewScatter = F_Schlick(F0 , fd90 , NdotV );
return lightScatter * viewScatter * energyFactor ;
}
#endif #endif

View file

@ -67,4 +67,15 @@ float D_GGX(float NdotH, float alphaRoughnessSq)
return alphaRoughnessSq / (M_PI_F * f * f); return alphaRoughnessSq / (M_PI_F * f * f);
} }
vec3 Fr_DisneyDiffuse(vec3 F0, float NdotV, float NdotL, float LdotH, float linearRoughness)
{
float energyBias = lerp(0 , 0.5 , linearRoughness );
float energyFactor = lerp(1.0 , 1.0 / 1.51 , linearRoughness );
float fd90 = energyBias + 2.0 * LdotH * LdotH * linearRoughness ;
vec3 lightScatter = F_Schlick( F0 , fd90 , NdotL );
vec3 viewScatter = F_Schlick(F0 , fd90 , NdotV );
return lightScatter * viewScatter * energyFactor ;
}
#endif #endif

View file

@ -216,8 +216,8 @@ float getDistanceAtt( vec3 unormalizedLightVector , float invSqrAttRadius )
float getSpotAngleAtt( vec3 normalizedLightVector , vec3 lightDir , vec2 lightSpotParams ) float getSpotAngleAtt( vec3 normalizedLightVector , vec3 lightDir , vec2 lightSpotParams )
{ {
float cd = dot ( lightDir , normalizedLightVector ); float cd = max(dot( lightDir , normalizedLightVector ),0.0);
float attenuation = saturate ( ( cd - lightSpotParams.x ) / lightSpotParams.y ); float attenuation = saturate ( ( cd - lightSpotParams.x/(cd*1.001) ) / lightSpotParams.y );
// smooth the transition // smooth the transition
return sqr(attenuation); return sqr(attenuation);
} }
@ -225,7 +225,7 @@ float getDistanceAtt( vec3 unormalizedLightVector , float invSqrAttRadius )
vec3 evaluateStandardBRDF(Surface surface, SurfaceToLight surfaceToLight) vec3 evaluateStandardBRDF(Surface surface, SurfaceToLight surfaceToLight)
{ {
//lambert diffuse //lambert diffuse
vec3 Fd = surface.albedo.rgb * M_1OVER_PI_F; vec3 Fd = Fr_DisneyDiffuse(surface.f0, surface.NdotV, surfaceToLight.NdotL, surfaceToLight.NdotH, surface.linearRoughness);
//GGX specular //GGX specular
vec3 F = F_Schlick(surface.f0, surface.f90, surfaceToLight.HdotV); vec3 F = F_Schlick(surface.f0, surface.f90, surfaceToLight.HdotV);
@ -236,7 +236,7 @@ vec3 evaluateStandardBRDF(Surface surface, SurfaceToLight surfaceToLight)
#if CAPTURING == 1 #if CAPTURING == 1
return saturate(mix(Fd + Fr,surface.f0,surface.metalness)); return saturate(mix(Fd + Fr,surface.f0,surface.metalness));
#else #else
return saturate(Fd + Fr); return Fd + Fr;
#endif #endif
} }
@ -254,6 +254,15 @@ vec3 getPunctualLight(Surface surface, SurfaceToLight surfaceToLight, vec3 light
return evaluateStandardBRDF(surface,surfaceToLight) * factor; return evaluateStandardBRDF(surface,surfaceToLight) * factor;
} }
vec3 getSpotlight(Surface surface, SurfaceToLight surfaceToLight, vec3 lightColor, float lightIntensity, float radius, vec3 lightDir, vec2 lightSpotParams, float shadow)
{
float attenuation = 1.0f;
attenuation *= getDistanceAtt(surfaceToLight.Lu, radius);
attenuation *= getSpotAngleAtt(-surfaceToLight.L, lightDir, lightSpotParams.xy);
vec3 factor = lightColor * max(surfaceToLight.NdotL* shadow * lightIntensity * attenuation, 0.0f) ;
return evaluateStandardBRDF(surface,surfaceToLight) * factor;
}
float computeSpecOcclusion( float NdotV , float AO , float roughness ) float computeSpecOcclusion( float NdotV , float AO , float roughness )
{ {
return saturate (pow( abs(NdotV + AO) , exp2 ( -16.0f * roughness - 1.0f )) - 1.0f + AO ); return saturate (pow( abs(NdotV + AO) , exp2 ( -16.0f * roughness - 1.0f )) - 1.0f + AO );
@ -270,7 +279,7 @@ vec4 compute4Lights( Surface surface,
vec4 inLightConfigData[4], vec4 inLightConfigData[4],
vec4 inLightColor[4], vec4 inLightColor[4],
vec4 inLightSpotDir[4], vec4 inLightSpotDir[4],
vec2 lightSpotParams[4], vec2 inlightSpotParams[4],
int hasVectorLight, int hasVectorLight,
vec4 vectorLightDirection, vec4 vectorLightDirection,
vec4 vectorLightingColor, vec4 vectorLightingColor,
@ -305,13 +314,10 @@ vec4 compute4Lights( Surface surface,
//get punctual light contribution //get punctual light contribution
lighting = getPunctualLight(surface, surfaceToLight, lightCol, lightBrightness, lightInvSqrRange, shadowed); lighting = getPunctualLight(surface, surfaceToLight, lightCol, lightBrightness, lightInvSqrRange, shadowed);
} }
else //spot else if(inLightConfigData[i].x == 1) //spot
{ {
//get spot light contribution
//get Punctual light contribution lighting = getSpotlight(surface, surfaceToLight, lightCol, lightBrightness, lightInvSqrRange, inLightSpotDir[i].xyz, inlightSpotParams[i], shadowed);
lighting = getPunctualLight(surface, surfaceToLight, lightCol, lightBrightness, lightInvSqrRange, shadowed);
//get spot angle attenuation
lighting *= getSpotAngleAtt(-surfaceToLight.L, inLightSpotDir[i].xyz, lightSpotParams[i].xy );
} }
} }
finalLighting += lighting; finalLighting += lighting;

View file

@ -217,16 +217,16 @@ float getDistanceAtt( float3 unormalizedLightVector , float invSqrAttRadius )
float getSpotAngleAtt( float3 normalizedLightVector , float3 lightDir , float2 lightSpotParams ) float getSpotAngleAtt( float3 normalizedLightVector , float3 lightDir , float2 lightSpotParams )
{ {
float cd = dot ( lightDir , normalizedLightVector ); float cd = max(dot ( lightDir , normalizedLightVector ),0.0);
float attenuation = saturate ( ( cd - lightSpotParams.x ) / lightSpotParams.y ); float attenuation = saturate(((cd - lightSpotParams.x/(cd*1.001))/lightSpotParams.y));
// smooth the transition // smooth the transition
return sqr(attenuation); return sqr(attenuation);
} }
float3 evaluateStandardBRDF(Surface surface, SurfaceToLight surfaceToLight) float3 evaluateStandardBRDF(Surface surface, SurfaceToLight surfaceToLight)
{ {
//lambert diffuse //disney diffuse
float3 Fd = surface.albedo.rgb * M_1OVER_PI_F; float3 Fd = Fr_DisneyDiffuse(surface.f0, surface.NdotV, surfaceToLight.NdotL, surfaceToLight.NdotH, surface.linearRoughness);
//GGX specular //GGX specular
float3 F = F_Schlick(surface.f0, surface.f90, surfaceToLight.HdotV); float3 F = F_Schlick(surface.f0, surface.f90, surfaceToLight.HdotV);
@ -237,7 +237,7 @@ float3 evaluateStandardBRDF(Surface surface, SurfaceToLight surfaceToLight)
#if CAPTURING == 1 #if CAPTURING == 1
return saturate(lerp(Fd + Fr,surface.f0,surface.metalness)); return saturate(lerp(Fd + Fr,surface.f0,surface.metalness));
#else #else
return saturate(Fd + Fr); return Fd + Fr;
#endif #endif
} }
@ -255,6 +255,14 @@ float3 getPunctualLight(Surface surface, SurfaceToLight surfaceToLight, float3 l
return evaluateStandardBRDF(surface,surfaceToLight) * factor; return evaluateStandardBRDF(surface,surfaceToLight) * factor;
} }
float3 getSpotlight(Surface surface, SurfaceToLight surfaceToLight, float3 lightColor, float lightIntensity, float radius, float3 lightDir, float2 lightSpotParams, float shadow)
{
float attenuation = 1.0f;
attenuation *= getDistanceAtt(surfaceToLight.Lu, radius);
attenuation *= getSpotAngleAtt(-surfaceToLight.L, lightDir, lightSpotParams.xy);
float3 factor = lightColor * max(surfaceToLight.NdotL* shadow * lightIntensity * attenuation, 0.0f) ;
return evaluateStandardBRDF(surface,surfaceToLight) * factor;
}
float computeSpecOcclusion( float NdotV , float AO , float roughness ) float computeSpecOcclusion( float NdotV , float AO , float roughness )
{ {
return saturate (pow( abs(NdotV + AO) , exp2 ( -16.0f * roughness - 1.0f )) - 1.0f + AO ); return saturate (pow( abs(NdotV + AO) , exp2 ( -16.0f * roughness - 1.0f )) - 1.0f + AO );
@ -271,7 +279,7 @@ float4 compute4Lights( Surface surface,
float4 inLightConfigData[4], float4 inLightConfigData[4],
float4 inLightColor[4], float4 inLightColor[4],
float4 inLightSpotDir[4], float4 inLightSpotDir[4],
float2 lightSpotParams[4], float2 inlightSpotParams[4],
int hasVectorLight, int hasVectorLight,
float4 vectorLightDirection, float4 vectorLightDirection,
float4 vectorLightingColor, float4 vectorLightingColor,
@ -296,7 +304,7 @@ float4 compute4Lights( Surface surface,
float lightBrightness = inLightConfigData[i].y; float lightBrightness = inLightConfigData[i].y;
float lightInvSqrRange= inLightConfigData[i].a; float lightInvSqrRange= inLightConfigData[i].a;
float3 lighting = 0.0.xxx; float3 lighting = float3(0.0,0.0,0.0);
[branch] [branch]
if(dist < lightRange) if(dist < lightRange)
@ -307,13 +315,10 @@ float4 compute4Lights( Surface surface,
//get punctual light contribution //get punctual light contribution
lighting = getPunctualLight(surface, surfaceToLight, lightCol, lightBrightness, lightInvSqrRange, shadowed); lighting = getPunctualLight(surface, surfaceToLight, lightCol, lightBrightness, lightInvSqrRange, shadowed);
} }
else //spot else if(inLightConfigData[i].x == 1) //spot
{ {
//get spot light contribution
//get Punctual light contribution lighting = getSpotlight(surface, surfaceToLight, lightCol, lightBrightness, lightInvSqrRange, inLightSpotDir[i].xyz, inlightSpotParams[i], shadowed);
lighting = getPunctualLight(surface, surfaceToLight, lightCol, lightBrightness, lightInvSqrRange, shadowed);
//get spot angle attenuation
lighting *= getSpotAngleAtt(-surfaceToLight.L, inLightSpotDir[i].xyz, lightSpotParams[i].xy );
} }
} }
finalLighting += lighting; finalLighting += lighting;
@ -321,7 +326,7 @@ float4 compute4Lights( Surface surface,
//Vector light //Vector light
[branch] [branch]
if(hasVectorLight) if(hasVectorLight == 1)
{ {
SurfaceToLight surfaceToVecLight = createSurfaceToLight(surface, -vectorLightDirection.xyz); SurfaceToLight surfaceToVecLight = createSurfaceToLight(surface, -vectorLightDirection.xyz);

View file

@ -154,10 +154,8 @@ void main()
return; return;
#endif #endif
//get Punctual light contribution //get spot light contribution
lighting = getPunctualLight(surface, surfaceToLight, lightCol, lightBrightness, lightInvSqrRange, shadow); lighting = getSpotlight(surface, surfaceToLight, lightCol, lightBrightness, lightInvSqrRange, lightDirection, lightSpotParams, shadow);
//get spot angle attenuation
lighting *= getSpotAngleAtt(-surfaceToLight.L, lightDirection, lightSpotParams );
} }
OUT_col = vec4(lighting, 0); OUT_col = vec4(lighting, 0);

View file

@ -151,10 +151,8 @@ float4 main( ConvexConnectP IN ) : SV_TARGET
return final; return final;
#endif #endif
//get Punctual light contribution //get spot light contribution
lighting = getPunctualLight(surface, surfaceToLight, lightCol, lightBrightness, lightInvSqrRange, shadow); lighting = getSpotlight(surface, surfaceToLight, lightCol, lightBrightness, lightInvSqrRange, lightDirection, lightSpotParams, shadow);
//get spot angle attenuation
lighting *= getSpotAngleAtt(-surfaceToLight.L, lightDirection, lightSpotParams );
} }
return float4(lighting, 0); return float4(lighting, 0);