144 lines
3.7 KiB
HLSL
144 lines
3.7 KiB
HLSL
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
|
|
|
#ifndef __MONTE_CARLO__
|
|
#define __MONTE_CARLO__
|
|
|
|
float3 TangentToWorld(float3 vec, float3 tangentZ)
|
|
{
|
|
float3 upVector = abs(tangentZ.z) < 0.999 ? float3(0, 0, 1) : float3(1, 0, 0);
|
|
float3 tangentX = normalize(cross(upVector, tangentZ));
|
|
float3 tangentY = cross(tangentZ, tangentX);
|
|
return tangentX * vec.x + tangentY * vec.y + tangentZ * vec.z;
|
|
}
|
|
|
|
uint ReverseBits32(uint bits)
|
|
{
|
|
#if FEATURE_LEVEL >= FEATURE_LEVEL_SM5
|
|
return reversebits(bits);
|
|
#else
|
|
bits = ( bits << 16) | ( bits >> 16);
|
|
bits = ( (bits & 0x00ff00ff) << 8 ) | ( (bits & 0xff00ff00) >> 8 );
|
|
bits = ( (bits & 0x0f0f0f0f) << 4 ) | ( (bits & 0xf0f0f0f0) >> 4 );
|
|
bits = ( (bits & 0x33333333) << 2 ) | ( (bits & 0xcccccccc) >> 2 );
|
|
bits = ( (bits & 0x55555555) << 1 ) | ( (bits & 0xaaaaaaaa) >> 1 );
|
|
return bits;
|
|
#endif
|
|
}
|
|
|
|
float2 Hammersley(uint index, uint numSamples, uint2 random)
|
|
{
|
|
float e1 = frac((float)index / numSamples + float(random.x & 0xffff) / (1 << 16));
|
|
float e2 = float(ReverseBits32(index) ^ random.y) * 2.3283064365386963e-10;
|
|
return float2(e1, e2);
|
|
}
|
|
|
|
float4 UniformSampleSphere(float2 e)
|
|
{
|
|
float phi = 2 * PI * e.x;
|
|
float cosTheta = 1 - 2 * e.y;
|
|
float sinTheta = sqrt(1 - cosTheta * cosTheta);
|
|
|
|
float3 h;
|
|
h.x = sinTheta * cos(phi);
|
|
h.y = sinTheta * sin(phi);
|
|
h.z = cosTheta;
|
|
|
|
float pdf = 1.0 / (4 * PI);
|
|
return float4(h, pdf);
|
|
}
|
|
|
|
float4 UniformSampleHemisphere(float2 e)
|
|
{
|
|
float phi = 2 * PI * e.x;
|
|
float cosTheta = e.y;
|
|
float sinTheta = sqrt(1 - cosTheta * cosTheta);
|
|
|
|
float3 h;
|
|
h.x = sinTheta * cos(phi);
|
|
h.y = sinTheta * sin(phi);
|
|
h.z = cosTheta;
|
|
|
|
float pdf = 1.0 / (2 * PI);
|
|
return float4(h, pdf);
|
|
}
|
|
|
|
float4 CosineSampleHemisphere(float2 e)
|
|
{
|
|
float phi = 2 * PI * e.x;
|
|
float cosTheta = sqrt(e.y);
|
|
float sinTheta = sqrt(1 - cosTheta * cosTheta);
|
|
|
|
float3 h;
|
|
h.x = sinTheta * cos(phi);
|
|
h.y = sinTheta * sin(phi);
|
|
h.z = cosTheta;
|
|
|
|
float pdf = cosTheta / PI;
|
|
return float4(h, pdf);
|
|
}
|
|
|
|
float4 UniformSampleCone(float2 e, float cosThetaMax)
|
|
{
|
|
float phi = 2 * PI * e.x;
|
|
float cosTheta = lerp(cosThetaMax, 1, e.y);
|
|
float sinTheta = sqrt(1 - cosTheta * cosTheta);
|
|
|
|
float3 l;
|
|
l.x = sinTheta * cos(phi);
|
|
l.y = sinTheta * sin(phi);
|
|
l.z = cosTheta;
|
|
|
|
float pdf = 1.0 / (2 * PI * (1 - cosThetaMax));
|
|
return float4(l, pdf);
|
|
}
|
|
|
|
float4 ImportanceSampleBlinn(float2 e, float roughness)
|
|
{
|
|
float m = roughness * roughness;
|
|
float n = 2 / (m * m) - 2;
|
|
|
|
float phi = 2 * PI * e.x;
|
|
float cosTheta = ClampedPow(e.y, 1 / (n + 1));
|
|
float sinTheta = sqrt(1 - cosTheta * cosTheta);
|
|
|
|
float3 h;
|
|
h.x = sinTheta * cos(phi);
|
|
h.y = sinTheta * sin(phi);
|
|
h.z = cosTheta;
|
|
|
|
float d = (n + 2) / (2 * PI) * ClampedPow(cosTheta, n);
|
|
float pdf = d * cosTheta;
|
|
return float4(h, pdf);
|
|
}
|
|
|
|
float4 ImportanceSampleGGX(float2 e, float roughness)
|
|
{
|
|
float m = roughness * roughness;
|
|
float m2 = m * m;
|
|
|
|
float phi = 2 * PI * e.x;
|
|
float cosTheta = sqrt((1 - e.y) / (1 + (m2 - 1) * e.y));
|
|
float sinTheta = sqrt(1 - cosTheta * cosTheta);
|
|
|
|
float3 h;
|
|
h.x = sinTheta * cos(phi);
|
|
h.y = sinTheta * sin(phi);
|
|
h.z = cosTheta;
|
|
|
|
float r = (cosTheta * m2 - cosTheta) * cosTheta + 1;
|
|
float d = m2 / (PI * r * r);
|
|
float pdf = d * cosTheta;
|
|
return float4(h, pdf);
|
|
}
|
|
|
|
// Multiple importance sampling power heuristic of two functions with a power of two.
|
|
// [Veach 1997, "Robust Monte Carlo Methods for Light Transport Simulation"]
|
|
float MISWeight(uint number, float PDF, uint otherNumber, float otherPDF)
|
|
{
|
|
float weight = number * PDF;
|
|
float otherWeight = otherNumber * otherPDF;
|
|
return weight * weight / (weight * weight + otherWeight * otherWeight);
|
|
}
|
|
|
|
#endif
|