-
Notifications
You must be signed in to change notification settings - Fork 338
/
Lighting.hx
141 lines (111 loc) · 4.02 KB
/
Lighting.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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package h3d.shader.pbr;
class Indirect extends PropsDefinition {
static var SRC = {
@:import h3d.shader.pbr.BDRF;
// Flags
@const var drawIndirectDiffuse : Bool;
@const var drawIndirectSpecular : Bool;
@const var showSky : Bool;
@const var skyColor : Bool;
// Indirect Params
@param var irrLut : Sampler2D;
@param var irrDiffuse : SamplerCube;
@param var irrSpecular : SamplerCube;
@param var irrSpecularLevels : Float;
@param var irrPower : Float;
@param var irrRotation : Vec2;
// Sky Params
@param var skyMap : SamplerCube;
@param var skyHdrMax : Float;
@const var gammaCorrect : Bool;
@param var cameraInvViewProj : Mat4;
@param var skyColorValue : Vec3;
// Emissive Blend
@param var emissivePower : Float;
var calculatedUV : Vec2;
function rotateNormal( n : Vec3 ) : Vec3 {
return vec3(n.x * irrRotation.x - n.y * irrRotation.y, n.x * irrRotation.y + n.y * irrRotation.x, n.z);
}
function getEnvSpecular( normal : Vec3, roughness : Float ) : Vec3 {
return irrSpecular.textureLod( rotateNormal(normal), roughness * irrSpecularLevels).rgb;
}
function getEnvDiffuse( normal : Vec3 ) : Vec3 {
return irrDiffuse.get( rotateNormal(normal) ).rgb;
}
function fragment() {
#if !MRT_low
var isSky = normal.dot(normal) <= 0;
#else
var isSky = normal.dot(normal) > 1.1; // due to normal packing, sky normal is likely sqrt(3) > 1.7
#end
if( isSky ) {
if( showSky ) {
var color : Vec3;
if( skyColor ) {
color = skyColorValue;
if( gammaCorrect )
color *= color;
} else {
var normal = (vec3( uvToScreen(calculatedUV), 1. ) * cameraInvViewProj.mat3x4()).normalize();
color = skyMap.get(rotateNormal(normal)).rgb;
color = min(color, skyHdrMax);
if( gammaCorrect )
color *= color;
color *= irrPower;
}
pixelColor.rgb += color;
} else
discard;
} else {
var diffuse = vec3(0.);
var specular = vec3(0.);
var F0 = pbrSpecularColor;
var F = F0 + (max(vec3(1 - roughness), F0) - F0) * exp2( ( -5.55473 * NdV - 6.98316) * NdV );
if( drawIndirectDiffuse ) {
diffuse = getEnvDiffuse(normal) * albedo;
}
if( drawIndirectSpecular ) {
var reflectVec = reflect(-view, normal);
var envSpec = getEnvSpecular(reflectVec, roughness);
var envBRDF = irrLut.get(vec2(roughness, NdV));
specular = envSpec * (F * envBRDF.x + envBRDF.y);
}
var indirect = (diffuse * (1 - metalness) * (1 - F) + specular) * irrPower;
pixelColor.rgb += indirect * occlusion + albedo * emissive * emissivePower;
}
}
};
}
class Direct extends PropsDefinition {
static var SRC = {
@:import h3d.shader.pbr.BDRF;
var pbrLightDirection : Vec3;
var pbrSpecularLightDirection : Vec3;
var pbrLightColor : Vec3;
var pbrOcclusionFactor : Float;
@const var doDiscard : Bool = true;
function __init__fragment2() {
pbrSpecularLightDirection = pbrLightDirection;
}
function fragment() {
var NdL = normal.dot(pbrLightDirection).max(0.);
if( pbrLightColor.dot(pbrLightColor) > 0.0001 && NdL > 0 ) {
var half = (pbrSpecularLightDirection + view).normalize();
var NdH = normal.dot(half).max(0.);
var VdH = view.dot(half).max(0.);
// ------------- DIRECT LIGHT -------------------------
var F0 = pbrSpecularColor;
var diffuse = albedo / PI;
// General Cook-Torrance formula for microfacet BRDF
// f(l,v) = D(h).F(v,h).G(l,v,h) / 4(n.l)(n.v)
var D = normalDistributionGGX(NdH, roughness);// Normal distribution fonction
var F = fresnelSchlick(VdH, F0);// Fresnel term
var G = geometrySchlickGGX(NdV, NdL, roughness);// Geometric attenuation
var specular = (D * F * G).max(0.);
var direct = (diffuse * (1 - metalness) * (1 - F) + specular) * pbrLightColor * NdL;
pixelColor.rgb += direct * shadow * mix(1, occlusion, pbrOcclusionFactor);
} else if( doDiscard )
discard;
}
};
}