渲染流水线(课外科普):
数据类型:
常见的有这几种
float、half、fixed(三个都是浮点型 只是精度不一样)
float // 32位浮点数, 精度: 小数点后6位, 适用: 模型坐标、纹理uv坐标,复杂函数计算,如:三角函数,幂运算等等;
half // 16位浮点数, 精度: 小数点后3位, 数值范围为[-60000,+60000],适用: 模型坐标、纹理uv坐标,方向向量,HDR颜色等等。
fixed // 12位浮点数, 精度: 1/256, 数值范围为[-2,+2],适用: 光照计算、颜色
interger// (没用过,查阅资料一般用于数组索引)
bool // 8位布尔数
string // 字符串(没用过)
sampler2D_half(中精度2D纹理)
sampler2D_float(高精度2D纹理)
sampler3D_half(中精度3D纹理)
sampler3D_float(高精度3D纹理)
samplerCUBE_halft(中精度立方体纹理)
samplerCUBE_float(高精度立方体纹理)
Input:
//自定义结构输入语句,可更具需求添加,详细请查阅更多的资料
struct Input
{
float3 worldPos; // 世界坐标
float3 screenPos; // 屏幕坐标
half3 viewDir; // 摄像机拍摄方向
float4 color : COLOR; // 顶点颜色。
fixed2 uv_MainTex; // 纹理uv坐标(命名方式必须是uv_纹理变量名称)
fixed2 uv_NormTex; // 法线纹理uv坐标(命名方式必须是uv_法线纹理变量名称)
};
SurfaceOutput:
//固定结构体,不需要用户自定义。
struct SurfaceOutput
{
half3 Albedo; // 反射率, 即颜色纹理rgb (美术同学通常说的固有色)
half3 Normal; // 法线向量
half3 Emission; // 自发光颜色rgb
half Alpha; // 透明度
half Specular; // 镜面反射度
half Gloss; // 光泽度
};
函数:
// 数值计算
sign(x)、abs(x) // 符号、绝对值
min(a, b)、max(a, b) // 最值函数
ceil(x)、floor(x)、round(x) // 取整函数
frac(x) // 取小数部分
fmod(x, y) // 取余数
rap(x) // 倒数(1/x)
sqrt(x)、pow(x) // 幂函数
exp(x)、exp2(x) // 指数函数(e^x、2^x)
log(x)、log10(x)、log2(x) // 对数函数
degrees(x)、radians(x) // 角度转换函数
sin(x)、cos(x)、tan(x)、asin(x)、acos(x)、atan(x) // 三角函数
sinh(x)、cosh(x)、tanh(x) // 双曲线函数
saturate(x) // 将x约束在0和1之间, 超过边界就取边界值
clamp(x, min, max) // 将x约束在min和max之间, 超过边界就取边界值
smoothstep (min, max, x) // 平滑比例, 公式: k=saturate((x-min)/(max-min)), y=k*k*(3-2*k)
lerp(a, b, f) // 插值, 公式: y=x+f*(y-x), a、b可以是向量
// 向量计算
distance(pos1, pos2) // 计算pos1与pos2之间的距离
length(vec) // 计算向量的模长
normalize(vec) // 计算向量的单位向量
dot(vec1, vec2) // 向量点乘
cross(vec1, vec2) // 向量叉乘
reflect(i, n) // 根据入射向量和法线向量计算反射向量
// 矩阵计算
mul(M, N)、mul(M, v), mul(v, M) // M*N、M*v、v*M
// 纹理计算
tex2D(sampler2D, uv_Tex) // 查询纹理坐标对应的纹理值
UnpackNormal(color) // 根据法线纹理解析法线向量
详细参考文章
https://blog.csdn.net/sinat_34014668/article/details/127465475
Shader "Unlit/SurfShader"
{
//属性,暴露给程序使用;
Properties
{
_Color("COlor",color)=(1,1,1,1)
_MainTex ("Texture", 2D) = "white" {}
//Range(0,1)是把值限制在0~1之间,在unity面板上显示是滑块。
_Glass("Glass",Range(0,1))=1
_Metallic("Metallic",Range(0,1))=0
}
//表面着色器
SubShader
{
//定义渲染方式为不透明
Tags { "RenderType"="Opaque" }
LOD 100
CGPROGRAM
//#pragma 编译指令 surface 定义是表面着色器 命名为surf ,它的类型是基于物理的标准光照,
//fullforwardshadows 是启用阴影,他还可以写成Standard addshadow。
#pragma surface surf Standard fullforwardshadows
//着色器使用硬件的“shader model 3.0”的能力,不写默认是shader model 2.0.
#pragma target 3.0
//sampler2D就是和texture2D所绑定的一个数据容器接口,然后传入_MainTex。
sampler2D _MainTex;
half _Glass;
half _Metallic;
fixed4 _Color;
//half3 Albedo; 反射率,像素的固有色。
//half3 Normal; 法线方向
//half3 Emission; 自发光
//half Specular; 高光系数
//half Gloss; 光滑度(高光),值越大越光滑,反射越清晰,反之越粗糙,越模糊。
//half Alpha; 透明度。
//字面意思,输入结构体。
struct Input{
float2 uv_MainTex; //获取UV坐标值。
};
//Input i 是接入结构体Input,inout SurfaceOutputStandard o 是输出
void surf (Input i, inout SurfaceOutputStandard o) {
//输出结果(可转化为rgba,也可以不用,看最终运用,一般乘颜色的话,最好转化)
fixed4 c = tex2D (_MainTex, i.uv_MainTex).rgba * _Color;
//输出的反色率(固有色)为c ;
o.Albedo=c.rgb;
//输出的金属度为自定义属性里面_Metallic值;
o.Metallic=_Metallic;
//输出的光滑度为自定义属性里面_Glass;
o.Smoothness = _Glass;
//输出的透明度为c的alpha值,也可以属性里面定义一个值乘上去或者单独使用。
o.Alpha=c.a;
}
ENDCG
}
//遍历所有的SubShader ,当前设备显卡不支持时,返回到Diffuse shader上。
//所以,FallBack "Diffuse" 非常重要,FallBack会使用unity内置的一个通用阴影pass。
FallBack "Diffuse"
}