Reputation: 5962
I'm trying to load a texture with three.js to use it as a normal map. It returns no error or anything else, but the texture is not loading. I end up with a black ball
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);
I don't really see what I could be missing here. Any idea ?
Upvotes: 2
Views: 354
Reputation: 31086
You render the scene with a normal map which is not yet fully loaded. Try it like so:
/** 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/[email protected]/build/three.js"></script>
<canvas id="canvas"></canvas>
Notice the call of render()
in the onLoad()
callback of TextureLoader.load()
.
Upvotes: 2