shader单独修改阴影颜色

        我们美术有个需求是只需要修改阴影的颜色,于是我第一想法和网上很多人的想法一样,去修改unity设置的光照颜色。

于是就修改了Lightting中的Setting的

网上也很多人说这样修改。但是我修改后发现其实这个修改的是环境光,是全局的一个光照,并不是只对阴影生效。所以这个修改时不能做到“只需要”修改阴影颜色的需求的。

        我们知道阴影一般有两部分组成,第一是该物体是否能投射阴影,第二是该物体是否能接受阴影。

然后我就参考shader中实现阴影的部分。

在shader中,一般我们要真能投射阴影的话需要FallBack "Diffuse"来实现。因为在unity的shader中Diffuse做了投射阴影的行为。我们可以看到unity自身的shader写法

可以观察到其实这里没其他区别,区别主要是有个Fallback "Mobile/VertexLit"。那么我们尝试只Fallback这个vertexlit是否能投射阴影。

结论是可以的。

然后我们看看Mobile/VertexLit做了什么

主要在这个pass里,他的光照类型也是ShadowCaster然后顶点及片元都是shadow相关的计算。可得知这块就是核心的shaow投影算法。(具体他里面在做什么,大家可以自己查阅unity的shader)

如果我们想修改投影的颜色,这个投射投影的地方我们需不需要改变?

是不需要的,他只是关于阴影投射的方式,并不是真正显示投影的shader。

那么真正投射阴影的shader在哪呢?

其实就是在接受投影的shader中。

比如在地板上我们就由接受投影的shader来负责显示投影对象的

VtoS vertex_shader(Input v)
				{
				    VtoS data;
				    data.pos = UnityObjectToClipPos(v.vertex);
				    data.uv_main_fog.xy = v.texcoord0.xy * _MainTex_ST.xy + _MainTex_ST.zw;
				    data.uv_main_fog.z = EBGFogVertex(v.vertex);
				    data.uv_lm = v.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
				    float3 worldN = normalize(mul((float3x3)unity_ObjectToWorld, v.normal));
				        data.worldN = worldN;
				    data._ShadowCoord = float4(0,0,0,0);
				    TRANSFER_VERTEX_TO_FRAGMENT(data);
				    return data;
				}
				float4 fragment_shader(VtoS IN) : COLOR0
				{
				    fixed4 mainTex = tex2D(_MainTex, IN.uv_main_fog.xy);
				    fixed3 col = mainTex.rgb;
				    col *= _EBGEnvLightColorScale;
				    col *= _EBGEnvScale;
				    half3 light = 1;
				         half3 bakedColor = DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, IN.uv_lm.xy));
				   light = bakedColor;
				    col *= light;
				    fixed alpha = 1.0;
				    col = EBGFogFragment(col, IN.uv_main_fog.z);
				    col = col * _EBGEnvAdjustScale + _EBGEnvAdjustOffset;
					float atten = SHADOW_ATTENUATION(IN);
					col = col * atten;
				    return fixed4(col, alpha);
				}

在上面这个shader中,atten就是具体显示哪个像素需要显示阴影的地方。(具体的实现方式其实跟shadowmaptexture相关,大家可以自行看unity的shader)

那么我们分析如果不显示阴影的话,那么atten必须为1.

所以如果我们要让显示的阴影改变颜色的话就是改变col了,可以在atten不为1的时候给col乘上一个颜色。(如果你需要增加对比度或明暗度则可以转为hsv来运算)

col = fixed3(col.r * (atten < 1 ? _ShadowColor.r : 1) * atten, col.g * (atten < 1 ? _ShadowColor.g : 1) * atten, col.b * (atten < 1 ? _ShadowColor.b : 1) * atten);

具体shader为

Tags
		{
			"Queue"="Geometry"
			"RenderType"="Environment"
			"LightMode"="ForwardBase"
		}
		Lighting Off
		Fog { Mode Off }
		Cull Back
		ZWrite On
		ZTest LEqual
		Blend Off
		Subshader
		{
			LOD 400
			Pass
			{
				CGPROGRAM
				#include "UnityCG.cginc"
				#include "Lighting.cginc"
				#include "AutoLight.cginc"
				#include "Assets/Scripts/Rendering/Shaders/Lib/EBG_Globals.cginc"
				#pragma target 3.0
				#pragma vertex vertex_shader
				#pragma fragment fragment_shader
				#pragma multi_compile_fwdbase
				//EBG_FOG_ON EBG_DYNAMIC_SHADOWS_ON EBG_LIGHTMAP_ON EBG_VERTEX_LIGHTING_OFF EBG_ALPHA_CUTOFF_OFF EBG_HIGHLIGHTS_IGNORE_ALPHA_OFF EBG_REFLECTIONS_OFF EBG_PLANAR_REFLECTIONS_OFF EBG_FRESNEL_OFF EBG_DISABLE_LIGHTMAP_OFF
				sampler2D _MainTex;
				struct Input
				{
				    float4 vertex : POSITION;
				    float2 texcoord0 : TEXCOORD0;
				    float3 normal : NORMAL;
				    float2 texcoord1 : TEXCOORD1;
				};
				struct VtoS
				{
				    float4 pos : SV_POSITION;
				    float3 uv_main_fog : TEXCOORD0;
				    float2 uv_lm : TEXCOORD1;
				    float4 _ShadowCoord : TEXCOORD8;
				    float3 worldN : TEXCOORD9;
				};
				float4 _MainTex_ST;
				float4 _ShadowColor;
				VtoS vertex_shader(Input v)
				{
				    VtoS data;
				    data.pos = UnityObjectToClipPos(v.vertex);
				    data.uv_main_fog.xy = v.texcoord0.xy * _MainTex_ST.xy + _MainTex_ST.zw;
				    data.uv_main_fog.z = EBGFogVertex(v.vertex);
				    data.uv_lm = v.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
				    float3 worldN = normalize(mul((float3x3)unity_ObjectToWorld, v.normal));
				        data.worldN = worldN;
				    data._ShadowCoord = float4(0,0,0,0);
				    TRANSFER_VERTEX_TO_FRAGMENT(data);
				    return data;
				}
				float4 fragment_shader(VtoS IN) : COLOR0
				{
				    fixed4 mainTex = tex2D(_MainTex, IN.uv_main_fog.xy);
				    fixed3 col = mainTex.rgb;
				    col *= _EBGEnvLightColorScale;
				    col *= _EBGEnvScale;
				    half3 light = 1;
				         half3 bakedColor = DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, IN.uv_lm.xy));
				   light = bakedColor;
				    col *= light;
				    fixed alpha = 1.0;
				    col = EBGFogFragment(col, IN.uv_main_fog.z);
				    col = col * _EBGEnvAdjustScale + _EBGEnvAdjustOffset;
					float atten = SHADOW_ATTENUATION(IN);
					//col = col * atten;
					col = fixed3(col.r * (atten < 1 ? _ShadowColor.r : 1) * atten, col.g * (atten < 1 ? _ShadowColor.g : 1) * atten, col.b * (atten < 1 ? _ShadowColor.b : 1) * atten);
				    return fixed4(col, alpha);
				}
				
				ENDCG
			}
		}

当然_ShadowColor是一个颜色值,初始时4个1。

_ShadowColor("Shadow Color", Color) = (1, 1, 1, 1)

然后我们再看阴影,他会根据你的shaowcolor变色了。

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值