0
votes

I'm creating a custom three.js app where I load an OBJ/MTL model for rendering. I want to apply a custom shader to the loaded model, but the color & specular uniforms that I manually pass to the RawShaderMaterial aren't being updated. Or rather, they are all populated with the same value. Thus rendering my model the same color.

He is some example code. If there's an easy solution or a better approach, I would be very interested to know.

var mtlLoader = new THREE.MTLLoader();
mtlLoader.setPath(path);
mtlLoader.load(mtlName, function(materials) {
var objLoader = new THREE.OBJLoader();
materials.preload();


objLoader.setMaterials(materials);


objLoader.setPath(path);
objLoader.load(objName, function(object) {
    if (shader) {
        object.traverse(function (child) {
            if (child instanceof THREE.Mesh) {
                var customShader = shader;
                var color = child.material["color"];
                customShader.uniforms["color"] = {type: 'v3', value: color};
                customShader.uniforms["specular"] = {type: 'v3', value: child.material["specular"]};

                child.material = customShader; 
            }
       });
    }
}

Vertex Shader: precision mediump float; precision mediump int;

    uniform mat4 modelViewMatrix;
    uniform mat4 projectionMatrix;

    attribute vec3 position;
    attribute vec3 normal;
    attribute vec2 uv;

    varying vec3 Normal;
    varying vec2 UV;

    void main() {
        Normal = normal;
        UV = uv;
        gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    }

Fragment Shader: precision mediump float; precision mediump int;

    uniform vec3 color;
    uniform vec3 specular;

    varying vec3 Normal;
    varying vec2 UV;

    void main() {
        gl_FragColor = vec4(color, 1.0);
    }
1

1 Answers

0
votes

I found my issue.

It was simply because I was not properly cloning my ShaderMaterial.

object.traverse(function (child) {
        if (child instanceof THREE.Mesh) {
            var customShader = shader.clone();
            var color = child.material["color"];
            customShader.uniforms["color"] = {type: 'v3', value: color};
            customShader.uniforms["specular"] = {type: 'v3', value: child.material["specular"]};

            child.material = customShader; 
        }
   });