shader 延迟渲染后处理

Edit–>Project Settings–>Graphics中的Built-in Shader Settings中的Deferred默认是选择Built-in shader的,这是延迟渲染默认使用的后处理方式。我们选择Custom shader,然后将自己写的延迟渲染后处理的shader代码拖进去,也能实现相应的后处理效果。

shader代码如下:

Shader "MyShader/002-Deferred"
{
	Properties
	{

	}
	SubShader
	{

		Pass
		{
			ZWrite Off
			//LDR: Blend DstColor Zero       HDR: Blend One One
			Blend [_SrcBlend] [_DstBlend]

			CGPROGRAM

			#pragma target 3.0
			#pragma vertex vert
			#pragma fragment frag
			#pragma multi_compile_lightpass
			//排除不支持MRT的硬件
			//#pragma exclude_renderers norm
			#pragma multi_compile __ UNITY_HDR_ON

			#include"UnityCG.cginc"
			#include"UnityDeferredLibrary.cginc"
			#include"UnityGBuffer.cginc"

			sampler2D _CameraGBufferTexture0;
			sampler2D _CameraGBufferTexture1;
			sampler2D _CameraGBufferTexture2;
			sampler2D _CameraGBufferTexture3;

			struct a2v
			{
				float4 vertex:POSITION;
				float3 normal:NORMAL;
			};

			struct v2f
			{
				float4 vertex:SV_POSITION;
				float4 uv:TEXCOORD0;
				float3 ray:TEXCOORD1;
			};

			v2f vert(a2v v)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.uv = ComputeScreenPos(o.vertex);
				o.ray = UnityObjectToViewPos(v.vertex)*float3(-1, -1, 1);
				//_LightAsQuad 当在处理四边形时,也就是有直射光时返回1,否则返回0
				o.ray = lerp(o.ray, v.normal, _LightAsQuad);
				return o;
			}

			#ifdef UNITY_HDR_ON
			half4
			#else
			fixed4
			#endif
			frag(v2f i) :SV_Target
			{
				float3 worldPos;
				float2 uv;
				half3 lightDir;
				float atten;
				float fadeDist;
				UnityDeferredCalculateLightParams(i, worldPos, uv, lightDir, atten, fadeDist);
				//上面这几句代码可替代下面注释的这些代码!!!




				//float2 uv = i.uv.xy / i.uv.w;
				通过深度和方向重新构建世界坐标
				//float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv);
				//depth = Linear01Depth(depth);
				ray只能表示方向,长度不一定    _ProjectionParams.z是远平面,因为xyz都是等比例,所以_ProjectionParams.z / i.ray.z就是rayToFarPlane向量和ray向量的比值
				//float3 rayToFarPlane = i.ray*(_ProjectionParams.z / i.ray.z);
				//float4 viewPos = float4(rayToFarPlane*depth, 1);
				//float3 worldPos = mul(unity_CameraToWorld, viewPos).xyz;

				//float fadeDist = UnityComputeShadowFadeDistance(worldPos, viewPos.z);

				对不同的光进行光衰减计算 包括阴影计算
				//#if defined(SPOT)
				//	float3 toLight = _LightPos.xyz - worldPos;
				//	half3 lightDir = normalize(toLight);

				//	float4 uvCookie = mul(unity_WorldToLight, float4(worldPos, 1));
				//	float atten = tex2Dbias(_LightTexture0, float4(uvCookie.xy / uvCookie.w, 0, -8)).w;

				//	atten *= uvCookie < 0;

				//	atten *= tex2D(_LightTextureB0, dot(toLight, toLight)*_LightPos.w).r;

				//	atten *= UnityDeferredComputeShadow(worldPos, fadeDist, uv);
				//#elif defined(DIRECTIONAL)||defined(DIRECTIONAL_COOKIE)
				//	half3 lightDir = -_LightDir.xyz;
				//	float atten = 1.0;

				//	atten *= UnityDeferredComputeShadow(worldPos, fadeDist, uv);

				//	#if defined(DIRECTIONAL_COOKIE)
				//	float4 uvCookie = mul(unity_WorldToLight, float4(worldPos, 1));
				//	atten *= tex2Dbias(_LightTexture0, float4(uvCookie.xy , 0, -8)).w;
				//	#endif
				//#elif defined(POINT)||defined(POINT_COOKIE)
				//	float3 toLight = _LightPos.xyz - worldPos;
				//	half3 lightDir = normalize(toLight);

				//	float atten = tex2D(_LightTextureB0, dot(toLight, toLight)*_LightPos.w).r;

				//	atten *= UnityDeferredComputeShadow(worldPos, fadeDist, uv);

				//	#if defined(POINT_COOKIE)
				//	float4 uvCookie = mul(unity_WorldToLight, float4(worldPos, 1));
				//	atten *= texCUBEbias(_LightTexture0, float4(uvCookie.xyz, 0, -8)).w;
				//	#endif
				//#else
				//half3 lightDir = 0;
				//float atten = 0;
				//#endif





				half3 lightColor = _LightColor.rgb*atten;

				half4 gbuffer0 = tex2D(_CameraGBufferTexture0, uv);
				half4 gbuffer1 = tex2D(_CameraGBufferTexture1, uv);
				half4 gbuffer2 = tex2D(_CameraGBufferTexture2, uv);

				half3 diffuseColor = gbuffer0.rgb;
				half3 specularColor = gbuffer1.rgb;
				float gloss = gbuffer1.a * 50;
				float3 worldNormal = normalize(gbuffer2.xyz * 2 - 1);

				half3 viewDir = normalize(_WorldSpaceCameraPos - worldPos);
				half3 halfDir = normalize(lightDir + viewDir);

				half3 diffuse = lightColor * diffuseColor*max(0, dot(worldNormal, lightDir));
				half3 specular = lightColor * specularColor*pow(max(0, dot(worldNormal, halfDir)), gloss);

				half4 color = float4(diffuse + specular, 1);
				#ifdef UNITY_HDR_ON
				return color;
				#else
				return exp2(-color);
				#endif
				
			}
			ENDCG
		}

		//转码Pass,主要是对于LDR转码
		Pass
		{
			ZTest Always
			Cull Off
			ZWrite Off
			Stencil
			{
				ref[_StencilNonBackground]
				readMask[_StencilNonBackground]

				compback equal
				compfront equal
			}

			CGPROGRAM

			#pragma target 3.0
			#pragma vertex vert
			#pragma fragment frag
			#pragma exclude_renderers nomrt

			#include"UnityCG.cginc"

			sampler2D _LightBuffer;
		
			struct v2f
			{
				float4 vertex:SV_POSITION;
				float2 texcoord:TEXCOORD0;
			};

			v2f vert(float4 vertex:POSITION, float2 texcoord : TEXCOORD0)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(vertex);
				o.texcoord = texcoord.xy;
				#ifdef UNITY_SINGLE_PASS_STEREO
				o.texcoord = TransformStereoScreenSpaceTex(o.texcoord, 1.0);
				#endif
				return o;
			}

			fixed4 frag(v2f i):SV_Target
			{
				return -log2(tex2D(_LightBuffer,i.texcoord));
			}

			ENDCG
		}
    }
}

这个后处理代码有点难度,有兴趣的可以研究以下。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值