|
|
|
|
|
|
|
|
|
|
float4x4 localToWorld = float4x4(float4(lightData.right, 0.0), float4(lightData.up, 0.0), float4(lightData.forward, 0.0), float4(lightData.positionWS, 1.0)); |
|
|
|
|
|
|
|
if (lightData.lightType == GPULIGHTTYPE_SPHERE) |
|
|
|
SampleSphere(u, localToWorld, lightData.size.x, lightPdf, P, Ns); |
|
|
|
else if (lightData.lightType == GPULIGHTTYPE_HEMISPHERE) |
|
|
|
SampleHemisphere(u, localToWorld, lightData.size.x, lightPdf, P, Ns); |
|
|
|
else if (lightData.lightType == GPULIGHTTYPE_CYLINDER) |
|
|
|
SampleCylinder(u, localToWorld, lightData.size.x, lightData.size.y, lightPdf, P, Ns); |
|
|
|
else if (lightData.lightType == GPULIGHTTYPE_RECTANGLE) |
|
|
|
SampleRectangle(u, localToWorld, lightData.size.x, lightData.size.y, lightPdf, P, Ns); |
|
|
|
else if (lightData.lightType == GPULIGHTTYPE_DISK) |
|
|
|
SampleDisk(u, localToWorld, lightData.size.x, lightPdf, P, Ns); |
|
|
|
else if (lightData.lightType == GPULIGHTTYPE_LINE) |
|
|
|
// SampleLine(u, localToWorld, areaLight.lightRadius0, lightPdf, P, Ns); |
|
|
|
; // TODO |
|
|
|
switch (lightData.lightType) |
|
|
|
{ |
|
|
|
case GPULIGHTTYPE_SPHERE: |
|
|
|
SampleSphere(u, localToWorld, lightData.size.x, lightPdf, P, Ns); |
|
|
|
break; |
|
|
|
case GPULIGHTTYPE_HEMISPHERE: |
|
|
|
SampleHemisphere(u, localToWorld, lightData.size.x, lightPdf, P, Ns); |
|
|
|
break; |
|
|
|
case GPULIGHTTYPE_CYLINDER: |
|
|
|
SampleCylinder(u, localToWorld, lightData.size.x, lightData.size.y, lightPdf, P, Ns); |
|
|
|
break; |
|
|
|
case GPULIGHTTYPE_RECTANGLE: |
|
|
|
SampleRectangle(u, localToWorld, lightData.size.x, lightData.size.y, lightPdf, P, Ns); |
|
|
|
break; |
|
|
|
case GPULIGHTTYPE_DISK: |
|
|
|
SampleDisk(u, localToWorld, lightData.size.x, lightPdf, P, Ns); |
|
|
|
break; |
|
|
|
// case GPULIGHTTYPE_LINE: handled by a separate function. |
|
|
|
} |
|
|
|
|
|
|
|
// Get distance |
|
|
|
float3 unL = P - positionWS; |
|
|
|
|
|
|
specularLighting = fresnelTerm * lightData.color * ltcValue; |
|
|
|
} |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
|
|
// EvaluateBSDFLine - Reference |
|
|
|
//----------------------------------------------------------------------------- |
|
|
|
|
|
|
|
void IntegrateBSDFLineRef(float3 V, float3 positionWS, PreLightData preLightData, |
|
|
|
LightData lightData, BSDFData bsdfData, |
|
|
|
out float3 diffuseLighting, out float3 specularLighting, |
|
|
|
int sampleCount = 64) |
|
|
|
{ |
|
|
|
diffuseLighting = float3(0.0, 0.0, 0.0); |
|
|
|
specularLighting = float3(0.0, 0.0, 0.0); |
|
|
|
|
|
|
|
const float len = lightData.size.x; |
|
|
|
const float3 p0 = lightData.positionWS - lightData.right * (0.5 * len); |
|
|
|
const float3 dir = lightData.right; |
|
|
|
const float dt = len * rcp(sampleCount); |
|
|
|
const float off = 0.5 * dt; |
|
|
|
|
|
|
|
// Uniformly sample the line segment with the Pdf = 1 / len. |
|
|
|
const float invPdf = len; |
|
|
|
|
|
|
|
for (int i = 0; i < sampleCount; ++i) |
|
|
|
{ |
|
|
|
// Place the sample in the middle of the interval. |
|
|
|
float t = off + i * dt; |
|
|
|
float3 sPos = p0 + t * dir; |
|
|
|
float3 unL = sPos - positionWS; |
|
|
|
float dist2 = dot(unL, unL); |
|
|
|
float3 L = normalize(L); |
|
|
|
float sinLD = length(cross(L, dir)); |
|
|
|
float NdotL = saturate(dot(bsdfData.normalWS, L)); |
|
|
|
|
|
|
|
float3 lightDiff, lightSpec; |
|
|
|
|
|
|
|
BSDF(V, L, positionWS, preLightData, bsdfData, lightDiff, lightSpec); |
|
|
|
|
|
|
|
diffuseLighting += lightDiff * (sinLD / dist2 * NdotL); |
|
|
|
specularLighting += lightSpec * (sinLD / dist2 * NdotL); |
|
|
|
} |
|
|
|
|
|
|
|
// The factor of 2 is due to the fact: Integral{0, 2 PI}{max(0, cos(x))dx} = 2. |
|
|
|
float normFactor = 2.0 * invPdf * rcp(sampleCount); |
|
|
|
|
|
|
|
diffuseLighting *= normFactor * lightData.diffuseScale * lightData.color; |
|
|
|
specularLighting *= normFactor * lightData.specularScale * lightData.color; |
|
|
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
|
|