片段着色器中的Alpha值无法正常工作(gl_FragColor)。

4
我正在使用Three.js和ShaderMaterial使用Fragment Shader绘制Points Geometry。
我想让每个点都有模糊的边缘,但我无法让alpha起作用,它只会变成白色。
当像素完全透明时,我可以放弃它们以创建圆形,但是模糊效果会淡化到白色然后被突然截断。
以下是屏幕上显示的内容:What I see on screen Three.JS 代码
var shaderMaterial = new THREE.ShaderMaterial( {
      uniforms:     uniforms,
      vertexShader:   document.getElementById( 'vertexshader' ).textContent,
      fragmentShader: document.getElementById( 'fragmentshader' ).textContent,
      blending: THREE.NormalBlending,
      depthTest: true,
      transparent: true,
      clipping: true
    });

    var points = new THREE.Points(geometry, shaderMaterial);

片元着色器:

//translate gl_PointCoord to be centered at 0,0
vec2 cxy = 2.0 * gl_PointCoord - 1.0;

//calculate alpha based on distance from centre
//(I'm doubling it to get a less gradual fade) 
float newAlpha = (1.0-distance(cxy, vec2(0.0,0.0))) * 2.0;

if (newAlpha < 0.01)
{
    //discard pixels that have ~0 alpha
    discard;
}

gl_FragColor = vec4( newR, newG, newB, newAlpha);

先行感谢任何帮助 :) 这个问题困扰我很久。
编辑:深度测试开启和关闭的图像。在我看来,深度测试确实将它们按正确顺序放置了?
深度测试为false:depthTest:false 深度测试为true:depthTest:true

我认为这里的问题在于您的材质中有 depthTest: true。由于粒子绘制的顺序是由几何体实例上的顶点位置设置的,因此粒子不会按照前后顺序渲染。导致渲染不正确。 - ScieCode
1
我可以从您提供的图像中看到,它们没有按照后面的顺序渲染,因为有些粒子按预期渲染,而其他粒子则没有。我知道Three.js在渲染之前不会对网格的顶点进行排序,只会对场景中的对象进行排序。 - ScieCode
奇怪在哪里?能提供一个实时示例以方便调试吗? - ScieCode
刚刚添加了深度测试(depthtest)真/假的图像。我会尝试在jsfiddle上发布一些内容。 - Jonathan Plackett
如果alpha分量实际上并没有使物体透明,那么为什么gl_FragColor中会有一个alpha分量呢? - Jonathan Plackett
显示剩余7条评论
1个回答

2

你的JSFiddle示例有几个地方存在冲突。你试图在Three.js中设置材质混合模式,但随后又被覆盖了:

"Original Answer" 翻译成中文是 "最初的回答"

var gl = renderer.context;
gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);

你正在请求一个animationFrame,但是在其中使用了setTimeout,这样做就会失去使用animationFrame的所有好处。
我能够稍微改进一下:
blending: THREE.NormalBlending,
transparent: true,
depthWrite: false,
depthTest: true

您可以在此处实时查看修复情况:https://jsfiddle.net/yxj8zvmp/。尽管有太多的属性和uniforms传递到您的几何体中,以至于真正找出深度不按预期工作的原因很困难。为什么要传递u_camera,当您已经有cameraPosition,并且您的position属性长度为1?感觉像是原始WebGL与Three.js混合使用。

他在你们上面的对话中发布了这个链接:https://jsfiddle.net/jonathanplackett/Lt1kmp7v/ - M -
是的,我不知道他的小提琴去哪了。 - ScieCode
我只是想指出,在没有其他物体的场景中设置 depthWrite: false,与我最初建议的 depthTest: false 具有完全相同的效果。我知道 @marquizzo 知道这一点,但其他人可能不知道。 - ScieCode

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接