Hello Unity alpha users!
2020.1.0a15 is out and it brings a new shader preprocessor (experimental). You can enable it by passing a command line option “-force-new-shader-pp” to the Editor executable.
EDITED on 09.01.2020: As of 2020.1.0a18 you can enable it per project via Project Settings → Editor Settings → Caching Preprocessor checkbox.
EDITED on 03.05.2020: As of 2020.2.0a8 it’s possible to override preprocessor in the shader inspector on a per shader basis.
EDITED on 04.06.2020: As of 2020.2.0a13 Caching Preprocessor is now the default option. It is still possible to turn it off either in project settings or on a per-shader basis.
It’s going to be faster (performance improvements coming in 2020.1.0a16, shader compilation time is reduced by 5-25%), comes with new features and follows the C standard more thoroughly.
New features
Show preprocessed source
Shader inspector now has a checkbox “Preprocess only” which toggles between compiling shader variants and showing preprocessed source. The checkbox is only active for the new preprocessor.
Conditionals can now affect #pragma directives
#pragma directive parsing is now done using the new preprocessor, which means preprocessor conditionals can be used to influence, which #pragma directives are selected.
Restrictions:
#pragma directives are not searched for in include files (this would increase shader compilation time significantly).
Conditionals will affect #pragma directives if the expression depends only on:
- Any custom #define
- The following platform keywords: SHADER_API_MOBILE, SHADER_API_DESKTOP, UNITY_NO_RGBM, UNITY_USE_NATIVE_HDR, UNITY_FRAMEBUFFER_FETCH_AVAILABLE, UNITY_NO_CUBEMAP_ARRAY
- Unity version macro
The list may be expanded in the future.
Accurate include dependency tracking
The same rules that are used for conditionals affecting #pragma directives are now applied to include dependency tracking. This reduces the chance of shader reimport when some include file changes.
Support for #pragma once
directive
Instead of writing the regular include guards
#ifndef MY_ASWESOME_INCLUDE_FILE_INCLUDED
#define MY_ASWESOME_INCLUDE_FILE_INCLUDED
<actual include code here>
#endif //MY_ASWESOME_INCLUDE_FILE_INCLUDED
It’s now possible to just write
#pragma once
<actual include code here>
Support for #pragma warning directive
#pragma warning behaves the same as #pragma error, but issues a warning.
New #include_with_pragmas directive (from 2020.1.0a18)
This is a new directive introduced for the new preprocessor. It is exactly the same as the standard #include directive, but it is not ignored during shader import time, which makes it possible to put shader snippet parameters (#pragma directives) in an include file.
This directive has to be used explicitly (e.g. if you use #include_with_pragmas inside a file included using a regular #include directive, it won’t be checked).
Differences in behaviour with the previous preprocessor
- Octal number recognition is deferred to the compiler unless the number is part of a preprocessor conditional expression.
- No number truncation to 64 bits happens in the preprocessor unless the number is part of a preprocessor conditional expression.
- String with escape characters are now handled correctly.
- #line directive can use non-10-base integers as line number
- #line directive arguments will be macro-expanded if they don’t match or <Integer + String> pattern
- FILE and LINE macros can be used.
- “\\n” is not treated as a space anymore.
- “\\n” can now be used anywhere in the code, for example “#\\nd\\ne\\nf\\ni\\nn\\ne\\n A\\n 1\n” is equivalent to “#define A 1\n”
- When a macro is redefined, the new preprocessor issues a warning if the definition is different and uses the last definition.
- defined(x) can now come as a result of macro expansion
- Macros with 0 parameters are now supported. Expamle: #define A() B
- Self-referring macros are now handled correctly. Example: #define A 1 + A
- Empty macro arguments are now supported. Example: #define A(x, y)… A(,)
- Commas inside brackets (“[ ]”) and braces (“{}”) will now be treated as a delimiter between macro arguments.
- Generic preprocessing numbers are now recognized as such.
- Self-expanding macros are now handled correctly.
- In general, macro expansion now follows the C standard.
- Ill-formed #undef directives are no longer ignored when the first argument matches .
- Full stringizing support.
- Concatenation works within macros without arguments. Example: #define A x ## y
- Invalid concatenation now issues a warning.
- Macro parameters are not macro-expanded when used for concatenation or stringizing.
- Character constants are now treated as integers.
- No support for % operator in conditionals.
- Shift operators are now supported in conditionals.
- #include directive arguments are now macro-expanded if they don’t match the regular format.
- When the new preprocessor encounters a macro name without parameters no substitution happens (previously resulted in an error).
Restrictions (EDITED on 20.12.2019)
The following platforms are supported starting from Unity 2020.1.0a17:
- Xbox One
- PS4
The following shader types are supported starting from Unity 2020.1.0a17:
- Compute shaders
The following shader types are not yet supported:
- Ray tracing shaders
- Surface shaders
These will gradually become available in the upcoming alpha releases.
Thanks for reading this far
Stay tuned!