1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
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
}
}
}
|