/
BDRF.hx
67 lines (55 loc) · 2.32 KB
/
BDRF.hx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package h3d.shader.pbr;
class BDRF extends hxsl.Shader {
static var SRC = {
function getAnisotropicRoughness( roughness : Float, anisotropy : Float ) : Vec2 {
// [Burley12] Offers more pleasant and intuitive results, but is slightly more expensive
//var da = sqrt(1 - 0.9 * anisotropy);
//var at = anisotropy / da;
//var ab = anisotropy * da;
// [Kulla17] Allows creation of sharp highlights
var at = max(roughness * (1.0 + anisotropy), 0.001);
var ab = max(roughness * (1.0 - anisotropy), 0.001);
return vec2(at, ab);
}
// [Heitz14] Anisotropic visibility function
function smithGGXCorrelatedAnisotropic( at : Float, ab : Float, TdV : Float, BdV : Float, TdL : Float, BdL : Float, NdV: Float, NdL : Float ) : Float {
var lambdaV = NdL * length(vec3(at * TdV, ab * BdV, NdV));
var lambdaL = NdV * length(vec3(at * TdL, ab * BdL, NdL));
var v = 0.5 / (lambdaV + lambdaL);
return saturate(v);
}
// GGX Anisotropic
function normalDistributionGGXAnisotropic( at : Float, ab : Float, NdH : Float, TdH : Float, BdH : Float, roughness : Float, anisotropy : Float ) : Float {
var a2 = at * ab;
var v = vec3(ab * TdH, at * BdH, a2 * NdH);
var v2 = dot(v, v);
var w2 = a2 / v2;
return a2 * w2 * w2 * (1.0 / PI);
}
// Formulas below from 2013 Siggraph "Real Shading in UE4"
// GGX (Trowbridge-Reitz) "Disney"
function normalDistributionGGX( NdH : Float, roughness: Float ) : Float {
var alpha = roughness * roughness;
var alpha2 = alpha * alpha;
var denom = NdH * NdH * (alpha2 - 1.) + 1;
return alpha2 / (PI * denom * denom);
}
// G = geometric attenuation
// Schlick (modified for UE4 with k=alpha/2)
// k = (rough + 1)² / 8
function geometrySchlickGGX( NdV : Float, NdL : Float, roughness : Float ) : Float {
var k = (roughness + 1);
k *= k;
k *= 0.125;
//var G = (1 / (NdV * (1 - k) + k)) * (1 / (NdL * (1 - k) + k)) * NdL * NdV;
//var Att = 1 / (4 * NdL * NdV);
return (1 / (NdV * (1 - k) + k)) * (1 / (NdL * (1 - k) + k)) * 0.25;
}
// Schlick approx
// pow 5 optimized with Spherical Gaussian
// var F = F0 + (1 - F0) * pow(1 - v.dot(h), 5.);
function fresnelSchlick( VdH : Float, F0 : Vec3 ) : Vec3 {
return F0 + (1. - F0) * exp2( ( -5.55473 * VdH - 6.98316) * VdH );
}
}
}