部门有个实习TA要做PCSS,需要采样shadowmap里的值,与片元深度做差,来计算遮挡距离。
Unity默认的shadowmap采样是比较采样,只返回0和1:
#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)
因为要获取深度值,所以就改成:
//大致代码
TEXTURE_SHADOW(_CustomShadow);
SAMPLER(sampler_CustomShadow);
shadowAtten = SAMPLE_TEXTURE2D(_CustomShadow, sampler_CustomShadow, coord.xy) > coord.z;
同样的工程,在几个人那里正常,在一个人那里显示没有阴影。排除显卡驱动、操作系统后。测试显卡适配性,然后发现在16系显卡正常,在10系显卡显示错误。
测试将采样器换成inline sampler state:SamplerState my_point_clamp_sampler;
,结果正确,通过renderdoc比较采样器,发现sampler_CustomShadow
的Filter带有Comparison。
因此能猜出问题所在:Unity认为shadowmap的rendertexture只需要比较,不需要获取深度值,因此以ShadowMap类型创建的RT,其采样器会设置为比较采样器。而在不同系的显卡上,其底层逻辑有区别,10系用比较采样器采样(不是比较采样),会获取到错误的值,而16系用比较采样器比较,也能获取正常的值,因此导致了效果在不同显卡设备上的差异。
最后将RT申请的格式设置成Depth就好了。
网友评论