【Unity 代码相关】自定义CGInclude 预编译

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

补充一些零碎的小知识点为了提高效率我选择更快速的方法直接引用他人写的不错的文章复习的时候就可以直接查看啦

1 自定义cginc工具库 

unity 自定义shader cginc 函数工具库并引用

Unity内置有很多.cginc文件都是自带的shader工具函数库例如常用的Lighting.cgincUnityCG.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

#ifndefif ! 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        //  为编译程序提供非常规的控制流信息可跟oncemessage等许多参数。

2.3 #pragma once 指令

这个指令似乎没怎么见过它的作用是使同一个文件不会被包含多次与上面提到的#ifndef相比更加方便了遇到已经被引过的文件会直接跳过。但无法剔除不同的2个表达同一个物理意义的文件。

与#ifndef混用

#pragma once

#ifndef  XXX
#define  XXX

#endif
阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6