着色器和shade

发布时间:2016-12-11 6:45:12 编辑:www.fx114.net 分享查询网我要评论
本篇文章主要介绍了"着色器和shade",主要涉及到着色器和shade方面的内容,对于着色器和shade感兴趣的同学可以参考一下。

Properties块内的语法都是单行的。每个属性都是由内部名称 开始,后面括号中是显示在检视面板(Inspector)中的名字和该属性的类型。等号后边跟的是默认值。 零基础Unity3D游戏开发系列 第四章:游戏资源导入导出(三)材质与着色器 已经定义好了需要的属性,可以开始写自己的着色器(shader)了 不同的显卡有不同的渲染能力。例如,某些显卡支持片段程序( fragment programs)和别人不一样,有的可以放下四个纹理通道(textures per pass)而有些只放下一个或两个。为了适应不同的显卡,一个着色器可以包含多个子着色器(SubShaders)。Unity在渲染着色器时,它会根据显卡去匹配合适的子着色器(subshaders)。 通道Passes 每个子着色器(subshader)都是一个通道集合。对于每一个pass,都要渲染几何对象,所以必须至少有一个pass。我们的VertexLit着色器只有一个pass .在pass内定义的任何一个命令都会在显卡上渲染指定的几何图形。 在上面的例子中,我们有一个材质(Material)块,定义了照明时所需要几项固定参数。 Lighting On 这个命令是打开顶点光照明设备,SeparateSpecular On是指允许使用一个单独的颜色作为镜面高光。 SetTexture是非常重要的。这个命令可以定义影像纹理如何混合、组合以及如何运用于我们的渲染里,SetTexture之后通常跟随纹理的属性名称(我们在这里使用_MainTex ),接下来是combiner 块,定义纹理的处理方式,这个combiner 块的命令会对屏幕显示每一个像素执行的运算。 在这个块(Material块)内我们设定了一个常量颜色值(_Color)。接下来Combine命令,我们指定如何混合纹理以及颜色值。用Combine命令格式: Combine ColorPart, AlphaPart 在这里ColorPart与AlphaPart定义了混合的颜色(RGB)和alpha值(A)的信息,如果AlphaPart被省略了它将与颜色部分做同样的混合。 这个例子中,颜色部分的结果来着当前纹理(_MainTex)的颜色,乘以顶点光照颜色,再乘以2以增强照明强度。aplha值(在逗号以后)是由texture*constant得来(constant由之前constantColor设置)。 在Unity着色器中编写自定义顶点(vertex)和片段程序( fragment programs)。 顶点(vertex)和片段程序( fragment programs) 快速创建一个子着色器(SubShaders)的方法是使用其他定义好的通道(passes)。UsePass就是这样的一个命令,所以你可以重复使用优秀的着色器代码。下面的例子将教你使用该命令实现调用Unity内置的名字为“BASE”的镜面着色器(Specular shader): UsePass “Specular/BASE” 为了让UsePass起作用,必须给通道(pass)一个你所想要的名字。Name这个命令是给当前所在的通道(pass)赋予一个名字。 Name “MyPassName” 当你使用顶点(vertex)和片断程序(fragment programs)(即所谓的“可编程管线)时,显卡的大部分硬编码(”固定功能管线“)功能将关闭。例如,使用一个顶点(vertex)程序完全可以做到关闭标准的3D变换,灯光和纹理坐标的功能。类似的,使用一个片段程序( fragment programs)可以替换任何纹理混合模式。编写顶点(vertex)/片断程序(fragment programs)需要对3D转换,照明和坐标空间有透彻的了解 。 因为你要自己写出API 实现的效果就像OpenGL的自身的固定功能一样。另外,还可以实现比置功能以外自己需要的功能。//Unity3D教程手册:www.unitymanual.com 着色器通过在着色器文本中嵌入”Cg片段“实现在着色器语言(ShaderLab)中写入Cg编程语言。Cg片段是通过Unity编辑被编译成低级的着色器,最终的着色器是包含在你的游戏数据文件内的,游戏数据文件只包含低级指令集合。当你在项目视图( Project View)中选择一个着色器,在检视面板(Inspector)中的着色器文本后会显示Cg 编译(Cg compilation),这可能有助于帮助调试。Unity将自动编译OpenGL和Direct3D的Cg片段,所以你写的着色器使用了Cg也可以在这两个环境下运行。要注意的是,Cg代码是要通过编译的,所以你不能在运行的时候创建Cg着色器代码。 一般情况下,Cg片段是放在通道(Pass)块的。就像下面这样: [C#] 纯文本查看 复制代码 ? 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <font style="color:rgb(85, 85, 85)"><font face="微软雅黑">Pass {   // ... the usual pass state setup ...      CGPROGRAM   // compilation directives for this snippet, e.g.:   #pragma vertex vert   #pragma fragment frag      // the Cg code itself      ENDCG   // ... the rest of pass setup ...   } </font></font> 下面的例子演示了一个完整Cg程序的着色器,它渲染对象的结果是颜色随着法线而变化: [C#] 纯文本查看 复制代码 ? 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 <font style="color:rgb(85, 85, 85)"><font face="微软雅黑">Shader "Tutorial/Display Normals" {   SubShader {   Pass {      CGPROGRAM   #pragma vertex vert   #pragma fragment frag   #include "UnityCG.cginc"      struct v2f {   float4 pos : SV_POSITION;   float3 color : COLOR0;   };      v2f vert (appdata_base v)   {   v2f o;   o.pos = mul (UNITY_MATRIX_MVP, v.vertex);   o.color = v.normal * 0.5 + 0.5;   return o;   }      half4 frag (v2f i) : COLOR   {   return half4 (i.color, 1);   }   ENDCG      }   }   Fallback "VertexLit"   } </font></font> 应用到对象上时,会看到和下图类似的效果。(需要你的显卡支持顶点(vertex)和片段程序(fragment programs)) 零基础Unity3D游戏开发系列 第四章:游戏资源导入导出(三)材质与着色器 分析一下这段Cg代码。 整个Cg片段写在CGPROGRAM与ENDCG关键字中间。开始编译的指令是 #pragma 给出: #pragma vertex name告诉该代码在提供的函数里包含了一个顶点(vertex)程序。(上面的例子中是在vert 函数里)。 #pragma fragment name告诉代码在提供的函数里包含了一个片段(fragment)程序。(上面的例子中是在frag 函数里)。 接下来编译的指令只是普通的Cg代码。首先需要导入一个内置的Cg文件: #include UnityCg.cginc UnityCg.cginc文件包含了常用的声明,所以可以保持着色器程度简短。这个文件可以在Unity里找到(Windows系统下:{Unity安装路径} /Data /CGIncludes /UnityCG.cginc;Mac系统下:/Applications/Unity/Unity.app/Contents/CGIncludes/UnityCG.cginc)。在这里,我们将通过这个文件使用appdata_base结构。我们也可以不导入这个文件,直接在着色器中定义他们。 接下来,我们定义一个“顶点(vertex)片段(fragment)”结构(这里命名为V2F) -什么信息是从顶点(vertex)传递到片断(fragment)程序?通过位置(position)和颜色(color)参数。颜色将在顶点(vertex)程序中计算,只在片断(fragment)程序中输出。 先定义顶点(vertex)程序-在这里是vert 函数。在这个函数内,我们计算位置(position)和颜色(color)然后返回: [C#] 纯文本查看 复制代码 ? 1 2 <font style="color:rgb(85, 85, 85)"><font face="微软雅黑">o.color = v.normal * 0.5 + 0.5; </font></font> 法线(normal)的取值范围是[-1,1],而颜色的取值范围是[0,1]。所以我们要通过上述计算微调一下,才能符合颜色的取值范围。接下来我们定义了一个片段(fragment)程序-frag 函数。它只返回计算好的颜色和透明值。 [C#] 纯文本查看 复制代码 ? 1 2 3 4 5 6 7 8 <font style="color:rgb(85, 85, 85)"><font face="微软雅黑">half4 frag (v2f i) : COLOR   {   return half4 (i.color, 1);   } </font></font> 在Cg代码中使用着色器属性 当你在着色器中定义属性(properties)的时候,你给他们起这样的名字:_Color或_MainTex。但在Cg代码中使用着色器属性(shader properties),你就必须定义一个变量,变量的的名字和类型要与它相匹配。Unity会自动设置的CG变量,名字与着色器属性(Shader properties)匹配。//Unity3D教程手册:www.unitymanual.com 下面是一个完整的着色器,它显示了一张调整了颜色的纹理。当然,你可以很容易地在纹理合成中调用类似的指令,但现在只是为了展示一下如何在Cg代码中使用属性(properties): [C#] 纯文本查看 复制代码 ? 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 <font style="color:rgb(85, 85, 85)"><font face="微软雅黑">Shader "Tutorial/Textured Colored" {   Properties {   _Color ("Main Color", Color) = (1,1,1,0.5)   _MainTex ("Texture", 2D) = "white" { }   }   SubShader {   Pass {      CGPROGRAM   #pragma vertex vert   #pragma fragment frag      #include "UnityCG.cginc"      float4 _Color;   sampler2D _MainTex;      struct v2f {   float4 pos : SV_POSITION;   float2 uv : TEXCOORD0;   };      float4 _MainTex_ST;      v2f vert (appdata_base v)   {   v2f o;   o.pos = mul (UNITY_MATRIX_MVP, v.vertex);   o.uv = TRANSFORM_TEX (v.texcoord, _MainTex);   return o;   }      half4 frag (v2f i) : COLOR   {   half4 texcol = tex2D (_MainTex, i.uv);   return texcol * _Color;   }   ENDCG      }   }   Fallback "VertexLit"   } </font></font> 在这里,我们定义了两个属性(properties),即_Color和_MainTex。在Cg代码内,我们定义相应的变量: [C#] 纯文本查看 复制代码 ? 1 2 3 4 <font style="color:rgb(85, 85, 85)"><font face="微软雅黑">float4 _Color;   sampler2D _MainTex; </font></font> 这里的顶点(vertex)和片断(fragment)程序没有做别的事情;顶点(vertex)程序使用UnityCG.cginc里的TRANSFORM_TEX,用来保证纹理(texture)正确的缩放和偏移。片断(fragment)程序只是对纹理(texture)进行采样然后乘以颜色值。 请注意,因为这是我们自己编写的片段(fragment)程序,我们并不需要任何SetTexture命令,就演示了如何在着色器中利用片段(fragment)程序完美的控制纹理(texture)。 编写表面着色器 Writing Surface Shaders 表面着色器示例 Surface Shader Examples 本文来自:Unity3D教程手册QQ群(290248177)作者:傻瓜(QQ:4073

上一篇:linux 移植遇到的问题备份
下一篇:Spring中的JDBCTemplate使用(非常详细的配置过程)

相关文章

关键词: 着色器和shade

相关评论