Skip to content

Commit f1226e6

Browse files
committed
-Dev: Added other types of diffuse models to PBR BRDF
1 parent d40780c commit f1226e6

File tree

5 files changed

+110
-24
lines changed

5 files changed

+110
-24
lines changed

resources/shaders/deferred/composition.glsl

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ void main() {
2727
#include utils.glsl
2828
#include shadows.glsl
2929
#include fresnel.glsl
30-
#include BRDFs/cook_torrance_BRDF.glsl
30+
#include BRDFs/burley_BxDF.glsl
3131
#include BRDFs/marschner_BSDF.glsl
32-
#include BRDFs/disney_BSSDF_2015.glsl
32+
#include BRDFs/wip_BSSDF.glsl
3333
#include warp.glsl
3434
#include raytracing.glsl
3535
#include hashing.glsl
@@ -150,7 +150,7 @@ void main() {
150150
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
151151
if(g_material.w == PHYSICAL_MATERIAL) {
152152
//Populate BRDF ________________________
153-
CookTorranceBRDF brdf;
153+
BurleySimpleBRDF brdf;
154154
brdf.albedo = g_albedo;
155155
brdf.opacity = g_opacity;
156156
brdf.normal = g_normal;
@@ -160,13 +160,14 @@ void main() {
160160
brdf.F0 = vec3(0.04);
161161
brdf.F0 = mix(brdf.F0, brdf.albedo, brdf.metalness);
162162
brdf.emission = g_emission;
163+
brdf.diffuseModel = 1.0;
163164

164165
// Indirect Component ____________________________
165166
if(settings.vxgi.enabled == 1) {
166167

167168
// Diffuse
168169
indirect = diffuseVoxelGI2(voxelMap, modelPos, modelNormal, settings.vxgi, scene.maxCoord.x - scene.minCoord.x);
169-
indirect.rgb = evalDiffuseCookTorranceBRDF(modelNormal, normalize(camera.position.xyz - modelPos), indirect.rgb, brdf);
170+
indirect.rgb = evalDiffuseBurleySimpleBRDF(modelNormal, normalize(camera.position.xyz - modelPos), indirect.rgb, brdf);
170171
indirect.rgb *= (1.0 - indirect.a); //Account for occlusion
171172

172173
// Specular
@@ -175,7 +176,7 @@ void main() {
175176
vec3 startPos = modelPos + modelNormal * voxelWorldSize * settings.vxgi.offset;
176177

177178
const float CONE_SPREAD = mix(0.005, settings.vxgi.diffuseConeSpread, brdf.roughness);
178-
indirectSpecular = evalSpecularCookTorranceBRDF(modelNormal, normalize(camera.position.xyz - modelPos), traceCone(voxelMap, startPos, specularConeDirection, settings.vxgi.maxDistance, CONE_SPREAD, voxelWorldSize).rgb, brdfMap, brdf);
179+
indirectSpecular = evalSpecularBurleySimpleBRDF(modelNormal, normalize(camera.position.xyz - modelPos), traceCone(voxelMap, startPos, specularConeDirection, settings.vxgi.maxDistance, CONE_SPREAD, voxelWorldSize).rgb, brdfMap, brdf);
179180

180181
indirect.rgb += indirectSpecular.rgb;
181182
}
@@ -186,7 +187,7 @@ void main() {
186187

187188
//Direct Component ________________________
188189
vec3 lighting = vec3(0.0);
189-
lighting = evalCookTorranceBRDF(scene.lights[i].type != DIRECTIONAL_LIGHT ? normalize(scene.lights[i].position - g_pos) : normalize(-scene.lights[i].position.xyz), //wi
190+
lighting = evalBurleySimpleBRDF(scene.lights[i].type != DIRECTIONAL_LIGHT ? normalize(scene.lights[i].position - g_pos) : normalize(-scene.lights[i].position.xyz), //wi
190191
normalize(-g_pos), //wo
191192
scene.lights[i].color * computeAttenuation(scene.lights[i].position, g_pos, scene.lights[i].areaEffect, int(scene.lights[i].type)) * scene.lights[i].intensity, //radiance
192193
brdf);
@@ -203,7 +204,7 @@ void main() {
203204
mat3 rotY = rotationY(radians(scene.envRotation));
204205
vec3 rotatedNormal = normalize(rotY * modelNormal);
205206
vec3 irradiance = texture(irradianceMap, rotatedNormal).rgb * scene.ambientIntensity;
206-
ambient = evalDiffuseCookTorranceBRDF(rotatedNormal, normalize(camera.position.xyz - modelPos), irradiance, brdf);
207+
ambient = evalDiffuseBurleySimpleBRDF(rotatedNormal, normalize(camera.position.xyz - modelPos), irradiance, brdf);
207208
} else {
208209
ambient = (scene.ambientIntensity * scene.ambientColor) * brdf.albedo;
209210
}

resources/shaders/forward/physically_based.glsl

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ void main() {
8484
#include utils.glsl
8585
#include shadows.glsl
8686
#include fresnel.glsl
87-
#include BRDFs/cook_torrance_BRDF.glsl
87+
#include BRDFs/burley_BxDF.glsl
8888
#include warp.glsl
8989
#include raytracing.glsl
9090

@@ -142,7 +142,7 @@ layout(set = 2, binding = 5) uniform sampler2D emissiveTex;
142142

143143

144144
//BRDF Definiiton
145-
CookTorranceBRDF brdf;
145+
BurleySimpleBRDF brdf;
146146

147147

148148
void setupBRDFProperties(){
@@ -176,6 +176,8 @@ void setupBRDFProperties(){
176176

177177
brdf.emission = material.hasEmissiveTexture ? mix(material.emissiveColor, texture(emissiveTex, v_uv).rgb, material.emissiveWeight) : material.emissiveColor;
178178
brdf.emission *= material.emissionIntensity;
179+
180+
brdf.diffuseModel = 0.0;
179181
}
180182

181183

@@ -194,7 +196,7 @@ void main() {
194196
//If inside liught area influence
195197
if(isInAreaOfInfluence(scene.lights[i].position, v_pos,scene.lights[i].areaEffect,int(scene.lights[i].type))){
196198

197-
vec3 lighting =evalCookTorranceBRDF(
199+
vec3 lighting =evalBurleySimpleBRDF(
198200
scene.lights[i].type != DIRECTIONAL_LIGHT ? normalize(scene.lights[i].position - v_pos) : normalize(scene.lights[i].position.xyz), //wi
199201
normalize(-v_pos), //wo
200202
scene.lights[i].color * computeAttenuation(scene.lights[i].position, v_pos,scene.lights[i].areaEffect,int(scene.lights[i].type)) * scene.lights[i].intensity, //radiance
@@ -229,7 +231,7 @@ void main() {
229231
mat3 rotY = rotationY(radians(scene.envRotation));
230232
vec3 rotatedNormal = normalize(rotY * v_modelNormal);
231233
vec3 irradiance = texture(irradianceMap, rotatedNormal).rgb*scene.ambientIntensity;
232-
ambient = evalDiffuseCookTorranceBRDF(
234+
ambient = evalDiffuseBurleySimpleBRDF(
233235
rotatedNormal,
234236
normalize(camera.position.xyz-v_modelPos),
235237
irradiance,

resources/shaders/include/BRDFs/cook_torrance_BRDF.glsl renamed to resources/shaders/include/BRDFs/burley_BxDF.glsl

Lines changed: 94 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
#define EPSILON 0.001
1111
#endif
1212

13-
struct CookTorranceBRDF{
13+
//Simplified Burley Function
14+
struct BurleySimpleBRDF{
1415
vec3 albedo;
1516
float opacity;
1617
vec3 normal;
@@ -20,6 +21,22 @@ struct CookTorranceBRDF{
2021
vec3 emission;
2122
vec3 F0;
2223
vec3 F;
24+
float diffuseModel;
25+
};
26+
27+
//Complete Burley Function (2015 definition) accounting for scattering and other layers effects.
28+
struct BurleyBSDF{
29+
vec3 albedo;
30+
float opacity;
31+
vec3 normal;
32+
float metalness;
33+
float roughness;
34+
float ao;
35+
vec3 emission;
36+
vec3 F0;
37+
vec3 F;
38+
39+
//WIP
2340
};
2441

2542
//Normal Distribution
@@ -57,17 +74,77 @@ float geometrySmith(vec3 N, vec3 V, vec3 L, float roughness) {
5774
return ggx1 * ggx2;
5875
}
5976

60-
vec3 evalCookTorranceBRDF(
77+
//Burley (Disney) diffuse term
78+
vec3 diffuseBurley(vec3 wi, vec3 wo, vec3 n, vec3 albedo, float roughness)
79+
{
80+
float NdotL = max(dot(n, wi), 0.0);
81+
float NdotV = max(dot(n, wo), 0.0);
82+
83+
float FL = pow(1.0 - NdotL, 5.0);
84+
float FV = pow(1.0 - NdotV, 5.0);
85+
float Fd90 = 0.5 + 2.0 * roughness * NdotL * NdotL;
86+
87+
float diffuseFactor = (1.0 + (Fd90 - 1.0) * FL) * (1.0 + (Fd90 - 1.0) * FV);
88+
return albedo * (diffuseFactor * NdotL / PI);
89+
}
90+
91+
//Oren–Nayar diffuse term
92+
vec3 diffuseOrenNayar(vec3 wi, vec3 wo, vec3 n, vec3 albedo, float roughness)
93+
{
94+
float NdotL = max(dot(n, wi), 0.0);
95+
float NdotV = max(dot(n, wo), 0.0);
96+
97+
if (NdotL <= 0.0 || NdotV <= 0.0)
98+
return vec3(0.0);
99+
100+
float sigma = roughness * roughness;
101+
float sigma2 = sigma * sigma;
102+
103+
float A = 1.0 - (sigma2 / (2.0 * (sigma2 + 0.33)));
104+
float B = 0.45 * sigma2 / (sigma2 + 0.09);
105+
106+
vec3 vi = normalize(wi - n * dot(n, wi));
107+
vec3 vo = normalize(wo - n * dot(n, wo));
108+
float cosPhiDiff = max(dot(vi, vo), 0.0);
109+
110+
float alpha = max(acos(NdotL), acos(NdotV));
111+
float beta = min(acos(NdotL), acos(NdotV));
112+
113+
float orenNayar = NdotL * (A + B * cosPhiDiff * sin(alpha) * tan(beta));
114+
115+
return albedo * orenNayar / PI;
116+
}
117+
118+
// Dispatcher for diffuse type
119+
vec3 getDiffuseTerm(vec3 wi, vec3 wo, BurleySimpleBRDF brdf)
120+
{
121+
if (brdf.diffuseModel == 0) {
122+
// Lambert
123+
float NdotL = max(dot(brdf.normal, wi), 0.0);
124+
return brdf.albedo * NdotL / PI;
125+
}
126+
else if (brdf.diffuseModel == 1) {
127+
// Burley
128+
return diffuseBurley(wi, wo, brdf.normal, brdf.albedo, brdf.roughness);
129+
}
130+
else {
131+
// Oren–Nayar
132+
return diffuseOrenNayar(wi, wo, brdf.normal, brdf.albedo, brdf.roughness);
133+
}
134+
}
135+
136+
vec3 evalBurleySimpleBRDF(
61137
vec3 wi,
62138
vec3 wo,
63139
vec3 radiance,
64-
CookTorranceBRDF brdf)
140+
BurleySimpleBRDF brdf)
65141
{
66142

67143
//Vector setup
68144
vec3 h = normalize(wi + wo);
69145

70-
// Cook-Torrance BRDF
146+
// Cook-Torrance Specular Term
147+
// -----------------------------------
71148
float NDF = distributionGGX(brdf.normal, h, brdf.roughness);
72149
float G = geometrySmith(brdf.normal, wo, wi, brdf.roughness);
73150
vec3 F = fresnelSchlick(max(dot(h, wo), 0.0), brdf.F0);
@@ -85,20 +162,26 @@ vec3 evalCookTorranceBRDF(
85162
float specularScale = 1.0 - smoothness * 0.1; // Scaling factor reduces specular at low roughness
86163
specular *= specularScale;
87164

88-
// Add to outgoing radiance result
89-
float lambertian = max(dot(brdf.normal, wi), 0.0);
165+
// -----------------------------------
166+
// Diffuse Term
167+
// -----------------------------------
168+
169+
vec3 diffuse = getDiffuseTerm(wi, wo, brdf);
170+
171+
// -----------------------------------
90172
//Store fresnel value
173+
// -----------------------------------
91174
brdf.F = F;
92175

93-
return (kD * brdf.albedo / PI + specular) * radiance * lambertian;
176+
return (kD * diffuse + specular) * radiance;
94177

95178
}
96179
// For IBL
97-
vec3 evalDiffuseCookTorranceBRDF(
180+
vec3 evalDiffuseBurleySimpleBRDF(
98181
vec3 wi,
99182
vec3 wo,
100183
vec3 irradiance,
101-
CookTorranceBRDF brdf){
184+
BurleySimpleBRDF brdf){
102185

103186
float WidotWo = max(dot(wi, wo), 0.0);
104187
vec3 specularity = fresnelSchlickRoughness(WidotWo, brdf.F0, brdf.roughness);
@@ -108,12 +191,12 @@ vec3 evalDiffuseCookTorranceBRDF(
108191
vec3 diffuse = irradiance * brdf.albedo;
109192
return aDiffuse * diffuse;
110193
}
111-
vec3 evalSpecularCookTorranceBRDF(
194+
vec3 evalSpecularBurleySimpleBRDF(
112195
vec3 wi,
113196
vec3 wo,
114197
vec3 irradiance,
115198
sampler2D brdfLUT,
116-
CookTorranceBRDF brdf){
199+
BurleySimpleBRDF brdf){
117200

118201
float WidotWo = max(dot(wi, wo), 0.0);
119202
vec3 specularity = fresnelSchlickRoughness(WidotWo, brdf.F0, brdf.roughness);
File renamed without changes.

resources/shaders/include/VXGI.glsl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ vec4 diffuseVoxelGI2(sampler3D voxelMap, vec3 worldPos, vec3 worldNormal, VXGI v
166166
return diffuseIndirect;
167167

168168
}
169-
vec4 diffuseVoxelGI_CookTorrance(sampler3D voxelMap, samplerCube envMap, vec3 worldPos, vec3 worldNormal, vec3 worldView, VXGI vxgi, CookTorranceBRDF brdf, float worldVolumeSize){
169+
vec4 diffuseVoxelGI_CookTorrance(sampler3D voxelMap, samplerCube envMap, vec3 worldPos, vec3 worldNormal, vec3 worldView, VXGI vxgi, BurleySimpleBRDF brdf, float worldVolumeSize){
170170

171171
const float DIFFUSE_CONE_APERTURE = vxgi.diffuseConeSpread;
172172
const float VOXEL_SIZE = 1.0/float(vxgi.resolution);
@@ -186,7 +186,7 @@ vec4 diffuseVoxelGI_CookTorrance(sampler3D voxelMap, samplerCube envMap, vec3 wo
186186
coneTraceCount += 1.0;
187187

188188
vec4 irradiance = traceCone(voxelMap, startPos, DIFFUSE_CONE_DIRECTIONS[i], vxgi.maxDistance, DIFFUSE_CONE_APERTURE, voxelWorldSize);
189-
diffuseIndirect += evalDiffuseCookTorranceBRDF(DIFFUSE_CONE_DIRECTIONS[i], worldView ,irradiance.rgb, brdf) * cosTheta;
189+
diffuseIndirect += evalDiffuseBurleySimpleBRDF(DIFFUSE_CONE_DIRECTIONS[i], worldView ,irradiance.rgb, brdf) * cosTheta;
190190
occlusion += irradiance.a;
191191

192192
// diffuseIndirect += (1.0 - irradiance.a) *vec3(1.0,0.0,0.0) * scene.ambientIntensity;

0 commit comments

Comments
 (0)