您现在的位置是:首页 >学无止境 >unity Shader实现半透明阴影网站首页学无止境
unity Shader实现半透明阴影
简介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这个东西实现的,一直会更新的噪波图,然后模拟出来的半透明效果。
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。