Home > Net >  Texture not showing on ThreeJS PointsMaterial map
Texture not showing on ThreeJS PointsMaterial map

Time:12-02

I'm trying to load this image as a map of PointsMaterial with TextureLoader but with no success, it throws no errors, but the texture won't show for some reason. Am I doing something wrong or what?

Code:

const scene = new THREE.Scene();

const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  1,
  1000
);

const particleBufferGeometry = new THREE.BufferGeometry();
const positionArray = [];

for (let i = 0; i < 10000; i  ) {
  positionArray.push((Math.random() * 2 - 1) * 200);
  positionArray.push((Math.random() * 2 - 1) * 200);
  positionArray.push((Math.random() * 2 - 1) * 200);
}

particleBufferGeometry.setAttribute("position", new THREE.Float32BufferAttribute(positionArray, 3));

const particlePointsMaterial = new THREE.PointsMaterial({
  size: 0.3,
  map: new THREE.TextureLoader().load("./sparkle.png"),
  transparent: true,
});

const particlePoints = new THREE.Points(particleBufferGeometry, particlePointsMaterial);

const renderer = new THREE.WebGLRenderer({
  antialias: true,
  alpha: true,
  canvas: document.getElementById("three")
});

renderer.setClearColor(0x000000, 0);
renderer.setSize(
  window.innerWidth,
  window.innerHeight
);

scene.add(particlePoints);

renderer.render(scene, camera);

CodePudding user response:

I found why is this happening. I was passing texture as a map before it loaded.

This is wrong.

const particlePointsMaterial = new THREE.PointsMaterial({
  size: 0.3,
  map: new THREE.TextureLoader().load("./sparkle.png"),
  transparent: true,
});

load() function of TextureLoader has second parameter onl oad that executes when texture loads. So solution is:

new THREE.TextureLoader().load("./sparkle.png", (texture) => {
  const particlePointsMaterial = new THREE.PointsMaterial({
    transparent: true,
    map: texture
  });

  const particlePoints = new THREE.Points(particleBufferGeometry, particlePointsMaterial);

  scene.add(particlePoints);

  renderer.render(scene, camera);
});

CodePudding user response:

Another option is to use animation loop:

body{
  overflow: hidden;
  margin: 0;
}
<canvas id="three"></canvas>
<script type="module">
import * as THREE from "https://cdn.skypack.dev/[email protected]";

const scene = new THREE.Scene();

const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  1,
  1000
);


const positionArray = [];
for (let i = 0; i < 10000; i  ) {
  positionArray.push(new THREE.Vector3().random().subScalar(0.5).multiplyScalar(400));
}
const particleBufferGeometry = new THREE.BufferGeometry().setFromPoints(positionArray);

const particlePointsMaterial = new THREE.PointsMaterial({
  size: 3,
  map: new THREE.TextureLoader().load("https://threejs.org/examples/textures/sprites/spark1.png"),
  transparent: true,
});

const particlePoints = new THREE.Points(particleBufferGeometry, particlePointsMaterial);

const renderer = new THREE.WebGLRenderer({
  antialias: true,
  alpha: true,
  canvas: document.getElementById("three")
});

renderer.setClearColor(0x000000, 1);
renderer.setSize(
  window.innerWidth,
  window.innerHeight
);

scene.add(particlePoints);

renderer.setAnimationLoop(() => { // animation loop
  renderer.render(scene, camera);
});
</script>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related