Skip to content

Commit a15c031

Browse files
committed
multiLight support for pbrMat
close #1277 , see #636
1 parent 1d3c43e commit a15c031

File tree

5 files changed

+102
-106
lines changed

5 files changed

+102
-106
lines changed

src/operators/material/pbrMat.glsl

Lines changed: 101 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -53,46 +53,112 @@ vec3 THIS_reflectanceMap(vec3 p, MaterialContext matCtx, vec3 refl, float roughn
5353
return mix(reflectMap, blurMap, roughness);
5454
}
5555

56-
//vec3 THIS_getColorForLight(
57-
// CoordT p, MaterialContext matCtx,
58-
// Light light, int lightIndex, float shadedLevel,
59-
// float roughness, float metallic,
60-
// vec3 baseColor
61-
//) {
62-
// vec3 lightDir = normalize(p - light.pos);
63-
// vec3 viewDir = normalize(-matCtx.ray.dir);
64-
//
65-
// float roughness = THIS_Roughness;
66-
// float metallic = THIS_Metallic;
67-
// matCtx.light = light;
68-
// matCtx.lightIndex = lightIndex;
69-
// matCtx.shadedLevel = shadedLevel;
70-
//
71-
// return vec3(0);
72-
//}
73-
74-
vec3 THIS_getColor(vec3 p, MaterialContext matCtx) {
75-
restoreIterationFromMaterial(matCtx, THIS_iterationCapture);
76-
vec3 mp = getPosForMaterial(p, matCtx);
77-
78-
#ifdef THIS_EXPOSE_normal
79-
THIS_normal = matCtx.normal;
56+
vec3 THIS_getColorForLight(
57+
CoordT p, vec3 mp, MaterialContext matCtx,
58+
Light light, int lightIndex, float shadedLevel,
59+
float roughness, float metallic,
60+
vec3 albedo
61+
) {
62+
#ifdef THIS_EXPOSE_lightcolor
63+
THIS_lightcolor = light.color;
64+
#endif
65+
#ifdef THIS_EXPOSE_lightpos
66+
THIS_lightpos = light.pos;
8067
#endif
8168
#ifdef THIS_EXPOSE_shadedlevel
8269
{
8370
THIS_shadedlevel = 1.;
8471
#ifdef RAYTK_USE_SHADOW
8572
if (matCtx.result.useShadow) {
86-
THIS_shadedlevel = matCtx.shadedLevel;
73+
THIS_shadedlevel = shadedLevel;
8774
}
8875
#endif
8976
}
9077
#endif
78+
79+
vec3 F0 = vec3(0.04); // Base normal incidence for
80+
// non-conductors (average of some materials)
81+
F0 = mix(F0,albedo,metallic); // If it is a metal, take the normal incidence (color)
82+
// from the albedo as metals should not have albedo color
83+
84+
// TODO: CLEANUP ALIASES
85+
vec3 eye = normalize(matCtx.ray.pos - p);
86+
vec3 n = matCtx.normal;
87+
vec3 r = reflect(-eye,n);
88+
float ndv = max(dot(n,eye),0.0);
89+
9190
#ifdef THIS_EXPOSE_lightcolor
92-
THIS_lightcolor = matCtx.light.color;
91+
THIS_lightcolor = light.color;
9392
#endif
9493
#ifdef THIS_EXPOSE_lightpos
95-
THIS_lightpos = matCtx.light.pos;
94+
THIS_lightpos = light.pos;
95+
#endif
96+
97+
vec3 lp = light.pos;
98+
vec3 lc = light.color;
99+
vec3 ld = normalize(lp - p);
100+
vec3 h = normalize(ld + eye);
101+
float ndl = max(dot(n,ld),0.0);
102+
float ndh = max(dot(n,h),0.0);
103+
104+
vec3 finalCol = vec3(0.);
105+
106+
{
107+
// Diffuse
108+
vec3 diffuseBRDF = albedo / PI;
109+
110+
// Specular
111+
float D = pbr_distribution(ndh,roughness);
112+
float G = pbr_geometry(ndv,ndl,roughness);
113+
vec3 F = pbr_fresnel(ndv,F0);
114+
115+
vec3 specularBRDFNom = D * G * F;
116+
float specularBRDFDenom = 4.0 * max(ndv * ndl, 0.0) + 0.001; // add bias to prevent
117+
// division by 0
118+
vec3 specularBRDF = specularBRDFNom / specularBRDFDenom;
119+
120+
// Outgoing light can't exced 1
121+
vec3 kS = F;
122+
vec3 kD = 1.0 - kS;
123+
kD *= 1.0 - metallic;
124+
125+
finalCol = (kD * diffuseBRDF + specularBRDF);
126+
finalCol = finalCol * ndl * lc;
127+
}
128+
129+
{
130+
// IBL
131+
vec3 F = pbr_fresnelRoughness(ndv,F0,roughness);
132+
vec3 kS = F;
133+
vec3 kD = 1.0 - kS;
134+
kD *= 1.0 - metallic;
135+
vec3 totalIBL = vec3(0.0);
136+
137+
// Diffuse IBL
138+
vec3 irradiance = THIS_irradianceMap(mp, matCtx);
139+
vec3 diffuseIBL = irradiance * albedo * kD * 1.0;
140+
141+
// Specular IBL
142+
vec3 reflectance = THIS_reflectanceMap(mp, matCtx, r, roughness, irradiance);
143+
vec3 specularIBL = reflectance * F;
144+
145+
totalIBL = kD * diffuseIBL + specularIBL;
146+
147+
finalCol += totalIBL;
148+
}
149+
150+
#if defined(THIS_Enableshadow) && defined(RAYTK_USE_SHADOW)
151+
finalCol *= shadedLevel;
152+
#endif
153+
return finalCol;
154+
}
155+
156+
vec3 THIS_getColor(vec3 p, MaterialContext matCtx) {
157+
restoreIterationFromMaterial(matCtx, THIS_iterationCapture);
158+
vec3 mp = getPosForMaterial(p, matCtx);
159+
160+
#ifdef THIS_EXPOSE_normal
161+
THIS_normal = matCtx.normal;
96162
#endif
97163
#ifdef THIS_EXPOSE_surfacecolor
98164
{
@@ -113,9 +179,6 @@ vec3 THIS_getColor(vec3 p, MaterialContext matCtx) {
113179
}
114180
#endif
115181

116-
vec3 lightDir = normalize(p - matCtx.light.pos);
117-
vec3 viewDir = normalize(-matCtx.ray.dir);
118-
119182
float roughness = THIS_Roughness;
120183
float metallic = THIS_Metallic;
121184

@@ -138,81 +201,14 @@ vec3 THIS_getColor(vec3 p, MaterialContext matCtx) {
138201

139202
vec3 albedo = baseColor * THIS_Albedo;
140203

141-
vec3 F0 = vec3(0.04); // Base normal incidence for
142-
// non-conductors (average of some materials)
143-
F0 = mix(F0,albedo,metallic); // If it is a metal, take the normal incidence (color)
144-
// from the albedo as metals should not have albedo color
145-
146-
// TODO: CLEANUP ALIASES
147-
vec3 eye = normalize(matCtx.ray.pos - p);
148-
vec3 n = matCtx.normal;
149-
vec3 r = reflect(-eye,n);
150-
float ndv = max(dot(n,eye),0.0);
151-
152-
const int kLights = 1;
153-
float sAcum = float(kLights);
154-
vec3 acum = vec3(0.0);
155-
156-
// TODO clean up loop?
157-
for (int i = 0; i < kLights; i++) {
158-
// Per-light parameters
159-
// vec3 lp = lights[i].Position;
160-
vec3 lp = matCtx.light.pos;
161-
vec3 ld = normalize(lp - p);
162-
vec3 h = normalize(ld + eye);
163-
float ndl = max(dot(n,ld),0.0);
164-
float ndh = max(dot(n,h),0.0);
165-
166-
// Diffuse
167-
vec3 diffuseBRDF = albedo / PI;
168-
169-
// Specular
170-
float D = pbr_distribution(ndh,roughness);
171-
float G = pbr_geometry(ndv,ndl,roughness);
172-
vec3 F = pbr_fresnel(ndv,F0);
173-
174-
vec3 specularBRDFNom = D * G * F;
175-
float specularBRDFDenom = 4.0 * max(ndv * ndl, 0.0) + 0.001; // add bias to prevent
176-
// division by 0
177-
vec3 specularBRDF = specularBRDFNom / specularBRDFDenom;
178-
179-
// Outgoing light can't exced 1
180-
vec3 kS = F;
181-
vec3 kD = 1.0 - kS;
182-
kD *= 1.0 - metallic;
183-
184-
vec3 finalCol = (kD * diffuseBRDF + specularBRDF);
185-
finalCol = finalCol * ndl * matCtx.light.color;
186-
acum += finalCol;
187-
188-
// Shadow
189-
// vec3 sDir = normalize(lp - p);
190-
// sAcum -= Shadow(p,sDir);
191-
#if defined(THIS_Enableshadow) && defined(RAYTK_USE_SHADOW)
192-
sAcum *= matCtx.shadedLevel;
193-
#endif
204+
vec3 col = vec3(0.);
205+
#if RAYTK_LIGHT_COUNT > 1
206+
for (int i = 0; i < RAYTK_LIGHT_COUNT; i++) {
207+
col += THIS_getColorForLight(p, mp, matCtx, matCtx.allLights[i], i, matCtx.allShadedLevels[i], roughness, metallic, albedo);
194208
}
195-
196-
// IBL
197-
vec3 F = pbr_fresnelRoughness(ndv,F0,roughness);
198-
vec3 kS = F;
199-
vec3 kD = 1.0 - kS;
200-
kD *= 1.0 - metallic;
201-
vec3 totalIBL = vec3(0.0);
202-
203-
// Diffuse IBL
204-
vec3 irradiance = THIS_irradianceMap(mp, matCtx);
205-
vec3 diffuseIBL = irradiance * albedo * kD * 1.0;
206-
207-
// Specular IBL
208-
vec3 reflectance = THIS_reflectanceMap(mp, matCtx, r, roughness, irradiance);
209-
vec3 specularIBL = reflectance * F;
210-
211-
totalIBL = kD * diffuseIBL + specularIBL;
212-
213-
// Shadowing
214-
float finalShadow = max(sAcum / float(kLights),0.02);
215-
216-
return (acum + totalIBL) * max(finalShadow,0.15);
209+
#else
210+
col = THIS_getColorForLight(p, mp, matCtx, matCtx.light, 0, matCtx.shadedLevel, roughness, metallic, albedo);
211+
#endif
212+
return col;
217213
}
218214

src/operators/material/pbrMat.tox

-248 Bytes
Binary file not shown.

src/operators/material/pbrMat.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
!rop
22
meta: !meta
33
opType: raytk.operators.material.pbrMat
4-
opVersion: '19'
4+
opVersion: '20'
55
opStatus: beta
66
opDef: !def
77
enable: !expr
Loading
Binary file not shown.

0 commit comments

Comments
 (0)