草庐IT

Unity Shader入门精要读书笔记 第三章 Unity Shader基础

DorinXL 2023-03-28 原文

Unity Shader入门精要读书笔记 第三章 Unity Shader基础

前言

Unity Shader的出现就是为了提供一个地方能够让开发者更轻松的管理着色器代码以及渲染设置,而不需要同各种shader文件一样管理多个文件、函数等。

3.1 Unity Shader概述

3.1.1 材质和Unity Shader

​ 在Unity中,我们需要配合使用材质(Material)和Unity Shader才能达到需要的效果。Unity Shader定义渲染所需的代码、属性和指令,而材质允许我们自己调节这些属性,并赋给相应的模型。

3.1.2 Unity中的材质

​ Unity中的材质需要结合一个GameObject的mesh或者Particle Systems(粒子系统)来工作。

3.1.3 Unity中的Shader

​ Unity中的shader文件同渲染管线的shader不同,所以笔记中会同原著一样称为Unity Shader

​ 在创建Unity Shader时,unity为我们提供了四种模板:

Standard Surface Shader 产生一个包含标准光照模型的表面着色器模板
Unlit Shader 不包含光照(但包含雾效)的基本的顶点/片元着色器
Image Effect Shader 为各种屏幕后处理效果提供基本模板
Compute Shader 利用GPC的并行性来进行一些与常规渲染流水线无关的计算

​ 由于《入门精要》这本书重点在如何在Unity中编写顶点/片元着色器,后续学习中通常会用Unlit Shader来生成一个基本的顶点/片元着色器模板。

​ 单独的Unity Shader不能发挥作用,必须同材质material结合起来。其本质上是一个文本文件,Unity Shader的导入设置面板可以看到该shader的一些相关信息(例如是否是固定函数着色器(fixed function)、是否投射阴影(cast shadows)、使用的渲染队列(Render queue)、属性(properties)列表等)。

3.2 Unity Shader的基础:ShaderLab

​ Unity专门提供了一种为Unity Shader服务的语言——ShaderLab,Unity Shader为控制渲染过程提供了一层抽象,帮助开发者更简单的完成工作。ShaderLab时Unity提供的编写Unity Shader的一种说明性语言,使用一些嵌套在花括号内的语义来描述一个Unity Shader文件的结构。类似CgFX和Direct3D Effects(.FX)语言,定义了显示一个材质所需的所有东西,而不仅是着色器代码

​ 一个Unity Shader的基础结构如下:

Shader "ShaderName"{
	Properties{
		//属性
	}
	SubShader{
		//显卡A使用的子着色器
	}
		SubShader{
		//显卡B使用的子着色器
	}
	Fallback "VertexLit"
}

​ Unity会在背后根据使用的平台将这些结构编译成真正的代码和Shader文件,开发者只需要和Unity Shader打交道就行。

3.3 Unity Shader的结构

3.3.1 给Shader起名字

​ 用 Shader "name"{ }就可以给Unity Shader命名,同时会出现在材质面板的下拉列表里。

​ 也可以添加前缀来有序组织位置分布,例如Shader "Custom/MyShader"{}的效果如图:

3.3.2 材质和Unity Shader的桥梁:Properties

​ Properties中包含一系列属性,这些属性会出现在材质面板中。

​ 其定义方式为 _名字("面板属性名",类型)=默认值,如:

Properties{
	Name("Display name",propertyType) = DefaultValue
	Name("Display name",propertyType) = DefaultValue
	//更多属性
}

​ 属性的名字通常用一个下划线开始。显示名字是出现在材质面板上的名字,同时需要指定类型和默认值。

​ 以下是Properties语义块支持的属性类型:

属性类型 默认值的定义语法 例子
Int number _Int("Int",Int) = 2
Float number _Float("Float",Float) = 1.5
Range(min,max) number _Range("Range",Range(0.0,5.0)) = 3.0
Color (number,number,number,number) _Color("Color",Color) = (1,1,1,1)
Vector (number,number,number,number) _Vector("Vector",Vector) = (6,2,3,1)
2D "defaulttexture"{} _2D("2D",2D) = ""{}
Cube "defaulttexture"{} _Cube(“Cube”,Cube) = "white"{}
3D "defaulttexture"{} _3D("3D",3D) = "black"{}

​ Int、Float、Range:数字类型的属性,默认值是单独的数字。

​ Color、Vector:默认值是括号包围的四维向量。

​ 2D、Cube、3D:默认值是字符串和花括号,字符串要么为空,要么是内置的纹理名称;花括号用于指定一些纹理属性,在Unitu5.0之后被移除。

3.3.3 重量级成员:SubShader

​ 一个Unity Shader可以包含多个SubShader语义块,至少要有一个。加载unity shader时会扫描所有SubShader,选择第一个能在目标平台运行的SubShader;如果都不支持,那么使用Fallback指定的UnityShader。

​ SubShader的结构如下:

SubShader{
	//可选
	[Tags]
	//可选
	[RenderSetup]
	Pass{
	}
	//其他的pass
}

​ 挨个介绍:

  1. 标签Tags和状态RenderSetup都是可选的,在SubShader中的设置会适用到所有pass。

  2. 标签Tags是一个键值对,都是字符串,代表着SubShader希望以怎样、何时来渲染此对象。

  3. 状态RenderSetup可以设置显卡的各种状态,并应用到所有的pass。

  4. Pass语义块则是一次完整的渲染流程

    来说说Pass:

    Pass{
    	[Name]
    	[Tags]
    	[RenderSetup]
    	//code
    }
    

    显然我们可以定义pass的名称,我们也可以引用其他Unity Shader的pass,如:UsePass "MyShader/MYPASSNAME",值得注意的是,unity内部会把所有Pass名称转换为大写字母,所有我们这里也要用大写字母。

    Pass内部也可以设置标签/渲染状态,用于告诉渲染引擎如何渲染该物体。

3.3.4 留后路:Fallback

​ Fallback规定了当所有的SubShader都不能在显卡上运行的时候所使用的Shader。

​ 开发者可以关闭Fallback,但是这会影响投影的投射。因为Fallback使用的内置shader包含了一个通用的Pass,这会造成阴影投射的效果。

3.3.5 其他语义

​ 比如CustomEditor语言扩展自定义编辑界面。

​ 比如Category语义对Unity Shader中的命令分组。

3.4 Unity Shader的形式

​ 在Unity中有三种形式来编写Unity Shader:

Shader "MyShader"{
	Properties{
		//所需的各种属性
	}
	SubShader{
		//真正意义上的Shader代码会出现在这里
		//表面着色器(Subface Shader) 或者
		//顶点/片元着色器(Vertex/Fragment Shader) 或者
		//固定函数着色器(Fixed Function Shader)
	}
	SubShader{
		//同上
	}
}

3.4.1 表面着色器

表面着色器(Sruface Shader)是Unity自己创造的一种着色器代码类型,代码量少;本质上还是顶点/片元着色器,可以看作是Unity对顶点/片元着色器的高层抽象。

​ 表面着色器的价值在于Unity帮我们处理了很多光照细节。

Shader "Custom/Simple Surface shader" {
	Subshader{
		Tags {"RenderType" = "opaque" }
		CGPROGRAM
		#pragma surface surf Lambert
		struct Input {
			float4 color : COLOR;
		};
		void surf ( Input IN, inout SurfaceOutput o){
			o.Albedo = 1;
		)
		ENDCG
	}
	Fallback "Diffuse"
}

​ 表面着色器定义在SubShader中的CGPROGRAMENDCG中。不在Pass中是因为不关心有几个pass,Unity会做好Pass的事情。

CGPROGRAMENDCG中的代码使用CG/HLSL编写。

3.4.2 顶点/片元着色器

​ 基本同表面着色器一致,但是CGPROGRAMENDCG需要写在Pass内,用来定义每个Pass自己的代码。

3.4.3 固定函数着色器

​ 旧版本设备不支持可编程管线着色器,所以使用固定函数着色器。

​ 固定函数着色器使用ShaderLab语法而不是CG/HLSL。

​ Unity5.2之后,所有固定函数着色器会在底层被编译成对应的顶点/片元着色器,真正意义上的固定函数着色器不复存在。

3.6 注意的地方

​ 3.6.1 Unity Shader不是Shader

Unity Shader实际上是一个ShaderLab文件,以.shader为后缀名的文件。

​ Unity Shader高度封装,不需要编写特定类型的顶点/片元Shader,可以通过指令开启渲染设置,方便的修改一些属性。

​ 同时由于Unity Shader的高度封装,一些Shader类型和语法受限。

​ 3.6.2 Unity Shader和CG/HLSL的关系

​ Unity Shader用ShaderLab语言编写,但是对于顶点/片元着色器会嵌套CG/HLSL代码来实现。

3.7 资料

​ 官方文档:http://docs.unity3d.com/Manual/SL-Reference.html

​ 官方简单着色器编写教程:http://docs.unity3d.com/Manual/ShaderTut1.html http://docs.unity3d.com/Manual/ShaderTut1.html

​ NVIDIA提供的CG文档:http://http.developer.nvidia.com/CG

​ NVIDIA提供的系列教程:http://http.developer.nvidia.com/CGTutorial/cG_tutorial_chapter01.html

有关Unity Shader入门精要读书笔记 第三章 Unity Shader基础的更多相关文章

  1. postman接口测试工具-基础使用教程 - 2

    1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,

  2. 软件测试基础 - 2

    Ⅰ软件测试基础一、软件测试基础理论1、软件测试的必要性所有的产品或者服务上线都需要测试2、测试的发展过程3、什么是软件测试找bug,发现缺陷4、测试的定义使用人工或自动的手段来运行或者测试某个系统的过程。目的在于检测它是否满足规定的需求。弄清预期结果和实际结果的差别。5、测试的目的以最小的人力、物力和时间找出软件中潜在的错误和缺陷6、测试的原则28原则:20%的主要功能要重点测(eg:支付宝的支付功能,其他功能都是次要的)80%的错误存在于20%的代码中7、测试标准8、测试的基本要求功能测试性能测试安全性测试兼容性测试易用性测试外观界面测试可靠性测试二、质量模型衡量一个优秀软件的维度①功能性功

  3. LC滤波器设计学习笔记(一)滤波电路入门 - 2

    目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称

  4. 微信小程序开发入门与实战(Behaviors使用) - 2

    @作者:SYFStrive @博客首页:HomePage📜:微信小程序📌:个人社区(欢迎大佬们加入)👉:社区链接🔗📌:觉得文章不错可以点点关注👉:专栏连接🔗💃:感谢支持,学累了可以先看小段由小胖给大家带来的街舞👉微信小程序(🔥)目录自定义组件-behaviors    1、什么是behaviors    2、behaviors的工作方式    3、创建behavior    4、导入并使用behavior    5、behavior中所有可用的节点    6、同名字段的覆盖和组合规则总结最后自定义组件-behaviors    1、什么是behaviorsbehaviors是小程序中,用于实现

  5. 【Java入门】使用Java实现文件夹的遍历 - 2

    遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg

  6. ES基础入门 - 2

    ES一、简介1、ElasticStackES技术栈:ElasticSearch:存数据+搜索;QL;Kibana:Web可视化平台,分析。LogStash:日志收集,Log4j:产生日志;log.info(xxx)。。。。使用场景:metrics:指标监控…2、基本概念Index(索引)动词:保存(插入)名词:类似MySQL数据库,给数据Type(类型)已废弃,以前类似MySQL的表现在用索引对数据分类Document(文档)真正要保存的一个JSON数据{name:"tcx"}二、入门实战{"name":"DESKTOP-1TSVGKG","cluster_name":"elasticsear

  7. ruby - 尝试比较两个文本文件,并根据信息创建第三个 - 2

    我有两个文本文件,master.txt和926.txt。如果926.txt中有一行不在master.txt中,我想写入一个新文件notinbook.txt。我写了我能想到的最好的东西,但考虑到我是一个糟糕的/新手程序员,它失败了。这是我的东西g=File.new("notinbook.txt","w")File.open("926.txt","r")do|f|while(line=f.gets)x=line.chompifFile.open("master.txt","w")do|h|endwhile(line=h.gets)ifline.chomp!=xputslineendende

  8. 【网络】-- 网络基础 - 2

    (本文是网络的宏观的概念铺垫)目录计算机网络背景网络发展认识"协议"网络协议初识协议分层OSI七层模型TCP/IP五层(或四层)模型报头以太网碰撞路由器IP地址和MAC地址IP地址与MAC地址总结IP地址MAC地址计算机网络背景网络发展        是最开始先有的计算机,计算机后来因为多项技术的水平升高,逐渐的计算机变的小型化、高效化。后来因为计算机其本身的计算能力比较的快速:独立模式:计算机之间相互独立。    如:有三个人,每个人做的不同的事物,但是是需要协作的完成。    而这三个人所做的事是需要进行协作的,然而刚开始因为每一台计算机之间都是互相独立的。所以前面的人处理完了就需要将数据

  9. 区块链入门教程(6)--WeBASE-Front节点前置服务安装 - 2

    文章目录1.任务背景2.任务目标3.相关知识点4.任务实操4.1安装配置JDK4.2启动FISCOBCOS4.3下载解压WeBASE-Front4.4拷贝sdk证书文件4.5启动节点4.6访问节点4.7检查运行状态5.任务总结1.任务背景FISCOBCOS其实是有控制台管理工具,用来对区块链系统进行各种管理操作。但是对于初学者来说,还是可视化界面更友好,本节就来介绍WeBASE管理平台,这是一款微众银行开源的自研区块链中间件平台,可以降低区块链使用的门槛,大幅提高区块链应用的开发效率。微众银行是腾讯牵头设立的民营银行,在国内民营银行里还是比较出名的。微众银行参与FISCOBCOS生态建设,一定

  10. Unity Shader 学习笔记(5)Shader变体、Shader属性定义技巧、自定义材质面板 - 2

    写在之前Shader变体、Shader属性定义技巧、自定义材质面板,这三个知识点任何一个单拿出来都是一套知识体系,不能一概而论,本文章目的在于将学习和实际工作中遇见的问题进行总结,类似于网络笔记之用,方便后续回顾查看,如有以偏概全、不祥不尽之处,还望海涵。1、Shader变体先看一段代码......Properties{ [KeywordEnum(on,off)]USL_USE_COL("IsUseColorMixTex?",int)=0 [Toggle(IS_RED_ON)]_IsRed("IsRed?",int)=0}......//中间省略,后续会有完整代码 #pragmamulti_c

随机推荐