Javascript 双面透明着色器看起来有问题
我做了一个小测试,允许您在3D环境中使用着色器进行实验 场景中有一个球体显示着色器 我创建的是一个非常简单的着色器,它使用2D噪波实现。球体的很大一部分仍然是黑色的,我使其透明。我希望球体的另一面也可见。所以我启用了透明度并将“渲染侧”设置为双面Javascript 双面透明着色器看起来有问题,javascript,glsl,three.js,webgl,shader,Javascript,Glsl,Three.js,Webgl,Shader,我做了一个小测试,允许您在3D环境中使用着色器进行实验 场景中有一个球体显示着色器 我创建的是一个非常简单的着色器,它使用2D噪波实现。球体的很大一部分仍然是黑色的,我使其透明。我希望球体的另一面也可见。所以我启用了透明度并将“渲染侧”设置为双面 material = new THREE.ShaderMaterial({ 'uniforms': uniforms, 'fragmentShader': $('textarea#input-fragment').val(),
material = new THREE.ShaderMaterial({
'uniforms': uniforms,
'fragmentShader': $('textarea#input-fragment').val(),
'vertexShader': $('textarea#input-vertex').val()
});
material.side = THREE.DoubleSide;
material.transparent = true;
在上一节课上,女同性恋更容易被注意到
从顶部查看球体时,只能从外侧看到着色器。从侧面看似乎有点起伏,从底部看似乎起作用
这些是不同的角度(顶部-侧面-底部):
下面是我的片段着色器的重要部分:
void main() {
float r = cnoise(vNormal.yz * 2.0 + t);
float g = cnoise(vNormal.xz * -1.0 + t);
float b = cnoise(vNormal.xy * -2.0 + t);
// opacity ranges assumable from 0 - 3, which is OK
gl_FragColor = vec4(r, g, b, r + g + b);
}
那么为什么我看到的是起伏的边缘,为什么视角很重要呢?你的着色器没有问题。如果设置以下各项,也可以看到效果:
gl_FragColor = vec4( 1.0, 1.0, 1.0, 0.5 );
在three.js中,自透明是很棘手的
出于性能原因,在WebGLRenderer
中,深度排序仅在对象之间(基于它们的位置)工作,而不是在单个对象内
无法控制对象中各个面的渲染顺序
这就是为什么从某些视角看,您的场景比从其他角度看要好的原因
解决方法之一是将几何体分解为每个面的单个网格
另一个解决方法(IMO,您的最佳选择)是将透明的双面球体替换为位于同一位置的两个透明球体——正面球体和背面球体
three.js r.56与我遇到的非常相似。理解这一点的原因最好从基本原理来解释。 没有更多关于代码或目标的详细信息,这里是r128版本之后的替代解决方案。只需在材质中再添加一行:
material.depthTest: false,
简而言之,正如@WestLangley所提到的,您的着色器很好,但是在渲染透明度期间,也会考虑像素彼此之间的深度-最终导致某些像素无法渲染。这就是你的“童车性”的来源。这并不是一个真正的bug,而是默认情况下场景的渲染方式,直到被告知要执行其他操作为止。你可能会遇到很多与你的期望相悖的*问题,因此我建议你阅读我发布的链接
*其中一个问题是:如果场景中有其他对象,那么当然,由于关闭了depthTest,您可能会得到不正确的对象放置,因为应该在背景中的对象可能会在前景中渲染。在此处发布着色器代码,不要只是链接到它。@BartekBanachewicz在我准备写这个问题之前,我不小心把它贴出来了。我很抱歉。它看起来好像有东西在那个球体前面。你能把它渲染成白色而不是透明吗,嗯哼。。。朝那个方向的东西。如果没有人回答“是”,我会在晚上考虑这个问题,这解释了很多。因为我的项目是一个开放的服务,仅仅为这个例外创建一个额外的领域是一种浪费,但是我相信这个答案会很好地为其他有同样问题的人服务!非常感谢你的回答。