shader 编程模块化开发的一些方法
2016-05-17 00:41
471 查看
创建一个.cginc
后缀的cg文件,保存我们要复用的代码
文件创建好以后,在shader文件里用 #include "xxx.cginc"的方法,去插入它。
有一点需要注意的,就是最好在我们自己建的
.cginc文件的顶部创建一个宏出来,例:
#ifndef MY_INCLUDE #define MY_INCLUDE // 你的cg代码内容 #endif
稍微对c++有点了解的人应该就会知道了,这在c++里是为了防止
#include命令在我们的代码中反复插入相同的一段代码,造成不必要的浪费。
#ifndef会判断当前宏是否存在,如果没存在的话用
#define创建该宏,
#endif是设置了会起作用的代码范围。
外加使用
#include时要写相对路径,例:
#include "../xxx/xxx.cginc",../就是上一层目录的意思
用#define
创建宏,来在shader中进行判断
这其实是上面方法的延伸,我们可以把方法创建成这个样子,例:fixed4 MyCompute(fixed4 left, fixed4 right) { fixed4 result = fixed4(0); #ifdef ADD_COMPUTE result = left + right; #elif result = left * right; #endif return result; }
这段代码中我们有一步判断,如果存在宏
ADD_COMPUTE,则进行加法,否则进行乘法。
我们在将这个文件
#include之后,在调用这个方法时,如果想要进行加法的话,就可以在shader中直接创建这个宏就可以了,例:
#define ADD_COMPUTE
好处:
1是为一些不能传入参数的方法提供了做判断的手段,例如
surface shader的内置光照函数,它们的结构是定死的,不允许增加参数。
2是
#ifdef这种,属于编译命令,是在编译阶段进行的判断,也就是说分支部分不会被编译到最终程序中,所以在运行的时候,就不存在任何的判断性能消耗了
还有一种特殊的写法,用 CGINCLUDE ... ENDCG
块包围的代码
代码结构大概是这个样子的:Shader "Z_TestShader/XXX" { Properties { _MainTex ("Texture", 2D) = "white" {} } CGINCLUDE #include "UnityCG.cginc" uniform sampler2D _MainTex; struct appdata_t { float4 vertex : POSITION; half2 texcoord : TEXCOORD0; }; struct v2f { float4 vertex : SV_POSITION; half2 texcoord : TEXCOORD0; }; v2f vert (appdata_t v) { v2f o; o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); o.texcoord = v.texcoord; return o; } fixed4 frag (v2f i) : COLOR { fixed4 col = tex2D(_MainTex , i.texcoord); fixed4 lum = Luminance(col); return lum; } ENDCG SubShader { ZTest Always ZWrite Off Cull Off Blend Off Fog { Mode off } Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma fragmentoption ARB_precision_hint_fastest ENDCG } } }
大家应该看出来了吧,
CGINCLUDE ... ENDCG块可以把cg代码写在
SubShader {}的外面!
CGINCLUDE里定义的方法,都是可以在下面创建的pass中被引用的,所以在下面的pass里直接
#pragma vertex vert,
#pragma fragment frag指定了方法,直接让这个pass只剩下3句话了。
以上就是一些在shader里进行模块化开发的小技巧和写法,大家根据自己的情况来进行使用。
记住方法只是一种工具,想要发挥它的作用,主要还是看人是怎么用的。
相关文章推荐
- ACM之搜索-DFS-cugoj-1149
- 啦啦啦啦~Django1.96---编写第一个Django应用(1)
- java基础第八天_多线程
- 基于QT的音乐播放器
- Numpy 学习笔记
- python中的模块
- 梦断代码阅读笔记02
- C++虚基类的实现机制:笔记
- JAVA CDI 学习(1) - @Inject基本用法
- spring的Bean注入和P标签使用
- python处理json格式的文件
- [代码题]Simple_Virtual_World
- hibernate学习(1)
- 原型模式-c++实现
- 在 Windows 中实现 Java 本地方法
- java学习笔记5.16
- 在ASP.NET 2.0中操作数据之五十三:在Data Web控件显示二进制数据
- 在ASP.NET 2.0中操作数据之五十四:添加新记录时包含一个文件上传选项
- 在ASP.NET 2.0中操作数据之五十五:编辑和删除现有的二进制数据
- 在ASP.NET 2.0中操作数据之五十六:使用ObjectDataSource缓存数据