Added UTSPolygonFormFactor and UTSComputeEdgeFactor
This commit is contained in:
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user