@@ -751,19 +751,25 @@ void IntegrateGGXAreaRef( float3 V, float3 positionWS, PreLightData preLightDa
751751
752752 float4x4 localToWorld = float4x4 (float4 (lightData.right, 0.0 ), float4 (lightData.up, 0.0 ), float4 (lightData.forward, 0.0 ), float4 (lightData.positionWS, 1.0 ));
753753
754- if (lightData.lightType == GPULIGHTTYPE_SPHERE)
755- SampleSphere (u, localToWorld, lightData.size.x, lightPdf, P, Ns);
756- else if (lightData.lightType == GPULIGHTTYPE_HEMISPHERE)
757- SampleHemisphere (u, localToWorld, lightData.size.x, lightPdf, P, Ns);
758- else if (lightData.lightType == GPULIGHTTYPE_CYLINDER)
759- SampleCylinder (u, localToWorld, lightData.size.x, lightData.size.y, lightPdf, P, Ns);
760- else if (lightData.lightType == GPULIGHTTYPE_RECTANGLE)
761- SampleRectangle (u, localToWorld, lightData.size.x, lightData.size.y, lightPdf, P, Ns);
762- else if (lightData.lightType == GPULIGHTTYPE_DISK)
763- SampleDisk (u, localToWorld, lightData.size.x, lightPdf, P, Ns);
764- else if (lightData.lightType == GPULIGHTTYPE_LINE)
765- // SampleLine(u, localToWorld, areaLight.lightRadius0, lightPdf, P, Ns);
766- ; // TODO
754+ switch (lightData.lightType)
755+ {
756+ case GPULIGHTTYPE_SPHERE:
757+ SampleSphere (u, localToWorld, lightData.size.x, lightPdf, P, Ns);
758+ break ;
759+ case GPULIGHTTYPE_HEMISPHERE:
760+ SampleHemisphere (u, localToWorld, lightData.size.x, lightPdf, P, Ns);
761+ break ;
762+ case GPULIGHTTYPE_CYLINDER:
763+ SampleCylinder (u, localToWorld, lightData.size.x, lightData.size.y, lightPdf, P, Ns);
764+ break ;
765+ case GPULIGHTTYPE_RECTANGLE:
766+ SampleRectangle (u, localToWorld, lightData.size.x, lightData.size.y, lightPdf, P, Ns);
767+ break ;
768+ case GPULIGHTTYPE_DISK:
769+ SampleDisk (u, localToWorld, lightData.size.x, lightPdf, P, Ns);
770+ break ;
771+ // case GPULIGHTTYPE_LINE: handled by a separate function.
772+ }
767773
768774 // Get distance
769775 float3 unL = P - positionWS;
@@ -795,6 +801,53 @@ void IntegrateGGXAreaRef( float3 V, float3 positionWS, PreLightData preLightDa
795801 specularLighting /= float (sampleCount);
796802}
797803
804+ //-----------------------------------------------------------------------------
805+ // EvaluateBSDFLine - Reference
806+ //-----------------------------------------------------------------------------
807+
808+ void IntegrateBSDFLineRef (float3 V, float3 positionWS, PreLightData preLightData,
809+ LightData lightData, BSDFData bsdfData,
810+ out float3 diffuseLighting, out float3 specularLighting,
811+ int sampleCount = 128 )
812+ {
813+ diffuseLighting = float3 (0.0 , 0.0 , 0.0 );
814+ specularLighting = float3 (0.0 , 0.0 , 0.0 );
815+
816+ const float len = lightData.size.x;
817+ const float3 p0 = lightData.positionWS - lightData.right * (0.5 * len);
818+ const float3 dir = lightData.right;
819+ const float dt = len * rcp (sampleCount);
820+ const float off = 0.5 * dt;
821+
822+ // Uniformly sample the line segment with the Pdf = 1 / len.
823+ const float invPdf = len;
824+
825+ for (int i = 0 ; i < sampleCount; ++i)
826+ {
827+ // Place the sample in the middle of the interval.
828+ float t = off + i * dt;
829+ float3 sPos = p0 + t * dir;
830+ float3 unL = sPos - positionWS;
831+ float dist2 = dot (unL, unL);
832+ float3 L = normalize (unL);
833+ float sinLD = length (cross (L, dir));
834+ float NdotL = saturate (dot (bsdfData.normalWS, L));
835+
836+ float3 lightDiff, lightSpec;
837+
838+ BSDF (V, L, positionWS, preLightData, bsdfData, lightDiff, lightSpec);
839+
840+ diffuseLighting += lightDiff * (sinLD / dist2 * NdotL);
841+ specularLighting += lightSpec * (sinLD / dist2 * NdotL);
842+ }
843+
844+ // The factor of 2 is due to the fact: Integral{0, 2 PI}{max(0, cos(x))dx} = 2.
845+ float normFactor = 2.0 * invPdf * rcp (sampleCount);
846+
847+ diffuseLighting *= normFactor * lightData.diffuseScale * lightData.color;
848+ specularLighting *= normFactor * lightData.specularScale * lightData.color;
849+ }
850+
798851//-----------------------------------------------------------------------------
799852// EvaluateBSDF_Area
800853//-----------------------------------------------------------------------------
@@ -805,7 +858,14 @@ void EvaluateBSDF_Area( LightLoopContext lightLoopContext,
805858 out float3 specularLighting)
806859{
807860#ifdef LIT_DISPLAY_REFERENCE_AREA
808- IntegrateGGXAreaRef (V, positionWS, preLightData, lightData, bsdfData, diffuseLighting, specularLighting);
861+ if (lightData.lightType == GPULIGHTTYPE_LINE)
862+ {
863+ IntegrateBSDFLineRef (V, positionWS, preLightData, lightData, bsdfData, diffuseLighting, specularLighting);
864+ }
865+ else
866+ {
867+ IntegrateGGXAreaRef (V, positionWS, preLightData, lightData, bsdfData, diffuseLighting, specularLighting);
868+ }
809869#else
810870 // TODO: This could be precomputed
811871 float halfWidth = lightData.size.x * 0.5 ;
0 commit comments