Javascript 使用THREE.js将图像加载到BufferGeometry曲面时出现问题

Javascript 使用THREE.js将图像加载到BufferGeometry曲面时出现问题,javascript,three.js,image-loading,buffer-geometry,Javascript,Three.js,Image Loading,Buffer Geometry,我正在尝试使用BufferGeometry在THREE.js中创建一个立方体,但是图像无法正确加载。我尝试了一些方法,但似乎没有任何效果,而且紫外线似乎不起作用 script.js 我有一个奇怪的错误,纹理不起作用 图画 我看不出您设置了任何UV纹理坐标。如果没有它们,渲染器、着色器、WebGL程序(或魔法发生的地方)将不知道如何将纹理应用于网格 const顶点=新数组([ -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0

我正在尝试使用
BufferGeometry
在THREE.js中创建一个立方体,但是图像无法正确加载。我尝试了一些方法,但似乎没有任何效果,而且紫外线似乎不起作用

script.js

我有一个奇怪的错误,纹理不起作用

图画


我看不出您设置了任何UV纹理坐标。如果没有它们,渲染器、着色器、WebGL程序(或魔法发生的地方)将不知道如何将纹理应用于网格

const顶点=新数组([
-1.0, -1.0, 1.0,
1.0, -1.0, 1.0,
1.0, 1.0, 1.0,
1.0, 1.0, 1.0,
-1.0, 1.0, 1.0,
-1.0, -1.0, 1.0
]);
const uvs=新的浮点数组([
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
1.0, 1.0,
0.0, 1.0,
0.0, 0.0
]);
this.geometry.addAttribute('position',新的三个.BufferAttribute(顶点,3));
this.geometry.addAttribute('uv',新的三个.BufferAttribute(uvs,2));

如果你试图创建一个立方体,每边都有不同的纹理,你也可以利用它。它的每一面都有不同的材质索引。因此,您只需将6种材质的数组应用于网格。

在简化问题时,您是否看到同样的问题?尝试在简单场景中仅渲染纹理立方体(没有所有包装材料),以确保纹理、几何体、,紫外线都能正常工作。问题可能是我没有紫外线。我没有加入紫外线的唯一原因是我不太明白它们的作用,也找不到一个好的来源来解释。一旦我发现并发布了一张图片,我认为它很好地说明了紫外线坐标:好吧,现在我有点奇怪了。我采纳了@TheJim01的建议,简化了所有内容,但是我刚刚看到的uv(编辑中的图片)产生了奇怪的效果,我犯了一个小错误:对于
addAttribute('uv',…
缓冲属性
itemSize
应该是
2
而不是
3
。我编辑了代码片段的最后一行。啊,我明白了。它现在可以工作了。
//Load the canvas to draw on
var canvas = document.querySelector('#canvas')
// The three.js scene: the 3D world where you put objects
const scene = new THREE.Scene();


function degrees_to_radians(degrees) {
    let pi = Math.PI;
    return degrees * (pi / 180);
}


// The camera
const camera = new THREE.PerspectiveCamera(
    60,
    window.innerWidth / window.innerHeight,
    0.0001,
    10000
);

// The renderer: something that draws 3D objects onto the canvas
const renderer = new THREE.WebGLRenderer({ canvas: canvas });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0x4a4a4a, 1);
document.body.appendChild(renderer.domElement);

const controls = new THREE.PointerLockControls(camera, document.body);

document.addEventListener('click', function () {
    controls.lock();
});

var key_map = {}; // You could also use an array
onkeydown = onkeyup = function (e) {
    e = e || event; // to deal with IE
    key_map[e.keyCode] = e.type == 'keydown';
}


const light = new THREE.PointLight( 0xffffff, 2, 0, 2 );
light.position.set( 10, 50, 10 );
scene.add( light );

camera.position.z = 4


const vertices = new Float32Array([
    -1.0, -1.0, 0.0,
    1.0, -1.0, 0.0,
    1.0, 1.0, 0.0,

    1.0, 1.0, 0.0,
    -1.0, 1.0, 0.0,
    -1.0, -1.0, 0.0
]);

const uvs = new Float32Array([
    0.0, 0.0,
    1.0, 0.0,
    1.0, 1.0,

    1.0, 1.0,
    0.0, 1.0,
    0.0, 0.0
]);

let textureLoader = new THREE.TextureLoader();
var texture = textureLoader.load('./images/grass.jpg');

const material = new THREE.MeshLambertMaterial({ map: texture });

const geometry = new THREE.BufferGeometry();
geometry.addAttribute('position', new THREE.BufferAttribute(vertices, 3));
geometry.addAttribute('uv', new THREE.BufferAttribute(uvs, 3));
geometry.computeVertexNormals();

var mesh = new THREE.Mesh(geometry, material);

scene.add(mesh);


const walk_speed = 0.05;
const sprint_speed = 0.15;
const fly_speed = 0.06;
var speed = 0;
var f_speed = 0;
var b_speed = 0;
var l_speed = 0;
var r_speed = 0;

function render() {
    //handle keypresses
    var cameraDirection = controls.getDirection(new THREE.Vector3()).clone();
    var angle = Math.atan2(cameraDirection.x, cameraDirection.z);

    if (key_map[87]) {
        //forwards
        if (key_map[17]) {
            f_speed = sprint_speed;
        } else {
            f_speed = walk_speed;
        }
        controls.getObject().position.z += (Math.cos(angle)) * f_speed;
        controls.getObject().position.x += (Math.sin(angle)) * f_speed;
    }
    if (key_map[83]) {
        //backwards
        if (key_map[17]) {
            speed = sprint_speed;
        } else {
            speed = walk_speed;
        }
        controls.getObject().position.z -= (Math.cos(angle)) * speed;
        controls.getObject().position.x -= (Math.sin(angle)) * speed;
    }
    if (key_map[65]) {
        //left
        if (key_map[17]) {
            speed = sprint_speed;
        } else {
            speed = walk_speed;
        }
        controls.getObject().position.z -= (Math.sin(angle)) * speed;
        controls.getObject().position.x += (Math.cos(angle)) * speed;
    }
    if (key_map[68]) {
        //right
        if (key_map[17]) {
            speed = sprint_speed;
        } else {
            speed = walk_speed;
        }
        controls.getObject().position.z += (Math.sin(angle)) * speed;
        controls.getObject().position.x -= (Math.cos(angle)) * speed;
    }

    if (key_map[16]) {
        //down
        camera.position.y -= fly_speed;
    }
    if (key_map[32]) {
        //up
        camera.position.y += fly_speed;
    }

    renderer.render(scene, camera);

    // Make it call the render() function about every 1/60 second
    requestAnimationFrame(render);
}


render();