Render 100k sprites with 0.1 opacity, transparent maps and smooth antialiasing

久未见 提交于 2019-12-23 04:52:32

问题


I have the following setup (only relevant bits of code):

Renderer

renderer = new THREE.WebGLRenderer({ 
    antialias: true, alpha: true, canvas: canvas 
});

Textures

dot: THREE.ImageUtils.loadTexture('./assets/images/dot.png')

Material

let material = new THREE.PointsMaterial({
    size: size,
    sizeAttenuation: true,
    color: color,
    map: textures.dot,
    // alphaMap: textures.dotAlpha,
    blending: THREE.NormalBlending, // THREE.MultiplyBlending
    transparent: true,
    alphaTest: 0.1,
    opacity: 0.3
});

Point cloud Usually I have 20 to 50 point clouds with 1k to 10k dots. What I see on screen it's a small fraction of theese.

pointCloud = new THREE.Points(geometry, material);

Adding points

cfg.pointCloud.forEach(point => {
    var vertex = new THREE.Vector3();
    vertex.x = point.x;
    vertex.y = point.y;
    vertex.z = point.z;
    geometry.vertices.push(vertex);
});

I have the following issues:

  • Overlaping sprites tend to clip each other instead of rendering on top of each other. Thus I get a lot of points simply obscured
  • If i use material.alphaTest = 0.5and material.opacity:0.1 the edges of the sprites become very sharp loosing all antialiasing effect. When viewed from a distance they tend to render very poorly and disappear. I was expecting being able to render smooth borders. I'm using 512x512 png maps.
  • When I move the camera away from the origin after a certain distance sprites tend to disappear.
  • Low opacity values seem to make the dots disappear.

How can I improve this rendering? Is there any other way besides using sprites? I'm lacking the know-how needed to write a custom shader so I will appreciate anything that helps with improving this rendering.

Here are some sample images that showcase the troubles:

  • Even though the blue dots density is much higher in the green zone they tend to be obscured. I belive this happens because the green and red dots are the first point clouds introduced to the scene. And they render on top of the blue ones.

  • If I tilt the camera it seems that some dots suddenly get rendered because of a different depth index.

  • If I increase the opacity of certain point clouds their sprites tend to be obscured by sprites with lower opacity. I was expecting some blending effect there.

  • Most of the dots tend to be clustered and due to the rendering quircks most of them tend to dissapear

  • Again some clipping effects from close up


回答1:


I managed to get a significant improvement in the rendering quality. I found very good answer here. Also this question had some good information.

I have added depthWrite and depthTest as false in the material.

let material = new THREE.PointsMaterial({
    size: size,
    sizeAttenuation: true,
    color: color,
    map: this._textures.dot,
    blending: THREE.NormalBlending,
    transparent: true,
    alphaTest: 0.1,
    opacity: 0.3,
    depthWrite: false,
    depthTest: false
});

The difference is significant:

Still I have to find a solution for the antialiasing issues. When far away from the camera, dots tend to totally dissolve and disappear as it is shown in this close-up.



来源:https://stackoverflow.com/questions/42871582/render-100k-sprites-with-0-1-opacity-transparent-maps-and-smooth-antialiasing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!