Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/458.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 双面透明着色器看起来有问题_Javascript_Glsl_Three.js_Webgl_Shader - Fatal编程技术网

Javascript 双面透明着色器看起来有问题

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(),

我做了一个小测试,允许您在3D环境中使用着色器进行实验

场景中有一个球体显示着色器

我创建的是一个非常简单的着色器,它使用2D噪波实现。球体的很大一部分仍然是黑色的,我使其透明。我希望球体的另一面也可见。所以我启用了透明度并将“渲染侧”设置为双面

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在我准备写这个问题之前,我不小心把它贴出来了。我很抱歉。它看起来好像有东西在那个球体前面。你能把它渲染成白色而不是透明吗,嗯哼。。。朝那个方向的东西。如果没有人回答“是”,我会在晚上考虑这个问题,这解释了很多。因为我的项目是一个开放的服务,仅仅为这个例外创建一个额外的领域是一种浪费,但是我相信这个答案会很好地为其他有同样问题的人服务!非常感谢你的回答。