4

I want to use THREE.ShaderMaterial instead of THREE.PointMaterial.
And have a problem with sizing or drawing of particles.

If I use THREE.PointMaterial, then sizes of particles depend on z coord of particle position (other words: depth of particle).
But, if I use THREE.ShaderMaterial then I lose the needed effect.

Try it here

what I mean

the left shpere is THREE.ShaderMaterial
the right shpere is THREE.PointMaterial

How you can see, have a big difference.

Maybe someone knows how to get the same result of rendering with using THREE.ShaderMaterial?

Code for mareials:

THREE.ShaderMaterial

const shaderPoint = THREE.ShaderLib.points
const uniforms = THREE.UniformsUtils.clone(shaderPoint.uniforms)
uniforms.map.value = /*set some texture*/
uniforms.size.value = 60
material = new THREE.ShaderMaterial({
    uniforms: uniforms,
    defines: {
        "USE_MAP": ""
    },
    transparent: true,
    // alphaTest: .4,
    depthWrite: false,
    // depthTest: false,
    // blending: THREE.AdditiveBlending,
    vertexShader: shaderPoint.vertexShader,
    fragmentShader: shaderPoint.fragmentShader
}))

THREE.PointMaterial

let material = new THREE.PointsMaterial({
    size: 60,
    // color: "#f0f",
    map:  uniforms.map.value,
    depthWrite: false,
    transparent: true
})
gman
  • 100,619
  • 31
  • 269
  • 393
Artem Zubkov
  • 559
  • 1
  • 14
  • 29
  • Have a look at [this SO answer](http://stackoverflow.com/questions/12337660/three-js-adjusting-opacity-of-individual-particles/12344288#12344288) and [this comment](https://github.com/mrdoob/three.js/issues/10385#issuecomment-267789138). That will give you ideas. – WestLangley Dec 20 '16 at 18:50
  • @WestLangley thanks for your comment. Really I found decision!!! If use `uniforms.scale.value = 350` and `USE_SIZEATTENUATION: ""` I have the same result :) thanks a lot! – Artem Zubkov Dec 20 '16 at 19:47

1 Answers1

2

Need use uniforms.scale.value = 350 and USE_SIZEATTENUATION: "" in order to say threejs to make correct shader vertex program.

THREE.ShaderMaterial

const shaderPoint = THREE.ShaderLib.points
const uniforms = THREE.UniformsUtils.clone(shaderPoint.uniforms)
uniforms.map.value = /*set some texture*/
uniforms.size.value = 60
/*+++*/
uniforms.scale.value = 350 // in my case value is 350
/*+++*/

material = new THREE.ShaderMaterial({
    uniforms: uniforms,
    defines: {
        USE_MAP: "",
        /*+++*/ 
        USE_SIZEATTENUATION: ""
        /*+++*/
    },
    transparent: true,
    // alphaTest: .4,
    depthWrite: false,
    // depthTest: false,
    // blending: THREE.AdditiveBlending,
    vertexShader: shaderPoint.vertexShader,
    fragmentShader: shaderPoint.fragmentShader
}))

UPD#1
To be honest, if you don't need write yourself shader for THREE.Points then you should use THREE.PointMaterial because it's also shaders.

I looked over into three.js source code and found how to correctly calculate scale for uniforms parameters.
file: src/renderers/WebGLRenderer.js
line: 2072
function: refreshUniformsPoints

Artem Zubkov
  • 559
  • 1
  • 14
  • 29