Skip to content

Instantly share code, notes, and snippets.

@reinsteam
Last active December 27, 2017 11:09
Show Gist options
  • Save reinsteam/12a81a6fbff178b298310ae7b6d6ca2f to your computer and use it in GitHub Desktop.
Save reinsteam/12a81a6fbff178b298310ae7b6d6ca2f to your computer and use it in GitHub Desktop.
uint BitReverse(uint x)
{
x = ((x & 0x55555555) << 1) | ((x & 0xaaaaaaaa) >> 1);
x = ((x & 0x33333333) << 2) | ((x & 0xcccccccc) >> 2);
x = ((x & 0x0f0f0f0f) << 4) | ((x & 0xf0f0f0f0) >> 4);
x = ((x & 0x00ff00ff) << 8) | ((x & 0xff00ff00) >> 8);
x = ((x & 0x0000ffff) << 16) | ((x & 0xffff0000) >> 16);
return x;
}
float2 Hammersley(uint SampleIdx, uint SampleCnt)
{
float u = float(SampleIdx) / float(SampleCnt);
float v = float(BitReverse(SampleIdx)) * 2.3283064365386963e-10;
return float2(u, v);
}
float3 SphericalToCartesian(float PhiAngle, float CosTheta, float SinTheta)
{
return float3(SinTheta * cos(PhiAngle), SinTheta * sin(PhiAngle), CosTheta);
}
float Ndf_GGX(float a2, float NoH)
{
const float denom = (NoH * a2 - NoH) * NoH + 1.0;
const float denSq = denom * denom;
return a2 * ONE_OVER_PI * rcp(denSq);
}
float Pdf_GGX(float a2, float NoH, float VoH)
{
// pdf == D(H) * N.H / (4.0 * L.H)
// L.H == V.H
return Ndf_GGX(a2, NoH) * NoH * rcp(VoH) * 0.25;
}
float Pdf_Blinn(float CosTheta, float n)
{
float D = (n + 2.0) * rcp(2.0 * PI) * pow(CosTheta, n);
return D * CosTheta;
}
float3 ImportanceSampleBlinn(float2 E, float Roughness)
{
const float m = Roughness * Roughness;
const float n = 2.0 * rcp(m * m) - 2.0;
const float PhiAngle = TWO_PI * E.x;
const float CosTheta = pow(1.0 - E.y, 1.0 * rcp(n + 1.0));
const float SinTheta = sqrt(1.0 - CosTheta * CosTheta);
return float4(SphericalToCartesian(PhiAngle, CosTheta));
}
float3 ImportanceSampleCos(float2 E)
{
const float PhiAngle = TWO_PI * E.x;
const float CosTheta = sqrt(1.0 - E.y);
const float SinTheta = sqrt(E.y);
return SphericalToCartesian(PhiAngle, CosTheta, SinTheta);
}
float3 ImportanceSampleGGX(float2 E, float Roughness)
{
const float a1 = Roughness * Roughness;
const float a2 = a1 * a1;
const float PhiAngle = TWO_PI * E.x;
const float CosThetaSq = (1.0 - E.y) * rcp(1.0 + (a2 - 1.0) * E.y);
const float CosTheta = sqrt(CosThetaSq);
const float SinTheta = sqrt(1.0 - CosThetaSq);
return SphericalToCartesian(PhiAngle, CosTheta, SinTheta);
}
float3 TangentToWorld(float3 H, float3 TangentX, float TangentY)
{
return TangentX * H.x + TangentY * H.y + N * H.z;
}
void ExtractTangent(float3 N, out float3 TangentX, out float3 TangentY)
{
float3 UpVector = abs(N.z) < 0.999 ? float3(0.0, 0.0, 1.0) : float3(1.0, 0.0, 0.0);
TangentX = normalize( cross( UpVector, N ) );
TangentY = cross( N, TangentX );
}
float3 AdjustNormal(float3 H, float N)
{
float3 TangentX;
float3 TangentY;
ExtractTangent(N, TangentX, TangentY);
return TangentToWorld(H, TangentX, TangentY);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment