GLTF and custom shader (now with live example)

Newbie here. I am attempting to ‘draw’ a heatmap on an object loaded from a GLTF file. To accomplish this, I have implemented custom vertex and fragment shaders. The GLTF image loads, and I am able to apply a red color to the model, so that’s great. My issue is that it seems that not the entire ‘base’ GLTF object is being loaded in my custom shader. The easiest way to see this is to compare the pictures of the two helmets I have attached. The top one is how the helmet should look, the second picture is the result of my custom shader. I am simply trying to draw some red spots ‘on top of’ the helmet where the mouse is. I am able to acheive the red effect, but the helmet seems to be ‘missing’ parts.

16%20PM 17%20PM

My fragment shader looks like this. I am very new to all 3D programming, so I am sure I am fundamentally misunderstanding something:

uniform vec2 u_mouse;
uniform vec2 u_resolution;
uniform sampler2D u_helmet_texture;

varying vec2 vUv;

void main() {
  vec2 st = gl_FragCoord.xy/u_resolution;
  float pct = 1.0 - distance(st, u_mouse);
  vec4 heatmap = vec4(pct*2.0, 0.1, 0.1, 0.7);
  vec4 helmet = texture2D(u_helmet_texture, vUv);

  vec4 color = mix(heatmap, helmet, .60);
  gl_FragColor = color;
}

And here is how I call the fragment shader from JS.

var fragmentShaderLoader = new THREE.FileLoader();
fragmentShaderLoader.load('fragment-shader-test.glsl',
  function (fragmentShader) {
    uniforms.u_helmet_texture = child.material;
    child.material = new THREE.ShaderMaterial({
                           uniforms: uniforms,
                           vertexShader: vertexShader,
                           fragmentShader: fragmentShader
    });
})
1 Like

Wouldn’t the sampler2D be child.material.map rather than child.material?

Can you please share your code as a live example?

Hey there, thank you so much, sure thing! I found Glitch easy to set up, it looks like a shared space for collaborative editing. The shaders and gltf files are under assets.

glitch.com/edit/#!/join/e51ff7f9-3d3c-47e0-8a45-2eb6f6c7f6d2

Go to that URL (I escaped it because it was getting truncated after the hashbang)
and click “Show Live” . Edits to the code should force a refresh (but not sure if editing the shaders under assets will)

Here is a workable fiddle with your code: https://jsfiddle.net/9k2p6mea/1/

Especially one statement was wrong:

uniforms.u_helmet_texture = child.material;

should be

uniforms.u_helmet_texture.value = child.material.map;

Thank you! That helped a lot. I am using your suggestion together with onBeforeCompile now, and it’s getting much closer to what I’m looking for.