Javascript 如何在webgl中正确设置透明度

Javascript 如何在webgl中正确设置透明度,javascript,webgl,webgl-extensions,Javascript,Webgl,Webgl Extensions,我不熟悉图形和webgl。我在webgl 1.0中为模型设置适当的透明度时遇到问题。 模型包含多个零件(几何图形) 着色器代码是 "if (usetransparency > 0.0) {\n" + "gl_FragColor = vec4(( diffuse - 0.2) * diffColor, 1.0); \n" + "gl_FragColor.w = transparency; \n" + "} \n" Js代码是 shader.s

我不熟悉图形和webgl。我在webgl 1.0中为模型设置适当的透明度时遇到问题。 模型包含多个零件(几何图形)

着色器代码是

"if (usetransparency > 0.0) {\n" +
        "gl_FragColor = vec4(( diffuse - 0.2) * diffColor, 1.0); \n" +
        "gl_FragColor.w = transparency;  \n" +
    "}  \n" 
Js代码是

 shader.setUseTransparency(1.0);
 shader.setTransparency(transparencyValue);
 GL.clearColor(0.5, 0.5, 0.5, 0.0);
 GL.enable(GL.DEPTH_TEST);
 GL.depthFunc(GL.LEQUAL)
 GL.depthMask(false);
 GL.enable(GL.BLEND);
 GL.blendFunc(GL.SRC_ALPHA, GL.ONE_MINUS_SRC_ALPHA);
渲染每个部分后,我将使depthMask为真

下面是所需的渲染图像

下面是我在webgl中得到的实际渲染图像

我没有使用任何像threejs这样的webgl库


请在这个问题上帮助我。

在OpenGL或WebGL中没有自动获得深度正确透明度的方法。多年来,已使用多种方法来实现这一目标:

深度排序:由于绘制是按提交绘制调用的顺序进行的,因此按其相机深度对所有对象进行排序。如果您不仅关心多个对象,而且还关心同一对象的正面/背面的正确透明度,则还必须根据深度对对象中的三角形进行排序。实现这一点的最佳方法是使用


另一个选项是顺序无关透明字段的算法,例如或。虽然我不确定这些方法中的哪一种可以在WebGL中实现。

对于您的示例,它可以像关闭深度测试一样简单

gl.disable(gl.DEPTH_TEST);
问题在于深度测试,如果前面画了什么,深度测试会阻止后面画什么

另一种解决方案是按距离摄影机的z距离对对象进行排序,然后从前向后绘制,但对于您的情况来说,这只是部分解决方案,因为即使绘制单个立方体,您也需要确保在绘制前面的面之前先绘制后面的面。在这种情况下,首先必须将所有对象前后排序,然后绘制每个对象两次,一次是剔除前向三角形,然后再次剔除后向三角形。这仅适用于通过的凸面对象

除此之外,您还必须开始细分对象或使用其他技术,如他在回答中引用的BDL

但在您的情况下,因为一切都是透明的,所以看起来您可以一起关闭深度测试

不过你可能想

“严格使用”;
常数vs=`
均匀mat4 u_世界视图投影;
统一vec3 u_lightWorldPos;
统一mat4 u_世界;
一致mat4 u_逆;
均匀mat4-u_-world逆变换;
属性向量4 a_位置;
属性向量3 a_normal;
属性向量2 a_texcoord;
可变vec4 v_位置;
可变矢量2 v_texCoord;
可变vec3 v_正常;
可变vec3 v_表面光源;
void main(){
v_texCoord=a_texCoord;
v_位置=(u_世界视图投影*a_位置);
v_normal=(u_WorldInverseTransfose*vec4(a_normal,0)).xyz;
v_surfaceToLight=u_lightWorldPos-(u_world*a_位置).xyz;
gl_位置=v_位置;
}
`;
常数fs=`
精密中泵浮子;
可变vec4 v_位置;
可变矢量2 v_texCoord;
可变vec3 v_正常;
可变vec3 v_表面光源;
均匀的vec4 u_亮色;
均匀vec4 u_扩散膜;
均匀二维u_扩散;
void main(){
vec4 diffuseColor=纹理2D(u_diffuse,v_texCoord)*u_diffuseMult;
vec3 a_normal=正常化(v_normal);
vec3 SURFACHETOLIGHT=规格化(v_SURFACHETOLIGHT);
浮动照明=abs(点(a_法线,表面照明));
gl_FragColor=vec4(diffuseColor.rgb*lit,diffuseColor.a);
gl_FragColor.rgb*=gl_FragColor.a;
}
`;
setDefaults({attribPrefix:“a_”});
var m4=twgl.m4;
var gl=document.querySelector(“canvas”).getContext(“webgl”);
var programInfo=twgl.createProgramInfo(gl[vs,fs]);
变量形状=[
twgl.primitives.createCubeBufferInfo(gl,2),
twgl.primitives.createSphereBufferInfo(gl,1,24,12),
twgl.primitives.createPlaneBufferInfo(gl,2,2),
twgl.primitives.createTruncatedConeBufferInfo(gl,1,0,2,24,1),
twgl.primitives.createCresentBufferInfo(gl,1,1,0.5,0.1,24),
twgl.primitives.createCylinderBufferInfo(gl,1,2,24,2),
twgl.primitives.createDiscBufferInfo(gl,1,24),
twgl.primitives.createTorusBufferInfo(gl,1,0.4,24,12),
];
函数随机数(最小值、最大值){
返回min+Math.random()*(max-min);
}
//共同价值观
var lightWorldPosition=[1,8,-10];
var lightColor=[1,1,1,0.2];
var camera=m4.identity();
var view=m4.identity();
var viewProjection=m4.identity();
var tex=twgl.createTexture(gl{
最小值:gl最近值,
杂志:德国劳埃德船级社,
src:[
255, 255, 255, 255,
192, 192, 192, 255,
192, 192, 192, 255,
255, 255, 255, 255,
],
});
var对象=[];
var-drawObjects=[];
var numObjects=100;
var baseHue=兰特(0,360);
对于(变量ii=0;ii