位置: 编程技术 - 正文

学习Unity3D Shader篇 - 从GLSL到Unity3D Shader(一)(学习雷锋好榜样)

编辑:rootadmin

推荐整理分享学习Unity3D Shader篇 - 从GLSL到Unity3D Shader(一)(学习雷锋好榜样),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:学习雷锋好榜样,学习通,学习心得,学习计划表模板,学习通,学习软件,学习雷锋好榜样,学习通,内容如对您有帮助,希望把文章链接给更多的朋友!

一直在用OpenGL&#;GLSL开发,也用过Unity3D自己开发过一些小玩意。但是一直涉及过U3D的Shader方面。今天开始,有时间就要学习一下。

如果有GLSL的开发经验,学习U3D的Shader开发的话就不是很难,主要就是注意一些CG和ShaderLab的语法和与GLSL的不同之处了。因此以下部分主要是面向有三维开发和shader开发经验的同学。

需要注意,U3D中shader是挂载在Material上,再通过Material挂载到GameObject上的。在脚本中通过操作Material来动态地向shader中传递数据。

对可编程渲染管线和GLSL略有了解的应该都知道,可编程管线最核心的两个部分就是vertex shader和fragment shader(在CG和HLSL叫做pixel shader)了。

而U3D为了简化Shader编写,以及处于兼容性方面的考虑,U3D在CG的基础之上又添加了一些其他的概念,比如Surface Shader, Subshader, Pass, Fallback, Category之类。

Surface Shader{}:理解了vertex shader和fragment shder,实际上也就可以理解surface shader。vertex shader是逐顶点操作,对每个vertex应用一次;fragment shader是逐片段操作,对每个fragment应用一次。那么surface shader自然是逐面操作啦,就是对模型的每个表面应用一次surface shader。比如一个立方体有6个面,那么surface shader会对这6个面各应用一次。

事实上,surface shader会被Unity3D翻译成CG代码。所以surface shader就是经U3D简化的CG shader。

Subshader{}:子着色器。如果有担心一个shader在某一款机型上不能运行怎么办?岂不是要写很多个shader文件?有了Subshader,你再也不需要这么麻烦了。现在我们可以将shader代码写入多个subshader,然后将这些subshader添加到一个shader文件中。在运行过程中,U3D会自顶向下检查当前的某个Subshader是否可用。如果可用,就执行当前shader,否则继续检查下一个subshader是否可用。

Fallback:如果所有的subshader都不能用怎么办?这时候只好叫Fallback出马了。如果所有Subshader都不能运行,那么将会执行Fallback指定的shader文件。

Pass{}:ShaderLab都将写到Pass块中。事实上,CG shader的语句是不能写到Pass中的,因此本节暂时不关注Pass{}语句块。

下面简要介绍一下一个较为完整的U3D的Shader的结构。

在U3D中创建一个shader,那么它的内容将是:(关键字用红色标出)

下面介绍一下关键的部分。

1: 关键字"Shader"指定了这是一个Shader文件。后面的"Custom/NewShader"就是这个Shader的包含路径的名字。

在给某个Material添加shader时,就可以在下图示例的路径找到该shader。

2. 关键字"Properties":我们都知道GLSL中可以通过glUniform{i}{fv}()函数来通过C&#;&#;向shader中传递数据。那么在U3D这种图形化开发环境中,我们该怎么向shader中传递数据呢?Here "Properties" comes into play。通过在Properties {}语句块中添加属性,便可以通过U3D的Inspector面板向Shader中的变量传递数据。

U3D中约定 ,属性变量名都会加一个下划线"_"作为前缀。

a. 这里_MainTex就是属性变量名(property name),类&#;于GLSL中的uniform变量。

b. 后面括号中的" "Base (RGB)" "是该变量的display name,即在U3D的Inspector面板中_MainTex显示出来的名字。

而 2D 则代表_MainTex变量的变量类型,此处 2D 相当于 GLSL中的sampler2D。

而常用的类型有:

Range(min, max):浮点范围属性,Inspector中可以用一个滑杆来修改);

Vector:四维向量。

Color :就是颜色了,也是个 一个四维向量,不过四个元素是r, g, b, a。

Rect:矩形纹理,学过OpenGL的都知道了。

Cube:也不用多说了吧。

c. "="后面的语句则是没有手动该变量赋&#;时,该变量的默认&#;。" "white" "就表明如果没有为_MainTex指定一个纹理,那么shader将把_MainTex看作一个纯白色的纹理。

学习Unity3D Shader篇 - 从GLSL到Unity3D Shader(一)(学习雷锋好榜样)

d. "{}"中的内容称为default values,就是缺省&#;,因此这个"{}"其实是可加可不加的。在属性变量为纹理类型时,"{}"中可以添加一些选项,比如纹理坐标生成模式(Object Linear, EyeLinear, SpereMap, CubeReflect或CubeNormal,相当于OpenGL固定管线的一些功能),光照贴图模式等等。

如果属性变量是数&#;型(比如Float, Vector, Color),那么这里要用小括号()而不是大括号{}。

下面做一个小实验,将Properties{}块中的内容改成这样:

然后选择挂载该shader的Material,可以看到Inspector面板的内容成为如下所示:

可以看到Hello! Shader与Material param字样。

那么,怎么在脚本中使用类&#;于glUniform()的功能呢?

答案就是Material对象的一系列set方法。比如这里的_Shininess是float,那么,可以写如下一个C#脚本:

便可以将滑杆的&#;传递到shader的_Shininess变量中。这里的"_Shininess"就是Properties块中的属性变量名。

3. Subshader:具体的shader代码就在这里了(也可以放在多个pass中,再把这些pass放到subshader里)。一个subshader可能有多个pass。多个pass是从前往后按顺序执行的。

4. Tags:专供Subshader使用,用来告诉U3D何时和怎么渲染物体。

用法是Tags{"标签0" = "&#;0", "标签1" = "&#;1", ...}

最常见的Tag就是"RenderType"吧,"RenderType" = "Opaque"表明这是一个不透明的物体。而Transparent就表明是透明物体啦。

搞过OpenGL的都知道透明物体的绘制是有讲究的,因此在这里指定Tags也是大有裨益的。

下面的话来自《猫都能学会的Unity3D Shader入门指南》

另外比较有用的标签还有"IgnoreProjector"="True"(不被Projectors影响),"ForceNoShadowCasting"="True"(从不产生阴影)以及"Queue"="xxx"(指定渲染顺序队列)。这里想要着重说一下的是Queue这个标签,如果你使用Unity做过一些透明和不透明物体的混合的话,很可能已经遇到过不透明物体无法呈现在透明物体之后的情况。这种情况很可能是由于Shader的渲染顺序不正确导致的。Queue指定了物体的渲染顺序,预定义的Queue有:

Background - 最早被调用的渲染,用来渲染天空盒或者背景Geometry - 这是默认&#;,用来渲染非透明物体(普通情况下,场景中的绝大多数物体应该是非透明的)AlphaTest - 用来渲染经过Alpha Test的像素,单独为AlphaTest设定一个Queue是出于对效率的考虑Transparent - 以从后往前的顺序渲染透明物体Overlay - 用来渲染叠加的效果,是渲染的最后阶段(比如镜头光晕等特效)

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

5 LOD 设置该shader的LOD参数。没什么解释的。

6. CGPROGRAM ... END:重头戏来了。实际的cg代码便出现在CGPROGRAM...END之间。

sampler2D _MainTex; 就相当于GLSL的uniform sampler2D _MainTex。而该_MainTex就是由Properties{}语句块传进来的。实际上在这里,uniform可以省略掉了,因为在Properties{}中的定义已经表明该变量是一个uniform变量,因此无需多此一举了。

7. #pragma surface surf Lambert:表明使用surf函数作为surface shader的入口函数,相当于GLSL的vs与fs的main()。而surf函数没有计算的光照部分由系统提供的Lambert模型计算。还有一个BlinnPhong模型可用。

8. struct Input {

float2 uv_MainTex;

}

必须声明成Input类型的结构体,作为surface shader的输入。若一个变量名字是某纹理属性变量名前加uv作为前缀,则该变量就是用来采样该纹理的纹理坐标。

9.

这就是表面着色器了。表面着色器和其他着色器用法差不多,但不能出现在Pass{}块中。而且,输入和输出必须为给定的Input与SurfaceOutput类型。

事实上SurfaceOutput是一个如下的结构体:

Albedo:就是ADS光照模型的Diffuse分量啦。

Gloss:ADS的Shininess。

其他的没什么说的了。

. FallBack "Diffuse":如果上面的着色器由于一些原因无法运行,则系统会运行"Diffuse"着色器。"Diffuse"是加路径的shader名。如果要回滚我们新加入的shader,则FallBack "Custom/NewShader"。

如此,一个简单的shader便完成了。下面的surface shader实现了一个极其简单的颜色通道修改功能。

Unity之一天一个技术点(十三)---以指定对象为中心,根据鼠标位置旋转照相机 vartarget:Transform;vardistance=.0;varxSpeed=.0;varySpeed=.0;varyMinLimit=-;varyMaxLimit=;privatevarx=0.0;privatevary=0.0;@AddComponentMenu(Camera-Control/MouseOrbit)partialclassMouseOrbit

unity手游<少侠历险记>(4)背包系统 前言本文由作者@zx一路飞奔出品,转载请注明出处文章地址:

Unity3D学习日志第一天 教材:《编程回忆录教程》第八讲1、预制的实质,预制的用法2、GameObject的菜单的用法应用:克隆球撞击墙的物理引擎用法第九讲1、组件(赋类型与引

标签: 学习雷锋好榜样

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

上一篇:Windbg调试Unity3d 卡死 无响应等问题测试(windbg调试驱动)

下一篇:Unity之一天一个技术点(十三)---以指定对象为中心,根据鼠标位置旋转照相机(unity如何成一组)

  • 计提的增值税和实际缴纳的差额
  • 印花税的纳税人是买方还是卖方
  • 开发票怎么操作
  • 小规模企业跨月专票如何冲红
  • 采购的固定资产验收无误后直接安装使用
  • 银行结息计入什么费用
  • 税收分类编码不可用是什么原因
  • 民办非营利组织幼儿园清算时固定资产如何处理
  • 销售蔬菜的个体工商怎么开具发票
  • 停工损耗会计分录怎么写
  • 企业期货投资收益税务案例
  • 增值税缴纳的罚款怎么算
  • 采购商品未收到分录
  • 行政单位年初预算怎么做
  • 增值税免税收入进项税额转出
  • 企业营改增后的会计处理有何变化
  • 收回固定资产残值
  • 每年空调的维保费用怎么入账?
  • 子公司是否可以共享总公司的资质
  • 工程结算收入的会计分录
  • 事业单位财务预算管理制度
  • 收到以前年度退回的企业所得税
  • 记账凭证的摘要怎么填写
  • 如何重装系统win7旗舰版
  • Mac SIP系统完整性保护开启及关闭的方法介绍
  • 潜亏挂账是什么意思
  • 石楠花 开花
  • 工业企业采购部工作职责
  • Obsidian:实现日记记录【设计并使用模板】
  • 小微企业免征增值税政策2023
  • vue导出word文档打开报错,内容有问题
  • 未开票收入申报对企业有什么影响
  • 注册公司时的注册资金
  • 昆明紫霞宫的46 道拐
  • 补缴房产税和土地使用税会计分录
  • php计算圆的周长和面积代码
  • 员工借款能直接从公司账上转么
  • 微信小程序怎么制作自己的小程序
  • 我的十年怎么写
  • win11预览版22000.51
  • php字符串比较函数怎么写
  • 政府会计累计盈余解析
  • java同步操作
  • 去年多计提的工资今年怎么冲
  • 付款后退货
  • 开具发票时如何做账务处理?
  • 劳务派遣公司差额征税怎么做账
  • 施工一个月多少钱
  • 所得税费用科目的期末余额应直接转入
  • 公司奖励员工制度
  • 物业临时用工人员管理制度范本
  • 财政补助结转结转的依据
  • 公司汽车维修
  • 原始股卖出需要缴税吗
  • 固定资产折旧四种方法的优缺点
  • 辞退员工 工资
  • 开票金额和税款的关系
  • 员工预支工资可以从工资里扣吗
  • 年末未分配利润总额计算公式
  • 一分钟教你
  • sql2000卸载干净
  • Windows server 2003 密码忘了
  • u深度u盘启动盘制作工具无法进入电脑
  • ubuntu configure
  • macbook程序在哪
  • 2021年win10累积更新
  • 一篇非常好的作文
  • win7系统更新显卡驱动后黑屏无法启动
  • win8.1 安装
  • win10的帮助系统在哪
  • androidtime
  • linux列操作
  • 安卓里面怎么调用方法
  • android应用开发基础
  • 使用Raygun对Node.js应用进行错误处理的方法
  • js新开一个窗口
  • listview item
  • js中substring和substr有区别吗
  • jquery 插件编写
  • python3模拟登录
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

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

    友情链接: 武汉网站建设