【Unity3d Shader】角色投影与倒影

'

投影的计算公式:已知光线方向、投影面,和两个点A和B,求A和B在投影面上的位置A‘和B

倒影的计算公式:

Shader "mgo/hero_shadow_reflection" {
	Properties
	{
		_MainTex("Texture", 2D) = "white" {}

		_WorldPos("_WorldPos", Vector) = (0,0,0)
		_LightDir("_LightDir", Vector) = (33,33,33,0)
		_GroundPlane("_GroundPlane", Vector) = (0, 1, 0, 0) //xyz 地面法线方向,w地面高度
		_ShadowFadeParam("_ShadowFadeParam", Range(0, 1)) = 0.5
		_reflectionAlpha("_reflectionAlpha", Range(0, 1)) = 0.7
		_ReflectionWave("_ReflectionWave", Vector) = (0.5, 0.5, 0.5, 0.5)//x:y方向的振幅 y:y方向的频率 z:x方向的振幅 w:x方向的频率
		_ReflectionWaveSpeed("_ReflectionWaveSpeed", Range(0, 2)) = 0.5
	}

		SubShader
		{
			Tags{ "Queue" = "Transparent+5" "IgnoreProjector" = "true" "RenderType" = "Transparent" }
			 Pass//角色
			{
				ZWrite On
				Cull Back

				CGPROGRAM
				#pragma vertex vert
				#pragma fragment frag
			// make fog work
			#pragma multi_compile_fog

			#include "UnityCG.cginc"

			struct appdata
			{
				float4 vertex : POSITION;
				float2 uv : TEXCOORD0;
			};

			struct v2f
			{
				float2 uv : TEXCOORD0;
				UNITY_FOG_COORDS(1)
				float4 vertex : SV_POSITION;
			};

			sampler2D _MainTex;
			float4 _MainTex_ST;

			v2f vert(appdata v)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.uv = TRANSFORM_TEX(v.uv, _MainTex);
				UNITY_TRANSFER_FOG(o,o.vertex);
				return o;
			}

			fixed4 frag(v2f i) : SV_Target
			{
				// sample the texture
				fixed4 col = tex2D(_MainTex, i.uv);
			// apply fog
			UNITY_APPLY_FOG(i.fogCoord, col);
			return col;
		}
		ENDCG
	}

	Pass//阴影
	{
		Blend SrcAlpha  OneMinusSrcAlpha
		ZWrite On
		Cull Back

		ColorMask RGB
		Stencil
		{
			Ref 0
			Comp Equal
			WriteMask 255
			ReadMask 255
			Pass Invert
			Fail Keep
			ZFail Keep
		}

		CGPROGRAM
		#pragma vertex vert
		#pragma fragment frag
		#pragma multi_compile_fog
		#include "UnityCG.cginc"

		float4 _GroundPlane;
		float4 _LightDir;
		float4 _WorldPos;
		float _ShadowFadeParam;

		struct appdata
		{
			float4 vertex : POSITION;
			float2 texcoord : TEXCOORD0;
		};

		struct v2f
		{
			float3 texcoord0 : TEXCOORD0;
			float3 texcoord1 : TEXCOORD1;
			UNITY_FOG_COORDS(1)
			float4 vertex : SV_POSITION;
		};

		sampler2D _MainTex;
		float4 _MainTex_ST;


		v2f vert(appdata v)
		{
			v2f o;
			float3 lightdir = normalize(_LightDir);
			float4 worldpos = mul(unity_ObjectToWorld, v.vertex);
			float distance = (_GroundPlane.w + 0.01 - dot(_GroundPlane.xyz, worldpos.xyz)) / dot(_GroundPlane.xyz, lightdir.xyz);
			worldpos.xyz = worldpos.xyz + distance * lightdir.xyz;
			o.vertex = UnityWorldToClipPos(worldpos);
			o.texcoord0 = _WorldPos.xyz;
			o.texcoord1 = worldpos.xyz;
			UNITY_TRANSFER_FOG(o, o.vertex);
			return o;
		}

		fixed4 frag(v2f i) : SV_Target
		{
			float4 color;
			color.rgb = 0;
			color.a = 1.0 - saturate(distance(i.texcoord0, i.texcoord1) * _ShadowFadeParam);
			UNITY_APPLY_FOG(i.fogCoord, col);
			return color;
		}
		ENDCG
	}


	Pass//倒影
	{
		Blend SrcAlpha  OneMinusSrcAlpha
		ZWrite On
		Cull Front

		CGPROGRAM
		#pragma vertex vert
		#pragma fragment frag
		#pragma multi_compile_fog
		#include "UnityCG.cginc"
		#define PI 3.1415926

		float4 _GroundPlane;
		half _reflectionAlpha;
		float4 _ReflectionWave;
		float _ReflectionWaveSpeed;
		sampler2D _MainTex;
		float4 _MainTex_ST;

		struct appdata
		{
			float4 vertex : POSITION;
			float2 uv : TEXCOORD0;
		};

		struct v2f
		{
			float2 texcoord0 : TEXCOORD0;
			float2 texcoord1 : TEXCOORD1;
			UNITY_FOG_COORDS(1)
			float4 vertex : SV_POSITION;
		};

		//params.x: 1,y方向的振幅
		//params.y: 1,y方向的频率
		//params.z: 1,x方向的振幅
		//params.w: 1,x方向的频率
		half3 Wave(float3 vertex, float speed, float4 params)
		{
			half3 result;
			half3 phase = (vertex + speed * half3(_Time.y, _Time.y, _Time.y))* PI * 2;
			result.y = params.x * sin(params.y * phase.x);
			result.x = params.z * sin(params.w * phase.y);
			result.z = 0;
			return result;
		}

		v2f vert(appdata v)
		{
			v2f o;
			float4 worldpos = mul(unity_ObjectToWorld, v.vertex);
			worldpos.y -= _GroundPlane.w;
			worldpos.xyz = reflect(worldpos.xyz, normalize(_GroundPlane.xyz));
			worldpos.y += _GroundPlane.w;
			worldpos.xyz += Wave(worldpos.xyz, _ReflectionWaveSpeed, _ReflectionWave);//波动
			o.vertex = UnityWorldToClipPos(worldpos);
			o.texcoord0 = TRANSFORM_TEX(v.uv, _MainTex);
			o.texcoord1.x = -worldpos.y + _GroundPlane.w;
			UNITY_TRANSFER_FOG(o, o.vertex);
			return o;
		}
		fixed4 frag(v2f i) : SV_Target
		{
			clip(i.texcoord1.x);
			fixed4 col = tex2D(_MainTex, i.texcoord0);
			col.a *= _reflectionAlpha;
			UNITY_APPLY_FOG(i.fogCoord, col);
			return col;
		}
		ENDCG

	}
		}
			Fallback "Diffuse"
}

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Unity ASE(Amplify Shader Editor)是Unity的一款强大的着色器编辑器插件。它允许开发者在Unity中创建和定制高度复杂的着色器,以实现更好的图形效果。 首先,安装Unity ASE需要先下载插件文件。我们可以在Unity Asset Store或Amplify Creations的官方网站上下载ASE的安装包。安装包通常是一个.unitypackage文件。 在Unity编辑器中,我们可以通过双击.unitypackage文件,或者在Unity菜单中选择"Assets" -> "Import Package" -> "Custom Package"来打开ASE安装程序。 安装程序会显示有关要导入的文件和文件夹的信息。我们可以查看并选择要导入的内容。一般我们会选择所有的文件和文件夹,以确保所有的功能都能正常使用。然后点击"Import"按钮开始导入过程。 导入过程可能需要一些时间,具体取决于电脑的性能和文件大小。一旦导入完成,我们可以在Unity编辑器的菜单栏中看到ASE的选项。 要在项目中使用ASE,我们可以创建一个新的着色器材质,并将Amplify Shader Editor添加到该材质的着色器中。我们可以通过在材质检视器中选择"Shader"属性,然后从弹出的列表中选择ASE来设置ASE着色器。 在ASE编辑器中,我们可以通过将节点连接在一起来创建着色器的各个部分。我们可以通过拖动节点、调整参数和使用各种节点来实现所需的图形效果。 完成着色器的编辑后,我们可以将其应用到游戏对象或场景中,以查看效果。我们可以在Unity中进行实时预览和调整,以便实现理想的视觉效果。 通过以上步骤,我们就可以成功安装和使用Unity ASE插件来创建和定制着色器,以提升游戏或应用的图形效果。 ### 回答2: Unity ASE(Amplified Shader Editor)是一款强大的着色器编辑器,可用于在Unity开发环境中创建和编辑自定义着色器。以下是关于如何安装Unity ASE的步骤: 首先,确保您已经安装了最新版本的Unity编辑器。在Unity官方网站上下载并安装适用于您的操作系统的Unity编辑器。 接下来,打开Unity编辑器并创建一个新的Unity项目或打开现有的项目。 在Unity编辑器中,单击“窗口(Window)”菜单,然后选择“软件包管理器(Package Manager)”。 在软件包管理器面板中,确保您正在查看的是“Unity 注册表(Unity Registry)”选项卡。然后,搜索“Amplify Shader Editor”。您将看到Unity ASE的最新版本。 单击“下载(Download)”按钮开始下载和安装Unity ASE。 下载和安装完成后,您将在Unity编辑器的“窗口(Window)”菜单中找到Unity ASE选项。单击它以打开Unity ASE编辑器。 现在,您已成功安装Unity ASE。您可以使用Unity ASE编辑器创建和编辑自定义着色器,并将其应用于您的Unity项目中的对象上。 请注意,Unity ASE是一个商业插件,并且需要购买许可证才能在商业项目中使用。您可以在Amplify Creations官方网站上获取更多关于许可证和定价的信息。 希望以上信息对您有所帮助,并顺利安装Unity ASE。 ### 回答3: Unity ASE是Unity游戏开发引擎的一款插件,用于创建和编辑游戏中的着色器(Shader)。下面是Unity ASE的安装步骤: 首先,需要先下载Unity ASE插件。可以在Unity的Asset Store或者官方网站上找到Unity ASE的下载链接。点击下载链接,选择适用于自身版本的插件。 下载完成后,解压缩插件文件。你会得到一个.unitypackage文件。 接下来,打开Unity游戏开发引擎。如果还没有Unity的话,需要先下载并安装Unity。 在Unity中,打开“Assets”菜单,选择“Import Package”>“Custom Package”。 浏览文件资源管理器,找到之前下载并解压的.unitypackage文件,选择打开。 Unity会显示一个面板,列出了即将导入的Unity ASE插件文件。确保所有文件都处于选中状态,然后点击“Import”按钮。 Unity会自动导入插件文件并将其添加到项目中。导入完成后,你会看到Unity ASE的文件夹出现在项目的“Assets”目录下。 现在,你可以开始使用Unity ASE插件了。可以在Unity的Material属性面板上找到ASE按钮,点击它可以打开Unity ASE插件的编辑界面。 通过Unity ASE,可以创建新的着色器、修改现有的着色器、调整材质的渲染效果等等。你可以在Unity ASE的官方网站上找到更多关于如何使用该插件的教程和文档。 总结一下,安装Unity ASE包括下载插件、导入插件到Unity项目中,然后就可以开始使用该插件进行游戏着色器的创建和编辑了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值