unity Shader实现半透明阴影

在shader中,要对移动端的兼容,还不想实现两套分开兼容的话,

#pragma exclude_renderers gles gles3 glcore
#pragma target 4.5

这两句话一定要改掉,第一行代码直接剔除了gles的渲染,而恰恰大部分移动端都是用的gles(安卓平台)所以,第一行要去掉。第二行是针对于ShaderMod,也就是一些shader新特性,可以调低,内置的lit里面是实现了两套一套高质感的用来配合pc,对gles平台专门书写了一套高性能的渲染。
如果我们需要多端兼容的话,推荐target的值 3 或者 3.5,放弃一些不兼容的特性。

目前unity URP对半透明对象的处理:不能参与Shadow Map,Depth,Depth Normal的渲染,可以在材质Debug模式下查看。
并且半透明无法产生阴影,屏幕空间阴影(这个需要深度),SSAO
半透明阴影:利用UnityDitherMask3D贴图解决
实现:
首先在ShadowPass的头部定义宏:

#if (SHADER_API_D3D11 || SHADER_API_GLCORE || SHADER_API_GLES3 || SHADER_API_METAL || SHADER_API_VULKAN)
    #define CAN_SKIP_VPOS
#endif

用来确定当前是否可以支持这种方式。

声明一张贴图,这是一张3d贴图,unity内置提供的

TEXTURE3D(_DitherMaskLOD); SAMPLER(sampler_DitherMaskLOD);

然后在片元着色器上面增加参数:

half4 ShadowPassFragment(Varyings input
#if !defined(CAN_SKIP_VPOS)
    , UNITY_VPOS_TYPE vpos : VPOS
#endif
) : SV_TARGET
{
    
    

这个是能够直接获取到屏幕空间的位置。

最后,在shader中增加噪波相关的运算:

half4 ShadowPassFragment(Varyings input
#if !defined(CAN_SKIP_VPOS)
    , UNITY_VPOS_TYPE vpos : VPOS
#endif
) : SV_TARGET
{
    
    
    half4 BaseColorAlpha = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, input.uv) * _BaseColor;
    half3 BaseColor = BaseColorAlpha.rgb;
    half BaseAlpha = BaseColorAlpha.a;
    #if defined(_ALPHATEST_ON)
        clip(BaseAlpha - _Cutoff);
    #endif

    #if defined(_SURFACE_TYPE_TRANSPARENT)
        #if defined(CAN_SKIP_VPOS)
            float2 vpos = input.positionCS;
        #endif
        half alphaRef = SAMPLE_TEXTURE3D(_DitherMaskLOD, sampler_DitherMaskLOD, float3(vpos.xy * 0.25, BaseAlpha * 0.9375)).a;
        clip(alphaRef - 0.01);
    #endif

    return 0;
}

在这里插入图片描述
注意,查看材质的ShadowPass不要被禁掉,要不然就无法渲染阴影了。
在这里插入图片描述
可以看到透明度设置为1的时候,和不透明效果一样。
在这里插入图片描述
修改透明度,不但模型变透明了,阴影也跟着变透明了。

它这种实现的原理其实不是真的透明了,是通过Dither这个东西实现的,一直会更新的噪波图,然后模拟出来的半透明效果。

猜你喜欢

转载自blog.csdn.net/qq_30100043/article/details/130400857