WebGL实践之半透阴影
2023-02-18 15:37:17 时间
楔子
相信很多人都知道,通过ShadowMap可以产生阴影,通过渲染阴影可以增加场景渲染的对比度,增加渲染的真实效果。 如下图所示:
但是对于透明或者半透明的对象,WebGL在处理阴影效果的时候,会把他当成一个不透明的对象来处理,这也渲染的阴影效果就显得很假。 比如下面树得阴影效果:
真实物理得效果中,树可能会有一些透光得间歇,所以阴影一般都不是一整块得效果。而是有些透光得亮点,如下图所示:
场景中,多家一些树,这种对比会更加明细,如下面两幅图所示,前面一个是整片阴影,后面一个是有半透阴影得效果:
半透阴影效果原来
实现半透阴影,可以通过透明度测试(alphaTest)功能来实现。一般来说,一张半透明得图片中,一部分地方是很透明得,opacity接近与零,我们希望在opacity小于某个值得时候,不生成阴影,可以通过alphaTest,把小于阈值得片元在生成阴影贴图的时候丢弃掉,自然就不会生成阴影。 所以流程大致如此:
-
绘制阴影贴图的时候,生成一个深度材质,设置深度材质alpahTest(=[阈值])和map,map是原本材质的贴图。 如果原本材质有alphaMap,也需要考虑在深度材质上面加上alphaMap。
-
正常绘制场景流程。
threejs 实践
通过three 实践,首先在材质上面增加要给属性shadowAlphaTest,通过shadowAlphaTest动态指定绘制阴影时候的alphaTest,如下所示:
this.shadowAlphaTest = undefined;
在生成深度材质的地方,如下修改:
result.alphaTest = material.shadowAlphaTest || material.alphaTest;
result.map = material.map;
result.alphaMap = material.alphaMap;
然后再绘制的时候,可以动态修改shadowAlphaTest的值,来达到控制半透阴影的效果,如下所示:
child.material.transparent = true;
child.material.opacity = 1.0;
child.material.shadowAlphaTest = 0.5;
最终的效果如下所示:
结语
如果有疑问,关注公号“ITMan彪叔” 可以添加作者微信进行交流,及时收到更多有价值的文章。
相关文章
- 痞子衡博客园主页文章图片无法显示的解决方法
- 基于redis的geo类型实现“附近的xx”功能
- IntelliJ IDEA 2022.3正式发布,配置云同步&支持Redis好用到炸
- 推荐一款采用 .NET 编写的 反编译到源码工具 Reko
- 【Docker】搭建部署Redis高可用集群实验
- 【K8S】kubernetes概念和架构(一)
- 【K8S】基于Windows系统下使用minikube安装kubernetes集群
- PromQL的简单使用
- Prometheus基于文件的服务发现
- Prometheus重新标记
- Prometheus的单机部署
- Vim的简单使用
- SpringBoot整合kafka
- kafka生产者和消费者api的简单使用
- kafka错误之 Topic xxx not present in metadata after 60000 ms
- kafka的基本概念
- 处理微信回调事件
- 微信公众号开发接入
- kafka集群搭建
- Spring Cloud Alibaba Nacos Config 的使用