如何在波前对象中加载 Canvas 纹理 (three.js)

how to load Canvas texture in wavefront obj (three.js)

感谢您的关注。我想使用 three.js 来显示从 Blender 导出的 obj 文件和从 canvas 映射纹理。我尝试 post obj 中的图像,它成功了。但是当我将 canvas 纹理放在 obj 上时,模型变黑了。我也试过通过toDataURL把canvas转成图片再映射,还是不行work.Any有帮助,不胜感激。

  function convertCanvasToImage(ele) {

    var image = new Image();
    image.src = ele.toDataURL("image/png");
    return image;
  }

  function changeCanvas() {

    canvas = document.getElementById('canvas_id'),
    ctx = canvas.getContext('2d');
    ctx.font = '20pt Arial';
    ctx.fillStyle = 'red';
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    ctx.fillStyle = 'white';
    ctx.fillRect(10, 10, canvas.width - 20, canvas.height - 20);
    ctx.fillStyle = 'black';
    ctx.textAlign = "center";
    ctx.textBaseline = "middle";
    ctx.fillText(new Date().getTime(), canvas.width / 2, canvas.height / 2);
    image_t = convertCanvasToImage(canvas);
    return image_t;
}

    function init() {

        container = document.createElement('div');
        document.body.appendChild(container);

        camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000);
        camera.position.z = 250;

        // scene
        scene = new THREE.Scene();
        scene.background = new THREE.Color( 'red' );

        var ambientLight = new THREE.AmbientLight(0xcccccc, 0.4);
        scene.add(ambientLight);

        var pointLight = new THREE.PointLight(0xffffff, 0.8);
        camera.add(pointLight);
        scene.add(camera);

        // manager

        function loadModel() {

            object.traverse(function (child) {

                if (child.isMesh) child.material.map = texture;

            });

            object.position.y = -95;
            scene.add(object);

        }

        var manager = new THREE.LoadingManager(loadModel);

        manager.onProgress = function (item, loaded, total) {

            console.log(item, loaded, total);

        };

        // texture
    // texture = new THREE.Texture(canvas); //it's my initial try,but it didn't work

    var textureLoader = new THREE.TextureLoader();
    texture = textureLoader.load("three.js-master/examples/models/obj/clothes/426_con.png");//this works!!!
    // img = changeCanvas()
    texture = textureLoader.load(image_t);//but this doesn't work!!!


        // model
        function onProgress(xhr) {
            if (xhr.lengthComputable) {
                var percentComplete = xhr.loaded / xhr.total * 100;
                console.log('model ' + Math.round(percentComplete, 2) + '% downloaded');
            }
        }

    function onError() {
    }

    var loader = new THREE.OBJLoader(manager);

    loader.load('three.js-master/examples/models/obj/clothes/426_con.obj', function (obj) {

        object = obj;
    }, onProgress, onError);

    renderer = new THREE.WebGLRenderer();
    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setSize(window.innerWidth, window.innerHeight);
    container.appendChild(renderer.domElement);

    function animate() {
        requestAnimationFrame(animate);
        camera.lookAt(scene.position);
        changeCanvas();
        texture.needsUpdate = true;
        renderer.render(scene, camera);
    }

我想知道如果three.js有直接在obj文件上纹理canvas的方法,需要任何翻译吗?

texture = new THREE.CanvasTexture(yourCanvas) ?

应该说我对JS不精通,真是粗心大意。感谢gman和manthrax,你们帮了大忙,你们的回答让我静下心来分析问题。虽然我能找到的所有 Three.js Canvas 纹理示例都是用于 gemotry 的纹理贴图,但也可以用于 obj。原来canvas生成的纹理和图片的纹理没有区别

<script>
    var container;
    var camera, scene, renderer,texture,canvas;
    var object;

  function changeCanvas() {
    canvas = document.getElementById('canvas_id');
    ctx = canvas.getContext('2d');
    img = new Image();
    img.onload = function(){ctx.drawImage(img, 0, 0)};
    img.src = "../assets/UV.png";//img address
  }

    function init() {

        container = document.createElement('div');
        document.body.appendChild(container);

        camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000);
        camera.position.z = 250;

        // scene
        scene = new THREE.Scene();
        scene.background = new THREE.Color( 'black' );

        var ambientLight = new THREE.AmbientLight(0xcccccc, 0.4);
        scene.add(ambientLight);

        var pointLight = new THREE.PointLight(0xffffff, 0.8);
        camera.add(pointLight);
        scene.add(camera);

        // manager

        function loadModel() {
            object.traverse(function (child) {
                if (child.isMesh) child.material.map = texture;
            });
            object.position.y = -95;
            scene.add(object);
        }

        var manager = new THREE.LoadingManager(loadModel);
        manager.onProgress = function (item, loaded, total) {
            console.log(item, loaded, total);
        };

        //texture
    changeCanvas();
    texture = new THREE.CanvasTexture(canvas);

        // model
        function onProgress(xhr) {
            if (xhr.lengthComputable) {
                var percentComplete = xhr.loaded / xhr.total * 100;
                console.log('model ' + Math.round(percentComplete, 2) + '% downloaded');
            }
        }

    function onError() {}

    var loader = new THREE.OBJLoader(manager);

    loader.load('../assets/426.obj', function (obj) {
        object = obj;
    }, onProgress, onError);

    renderer = new THREE.WebGLRenderer();
    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setSize(window.innerWidth, window.innerHeight);
    container.appendChild(renderer.domElement);

  var controls = new THREE.OrbitControls( camera, renderer.domElement );
}

    function animate() {
      // changeCanvas();
      texture.needsUpdate = true;
      camera.lookAt(scene.position);
      renderer.render(scene, camera);
    requestAnimationFrame(animate);
    }

  init();
    animate();

</script>