|
@@ -8,11 +8,11 @@
|
|
|
|
|
|
#pragma once
|
|
#pragma once
|
|
|
|
|
|
-#include <Atom/Features/PBR/Lights/LightTypesCommon.azsli>
|
|
|
|
-#include <Atom/Features/PBR/Lights/Ltc.azsli>
|
|
|
|
-
|
|
|
|
#if ENABLE_QUAD_LIGHTS
|
|
#if ENABLE_QUAD_LIGHTS
|
|
|
|
|
|
|
|
+#include <Atom/Features/PBR/Lights/Ltc.azsli>
|
|
|
|
+#include <Atom/Features/PBR/Lights/LightTypesCommon.azsli>
|
|
|
|
+
|
|
// Returns the solid angle at origin of a rectangle defined by points p0-p3. Does not handle horizon.
|
|
// Returns the solid angle at origin of a rectangle defined by points p0-p3. Does not handle horizon.
|
|
// Modified from https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf Listing 11 on page 49.
|
|
// Modified from https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf Listing 11 on page 49.
|
|
float RectangleSolidAngle(float3 v0, float3 v1, float3 v2, float3 v3)
|
|
float RectangleSolidAngle(float3 v0, float3 v1, float3 v2, float3 v3)
|
|
@@ -32,12 +32,12 @@ float RectangleSolidAngle(float3 v0, float3 v1, float3 v2, float3 v3)
|
|
|
|
|
|
// Unlike standard ray-plane intersection, this version is made for light planes to avoid discontinuities when the
|
|
// Unlike standard ray-plane intersection, this version is made for light planes to avoid discontinuities when the
|
|
// reflection vector is going away from a light plane.
|
|
// reflection vector is going away from a light plane.
|
|
-float3 RayLightPlaneIntersection(in float3 pos, in float3 rayDirection, in float3 lightOrigin, in float3 lightDirection)
|
|
|
|
|
|
+float3 RayLightPlaneIntersection(in float3 pos, in float3 rayDirection, in float3 lightOrigin, in float3 m_lightDirection)
|
|
{
|
|
{
|
|
float3 lightToPos = pos - lightOrigin;
|
|
float3 lightToPos = pos - lightOrigin;
|
|
- float reflectionDotLight = dot(rayDirection, -lightDirection);
|
|
|
|
|
|
+ float reflectionDotLight = dot(rayDirection, -m_lightDirection);
|
|
|
|
|
|
- float distanceToPlane = dot(lightToPos, lightDirection);
|
|
|
|
|
|
+ float distanceToPlane = dot(lightToPos, m_lightDirection);
|
|
if (reflectionDotLight >= 0.0001)
|
|
if (reflectionDotLight >= 0.0001)
|
|
{
|
|
{
|
|
// Reflection going towards the light
|
|
// Reflection going towards the light
|
|
@@ -50,7 +50,7 @@ float3 RayLightPlaneIntersection(in float3 pos, in float3 rayDirection, in float
|
|
float3 posToFarOffPoint = rayDirection * distanceToPlane * 10000.0;
|
|
float3 posToFarOffPoint = rayDirection * distanceToPlane * 10000.0;
|
|
float3 lightToFarOffPoint = lightToPos + posToFarOffPoint;
|
|
float3 lightToFarOffPoint = lightToPos + posToFarOffPoint;
|
|
// Here "intersection" refers to the projection of the far off point onto the light plane.
|
|
// Here "intersection" refers to the projection of the far off point onto the light plane.
|
|
- float3 intersectionToFarOffPoint = dot(lightToFarOffPoint, lightDirection) * lightDirection;
|
|
|
|
|
|
+ float3 intersectionToFarOffPoint = dot(lightToFarOffPoint, m_lightDirection) * m_lightDirection;
|
|
return pos + posToFarOffPoint - intersectionToFarOffPoint;
|
|
return pos + posToFarOffPoint - intersectionToFarOffPoint;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -69,38 +69,65 @@ float3 GetSpecularDominantDirection(float3 normal, float3 reflection, float roug
|
|
return normalize(lerp(normal, reflection, lerpFactor));
|
|
return normalize(lerp(normal, reflection, lerpFactor));
|
|
}
|
|
}
|
|
|
|
|
|
-// Quad light approximation. Diffuse portion based on https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf Pages 49-50.
|
|
|
|
-void ApplyQuadLight(QuadLight light, Surface surface, inout LightingData lightingData)
|
|
|
|
|
|
+
|
|
|
|
+#ifndef QuadLightUtil
|
|
|
|
+#define QuadLightUtil QuadLightUtil_PBR
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+class QuadLightUtil_PBR
|
|
{
|
|
{
|
|
- float3 lightDirection = cross(light.m_leftDir, light.m_upDir); // left and up are already normalized.
|
|
|
|
|
|
|
|
- float3 posToLight = light.m_position - surface.position;
|
|
|
|
- float posToLightDotLightDirection = dot(posToLight, -lightDirection);
|
|
|
|
|
|
+ real3 m_lightDirection;
|
|
|
|
+ real3 m_posToLight;
|
|
|
|
+ real m_posToLightDotLightDirection;
|
|
|
|
+ real m_distanceToLight2;
|
|
|
|
+ real m_falloff;
|
|
|
|
+ bool m_doubleSided;
|
|
|
|
+
|
|
|
|
+ static QuadLightUtil_PBR Init(QuadLight light, Surface surface)
|
|
|
|
+ {
|
|
|
|
+ QuadLightUtil_PBR result;
|
|
|
|
+
|
|
|
|
+ result.m_lightDirection = cross(light.m_leftDir, light.m_upDir); // left and up are already normalized.
|
|
|
|
|
|
- float distanceToLight2 = dot(posToLight, posToLight); // light distance squared
|
|
|
|
- float falloff = distanceToLight2 * light.m_invAttenuationRadiusSquared;
|
|
|
|
|
|
+ result.m_posToLight = light.m_position - surface.position;
|
|
|
|
+ result.m_posToLightDotLightDirection = dot(result.m_posToLight, -result.m_lightDirection);
|
|
|
|
+
|
|
|
|
+ result.m_distanceToLight2 = dot(result.m_posToLight, result.m_posToLight); // light distance squared
|
|
|
|
+ result.m_falloff = result.m_distanceToLight2 * light.m_invAttenuationRadiusSquared;
|
|
|
|
+
|
|
|
|
+ result.m_doubleSided = (light.m_flags & EmitsBothDirections) > 0;
|
|
|
|
+ if (result.m_doubleSided)
|
|
|
|
+ {
|
|
|
|
+ result.m_lightDirection *= sign(result.m_posToLightDotLightDirection);
|
|
|
|
+ result.m_posToLightDotLightDirection = abs(result.m_posToLightDotLightDirection);
|
|
|
|
+ }
|
|
|
|
+ if (result.m_posToLightDotLightDirection <= 0.0f)
|
|
|
|
+ {
|
|
|
|
+ result.m_falloff = 1.0f;
|
|
|
|
+ }
|
|
|
|
+ return result;
|
|
|
|
+ }
|
|
|
|
|
|
- bool doubleSided = (light.m_flags & EmitsBothDirections) > 0;
|
|
|
|
- if (doubleSided)
|
|
|
|
|
|
+ real GetFalloff()
|
|
{
|
|
{
|
|
- lightDirection *= sign(posToLightDotLightDirection);
|
|
|
|
- posToLightDotLightDirection = abs(posToLightDotLightDirection);
|
|
|
|
|
|
+ return m_falloff;
|
|
}
|
|
}
|
|
|
|
|
|
- if(falloff < 1.0f && posToLightDotLightDirection > 0.0)
|
|
|
|
|
|
+ void Apply(QuadLight light, Surface surface, real litRatio, inout LightingData lightingData)
|
|
{
|
|
{
|
|
- // Smoothly adjusts the light intensity so it reaches 0 at light.m_attenuationRadius distance
|
|
|
|
- float radiusAttenuation = 1.0 - (falloff * falloff);
|
|
|
|
|
|
+ // Smoothly adjusts the light intensity so it reaches 0 at light.m_attenuationRadius distance
|
|
|
|
+ float radiusAttenuation = 1.0 - (m_falloff * m_falloff);
|
|
radiusAttenuation = radiusAttenuation * radiusAttenuation;
|
|
radiusAttenuation = radiusAttenuation * radiusAttenuation;
|
|
|
|
|
|
float3 left = light.m_leftDir * light.m_halfWidth;
|
|
float3 left = light.m_leftDir * light.m_halfWidth;
|
|
float3 up = light.m_upDir * light.m_halfHeight;
|
|
float3 up = light.m_upDir * light.m_halfHeight;
|
|
|
|
|
|
// Calculation positions for 4 corners relative to the surface
|
|
// Calculation positions for 4 corners relative to the surface
|
|
- float3 p0 = posToLight + -left + up;
|
|
|
|
- float3 p1 = posToLight + -left + -up;
|
|
|
|
- float3 p2 = posToLight + left + -up;
|
|
|
|
- float3 p3 = posToLight + left + up;
|
|
|
|
|
|
+ float3 p0 = m_posToLight + -left + up;
|
|
|
|
+ float3 p1 = m_posToLight + -left + -up;
|
|
|
|
+ float3 p2 = m_posToLight + left + -up;
|
|
|
|
+ float3 p3 = m_posToLight + left + up;
|
|
|
|
|
|
bool useFastApproximation = (light.m_flags & UseFastApproximation) > 0;
|
|
bool useFastApproximation = (light.m_flags & UseFastApproximation) > 0;
|
|
if (!useFastApproximation && o_enableQuadLightLTC)
|
|
if (!useFastApproximation && o_enableQuadLightLTC)
|
|
@@ -117,7 +144,7 @@ void ApplyQuadLight(QuadLight light, Surface surface, inout LightingData lightin
|
|
float viewDiffuse = 0.0;
|
|
float viewDiffuse = 0.0;
|
|
float3 viewSpecular = float3(0.0, 0.0, 0.0);
|
|
float3 viewSpecular = float3(0.0, 0.0, 0.0);
|
|
|
|
|
|
- LtcQuadEvaluate(surface, lightingData, SceneSrg::m_ltcMatrix, SceneSrg::m_ltcAmplification, p, doubleSided, viewIndex, viewDiffuse, viewSpecular);
|
|
|
|
|
|
+ LtcQuadEvaluate(surface, lightingData, SceneSrg::m_ltcMatrix, SceneSrg::m_ltcAmplification, p, m_doubleSided, viewIndex, viewDiffuse, viewSpecular);
|
|
|
|
|
|
// Scale by inverse surface area of hemisphere (1/2pi), attenuation, and light intensity
|
|
// Scale by inverse surface area of hemisphere (1/2pi), attenuation, and light intensity
|
|
float3 intensity = 0.5 * INV_PI * radiusAttenuation * light.m_rgbIntensityNits;
|
|
float3 intensity = 0.5 * INV_PI * radiusAttenuation * light.m_rgbIntensityNits;
|
|
@@ -125,10 +152,10 @@ void ApplyQuadLight(QuadLight light, Surface surface, inout LightingData lightin
|
|
// Only add diffuse lighting once (for the first view)
|
|
// Only add diffuse lighting once (for the first view)
|
|
if (viewIndex == 0)
|
|
if (viewIndex == 0)
|
|
{
|
|
{
|
|
- lightingData.diffuseLighting += surface.albedo * viewDiffuse * intensity;
|
|
|
|
|
|
+ lightingData.diffuseLighting += surface.albedo * viewDiffuse * intensity * litRatio;
|
|
}
|
|
}
|
|
|
|
|
|
- lightingData.specularLighting[viewIndex] += viewSpecular * intensity;
|
|
|
|
|
|
+ lightingData.specularLighting[viewIndex] += viewSpecular * intensity * litRatio;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (useFastApproximation && o_enableQuadLightApprox)
|
|
else if (useFastApproximation && o_enableQuadLightApprox)
|
|
@@ -142,7 +169,7 @@ void ApplyQuadLight(QuadLight light, Surface surface, inout LightingData lightin
|
|
p2 = normalize(p2);
|
|
p2 = normalize(p2);
|
|
p3 = normalize(p3);
|
|
p3 = normalize(p3);
|
|
|
|
|
|
- float3 dirToLightCenter = normalize(posToLight);
|
|
|
|
|
|
+ float3 dirToLightCenter = normalize(m_posToLight);
|
|
|
|
|
|
// Intensity is the solid angle times the brightness of the light surface.
|
|
// Intensity is the solid angle times the brightness of the light surface.
|
|
// Each position contributes 1/5 of the light (4 corners + center)
|
|
// Each position contributes 1/5 of the light (4 corners + center)
|
|
@@ -155,8 +182,9 @@ void ApplyQuadLight(QuadLight light, Surface surface, inout LightingData lightin
|
|
GetDiffuseLighting(surface, lightingData, intensity, p2) +
|
|
GetDiffuseLighting(surface, lightingData, intensity, p2) +
|
|
GetDiffuseLighting(surface, lightingData, intensity, p3) +
|
|
GetDiffuseLighting(surface, lightingData, intensity, p3) +
|
|
GetDiffuseLighting(surface, lightingData, intensity, dirToLightCenter)
|
|
GetDiffuseLighting(surface, lightingData, intensity, dirToLightCenter)
|
|
- );
|
|
|
|
-
|
|
|
|
|
|
+ ) * litRatio;
|
|
|
|
+
|
|
|
|
+#if ENABLE_TRANSMISSION
|
|
// Transmission contribution
|
|
// Transmission contribution
|
|
// We cannot compute the actual transmission distance so we want to:
|
|
// We cannot compute the actual transmission distance so we want to:
|
|
// - If transmission mode is thick object -> use transmission thickness parameter instead
|
|
// - If transmission mode is thick object -> use transmission thickness parameter instead
|
|
@@ -166,7 +194,6 @@ void ApplyQuadLight(QuadLight light, Surface surface, inout LightingData lightin
|
|
// If the transmissionDistance is ignored then the attenuation distance (only used on thin objects) does not have any influence
|
|
// If the transmissionDistance is ignored then the attenuation distance (only used on thin objects) does not have any influence
|
|
const float attenuationDistance = 0.0f;
|
|
const float attenuationDistance = 0.0f;
|
|
|
|
|
|
-#if ENABLE_TRANSMISSION
|
|
|
|
lightingData.translucentBackLighting +=
|
|
lightingData.translucentBackLighting +=
|
|
(
|
|
(
|
|
GetBackLighting(surface, lightingData, intensity, p0, transmissionDistance, attenuationDistance) +
|
|
GetBackLighting(surface, lightingData, intensity, p0, transmissionDistance, attenuationDistance) +
|
|
@@ -174,7 +201,7 @@ void ApplyQuadLight(QuadLight light, Surface surface, inout LightingData lightin
|
|
GetBackLighting(surface, lightingData, intensity, p2, transmissionDistance, attenuationDistance) +
|
|
GetBackLighting(surface, lightingData, intensity, p2, transmissionDistance, attenuationDistance) +
|
|
GetBackLighting(surface, lightingData, intensity, p3, transmissionDistance, attenuationDistance) +
|
|
GetBackLighting(surface, lightingData, intensity, p3, transmissionDistance, attenuationDistance) +
|
|
GetBackLighting(surface, lightingData, intensity, dirToLightCenter, transmissionDistance, attenuationDistance)
|
|
GetBackLighting(surface, lightingData, intensity, dirToLightCenter, transmissionDistance, attenuationDistance)
|
|
- );
|
|
|
|
|
|
+ ) * litRatio;
|
|
#endif
|
|
#endif
|
|
|
|
|
|
// Calculate specular lighting for each view
|
|
// Calculate specular lighting for each view
|
|
@@ -186,7 +213,7 @@ void ApplyQuadLight(QuadLight light, Surface surface, inout LightingData lightin
|
|
|
|
|
|
// First find the reflection-plane intersection, then find the closest point on the rectangle to that intersection.
|
|
// First find the reflection-plane intersection, then find the closest point on the rectangle to that intersection.
|
|
float2 halfSize = float2(light.m_halfWidth, light.m_halfHeight);
|
|
float2 halfSize = float2(light.m_halfWidth, light.m_halfHeight);
|
|
- float3 positionOnPlane = RayLightPlaneIntersection(surface.position, reflectionDir, light.m_position, lightDirection);
|
|
|
|
|
|
+ float3 positionOnPlane = RayLightPlaneIntersection(surface.position, reflectionDir, light.m_position, m_lightDirection);
|
|
float3 lightPositionWorld = ClosestPointRect(positionOnPlane, light.m_position, light.m_leftDir, light.m_upDir, halfSize);
|
|
float3 lightPositionWorld = ClosestPointRect(positionOnPlane, light.m_position, light.m_leftDir, light.m_upDir, halfSize);
|
|
float3 lightPositionLocal = lightPositionWorld - surface.position;
|
|
float3 lightPositionLocal = lightPositionWorld - surface.position;
|
|
|
|
|
|
@@ -194,7 +221,7 @@ void ApplyQuadLight(QuadLight light, Surface surface, inout LightingData lightin
|
|
// is at a grazing angle. This can cause the "closest" point to tend towards the corners of the rectangle. To correct this,
|
|
// is at a grazing angle. This can cause the "closest" point to tend towards the corners of the rectangle. To correct this,
|
|
// we find the closest point on the reflection line to this first attempt, and use it for a second attempt.
|
|
// we find the closest point on the reflection line to this first attempt, and use it for a second attempt.
|
|
float3 localPositionOnLine = reflectionDir * dot(reflectionDir, lightPositionLocal);
|
|
float3 localPositionOnLine = reflectionDir * dot(reflectionDir, lightPositionLocal);
|
|
- lightPositionLocal = ClosestPointRect(localPositionOnLine, posToLight, light.m_leftDir, light.m_upDir, halfSize);
|
|
|
|
|
|
+ lightPositionLocal = ClosestPointRect(localPositionOnLine, m_posToLight, light.m_leftDir, light.m_upDir, halfSize);
|
|
|
|
|
|
float3 dirToLight = normalize(lightPositionLocal);
|
|
float3 dirToLight = normalize(lightPositionLocal);
|
|
float lightPositionDist2 = dot(lightPositionLocal, lightPositionLocal);
|
|
float lightPositionDist2 = dot(lightPositionLocal, lightPositionLocal);
|
|
@@ -203,110 +230,49 @@ void ApplyQuadLight(QuadLight light, Surface surface, inout LightingData lightin
|
|
float quadIntensityNormalization = GetIntensityAdjustedByRadiusAndRoughness(surface.roughnessA, 0.0, lightPositionDist2);
|
|
float quadIntensityNormalization = GetIntensityAdjustedByRadiusAndRoughness(surface.roughnessA, 0.0, lightPositionDist2);
|
|
|
|
|
|
// Specular contribution
|
|
// Specular contribution
|
|
- lightingData.specularLighting[viewIndex] += quadIntensityNormalization * GetSpecularLighting(surface, lightingData, intensity, dirToLight, viewIndex);
|
|
|
|
|
|
+ lightingData.specularLighting[viewIndex] += quadIntensityNormalization * GetSpecularLighting(surface, lightingData, intensity, dirToLight, viewIndex) * litRatio;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-}
|
|
|
|
-
|
|
|
|
-float3 SampleRectangle(float2 randomPoint, QuadLight light)
|
|
|
|
-{
|
|
|
|
- randomPoint = randomPoint * 2.0 - 1.0; // transform to -1 to 1 range.
|
|
|
|
- randomPoint *= float2(light.m_halfWidth, light.m_halfHeight);
|
|
|
|
- // Random point on light surface
|
|
|
|
- float3 outPoint = light.m_position + light.m_leftDir * randomPoint.x + light.m_upDir * randomPoint.y;
|
|
|
|
-
|
|
|
|
- return outPoint;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-void ValidateQuadLight(QuadLight light, Surface surface, inout LightingData lightingData)
|
|
|
|
-{
|
|
|
|
- float3 lightDirection = cross(light.m_leftDir, light.m_upDir); // left and up are already normalized.
|
|
|
|
-
|
|
|
|
- const uint sampleCount = 512;
|
|
|
|
|
|
|
|
- real3 diffuseAcc = float3(0.0, 0.0, 0.0);
|
|
|
|
- real3 translucentAcc = float3(0.0, 0.0, 0.0);
|
|
|
|
- real3 specularAcc[MAX_SHADING_VIEWS];
|
|
|
|
-
|
|
|
|
- [unroll]
|
|
|
|
- for(uint viewIndex = 0; viewIndex < GET_SHADING_VIEW_COUNT; ++viewIndex)
|
|
|
|
|
|
+ void ApplySampled(QuadLight light, Surface surface, inout LightingData lightingData, const uint sampleCount = 512)
|
|
{
|
|
{
|
|
- specularAcc[viewIndex] = float3(0.0, 0.0, 0.0);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- bool emitsBothDirections = (light.m_flags & EmitsBothDirections) > 0;
|
|
|
|
- float bothDirectionsFactor = emitsBothDirections ? -1.0 : 0.0;
|
|
|
|
|
|
+ real3 diffuseAcc = float3(0.0, 0.0, 0.0);
|
|
|
|
+ real3 translucentAcc = float3(0.0, 0.0, 0.0);
|
|
|
|
+ real3 specularAcc[MAX_SHADING_VIEWS];
|
|
|
|
|
|
- for (uint i = 0; i < sampleCount; ++i)
|
|
|
|
- {
|
|
|
|
- float2 randomPoint = GetHammersleyPoint(i, sampleCount);
|
|
|
|
- float3 samplePoint = SampleRectangle(randomPoint, light);
|
|
|
|
- AddSampleContribution(surface, lightingData, samplePoint, lightDirection, bothDirectionsFactor, diffuseAcc, specularAcc, translucentAcc);
|
|
|
|
- }
|
|
|
|
|
|
+ [unroll]
|
|
|
|
+ for(uint viewIndex = 0; viewIndex < GET_SHADING_VIEW_COUNT; ++viewIndex)
|
|
|
|
+ {
|
|
|
|
+ specularAcc[viewIndex] = float3(0.0, 0.0, 0.0);
|
|
|
|
+ }
|
|
|
|
|
|
- float area = light.m_halfWidth * light.m_halfHeight * 4.0;
|
|
|
|
- float3 intensityCandelas = light.m_rgbIntensityNits * area;
|
|
|
|
|
|
+ float bothDirectionsFactor = m_doubleSided ? -1.0 : 0.0;
|
|
|
|
|
|
- lightingData.diffuseLighting += (diffuseAcc / float(sampleCount)) * intensityCandelas;
|
|
|
|
|
|
+ for (uint i = 0; i < sampleCount; ++i)
|
|
|
|
+ {
|
|
|
|
+ float2 randomPoint = GetHammersleyPoint(i, sampleCount);
|
|
|
|
+ float3 samplePoint = SampleRectangle(randomPoint, light);
|
|
|
|
+ AddSampleContribution(surface, lightingData, samplePoint, m_lightDirection, bothDirectionsFactor, diffuseAcc, specularAcc, translucentAcc);
|
|
|
|
+ }
|
|
|
|
|
|
- [unroll]
|
|
|
|
- for(uint viewIndex = 0; viewIndex < GET_SHADING_VIEW_COUNT; ++viewIndex)
|
|
|
|
- {
|
|
|
|
- lightingData.specularLighting[viewIndex] += (specularAcc[viewIndex] / float(sampleCount)) * intensityCandelas;
|
|
|
|
- }
|
|
|
|
|
|
+ float area = light.m_halfWidth * light.m_halfHeight * 4.0;
|
|
|
|
+ float3 intensityCandelas = light.m_rgbIntensityNits * area;
|
|
|
|
|
|
-#if ENABLE_TRANSMISSION
|
|
|
|
- lightingData.translucentBackLighting += (translucentAcc / float(sampleCount)) * intensityCandelas;
|
|
|
|
-#endif
|
|
|
|
-}
|
|
|
|
|
|
+ lightingData.diffuseLighting += (diffuseAcc / float(sampleCount)) * intensityCandelas;
|
|
|
|
|
|
-void ApplyQuadLightInternal(uint lightIndex, Surface surface, inout LightingData lightingData)
|
|
|
|
-{
|
|
|
|
- if (o_enableQuadLightApprox || o_enableQuadLightLTC)
|
|
|
|
- {
|
|
|
|
- QuadLight light = ViewSrg::m_quadLights[lightIndex];
|
|
|
|
- if(!IsSameLightChannel(lightingData.lightingChannels, light.m_lightingChannelMask))
|
|
|
|
- {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-#if ENABLE_AREA_LIGHT_VALIDATION
|
|
|
|
- if (o_area_light_validation)
|
|
|
|
|
|
+ [unroll]
|
|
|
|
+ for(uint viewIndex = 0; viewIndex < GET_SHADING_VIEW_COUNT; ++viewIndex)
|
|
{
|
|
{
|
|
- ValidateQuadLight(light, surface, lightingData);
|
|
|
|
|
|
+ lightingData.specularLighting[viewIndex] += (specularAcc[viewIndex] / float(sampleCount)) * intensityCandelas;
|
|
}
|
|
}
|
|
- else
|
|
|
|
-#endif //ENABLE_AREA_LIGHT_VALIDATION
|
|
|
|
- {
|
|
|
|
- ApplyQuadLight(light, surface, lightingData);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-void ApplyQuadLights(Surface surface, inout LightingData lightingData)
|
|
|
|
-{
|
|
|
|
-#if ENABLE_LIGHT_CULLING
|
|
|
|
- lightingData.tileIterator.LoadAdvance();
|
|
|
|
-
|
|
|
|
- while( !lightingData.tileIterator.IsDone() )
|
|
|
|
- {
|
|
|
|
- uint currLightIndex = lightingData.tileIterator.GetValue();
|
|
|
|
- lightingData.tileIterator.LoadAdvance();
|
|
|
|
|
|
|
|
- ApplyQuadLightInternal(currLightIndex, surface, lightingData);
|
|
|
|
|
|
+ #if ENABLE_TRANSMISSION
|
|
|
|
+ lightingData.translucentBackLighting += (translucentAcc / float(sampleCount)) * intensityCandelas;
|
|
|
|
+ #endif
|
|
}
|
|
}
|
|
-#else
|
|
|
|
- for(uint lightIndex = 0; lightIndex < ViewSrg::m_quadLightCount; lightIndex++)
|
|
|
|
- {
|
|
|
|
- ApplyQuadLightInternal(lightIndex, surface, lightingData);
|
|
|
|
- }
|
|
|
|
-#endif
|
|
|
|
-}
|
|
|
|
|
|
|
|
-#else
|
|
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+#endif // ENABLE_QUAD_LIGHTS
|
|
|
|
|
|
-void ApplyQuadLights(Surface surface, inout LightingData lightingData)
|
|
|
|
-{
|
|
|
|
- //Not Enabled
|
|
|
|
-}
|
|
|
|
-#endif
|
|
|