I need help with setting material using glsl

I am making the simple babylon.js project that can set base texture, pattern overlay texture, pattern tint, lightmap of sphere using glsl.
I tried it but it doesn’t work.
I can see only base texture.
Please help me.
This is glsl code.

var customMaterial = new BABYLON.ShaderMaterial(
    "customShader",
    scene,
    {
        vertex: "custom",
        fragment: "custom",
    },
    {
        attributes: ["position", "normal", "uv"],
        uniforms: ["world", "worldView", "worldViewProjection", "view", "projection", "time",
                  "baseTexture", "overlayTexture", "lightmapTexture", "tintColor"]
    }
);

// GLSL Shader code
BABYLON.Effect.ShadersStore["customVertexShader"] = `
    precision highp float;
    attribute vec3 position;
    attribute vec3 normal;
    attribute vec2 uv;
    uniform mat4 worldViewProjection;
    varying vec2 vUV;
    varying vec3 vNormal;
    void main() {
        gl_Position = worldViewProjection * vec4(position, 1.0);
        vUV = uv;
        vNormal = normal;
    }
`;

BABYLON.Effect.ShadersStore["customFragmentShader"] = `
    precision highp float;
    varying vec2 vUV;
    varying vec3 vNormal;
    uniform sampler2D baseTexture;
    uniform sampler2D overlayTexture;
    uniform sampler2D lightmapTexture;
    uniform vec3 tintColor;
    
    void main() {
        // Sample textures with proper UV clamping
        vec4 baseColor = texture2D(baseTexture, clamp(vUV, 0.0, 1.0));
        vec4 overlay = texture2D(overlayTexture, clamp(vUV, 0.0, 1.0));
        vec4 lightmap = texture2D(lightmapTexture, clamp(vUV, 0.0, 1.0));
        
        // Create tinted overlay by multiplying pattern with tint color
        vec3 tintedOverlay = overlay.rgb * tintColor;
        
        // Combine base and tinted overlay using overlay blend mode
        vec3 blendedColor;
        for(int i = 0; i < 3; i++) {
            float base = baseColor.rgb[i];
            float blend = tintedOverlay[i];
            if(base < 0.5) {
                blendedColor[i] = 2.0 * base * blend;
            } else {
                blendedColor[i] = 1.0 - 2.0 * (1.0 - base) * (1.0 - blend);
            }
        }
        
        // Mix based on overlay alpha
        vec3 colorWithOverlay = mix(baseColor.rgb, blendedColor, overlay.a);
        
        // Apply lightmap
        vec3 finalColor = colorWithOverlay * lightmap.rgb;
        
        // Output final color with base texture alpha
        gl_FragColor = vec4(finalColor, baseColor.a);
    }
`;

// Set initial textures
customMaterial.setTexture("baseTexture", new BABYLON.Texture('./assets/img/model.png', scene));
customMaterial.setTexture("overlayTexture", new BABYLON.Texture('./assets/img/circleTexture.png', scene));
customMaterial.setTexture("lightmapTexture", new BABYLON.Texture('./assets/img/model.png', scene)); // Adding missing lightmap texture
customMaterial.setVector3("tintColor", new BABYLON.Color3('#ff0000'));
1 Like

Hi! can you try to reproduce this on the babylon playground

It’ll be easier to reason about it, debug and make changes that way : )

2 Likes

I don’t know that how can upload image for texture.
I’ll send project to you.
Please send me contact info.

Here is some doc to use your images in the PG:

https://doc.babylonjs.com/toolsAndResources/thePlayground/externalPGAssets

3 Likes

This is current state.

so here’s some errors,

BABYLON.Color3() takes in 3 numbers from 0 to 1.

so new BABYLON.Color3('#ff0000') isn’t right. It should be new BABYLON.Color3(1, 0, 0).

also mat.setVector3 is used for BABYLON.Vector3, for BABYLON.Color3 you have to use mat.setColor3

I’ve also simplified the shader a bit

here you go : )

4 Likes

Hello and welcome !

Ok there are several issues in your code :

Playground related :

  • Some textures with relative path such as ./assets/img/model.png would work only on your side
  • Textures with absolute path are OK, but in that case are having a CORS issue

BabylonJS related :

  • customMaterial.setVector3customMaterial.setColor3
  • From hex string you need to use BABYLON.Color3.FromHexString('#ff0000')

Here is an example with random texures from the playground server :

4 Likes

Thx for your help.
This is my target.
I ask for your help.

1 Like

the above playgrounds do exactly this, just the textures are different : )

replacing the textures as in your example:

1 Like

Please contact with me via telegram.
@pinelix

:interrobang:

@Franck_Mallete your first posts look legit, but this last one is really spammy :thinking:

@sebavan @Evgeni_Popov what do you think ?

1 Like

if you have further problems / issues or didn’t quite get some part of the fix,

Let’s just talk about it here, this way anyone who has the same problem in the future can also benefit from it : )

3 Likes

Sorry for my fault.
I wish more collaboration.

2 Likes

No worries, I’m just extremely carefull with new accounts inviting for a Telegram Chat :smile:
Did you try @Heaust-ops 's solution ?

2 Likes

no fault here ^^
I wish more collaboration too <3

Thx for your understanding.
I have many babylonJS tasks with glsl.
@Heaust-ops 's solution is excellent.
Thx, @Heaust-ops

2 Likes