您需要 登录 才可以下载或查看,没有账号?注册
x
本帖最后由 alostSoul 于 2018-8-21 10:17 编辑
我估计很多项目都会遇到这种问题,当我们想使用"RenderType" = "Transparent"的时候,物体无法实现阴影,亲几天考到了一个帖子感觉很有用分享一下
渲染Q1:当"RenderType" = "Transparent"的时候貌似是没有办法接受阴影的。我们需要在场景中做一层半透的地表, 来掩盖模型和地表之间的接缝,所以需要显示阴影, 请教各位大佬有什么好的方法吗?另外我想了解下为什么半透明物件默认不能接受阴影呢?
抛开Unity引擎,从本质上说,半透物体肯定是可以接受阴影的。之前就实现过地表有一块玻璃材质,会在玻璃上以及下面的物体上都有投射的阴影效果。所以如果自己编写的Shader,想要接受阴影,只需要采样Shadowmap,走一下阴影计算的过程就可以了。
对于Unity引擎,我试了一下的确选择Transparent的RenderType也就没有了阴影,这个我不是非常清楚是否可以自己在Shader中去强制走一下Shadowmap的处理过程来解决,题主可以试下。
但是题主要注意,半透物体接受阴影的情况下,尤其是题主要解决的这种覆盖接缝的情况,会导致这部分最后产生的阴影变得比较重的效果,因为半透下面的物体肯定还会有阴影产生,半透的阴影虽然可以受Alpha的影响变淡,但是叠加在一起就会出现变得更暗的问题。当然Transparent的部分不接受阴影,意味着阴影效果经过Alpha Blend之后会变得淡。
感谢贾伟昊@UWA问答社区提供了回答。
这个问题恰好之前做了些尝试,正如@贾伟昊所说,内置的Transparent是不接受阴影的,但可以尝试在自定义shader中强制走Shadowmap的。参考代码如下: Shader "Transparent/Diffuse With Shadows"{ Properties { _MainTex ("Texture", 2D) = "white" {} _Alpha ("Alpha", float) = 1 } SubShader { Pass { Tags {"LightMode"="ForwardBase" "RenderType"="Transparent"} ZWrite Off Blend SrcAlpha OneMinusSrcAlpha ColorMask RGB CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #include "Lighting.cginc" #pragma multi_compile_fwdbase nolightmap nodirlightmap nodynlightmap novertexlight #include "AutoLight.cginc" struct v2f { float2 uv : TEXCOORD0; SHADOW_COORDS(1) fixed3 diff : COLOR0; fixed3 ambient : COLOR1; float4 pos : SV_POSITION; }; v2f vert (appdata_base v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.uv = v.texcoord; half3 worldNormal = UnityObjectToWorldNormal(v.normal); half nl = max(0, dot(worldNormal, _WorldSpaceLightPos0.xyz)); o.diff = nl * _LightColor0.rgb; o.ambient = ShadeSH9(half4(worldNormal,1)); TRANSFER_SHADOW(o) return o; } sampler2D _MainTex; float _Alpha; fixed4 frag (v2f i) : SV_Target { fixed4 col = tex2D(_MainTex, i.uv); fixed shadow = SHADOW_ATTENUATION(i); fixed3 lighting = i.diff * shadow + i.ambient; col.rgb *= lighting; col.a *= _Alpha; return col; } ENDCG } }}
但直接用这个Shader也还是没有效果…
因为 文档里有句话,重点是粗体:
Only opaque objects cast and receive shadows so objects using the built-in Transparent or Particle shaders will neither cast nor receive. Generally, you can use the Transparent Cutout shaders instead for objects with “gaps” such as fences, vegetation, etc. Custom Shaders must be pixel-lit and use the Geometry render queue.
所以需要把Render Queue调整到2500:
然后效果就出来了:
该问题来自UWA问答社区,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5b67b9851e88b37d34e651da
LightmapQ2:我使用ShadowMask模式烘焙好了场景,生成了正确的Lightmap,其中包含Lightcolor和ShadowMask。之后将场景的物体和光照图等信息用自己的格式存储,启动游戏时再重建整个场景。 但是Lightmap正确设置之后,SHADOWS_SHADOWMSK宏没有被打开,Shader中只找到了Light Color 的Sampler,并没有找到ShadowMask的Sampler。 1)如何设置才能开启SHADOWS_SHADOWMSK的keyword,并正确地将贴图传入Shader(不能手动在材质上打开keyword,传入的贴图是默认的白色)? 2)另外之前因为场景物体设置成了静态,烘焙了光照图后不产生和接受阴影,但是自己从Prefab中创建出来的物体就会产生和接受阴影,是只能加载后将Renderer上的这两个选项关闭么?还是有什么统一设置?
第一个问题,从题主的描述上来看,你们重建整个场景,是否连同当时烘焙混合光照的那盏灯光也是重建出来的?如果是,确实会导致ShadowMask无法使用,我这边的做法是保留场景中用来烘焙混合光的那盏光源,这样ShadowMask才会起作用,两者有某种关系。场景中的物件可以保存为Prefab,加载后手动恢复以下Lightmap Index即可,烘焙光源留在场景中别删。
第二个问题,题主从Prefab直接拖进场景中的物件,需要手动恢复LightmapIndex和UV数据,否则得到的是实时光照和阴影。
|