`
380071587
  • 浏览: 445927 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

shaderlab学习一

 
阅读更多

转载:http://wuchengwu5.blog.163.com/blog/static/852237120111115104310682/

Unity中的材质着色器被称为ShaderLab,形式上接近于CgFXDirect3D Effects (.FX)

在Unity中配置属性的时候,其实就是针对Shader进行配置。下面我们看一个简单的脚本:

Shader "u3dcool.com/Tutorial/Basic" {      Properties {          _Color ("Main Color", Color) = (1,0.5,0.5,1)      }      SubShader {          Pass {              Material {                  Diffuse [_Color]              }              Lighting On          }      }  }

从中我们可以看到一个Shader脚本的组成:

  • Shader 包括所有代码,第一行的就是一个Shader的名称,斜杠表示目录结构;
  • Properties 包括了可以在Inspector(编辑器)中进行配置的参数选项;
  • SubShader 一个Shader中可以又多个SubShader来完成不同能力的渲染。

因为上面的例子比较简单,我们以一个比较复杂的VertexLit为例,再来说明一个Shader的组成,如下所示:

Shader "VertexLit" {      Properties {          _Color ("Main Color", Color) = (1,1,1,0.5)          _SpecColor ("Spec Color", Color) = (1,1,1,1)          _Emission ("Emmisive Color", Color) = (0,0,0,0)          _Shininess ("Shininess", Range (0.01, 1)) = 0.7          _MainTex ("Base (RGB)", 2D) = "white" { }      }        SubShader {          Pass {              Material {                  Diffuse [_Color]                  Ambient [_Color]                  Shininess [_Shininess]                  Specular [_SpecColor]                  Emission [_Emission]              }              Lighting On              SeparateSpecular On              SetTexture [_MainTex] {                  constantColor [_Color]                  Combine texture * primary DOUBLE, texture * constant              }          }      }  }

上面的这个例子稍微复杂一点,我们一点一点来讲。

Properties

首先就是这个Properties(属性)块,它定义了一些设计师可以在Inspector(Unity中的属性编辑界面)中进行配置的属性

在Properties代码中,每一个属性值占一行。每一行的写法:首先是内部名称(Internal name),然后是Inspector中显示的名称(Inspector title),然后是该属性的类型(Property type),最后是该属性的默认值(Default value)。如下所示:

所有属性的类型如下所示,而属性的默认值也因属性的不同而不同:

  • name (“display name”, Range (min, max)) = number
  • name (“display name”, Color) = (number, number, number, number)
  • name (“display name”, 2D) = “name” { options }
  • name (“display name”, Rect) = “name” { options }
  • name (“display name”, Float) = number
  • name (“display name”, Vector) = (number, number, number, number)

现在我们的属性定义就算是OK了,让我们再来看看如何编写真正的着色部分。

The Shader Body

不同的显卡有不同的处理能力,比如有的显卡就支持Fragment Program(片段编程),而有的就不支持。那为了更好的利用显卡的处理性能,所以在一个大的Shader中就包含了很多“小”Shader,被称之为SubShaders。当Unity渲染着色时,它会遍历所有SubShader,找到第一个被显卡支持的SubShader然后执行。如下所示:

Shader "Structure Example" {      Properties { /* ...shader properties... */}      SubShader {       // ...subshader that uses vertex/fragment programs...      }      SubShader {       // ...subshader that uses four textures per pass...      }      SubShader {       // ...subshader that uses two textures per pass...      }      SubShader {       // ...subshader that might look ugly but runs on anything :)      }  }  

Shader的这个特性,使得Unity既可以支持所有的硬件设备,又可以很好的区分并利用不同的硬件平台。但因此也使得Shader看起来有点长。

每一个SubShader定义了可供所有通道(All Passes)使用的渲染状态(Rendering State),同时又定义了渲染通道(Rendering Passes)。

Passes

每一个SubShader包含了很多通道,而通道又去渲染图形。因此,每个SubShader中必然包含至少一个Pass(通道)。比如刚才的VertexLit着色器代码所示:

// ...snip...  Pass {      Material {          Diffuse [_Color]          Ambient [_Color]          Shininess [_Shininess]          Specular [_SpecColor]          Emission [_Emission]      }      Lighting On      SeparateSpecular On      SetTexture [_MainTex] {          constantColor [_Color]          Combine texture * primary DOUBLE, texture * constant      }  }  // ...snip...  

在Pass中定义的命令告诉显卡应该去如何渲染特定的图形。

上面代码中的Material代码块绑定了一些属性。而Lighting On则激活了标准顶点光源(Standard Vertex Lighting),SperateSpecular On则激活了不同颜色的反射高光。

所有这些命令其实都映射到了OpenGL/Direct3D的硬件模型(Hardware Model)。

SetTexture命令则定义了如何对贴图进行处理,在这里使用了Combine对贴图进行处理,其语法为:

Combine ColorPart, AlphaPart  

Summary

到现在我们已经基本实现了一个Shader,里面包含一个SubShader和其中的一个Pass。其实我们可以定义多个SubShader和多个Pass。但现在的这个Shader已经满足了我们的需要,因为写成这样即可。

First教程,搞定~

<wbr></wbr>
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics