Added UTSPolygonFormFactor and UTSComputeEdgeFactor

This commit is contained in:
Misaki
2025-01-17 18:47:37 +09:00
parent b838223551
commit 12a03e9c3c
3 changed files with 107 additions and 173 deletions

View File

@@ -2,6 +2,8 @@
//nobuyuki@unity3d.com
//toshiyuki@unity3d.com (Universal RP/HDRP)
#define APPROXIMATE_POLY_LIGHT_AS_SPHERE_LIGHT
#if SHADERPASS != SHADERPASS_FORWARD
#error SHADERPASS_is_not_correctly_define
#endif
@@ -530,14 +532,14 @@ void Frag(PackedVaryingsToPS packedInput,
float4 distances; // {d, d^2, 1/d, d_proj}
GetPunctualLightVectors(posInput.positionWS, s_lightData, lightDirection, distances);
float4 lightColor = EvaluateLight_Punctual(context, posInput, s_lightData, lightDirection, distances);
float3 additionalLightColor = ApplyCurrentExposureMultiplier(lightColor.rgb) * lightColor.a;
float3 additionalLightColor = ApplyCurrentExposureMultiplier(lightColor.rgb);
const float notDirectional = 1.0f;
UTSLightData utsLightData;
utsLightData.lightColor = additionalLightColor;
utsLightData.lightDirection = lightDirection;
utsLightData.diffuseDimmer = s_lightData.diffuseDimmer;
utsLightData.specularDimmer = s_lightData.specularDimmer;
utsLightData.diffuseDimmer = s_lightData.diffuseDimmer * lightColor.a;
utsLightData.specularDimmer = s_lightData.specularDimmer * lightColor.a;
utsLightData.shadowTint = s_lightData.shadowTint;
utsLightData.penumbraTint = s_lightData.penumbraTint;
@@ -634,12 +636,25 @@ void Frag(PackedVaryingsToPS packedInput,
float4 ltcValue;
float4x3 lightVerts;
float3x3 invM = transpose(preLightData.ltcTransformDiffuse);
float3 A = mul(invM, right);
float3 B = mul(invM, up);
float3 C = mul(invM, center);
lightVerts[0] = C - halfWidth * A - halfHeight * B; // LL
lightVerts[1] = lightVerts[0] + (2 * halfHeight) * B; // UL
lightVerts[2] = lightVerts[1] + (2 * halfWidth) * A; // UR
lightVerts[3] = lightVerts[2] - (2 * halfHeight) * B; // LR
float3 F = UTSPolygonFormFactor(lightVerts, float3(0,0,1), 4);
float l = length(F * PI);
float alpha = saturate(max(0, (l * l) / (l + 1)));
// Diffuse
ltcValue = EvaluateLTC_Area(isRectLight, center, right, up, halfWidth, halfHeight, transpose(preLightData.ltcTransformDiffuse), /*bsdfData.perceptualRoughness*/ 1.0f, s_lightData.cookieMode, s_lightData.cookieScaleOffset);
utsLightData.diffuseDimmer *= ltcValue.a * intensity;
//ltcValue = smoothstep(0.0, 0.05, ltcValue);
//utsLightData.lightColor *= ltcValue.rgb * ltcValue.a * intensity;
utsLightData.lightColor *= ltcValue.rgb * intensity;
utsLightData.diffuseDimmer *= alpha * intensity;
utsLightData.lightColor *= ltcValue.rgb;
// Specular
ltcValue = EvaluateLTC_Area(isRectLight, center, right, up, halfWidth, halfHeight, transpose(preLightData.ltcTransformSpecular[0]), bsdfData.perceptualRoughness, s_lightData.cookieMode, s_lightData.cookieScaleOffset);
@@ -672,162 +687,6 @@ void Frag(PackedVaryingsToPS packedInput,
//utsAggregateLighting.directDiffuse += intensity;
#endif
/*
if(s_lightData.lightType == GPULIGHTTYPE_RECTANGLE)
{
#if SHADEROPTIONS_BARN_DOOR
// Apply the barn door modification to the light data
RectangularLightApplyBarnDoor(s_lightData, posInput.positionWS);
#endif
if (dot(s_lightData.forward, unL) < FLT_EPS)
{
float3x3 lightToWorld = float3x3(s_lightData.right, s_lightData.up, -s_lightData.forward);
unL = mul(unL, transpose(lightToWorld));
float halfWidth = s_lightData.size.x * 0.5;
float halfHeight = s_lightData.size.y * 0.5;
float range = s_lightData.range;
float3 invHalfDim = rcp(float3(range + halfWidth, range + halfHeight, range));
float intensity;
// Compute the light attenuation.
#ifdef ELLIPSOIDAL_ATTENUATION
// The attenuation volume is an axis-aligned ellipsoid s.t.
// r1 = (r + w / 2), r2 = (r + h / 2), r3 = r.
intensity = EllipsoidalDistanceAttenuation(unL, invHalfDim, s_lightData.rangeAttenuationScale, s_lightData.rangeAttenuationBias);
#else
// The attenuation volume is an axis-aligned box s.t.
// hX = (r + w / 2), hY = (r + h / 2), hZ = r.
intensity = BoxDistanceAttenuation(unL, invHalfDim, s_lightData.rangeAttenuationScale, s_lightData.rangeAttenuationBias);
#endif
if(intensity != 0.0f)
{
utsLightData.diffuseDimmer *= intensity;
utsLightData.specularDimmer *= intensity;
// Translate the light s.t. the shaded point is at the origin of the coordinate system.
s_lightData.positionRWS -= posInput.positionWS;
float4x3 lightVerts;
// TODO: some of this could be precomputed.
lightVerts[0] = s_lightData.positionRWS + s_lightData.right * -halfWidth + s_lightData.up * -halfHeight; // LL
lightVerts[1] = s_lightData.positionRWS + s_lightData.right * -halfWidth + s_lightData.up * halfHeight; // UL
lightVerts[2] = s_lightData.positionRWS + s_lightData.right * halfWidth + s_lightData.up * halfHeight; // UR
lightVerts[3] = s_lightData.positionRWS + s_lightData.right * halfWidth + s_lightData.up * -halfHeight; // LR
// Rotate the endpoints into the local coordinate system.
lightVerts = mul(lightVerts, transpose(preLightData.orthoBasisViewNormal));
float3 ltcValue;
// Evaluate the diffuse part
// Polygon irradiance in the transformed configuration.
float4x3 LD = mul(lightVerts, preLightData.ltcTransformDiffuse);
float3 formFactorD;
#ifdef APPROXIMATE_POLY_LIGHT_AS_SPHERE_LIGHT
formFactorD = PolygonFormFactor(LD, real3(0,0,1), 4);
ltcValue = PolygonIrradianceFromVectorFormFactor(formFactorD);
#else
ltcValue = PolygonIrradiance(LD);
#endif
utsLightData.diffuseDimmer *= ltcValue;
// Evaluate the specular part
// Polygon irradiance in the transformed configuration.
float4x3 LS = mul(lightVerts, preLightData.ltcTransformSpecular);
float3 formFactorS;
#ifdef APPROXIMATE_POLY_LIGHT_AS_SPHERE_LIGHT
formFactorS = PolygonFormFactor(LS, real3(0,0,1), 4);
ltcValue = PolygonIrradianceFromVectorFormFactor(formFactorS);
#else
ltcValue = PolygonIrradiance(LS);
#endif
utsLightData.specularDimmer *= ltcValue;
//Evaluate the shadow part
float shadow;
posInput.positionWS = posInput.positionWS + lightDirection * _ShadowBias;
#if defined(SCREEN_SPACE_SHADOWS_ON) && !defined(_SURFACE_TYPE_TRANSPARENT)
if ((s_lightData.screenSpaceShadowIndex & SCREEN_SPACE_SHADOW_INDEX_MASK) != INVALID_SCREEN_SPACE_SHADOW)
{
shadow = GetScreenSpaceShadow(posInput, s_lightData.screenSpaceShadowIndex);
}
else
#endif
{
shadow = EvaluateShadow_RectArea(context, posInput, s_lightData, builtinData, GetNormalForShadowBias(bsdfData), normalize(s_lightData.positionRWS), length(s_lightData.positionRWS));
}
context.shadowValue = shadow;
posInput.positionWS = posInput.positionWS - lightDirection * _ShadowBias;
#if defined(UTS_DEBUG_SELFSHADOW)
#else
UTS_OtherLights(context, input, utsLightData, surfaceData, bsdfData, s_lightData.lightType, i_normalDir, notDirectional, channelAlpha, utsAggregateLighting);
#endif
}
}
}
else if(s_lightData.lightType == GPULIGHTTYPE_TUBE)
{
float len = s_lightData.size.x;
float3 T = s_lightData.right;
// Pick the major axis of the ellipsoid.
float3 axis = s_lightData.right;
// We define the ellipsoid s.t. r1 = (r + len / 2), r2 = r3 = r.
// TODO: This could be precomputed.
float range = s_lightData.range;
float invAspectRatio = saturate(range / (range + (0.5 * len)));
// Compute the light attenuation.
float intensity = EllipsoidalDistanceAttenuation(unL, axis, invAspectRatio, s_lightData.rangeAttenuationScale, s_lightData.rangeAttenuationBias);
if(intensity != 0.0f)
{
utsLightData.diffuseDimmer *= intensity;
utsLightData.specularDimmer *= intensity;
// Translate the light s.t. the shaded point is at the origin of the coordinate system.
s_lightData.positionRWS -= posInput.positionWS;
// TODO: some of this could be precomputed.
float3 P1 = s_lightData.positionRWS - T * (0.5 * len);
float3 P2 = s_lightData.positionRWS + T * (0.5 * len);
// Rotate the endpoints into the local coordinate system.
P1 = mul(P1, transpose(preLightData.orthoBasisViewNormal));
P2 = mul(P2, transpose(preLightData.orthoBasisViewNormal));
// Compute the binormal in the local coordinate system.
float3 B = normalize(cross(P1, P2));
float ltcValue;
// Evaluate the diffuse part
ltcValue = LTCEvaluate(P1, P2, B, preLightData.ltcTransformDiffuse);
utsLightData.diffuseDimmer *= ltcValue;
// Evaluate the specular part
ltcValue = LTCEvaluate(P1, P2, B, preLightData.ltcTransformSpecular);
utsLightData.specularDimmer *= ltcValue;
#if defined(UTS_DEBUG_SELFSHADOW)
#else
UTS_OtherLights(context, input, utsLightData, surfaceData, bsdfData, s_lightData.lightType, i_normalDir, notDirectional, channelAlpha, utsAggregateLighting);
#endif
}
}
*/
}
s_lightData = FetchLight(lightStart, min(++i, last));