web-dev-qa-db-fra.com

Shader de texture personnalisé dans Three.js

Je cherche juste à créer un Fragment Shader très simple qui dessine une texture spécifiée dans le maillage. J'ai examiné une poignée de shaders de fragments personnalisés qui ont accompli la même chose et j'ai construit mes propres shaders et supporté le code JS autour de lui. Cependant, cela ne fonctionne tout simplement pas. Voici une abstraction de travail du code que j'essaie d'exécuter:

Vertex Shader

<script id="vertexShader" type="x-shader/x-vertex">
    varying vec2 vUv;

    void main() {
        vUv = uv;

        gl_Position =   projectionMatrix * 
                        modelViewMatrix * 
                        vec4(position,1.0);
    }
</script>

Fragment Shader

<script id="fragmentShader" type="x-shader/x-fragment">
    uniform sampler2D texture1;

    varying vec2 vUv;

    void main() {
        gl_FragColor = texture2D(texture1, vUv); // Displays Nothing
        //gl_FragColor = vec4(0.5, 0.2, 1.0, 1.0); // Works; Displays Flat Color
    }
</script>

Code de scène

<script>
    // Initialize WebGL Renderer
    var renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    var canvas = document.getElementById('canvas').appendChild(renderer.domElement);

    // Initialize Scenes
    var scene = new THREE.Scene();

    // Initialize Camera
    var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 100);
    camera.position.z = 10;

    // Create Light
    var light = new THREE.PointLight(0xFFFFFF);
    light.position.set(0, 0, 500);
    scene.add(light);

    // Create Ball
    var vertShader = document.getElementById('vertexShader').innerHTML;
    var fragShader = document.getElementById('fragmentShader').innerHTML;

    var uniforms = {
        texture1: { type: 't', value: 0, texture: THREE.ImageUtils.loadTexture( 'texture.jpg' ) }
    };

    var material = new THREE.ShaderMaterial({
        uniforms: uniforms,
        vertexShader: vertShader,
        fragmentShader: fragShader
    });

    var ball = new THREE.Mesh(new THREE.SphereGeometry(1, 50, 50), material);
    scene.add(ball);

    // Render the Scene
    renderer.render(scene, camera);
</script>

texture.jpg existe et s'affiche lorsqu'il est mappé à un MeshLambertMaterial. Lorsque je passe mon fragment shader à une couleur simple (commenté dans le code), il affiche correctement la balle.

L'exécution de ceci n'affiche rien du tout. Je n'ai pas d'erreurs, la balle n'apparaît pas du tout.

Je sais que je dois faire quelque chose de fondamentalement mauvais, mais je regarde les mêmes exemples dans lesquels ce code semble fonctionner depuis quelques jours maintenant et j'ai l'impression de me frapper la tête contre un mur. Toute aide serait appréciée!

Edit: j'utilise Three.js Revision 51

31
rrowland

Vous utilisez toujours l'ancienne syntaxe pour les uniformes

var uniforms = {
    texture1: {
        type: "t",
        value: 0,
        texture: THREE.ImageUtils.loadTexture("texture.jpg")
    }
};

Ceci est la nouvelle syntaxe

var uniforms = {
    texture1: { type: "t", value: THREE.ImageUtils.loadTexture( "texture.jpg" ) }
};
33
Gero3