Shortly after loading the "SpecGlossVsMetalRough" model from glTF-Sample-Assets,… my CompareLoaders app crashes with a bad shader compile.
This crash is reproducible with JME v3.8.0-alpha4 and -alpha3 but not -alpha2, so I think it's a recent regression.
The test model can be found online:
https://github.com/KhronosGroup/glTF-Sample-Assets/tree/main/Models/SpecGlossVsMetalRough
```console
Successfully loaded "SpecGlossVsMetalRough" from the gltf-sample-assets group using the Default loader(s).
======
Mar 05, 2025 11:19:00 AM com.jme3.renderer.opengl.GLRenderer updateShaderSourceData
WARNING: Bad compile of:
1 #version 150 core
2 #define SRGB 1
3 #define FRAGMENT_SHADER 1
4 #define BOUND_DRAW_BUFFER 0
5 #define BASECOLORMAP 1
6 #define EMISSIVE 1
7 #define SPECGLOSSPIPELINE 1
8 #define SPECULAR_AA 1
9 #define NORMAL_TYPE -1.0
10 #define SINGLE_PASS_LIGHTING 1
11 #define NB_LIGHTS 3
12 #define NB_PROBES 1
13 #define USE_AMBIENT_LIGHT 1
14 #extension GL_ARB_shader_texture_lod : enable
15 // -- begin import Common/ShaderLib/GLSLCompat.glsllib --
16 #ifdef GL_ES
17 #ifdef FRAGMENT_SHADER
18 precision highp float;
19 precision highp int;
20 #if __VERSION__ >= 130
21 precision highp sampler2DArray;
22 #endif
23 precision highp sampler2DArray;
24 precision highp sampler2DShadow;
25 precision highp samplerCube;
26 precision highp sampler3D;
27 precision highp sampler2D;
28 #if __VERSION__ >= 310
29 precision highp sampler2DMS;
30 #endif
31 #endif
32 #endif
33
34 #if defined GL_ES
35 # define hfloat highp float
36 # define hvec2 highp vec2
37 # define hvec3 highp vec3
38 # define hvec4 highp vec4
39 # define lfloat lowp float
40 # define lvec2 lowp vec2
41 # define lvec3 lowp vec3
42 # define lvec4 lowp vec4
43 #else
44 # define hfloat float
45 # define hvec2 vec2
46 # define hvec3 vec3
47 # define hvec4 vec4
48 # define lfloat float
49 # define lvec2 vec2
50 # define lvec3 vec3
51 # define lvec4 vec4
52 #endif
53
54 #if __VERSION__ >= 130
55
56 #ifdef FRAGMENT_SHADER
57 #ifdef GL_ES
58 #ifdef BOUND_DRAW_BUFFER
59
60 #if 0<=BOUND_DRAW_BUFFER
61 #if BOUND_DRAW_BUFFER == 0
62 layout( location = 0 ) out highp vec4 outFragColor;
63 #else
64 layout( location = 0 ) out highp vec4 outNOP0;
65 #endif
66 #endif
67
68 #if 1<=BOUND_DRAW_BUFFER
69 #if BOUND_DRAW_BUFFER == 1
70 layout( location = 1 ) out highp vec4 outFragColor;
71 #else
72 layout( location = 1 ) out highp vec4 outNOP1;
73 #endif
74 #endif
75
76 #if 2<=BOUND_DRAW_BUFFER
77 #if BOUND_DRAW_BUFFER == 2
78 layout( location = 2 ) out highp vec4 outFragColor;
79 #else
80 layout( location = 2 ) out highp vec4 outNOP2;
81 #endif
82 #endif
83
84 #if 3<=BOUND_DRAW_BUFFER
85 #if BOUND_DRAW_BUFFER == 3
86 layout( location = 3 ) out highp vec4 outFragColor;
87 #else
88 layout( location = 3 ) out highp vec4 outNOP3;
89 #endif
90 #endif
91
92 #if 4<=BOUND_DRAW_BUFFER
93 #if BOUND_DRAW_BUFFER == 4
94 layout( location = 4 ) out highp vec4 outFragColor;
95 #else
96 layout( location = 4 ) out highp vec4 outNOP4;
97 #endif
98 #endif
99
100 #if 5<=BOUND_DRAW_BUFFER
101 #if BOUND_DRAW_BUFFER == 5
102 layout( location = 5 ) out highp vec4 outFragColor;
103 #else
104 layout( location = 5 ) out highp vec4 outNOP5;
105 #endif
106 #endif
107
108 #if 6<=BOUND_DRAW_BUFFER
109 #if BOUND_DRAW_BUFFER == 6
110 layout( location = 6 ) out highp vec4 outFragColor;
111 #else
112 layout( location = 6 ) out highp vec4 outNOP6;
113 #endif
114 #endif
115
116 #if 7<=BOUND_DRAW_BUFFER
117 #if BOUND_DRAW_BUFFER == 7
118 layout( location = 7 ) out highp vec4 outFragColor;
119 #else
120 layout( location = 7 ) out highp vec4 outNOP7;
121 #endif
122 #endif
123
124 #if 8<=BOUND_DRAW_BUFFER
125 #if BOUND_DRAW_BUFFER == 8
126 layout( location = 8 ) out highp vec4 outFragColor;
127 #else
128 layout( location = 8 ) out highp vec4 outNOP8;
129 #endif
130 #endif
131
132 #if 9<=BOUND_DRAW_BUFFER
133 #if BOUND_DRAW_BUFFER == 9
134 layout( location = 9 ) out highp vec4 outFragColor;
135 #else
136 layout( location = 9 ) out highp vec4 outNOP9;
137 #endif
138 #endif
139
140 #if 10<=BOUND_DRAW_BUFFER
141 #if BOUND_DRAW_BUFFER == 10
142 layout( location = 10 ) out highp vec4 outFragColor;
143 #else
144 layout( location = 10 ) out highp vec4 outNOP10;
145 #endif
146 #endif
147
148 #if 11<=BOUND_DRAW_BUFFER
149 #if BOUND_DRAW_BUFFER == 11
150 layout( location = 11 ) out highp vec4 outFragColor;
151 #else
152 layout( location = 11 ) out highp vec4 outNOP11;
153 #endif
154 #endif
155
156 #if 12<=BOUND_DRAW_BUFFER
157 #if BOUND_DRAW_BUFFER == 12
158 layout( location = 12 ) out highp vec4 outFragColor;
159 #else
160 layout( location = 12 ) out highp vec4 outNOP12;
161 #endif
162 #endif
163
164 #if 13<=BOUND_DRAW_BUFFER
165 #if BOUND_DRAW_BUFFER == 13
166 layout( location = 13 ) out highp vec4 outFragColor;
167 #else
168 layout( location = 13 ) out highp vec4 outNOP13;
169 #endif
170 #endif
171
172 #if 14<=BOUND_DRAW_BUFFER
173 #if BOUND_DRAW_BUFFER == 14
174 layout( location = 14 ) out highp vec4 outFragColor;
175 #else
176 layout( location = 14 ) out highp vec4 outNOP14;
177 #endif
178 #endif
179 #else
180 out highp vec4 outFragColor;
181 #endif
182 #else
183 out vec4 outFragColor;
184 #endif
185 #endif
186
187 # define texture1D texture
188 # define texture2D texture
189 # define texture3D texture
190 # define textureCube texture
191 # define texture2DLod textureLod
192 # define textureCubeLod textureLod
193 # define texture2DArray texture
194 # if defined VERTEX_SHADER
195 # define varying out
196 # define attribute in
197 # elif defined FRAGMENT_SHADER
198 # define varying in
199 # define gl_FragColor outFragColor
200 # endif
201 #else
202 # define isnan(val) !(val<0.0||val>0.0||val==0.0)
203 #endif
204
205 #if __VERSION__ == 110
206 mat3 mat3_sub(mat4 m) {
207 return mat3(m[0].xyz, m[1].xyz, m[2].xyz);
208 }
209 #else
210 #define mat3_sub mat3
211 #endif
212
213 #if __VERSION__ <= 140
214 float determinant(mat2 m) {
215 return m[0][0] * m[1][1] - m[1][0] * m[0][1];
216 }
217
218 float determinant(mat3 m) {
219 return + m[0][0] * (m[1][1] * m[2][2] - m[1][2] * m[2][1])
220 - m[0][1] * (m[1][0] * m[2][2] - m[1][2] * m[2][0])
221 + m[0][2] * (m[1][0] * m[2][1] - m[1][1] * m[2][0]);
222 }
223 #endif
224
225 #if __VERSION__ <= 130
226 mat2 inverse(mat2 m) {
227 return mat2(m[1][1], -m[0][1], -m[1][0], m[0][0]) / determinant(m);
228 }
229
230 mat3 inverse(mat3 m) {
231 return mat3(
232 + (m[1][1] * m[2][2] - m[2][1] * m[1][2]),
233 - (m[1][0] * m[2][2] - m[2][0] * m[1][2]),
234 + (m[1][0] * m[2][1] - m[2][0] * m[1][1]),
235 - (m[0][1] * m[2][2] - m[2][1] * m[0][2]),
236 + (m[0][0] * m[2][2] - m[2][0] * m[0][2]),
237 - (m[0][0] * m[2][1] - m[2][0] * m[0][1]),
238 + (m[0][1] * m[1][2] - m[1][1] * m[0][2]),
239 - (m[0][0] * m[1][2] - m[1][0] * m[0][2]),
240 + (m[0][0] * m[1][1] - m[1][0] * m[0][1])) / determinant(m);
241 }
242 #endif
243 // -- end import Common/ShaderLib/GLSLCompat.glsllib --
244
245 // enable apis and import PBRLightingUtils
246 #define ENABLE_PBRLightingUtils_getWorldPosition 1
247 //#define ENABLE_PBRLightingUtils_getLocalPosition 1
248 #define ENABLE_PBRLightingUtils_getWorldNormal 1
249 #define ENABLE_PBRLightingUtils_getWorldTangent 1
250 #define ENABLE_PBRLightingUtils_getTexCoord 1
251 #define ENABLE_PBRLightingUtils_readPBRSurface 1
252 #define ENABLE_PBRLightingUtils_computeDirectLightContribution 1
253 #define ENABLE_PBRLightingUtils_computeProbesContribution 1
254
255 // -- begin import Common/ShaderLib/module/pbrlighting/PBRLightingUtils.glsllib --
256 #ifndef __PBR_LIGHT_UTILS_MODULE__
257 #define __PBR_LIGHT_UTILS_MODULE__
258
259 // -- begin import Common/ShaderLib/Math.glsllib --
260 #ifndef __MATH_GLSLLIB__
261 #define __MATH_GLSLLIB__
262
263 /// Multiplies the vector by the quaternion, then returns the resultant vector.
264 vec3 Math_QuaternionMult(in vec4 quat, in vec3 vec){
265 return vec + 2.0 * cross(quat.xyz, cross(quat.xyz, vec) + quat.w * vec);
266 }
267
268 void Math_lengthAndNormalize(in vec3 vec,out float outLength,out vec3 outNormal){
269 float dotv=dot(vec,vec);
270 float invl=inversesqrt(dotv);
271 outNormal=vec*invl;
272 outLength=invl*dotv;
273 }
274
275
276 #endif
277 // -- end import Common/ShaderLib/Math.glsllib --
278 // -- begin import Common/ShaderLib/PBR.glsllib --
279 #ifndef PI
280 #define PI 3.14159265358979323846264
281 #endif
282 #ifndef NB_PROBES
283 #define NB_PROBES 0
284 #endif
285
286 // BEGIN-@jhonkkk,Specular AA --------------------------------------------------------------
287 // see:http://www.jp.square-enix.com/tech/library/pdf/ImprovedGeometricSpecularAA(slides).pdf
288 // https://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition@15.0/manual/Geometric-Specular-Anti-Aliasing.html
289 float Specular_Anti_Aliasing(in vec3 normal, in vec3 half_vector,
290 float alpha, in float sigma, in float kappa)
291 {
292
293 vec3 dndu = dFdx(normal);
294 vec3 dndv = dFdy(normal);
295 float variance = sigma*sigma*(dot(dndu, dndu) + dot(dndv, dndv));
296 float kernel_roughness = min(kappa, variance);
297 return sqrt(alpha*alpha + kernel_roughness);
298 }
299 // END-@jhonkkk
300
301
302 //Specular fresnel computation
303 vec3 F_Shlick(float vh, vec3 F0){
304 float fresnelFact = pow(2.0, (-5.55473*vh - 6.98316) * vh);
305 return mix(F0, vec3(1.0, 1.0, 1.0), fresnelFact);
306 }
307
308 vec3 sphericalHarmonics( const in vec3 normal, const vec3 sph[9] ){
309 float x = normal.x;
310 float y = normal.y;
311 float z = normal.z;
312
313 vec3 result = (
314 sph[0] +
315
316 sph[1] * y +
317 sph[2] * z +
318 sph[3] * x +
319
320 sph[4] * y * x +
321 sph[5] * y * z +
322 sph[6] * (3.0 * z * z - 1.0) +
323 sph[7] * (z * x) +
324 sph[8] * (x*x - y*y)
325 );
326
327 return max(result, vec3(0.0));
328 }
329
330 // BEGIN-@jhonkkk,todo:Keeping the original PBR_ComputeDirectLight function signature is for backwards compatibility, but this adds an extra internal function call, theoretically here we should use a macro to define Inner_PBR_ComputeDirectLight, or best to calculate alpha externally and directly call the Inner_PBR_ComputeDirectLight function.
331 float Inner_PBR_ComputeDirectLight(
332 vec3 normal, vec3 halfVec, vec3 lightDir, vec3 viewDir,
333 vec3 lightColor, vec3 fZero, float alpha, float ndotv,
334 out vec3 outDiffuse, out vec3 outSpecular){
335
336 // Compute ndotl, ndoth, vdoth terms which are needed later.
337 float ndotl = max( dot(normal, lightDir), 0.0);
338 float ndoth = max( dot(normal, halfVec), 0.0);
339 float hdotv = max( dot(viewDir, halfVec), 0.0);
340
341 // Compute diffuse using energy-conserving Lambert.
342 // Alternatively, use Oren-Nayar for really rough
343 // materials or if you have lots of processing power ...
344 outDiffuse = vec3(ndotl) * lightColor;
345
346 //cook-torrence, microfacet BRDF : http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf
347
348 //D, GGX normal Distribution function
349 float alpha2 = alpha * alpha;
350 float sum = ((ndoth * ndoth) * (alpha2 - 1.0) + 1.0);
351 float denom = PI * sum * sum;
352 float D = alpha2 / denom;
353
354 // Compute Fresnel function via Schlick's approximation.
355 vec3 fresnel = F_Shlick(hdotv, fZero);
356
357 //G Schlick GGX Geometry shadowing term, k = alpha/2
358 float k = alpha * 0.5;
359
360 /*
361 //classic Schlick ggx
362 float G_V = ndotv / (ndotv * (1.0 - k) + k);
363 float G_L = ndotl / (ndotl * (1.0 - k) + k);
364 float G = ( G_V * G_L );
365
366 float specular =(D* fresnel * G) /(4 * ndotv);
367 */
368
369 // UE4 way to optimise Schlick GGX Geometry shadowing term
370 //http://graphicrants.blogspot.co.uk/2013/08/specular-brdf-reference.html
371 float G_V = ndotv + sqrt( (ndotv - ndotv * k) * ndotv + k );
372 float G_L = ndotl + sqrt( (ndotl - ndotl * k) * ndotl + k );
373 // the max here is to avoid division by 0 that may cause some small glitches.
374 float G = 1.0/max( G_V * G_L ,0.01);
375
376 float specular = D * G * ndotl;
377
378 outSpecular = vec3(specular) * fresnel * lightColor;
379 return hdotv;
380 }
381
382 float PBR_ComputeDirectLight(
383 vec3 normal, vec3 lightDir, vec3 viewDir,
384 vec3 lightColor, vec3 fZero, float roughness, float ndotv,
385 out vec3 outDiffuse, out vec3 outSpecular){
386 // Compute halfway vector.
387 vec3 halfVec = normalize(lightDir + viewDir);
388 return Inner_PBR_ComputeDirectLight(normal, halfVec, lightDir, viewDir,
389 lightColor, fZero, roughness * roughness, ndotv,
390 outDiffuse, outSpecular);
391 }
392
393 float PBR_ComputeDirectLightWithSpecularAA(
394 vec3 normal, vec3 lightDir, vec3 viewDir,
395 vec3 lightColor, vec3 fZero, float roughness, float sigma, float kappa, float ndotv,
396 out vec3 outDiffuse, out vec3 outSpecular){
397 // Compute halfway vector.
398 vec3 halfVec = normalize(lightDir + viewDir);
399 // Specular-AA
400 float alpha = Specular_Anti_Aliasing(normal, halfVec, roughness * roughness, sigma, kappa);
401 return Inner_PBR_ComputeDirectLight(normal, halfVec, lightDir, viewDir,
402 lightColor, fZero, alpha, ndotv,
403 outDiffuse, outSpecular);
404 }
405 // END-@jhonkkk
406
407 vec3 integrateBRDFApprox( const in vec3 specular, float roughness, float NoV ){
408 const vec4 c0 = vec4( -1, -0.0275, -0.572, 0.022 );
409 const vec4 c1 = vec4( 1, 0.0425, 1.04, -0.04 );
410 vec4 r = roughness * c0 + c1;
411 float a004 = min( r.x * r.x, exp2( -9.28 * NoV ) ) * r.x + r.y;
412 vec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw;
413 return specular * AB.x + AB.y;
414 }
415
416 // from Sebastien Lagarde https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf page 69
417 vec3 getSpecularDominantDir(const in vec3 N, const in vec3 R, const in float realRoughness){
418 vec3 dominant;
419
420 float smoothness = 1.0 - realRoughness;
421 float lerpFactor = smoothness * (sqrt(smoothness) + realRoughness);
422 // The result is not normalized as we fetch in a cubemap
423 dominant = mix(N, R, lerpFactor);
424
425 return dominant;
426 }
427
428 vec3 ApproximateSpecularIBL(samplerCube envMap,sampler2D integrateBRDF, vec3 SpecularColor , float Roughness, float ndotv, vec3 refVec, float nbMipMaps){
429 float Lod = sqrt( Roughness ) * (nbMipMaps - 1.0);
430 vec3 PrefilteredColor = textureCubeLod(envMap, refVec.xyz,Lod).rgb;
431 vec2 EnvBRDF = texture2D(integrateBRDF,vec2(Roughness, ndotv)).rg;
432 return PrefilteredColor * ( SpecularColor * EnvBRDF.x+ EnvBRDF.y );
433 }
434
435 vec3 ApproximateSpecularIBLPolynomial(samplerCube envMap, vec3 SpecularColor , float Roughness, float ndotv, vec3 refVec, float nbMipMaps){
436 float Lod = sqrt( Roughness ) * (nbMipMaps - 1.0);
437 vec3 PrefilteredColor = textureCubeLod(envMap, refVec.xyz, Lod).rgb;
438 return PrefilteredColor * integrateBRDFApprox(SpecularColor, Roughness, ndotv);
439 }
440
441
442 float renderProbe(vec3 viewDir, vec3 worldPos, vec3 normal, vec3 norm, float Roughness, vec4 diffuseColor, vec4 specularColor, float ndotv, vec3 ao, mat4 lightProbeData,vec3 shCoeffs[9],samplerCube prefEnvMap, inout vec3 color ){
443
444 // lightProbeData is a mat4 with this layout
445 // 3x3 rot mat|
446 // 0 1 2 | 3
447 // 0 | ax bx cx | px | )
448 // 1 | ay by cy | py | probe position
449 // 2 | az bz cz | pz | )
450 // --|----------|
451 // 3 | sx sy sz sp | -> 1/probe radius + nbMipMaps
452 // --scale--
453 // parallax fix for spherical / obb bounds and probe blending from
454 // from https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/
455 vec3 rv = reflect(-viewDir, normal);
456 vec4 probePos = lightProbeData[3];
457 float invRadius = fract( probePos.w);
458 float nbMipMaps = probePos.w - invRadius;
459 vec3 direction = worldPos - probePos.xyz;
460 float ndf = 0.0;
461
462 if(lightProbeData[0][3] != 0.0){
463 // oriented box probe
464 // mat3_sub our compat wrapper for mat3(mat4)
465 mat3 wToLocalRot = inverse(mat3_sub(lightProbeData));
466
467 vec3 scale = vec3(lightProbeData[0][3], lightProbeData[1][3], lightProbeData[2][3]);
468 #if NB_PROBES >= 2
469 // probe blending
470 // compute fragment position in probe local space
471 vec3 localPos = wToLocalRot * worldPos;
472 localPos -= probePos.xyz;
473 // compute normalized distance field
474 vec3 localDir = abs(localPos);
475 localDir /= scale;
476 ndf = max(max(localDir.x, localDir.y), localDir.z);
477 #endif
478 // parallax fix
479 vec3 rayLs = wToLocalRot * rv;
480 rayLs /= scale;
481
482 vec3 positionLs = worldPos - probePos.xyz;
483 positionLs = wToLocalRot * positionLs;
484 positionLs /= scale;
485
486 vec3 unit = vec3(1.0);
487 vec3 firstPlaneIntersect = (unit - positionLs) / rayLs;
488 vec3 secondPlaneIntersect = (-unit - positionLs) / rayLs;
489 vec3 furthestPlane = max(firstPlaneIntersect, secondPlaneIntersect);
490 float distance = min(min(furthestPlane.x, furthestPlane.y), furthestPlane.z);
491
492 vec3 intersectPositionWs = worldPos + rv * distance;
493 rv = intersectPositionWs - probePos.xyz;
494
495 } else {
496 // spherical probe
497 // parallax fix
498 rv = invRadius * direction + rv;
499
500 #if NB_PROBES >= 2
501 // probe blending
502 float dist = sqrt(dot(direction, direction));
503 ndf = dist * invRadius;
504 #endif
505 }
506
507 vec3 indirectDiffuse = vec3(0.0);
508 vec3 indirectSpecular = vec3(0.0);
509 indirectDiffuse = sphericalHarmonics(normal.xyz, shCoeffs) * diffuseColor.rgb;
510 vec3 dominantR = getSpecularDominantDir( normal, rv.xyz, Roughness * Roughness );
511 indirectSpecular = ApproximateSpecularIBLPolynomial(prefEnvMap, specularColor.rgb, Roughness, ndotv, dominantR, nbMipMaps);
512
513 #ifdef HORIZON_FADE
514 //horizon fade from http://marmosetco.tumblr.com/post/81245981087
515 float horiz = dot(rv, norm);
516 float horizFadePower = 1.0 - Roughness;
517 horiz = clamp( 1.0 + horizFadePower * horiz, 0.0, 1.0 );
518 horiz *= horiz;
519 indirectSpecular *= vec3(horiz);
520 #endif
521
522 vec3 indirectLighting = (indirectDiffuse + indirectSpecular) * ao;
523
524 color = indirectLighting * step( 0.0, probePos.w);
525 return ndf;
526 }
527 // -- end import Common/ShaderLib/PBR.glsllib --
528 // -- begin import Common/ShaderLib/Parallax.glsllib --
529 #if (defined(PARALLAXMAP) || (defined(NORMALMAP_PARALLAX) && defined(NORMALMAP))) && !defined(VERTEX_LIGHTING)
530 vec2 steepParallaxOffset(sampler2D parallaxMap, vec3 vViewDir,vec2 texCoord,float parallaxScale){
531 vec2 vParallaxDirection = normalize( vViewDir.xy );
532
533 // The length of this vector determines the furthest amount of displacement: (Ati's comment)
534 float fLength = length( vViewDir );
535 float fParallaxLength = sqrt( fLength * fLength - vViewDir.z * vViewDir.z ) / vViewDir.z;
536
537 // Compute the actual reverse parallax displacement vector: (Ati's comment)
538 vec2 vParallaxOffsetTS = vParallaxDirection * fParallaxLength;
539
540 // Need to scale the amount of displacement to account for different height ranges
541 // in height maps. This is controlled by an artist-editable parameter: (Ati's comment)
542 parallaxScale *=0.3;
543 vParallaxOffsetTS *= parallaxScale;
544
545 vec3 eyeDir = normalize(vViewDir).xyz;
546
547 float nMinSamples = 6.0;
548 float nMaxSamples = 1000.0 * parallaxScale;
549 float nNumSamples = mix( nMinSamples, nMaxSamples, 1.0 - eyeDir.z ); //In reference shader: int nNumSamples = (int)(lerp( nMinSamples, nMaxSamples, dot( eyeDirWS, N ) ));
550 float fStepSize = 1.0 / nNumSamples;
551 float fCurrHeight = 0.0;
552 float fPrevHeight = 1.0;
553 float fNextHeight = 0.0;
554 float nStepIndex = 0.0;
555 vec2 vTexOffsetPerStep = fStepSize * vParallaxOffsetTS;
556 vec2 vTexCurrentOffset = texCoord;
557 float fCurrentBound = 1.0;
558 float fParallaxAmount = 0.0;
559
560 while ( nStepIndex < nNumSamples && fCurrHeight <= fCurrentBound ) {
561 vTexCurrentOffset -= vTexOffsetPerStep;
562 fPrevHeight = fCurrHeight;
563
564
565 #ifdef NORMALMAP_PARALLAX
566 //parallax map is stored in the alpha channel of the normal map
567 fCurrHeight = texture2D( parallaxMap, vTexCurrentOffset).a;
568 #else
569 //parallax map is a texture
570 fCurrHeight = texture2D( parallaxMap, vTexCurrentOffset).r;
571 #endif
572
573 fCurrentBound -= fStepSize;
574 nStepIndex+=1.0;
575 }
576 vec2 pt1 = vec2( fCurrentBound, fCurrHeight );
577 vec2 pt2 = vec2( fCurrentBound + fStepSize, fPrevHeight );
578
579 float fDelta2 = pt2.x - pt2.y;
580 float fDelta1 = pt1.x - pt1.y;
581
582 float fDenominator = fDelta2 - fDelta1;
583
584 fParallaxAmount = (pt1.x * fDelta2 - pt2.x * fDelta1 ) / fDenominator;
585
586 vec2 vParallaxOffset = vParallaxOffsetTS * (1.0 - fParallaxAmount );
587 return texCoord - vParallaxOffset;
588 }
589
590 vec2 classicParallaxOffset(sampler2D parallaxMap, vec3 vViewDir,vec2 texCoord,float parallaxScale){
591 float h;
592 #ifdef NORMALMAP_PARALLAX
593 //parallax map is stored in the alpha channel of the normal map
594 h = texture2D(parallaxMap, texCoord).a;
595 #else
596 //parallax map is a texture
597 h = texture2D(parallaxMap, texCoord).r;
598 #endif
599 float heightScale = parallaxScale;
600 float heightBias = heightScale* -0.6;
601 vec3 normView = normalize(vViewDir);
602 h = (h * heightScale + heightBias) * normView.z;
603 return texCoord + (h * normView.xy);
604 }
605 #endif
606 // -- end import Common/ShaderLib/Parallax.glsllib --
607
608 // -- begin import Common/ShaderLib/module/Light.glsl --
609 #ifndef __LIGHT_MODULE__
610 #define __LIGHT_MODULE__
611
612 /**
613 * Defines a light
614 */
615
616
617 #ifndef Light
618 #define STRUCT_StdLight \
619 vec4 color; \
620 vec3 position; \
621 float type; \
622 float invRadius; \
623 float spotAngleCos; \
624 vec3 spotDirection; \
625 bool ready; \
626 float NdotL; \
627 float NdotH; \
628 float LdotH; \
629 float HdotV; \
630 vec3 vector; \
631 vec3 dir; \
632 float fallOff;
633 struct StdLight {
634 STRUCT_StdLight
635 };
636 #define Light StdLight
637 #endif
638
639
640
641 #endif
642 // -- end import Common/ShaderLib/module/Light.glsl --
643 // -- begin import Common/ShaderLib/module/PBRSurface.glsl --
644 #ifndef __SURFACE_MODULE__
645 #define __SURFACE_MODULE__
646
647 #ifndef PBRSurface
648 #define STRUCT_StdPBRSurface \
649 \
650 vec3 position; \
651 vec3 viewDir; \
652 vec3 geometryNormal; \
653 vec3 normal; \
654 bool frontFacing; \
655 float depth; \
656 mat3 tbnMat; \
657 bool hasTangents; \
658 \
659 vec3 albedo; \
660 float alpha; \
661 float metallic; \
662 float roughness; \
663 vec3 ao; \
664 vec3 lightMapColor; \
665 bool hasBasicLightMap; \
666 float exposure; \
667 vec3 emission; \
668 \
669 vec3 diffuseColor; \
670 vec3 specularColor; \
671 vec3 fZero; \
672 \
673 float NdotV; \
674 \
675 vec3 bakedLightContribution; \
676 vec3 directLightContribution; \
677 vec3 envLightContribution; \
678 float brightestNonGlobalLightStrength;
679 struct StdPBRSurface {
680 STRUCT_StdPBRSurface
681 };
682 #define PBRSurface StdPBRSurface
683 #endif
684 #endif
685 // -- end import Common/ShaderLib/module/PBRSurface.glsl --
686
687 // enable all apis
688 // #define ENABLE_PBRLightingUtils_getWorldPosition 1
689 // #define ENABLE_PBRLightingUtils_getLocalPosition 1
690 // #define ENABLE_PBRLightingUtils_getWorldNormal 1
691 // #define ENABLE_PBRLightingUtils_getWorldTangent 1
692 // #define ENABLE_PBRLightingUtils_getTexCoord 1
693 // #define ENABLE_PBRLightingUtils_newLight 1
694 // #define ENABLE_PBRLightingUtils_computeLightInWorldSpace 1
695 // #define ENABLE_PBRLightingUtils_readPBRSurface 1
696 // #define ENABLE_PBRLightingUtils_computeDirectLight 1
697 // #define ENABLE_PBRLightingUtils_computeDirectLightContribution 1
698 // #define ENABLE_PBRLightingUtils_computeProbesContribution 1
699
700 #if defined(ENABLE_PBRLightingUtils_readPBRSurface)||defined(ENABLE_PBRLightingUtils_getWorldPosition)
701 varying vec3 wPosition;
702 #endif
703
704 #if defined(ENABLE_PBRLightingUtils_readPBRSurface)||defined(ENABLE_PBRLightingUtils_getWorldNormal)
705 varying vec3 wNormal;
706 #endif
707
708 #if (defined(ENABLE_PBRLightingUtils_readPBRSurface)&&(defined(NORMALMAP)||defined(PARALLAXMAP)))||defined(ENABLE_PBRLightingUtils_getWorldTangent)
709 varying vec4 wTangent;
710 #endif
711
712 #if defined(ENABLE_PBRLightingUtils_readPBRSurface)||defined(ENABLE_PBRLightingUtils_getTexCoord)
713 varying vec2 texCoord;
714 #ifdef SEPARATE_TEXCOORD
715 varying vec2 texCoord2;
716 #endif
717 #endif
718
719 #if defined(ENABLE_PBRLightingUtils_getLocalPosition)
720 varying vec3 lPosition;
721 #endif
722
723
724
725 #ifdef ENABLE_PBRLightingUtils_readPBRSurface
726 varying vec4 Color;
727
728 uniform float m_Roughness;
729 uniform float m_Metallic;
730
731
732 #ifdef BASECOLORMAP
733 uniform sampler2D m_BaseColorMap;
734 #endif
735
736 #ifdef USE_PACKED_MR
737 uniform sampler2D m_MetallicRoughnessMap;
738 #else
739 #ifdef METALLICMAP
740 uniform sampler2D m_MetallicMap;
741 #endif
742 #ifdef ROUGHNESSMAP
743 uniform sampler2D m_RoughnessMap;
744 #endif
745 #endif
746
747 #ifdef EMISSIVE
748 uniform vec4 m_Emissive;
749 #endif
750 #ifdef EMISSIVEMAP
751 uniform sampler2D m_EmissiveMap;
752 #endif
753 #if defined(EMISSIVE) || defined(EMISSIVEMAP)
754 uniform float m_EmissivePower;
755 uniform float m_EmissiveIntensity;
756 #endif
757
758
759
760 #ifdef SPECGLOSSPIPELINE
761 uniform vec4 m_Specular;
762 uniform float m_Glossiness;
763 #ifdef USE_PACKED_SG
764 uniform sampler2D m_SpecularGlossinessMap;
765 #else
766 uniform sampler2D m_SpecularMap;
767 uniform sampler2D m_GlossinessMap;
768 #endif
769 #endif
770
771 #ifdef PARALLAXMAP
772 uniform sampler2D m_ParallaxMap;
773 #endif
774 #if (defined(PARALLAXMAP) || (defined(NORMALMAP_PARALLAX) && defined(NORMALMAP)))
775 uniform float m_ParallaxHeight;
776 #endif
777
778 #ifdef LIGHTMAP
779 uniform sampler2D m_LightMap;
780 #endif
781
782 #ifdef AO_STRENGTH
783 uniform float m_AoStrength;
784 #endif
785
786 #if defined(NORMALMAP) || defined(PARALLAXMAP)
787 uniform sampler2D m_NormalMap;
788 #endif
789 #ifdef NORMALSCALE
790 uniform float m_NormalScale;
791 #endif
792
793 #ifdef DISCARD_ALPHA
794 uniform float m_AlphaDiscardThreshold;
795 #endif
796 #endif
797
798 #if defined(ENABLE_PBRLightingUtils_computeDirectLight) || defined(ENABLE_PBRLightingUtils_computeDirectLightContribution)
799
800 // Specular-AA
801 #ifdef SPECULAR_AA_SCREEN_SPACE_VARIANCE
802 uniform float m_SpecularAASigma;
803 #endif
804 #ifdef SPECULAR_AA_THRESHOLD
805 uniform float m_SpecularAAKappa;
806 #endif
807
808 // DirectionalLight Exposure
809 #if defined(EXPOSUREMAP)
810 uniform sampler2D m_SunLightExposureMap;
811 #endif
812 #if defined(USE_VERTEX_COLORS_AS_SUN_EXPOSURE)
813 varying vec4 vertColors;
814 #endif
815 #ifdef STATIC_SUN_EXPOSURE
816 uniform float m_StaticSunIntensity;
817 #endif
818
819 void PBRLightingUtils_readSunLightExposureParams(inout PBRSurface surface){
820
821 surface.exposure = 1.0; //default value
822 #ifdef EXPOSUREMAP
823 surface.exposure *= texture2D(m_SunLightExposureMap, newTexCoord;
824 #endif
825 #ifdef STATIC_SUN_EXPOSURE
826 surface.exposure *= m_StaticSunIntensity; //single float value to indicate percentage of sunlight hitting the model (only suitable for small models or models with equal sunlight exposure accross the entire model
827 #endif
828 #ifdef USE_VERTEX_COLORS_AS_SUN_EXPOSURE
829 surface.exposure *= vertColors.r; // use red channel of vertexColors for non-uniform sunlighting accross a single model
830 #endif
831 }
832
833 #endif
834
835
836
837 #ifdef ENABLE_PBRLightingUtils_computeProbesContribution
838 #if NB_PROBES >= 1
839 uniform samplerCube g_PrefEnvMap;
840 uniform vec3 g_ShCoeffs[9];
841 uniform mat4 g_LightProbeData;
842 #endif
843 #if NB_PROBES >= 2
844 uniform samplerCube g_PrefEnvMap2;
845 uniform vec3 g_ShCoeffs2[9];
846 uniform mat4 g_LightProbeData2;
847 #endif
848 #if NB_PROBES == 3
849 uniform samplerCube g_PrefEnvMap3;
850 uniform vec3 g_ShCoeffs3[9];
851 uniform mat4 g_LightProbeData3;
852 #endif
853 #endif
854
855 #ifdef ENABLE_PBRLightingUtils_getWorldPosition
856 vec3 PBRLightingUtils_getWorldPosition(){
857 return wPosition.xyz;
858 }
859 #endif
860
861 #ifdef ENABLE_PBRLightingUtils_getWorldNormal
862 vec3 PBRLightingUtils_getWorldNormal(){
863 return normalize(wNormal.xyz);
864 }
865 #endif
866
867 #ifdef ENABLE_PBRLightingUtils_getWorldTangent
868 vec4 PBRLightingUtils_getWorldTangent(){
869 return wTangent;
870 }
871 #endif
872
873 #ifdef ENABLE_PBRLightingUtils_getTexCoord
874 vec2 PBRLightingUtils_getTexCoord(){
875 return texCoord;
876 }
877
878 #ifdef SEPARATE_TEXCOORD
879 vec2 PBRLightingUtils_getTexCoord2(){
880 return texCoord2;
881 }
882 #endif
883 #endif
884
885
886
887 #if defined(ENABLE_PBRLightingUtils_computeDirectLightContribution) || defined(ENABLE_PBRLightingUtils_newLight)
888 Light PBRLightingUtils_newLight(vec4 color, vec3 position, float type, float invRadius, float spotAngleCos, vec3 spotDirection){
889 Light l;
890 l.color = color;
891 l.position = position;
892 l.type = type;
893 l.invRadius = invRadius;
894 l.spotAngleCos = spotAngleCos;
895 l.spotDirection = spotDirection;
896 l.ready = false;
897 return l;
898 }
899 #endif
900
901
902 #if defined(ENABLE_PBRLightingUtils_computeDirectLightContribution) || defined(ENABLE_PBRLightingUtils_computeLightInWorldSpace)
903 void PBRLightingUtils_computeLightInWorldSpace(vec3 worldPos,vec3 worldNormal, vec3 viewDir, inout Light light){
904 if(light.ready) return;
905
906 // lightComputeDir
907 float posLight = step(0.5, light.type);
908 light.vector = light.position.xyz * sign(posLight - 0.5) - (worldPos * posLight); //tempVec lightVec
909
910 vec3 L; // lightDir
911 float dist;
912 Math_lengthAndNormalize(light.vector,dist,L);
913
914 float invRange=light.invRadius; // position.w
915 const float light_threshold = 0.01;
916
917 #ifdef SRGB
918 light.fallOff = (1.0 - invRange * dist) / (1.0 + invRange * dist * dist); // lightDir.w
919 light.fallOff = clamp(light.fallOff, 1.0 - posLight, 1.0);
920 #else
921 light.fallOff = clamp(1.0 - invRange * dist * posLight, 0.0, 1.0);
922 #endif
923
924 // computeSpotFalloff
925 if(light.type>1.){
926 vec3 spotdir = normalize(light.spotDirection);
927 float curAngleCos = dot(-L, spotdir);
928 float innerAngleCos = floor(light.spotAngleCos) * 0.001;
929 float outerAngleCos = fract(light.spotAngleCos);
930 float innerMinusOuter = innerAngleCos - outerAngleCos;
931 float falloff = clamp((curAngleCos - outerAngleCos) / innerMinusOuter, 0.0, 1.0);
932 #ifdef SRGB
933 // Use quadratic falloff (notice the ^4)
934 falloff = pow(clamp((curAngleCos - outerAngleCos) / innerMinusOuter, 0.0, 1.0), 4.0);
935 #endif
936 light.fallOff*=falloff;
937 }
938
939
940 vec3 h=normalize(L+viewDir);
941 light.dir=L;
942 light.NdotL = max(dot(worldNormal, L), 0.0);
943 light.NdotH = max(dot(worldNormal, h), 0.0);
944 light.LdotH = max(dot(L, h), 0.0);
945 light.HdotV = max(dot(viewDir,h), 0.);
946 }
947 #endif
948
949 PBRSurface PBRLightingUtils_createPBRSurface(in vec3 wViewDir){
950
951 PBRSurface surface; //creates a new PBRSurface
952
953 surface.position = wPosition;
954 surface.viewDir = wViewDir;
955 surface.geometryNormal = normalize(wNormal);
956
957 //set default values
958 surface.hasTangents = false;
959 surface.hasBasicLightMap = false;
960 surface.albedo = vec3(1.0);
961 surface.normal = surface.geometryNormal;
962 surface.emission = vec3(0.0);
963 surface.ao = vec3(1.0);
964 surface.lightMapColor = vec3(0.0);
965 surface.alpha = 1.0;
966 surface.roughness = 1.0;
967 surface.metallic = 0.0;
968 surface.alpha = 1.0;
969 surface.exposure = 1.0;
970
971 return surface;
972 }
973
974 #ifdef ENABLE_PBRLightingUtils_readPBRSurface
975 vec2 newTexCoord;
976
977 void PBRLightingUtils_readPBRSurface(inout PBRSurface surface){
978
979 surface.bakedLightContribution = vec3(0.0);
980 surface.directLightContribution = vec3(0.0);
981 surface.envLightContribution = vec3(0.0);
982
983 #ifdef ENABLE_PBRLightingUtils_getWorldTangent
984 vec3 tan = normalize(wTangent.xyz);
985 surface.tbnMat = mat3(tan, wTangent.w * cross( surface.geometryNormal, tan), surface.geometryNormal);
986 surface.hasTangents = true;
987 #endif
988
989
990 #if (defined(PARALLAXMAP) || (defined(NORMALMAP_PARALLAX) && defined(NORMALMAP)))
991 vec3 vViewDir = surface.viewDir * surface.tbnMat;
992 #ifdef STEEP_PARALLAX
993 #ifdef NORMALMAP_PARALLAX
994 //parallax map is stored in the alpha channel of the normal map
995 newTexCoord = steepParallaxOffset(m_NormalMap, vViewDir, texCoord, m_ParallaxHeight);
996 #else
997 //parallax map is a texture
998 newTexCoord = steepParallaxOffset(m_ParallaxMap, vViewDir, texCoord, m_ParallaxHeight);
999 #endif
1000 #else
1001 #ifdef NORMALMAP_PARALLAX
1002 //parallax map is stored in the alpha channel of the normal map
1003 newTexCoord = classicParallaxOffset(m_NormalMap, vViewDir, texCoord, m_ParallaxHeight);
1004 #else
1005 //parallax map is a texture
1006 newTexCoord = classicParallaxOffset(m_ParallaxMap, vViewDir, texCoord, m_ParallaxHeight);
1007 #endif
1008 #endif
1009 #else
1010 newTexCoord = texCoord;
1011 #endif
1012
1013 #ifdef BASECOLORMAP
1014 vec4 baseColor = texture2D(m_BaseColorMap, newTexCoord) * Color;
1015 #else
1016 vec4 baseColor = Color;
1017 #endif
1018
1019 #ifdef DISCARD_ALPHA
1020 if( baseColor.a < m_AlphaDiscardThreshold) discard;
1021 #endif
1022
1023 surface.albedo = baseColor.rgb;
1024 surface.alpha = baseColor.a;
1025
1026 //ao in r channel, roughness in green channel, metallic in blue channel!
1027 vec3 aoRoughnessMetallicValue = vec3(1.0, 1.0, 0.0);
1028 #ifdef USE_PACKED_MR
1029 aoRoughnessMetallicValue = texture2D(m_MetallicRoughnessMap, newTexCoord).rgb;
1030 surface.roughness = aoRoughnessMetallicValue.g * max(m_Roughness, 1e-4);
1031 surface.metallic = aoRoughnessMetallicValue.b * max(m_Metallic, 0.0);
1032 #else
1033 #ifdef ROUGHNESSMAP
1034 surface.roughness = texture2D(m_RoughnessMap, newTexCoord).r * max(m_Roughness, 1e-4);
1035 #else
1036 surface.roughness = max(m_Roughness, 1e-4);
1037 #endif
1038 #ifdef METALLICMAP
1039 surface.metallic = texture2D(m_MetallicMap, newTexCoord).r * max(m_Metallic, 0.0);
1040 #else
1041 surface.metallic = max(m_Metallic, 0.0);
1042 #endif
1043 #endif
1044
1045
1046
1047 #if defined(NORMALMAP)
1048 vec4 normalHeight = texture2D(m_NormalMap, newTexCoord);
1049 // Note we invert directx style normal maps to opengl style
1050 #ifdef NORMALSCALE
1051 vec3 normal = normalize((normalHeight.xyz * vec3(2.0, NORMAL_TYPE * 2.0, 2.0) - vec3(1.0, NORMAL_TYPE * 1.0, 1.0)) * vec3(m_NormalScale, m_NormalScale, 1.0));
1052 #else
1053 vec3 normal = normalize((normalHeight.xyz * vec3(2.0, NORMAL_TYPE * 2.0, 2.0) - vec3(1.0, NORMAL_TYPE * 1.0, 1.0)));
1054 #endif
1055 surface.normal = normalize(surface.tbnMat * normal);
1056 #else
1057 surface.normal = surface.geometryNormal;
1058 #endif
1059
1060 //spec gloss tex reads:
1061
1062 #ifdef SPECGLOSSPIPELINE
1063 #ifdef USE_PACKED_SG
1064 vec4 specularColor = texture2D(m_SpecularGlossinessMap, newTexCoord);
1065 float glossiness = specularColor.a * m_Glossiness;
1066 specularColor *= m_Specular;
1067 #else
1068 #ifdef SPECULARMAP
1069 vec4 specularColor = texture2D(m_SpecularMap, newTexCoord);
1070 #else
1071 vec4 specularColor = vec4(1.0);
1072 #endif
1073 #ifdef GLOSSINESSMAP
1074 float glossiness = texture2D(m_GlossinesMap, newTexCoord).r * m_Glossiness;
1075 #else
1076 float glossiness = m_Glossiness;
1077 #endif
1078 specularColor *= m_Specular;
1079 surface.specularColor = specularColor;
1080 #endif
1081 #endif
[...470 lines deleted ...]
1552 gl_FragColor = PBRLightingUtils_getColorOutputForDebugMode(m_DebugValuesMode, vec4(gl_FragColor.rgba), surface);
1553 #endif
1554 }
Mar 05, 2025 11:19:00 AM com.jme3.app.LegacyApplication handleError
SEVERE: Uncaught exception thrown in Thread[jME3 Main,5,main]
com.jme3.renderer.RendererException: compile error in: ShaderSource[name=Common/MatDefs/Light/PBRLighting.frag, defines, type=Fragment, language=GLSL150]
0(1079) : error C7011: implicit cast from "vec4" to "vec3"
at com.jme3.renderer.opengl.GLRenderer.updateShaderSourceData(GLRenderer.java:1659)
at com.jme3.renderer.opengl.GLRenderer.updateShaderData(GLRenderer.java:1686)
at com.jme3.renderer.opengl.GLRenderer.setShader(GLRenderer.java:1751)
at com.jme3.material.logic.SinglePassAndImageBasedLightingLogic.render(SinglePassAndImageBasedLightingLogic.java:277)
at com.jme3.material.Technique.render(Technique.java:168)
at com.jme3.material.Material.render(Material.java:1099)
at com.jme3.renderer.RenderManager.renderGeometry(RenderManager.java:842)
at com.jme3.renderer.RenderManager.renderGeometry(RenderManager.java:772)
at com.jme3.renderer.queue.RenderQueue.renderGeometryList(RenderQueue.java:273)
at com.jme3.renderer.queue.RenderQueue.renderQueue(RenderQueue.java:315)
at com.jme3.renderer.RenderManager.renderViewPortQueues(RenderManager.java:1117)
at com.jme3.renderer.RenderManager.flushQueue(RenderManager.java:1012)
at com.jme3.renderer.pipeline.ForwardPipeline.pipelineRender(ForwardPipeline.java:117)
at com.jme3.renderer.RenderManager.renderViewPort(RenderManager.java:1313)
at com.jme3.renderer.RenderManager.render(RenderManager.java:1355)
at com.jme3.app.SimpleApplication.update(SimpleApplication.java:283)
at com.jme3.system.lwjgl.LwjglWindow.runLoop(LwjglWindow.java:707)
at com.jme3.system.lwjgl.LwjglWindow.run(LwjglWindow.java:797)
at java.base/java.lang.Thread.run(Thread.java:840)
Mar 05, 2025 11:19:00 AM com.jme3.system.JmeSystemDelegate lambda$new$0
WARNING: JmeDialogsFactory implementation not found.
Uncaught exception thrown in Thread[jME3 Main,5,main]
RendererException: compile error in: ShaderSource[name=Common/MatDefs/Light/PBRLighting.frag, defines, type=Fragment, language=GLSL150]
0(1079) : error C7011: implicit cast from "vec4" to "vec3"
```