[Unity script related] Custom CGInclude precompilation

Add some small knowledge points. In order to improve efficiency, I choose a faster method, directly quoting good articles written by others, and you can directly check them when reviewing!

1 Custom cginc tool library 

Unity custom shader cginc function tool library and reference

Unity has many built-in .cginc files, all of which are built-in shader tool function libraries, such as the commonly used Lighting.cginc , UnityCG.cginc , etc. The references in the shader are usually added to the PASS as follows:

#include "UnityCG.cginc"

When we want to customize the function tool library by ourselves, we have to consider the format and how to use it in the shader.

1.1 Create a file

The .cginc file cannot be directly created inside unity, and the file under the folder should be changed to .cginc

1.2 Standard structure format

#ifndef XXX
#define XXX

// 定义常用的宏、结构体、全局变量、函数等等

#endif

#ifndef avoids double definition

 When the number of program files increases, it is easy to cause the files to be repeatedly referenced. At this time, it is best to add #ifdef #define and #endif to avoid double definition errors. Take the recent cyber villain to have a custom one. Take the interpolation ambient light .cginc file as an example:

#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, that is, "if xx is not defined", the whole precompilation process is probably:

If the macro MY_CGINC is not defined, the condition is true, continue until the content in the middle of #endif, that is, define the macro MY_CGINC, and define a method TrinColAmbient(); if this macro is defined, the condition is false, Skip content directly, endif

1.3 use

If the .cginc file is in the same directory as the current shader, directly:

#include "MYcginc.cginc"

But generally the .cginc file we create will be placed in a file directory different from the shader, and a relative path is needed at this time:

#include "../cginc/Mycginc.cginc"

The ../ here means the upper level directory, and the same ../../ means the upper two level directories. For details about the relative path, you can see: What is a relative path? The specific writing and usage of relative paths

2 precompilation processing

VS learning c language note record

What is precompilation? When is precompilation required (interview questions for C and C++ engineers)

Now that the content of #ifndef and #define is involved, let's learn the concept of precompilation processing by the way. 

2.1 Basic concepts 

what is?

Precompilation can also be called preprocessing, which is to do some code text replacement work and process instructions starting with #, for example:

#include // Copy the file code included in #include

#define // macro definition replacement

When does it begin?

Precompilation instructions occur before the program officially starts to compile , but this precompilation itself can be placed anywhere in the program.

3 functions

  • macro definition
  • conditional compilation
  • include file

2.2 Common compilation instructions

Here is a direct reference to the article to avoid repeated introduction of header files and summary of repeated definitions, invasion and deletion:

//条件编译
     #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 directive

This instruction seems to have not been seen much. Its function is to prevent the same file from being included multiple times . Compared with #ifndef mentioned above, it is more convenient. When encountering a file that has been cited, it will be skipped directly . However, two different files expressing the same physical meaning cannot be eliminated.

mixed with #ifndef

#pragma once

#ifndef  XXX
#define  XXX

#endif

Guess you like

Origin blog.csdn.net/qq_41835314/article/details/128835713