three.js的alphaTest

您所在的位置:网站首页 threejs流水 three.js的alphaTest

three.js的alphaTest

2023-03-13 11:44| 来源: 网络整理| 查看: 265

测试是什么

在说透明测试之前,我想啰嗦一下,对测试这个词的理解。webgl有很多测试,像深度测试,模版测试,裁剪测试等等。 每种测试都是一道关卡, 只有通过测试才能继续下一关,没有通过测试的就只能止步了,已经失去了显示在屏幕上的可能性。 专业一点的说法就是,不能通过测试的片元会被抛弃,不能继续流水线。

graph LR 顶点 -->2[片元] 2-->3[裁剪测试] 3-->4[模板和深度测试] 4-->5[...] 透明测试

所以透明测试的意思就是, 如果片元颜色的不透明度(alpha通道)低于预设的透明测试的值就会被抛弃。关键代码就这么点。

discard 关键字的意思就是抛弃这个片元,可以类比常规语言的return 之类的关键字。 不同的是,glsl中只要出现这个关键字,就会终止着色器代码,不管有多少层嵌套。

if ( diffuseColor.a < alphaTest) discard; 复制代码

three的透明测试是用着色器代码实现的,因为webgl没有提供相关api,可能就是因为实现确实简单,有了可编程流水线,用两行代码就能实现。

threeJS的具体实现

打开threejs的项目搜索USE_ALPHATEST,就可以看到相关的代码了。本地的three.js版本为146.0。

image.png 在threejs中 ,alphaTest是材质上的一个属性。在webGLProgam.js里面,我们可以看到,插入定义USE_ALPHATEST的条件就是 alphaTest为真。 alphaTest默认是0,所以默认就是不开启。

parameters.alphaTest ? '#define USE_ALPHATEST' : '', 复制代码

启用和关闭透明测试的方法就是使用条件编译。如果定义了 USE_ALPHATEST,就会执行条件语句内的代码 。 three的glsl的代码,是按功能分块的,每个模块又分变量声明和运算逻辑 ,这是很符合glsl的函数编程的。 所以下面的两行代码,分别被条件编译包裹。

#ifdef USE_ALPHATEST uniform float alphaTest; #endif #ifdef USE_ALPHATEST if ( diffuseColor.a < alphaTest ) discard; #endif 复制代码 我的问题

按上面的设计 ,在alphaTest = 0的时候, 不透明度为0的变片元仍会显示(如果没有开启transparent),这很合理。 而我的问题就是, 现在有材质的alphaTest为 0 , 有透明贴图,没有开启透明,结果就有意料之外片元显示出来了。 因为只有小于透明测试的值才会被抛弃,0 它不小于0,所以测试通过了。 常规的解决办法就是,增加alphaTest,比如设置为 0.001。

image.png

image.png 但是,如果我就是要在不透明度为0的时候,才抛弃它呢? 那也很简单,把上面的代码改一改。 这里我直接默认一直开启透明测试,当然也可以改成不小于0时开启。 透明测试和return一样,要尽早执行,减少无用功。

true ? '#define USE_ALPHATEST' : '', 复制代码 #ifdef USE_ALPHATEST if ( diffuseColor.a


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3