透明效果

基本概念

如何实现

通过控制模型的透明通道来实现透明效果

透明度

片元属性
0(完全透明,不显示)~1(完全不透明)

Unity中实现透明效果的方法

透明度测试
  • 无需关闭深度写入,根据透明度决定是否舍弃片元(若透明度小于某值则舍弃,否则视为不透明物体)
  • 由上面的处理方式可知,得到的效果只有完全透明和完全不透明两种
透明度混合(真正的半透明)
  • 使用当前片元的透明度作为混合因子,与已存储在颜色缓冲中的颜色进行混合得到新颜色
  • 需关闭深度写入(若不关闭则会导致无法显示半透明物体后面的物体(因距离摄像机远于半透明物体而被剔除),需开发者注意控制渲染顺序),未关闭深度测试(即在进行透明度混合时,深度缓冲只读)
  • 比较片元的深度与深度缓冲中的深度,若片元更远则不进行处理,从而确保不透明物体能挡住半透明物体
  • 深度缓冲(z-buffer)解决了不透明物体的渲染顺序
  • 渲染片元时,将其深度值与已存在于深度缓冲中的值进行比较,若其距离摄像机更远,则可知不应将其渲染,否则,将其渲染并用其深度值更新深度缓冲(即深度缓冲中始终保存当前最靠近摄像机的内容,作为对照量来确认片元是否应被渲染)

渲染顺序

含义

因为事先透明效果需关闭深度写入,因此需开发者控制渲染顺序,按如下规则进行渲染

  • 渲染所有不透明物体(开启深度测试和深度写入)
  • 将半透明物体按距摄像机距离由远至近排序,按由远至近的顺序依次渲染(开启深度测试,关闭深度写入)
问题

上述规则的问题:循环重叠

  • “将半透明物体排序”,深度缓冲中的值是像素级别的,一个物体与摄像机的距离无法确切反映其每个像素与摄像机的距离(无法解决3个物体循环重叠的问题)
解决问题的方法

准确的说是缓解,因为仍可能出错

  • 减少错误排序
    让模型是凸面体
    复杂模型拆分为多个可独立排序的子模型
  • 让错误(穿插)不明显
    让透明通道更柔和
    用开启了深度写入的半透明效果来近似模拟半透明

Unity中的渲染顺序

render queue
通过SubShader的Queue标签决定模型所属渲染队列
用整数索引表示各渲染队列,索引数越小越早被渲染

  • Background 1000 背景上的物体
  • Geometry 2000 默认(不透明)
  • AlphaTest 2450 需使用透明度测试的物体
  • Transparent 3000 按从后往前的顺序渲染,使用了透明度混合的物体都应使用本队列
  • Overlay 4000 叠加效果

关闭深度写入的方法

  • ZWrite Off:可以写在Pass或SubShader中

Unity中实现透明Shader

透明度测试

  • 逐片元判断,若其透明度不满足条件(如小于指定阈值),舍弃片元,否则视为不透明物体
  • 结果:只有透明和不透明两种情况

透明度混合

  • 用片元的透明度作为混合因子,与颜色缓冲中的颜色进行混的得到新的颜色
  • 混合时需关闭深度写入(开发者要自行留意渲染顺序)
    关闭后无法对模型进行像素级别的深度排序,当模型网格间互相交叉时,得到的半透明效果是错误的(相互交叉)
  • Unity的Blend指令:Blend SrcFactor(源颜色的混合因子) DstFactor(目标颜色的混合因子)
    源颜色和目标颜色各自乘以自己的混合因子,再相加

半透明效果(开启深度写入)

实现模型与其背景的混合效果,而模型内部之间不产生半透明效果(避免出现相互交叉的错误)
用两个Pass渲染模型(性能问题:因为多用了一个Pass)

  • 开启深度写入,不输出颜色:将模型的深度值写入深度缓冲
Pass
{
    ZWrite On   // 开启深度写入
    ColorMask 0 // 渲染命令:设置颜色通道的写掩码  0表示不写入任何颜色通道(不输出任何颜色)              
}
  • 进行正常的透明度混合

ShaderLab混合命令

混合等式和参数

混合是逐片元操作,不可编程,高度可配置
混合等式:已知源颜色和模板颜色,通过混合等式得到输出颜色

  • 2个混合等式:混合RGB 和 混合A
  • 每个等式有2个因子:与源颜色相乘的因子 和 与目标颜色相乘的因子
混合操作

对颜色和因子进行操作:加、减、取最小(源颜色和目标颜色中)、取最大(源颜色和目标颜色中)

常见的混合类型

混合类型:混合操作和混合因子命令的组合(类似PS的混合模式)

双面渲染的透明效果

默认情况下,渲染引擎剔除了物体背面(相对于摄像机方向)的渲染图元,只渲染了物体正面
对于半透明的物体,需要能在其正面看到其内部及背面的形状
使用Cull指令控制要剔除哪个面的渲染图元
Cull Back(不渲染背对摄像机的) | Front(不渲染朝向摄像机的) | Off (关闭剔除功能,渲染所有图元)

透明度测试的双面渲染

直接在Pass的渲染设置中使用Cull指令关闭剔除(Off)

透明度混合的双面渲染

不能直接关闭剔除(透明度混合关闭了深度写入,如果关闭剔除,会无法保证同一物体的正面和背面图元的渲染顺序,渲染顺序的错误会导致错误的半透明效果)
分2个Pass (保证背面一定在正面前被渲染,原因是Unity是顺序执行SubShader的各Pass的),第一个渲染背面(Cull Front)、第二个渲染正面(Cull Back)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 一、前提知识 (1)深度缓存 它的基本思想是:根据深度缓存中的值来判断该片元距离摄像机的距离,当渲染一个片元时,需...
    zzqlb阅读 3,152评论 0 1
  • ●透明是游戏中经常使用的一种效果,在实时渲染透明效果,通常会在渲染模型时控制它的透明通道。在unity中实现透明效...
    黒可乐阅读 1,156评论 0 0
  • 前天送走我爸 他从6月份来深圳,不到5个月的时间,这几个月,我是真的开心不起来,不喜欢他,希望他赶快走 从小我应该...
    Facethesun99阅读 313评论 0 0
  • 《迈向基地》是阿西莫夫基地系列中的前传,讲述了哈里·谢顿建立第一基地,第二基地的过程。在银河帝国日渐没落,川陀日渐...
    苏佑仁阅读 811评论 0 0
  • 预备――拉屎
    橘子皮児阅读 151评论 1 1