Error compiling Gaussian Splat node material

I have been struggling to get a bug squashed surrounding node materials and a gaussian splat.

I am attempting to apply this transition when splats load in my platform - https://playground.babylonjs.com/#CID4NN#264

Here is the node material - Babylon.js Node Material Editor

When I apply this in my app, I get errors.

Here is the code in my app-

    if (fileExtension === ".splat" || fileExtension === ".ply" || fileExtension === '.spz') {
      const nodeMaterial = await NodeMaterial.ParseFromFileAsync('nodeMat', 'https://firebasestorage.googleapis.com/v0/b/story-splat.firebasestorage.app/o/public%2Fmaterials%2FsplatFadeNodeMaterial.json?alt=media&token=00ea0eea-ea77-40bf-9f98-ed9bc54c25f9', scene)
      newMeshes.forEach((mesh) => {
            mesh.material = nodeMaterial;
        });
    }

Error below -

logger.ts:107 BJS - [19:02:39]: Build of NodeMaterial failed:
input vector from block VertexOutput[VertexOutputBlock] is not connected and is not optional.
input left from block Add[AddBlock] is not connected and is not optional.
input left from block Add[AddBlock] is not connected and is not optional.

Following Errors

Summary

BJS - [19:02:40]: Unable to compile effect:

logger.ts:107 BJS - [19:02:40]: Uniforms: u_Float, u_Time, u_Float1, u_Float2, u_Float3

logger.ts:107 BJS - [19:02:40]: Vertex code:

logger.ts:107 BJS - [19:02:40]: #version 300 es
#define WEBGL2
#define PREPASS_NORMAL_INDEX -1
#define PREPASS_WORLD_NORMAL_INDEX -1
#define PREPASS_POSITION_INDEX -1
#define PREPASS_LOCAL_POSITION_INDEX -1
#define PREPASS_DEPTH_INDEX -1
#define PREPASS_SCREENSPACE_DEPTH_INDEX -1
#define SCENE_MRT_COUNT 0
#define NUM_BONE_INFLUENCERS 0
#define BonesPerMesh 0
#define NUM_MORPH_INFLUENCERS 0
#define TONEMAPPING 0
#define BUMPDIRECTUV 0
#define CAMERA_PERSPECTIVE

#define SHADER_NAME fragment:nodeMaterial1
precision highp sampler2DArray;
precision highp float;
uniform float u_Float;
uniform float u_Time;
uniform float u_Float1;
uniform float u_Float2;
uniform float u_Float3;
const float PI=3.1415926535897932384626433832795;
const float RECIPROCAL_PI=0.3183098861837907;
const float RECIPROCAL_PI2=0.15915494309189535;
const float HALF_MIN=5.96046448e-08;
const float LinearEncodePowerApprox=2.2;
const float GammaEncodePowerApprox=1.0/LinearEncodePowerApprox;
const vec3 LuminanceEncodeApprox=vec3(0.2126,0.7152,0.0722);
const float Epsilon=0.0000001;
#define saturate(x) clamp(x,0.0,1.0)
#define absEps(x) abs(x)+Epsilon
#define maxEps(x) max(x,Epsilon)
#define saturateEps(x) clamp(x,Epsilon,1.0)
mat3 transposeMat3(mat3 inMatrix) {vec3 i0=inMatrix[0];
vec3 i1=inMatrix[1];
vec3 i2=inMatrix[2];
mat3 outMatrix=mat3(
vec3(i0.x,i1.x,i2.x),
vec3(i0.y,i1.y,i2.y),
vec3(i0.z,i1.z,i2.z)
);
return outMatrix;
}
mat3 inverseMat3(mat3 inMatrix) {float a00=inMatrix[0][0],a01=inMatrix[0][1],a02=inMatrix[0][2];
float a10=inMatrix[1][0],a11=inMatrix[1][1],a12=inMatrix[1][2];
float a20=inMatrix[2][0],a21=inMatrix[2][1],a22=inMatrix[2][2];
float b01=a22a11-a12a21;
float b11=-a22a10+a12a20;
float b21=a21a10-a11a20;
float det=a00b01+a01b11+a02b21;
return mat3(b01,(-a22
a01+a02a21),(a12a01-a02a11),
b11,(a22
a00-a02a20),(-a12a00+a02a10),
b21,(-a21
a00+a01a20),(a11a00-a01a10))/det;
}
float toLinearSpace(float color)
{
return pow(color,LinearEncodePowerApprox);
}
vec3 toLinearSpace(vec3 color)
{
return pow(color,vec3(LinearEncodePowerApprox));
}
vec4 toLinearSpace(vec4 color)
{
return vec4(pow(color.rgb,vec3(LinearEncodePowerApprox)),color.a);
}
float toGammaSpace(float color)
{
return pow(color,GammaEncodePowerApprox);
}
vec3 toGammaSpace(vec3 color)
{
return pow(color,vec3(GammaEncodePowerApprox));
}
vec4 toGammaSpace(vec4 color)
{
return vec4(pow(color.rgb,vec3(GammaEncodePowerApprox)),color.a);
}
float square(float value)
{return value
value;
}
vec3 square(vec3 value)
{return valuevalue;
}
float pow5(float value) {float sq=value
value;
return sqsqvalue;
}
float getLuminance(vec3 color)
{return clamp(dot(color,LuminanceEncodeApprox),0.,1.);
}
float getRand(vec2 seed) {return fract(sin(dot(seed.xy ,vec2(12.9898,78.233)))43758.5453);
}
float dither(vec2 seed,float varianceAmount) {float rand=getRand(seed);
float normVariance=varianceAmount/255.0;
float dither=mix(-normVariance,normVariance,rand);
return dither;
}
const float rgbdMaxRange=255.0;
vec4 toRGBD(vec3 color) {float maxRGB=maxEps(max(color.r,max(color.g,color.b)));
float D =max(rgbdMaxRange/maxRGB,1.);
D =clamp(floor(D)/255.0,0.,1.);
vec3 rgb=color.rgb
D;
rgb=toGammaSpace(rgb);
return vec4(clamp(rgb,0.,1.),D);
}
vec3 fromRGBD(vec4 rgbd) {rgbd.rgb=toLinearSpace(rgbd.rgb);
return rgbd.rgb/rgbd.a;
}
vec3 parallaxCorrectNormal( vec3 vertexPos,vec3 origVec,vec3 cubeSize,vec3 cubePos ) {vec3 invOrigVec=vec3(1.0,1.0,1.0)/origVec;
vec3 halfSize=cubeSize*0.5;
vec3 intersecAtMaxPlane=(cubePos+halfSize-vertexPos)*invOrigVec;
vec3 intersecAtMinPlane=(cubePos-halfSize-vertexPos)invOrigVec;
vec3 largestIntersec=max(intersecAtMaxPlane,intersecAtMinPlane);
float distance=min(min(largestIntersec.x,largestIntersec.y),largestIntersec.z);
vec3 intersectPositionWS=vertexPos+origVec
distance;
return intersectPositionWS-cubePos;
}
layout(location = 0) out vec4 glFragColor;
void main(void) {
float output6 = sin(u_Time);
float output5 = output6 * u_Float1;
float output4 = + output5;
float output3 = clamp(output4, (0.0), (1.0));
float output2 = smoothstep(float(u_Float2), float(u_Float3), output3);
float output1 = u_Float - output2;
float output0 = + output1;
glFragColor = vec4(output0, output0, output0, 1.0);
}

logger.ts:107 BJS - [19:02:40]: Offending line [26] in vertex code: gl_Position = ;

logger.ts:107 BJS - [19:02:40]: Error: VERTEX SHADER ERROR: 0:26: ‘;’ : syntax error

It is really hard to tell without a repro in the playground, but it feels like some nodes are missing in your case ? Are you using the latest version ?

yeah I am using version 7.42.0, and loading the exact same JSON file in both cases. I have tried deleting node_modules and reinstalling them.

This is a react app if that matters at all

Here is more of my code for some context, it is doing nothing fancy at all here

let result: ISceneLoaderAsyncResult;
let isLocal = false;

// Configure loading options with progress tracking
const loadingOptions = {
  onProgress: (event: ISceneLoaderProgressEvent) => {
    if (onProgress && event.lengthComputable) {
      const progressPercent = (event.loaded / event.total) * 100;
      console.log("Loading progress:", progressPercent.toFixed(2) + "%");
      onProgress(progressPercent);
    }
  }
};

if (typeof fileOrUrl === "string") {
  console.log("Loading model from URL:", fileOrUrl);
  // Load from URL with progress tracking
  result = await SceneLoader.ImportMeshAsync("", fileOrUrl, "", scene, loadingOptions.onProgress);
  isLocal = false;
} else {
  console.log("Loading model from file:", fileOrUrl.name);
  result = await SceneLoader.ImportMeshAsync("", "", fileOrUrl, scene, loadingOptions.onProgress);
  isLocal = true;
}

const newMeshes = result.meshes;
newMeshes.forEach((mesh) => {
  if (mesh instanceof Mesh) {
    mesh.position = Vector3.Zero();
  }
});

//if mesh type === splat apply node material to the mesh
if (fileExtension === ".splat" || fileExtension === ".ply" || fileExtension === ".spz") {
  const nodeMaterial = await NodeMaterial.ParseFromFileAsync('nodeMat', 'https://firebasestorage.googleapis.com/v0/b/story-splat.firebasestorage.app/o/public%2Fmaterials%2FsplatFadeNodeMaterial.json?alt=media&token=00ea0eea-ea77-40bf-9f98-ed9bc54c25f9', scene)
  newMeshes.forEach((mesh) => {
        mesh.material = nodeMaterial;
    });
}

Appreciate any ideas you have that I can explore as a solution

A repro even on Github would be necessary in your case unfortunately

I can do that and link it here shortly

FYI I am struggling to reproduce it, it works in an isolated repo. It must be something with my current set up for StorySplat that is causing problems. I will fix this and report back here for others with the same issue in the future

@sebavan I was able to get it to work running npm start directly, so the issue lies within my docker container for some reason. I will report back here with a final solution.

Well, I deleted my docker container completely and restarted it, and it worked. I think at one point I installed a version of Babylon by mistake that was conflicting with the @babylonjs/core installation. I fixed it but docker held onto it.

1 Like

can you share the final result, i think im trying to do something similar, this might be the answer

Storysplat.com uses it now, check out the discover page Story Splat - Interactive 3D Story Creation with Gaussian Splats

1 Like