Bug with the compilation of the terrainlighting shader

Hello everybody, i got a “strange” bug.
Context : i am using the endless terrain generation, i wanted to add a light thing on it, so i switched from the HeightBasedTerrain.j3md to the TerrainLighting.j3md. Except for textures parameters (i had to change them), it works.

But, when i set one or more “NormalMap”, i got an error:

févr. 15, 2014 4:02:39 PM com.jme3.renderer.lwjgl.LwjglRenderer updateShaderSourceData WARNING: Bad compile of:

[HUGE piece of code, 665 lines of codes]

févr. 15, 2014 4:02:39 PM com.jme3.app.Application handleError
SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
com.jme3.renderer.RendererException: compile error in:ShaderSource[name=Common/MatDefs/Terrain/TerrainLighting.frag, defines, type=Fragment, language=GLSL100] error:Fragment shader failed to compile with the following errors:
ERROR: 0:640: error(#143) Undeclared identifier: calculateNormal
ERROR: 0:640: error(#202) No matching overloaded function found: calculateNormal
WARNING: 0:640: warning(#402) Implicit truncation of vector from size: 1 to size: 3
ERROR: error(#273) 2 compilation errors. No code generated

I tried to use a normal map from here : http://www.tutorialsforblender3d.com/Textures/Sand/Sand_Normal_1.html

The strange thing is the “language=GLSL100” in the message, and we have “// NOTE: Doesn’t support OpenGL1” at the beginning of the file. I am maybe doing something wrong, but i don’t think that the error comes from me.

BTW, any news about a heightbased shader (for terrains) that supports lighting ? I know that the author of the existing height-based shader didn’t finish his shader (and will likely never finish it) but maybe someone else did an other one ? Anyway, this is not the topic, don’t bother with this last question.

“[HUGE piece of code, 665 lines of codes]”

It would be useful to see line 640 in that “huge piece of code”. The reason the whole shader gets logged is so that the error line number can be matched to the actual shader line number after the includes, etc. have been expanded.

1 Like

well, the line 640 is blank, so …

you already have the code (it’s the code in jme, in the jme-terrain.jar file, in Common/MatDefs/Terrain/TerrainLighting.frag ).

Well, i’ll keep investigating on this.

@bubuche said: well, the line 640 is blank, so ...

you already have the code (it’s the code in jme, in the jme-terrain.jar file, in Common/MatDefs/Terrain/TerrainLighting.frag ).

Well, i’ll keep investigating on this.

I think you misunderstand. The code as in svn is useless unless I run it and get the same error.

The dump of the code in the log has expanded all of the included libraries, etc. and so the line numbers help track down the error that the shader compiler gives. I can guarantee you 10000% that line 640 was not blank.

Though I guess the “Undeclared identifier: calculateNormal” is pretty clear. We might have to see the whole dump so as to compare it to the unexpanded shader to see what #defines or whatever are wrong.

Well sorry, i thought you was talking about the line in the file where the line is effectively blank.

Ok, the line 640 is

vec3 normal = calculateNormal(texCoord);

in the block

[java]
//---------------------
634 // normal calculations
635 //---------------------
636 #if defined(NORMALMAP) || defined(NORMALMAP_1) || defined(NORMALMAP_2) || defined(NORMALMAP_3) || defined(NORMALMAP_4) || defined(NORMALMAP_5) || defined(NORMALMAP_6) || defined(NORMALMAP_7) || defined(NORMALMAP_8) || defined(NORMALMAP_9) || defined(NORMALMAP_10) || defined(NORMALMAP_11)
637 #ifdef TRI_PLANAR_MAPPING
638 vec3 normal = calculateNormalTriPlanar(wNormal, wVertex, texCoord);
639 #else
640 vec3 normal = calculateNormal(texCoord);
641 #endif
642 #else
643 vec3 normal = vNormal;
644 #endif[/java]

if you still don’t have enough information, i’ll use pastebin.
btw, i tried (now) to enable the triplanar, and i get the same error (except the line that point to
[java]
vec3 normal = calculateNormalTriPlanar(wNormal, wVertex, texCoord);
[/java])

function where this code is :

[java]
596 void main(){
597
598 //----------------------
599 // diffuse calculations
600 //----------------------
601 #ifdef DIFFUSEMAP
602 #ifdef ALPHAMAP
603 #ifdef TRI_PLANAR_MAPPING
604 vec4 diffuseColor = calculateTriPlanarDiffuseBlend(wNormal, wVertex, texCoord);
605 #else
606 vec4 diffuseColor = calculateDiffuseBlend(texCoord);
607 #endif
608 #else
609 vec4 diffuseColor = texture2D(m_DiffuseMap, texCoord);
610 #endif
611 #else
612 vec4 diffuseColor = vec4(1.0);
613 #endif
614
615 float spotFallOff = 1.0;
616 if(g_LightDirection.w!=0.0){
617 vec3 L=normalize(lightVec.xyz);
618 vec3 spotdir = normalize(g_LightDirection.xyz);
619 float curAngleCos = dot(-L, spotdir);
620 float innerAngleCos = floor(g_LightDirection.w) * 0.001;
621 float outerAngleCos = fract(g_LightDirection.w);
622 float innerMinusOuter = innerAngleCos - outerAngleCos;
623
624 spotFallOff = (curAngleCos - outerAngleCos) / innerMinusOuter;
625
626 if(spotFallOff <= 0.0){
627 gl_FragColor = AmbientSum * diffuseColor;
628 return;
629 }else{
630 spotFallOff = clamp(spotFallOff, 0.0, 1.0);
631 }
632 }
633
634 //---------------------
635 // normal calculations
636 //---------------------
637 #if defined(NORMALMAP) || defined(NORMALMAP_1) || defined(NORMALMAP_2) || defined(NORMALMAP_3) || defined(NORMALMAP_4) || defined(NORMALMAP_5) || defined(NORMALMAP_6) || defined(NORMALMAP_7) || defined(NORMALMAP_8) || defined(NORMALMAP_9) || defined(NORMALMAP_10) || defined(NORMALMAP_11)
638 #ifdef TRI_PLANAR_MAPPING
639 vec3 normal = calculateNormalTriPlanar(wNormal, wVertex, texCoord);
640 #else
641 vec3 normal = calculateNormal(texCoord);
642 #endif
643 #else
disconnected !
644 vec3 normal = vNormal;
645 #endif
646
647
648 //-----------------------
649 // lighting calculations
650 //-----------------------
651 vec4 lightDir = vLightDir;
652 lightDir.xyz = normalize(lightDir.xyz);
653
654 vec2 light = computeLighting(vPosition, normal, vViewDir.xyz, lightDir.xyz)*spotFallOff;
655
656 vec4 specularColor = vec4(1.0);
657
658 //--------------------------
659 // final color calculations
660 //--------------------------
661 gl_FragColor = AmbientSum * diffuseColor +
662 DiffuseSum * diffuseColor * light.x +
663 SpecularSum * specularColor * light.y;
664
665 //gl_FragColor.a = alpha;
666 }
[/java]

Seems like something it needs (included/imported/whatever) has been left out or has changed since this code was written I guess.

ok, i found (i really think) the problem.

the incrimined function “calculatenormal” is defined in the file as i said, but it’s definition only occurs when an alpha map is defined… for a reason i don’t really understand.

to make it clear :

you have this
[java]
#ifdef ALPHAMAP


vec3 calculateNormal(in vec2 texCoord) {

}


#endef
[java]
now i need to test if everything is fine, especially if the normal map is correctly applied. I think that yes, but i really need to make 2 screenshot to compare them back to bakc to avoid the “placebo” effect.

But i am very tired right now (8:28 am, i worked all the night :slight_smile: ) so i’ll do more test this evening.

And i think that it could deserves either a fix or some documentation :wink: