位置: 编程技术 - 正文

unity3d shader 学习笔记1(unity shader视频教程)

编辑:rootadmin

推荐整理分享unity3d shader 学习笔记1(unity shader视频教程),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:unity shader lod,unity shader cull off,unity的shader用法,unity shader lerp,unity shader视频教程,unity shader入门精要,unity shader入门精要,unity shader视频教程,内容如对您有帮助,希望把文章链接给更多的朋友!

在unity中我们经常会使用shader,但是从来没有深究过,最近在做项目时遇到相关问题,无从下手,决定系统学习一番,在此前提下把我学习的过程做一个记录。学习过程中参考了浅墨和风宇冲两位高人的博客,本文有不对的地方,还望指正。

按照学习技术的习惯,在第一次接触shader时,我们首先会想这两个个问题,

问题一:什么是shader,它能做什么?

问题二:unity中shader使用的语言是什么?

问题一:shader,也就是着色器,它本质就是一段程序,这段程序的作用是把Mesh(网&#;)以指定的方式以及指向的贴图或颜色等处理后,然后通过绘制把处理后的图像显示在屏幕上。所以简而言之:

什么是shader,shader就是一段处理颜色,贴图纹理并且进行计算和变换到渲染器的程序。

unity中shader分两类:Surface Shader(表面着色器)和Vertex Shader &Fragment Shader(顶点着色器&片段着色器)以及Fixed Function Shader(固定功能着色器)下面会讲如何在区分。

shader能做什么呢,比如光影特效,颜色变换等。暂时只想到这些

问题二:unity中的shader使用的是一种shaderLab的语言编写的。它的语法风&#;类&#;NVIDIA的CgFX和Direct3D,它具备了显示材质(Material)所需要的一切信息,在unity的shader代码中我们可以使用CG语言写CG程序,所谓CG语言就是C for Graphics,说到一种语言我们就介绍下的他的数据类型,CG语言有6中数据类型,分别是

1. float,位浮点数据,一个符号位。浮点数据类型被所有的profile支持(但是DirectX8 pixel profiles在一些操作中降低了浮点数的精度和范围);

2. half,为浮点数据;

3. int,位整形数据,有些profile会将int类型作为float类型使用;

4. fixed,位定点数,被所有的fragment profiles所支持;

5. bool,布尔数据,通常用于if和条件操作符(?:),布尔数据类型被所有的profiles支持;

6. sampler*,纹理对象的句柄(the handle to a texture object),分为6类:sampler, sampler1D, sampler2D, sampler3D, samplerCUBE,和samplerRECT。DirectX profiles不支持samplerRECT类型,除此之外这些类型被所有的pixel profiles和 NV vertex program profile所支持(CgUsersManual 页)。由此可见,在不远的未来,顶点程序也将广泛支持纹理操作;

除了上面的基本数据类型外,Cg还提供了内置的向量数据类型(built-in vector data types),内置的向量数据类型基于基础数据类型。例如:float4,表示float类型的4元向量;bool4,表示bool类型4元向量。

注意:向量最长不能超过4元,即在Cg程序中可以声明float1、float2、float3、float4类型的数组变量,但是不能声明超过4元的向量,例如:

float5 array ;// 编译报错

向量初始化方式一般为:

float4 array = float4(1.0, 2.0, 3.0, 4.0);

较长的向量还可以通过较短的向量进行构建:

float2 a = float2(1.0, 1.0);

float4 b = float4(a, 0.0, 0.0);

此外,Cg还提供矩阵数据类型,不过最大的维数不能超过4*4阶。例如:

float1x1 matrix1; // 等价于 float matirx1; x 是字符,并不是乘号!

float2x3 matrix2; // 表示2*3 阶矩阵,包含6 个 float 类型数据

float4x2 matrix3;// 表示 4*2 阶矩阵,包含 8 个 float 类型数据

float4x4 matrix4 ;// 表示4*4 阶矩阵,这是最大的维数

矩阵的初始化方式为:

float2x3 matrix5 = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0};

CG语言中也有数组数据类型,它在Cg程序中的作用是:作为函数的形参,用于大量数据的转递。

Cg中声明数组变量的方式和C语言类&#;:例如:

float a[]; // 声明了一个数组,包含 个 float 类型数据

float4 b[]; // 声明了一个数组,包含 个 float4 类型向量数据

注意:Cg中向量、矩阵与数组是完全不同,向量和矩阵是内置的数据类型(矩阵基于向量),而数组则是一种数据结构,不是内置数据类型!这一点和CC&#;&#; 中不太一样,在CC&#;&#;中,这三者同属于数据结构,数组可以构建向量和矩阵。下一节中将详细阐述Cg中的数组类型。

下面我们来看一段unity的shader代码。打开unity,Assets->Create->Shader,会在Assets路径下创建了一个shader脚本,可以用文本编辑工具打开,我使用的是一个VS的shader插件,可以显示语法高亮。代码如下:

我们先来看看这段代码的结构,它大体分四块Shader “Custom/NewShader” ,Properties和SubShader以及FallBack “Diffuse”。

简单的可以用如下的形式来概括:

Shader "name" { [Properties] SubShaders[Fallback] }

用图来说

Shader “Custom/NewShader” :它定义了我们自定义的这个shader的目录结构,Custom下名字叫做NewShader。目录和它的名字我们可以随意修改 ,并且不必和文件名相同。 “/”用来构建子菜单,作用便于管理,如Custom/canglang/NewShader那么在 Inspector 检视窗口就会显示成这样

Properties:unity圣典的解释是:

Shaders can define a list of parameters to be set by artists in Unity’s material inspector. The Properties block in the shader file definesthem.我简单理解为属性定义并且属性会将display name显示在材质检视器中,显示GUI元素,包括纹理,颜色,滑动条,float&#;等,能够很便利的让我们进行修改

语法结构为:Properties { Property [Property ...] }

定义属性块,其中可包含多个属性,其定义如下:

name ("display name", type) =Defaultvalue

type的类型有7种:Range(min,max),Color ,2D,Rect,Cube,Float,Vector,每一种的具体含义及定义如下:

name ("display name", Range (min, max)) =number

定义浮点数属性,在检视器中可通过一个标注最大最小&#;的滑条来修改。

name ("display name", Color) =(number,number,number,number)

unity3d shader 学习笔记1(unity shader视频教程)

定义颜色属性

name ("display name", 2D) = "name" {options }

定义2D纹理属性

name ("display name", Rect) = "name"{ options }

定义长方形(非2次方)纹理属性

name ("display name", Cube) = "name"{ options }

定义立方贴图纹理属性

name ("display name", Float) = number

定义浮点数属性

name ("display name", Vector) =(number,number,number,number)

定义一个四元素的容器(相当于Vector4)属性

例如_MyColor ("My Color", Color) =(1,1,1,0)为例,

_MyColor ------Internal name(内部名称)

My Color-------Inspector title(Inspector窗口显示的名称)

Color-----------Property type(属性类型)

(1,1,1,0)--------Default value(默认&#;)

注意:

1、Properties块内的语法都是单行的。每个属性都是由内部名称开始,后面括号中是显示在检视面板(Inspector)中的名字和该属性的类型。等号后边跟的是默认&#;。

2、对于Range和Float类型的属性只能是单精度&#;。

3、对于Color和Vector类型的属性将包含4个由括号围住的数描述。

4、对于纹理(2D, Rect, Cube) 缺省&#;既可以是一个空字符串也可以是某个内置的缺省纹理:"white", "black", "gray" or"bump"

SubShader:子着色器,是shader代码的主体,一个shader可以包含一个或多个子着色器,每个子着色器可以包含一个或多个pass,但是在运行时具体能不能执行或者限制性哪个子着色器完全由运行平台决定。因为机子不同,运行的显卡支持环境也不同。所以多个子着色器的作用就在于此,例如对于一个效果,预想想好ABC多套方案,A在牛&#;机子上能运行,B在一般机子上能运行,C在烂机子上运行。全都不行了还有FallBack呢。而且在运行时系统也会把子着色器中代码分成多个合适的pass。

具体结构如下:

SubShader

{

pass

{

}

}

FallBack “Diffuse”:回滚,也称备胎,作用是处理所有SubShader都不能运行的情况,以防万一,留个备胎,不然显示不了咋办呢。这里设的备胎是Diffuse(漫反射)。

注意:SubShader在Shader代码中必须有,而properties和fallback是可以不写的

下面来看下我们新建的NewShader中SubShader的代码

Tags { "RenderType"="Opaque" }:Tags是标签,SubShader可以写多个Tags(标签)来标定这个SubShader,当然也可以不写,硬件平台通过这些标签来决定什么时候调用这个SubShader进行渲染,在我们新建的这个shader中使用的是unity默认的"RenderType" = "Opaque",它的含义是告诉硬件平台在渲染非透明物体时调用该SubShader,与之对应的,渲染含有透明效果的物体时是"RenderType" = "Transparent",我在这列举我们经常会使用的几个标签如下:

"RenderType" = "Opaque" 渲染非透明物体

"RenderType" = "Transparent" 渲染含有透明效果的物体

"IgnoreProjector"="True" 不被Projectors影 响

"ForceNoShadowCasting"="True" 从不产生阴影

"Queue"="xxx"指定渲染顺序队列

我们要着重讲下这个Queue,Queue制定了该物体的渲染顺序,所以尤其是在透明与不透明物体混合时我们要注意,不然可能显示不出来。

预订的Queue有如下几个:

Background最先被调用的渲染,一般用来渲染天空和或者背景

Geometry默认&#;,用来渲染非透明物体(普通情况下,场景中绝大多数物体应该是非透明的)

AlphaTest用来熏染经过Alpha Test的像素,单独为AlphaTest设定一个Queue是出于对效率的考虑

Transparent以从后往前的顺序渲染透明物体

Overlay用来渲染叠加的效果,是渲染的最后阶段(比如镜头光晕等特效)

这 些预定义的&#;本质上是一组定义整数,Background = , Geometry = , AlphaTest = , Transparent = ,最后Overlay = 。在我们实际设置Queue&#;时,不仅能使用上面的几个预定义&#;,我们也可以指定自己的Queue&#;,写成类&#;这 样:"Queue"="Transparent&#;",表示一个在Transparent之后的Queue上进行调用。通过调整Queue&#;, 我们可以确保某些物体一定在另一些物体之前或者之后渲染,这个技巧有时候很有用处。

LOD :LOD(Level of Detail),他的&#;决定我们写的Shader在unity设定的品质环境下能不能用,在Unity的Quality Settings中我们可以设定允许的最大LOD,当设定的LOD小于SubShader所指定的LOD时,这个SubShader将不可用。Unity 内建Shader定义了一组LOD的数&#;,我们在实现自己的Shader的时候可以将其作为参考来设定自己的LOD数&#;,这样在之后调整根据设备图形性能 来调整画质时可以进行比较精确的控制。

VertexLit及其系列 = Decal, Reflective VertexLit = Diffuse = Diffuse Detail, Reflective Bumped Unlit, Reflective Bumped VertexLit = Bumped, Specular = Bumped Specular = Parallax = Parallax Specular = CGPROGRAM:标记语句,标识从这里开始是一顿CG程序(我们在写Unity的Shader时用的是Cg/HLSL语言)。最后一行的ENDCG与CGPROGRAM是对应的,表明CG程序到此结束。#pragma surface surf Lambert:这是一条编译指令,它声明了我们写的这个shader的类型,以及光照模型。他的语法如下:#pragma surface surfaceFunction lightModel [optionalparams]surface - 声明该Shader是一个Surface Shader(表面着色器)

surfaceFunction - shader代码方法的名字

lightModel - 使用的光照模型

所以例子中我们这句指令的意义就是:声明一个表面着色器(Surface Shader),实际的代码在surf函数,使用Lambert(普通的diffuse漫反射)为光照模型。

sampler2D _MainTex:解释sampler2D之前,我们先说下_MainTex,我们会发现在前面的Properties模块已经有了一个_MainTex的贴图属性声明。这里为什么还要声明它,原因是CGPROGRAM...ENDCG定义的代码块是一段CG程序,而shader的其他部分使用shaderLab写的,ShaderLab是unity可以直接使用和编译的,CG程序不能,所以必须使用和之前变量相同的名字再次进行声明,这样就能链接到Properties的变量,使得我们的CG代码能够使用这个变量。再来说这个sampler2D是一个2D贴图的类型,从他可以获得2d贴图的像素与坐标的对应数据

struct Input:首先它是一个结构体,名字叫做Input,这个结构体名字是CG规定的,我们不能改变,它是作为下面suf函数参数需要传入进去的,但是他的内容可改,这就给了我们发挥的空间,我们可以自己把需要参与计算的数据放进这个结构体,例子中的结构体定义了定义了一个uv_MainTex的变量,类型是float2,CG中经常有float2,float3,float4的类型,它其实就是把2个或者3个或者4个float类型打包在一起。但是这个变量有些特别,我们在前面已经定义了一个_MainTex的2D贴图变量,在这我们的uv_MainTex只是比它多了一个uv_前缀,感觉这么写有什么含义&#;的,没错!就是有特别意义的,在CG程序中,有个很特别的做法,就是在一个贴图变量之前加上一个uv_前缀,就代表提取它的uv&#;,那么我们就会问什么是uv&#;,所谓uv&#;就是&#;贴图纹理的二维坐标,在这个例子中我们就能去取前面定义的贴图_MainTex的坐标&#;来参与计算了。

void surf (Input IN, inout SurfaceOutput o) :这是一个函数,也是这段CG代码的核心处理函数,和C语言的语法一样,我们说过CG语言就是C for graphics,是一种偏C的语言,所以他的含义很好理解,但是注意的是CG语言规定了这个函数参数的类型和名字,我们没法改,只能按照规定写,返回类型为空,两个参数一个是 IN类型是我们刚定义的Input结构体,一个是inout的SurfaceOutput结构体,Input我们刚刚已经解释过了,SurfaceOutput是已经定义好了内部类型的输出结构,接下来我们来解释例子中这个函数的函数体的具体做的事情,half4 c = tex2D (_MainTex, IN.uv_MainTex);tex2D函数,是CG程序中用来在一张贴图中对一个点进行采样的方法,返回一个half4(half是CG语言中的半精度类型我们可以就理解为float,精度较低,效率高),他有两个参数,参数一是一张贴图变量,参数二是该贴图变量的uv信息。o.Albedo = c.rgb; o.Alpha = c.a;这两句把取得采样信息,赋&#;给SurfaceOutput输出结构,这样shader就按照贴图上的uv信息,直接使用rgba信息来进行着色,于是就在屏幕中显示出来了。

ok,通过例子中的shader代码,我们把shader的整个基础结构作了一个简单的介绍。明天我们继续....

如何修改新建脚本模板-ScriptTemplates(Unity3D开发之十五) 猴子原创,欢迎转载。转载请注明:转载自Cocos2Der-CSDN,谢谢!原文地址:

unity 3d 生成apk文件时,设置图标 如图所示:注意红线标注部分:如果安装到手机之后,程序的图标还是unity的默认图标,重启手机即可。

Unity 热更新之ULua 踩坑篇 Unity的原生c#是无法在移动端上进行热更新的,那么如果线上发布遇到重大闪退事故的话,那么就不可以通过游戏内的热更新进行bug修复,只能重新提交

标签: unity shader视频教程

本文链接地址:https://www.jiuchutong.com/biancheng/383556.html 转载请保留说明!

上一篇:Unity手游之路<十三>手游代码更新策略探讨(手机unity游戏)

下一篇:如何修改新建脚本模板-ScriptTemplates(Unity3D开发之十五)(如何修改新建的内容)

  • 延期缴税申请需要先申报吗?
  • 投资性房地产公允价值变动
  • 注册公司工贸和商贸区别
  • 当月开票没有收到钱
  • 本年支付 历年支付
  • 没有收入的小规模纳税人可以无票入费用吗?
  • 租赁房屋到期装修费怎么办?
  • 总公司向子公司收取管理费如何纳税
  • 商业地产运营成本核算
  • 企业要怎样才能发挥其在实现生态产品价值过程中的作用
  • 报销跨月还能报销吗
  • 采购商品验收入库流程
  • 公司收到股东的投资款以后怎么处理
  • 出口退税总是差进项票怎么处理
  • 公对公转账需要多久到账
  • 修缮发票要注明什么
  • 消费税有哪几种纳税方式
  • 纳税人备案信息包括
  • 减税降费在中国 应形成制度性
  • 新注册公司季度资产为零
  • 特定业务预缴所得税不能填写
  • 网络科技公司会计核算及账务处理
  • 劳务公司差额征税账务处理
  • 申报是不是就是报税
  • 促销费属于现代服务类吗
  • 红字发票是否需要盖发票章
  • 旧货销售的增值税税率
  • 怎样破解wifi密码怎么办
  • 加速折旧法和直线折旧法的区别
  • 重装系统D盘文件还能恢复吗
  • 只有高新技术企业能享受研发加计扣除吗
  • 常见的财务报表分析方法有多选题
  • php文件在线解密
  • win10的环境配置在哪
  • 【超用心整理】Markdown常用语法介绍,看这一个就够了
  • 现金溢余和短缺的会计分录
  • java泛型方法的使用
  • 处理二手物品要交增值税吗
  • 存货毁损计入什么科目
  • 财政拨付资金什么意思
  • 金融企业往来支出属于费用吗
  • 员工辞退补偿金扣个税吗
  • 账面未分配利润等于净利润?
  • 汽车折旧费谁出
  • 商业承兑汇票贴现会计分录
  • 收到客户付款多久到账
  • 票据带息和不带息
  • 其他应收款的会计分录有哪些
  • Pythonround函数作用
  • centos彻底删除文件
  • 利息收入管理办法
  • 个人社保应不应该缴纳
  • 暂估成本发票最晚什么时候补齐
  • 收到投资款如何做账务处理
  • 国有企业无偿划转股权缴纳印花税
  • 银行开手续费发票怎么做账
  • 商场收租户电费会计分录
  • 成本法和权益法的转换
  • 资产类科目一般是什么
  • 印花税需要计提税金及附加吗
  • 注册表 启动
  • Win7系统重装后开不了机
  • linux make命令怎么用
  • centos7 eth
  • xp从装系统
  • 360rps.exe
  • imscmig.exe
  • javascript入门教程
  • css onclick
  • angular.js
  • python快捷键大全
  • 基于javascript的毕业设计
  • jquery右键弹出菜单
  • js新年倒计时
  • 国税登录不了
  • 增值税预缴税款在主表怎么填写
  • 广东税务社保缴费查询
  • 云南省电子税务
  • 有发票代码和发票号码能下载到电子发票吗
  • 增值税纳税申报表附列资料(三)
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设