Shader "Erika/Common/GBuffer" { //unity参数入口 Properties { _MainTex("贴图",2D) = "white"{} _Diffuse("漫反射",Color) = (1,1,1,1) _Specular("高光色",Color) = (1,1,1,1) _Gloss("平滑度",Range(1,100)) = 50 } SubShader { //非透明队列 Tags { "RenderType" = "Opaque" } LOD 100 //延迟渲染 Pass { //设置 光照模式为延迟渲染 Tags{"LightMode" = "Deferred"} CGPROGRAM // 声明顶点着色器、片元着色器和输出目标 #pragma target 3.0 #pragma vertex vert #pragma fragment frag //排除不支持MRT的硬件 //#pragma exclude_renderers norm // unity 函数库 #include"UnityCG.cginc" //定义UNITY_HDR_ON关键字 //在c# 中 Shader.EnableKeyword("UNITY_HDR_ON"); Shader.DisableKeyword("UNITY_HDR_ON"); // 设定hdr是否开启 #pragma multi_compile __ UNITY_HDR_ON // 贴图 sampler2D _MainTex; // 题图uv处理 float4 _MainTex_ST; // 漫反射光 float4 _Diffuse; // 高光 float4 _Specular; // 平滑度 float _Gloss; // 顶点渲染器所传入的参数结构,分别是顶点位置、法线信息、uv坐标 struct a2v { float4 pos:POSITION; float3 normal:NORMAL; float2 uv:TEXCOORD0; }; // 片元渲染器所需的传入参数结构,分别是像素位置、uv坐标、像素世界位置、像素世界法线 struct v2f { float4 pos:SV_POSITION; float2 uv : TEXCOORD0; float3 worldPos:TEXCOORD1; float3 worldNormal:TEXCOORD2; }; // 延迟渲染所需的输出结构。正向渲染只需要输出1个Target,而延迟渲染的片元需要输出4个Target struct DeferredOutput { //// RGB存储漫反射颜色,A通道存储遮罩 //float4 gBuffer0:SV_TARGET0; //// RGB存储高光(镜面)反射颜色,A通道存储高光反射的指数部分,也就是平滑度 //float4 gBuffer1:SV_TARGET1; //// RGB通道存储世界空间法线,A通道没用 //float4 gBuffer2:SV_TARGET2; //// Emission + lighting + lightmaps + reflection probes (高动态光照渲染/低动态光照渲染)用于存储自发光+lightmap+反射探针深度缓冲和模板缓冲 //float4 gBuffer3:SV_TARGET3; float4 normal : SV_TARGET0; float4 position : SV_TARGET1; }; // 顶点渲染器 v2f vert(a2v v) { v2f o; // 获取裁剪空间下的顶点坐标 o.pos = UnityObjectToClipPos(v.pos); // 应用uv设置,获取正确的uv o.uv = TRANSFORM_TEX(v.uv, _MainTex); // 获取顶点的世界坐标 o.worldPos = mul(unity_ObjectToWorld, v.pos).xyz; // 获取世界坐标下的法线 o.worldNormal = UnityObjectToWorldNormal(v.normal); return o; } // 片元着色器 DeferredOutput frag(v2f i) { DeferredOutput o; //// 像素颜色 = 贴图颜色 * 漫反射颜色 //fixed3 color = tex2D(_MainTex, i.uv).rgb * _Diffuse.rgb; //// 默认使用高光反射输出!! //o.gBuffer0.rgb = color; // RGB存储漫反射颜色,A通道存储遮罩 //o.gBuffer0.a = 1; // 漫反射的透明度 //o.gBuffer1.rgb = _Specular.rgb; // RGB存储高光(镜面)反射颜色, //o.gBuffer1.a = _Gloss / 100; // 高光(镜面)反射颜色 的 //o.gBuffer2 = float4(i.worldNormal * 0.5 + 0.5, 1); // RGB通道存储世界空间法线,A通道没用 //// 如果没开启HDR,要给颜色编码转换一下数据exp2,后面在lightpass2里则是进行解码log2 //#if !defined(UNITY_HDR_ON) // color.rgb = exp2(-color.rgb); //#endif //// Emission + lighting + lightmaps + reflection probes (高动态光照渲染/低动态光照渲染)用于存储自发光+lightmap+反射探针深度缓冲和模板缓冲 //o.gBuffer3 = fixed4(color, 1); o.normal = float4(i.worldNormal * 0.5 + 0.5, 1); o.position = float4(i.worldPos, 1); return o; } ENDCG } } }