2021-05-09 20:04:41 -04:00
|
|
|
const float PI = 3.14159265359;
|
|
|
|
const float EPSILON = 0.005;
|
|
|
|
|
2022-02-15 09:01:35 -05:00
|
|
|
const vec2 PoissionPCFDisk[16] = {
|
|
|
|
vec2( -0.94201624, -0.39906216 ),
|
|
|
|
vec2( 0.94558609, -0.76890725 ),
|
|
|
|
vec2( -0.094184101, -0.92938870 ),
|
|
|
|
vec2( 0.34495938, 0.29387760 ),
|
|
|
|
vec2( -0.91588581, 0.45771432 ),
|
|
|
|
vec2( -0.81544232, -0.87912464 ),
|
|
|
|
vec2( -0.38277543, 0.27676845 ),
|
|
|
|
vec2( 0.97484398, 0.75648379 ),
|
|
|
|
vec2( 0.44323325, -0.97511554 ),
|
|
|
|
vec2( 0.53742981, -0.47373420 ),
|
|
|
|
vec2( -0.26496911, -0.41893023 ),
|
|
|
|
vec2( 0.79197514, 0.19090188 ),
|
|
|
|
vec2( -0.24188840, 0.99706507 ),
|
|
|
|
vec2( -0.81409955, 0.91437590 ),
|
|
|
|
vec2( 0.19984126, 0.78641367 ),
|
|
|
|
vec2( 0.14383161, -0.14100790 )
|
|
|
|
};
|
|
|
|
|
2021-05-09 20:04:41 -04:00
|
|
|
const vec2 PoissonOffsets[64] = {
|
|
|
|
vec2(0.0617981, 0.07294159),
|
|
|
|
vec2(0.6470215, 0.7474022),
|
|
|
|
vec2(-0.5987766, -0.7512833),
|
|
|
|
vec2(-0.693034, 0.6913887),
|
|
|
|
vec2(0.6987045, -0.6843052),
|
|
|
|
vec2(-0.9402866, 0.04474335),
|
|
|
|
vec2(0.8934509, 0.07369385),
|
|
|
|
vec2(0.1592735, -0.9686295),
|
|
|
|
vec2(-0.05664673, 0.995282),
|
|
|
|
vec2(-0.1203411, -0.1301079),
|
|
|
|
vec2(0.1741608, -0.1682285),
|
|
|
|
vec2(-0.09369049, 0.3196758),
|
|
|
|
vec2(0.185363, 0.3213367),
|
|
|
|
vec2(-0.1493771, -0.3147511),
|
|
|
|
vec2(0.4452095, 0.2580113),
|
|
|
|
vec2(-0.1080467, -0.5329178),
|
|
|
|
vec2(0.1604507, 0.5460774),
|
|
|
|
vec2(-0.4037193, -0.2611179),
|
|
|
|
vec2(0.5947998, -0.2146744),
|
|
|
|
vec2(0.3276062, 0.9244621),
|
|
|
|
vec2(-0.6518704, -0.2503952),
|
|
|
|
vec2(-0.3580975, 0.2806469),
|
|
|
|
vec2(0.8587891, 0.4838005),
|
|
|
|
vec2(-0.1596546, -0.8791054),
|
|
|
|
vec2(-0.3096867, 0.5588146),
|
|
|
|
vec2(-0.5128918, 0.1448544),
|
|
|
|
vec2(0.8581337, -0.424046),
|
|
|
|
vec2(0.1562584, -0.5610626),
|
|
|
|
vec2(-0.7647934, 0.2709858),
|
|
|
|
vec2(-0.3090832, 0.9020988),
|
|
|
|
vec2(0.3935608, 0.4609676),
|
|
|
|
vec2(0.3929337, -0.5010948),
|
|
|
|
vec2(-0.8682281, -0.1990303),
|
|
|
|
vec2(-0.01973724, 0.6478714),
|
|
|
|
vec2(-0.3897587, -0.4665619),
|
|
|
|
vec2(-0.7416366, -0.4377831),
|
|
|
|
vec2(-0.5523247, 0.4272514),
|
|
|
|
vec2(-0.5325066, 0.8410385),
|
|
|
|
vec2(0.3085465, -0.7842533),
|
|
|
|
vec2(0.8400612, -0.200119),
|
|
|
|
vec2(0.6632416, 0.3067062),
|
|
|
|
vec2(-0.4462856, -0.04265022),
|
|
|
|
vec2(0.06892014, 0.812484),
|
|
|
|
vec2(0.5149567, -0.7502338),
|
|
|
|
vec2(0.6464897, -0.4666451),
|
|
|
|
vec2(-0.159861, 0.1038342),
|
|
|
|
vec2(0.6455986, 0.04419327),
|
|
|
|
vec2(-0.7445076, 0.5035095),
|
|
|
|
vec2(0.9430245, 0.3139912),
|
|
|
|
vec2(0.0349884, -0.7968109),
|
|
|
|
vec2(-0.9517487, 0.2963554),
|
|
|
|
vec2(-0.7304786, -0.01006928),
|
|
|
|
vec2(-0.5862702, -0.5531025),
|
|
|
|
vec2(0.3029106, 0.09497032),
|
|
|
|
vec2(0.09025345, -0.3503742),
|
|
|
|
vec2(0.4356628, -0.0710125),
|
|
|
|
vec2(0.4112572, 0.7500054),
|
|
|
|
vec2(0.3401214, -0.3047142),
|
|
|
|
vec2(-0.2192158, -0.6911137),
|
|
|
|
vec2(-0.4676369, 0.6570358),
|
|
|
|
vec2(0.6295372, 0.5629555),
|
|
|
|
vec2(0.1253822, 0.9892166),
|
|
|
|
vec2(-0.1154335, 0.8248222),
|
|
|
|
vec2(-0.4230408, -0.7129914)
|
|
|
|
};
|
|
|
|
|
|
|
|
// GGX/Trowbridge-Reitz Normal Distribution
|
|
|
|
float ggx_distribution(const vec3 N, const vec3 H, const float roughness) {
|
|
|
|
const float roughness_squared = roughness * roughness;
|
|
|
|
|
|
|
|
const float NdotH = dot(N, H);
|
|
|
|
|
|
|
|
const float denominator = (NdotH * NdotH) * (roughness_squared - 1.0) + 1.0;
|
|
|
|
|
|
|
|
return roughness_squared / (PI * (denominator * denominator));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Slick Geometry
|
|
|
|
float geometry_slick_direct(const vec3 N, const vec3 V, const float roughness) {
|
|
|
|
const float NdotV = clamp(dot(N, V), 0.0, 1.0);
|
|
|
|
const float denominator = NdotV * (1.0 - roughness) + roughness;
|
|
|
|
|
|
|
|
return NdotV / denominator;
|
|
|
|
}
|
|
|
|
|
|
|
|
// GGX Smith Geometry, using GGX slick but combining both the view direction and the light direction
|
|
|
|
float geometry_smith(const vec3 N, const vec3 V, const vec3 L, float roughness) {
|
|
|
|
const float dotNV = max(dot(N, V), 0.0);
|
|
|
|
const float dotNL = max(dot(N, L), 0.0);
|
|
|
|
|
|
|
|
const float k = (roughness * roughness) / 2.0;
|
|
|
|
const float GL = dotNL / (dotNL * (1.0 - k) + k);
|
|
|
|
const float GV = dotNV / (dotNV * (1.0 - k) + k);
|
|
|
|
|
|
|
|
return GL * GV;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fresnel Shlick
|
|
|
|
vec3 fresnel_schlick(const float cos_theta, const vec3 F0) {
|
|
|
|
return F0 + (1.0 - F0) * pow(1.0 - cos_theta, 5.0);
|
|
|
|
}
|
|
|
|
|
|
|
|
vec3 fresnel_schlick_roughness(float cosTheta, vec3 F0, float roughness) {
|
|
|
|
return F0 + (max(vec3(1.0 - roughness), F0) - F0) * pow(1.0 - cosTheta, 5.0);
|
|
|
|
}
|
|
|
|
|
|
|
|
// efficient VanDerCorpus calculation from http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
|
|
|
|
float radical_inverse(uint bits) {
|
|
|
|
bits = (bits << 16u) | (bits >> 16u);
|
|
|
|
bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
|
|
|
|
bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
|
|
|
|
bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
|
|
|
|
bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
|
|
|
|
|
|
|
|
return float(bits) * 2.3283064365386963e-10;
|
|
|
|
}
|
|
|
|
|
|
|
|
vec2 hammersley(const uint i, const uint N) {
|
|
|
|
return vec2(float(i) / float(N), radical_inverse(i));
|
|
|
|
}
|
|
|
|
|
|
|
|
vec3 importance_sample_ggx(const vec2 Xi, const vec3 N, const float roughness) {
|
|
|
|
const float a = roughness*roughness;
|
|
|
|
|
|
|
|
const float phi = 2.0 * PI * Xi.x;
|
|
|
|
const float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (a*a - 1.0) * Xi.y));
|
|
|
|
const float sinTheta = sqrt(1.0 - cosTheta*cosTheta);
|
|
|
|
|
|
|
|
// from spherical coordinates to cartesian coordinates - halfway vector
|
|
|
|
vec3 H;
|
|
|
|
H.x = cos(phi) * sinTheta;
|
|
|
|
H.y = sin(phi) * sinTheta;
|
|
|
|
H.z = cosTheta;
|
|
|
|
|
|
|
|
// from tangent-space H vector to world-space sample vector
|
|
|
|
const vec3 up = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
|
|
|
|
const vec3 tangent = normalize(cross(up, N));
|
|
|
|
const vec3 bitangent = cross(N, tangent);
|
|
|
|
|
|
|
|
return normalize(tangent * H.x + bitangent * H.y + N * H.z);
|
|
|
|
}
|
|
|
|
|
|
|
|
vec3 from_linear_to_srgb(const vec3 linearRGB) {
|
|
|
|
bvec3 cutoff = lessThan(linearRGB, vec3(0.0031308));
|
|
|
|
vec3 higher = vec3(1.055)*pow(linearRGB, vec3(1.0/2.4)) - vec3(0.055);
|
|
|
|
vec3 lower = linearRGB * vec3(12.92);
|
|
|
|
|
|
|
|
return mix(higher, lower, cutoff);
|
|
|
|
}
|
|
|
|
|
|
|
|
vec3 from_srgb_to_linear(const vec3 sRGB) {
|
|
|
|
bvec3 cutoff = lessThan(sRGB, vec3(0.04045));
|
|
|
|
vec3 higher = pow((sRGB + vec3(0.055))/vec3(1.055), vec3(2.4));
|
|
|
|
vec3 lower = sRGB/vec3(12.92);
|
|
|
|
|
|
|
|
return mix(higher, lower, cutoff);
|
|
|
|
}
|