US3S6L8——透明度混合物体阴影实现

知识回顾

透明度测试只能处理极端效果(完全透明和完全不透明)
而透明度混合可以帮助我们实现半透明效果

它的基本原理:关闭深度写入,开启混合,让片元颜色和颜色缓冲区中颜色进行混合计算

相关内容详见:US3S3L5——透明度混合

透明度混合 Shader 处理阴影

复用之前实现的透明混合 Shader,具体内容详见:US3S3L5——透明度混合、US3S3L6——开启深度写入的半透明

根据 透明度测试实现阴影接收和投射 的思路,如果想要物体产生阴影效果无非就两步:

  1. 投射阴影:在 FallBack​ 中关联内置的对应 Shader("Transparent/VertexLit"​)

    1
    Fallback "Tranparent/VertexLit"
  2. 接受阴影:在 Shader 中书写计算阴影衰减值的相关代码

因此对于透明度混合的 Shader 也会使用同样的思路去制作

但是!由于透明度混合需要关闭深度写入,而阴影相关的处理需要用到深度值参与计算
因此 Unity 中从性能方面考虑(要计算半透明物体的的阴影表现效果是相对复杂的)
所有的内置半透明 Shader 都不会产生阴影效果(例如 "Transparent/VertexLit"​)

因此:

  1. 透明混合 Shader 想要投射阴影时

    不管在 FallBack​ 中写入哪种自带的半透明混合 Shader,都不会有投射阴影的效果,因为深度不会写入

  2. 透明混合 Shader 想要接受阴影时

    Unity 内置关于阴影接收计算的相关宏,不会计算处理透明混合Shader
    即:混合因子设置为半透明效果(Blend SrcAlpha OneMinusSrcAlpha​)的 Shader
    因为透明混合物体的深度值和遮挡关系,无法直接用传统的深度缓冲和阴影贴图来处理

结论:Unity 中不会直接为透明度混合 Shader 处理阴影,目前学习的内容暂时不能支持我们直接为半透明混合物体生成一个较为合理的阴影

强制生成阴影

我们可以尝试让透明混合 Shader 强制投射阴影,在 FallBack​ 中设置一个非透明 Shader,比如 VertexLit​、Diffuse​ 等
用其中的灯光模式设置为阴影投射的渲染通道来参与阴影映射纹理的计算,把该物体当成一个实体物体处理

但是,这种效果并不真实,不建议使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Shader "TeachShader/Lesson70_Transparent"
{
Properties
{
_MainTex("MainTex", 2D) = ""{} // 纹理贴图
_MainColor("MainColor", Color) = (1, 1, 1, 1) // 漫反射颜色
_SpecularColor("SpecularColor", Color) = (1, 1, 1, 1) // 高光反射颜色
_SpecularNum("SpecularNum", Range(0, 20)) = 15 // 光泽度
_AlphaScale("AlphaScale", Range(0, 1)) = 1 // 对象总体透明度
}
SubShader { /*...*/ }

Fallback "VertexLit"
}

效果显示(右为强制开启阴影投射的Shader):

image

可以看到,强制开启阴影后,虽然存在阴影,但是这个阴影和非透明物体的阴影无异,没有阴影淡化,阴影也没有颜色,且没有接受阴影效果