Tim*_* S. 5 javascript shader glsl webgl three.js
我做了一个小测试,允许您使用Three.js在 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;
Run Code Online (Sandbox Code Playgroud)
在这个例子中,错误更容易被注意到。
从顶部查看球体时,您只能从外侧看到着色器。从侧面看似乎有点不稳定,从底部看似乎很有效。
这些是不同的角度(顶部 - 侧面 - 底部):

这是我的片段着色器的重要部分:
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);
}
Run Code Online (Sandbox Code Playgroud)
那么为什么我会看到不规则的边缘以及为什么视角很重要?
你的着色器没有任何问题。如果您设置以下内容,您还可以看到效果:
gl_FragColor = vec4( 1.0, 1.0, 1.0, 0.5 );
Run Code Online (Sandbox Code Playgroud)
在 Three.js 中,自我透明性很棘手。
出于性能原因WebGLRenderer,深度排序仅在对象之间进行(基于其位置),而不是在单个对象内进行。
无法控制对象内各个面的渲染顺序。
这就是为什么从某些视角来看您的场景比其他角度看起来更好的原因。
一种解决方法是将几何体分解为每个面一个的单独网格。
另一种解决方法(IMO,你最好的选择)是用同一位置的两个透明球体(一个正面球体和一个背面球体)替换透明的双面球体。
三.js r.56