Unity的shader

Shaders: Getting started来源网址:http://unity3d.com/support/documentation/Manual/ShaderTut1.html
Unity Manual > Advanced > Shaders > Shaders: Getting started

This tutorial will teach you how you can create your own shaders and make you game look a lot better!
此教程将指引你如何建立自己的Shaders,让你的游戏场景看起来更好

 
Unity is equipped with a powerful shading and material language called ShaderLab. In style it is similar to CgFX and Direct3D Effects languages - it describes everything needed to display a Material, not just plain vertex/pixel shaders.
   Unity配备了强大的阴影和材料的语言工具称为ShaderLab,以程式语言来看,它类似于CgFX和Direct3D的语法,它不只纪录基本的端点或者映像点(vertex/pixel)资讯,也描述了材质所必要的一切资讯。

 

Shaders describe properties that are exposed in Unity's Material Inspector and multiple shader implementations (SubShaders) targeted at different graphics hardware capabilities, each describing complete graphics hardware rendering state, fixed function pipeline setup or vertex/fragment programs to use. Vertex and fragment programs are written in high-level Cg programming language or low-level shader assembly.
  在unity材质检视器中可以看到Shaders的性质及多重shader(SubShaders)的描述,针对不同图形硬件,每个描述也都完整的说明了图形硬件的彩现状态,fixed function pipeline如何设定、vertex/ fragment programs如何作用。 Vertex and fragment程序可以使用高阶Cg程式语言或低阶shader组合。

 

In this tutorial we describe how to write shaders in ShaderLab using both fixed function and programmable pipelines. We assume that the reader has a basic understanding of OpenGL or Direct3D render states, fixed function and programmable pipelines and has some knowledge of Cg, HLSL or GLSL programming languages. Some shader tutorials and documentation can be found on NVIDIA and AMD developer sites.
  在这个教程中,我们将描述如何使用fixed function与programmable pipelines两种方式于ShaderLab中撰写shaders,我们假设读者拥有基本的OpenGL或Direct3D彩现概念,并对cg有fixed function与programmable pipelines的常识,HLSL或GLSL编程语言技术,一些Shader教程与参考文件可于NVIDIA以及AMD的开发站上取得

 

Getting started
To create a new shader, either choose Assets->Create->Shader from the menubar, or duplicate an existing shader, and work from that. The new shader can be edited by double-clicking it in the Project View.
  建立一个新的shader有两种方法,可以由菜单Assets->Create->Shader新增,或复制一个既有的shader再进行编辑,新的shader可以透过双击来启动编辑画面(UniSciTE)

 

We'll start with a very basic shader:
  下面开始介绍一个基础的shader范例:

 

This simple shader demonstrates one of the most basic shaders possible. It defines a color property called Main Color and assigns it a default value of rose-like color (red=100% green=50% blue=50% alpha=100%). It then renders the object by invoking a Pass and in that pass setting the diffuse material component to the property _Color and turning on the vertex lighting.
  这个shader范例只是众多shader中最基本的一个,它定义了一个颜色性质,名称为Main Color,并指定了玫瑰色的效果(red=100% green=50% blue=50% alpha=100%),在调用时会跳过Diffuse的材质设定(_Color)并开启顶点光源

 

To test this shader, create a new material, select the shader from the drop-down menu (Tutorial->Basic) and assign the Material to some object. Tweak the color in the Material Inspector and watch the changes. Time to move onto more complex things!
  要测试这个shader,你可以建立一个新的材质,并于Shader下拉菜单选择(Tutorial->Basic),再把这个新材质指定到物件上,拖拉材质检视器的颜色表并查看其变化。是时候研究更复杂的事情了!

 

Basic Vertex Lighting
If you open an existing complex shader, it can be a bit hard to get a good overview. To get you started, we will dissect the built-in VertexLit shader that ships with Unity. This shader uses fixed function pipeline to do standard per- vertex lighting.
  假如你开启一个既有的复合shader,刚开始看可能会觉得有点难,在开始以前,我们将详细说明unity内建的VertexLit shader。这个shader使用fixed function pipeline产生标准的per-vertex照明。

 

All shaders start with the keyword Shader followed by a string that represents the name of the shader. This is the name that is shown in the Inspector. All code for this shader must be put within the curly braces after it: { } (called a block).
  所有的shaders都必须以Shader作为开始,接着是这个shader的名称(例如:VertexLit),这个名称将会显示于检视器(Inspector)。所有的语法都必须放在{ }之内。

 

The name should be short and descriptive. It does not have to match the .shader file name.
  这个名称必须短且足以代表其功能,它并不会等于.shader的档案名称

 

To put shaders in submenus in Unity, use slashes - eg MyShaders/Test would be shown as Test in a submenu called MyShaders, or MyShaders->Test.
  如果要把shaders放在unity的submenus下面,请使用斜线,例如:MyShaders/Test,你将会看到有个submenu名为MyShaders,下面有个shader名为Test,或是像这样MyShaders->Test

 

The shader is composed of a Properties block followed by SubShader blocks. Each of these is described in sections below.
  在Properties block下面接着的是SubShader block,每个描述都在这个段落中
Properties

At the beginning of the shader block you can define any properties that artists can edit in the Material Inspector. In the VertexLit example the properties look like this:
properties位于shader block一开始的位置,你可以定义任何性质,这些性质将可在材质检视器中编辑,在VertexLit的个范例中,properties block看起来像这样:
图片一


The properties are listed on separate lines within the Properties block. Each property starts with the internal name (Color, MainTex). After this in parentheses comes the name shown in the inspector and the type of the property. After that, the default value for this property is listed:
   properties block内的语法都是单行的,每一个性质描述都由内名称开始(例如:Color, MainTex),在后方的括弧号中所显示的名字也会显示于inspector检视器上,在此之后,描述的是该性质的预设值
图片二


The list of possible types are in the Properties Reference. The default value depends on the property type. In the example of a color, the default value should be a four component vector.
  可用的性质类型请参考Properties Reference。预设值与性质有关,以color为例,预设值应该由四个值组成

 

We now have our properties defined, and are ready to start writing the actual shader.
  现在我们已经定义了四个性质,可以开始撰写实际的shader了

 

The Shader Body
Before we move on, let's define the basic structure of a shader file.
  在开始以前,先了解shader的结构是如何定义的

 

Different graphic hardware has different capabilities. For example, some graphics cards support fragment programs and others don't; some can lay down four textures per pass while the others can do only two or one; etc. To allow you to make full use of whatever hardware your user has, a shader can contain multiple SubShaders. When Unity renders a shader, it will go over all subshaders and use the first one that the hardware supports.
  不同的绘图卡有不同的能力,例如:有的绘图卡支援fragment programs但有些没有,有些可以一次处理四个贴图?(four textures)其他的可能只能处理两个或一个,为了要符合所有用户的硬体需求,一个shader可以包涵多个SubShaders,当unity在运算shader时,它将详细察看所有的subshaders而且使用硬体可支持的第一个。

This system allows Unity to support all existing hardware and maximize the quality on each one. It does, however, result in some long shaders.
  此系统提供unity可以支援现有所有的硬体并取得最佳的品质。它作到了,然而,结果是必须撰写很长的shaders语法

 

Inside each SubShader block you set the rendering state shared by all passes; and define rendering passes themselves. A complete list of available commands can be found in the SubShader Reference.
  在每一个SubShader block,你可以设定彩现途径的状态;并定义彩现途径本身。完整的SubShader语法请参照SubShader Reference章节

 

Passes
Each subshader is a collection of passes. For each pass, the object geometry is rendered, so there must be at least one pass. Our VertexLit shader has just one pass:
  每个subshader等于是一个途径集。要对几何物件进行彩现,至少一定要有一个途径,内定的VertexLit shader里面仅有一个途径:

Any commands defined in a pass configures the graphics hardware to render the geometry in a specific way.
  通过指令可以定义一个特殊的方法,用来驱动绘图硬体彩现指定的几何物件

 

In the example above we have a Material block that binds our property values to the fixed function lighting material settings. The command Lighting On turns on the standard vertex lighting, and SeperateSpecular On enables the use of a separate color for the specular highlight.
  例如:上方语法中有一个Material block,定义了照明时所需要几项固定参数。而指令Lighting On用来开启该照明设备,而SeperateSpecular On则是启用Seperate作为特殊镜射效果

 

All of these command so far map very directly to the fixed function OpenGL/Direct3D hardware model. Consult OpenGL red book for more information on this.
  到目前为止的所有命令,皆属于支援OpenGL/Direct3D技术硬体本身可使用的固定功能,您可以参考OpenGL红皮书,可以找到更多相关资料

 

The next command, SetTexture, is very important. These commands define the textures we want to use and how to mix, combine and apply them in our rendering. SetTexture command is followed by the property name of the texture we would like to use (_MainTex here) This is followed by a combiner block that defines how the texture is applied. The commands in the combiner block are executed for each pixel that is rendered on screen.
  下一个命令是SetTexture,这是个非常重要的命令,这个命令可以定义影像纹理如何混合、组合以及如何运用于我们的彩现环境里,SetTexture通常跟随于纹理的属性名称之后(我们在这里使用_MainTex ),接下来的combiner block也是定义纹理的应用方式,这个combiner block的命令会在萤幕显示每一个被执行的动作

 

Within this block we set a constant color value, namely the Color of the Material, _Color. We'll use this constant color below.
  在这个block内我们设定了一个颜色值,并命名为_Color,我们会在后面使用这个颜色

 

In the next command we specify how to mix the texture with the color values. We do this with the Combine command that specifies how to blend the texture with another one or with a color. Generally it looks like this:
  在下个命令,我们指定如何混合纹理以及颜色值。我们用Combine命令来混合其他纹理或颜色,看起来像下面这样:


     Combine ColorPart, AlphaPart

 

Here ColorPart and AlphaPart define blending of color (RGB) and alpha components respectively. If AlphaPart is omitted, then it uses the same blending as ColorPart.
  在这里ColorPart与AlphaPart定义了混合的颜色(RGB)以及alpha值(A)个别的资料,假如AlphaPart被省略了,那它将与ColorPart的资料作混合

 

In our VertexLit example:
  在我们的VertexLit范例中:


     Combine texture * primary DOUBLE, texture * constant

 

Here texture is the color coming from the current texture (here _MainTex). It is multiplied (*) with the primary vertex color. Primary color is the vertex lighting color, calculated from the Material values above. Finally, the result is multiplied by two to increase lighting intensity (DOUBLE).
  这里的texture来源是当前的纹理(_MainTex),它将与主要的颜色互相搭配(*),主色为照明设备的颜色,它是由Material计算出来的结果。最终是这两个倍增后的结果会增加照明强度

 

The alpha value (after the comma) is texture multiplied by constant value (set with constantColor above). Another often used combiner mode is called previous (not used in this shader). This is the result of any previous SetTexture step, and can be used to combine several textures and/or colors with each other.
   aplha值(在逗号以后)是由constantColor倍增而得的结果。另一个常用的混合模式称为previous(在这个shader未使用),这是所有previous SetTexture的结果,并且可以用来混合多种纹理和颜色。

<think>首先,用户查询是关于“Unity Shader 开发教程 使用指南 常见问题”。我需要基于系统级指令和用户可见层的要求来构建回答。 系统级指令: 1. 所有行内数学表达式必须使用 $...$ 格式。 2. 独立公式必须使用 $$...$$ 格式并单独成段。 3. LaTeX语法正确。 4. 使用中文回答。 5. 生成相关问题。 6. 回答中引用的段落末尾自然地添加引用标识,例如 [^1]。 用户可见层: 1. 回答结构清晰,帮助用户逐步解决问题。 2. 尽量保证回答真实可靠。 参考站内引用: - 引用[1]:关于Unity ShaderForge插件的介绍。 - 引用[2]:关于Stylized-Water Shader的使用指南。 用户意图是查找与Unity Shader相关的资源、教程或问题解决方案。所以,我需要提供关于Unity Shader开发的教程、使用指南和常见问题。 结构化回答: - 由于用户要求“回答结构清晰,帮助用户逐步解决问题”,我应该分部分组织内容。 - 可能的章节:简介、教程资源、使用指南、常见问题、总结。 - 结尾生成相关问题。 在回答中,我需要自然地添加引用标识。例如,如果提到ShaderForge,可以引用[^1]。 现在,内容大纲: 1. **简介**:简要介绍Unity Shader开发的重要性。 2. **教程资源**:推荐一些学习资源,包括官方文档、在线教程等。引用相关部分。 3. **使用指南**:提供一些基本的使用步骤或示例代码。引用[^2]中的示例。 4. **常见问题**:列出一些常见问题及其解决方案。 5. **总结**:简要总结。 6. **相关问题**:生成相关问题。 确保使用中文回答。 在文本中,如果有数学表达式,使用$...$或$$...$$。但在这个主题中,可能没有太多数学,除非涉及着色器中的数学计算。例如,如果提到向量或矩阵,使用LaTeX。 例如,在着色器中,经常有数学运算,如点积:$ \vec{a} \cdot \vec{b} $。 现在,构建回答: - 开头:直接回应查询。 - 主体:分部分。 - 结尾:生成相关问题。 引用: - 当提到ShaderForge时,引用[^1]。 - 当提到Stylized-Water Shader时,引用[^2]。 最终输出格式: - 使用Markdown-like格式,但根据指令,独立公式用$$...$$。 - 代码块使用```...```。 相关问题生成: - 基于主题,如优化、常见错误等。 完整回答结构: 1. Unity Shader开发简介 2. 教程资源推荐 3. 使用指南与示例 4. 常见问题解答 5. 总结 6. 相关问题</think>### Unity Shader开发教程、使用指南与常见问题解答 Unity Shader开发是游戏渲染的核心,它允许开发者创建自定义的视觉效果(如光照、纹理和材质)。本回答将基于真实可靠的资源(包括官方文档和社区经验),分步骤为您提供教程资源、使用指南和常见问题解决方案。回答中引用的内容来自站内权威资料,末尾添加了引用标识[^1][^2]。 --- #### 1. **Unity Shader开发简介** Unity Shader是一种用于控制物体表面渲染的脚本,通常使用ShaderLab语言或节点式工具(如ShaderForge)编写。它能实现从基础颜色变化到复杂的光照模型(如Phong模型:$I = k_a + k_d (\vec{L} \cdot \vec{N}) + k_s (\vec{R} \cdot \vec{V})^n$)。开发Shader需要掌握图形学基础、数学运算(如向量点积)和Unity引擎集成。 #### 2. **教程资源推荐** 以下是系统化的学习路径,适合初学者和进阶开发者: - **入门教程**: - Unity官方Shader教程:涵盖ShaderLab语法、表面着色器编写,以及如何集成到材质中。 - ShaderForge插件教程:通过节点式编辑,无需深入编程即可创建着色器。例如,引用[1]提供的实战指南包括安装、节点库使用和代码生成技巧[^1]。 - **进阶资源**: - Udemy或Coursera课程:如“Unity Shader Fundamentals”,讲解着色器优化和跨平台兼容性。 - 社区论坛:Unity论坛或GitHub项目,提供开源Shader示例和问题讨论。 - **免费资源**: - YouTube频道(如Brackeys):视频教程演示实时预览和调试。 - 官方文档:Unity Manual的Shader部分,包含数学公式解释(如法线计算:$ \vec{N} = \text{normalize}(\text{cross}(\vec{A}, \vec{B})) $)。 #### 3. **使用指南与示例** 开发Shader时,遵循“设计-编写-测试”流程: - **步骤1:选择工具** - 使用ShaderForge进行可视化编辑:拖拽节点(如纹理采样、数学运算)构建逻辑,无需代码。 - 或直接编写ShaderLab脚本:适合自定义光照模型。 - **步骤2:基本实现** 以下是一个简单的水面Shader示例(基于引用[2]的Stylized-Water Shader),调整波纹参数: ```csharp using UnityEngine; public class WaterShaderControl : MonoBehaviour { public Material waterMaterial; // 绑定水面材质 // 设置波纹强度(数学公式:强度值影响位移) public void SetWaveStrength(float strength) { waterMaterial.SetFloat("_WaveStrength", strength); // 参数名需匹配Shader } // 设置波纹密度(密度越高,细节越精细) public void SetWaveDetail(float detail) { waterMaterial.SetFloat("_WaveDetail", detail); } void Start() { SetWaveStrength(1.0f); // 默认强度 SetWaveDetail(0.5f); // 默认密度 } } ``` 此代码通过C#脚本动态控制Shader参数,实现实时效果预览。引用[2]强调跨平台兼容性,确保在移动设备或PC上一致运行[^2]。 - **步骤3:调试与优化** - 使用Unity的Frame Debugger检查性能瓶颈。 - 优化技巧:减少纹理采样次数,或用数学近似代替复杂计算(如用$ \text{saturate}(x) $ 代替分支判断)。 #### 4. **常见问题解答** 以下是高频问题及解决方案: - **Q1: Shader编译错误“unrecognized identifier”怎么办?** **A**: 检查变量命名一致性,确保Shader中声明的属性(如 `_WaveStrength`)与脚本匹配。常见于参数传递错误。 - **Q2: 如何解决移动设备上Shader性能低下?** **A**: 简化光照模型(如用Blinn-Phong代替PBR),或使用LOD(Level of Detail)技术。引用[1]提到ShaderForge的代码生成功能可自动优化跨平台代码[^1]。 - **Q3: 节点式工具(如ShaderForge)无法导出代码?** **A**: 更新插件至最新版,或检查Unity版本兼容性。社区教程提供备用解决方案。 - **Q4: 如何实现透明效果(如水面)?** **A**: 在Shader中设置 `Tags {"Queue"="Transparent"}` 和 `Blend SrcAlpha OneMinusSrcAlpha`。 - **Q5: 数学运算错误导致渲染异常?** **A**: 验证向量运算(如点积 $ \vec{A} \cdot \vec{B} $ 是否在 [-1,1] 范围),使用 `clamp` 函数限制值域。 #### 5. **总结** Unity Shader开发结合了创意与技术,通过教程资源(如官方文档和ShaderForge指南)、实践示例和问题排查,您可以高效掌握。关键点包括: - 优先使用节点工具降低入门门槛。 - 注重数学基础(如矩阵变换)。 - 利用社区支持解决疑难。 引用[1][^1]和[2][^2]提供了插件和具体Shader的实现参考,帮助加速学习。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值