Unity Shader 编程之一

本文参考SIKI老师的Shader视频教程进行的学习总结

Shader介绍

unity中GameObject由Component组成,与渲染有关的两个组件Mesh FilterMesh Renderer
- Mesh Filter:存储一个Mesh(模型网格,就是模型由哪些三角面组成,组成一个什么样子的模型,三角面的一些顶点信息)
- Mesh Renderer:用来渲染模型的外观,就是样子,按照Mesh给它的皮肤,给它的颜色。通过Material(材质)控制模型渲染的样子
- Material:由贴图(可以没有,可以是单纯的颜色)和Shader组成
- Shader(着色器):实际上就是一小段程序它负责将输入的Mesh(网格)以指定的方式和输入的贴图或者颜色等组合作用,然后输出。绘图单元可以依据这个输出来将图像绘制到屏幕上。输入的贴图或者颜色等,加上对应的Shader,以及对Shader的特定的参数设置,将这些内容(Shader及输入参数)打包存储在一起,得到的就是一个Material(材质)。之后,我们便可以将材质赋予合适的renderer(渲染器)来进行渲染(输出)了。

OpenGL、DirectX介绍

图像编程接口。OpenGL稳定,可跨平台使用。DirectX由微软开发,Windows平台游戏基本上都使用DirectX开发。
shader可以认为是一种渲染命令 ,由opengl 或者dx进行解析,来控制渲染丰富多彩的图形。

Shader Language介绍

  • OpenGL: 使用GLSL 编写shader
  • DirectX 使用HLSL 编写shader
  • 英伟达 CG 编写shader(跨平台)
  • Unity中使用的是ShaderLab编写Unity中的Shader,是基于CG进行了封装

Unity Shader的分类

  • 表面着色器 Surface Shader
  • 顶点/片元着色器 Vertex/Fragment Shader
  • 固定函数着色器 Fixed Function Shader

Unity Shader的基本结构

Shader "Custom/MyShader"{
    Properties{

    }
    SubShader{
        Pass{
            CGPROGRAM
            ENDCG
        }
    }
    FallBack  "Diffuse"
}
  • Custom/MyShader :定义了Shader在Inspector面板中的路径
    这里写图片描述
  • Properties :Shader属性
  • SubShader :利用定义的Shader属性而实现的渲染代码来控制渲染的效果,Shader中可以包含多个SubShader,显卡运行效果的时候从第一个SubShader开始,如果第一个SubShader的效果都可以实现,那么就使用第一个SubShader,如果显卡发现这个SubShader里面的某些效果实现不了,它会自动运行下一个SubShader
  • Pass :一个SubShader 中必须包含一个Pass
  • FallBack :后备方案如果显卡发现没有满足的SubShader则会使用FallBack中定义的Shader

Properties属性介绍

    Properties{
        _Color("Color",Color) = (1,1,1,1) //颜色rgba
        _Vector("Vector",Vector) = (1,2,3,4) //一个四维向量
        _Int("Int",Int) = 123 //整数
        _Float("Float",Float) = 4.5 //浮点数
        _Range("Range",Range(0,100)) = 61 //浮点数范围
        _2D("2D",2D) = "white"{} //2D贴图
        _Cube("Cube",Cube) = "red"{} //Cube贴图(天空盒)
        _3D("3D",3D) = "white"{} //3D贴图
    }
  • 属性定义格式:变量名(Inpsector显示名,类型) = 默认值
    Unity Shader 编程之一_第1张图片
  • _2D、_Cube、 _3D:默认值为通过一个字符串后跟一个花括号指定。字符串要么为空,要么是内置的纹理名称,如“white”、“black”、“gray”或者”bump”,当在Inspector面板中该属性未指定图片时,则值为设置的纹理颜色,若设置了图片则值为图片的颜色
  • 属性的使用 :需在SubShader中重新定义
  SubShader{
        Pass{
            CGPROGRAM
            float4 _Color; //float4对应Color
            float4 _Vector; //float4对应Vector
            float _Int; //float对应Int
            float _Float; //float对应Float
            float _Range; //float对应Range
            sampler2D _2D; //sampler2D对应2D
            samplerCube _Cube; //samplerCube对应Cube
            sampler3D _3D; //sampler3D对应3D
            ENDCG
        }
    }
  • float、half、fixed 的区别:float为32位存储、half为16位存储范围为(-6万~6万)、fixed为11位存储范围为(-2~2),根据数据的类型对应相应的类型可节约显存空间

顶点、片元函数介绍

  • 基本结构
        SubShader{
            Pass{
                CGPROGRAM
#pragma vertex vert //顶点函数,这里只是申明了顶点函数的函数名为vert
#pragma fragment frag //片元函数,这里只是申明了片元函数的函数名为frag
                //a2v application to vertex
                struct a2v {
                float4 vertex : POSITION; //告诉Unity将模型空间下的顶点坐标填充给vertex
                float3 normal : NORMAL; //告诉Unity将模型空间下的法线方向填充给normal
                float4 texcoord : TEXCOORD0; //告诉Unity把第一套纹理坐标填充给texcoord
                };

                struct v2f {
                    float4 position : SV_POSITION;
                    float3 tempColor : COLOR0;
                };

                v2f vert(a2v v){
                    v2f f;
                    f.position = mul(UNITY_MATRIX_MVP, v.vertex); //将顶点坐标通过矩阵运算从模型空间转换到裁剪空间
                    f.tempColor = v.normal;
                    return f;
                }

                fixed4 frag(v2f f) : SV_TARGET{
                    return fixed4(f.tempColor,1); //顶点的法线作为返回的颜色值
                }
                ENDCG
            }
        }
  • 声明
#pragma vertex vert //顶点函数,这里只是申明了顶点函数的函数名为vert
#pragma fragment frag //片元函数,这里只是申明了片元函数的函数名为frag
  • 顶点函数的基本作用:是将顶点从模型空间变换到裁剪空间
  • 片元函数的基本作用:返回模型对应的屏幕上的每一个像素的颜色值
  • 参数语义
    从应用程序传递到顶点函数的语义有哪些a2v
struct a2v {
                float4 vertex : POSITION; //告诉Unity将模型空间下的顶点坐标填充给vertex
                float3 normal : NORMAL; //告诉Unity将模型空间下的法线方向填充给normal
                float4 texcoord : TEXCOORD0; //告诉Unity把第一套纹理坐标填充给texcoord
            };

POSITION 顶点坐标(模型空间下的)
NORMAL 法线( 模型空间下)
TANGENT 切线(模型空间)
TEXCOORD0 ~n 纹理坐标
COLOR 顶点颜色

从顶点函数传递给片元函数的时候可以使用的语义

struct v2f {
                    float4 position : SV_POSITION;
                    float3 tempColor : COLOR0;
                };

SV_POSITION 剪裁空间中的顶点坐标(一般是系统直接使用)
COLOR0 可以传递一组值 4个
COLOR1 可以传递一组值 4个
TEXCOORD0~7 传递纹理坐标

片元函数传递给系统

fixed4 frag(v2f f) : SV_TARGET{
                    return fixed4(f.tempColor,1); //顶点的法线作为返回的颜色值
                }

SV_Target 颜色值,显示到屏幕上的颜色

  • 运行效果

Unity Shader 编程之一_第2张图片

你可能感兴趣的:(shader)