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

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

引言

着色器就是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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值