javascript - 纹理加载器不适用于法线贴图

标签 javascript three.js

我正在尝试使用 Three.js 加载纹理以将其用作法线贴图。它不返回任何错误或其他任何内容,但纹理未加载。我最终得到一个黑球

import * as THREE from 'three';

/** Build the scene. */
const canvas = document.querySelector('#canvas');
const scene = new THREE.Scene();
const textureLoader = new THREE.TextureLoader();

/** Create the sphere. */
const gemoetry = new THREE.SphereBufferGeometry(.5, 64, 64);
const material = new THREE.MeshStandardMaterial({
  metalness: 0.7,
  roughness: 0.2,
  normalMap: textureLoader.load('https://res.cloudinary.com/axiol/image/upload/v1617884764/CodePen/normalMap.png'),
  color: new THREE.Color(0x292929)
});
const sphere = new THREE.Mesh(gemoetry, material);
scene.add(sphere);

/** Set the sizes based on the windows size. */
const sizes = {
  width: window.innerWidth,
  height: window.innerHeight
};

/** Add some light. */
const pointLight = new THREE.PointLight(0xffffff, 0.1)
pointLight.position.x = 2
pointLight.position.y = 3
pointLight.position.z = 4
scene.add(pointLight)

window.addEventListener('resize', () => {
  sizes.width = window.innerWidth
  sizes.height = window.innerHeight

  camera.aspect = sizes.width / sizes.height
  camera.updateProjectionMatrix()

  renderer.setSize(sizes.width, sizes.height)
  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
});

/** Place the camera. */
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height, 0.1, 100);
camera.position.x = 0;
camera.position.y = 0;
camera.position.z = 2;
scene.add(camera);

/** Render the scene. */
const renderer = new THREE.WebGLRenderer({
  canvas: canvas,
  alpha: true
});
renderer.setSize(sizes.width, sizes.height);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
renderer.render(scene, camera);

我真的不明白我在这里可能会错过什么。有什么想法吗?

最佳答案

您使用尚未完全加载的法线贴图渲染场景。像这样尝试一下:

/** Build the scene. */
const canvas = document.querySelector('#canvas');
const scene = new THREE.Scene();
scene.background = new THREE.Color(0xffffff);
const textureLoader = new THREE.TextureLoader();

/** Create the sphere. */
const gemoetry = new THREE.SphereBufferGeometry(0.5, 64, 64);
const material = new THREE.MeshStandardMaterial({
  metalness: 0.7,
  roughness: 0.2,
  normalMap: textureLoader.load('https://res.cloudinary.com/axiol/image/upload/v1617884764/CodePen/normalMap.png', render),
  color: new THREE.Color(0xffffff)
});
const sphere = new THREE.Mesh(gemoetry, material);
scene.add(sphere);

/** Set the sizes based on the windows size. */
const sizes = {
  width: window.innerWidth,
  height: window.innerHeight
};

/** Add some light. */
const pointLight = new THREE.PointLight(0xffffff, 1)
pointLight.position.x = 2
pointLight.position.y = 3
pointLight.position.z = 4
scene.add(pointLight)

window.addEventListener('resize', () => {
  sizes.width = window.innerWidth
  sizes.height = window.innerHeight

  camera.aspect = sizes.width / sizes.height
  camera.updateProjectionMatrix()

  renderer.setSize(sizes.width, sizes.height)
  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
});

/** Place the camera. */
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height, 0.1, 100);
camera.position.x = 0;
camera.position.y = 0;
camera.position.z = 2;
scene.add(camera);

/** Render the scene. */
const renderer = new THREE.WebGLRenderer({
  canvas: canvas
});
renderer.setSize(sizes.width, sizes.height);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
render();

function render() {

  renderer.render(scene, camera);

}
body {
  margin:0
}
<script src="https://cdn.jsdelivr.net/npm/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="20544852454560100e1112170e10" rel="noreferrer noopener nofollow">[email protected]</a>/build/three.js"></script>
<canvas id="canvas"></canvas>

注意 TextureLoader.load()onLoad() 回调中对 render() 的调用。

关于javascript - 纹理加载器不适用于法线贴图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67004770/

相关文章:

javascript - 如何在三个js中高效多次渲染一个网格?

javascript - 从控件事件中获取 html 中的 javascript 结果

javascript - 在 javascript 中更改 css 转换不会触发 Javascript 中的转换

javascript - 如何在 React OpenSeadragon 中添加多个图 block 图像

javascript - 如何让我的文本标签始终面向相机?也许使用 Sprite ?

javascript - THREE.js生成UV坐标

javascript - 创建一个没有未定义的json

javascript - 调整与输入值长度相对应的输入宽度

javascript - Three.ar.js 不良的宽高比会导致图像拉伸(stretch)?

javascript - 测量 3d 模型的距离?