INSTANCES define not consistent on shader compilation

EDIT :

It was not clear why the shader store saved a different file version, so I decided to investigate the bundle itself. I finally discovered that it was modified during the publication process on the web. Fixing the transfer mode resolved the issue. However, there are still some issue if unexpected ASCII characters encountered during the shader node process/parsing. We may need to investigate this further to avoid such issues during basic web deployment operations.

Thanks, everyone, for the support.

This demo is not quite perfect, but I encourage you to check the statistics about the frame rate. For example, there are only 2 draw calls and room for enhancement. This is a very good basis for Babylon Map.

Here is the link to the demo.

The map is hosted on an interactive display surface that tracks your inputs. Here’s how to navigate the map:

  • Dragging the Map:Click and hold the left mouse button to drag the map.
  • Rotating the Map:Click and hold the right mouse button to rotate the map.
  • Zooming:Use the mouse wheel to zoom in and out when the pointer is over the map.

Hello,

I have written a custom shader that extends PushMaterial. Since I use instances heavily, I defined INSTANCES within it using the common MaterialDefines class. Everything works well in Visual Studio Code with various browsers. I have included the necessary instancesDeclaration and instancesVertex includes, and the generated shader is correct and work as expected
here the generated file

// Important Note: This file has been generated as part of the build process.
// Therefore, any manual changes made to this file will be overridden by the next build.
// We strongly advise against editing this file directly, as it may cause unintended consequences and affect the final product.
import { ShaderStore } from "@babylonjs/core";
const name = "webmapVertexShader";
const shader = `#include<instancesDeclaration>
#include<clipVertexDeclaration>
#include<lightVertexDeclaration>
#include<elevationVertexDeclaration>
uniform mat4 viewProjection;
in vec3 position; 
in vec2 uv; 
#if defined(FLAT_SHADING) || defined(GOUREAUD_SHADING)
uniform vec4 uTerrainColor;
#endif
out vec3 vUvs;
void main(void) {
#include<instancesVertex>
float depth=demIds[int(position.z)] ;
vec3 v=vec3(uv.xy,depth);
if( depth<0.0) {
v.x=v.x==0.0 ? 1.0 : v.x;
v.y=v.y==0.0 ? 1.0 : v.y; 
v.z=depth=demIds[0];
} 
float rawAltitude=float(texture(uAltitudes,v)) ;
float alt=(rawAltitude -uAltRange.x)*uMapScale;
vec4 pos=vec4(position.xy,alt,1.0);
vec4 worldPosition=finalWorld*pos;
vec4 pixel=texture(uNormals,v);
vec3 rawNormal=elevation_rgbaToNormal(pixel);
vec3 worldNormal=vec3(-rawNormal.x,rawNormal.z,rawNormal.y); 
#if defined(FLAT_SHADING) || defined(GOUREAUD_SHADING)
#if defined(SPECULAR)
vec3 lightColor=calculateLight(uAmbientLight,uHemiLight,uPointLights,uNumPointLights,uSpotLights,uNumSpotLights,worldNormal,worldPosition.xyz,uViewPosition,uShininess);
#else
vec3 lightColor=calculateLight(uAmbientLight,uHemiLight,uPointLights,uNumPointLights,uSpotLights,uNumSpotLights,worldNormal,worldPosition.xyz);
#endif
vColor= vec4(uTerrainColor.rgb*lightColor,uTerrainColor.a);
#endif
#if defined(PHONG_SHADING) || defined (BLINN_PHONG_SHADING)
vNormal=worldNormal;
vPosition=worldPosition.xyz;
#endif
#include<clipVertex>
gl_Position=viewProjection*worldPosition;
vUvs=vec3(- position.xy+0.5,demIds[0]);
}`;
ShaderStore.ShadersStore[name] = shader;
/** @internal */ export const webmapVertexShader = { name, shader };

However, once I deploy it on the web or try to use it in the playground, the compilation does not take the INSTANCES define into account for the instancesVertex include ONLY. This results in an inconsistent shader, producing a buggy mat4 finalWorld = world; instead of correctly handling the instance declarations.

For example, the expected instance declarations output attributes like:

attribute vec4 world0;
attribute vec4 world1;
attribute vec4 world2;
attribute vec4 world3;

...

mat4 finalWorld=mat4(world0,world1,world2,world3);

Due to this inconsistency, i obtain

attribute vec4 world0;
attribute vec4 world1;
attribute vec4 world2;
attribute vec4 world3;

...

mat4 finalWorld = world;

And the shader fails to compile.

Below is the output from the console

#define WEBGL2 
#define BLINN_PHONG_SHADING
#define MAX_SPOT_LIGHTS 3
#define MAX_POINT_LIGHTS 3
#define CLIP_PLANES
#define INSTANCES

#define SHADER_NAME vertex:webmap
precision highp float;
in vec4 world0;
in vec4 world1;
in vec4 world2;
in vec4 world3;
struct Plane {vec3 point;
vec3 normal;
};
float clipDistance(vec3 worldPos,Plane plane ){vec3 p=worldPos-plane.point;
return dot(p,plane.normal);
} uniform Plane uNorthClip;
uniform Plane uSouthClip;
uniform Plane uEastClip;
uniform Plane uWestClip;
out vec4 vfClipDistance;
out vec3 vNormal;
out vec3 vPosition;
vec3 elevation_rgbaToNormal(vec4 rgba) {float x=(2.0*rgba.r)-1.0;
float y=(2.0*rgba.g)-1.0;
float z=(rgba.b*255.0-128.0)/127.0;
return normalize(vec3(x,y,z));
}uniform highp sampler2DArray uAltitudes;
uniform highp sampler2DArray uNormals;
uniform highp vec2 uAltRange;
uniform highp float uMapScale;
in vec4 demIds;
uniform mat4 viewProjection;
in vec3 position;
in vec2 uv;
out vec3 vUvs;
mat4 finalWorld=world;
float depth=demIds[int(position.z)];
vec3 v=vec3(uv.xy,depth);
...
babylon.js:1 BJS - [17:59:21]: Error: VERTEX SHADER ERROR: 0:40: 'world' : undeclared identifier

Anyone ever encounter this behavior ??
this is how it’s look like when working

Do you see any network error? Also this may be an issue with reaching the shader includes

Any way to repro inthe PG?

here the playground
The only error i get are from the tile server using non secure http connection.
Update : I just introduce “https” scheme to get rideof these network error but this change nothing regarding the shader compilation.

fragment is also completely out. It does not even have the main function

This is most likely related to a problem with the imports of the shader includes

Can you unroll the shader and the js code in the PG? I would like to debug it

there is a LOT of code… :grimacing:
i do not know how to put this onto the PG. You already have access to the GIT, main branch.

yeah that’s my issue ;D

It is super hard to debug now (unless I spend the day on it :frowning: )

The thing is if that is working on your local machine I assume it is related to UMD build.
Can you try to run it locally but with the babylon.js file directly? not using source code of babylon

1 Like

I put the latest Babylon.js from the CDN into my local libs folder, and it’s working. I may try using the minified version or the online version next. I’ll attempt to reproduce the issue locally.
EDIT 1 :

EDIT 1: I started debugging. All includes are correctly loaded, but the error seems to be within the function:
function _ProcessShaderConversion(sourceCode: string, options: ProcessingOptions, engine?: AbstractEngine): string
The input is correct, but the output is buggy. It appears that the issue lies in the parsing of #ifdef or #if defined().

EDIT 2 : don’t know why this issue occurs online but not locally with VS Code. The preprocessor is not being handled correctly within the nodes.
image
The problem arises from a parsed line that, for some reason, becomes:
void main(void){#ifdef INSTANCES
which is not what i have in my shader code…

keep you update.

1 Like