PA1 Shader Fundamentals
Shader 与渲染算法 - 基础 - 着色器基础
1 世界伊始:A Yellow Bing

1.1 准备工作
1.2 粗糙的想法 Rough Idea
vertex shader:将物体好端端放在屏幕上即可;
fragment shader:直接返回一个 “定义的颜色”;
“” 应当使 Unity 编辑器的观众看到,方便实时修改。
1.3 CODING
// shader 版本的 Hello World
Shader "Code/PA1_Fundamental/YellowSphere"
{
Properties {
_Tint("Tint", Color) = (1,1,0,1) // Tint,英文 “染色”
}
SubShader {
Pass {
CGPROGRAM
#pragma vertex Vert
#pragma fragment Frag
#include "UnityCG.cginc"
float4 _Tint;
// 顶点坐标使用 MVP 变换,从物体局部坐标转换为屏幕空间坐标
float4 Vert(float4 position: POSITION): SV_POSITION {
return mul(unity_MatrixMVP, position);
}
// 直接返回在 Properties 中定义的 _Tint
float4 Frag(): SV_Target {
return _Tint;
}
ENDCG
}
}
}
2 传递更多:渐变饼饼

2.1 粗糙的想法 Rough Idea
vertex shader:坐标作为颜色插值(xyz -> rgb)。传回物体空间坐标;
fragment shader:将物体空间坐标映射到颜色值,再乘以 Tint,从而得到色彩滤镜效果;
refactor:通过 structure 封装数据,进行多数据在 vertex shader 与 fragment shader 之间的数据传递。
2.2 CODING
CGPROGRAM
#pragma vertex Vert
#pragma fragment Frag
#include "UnityCG.cginc"
float4 _Tint;
struct Interpolators {
float4 position: SV_POSITION;
float3 localPosition: TEXCOORD0;
};
Interpolators Vert(float4 position: POSITION) {
Interpolators i;
i.localPosition = position.xyz;
i.position = mul(unity_MatrixMVP, position);
return i;
}
float4 Frag(Interpolators i): SV_TARGET {
return float4(i.localPosition + 0.5, 1) * _Tint;
}
ENDCG
3 UV 初步:可视化 UV 坐标

3.1 粗糙的想法 Rough Idea
vertex shader:传回物体顶点 UV 坐标(
物体空间坐标);fragment shader:将 UV 坐标映射为颜色的四个分量。
3.2 CODING
// 使用 struct 重构代码
CGPROGRAM
#pragma vertex Vert
#pragma fragment Frag
#include "UnityCG.cginc"
struct VertexData {
float4 position: POSITION;
float2 uv: TEXCOORD0;
};
struct Interpolators {
float4 position: SV_POSITION;
float2 uv: TEXCOORD0;
// float3 localPosition: TEXCOORD0;
};
Interpolators Vert(VertexData v) {
Interpolators i;
// i.localPosition = v.position.xyz;
i.uv = v.uv;
i.position = mul(unity_MatrixMVP, v.position);
return i;
}
float4 Frag(Interpolators i): SV_TARGET {
// return float4(i.localPosition + 0.5, 1) * _Tint;
return float4(i.uv, 1, 1);
}
ENDCG
4 UV 进步:花纹球球

4.1 粗糙的想法 Rough Idea
添加一个可以放材质(及其控制柄)的地方;
vertex shader:物体顶点 UV 坐标考虑材质 Tilling 和 Offset;
fragment shader:输出材质的采样。
4.2 CODING
Shader "Code/PA1_Fundamental/UVTexture"
{
Properties {
_MainTex("Texture", 2D) = "white"{}
}
SubShader {
Pass {
CGPROGRAM
#pragma vertex Vert
#pragma fragment Frag
#include "UnityCG.cginc"
;
;
struct VertexData {
float4 position: POSITION;
float2 uv: TEXCOORD0;
};
struct Interpolators {
float4 position: SV_POSITION;
float2 uv: TEXCOORD0;
};
Interpolators Vert(VertexData v) {
Interpolators i;
// i.uv = v.uv * _MainTex_ST.xy + _MainTex_ST.zw;
i.uv = TRANSFORM_TEX(v.uv, _MainTex);
i.position = mul(unity_MatrixMVP, v.position);
return i;
}
float4 Frag(Interpolators i): SV_TARGET {
return tex2D(_MainTex, i.uv);
}
ENDCG
}
}
}


APPENDIX
Anki
Reference
Last updated