Shader编程

Unity Shader 入门(一) SurfaceShade

2020-11-23  本文已影响0人  xzhuan

xzhuan原创稿件,转载请注明出处!

//-------------------------------【Unity右键路径】-----------------------------------------
Shader "Custom/MySurfaceShader"
{
   //-------------------------------【Shader属性】-----------------------------------------
   Properties
   {
       // Color :颜色 Inspector面板里会有一个选取颜色的picker
       // Range :某范围内的浮点数 Inspector面板里会出现一个Slider
       // 2D :   2D纹理
       // Rect : 创建非2次方边长的纹理
       // Cube : 创建Cube Map,也是一种纹理
       // Float :浮点数,和Range的区别就是Range是一个范围内的数,Float是单个数
       // Vector:向量 定义一个四元素的容器
       _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
   {
       //----------------------------【标签】---------------------------  
       //Queque 渲染顺序       BackGround/Geometry
       //RenderType 渲染类型   Opaque不透明/Transparent透明
       Tags { "RenderType"="Opaque" }
       //Level of Detail
       LOD 200

       //CG程序 开始
       CGPROGRAM
       // Physically based Standard lighting model, and enable shadows on all light types
       //说明是surface shader,可以换成Vertex或Fragment,surf是表面处理函数,在代码段的下面就有一个surf函数。Standard fullforwardshadows是光照模型函数。
       #pragma surface surf Standard fullforwardshadows

       // Use shader model 3.0 target, to get nicer looking lighting
       //设置编译目标Shader model的版本
       #pragma target 3.0

       //在surf函数的上面,将properties里的变量用相同的名称定义一遍。还有一个Input结构体,这是输入结构
       sampler2D _MainTex;

       struct Input
       {
           float2 uv_MainTex;
       };

       half _Glossiness;
       half _Metallic;
       fixed4 _Color;

       // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
       // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
       // #pragma instancing_options assumeuniformscaling
       UNITY_INSTANCING_BUFFER_START(Props)
       // put more per-instance properties here
       UNITY_INSTANCING_BUFFER_END(Props)

       void surf (Input IN, inout SurfaceOutputStandard o)
       {
           // Albedo comes from a texture tinted by color
           //先定义了一个4元的定点数c,tex2D是纹理采样函数,第一个参数是纹理,第二个参数是uv坐标,函数的返回值乘以颜色
           fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
           //o这个变量就是着色器会输出的变量,也就是存储着我们眼睛会看到的效果的变量
           //后面的语句的意思就是将各个值赋给o里的不同值。rgb就是RGB颜色,Albedo是反射值,Metalic是金属值,Smoothness是光滑值,Alpha是透明通道
           o.Albedo = c.rgb;
           // Metallic and smoothness come from slider variables
           o.Metallic = _Metallic;
           o.Smoothness = _Glossiness;
           o.Alpha = c.a;
       }
       //CG程序 结束
       ENDCG
   }

   //备胎: 表示前面的着色程序显卡不支持的时候就用默认的“Diffuse”
   FallBack "Diffuse"
}

CG数据结构 类型

CG支持7种数据类型:
float 32位浮点数
half 16位浮点数
int 32位整型数
fixed 12位定点数
bool 布尔数据
sampler 纹理对象的句柄,公有sampler, sampler1D, sampler2D, sampler3D, samplerCUBE, 和 samplerRECT 六种
string 字符,其实没有必要在CG中用到字符
向量类型 float2就是2元的float类型的向量,fixed4就是4元的fixed类型的向量
向量最长不超过4元
此外,CG还支持矩阵数据类型,比如:
float2×4 matrix; // 表示2×4阶矩阵,包含8个float类型数据

surface shader的输入输出结构:
输入结构就是存储输入的信息,输出结构就是存储要输出的信息,也就是我们的眼睛会看见的效果。
struct Input
{
float2 uv_MainTex;
}
纹理坐标必须命名为“uv”+"纹理名称",uv_MainTex就是名为_MainTex的纹理的uv坐标。

surface shader的默认的几种输出结构如下,输出结构也是可以自定义的。
struct SurfaceOutput
{
fixed3 Albedo; // 漫反射颜色
fixed3 Normal; // 切线空间法线,如果赋值的话
fixed3 Emission; // 自发光颜色
half Specular; // 高光强度,范围是0-1
fixed Gloss; // specular intensity
fixed Alpha; // 透明度
};
struct SurfaceOutputStandard
{
fixed3 Albedo; // 基础 (漫反射或镜面反射) 颜色
fixed3 Normal; // 切线空间法线,如果赋值的话
half3 Emission; // 自发光颜色
half Metallic; // 0=非金属, 1=金属
half Smoothness; // 0=粗糙, 1=光滑
half Occlusion; // 遮挡(默认1)
fixed Alpha; // 透明度
};
struct SurfaceOutputStandardSpecular
{
fixed3 Albedo; // 漫反射颜色
fixed3 Specular; // 镜面反射颜色
fixed3 Normal; // 切线空间法线,如果赋值的话
half3 Emission; // 自发光颜色
half Smoothness; // 0=粗糙, 1=光滑
half Occlusion; // 遮挡(默认1)
fixed Alpha; // 透明度
};

那么定义变量的时候怎么知道该用哪种类型呢?

  1. 精度够用就好
  2. 颜色和单位向量,使用fixed
  3. 其他情况,尽量使用half(即范围在[-6万, +6万]内、精确到小数点后3.3位);否则才使用float。
上一篇下一篇

猜你喜欢

热点阅读