|
|
|
|
|
|
// Transmittance(x, z) = Transmittance(x, y) * Transmittance(y, z) |
|
|
|
// Integral{a, b}{Transmittance(0, t) * Li(t) dt} = Transmittance(0, a) * Integral{a, b}{Transmittance(0, t - a) * Li(t) dt}. |
|
|
|
|
|
|
|
float OpticalDepthHomogeneousMedia(float extinction, float intervalLength) |
|
|
|
float OpticalDepthHomogeneousMedium(float extinction, float intervalLength) |
|
|
|
float3 OpticalDepthHomogeneousMedia(float3 extinction, float intervalLength) |
|
|
|
float3 OpticalDepthHomogeneousMedium(float3 extinction, float intervalLength) |
|
|
|
{ |
|
|
|
return extinction * intervalLength; |
|
|
|
} |
|
|
|
|
|
|
return exp(-opticalDepth); |
|
|
|
} |
|
|
|
|
|
|
|
float TransmittanceHomogeneousMedia(float extinction, float intervalLength) |
|
|
|
float TransmittanceHomogeneousMedium(float extinction, float intervalLength) |
|
|
|
return Transmittance(OpticalDepthHomogeneousMedia(extinction, intervalLength)); |
|
|
|
return Transmittance(OpticalDepthHomogeneousMedium(extinction, intervalLength)); |
|
|
|
float3 TransmittanceHomogeneousMedia(float3 extinction, float intervalLength) |
|
|
|
float3 TransmittanceHomogeneousMedium(float3 extinction, float intervalLength) |
|
|
|
return Transmittance(OpticalDepthHomogeneousMedia(extinction, intervalLength)); |
|
|
|
return Transmittance(OpticalDepthHomogeneousMedium(extinction, intervalLength)); |
|
|
|
float TransmittanceIntegralHomogeneousMedia(float extinction, float intervalLength) |
|
|
|
float TransmittanceIntegralHomogeneousMedium(float extinction, float intervalLength) |
|
|
|
float3 TransmittanceIntegralHomogeneousMedia(float3 extinction, float intervalLength) |
|
|
|
float3 TransmittanceIntegralHomogeneousMedium(float3 extinction, float intervalLength) |
|
|
|
{ |
|
|
|
return rcp(extinction) - rcp(extinction) * exp(-extinction * intervalLength); |
|
|
|
} |
|
|
|
|
|
|
HenyeyGreensteinPhasePartVarying(asymmetry, LdotD); |
|
|
|
} |
|
|
|
|
|
|
|
// Samples the interval of homogeneous participating media using the closed-form tracking approach |
|
|
|
// (proportionally to the transmittance times the extinction coefficient). |
|
|
|
// Returns the offset from the start of the interval and the weight = (extinction * transmittance / pdf). |
|
|
|
// Samples the interval of homogeneous participating medium using the closed-form tracking approach |
|
|
|
// (proportionally to the transmittance). |
|
|
|
// Returns the offset from the start of the interval and the weight = (transmittance / pdf). |
|
|
|
void ImportanceSampleHomogeneousMedia(float extinction, float intervalLength, float rndVal, |
|
|
|
void ImportanceSampleHomogeneousMedium(float rndVal, float extinction, float intervalLength, |
|
|
|
// weight = extinction * exp(-extinction * t) / pdf |
|
|
|
// weight = 1 - exp(-intervalLength * extinction) |
|
|
|
// weight = exp(-extinction * t) / pdf |
|
|
|
// weight = (1 - exp(-extinction * intervalLength)) / extinction; |
|
|
|
weight = 1 - exp(-extinction * intervalLength); |
|
|
|
offset = log(1 - rndVal * weight) / extinction; |
|
|
|
float x = 1 - exp(-extinction * intervalLength); |
|
|
|
|
|
|
|
weight = x * rcp(extinction); |
|
|
|
offset = -log(1 - rndVal * x) * rcp(extinction); |
|
|
|
// Ref: Importance Sampling of Area Lights in Participating Media. |
|
|
|
void ImportanceSamplePunctualLight(float3 lightPosition, float3 rayOrigin, float3 rayDirection, |
|
|
|
float tMin, float tMax, float rndVal, |
|
|
|
// Ref: Importance Sampling of Area Lights in Participating Medium. |
|
|
|
void ImportanceSamplePunctualLight(float rndVal, float3 lightPosition, |
|
|
|
float3 rayOrigin, float3 rayDirection, |
|
|
|
float tMin, float tMax, |
|
|
|
out float dist, out float rcpPdf) |
|
|
|
{ |
|
|
|
float3 originToLight = lightPosition - rayOrigin; |
|
|
|