PAR
PAR

Reputation: 441

Threejs latest version 0.130.1 is not rendering shadermaterial

We were using Three 0.115 version and everything was working. Since we got vulnerability issues for < 0.125, we decided to upgrade to latest version. Then we are getting issues with shader material.

We have an application that uses Point cloud rendered with buffer geometry(positions, sizes and colors bufferattributes) and shadermaterial.

function vertexShader() {
  return `attribute float size;
  attribute vec3 customColor;
  varying vec3 vColor;
  attribute float visibility;
  varying float vVisible;
  void main() {
    vColor = customColor;
    vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
    gl_PointSize = size * ( 300.0 / -mvPosition.z );
    gl_Position = projectionMatrix * mvPosition;
    vVisible = visibility;
  }`
}

function fragmentShader() {
  return `uniform vec3 color;
  uniform sampler2D pointTexture;
  varying vec3 vColor;
  varying float vVisible;
  void main() {
    gl_FragColor = vec4( color * vColor, 1.0 );
    gl_FragColor = gl_FragColor * texture2D( pointTexture, gl_PointCoord );
    if ( gl_FragColor.a < ALPHATEST ) discard;
    if (vVisible < 0.5) discard;
  }`
}

and in our javascript init code.

const material = new THREE.ShaderMaterial({
    uniforms: {
      color: { value: new THREE.Color(0xffffff) },
      texture: { value: new THREE.TextureLoader().load(circle) },
      resolution: { value: new THREE.Vector2() },
    },
    vertexShader: vertexShader(),
    fragmentShader: fragmentShader(),
    alphaTest: 0.9,
    blending: THREE.AdditiveBlending
  });

there is no error in console. But points are not rendered. we use raycast for detecting points and that works without any issue.

Any idea why after upgrading to latest version of three, rendering of points fails? is this something to do with shadermaterial?

Thanks for the help :)

Upvotes: 0

Views: 188

Answers (1)

Mugen87
Mugen87

Reputation: 31026

You define the texture uniform like so:

texture: { value: new THREE.TextureLoader().load(circle) },

and in the shader you have this line

uniform sampler2D pointTexture;

I don't understand how this code ever worked since the uniform names do not match. I've aligned the names in the following example which is loosely based on your code.

let camera, scene, renderer;

init();
animate();

function init() {

  camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.01, 10);
  camera.position.z = 3;

  scene = new THREE.Scene();

  const geometry = new THREE.BufferGeometry().setFromPoints([new THREE.Vector3(1, 0, 0), new THREE.Vector3()]);

  const material = new THREE.ShaderMaterial({
    uniforms: {
      color: {
        value: new THREE.Color(0xffffff)
      },
      pointTexture: {
        value: new THREE.TextureLoader().load('https://threejs.org/examples/textures/sprite.png')
      },
      resolution: {
        value: new THREE.Vector2()
      },
    },
    vertexShader: vertexShader(),
    fragmentShader: fragmentShader(),
    alphaTest: 0.9,
    blending: THREE.AdditiveBlending
  });

  const points = new THREE.Points(geometry, material);
  scene.add(points);

  renderer = new THREE.WebGLRenderer({
    antialias: true
  });
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);

}

function animate() {

  requestAnimationFrame(animate);
  renderer.render(scene, camera);

}

function vertexShader() {
  return `
  void main() {
    vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
    gl_PointSize = ( 300.0 / -mvPosition.z );
    gl_Position = projectionMatrix * mvPosition;
  }`
}

function fragmentShader() {
  return `
  uniform sampler2D pointTexture;
  void main() {
    gl_FragColor = texture2D( pointTexture, gl_PointCoord );
  }`
}
body {
      margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/three.min.js"></script>

Upvotes: 2

Related Questions