You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
42 lines
1.6 KiB
42 lines
1.6 KiB
float dist2(float3 vecA, float3 vecB)
|
|
{
|
|
float3 res = vecA - vecB;
|
|
return dot(res, res);
|
|
}
|
|
|
|
float dist(float3 vecA, float3 vecB)
|
|
{
|
|
float3 res = vecA - vecB;
|
|
return length(res);
|
|
}
|
|
|
|
void SampleSphericalSphere(float3 spherePosition, float sphereRadius, float u, float v, float3 position, out float3 outPosition, out float outPDF)
|
|
{
|
|
// Compute coordinate system for sphere sampling.
|
|
float3 wc = normalize(spherePosition - position);
|
|
float3x3 localToWorld = GetLocalFrame(wc);
|
|
|
|
// Sample sphere uniformly inside subtended cone.
|
|
float sphereRadius2 = sphereRadius * sphereRadius;
|
|
float sinThetaMax2 = sphereRadius2 / dist2(position, spherePosition);
|
|
float cosThetaMax = sqrt(max(0.0f, 1.0f - sinThetaMax2));
|
|
float cosTheta = (1.0f - u) + u * cosThetaMax;
|
|
float sinTheta = sqrt(max(0.0f, 1.0f - cosTheta * cosTheta));
|
|
float phi = v * 2.0f * PI;
|
|
|
|
float dc = dist(position, spherePosition);
|
|
float ds = dc * cosTheta - sqrt(max(0.0f, sphereRadius2 - dc * dc * sinTheta * sinTheta));
|
|
float cosAlpha = (dc * dc + sphereRadius2 - ds * ds) / (2.0f * dc * sphereRadius);
|
|
float sinAlpha = sqrt(max(0.0f, 1.0f - cosAlpha * cosAlpha));
|
|
|
|
// Compute surface normal and sampled point on sphere.
|
|
float cphi = cos(phi);
|
|
float sphi = sin(phi);
|
|
float3 nWorld = sinAlpha * cphi * -localToWorld[0] + sinAlpha * sphi * -localToWorld[1] + cosAlpha * -wc;
|
|
|
|
// Compute the world position of the sample
|
|
outPosition = sphereRadius * nWorld + spherePosition;
|
|
|
|
// Uniform cone PDF.
|
|
outPDF = 2.0f * PI * (1 - cosThetaMax);
|
|
}
|