首页 > 学院 > 开发设计 > 正文

Unity3D The Blacksmith 角色阴影技术使用心得

2019-11-11 01:59:38
字体:
来源:转载
供稿:网友

     这个demo放出来之后,对其中的角色阴影部分的技术十分感兴趣,我就赶紧下过来研究了一下。官方的技术博客里有对这一部分技术的介绍,链接在这里:独特的角色阴影,

其中写到只要在其他shader里添加

#PRagma multi_compile _ UNIQUE_SHADOW UNIQUE_SHADOW_LIGHT_COOKIE#include "UniqueShadow_ShadowSample.cginc"这两行代码就能使用这个高级阴影了。 我之前也因为在做一些demo的时候发现unity默认阴影达不到理想效果,和ue4比起来还是有一定差距的。于是就想到使用这个阴影技术了。于是我兴致勃勃的把这两行代码和几个库文件加到我的shader和项目里去,一运行发现,高级阴影并没有出现。哎,看样子只能自己研究了。

   既然是阴影,那么着手点就是unity里的阴影部分的代码,手动写过自定义阴影的人应该都知道,unity阴影计算:SHADOW_COORDS、TRANSFER_SHADOW、SHADOW_ATTENUATION三个函数了,unity把阴影生成的代码都写在了这三个函数里,方便调用。我看The Blacksmith的技术博客上写着:  我们发现原来有一个非常简单的方法来对常见的Unity shader所用的阴影方法进行重写。 于是我琢磨着应该是他们也用了这三个方法,于是打开 UniqueShadow_ShadowSample.cginc 文件,果不其然,在最下面找到了这么一段代码

#if defined(UNITY_PASS_FORWARDBASE) || defined(UNITY_PASS_FORWARDADD) || defined(UNIQUE_SHADOW_FORCE_REPLACE_BUILTIN)	#undef SHADOW_COORDS	#undef TRANSFER_SHADOW	#undef SHADOW_ATTENUATION	#define SHADOW_COORDS(i)					UNIQUE_SHADOW_INTERP(i)	#define TRANSFER_SHADOW						o.uniqueShadowPos = mul(u_UniqueShadowMatrix, float4(worldPos.xyz, 1.f));	#define SHADOW_ATTENUATION(i)				UNIQUE_SHADOW_SAMPLE(i);#endif这里的意思就是,如果判断pass的名字是

UNITY_PASS_FORWARDBASE、NITY_PASS_FORWARDADD、UNIQUE_SHADOW_FORCE_REPLACE_BUILTIN

这三个的话,就会把   

SHADOW_COORDS(i) 替换成UNIQUE_SHADOW_INTERP(i),SHADOW_ATTENUATION(i)替换成UNIQUE_SHADOW_SAMPLE(i);TRANSFER_SHADOW的值替换成后面的 o.uniqueShadowPos这样的话就好说了,之后只要把自己的shader里生成阴影的pass名字改成三个里的任意一个,生成阴影的代码还是按照原来的方式写就可以了。于是我立马新建了一个Unlit Shader,添加上生成阴影的代码后,把pass的名字改成了UNITY_PASS_FORWARDBASE,代码如下

Shader "Custom/simpleSuperShadow"{	Properties	{		_MainTex ("Texture", 2D) = "white" {}	}	SubShader	{		Tags { "RenderType"="Opaque" }				LOD 100		Pass		{			Tags{ "LightMode" = "ForwardBase" }			CGPROGRAM			#pragma vertex vert			#pragma fragment frag			#pragma multi_compile_fwdbase			#include "UnityCG.cginc"			#include "AutoLight.cginc"#define UNITY_PASS_FORWARDBASE#pragma multi_compile _ UNIQUE_SHADOW UNIQUE_SHADOW_LIGHT_COOKIE#include "UniqueShadow/UniqueShadow_ShadowSample.cginc"								struct v2f			{				float2 uv : TEXCOORD0;				float4 pos : SV_POSITION;				float3 worldPos : TEXCOORD1;				SHADOW_COORDS(2)			};			sampler2D _MainTex;			float4 _MainTex_ST;						v2f vert (appdata_full v)			{				v2f o;				o.pos = mul(UNITY_MATRIX_MVP, v.vertex);				o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);						o.worldPos = mul(_Object2World, v.vertex).xyz;				TRANSFER_SHADOW(o);				return o;			}						fixed4 frag (v2f i) : SV_Target			{				// sample the texture				fixed4 col = tex2D(_MainTex, i.uv);				fixed shadow = SHADOW_ATTENUATION(i);				return col * shadow;			}			ENDCG		}	}		FallBack "Diffuse"}点击运行之后,shader报错,提示我顶点函数里worldPos未定义,报错的地方是在TRANSFER_SHADOW(o)这一行,但是我明明在v2f里定义了这个变量,并且在上一行赋值了才对。这个提示不应该出现才对。对于这个问题,我毫无头绪,不知道自己哪里出了问题。于是我又新建了一个standard surface shader,这次我只在里面添加了#pragma multi_compile _ UNIQUE_SHADOW UNIQUE_SHADOW_LIGHT_COOKIE#include "UniqueShadow/UniqueShadow_ShadowSample.cginc"两行,运行一下,居然成功了,于是我在编辑器里点开了surface shader的原始代码,通过仔细对比阴影生成的三个函数发现,surface shader在顶点函数使用worldPos的时候,并不是直接给o.worldPos赋值的,而是先定义了一个float3的worldPos变量,计算出来以后再让o.worldPos = worldPos,这里感觉应该是一样的才是,并没有什么特别的地方啊。虽然我不是很清楚surface shader里为啥要这么写,但是抱着试一试的心情,我把自己的shader的顶点函数从原来的

v2f vert (appdata_full v){	v2f o;	o.pos = mul(UNITY_MATRIX_MVP, v.vertex);	o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);			o.worldPos = mul(_Object2World, v.vertex).xyz;	TRANSFER_SHADOW(o);	return o;}这样,改成了

v2f vert (appdata_full v){	v2f o;	o.pos = mul(UNITY_MATRIX_MVP, v.vertex);	o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);	float3 worldPos = mul(_Object2World, v.vertex).xyz;	o.worldPos = worldPos;	TRANSFER_SHADOW(o);	return o;}这样,于是我运行一下。卧槽竟然成功了。按道理来说定义一个临时变量和直接赋值应该没有区别才是,为啥这里不定义一个就不行呢,mul(_Object2Wrold,v.vertex).xyz返回的本来就是一个float3的变量才是,为毛非要这么做才能正确显示呢。实在是不知道要怎么解释。希望知道的大大们能够帮我解释一下。总结一下这个高级阴影的使用方法1.给计算阴影的pass添加

#define UNITY_PASS_FORWARDBASE#pragma multi_compile _ UNIQUE_SHADOW UNIQUE_SHADOW_LIGHT_COOKIE#include "UniqueShadow/UniqueShadow_ShadowSample.cginc"

这三行代码,然后在顶点函数使用TRANSFES_SHADOW的地方改成float3 worldPos = mul(_Object2World, v.vertex).xyz;o.worldPos = worldPos;TRANSFER_SHADOW(o);这样自定义的shader也能够使用这个超高分辨率的阴影了。

这里我用了一个卡通shader做测试未使用高级阴影:使用高级阴影:这样就能做出媲美ue4的高级阴影来了。


上一篇:spring 头文件

下一篇:poj2550

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表