Last active
December 27, 2017 11:09
-
-
Save reinsteam/12a81a6fbff178b298310ae7b6d6ca2f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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