Shader "Unlit/Shader_deffer"
{
Properties
{
}
SubShader
{
Pass
{ ZWrite Off
//LDR Blend DstColor Zero HDR : Blend One One
Blend [_SrcBlend] [_DstBlend] //计算光照 叠加
CGPROGRAM
//Shader3.0;
#pragma target 3.0
#pragma vertex vert
#pragma fragment frag
// make fog work
// 后处理
#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;
struct a2v
{
float4 vertex:POSITION;
float3 normal:NORMAL;
};
unity_v2f_deferred vert(a2v i)
{
unity_v2f_deferred o;
o.pos = UnityObjectToClipPos(i.vertex);
o.uv = ComputeScreenPos(o.pos);
o.ray = UnityObjectToViewPos(i.vertex) * float3(-1,-1,1);
//_LightAsQuad 当在处理四边形时,也就是直射光时返回1,否则返回0
o.ray = lerp(o.ray, i.normal, _LightAsQuad);
return o;
};
#ifdef UNITY_HDR_ON
half4
#else
fixed4
#endif
frag(unity_v2f_deferred i):SV_TARGET
{
//float2 uv =i.uv.xy/i.uv.w;//算出真正uv的值
通过深度和方向重新构建世界坐标
//float depth=SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,uv);//_CameraDepthTexture unity自动返回
//depth=Linear01Depth(depth);//计算成为线性深度值
/ray 只能表示方向,长度不一定 _ProjectionParams.z是远平面, 因为xyz都是等比例,所以 _ProjectionParams.z/i.ray.z就是 rayToFraPlane向量和ray向量的比值
//float3 raytoPlane=i.ray*(_ProjectionParams.z/i.ray.z);//ray的长度
//float4 viewPos=float4(raytoPlane*depth,1);//视角空间位置
//float3 worldPos=mul(unity_CameraToWorld,viewPos).xyz;
//float fadeDist=UnityComputeShadowFadeDistance(worldPos,viewPos.z);
float3 worldPos;
float2 uv;
half3 lightDir;
float atten;
float fadeDist;
UnityDeferredCalculateLightParams(i,worldPos,uv,lightDir, atten,fadeDist);
// //对光衰减的计算
// //如果是区域光
// #if defined(SPOT)
// float3 toLight = _LightPos.xyz-worldPos;
// half3 lightDir = normalize(toLight);
// float4 uvCookie = mul(unity_WorldToLight, float4(worldPos,1));
// //计算衰减 _LightTexture0无cookie衰减的采样
// float atten = tex2Dbias(_LightTexture0, float4(uvCookie.xy/uvCookie.w,0,-8)).w;
// atten *= uvCookie < 0;
// //使用cookie _LightTextureB0采样
// 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);
// //定义了方向光的cookie
// #if defined(DIRECTIONAL_COOKIE)
// float4 uvCookie = mul(unity_WorldToLight, float4(worldPos,1));
// atten *= tex2Dbias(_LightTexture0, float4(uvCookie.xy,0,-8)).w;//方向光不是透视不需要除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, -8)).w;//采样的是cubemap
// #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);
fixed3 viewDir = normalize(_WorldSpaceCameraPos - worldPos);
fixed3 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);//LDR
#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
}
}
}
复杂的延迟渲染,配合上一篇一起使用
于 2022-09-14 22:20:50 首次发布