《着色器和屏幕特效》读书笔记第一章-创建一个着色器

来源:互联网 发布:趋势操盘软件 编辑:程序博客网 时间:2024/05/20 07:33

本书版本为“占红来 译”版,笔记会持续更新,有错误的地方欢迎指正,谢谢!

引言

着色器就是Shader,它是一种特殊的程序,主要用来模拟光照效果。

创建基本的标准着色器

渲染器决定了物体在屏幕上呈现出来的外观,每个3D模型都有一个名为MeshRenderer的渲染器。一个物体只能有一个渲染器,但一个渲染器可以有多种材质。每一种材质就是一个着色器呈现出来的外观,因此着色器也就是3D图像食物链的最后一环。

新建一个标准着色器(也就是漫反射着色器)已有一些基础代码(Cg语言):

///着色器的路径。在给材质指定着色器时,该着色器会出现在指定的下拉菜单中。Shader "BookShaders/1-2 StandardDiffuse"{    Properties//制定类型并初始化属性。    {        _Color ("Color", Color) = (1,1,1,1)        //有了这个2D类型,便可在Inspector中添加Texture(纹理)。        _MainTex ("Albedo (RGB)", 2D) = "white" {}        _Glossiness ("Smoothness", Range(0,1)) = 0.5        _Metallic ("Metallic", Range(0,1)) = 0.0    }    SubShader {        //标签RenderType设置为Opaque,指明渲染的物体不透明。        Tags { "RenderType"="Opaque" }        LOD 200        CGPROGRAM//从这开始,到ENDCG的代码段,为表面着色器代码。        //使用surf()作为表面着色器的输入输出函数,并使用了Standard fullforwardshadows光照模型。        #pragma surface surf Standard fullforwardshadows        //选择模型目标为3.0,2.0能使用 传递的参数 比较少,以防Shader崩溃。        #pragma target 3.0        //创建了与属性变量同名的变量,并声明了他们的数据类型。        //也就创建了surf()访问属性的桥梁。        sampler2D _MainTex;        half _Glossiness;        half _Metallic;        fixed4 _Color;        //输入结构,里面装的是表面函数(surf())的输入参数。        struct Input {            //获取图片的uv坐标的固定格式,即为 图片名前加uv。            float2 uv_MainTex;        };        void surf (Input IN, inout SurfaceOutputStandard o) {            //使用tex2D()对_MainTex的uv_MainTex坐标进行采样,获取颜色值,该采样值再与_Color混合。            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;            //输出到Unity的预置输出结构SurfaceOutputStandard的Albedo中。            o.Albedo = c.rgb;            o.Metallic = _Metallic;//金属质感            o.Smoothness = _Glossiness;//光滑度            o.Alpha = c.a;//对透明度的操作无效,因为已指定为不透明物体。        }        ENDCG    }    FallBack "Diffuse"//回滚。如果Pass无法运行,则使用该备用的Shader。}

这是表面着色器,基于物理基础渲染,通过模拟光照到物体上,来获得真实感。创建好着色器后,需要把它关联到一个材质上,接下来就可以将这个材质指定给物体使用了。

从Unity4到Unity5迁移

如果Unity版本大升级,在源文件升级时,最安全的方式是将包含项目的整个文件夹先拷贝一份或者github。

拟实效果好的着色器需要占用大量的计算资源,所以特效最好用在一些却之不可的地方。Unity5的标准着色器集合了法线映射、透明和反射功能,如果你的材质没有用到反射,那么Unity5是不会计算这一部分的。

给着色器添加属性

Properties代码段中的属性,会显示在Inspector面板中方便开发者调值。属性归属于着色器,而属性的值归属于材质!因为:同一个着色器可用于不同的材质。另外,修改某一个材质的属性值,会影响到所有应用了该材质的物体。

定义属性的语法:

_CircleColor("Circle Color",Color)=(1,1,1,1)

分别对应:
变量名(供Cg用、在Inspector中显示的名字 、类型(也就是类型)、默认值

表面着色器属性类型 功能(将在Inspector面板中显示) Range(min,max) 创建一个范围从min到max的浮点型属性值(Cg的浮点数不需要在末尾加f) Color 创建一个有4位参数的颜色控件 2D 创建一个纹理样本 Float 创建一个浮点值 Vector 创建4位浮点数构成的向量,一般用于表示方向或颜色

在表面着色器中使用属性

绝大部分着色器都从标准着色器开始,然后逐步调整为想要的漫反射组件。
材质是一种资源,所以,运行时的修改也是永久性的。
着色器的错误不会阻止游戏的运行,但都呈现为洋红色的样子。

总结:

  1. 使用表面着色器方便实现多种效果,而且不用考虑光照模型的具体实现,但方便意味着局限,所以 它仅仅是顶点和片元着色器的一个子集。
  2. 在手游中少用表面着色器,因为:它是顶点和片元着色器在上一层的一个抽象,它实际上也是顶点和片元着色器,Unity会根据编写的表面着色器代码自动生成为顶点和片元着色器,所以性能浪费大。
  3. 顶点和片元着色器(和GPU的渲染流水线有关)是GPU拥有的书写方式,在Pass中编写vert和frag函数;
    表面着色器是Unity原创的书写方式,在SubShader中的CGPROGRAM和ENDCG区间内编写surf函数。
阅读全文
0 0
原创粉丝点击