(1) 表面着色器和纹理映射
下面这个 图 呢 是我们 unity3d Shader 的 一个 工作流程图
大体流程:
- 逐定点修改器 用于模型顶点的修改操作(如果没有需要的话可以直接下一个步骤);顶点修改器的 输出参数 是我们的 表面着色器的 输入参数,( Input ) 如果没有修改就是 原样输出
- 表面(函数)着色器 经过一系列 需要的计算, 将结果输入到 SurfaceOutput 中 做为 光照模型的 传入参数
- 光照模型 使用表面函数 输入的信息 以及场景中的 光源信息 结合 (物理计算) 最后到的 像素点的颜色信息
其中 Input SurfaceOutput 这两个结构体 分别是
- Input 表 面函数输入 结构体
- SurfaceOutput 表 面函数输出 结构体
后面的 章节 也就是围绕这个五个 部分 进行详细的讲解
漫反射着色原理:
一个标准的 漫反射shader
Shader "Custom/chapter02/CustomDiffuse"
{
Properties
{
_Color ("Color", Color) = (1,1,1,1)
}
SubShader
{
Tags { "RenderType"="Opaque" } //渲染类型为不透明
LOD 200
CGPROGRAM //*****渲染队 开始 标记
//第一个 编译器指令 指定了用到的表面函数 以及 光照模型 还有其他的 渲染设置
//-surface surf
//指定当前表面 处理函数为 surf
//-Standard
//使用的是标准的 光照模型 unity 为我们提供的 一个标准光照模型资源 ;这里也可以自定义光照模型
//-fullforwardshadows
//使用的阴影效果
#pragma surface surf Standard fullforwardshadows
//第二个 编译器指令 指定了 使用的 shader 模型版本为 3.0
#pragma target 3.0
// 表面函数的 输入结构体 (应为Unity shader 输入结构体 不能为 空,所以即使没有 贴图 这里也不能为 空)
struct Input
{
float2 uv_MainTex;
};
//为属性值 关联的变量
fixed4 _Color;
UNITY_INSTANCING_BUFFER_START(Props)
UNITY_INSTANCING_BUFFER_END(Props)
//表面处理函数
//--Input IN
//表面输入结构体
//
//--inout SurfaceOutputStandard
//标准表面输出结构体; 填充完毕之后 就会返回到 标准光照模型 standard 里面进行光照计算 最终会到的像素值
void surf (Input IN, inout SurfaceOutputStandard o)
{
fixed4 c = _Color;
o.Albedo = c.rgb;
}
ENDCG //*****渲染队 结束 标记
}
FallBack "Diffuse"
}
设置光照模型 为 兰伯特光照模型 lambert, 相对于 标准光照模型 SurfaceOutput; lambert 更简单 运算更快 修改两个地方就可以
#pragma surface surf Lambert fullforwardshadows
void surf (Input IN, inout SurfaceOutput o)
{
fixed4 c = _Color;
o.Albedo = c.rgb;
}
//Lambert 光照的模型 需要对应的 表面函数 输出结构体
压缩 数组 压缩矩阵:
Unity Shader 重要 数据类型 压缩 数组; CG 里面有两种数据类型
- 单值 : float int
- 压缩数组 : float3 int4
- 压缩矩阵 : float4*4(4*4的 float 矩阵)
压缩数组 可以拆分:
float3 ==> {x, y, z} || {r, g, b}
float4 ==> {x, y, z,w} || {r, g, b,a}
压缩数组的
● 混写:swizzling
--CG o.Albdeo = _Color.rgb --C# 示例 非真实 CG 代码 o.Albdeo.r = _Color.r o.Albdeo.g = _Color.g o.Albdeo.b = _Color.b
调换 RGB 通道 值
_Color.brg //就能达到 调换 R 通道 和 B 通道的值
● 涂抹:smearing
单值 赋给 压缩数字; 压缩数组的各个 分量 均被 赋值
o.Albedo = 0 //(0,0,0)
● 遮罩:masking 只对 压缩数组 指定分量 进行赋值
o.Albedo.rg = _Color.rg
● 压缩矩阵
float4*4 matrix; // 4*4 压缩矩阵 //... .. . float first = matrix._m00; // 得到第一行 第一列的 数据 float last = matrix._m33; // 得到第三行 第三列的 数据 _mrc float4 diagonal = matrix._m00_m11_m22_m33 //连式获取 对角线矩阵数据 float4 firstRow = matrix[0] //获取矩阵 第一行数据 float4 firstRow1= matrix._m00_m01_m02_m03 //获取矩阵 第一行数据 (连式方式)