将用户上传的纹理加载到three.js中的几何体

Jos*_*man 6 html javascript three.js

我是 Three.js 和 javascript(一般编码)的新手,但我在尝试可能性方面有很多乐趣,并创建了一些带有灯光、来自 3D JSON 模型的自定义几何图形的小型 Three.js 场景来开发我的能够实现我构建 3D 网站的最终目标的技能。

我目前完全陷入了允许用户从 HTML 'input' 文件标签上传图像文件的问题上,并让该图像出现在场景中已经存在的 PlaneGeometry 网格上,并且虚拟纹理已经加载到材料。

我可以让纹理图像毫无问题地出现在飞机上,并且我的 HTML“输入”文件按钮出现在屏幕上,我可以单击它并加载一个图像,但它没有链接到 Three.js 中的任何内容,这就是我的地方卡住了,我不明白如何继续。

我发现我可以看到这个JSFIDDLE 示例,但我无法弄清楚如何使用它向已经存在的几何体和材料添加自定义纹理。

<body>
<!-- three.js container -->
<input id="userImage" type="file" />
<div id="container"></div>
<script type="x-shader/x-vertex" id="vertexShader">
    varying vec2 vUv;

    void main() {
        vUv = uv;
        gl_Position = vec4(uv * 2. - vec2(1, 1), 0., 1.);
    }
</script>
<script type="x-shader/x-fragment" id="fragmentShader">
    precision highp float;

    varying vec2 vUv;
    uniform sampler2D texture1;
    void main() {
        gl_FragColor = texture2D(texture1, vUv.xy);
    }
</script>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/three.min.js"></script>
<script>

    init()

    function init(){
        $("#userImage").change(function () {
            var image = document.createElement( 'img' );
            var texture = new THREE.Texture( image );
            image.onload = function()  {
                texture.needsUpdate = true;
        };

        userImage = $("#userImage")[0];
        if (userImage.files && userImage.files[0]) {
            var reader = new FileReader();

            reader.onload = function (e) {
                image.src = e.target.result;
            };

            reader.readAsDataURL(userImage.files[0]);
        }

        camera = new THREE.OrthographicCamera();
        renderer = new THREE.WebGLRenderer({
            antialias: false
        });
        renderer.setSize(window.innerWidth, window.innerHeight);
        shader = new THREE.ShaderMaterial({
            vertexShader: document.getElementById('vertexShader').textContent,
            fragmentShader: document.getElementById('fragmentShader').textContent,
            uniforms: {
                texture1: {
                    type: "t",
                    value: texture
                }
            }
        });
        scene = new THREE.Scene();
        scene.add(new THREE.Mesh(new THREE.PlaneGeometry(1), shader));

        $('#container').append(renderer.domElement);

            animate();

        function animate() {
            requestAnimationFrame(animate);

            renderer.render(scene, camera);
        }
    }); 
    }
</script>
Run Code Online (Sandbox Code Playgroud)

有没有人介意分享一个例子,说明他们如何允许用户上传的纹理加载到已经存在的纹理、材质和对象上?

当前three.js结果的图像,顶部是HTML加载器

Rab*_*d76 2

用于addEventListener向“文件”添加“更改”事件input

document.getElementById('userImage').addEventListener('change', function(e) {
     .....  
} );
Run Code Online (Sandbox Code Playgroud)

target.files[0]新文件可以通过事件参数的属性获取:

var userImage = e.target.files[0];     
Run Code Online (Sandbox Code Playgroud)

用于URL.createObjectURL创建包含 URL 的 DOMString:

var userImageURL = URL.createObjectURL( userImage );
Run Code Online (Sandbox Code Playgroud)

我建议用于THREE.TextureLoader加载纹理:

var loader = new THREE.TextureLoader();
loader.setCrossOrigin("");
var texture = loader.load(userImageURL);
Run Code Online (Sandbox Code Playgroud)

请参阅示例,该示例基于您的问题的代码:

document.getElementById('userImage').addEventListener('change', function(e) {
     .....  
} );
Run Code Online (Sandbox Code Playgroud)
var userImage = e.target.files[0];     
Run Code Online (Sandbox Code Playgroud)