关于Unity中Shader的使用
在游戏的开发过程中,程序员不太会自己去写shader,因为写起来很麻烦,而且只有Unity会报错,编译器也没有什么提示。
通常是拿别人的shader改一改,当然,程序员还是要能看懂和会一点shader
Unity坐标系转换
1: transform.localToWorldMatrix 局部转世界的矩阵;
2: transfrom.worldToLocalMatrix 世界坐标转局部坐标矩阵;
MultiplyPoint, MultiplyPoint3x4 MultiplayVector 来进行坐标变换;
4: shader中 左乘_World2Object矩阵来实现世界坐标转局部坐标变换;
5: shader中左乘_Object2World矩阵来实现局部转世界的转换;
6: UNITY_MATRIX_MV 基本变换矩阵 x 摄像机矩阵;
7: UNITY_MATRIX_MVP 基本变换矩阵x摄像机矩阵x投影矩阵;
8: UNITY_MATRIX_V 摄像机矩阵;
9: UNITY_MATRIX_P 投影矩阵;
10: UNITY_MATRIX_VP摄像机矩阵x投影矩阵;
11: UNITY_MATRIX_T_MV (基本变换矩阵 x 摄像机矩阵) 转置矩阵;
12: UNITY_MATRIX_IT_MV(基本变换矩阵 x 摄像机矩阵) 的逆转置矩阵;
13: UNITY_MATRIX_TEXTURE0 纹理变化矩阵;
GPU管道流水线
1: 主要的运算在GPU上计算,CPU插入指令;
2: 大致流程:
顶点着色器和片元着色器
1: 控制灵活,但不能参与光照计算;
2: 在着色器中插入Cg代码段,编写在CGPROGRAM 与 ENDCG之间;
3: 编译指令: #pragma控制 着色器代码编译。每一个Shader都有入口函数
#pragma vertex name 将名称为name的函数编译为顶点着色器;
#pragma fragment name 将名称为name的函数编译为片元着色器;
4: 参数和返回值有语义修饰
常用语义修饰
1:POSITION : 位置
2:TANGENT : 切线
3: NORMAL: 法线
4: TEXCOORD0: 第一套纹理
5: TEXCOORD1: 第二套纹理
6: TEXCOORD2: 第三套纹理
7: TEXCOORD3: 第四套纹理
8: COLOR: 颜色
Shader实例
1.创建好Unity工程目录
2.创建一个Cube物体
3.在resources文件夹下创建一个shaders文件夹
4.进入shaders,create---->Shader---->Standard Surface Shader---->重命名MyShader
5.打开MyShader
Shader "Custom/MyShader" { // 绑定到编辑器上去, shader程序里面可以使用; Properties { _Color ("Color", Color) = (1,1,1,1) _MainTex ("Albedo (RGB)", 2D) = "white" {} _Glossiness ("Smoothness", Range(0,1)) = 0.5 _Metallic ("Metallic", Range(0,1)) = 0.0 } SubShader { Pass { CGPROGRAM // 插入我们的Cg代码段开始标志 // 指定哪段代码是顶点shader,把my_vertex作为顶点shader的入口 #pragma vertex my_vertex // : 语义说明,怎么获得上一个工位的参数---->语义bind,告诉上一个工位我需要position参数,那么上一个工位就会给我们传这个参数,这里就可以使用 float4 my_vertex(float4 v : POSITION) : POSITION { return mul(UNITY_MATRIX_MVP, v); } // 指定哪段代码是片元着色shader #pragma fragment my_frag fixed4 my_frag() : COLOR{ return fixed4(1.0, 0, 0, 1.0); } ENDCG // 插入我们的Cg代码段结束标志 } } FallBack "Diffuse" }
6.在shaders文件夹下创建一个材质Material,命名为MyShader
7.在材质球的右上角的shader选项选择Custom---->MyShader
8.把材质球拖进Cube的材质属性里面
注意:
每个Shader有输入和输出,盒子有对应几个函数,函数有输入参数外加返回值的输出。