补充一些零碎的小知识点,为了提高效率我选择更快速的方法,直接引用他人写的不错的文章,复习的时候就可以直接查看啦!
1 自定义cginc工具库
unity 自定义shader cginc 函数工具库并引用
Unity内置有很多.cginc文件,都是自带的shader工具函数库,例如常用的Lighting.cginc、UnityCG.cginc等,shader中引用通常是在PASS中添加如下内容:
#include "UnityCG.cginc"
当我们想要自己自定函数工具库时,就要考虑何种格式、shader中如何使用的问题了。
1.1 创建文件
unity内部不能直接创建.cginc文件,文件夹下文件,更改后缀为.cginc
1.2 标准结构格式
#ifndef XXX
#define XXX
// 定义常用的宏、结构体、全局变量、函数等等
#endif
#ifndef 避免双重定义
当程序文件多了起来,容易出现文件被重复引用的情况,此时最好加上#ifdef #define和#endif,避免双重定义的错误,拿最近做庄懂赛博小人有个自定义的插值环境光.cginc文件为例:
#ifndef MY_CGINC
#define MY_CGINC
//插值环境光,三个颜色:顶up、侧side、底down
float3 TrinColAmbient (float3 n, float3 uCol, float sCol, float dCol) {
float uMask = max(0.0, n.g); // 获取朝上部分遮罩
float dMask = max(0.0, -n.g); // 获取朝下部分遮罩
float sMask = 1.0 - uMask - dMask; // 获取侧面部分遮罩
float3 envCol = uCol * uMask +
sCol * sMask +
dCol * dMask; // 混合环境颜色
return enCol;
}
#endif
#ifndef,if ! define,即“如果没定义xx”,整个预编译过程大概是:
如果没定义MY_CGINC这个宏的话,则条件为真,继续进行接下来直到#endif中间的内容,即定义MY_CGINC这个宏,并定义一个方法TrinColAmbient();如果定义过了这个宏,则条件为假,直接跳过内容,endif
1.3 使用
如果.cginc文件在当前shader的相同目录下,直接:
#include "MYcginc.cginc"
但一般我们创建的.cginc文件都会放在跟shader不同的文件目录下,此时就需要相对路径了:
#include "../cginc/Mycginc.cginc"
这里的../表示上一级目录,同样的../../表示上两级目录,具体关于相对路径可以看:什么是相对路径?相对路径的具体写法和用法
2 预编译处理
VS学习c语言笔记记录_九九345的博客-CSDN博客_vs语言符合模式
什么是相对路径?相对路径的具体写法和用法
既然涉及到了#ifndef、#define的内容,就顺便学习一下预编译处理这个概念。
2.1 基本概念
什么是?
预编译也可以叫做预处理,是做些代码文本的替换工作,处理#开头的指令,例如:
#include // 拷贝#include包含的文件代码
#define // 宏定义替换
什么时候开始?
预编译指令发生在程序正式开始编译前,但这个预编译本身可以放在程序的任何位置。
3种功能
宏定义
条件编译
包含文件
2.2 常见的编译指令
这里直接引用了文章避免头文件重复引入和重复定义中的汇总,侵删:
//条件编译
#define // 宏定义
#undef // 取消宏
#include // 文本包含
#ifdef // 如果宏被定义就进行编译
#if defined // 与ifdefine的区别在于可以可以组成复杂的判别条件
#ifndef // 如果宏未被定义就进行编译
#if !defined // 与if !define的区别在于可以可以组成复杂的判别条件
#endif // 结束编译块的控制
#if defined // 表达式非零就对代码进行编译
#else // 作为其他预处理的剩余选项进行编译
#elif // 这是一种#else和#if的组合选项
#elif defined // 与ifdefine的区别在于可以可以组成复杂的判别条件
#elif !defined // 与ifdefine的区别在于可以可以组成复杂的判别条件
//编译指令
#line // 改变当前的行数和文件名称
#error // 输出一个错误信息
#pragma // 为编译程序提供非常规的控制流信息,可跟once,message等许多参数。
2.3 #pragma once 指令
这个指令似乎没怎么见过,它的作用是:使同一个文件不会被包含多次,与上面提到的#ifndef相比更加方便了,遇到已经被引过的文件会直接跳过。但无法剔除不同的2个表达同一个物理意义的文件。
与#ifndef混用
#pragma once
#ifndef XXX
#define XXX
#endif
————————————————
版权声明:本文为CSDN博主「九九345」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_41835314/article/details/128835713