前部分知识复习04

一、深度测试与深度写入

深度:像素距离摄像机的远近,离摄像机越近,深度越小;离摄像机越远,深度越大;

 默认深度值为 1

深度测试(ZTest):将当前像素的深度值与深度缓冲中的深度值进行比较,满足条件则通过测试;比较的语法有Less、Greater、Equal等

深度写入(ZWrite):前提是已经通过了深度测试 

例如:ZWrite On / ZWrite Off

 在制作半透明的效果时一般将深度写入关闭 (ZWrite Off)


Pass
{
   ZWrite On;       //代表写入最前面的深度
   ColorMask 0    //代表不写入任何颜色
}

在半透明模型的Shader中增加上面Pass,可以解决复杂模型在实现半透明效果时出现背面的情况


  • 待解决的问题:

突然灵感一来,想到了为什么会出现这样的效果

如图三,因为当前一个Pass打开深度写入后,深度缓冲中的默认值为该模型最前面像素的深度值(也就是离摄像机最近的模型像素的深度值),在当渲染下一个Pass时,当条件为Greater(大于)通过测试时,这时只会渲染比离摄像机最近模型的深度值还大的地方,所以就等会出现如图三所式的情况

所以如图二,关闭前一个Pass的深度写入后就不会出现这样的效果

图四,前一个Pass打开深度写入后,在下一个Pass中当深度测试为小于时,当前Pass模型的所有像素的深度值,不是等于就是大于深度缓冲中的值,所以全部不通过(离摄像机越近,深度值越小)

图五,深度测试为小于等于时,离摄像机最近的模型像素的深度值等于当前深度缓冲中的深度值,通过测试,但是后面的模型像素的深度值大于当前深度缓冲中的深度值,测试不通过,这样就解决了半透明模型渲染出背面的问题

但是,此时还没有想到能够解决图一中所示情况的有效办法!!!!!

二、菲尼尔效果实现

菲尼尔:1-dot(N,V)

float3 N=normalize(i.worldNormal);


float3 V=normalize(_WorldSpaceCameraPos-i.worldPos);

 流光效果的实现:

float v=frac(i.worldPos.y*2+_Time.y);
c*=v;

 代码:

Shader"unity/practices01"
{
	Properties
	{
		_Kd("Kd",float)=1
		_Kd2("Kd2",float)=1
		[Enum(UnityEngine.Rendering.BlendMode)]_DstBlend("DstBlend",int)=0
		[Enum(UnityEngine.Rendering.BlendMode)]_SrcBlend("SrcBlend",int)=0
		[Enum(UnityEngine.Rendering.CompareFunction)]_ZTest("ZTest",int)=0
		_Color("Color",Color)=(1,1,1,1)
	 }

	SubShader
	{   
		// Pass
		// {
		// 	ZWrite On
		// 	ColorMask 0
		//  }
		
		Tags{"Queue"="Transparent"}

		Blend [_DstBlend] [_SrcBlend]
	
		Pass
		{
			ZTest [_ZTest]
			ZWrite Off

			CGPROGRAM

			#pragma vertex vert
			#pragma fragment frag

			#include "UnityCG.cginc"

			float _Kd;
			float _Kd2;
			float4 _Color;

			struct appdate
			{
				float4 vertex : POSITION;
				float4 uv : TEXCOORD;
				float3 normal : NORMAL;
			 };

			struct v2f 
			{
				float4 pos : SV_POSITION;
				float4 uv : TEXCOORD;
				float3 worldNormal : TEXCOORD1;
				float4 worldPos : TEXCOORD2;
			 };

			v2f vert(appdate v)
			{
				v2f o;
				o.pos=UnityObjectToClipPos(v.vertex);
				o.uv=v.uv;
				o.worldNormal=UnityObjectToWorldNormal(v.normal);
				o.worldPos=mul(unity_ObjectToWorld,v.vertex);
				return o;
			 }

			float4 frag(v2f i):SV_Target
			{
				float4 c=float4(1,1,1,1);
				float3 N=normalize(i.worldNormal);
				float3 V=normalize(_WorldSpaceCameraPos-i.worldPos);
				float fresnel=_Kd2*pow(1-dot(N,V),_Kd);
				c=fresnel*_Color;
				float v=frac(i.worldPos.y*2+_Time.y);
				c*=v;
				return c;
			 }
			ENDCG
		 }
	 }

 }

三、Pass的复用

在需要使用的Pass中添加

Name "X"

在需要引用上面Pass的SubShader中添加

UsePass "unity/XXXX/X"     // 路径 (Pass的复用)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值