-
Notifications
You must be signed in to change notification settings - Fork 134
Enabling shader keywords
Working with shader files often requires using #if
preprocessor directives to generate different shader variants. These branches can be used to introduce conditional behaviour for different platforms, such as mobile or desktop, different graphics APIs such as Vulkan or DirectX, or even different user features, enabled at runtime with shader keywords.
Rider will parse your shader source code, while you type. It builds a semantic model and can use this to provide rich functionality such as syntax highlighting, ctrl+click navigation, finding usages and smart rename and other refactorings. However, it is not feasible for Rider to build a semantic model of the content of all preprocessor directives simultaneously; an inactive branch might contain alternative conflicting declarations of existing fields or functions, or broken code, or could even contain unexpected syntax to close one function and declare another one (e.g. by including a close brace and a new function declaration). So Rider will only analyse the preprocessor branches based on the currently defined symbols while editing. This leads to "inactive", grey-out preprocessor branches, with no syntax highlighting or inspections.
Rider 2023.3 introduces a way to choose which shader keywords are enabled, and which Unity shader preprocessor symbols are defined.
Clicking the "Variants" widget in the breadcrumb bar at the bottom of the editor will show a popup that tells Rider to treat different symbols as defined while editing. For example, it's possible to select the graphics API - selecting "DirectX 11" will tell Rider to consider the SHADER_API_D3D11
symbol to be defined, and anything inside #if SHADER_API_D3D11
would be parsed as active code, with syntax highlighting and inspections and so on. Switching to "Vulkan" would mean that SHADER_API_D3D11
is no longer active, and the preprocessor branch would be considered inactive, but anything inside #if SHADER_API_VULKAN
would be active instead.
Similarly, Rider can switch between desktop and mobile to activate the SHADER_API_DESKTOP
or SHADER_API_MOBILE
symbols.
Note that Rider will provide completion for known SHADER_
symbols.
Rider also allows enabling shader keywords. The following #pragma
directive will declare the BLUE
, RED
and GREEN
shader keywords. These keywords can be enabled at runtime with the Shader.EnableKeyword
API, amongst others (see the docs for shader keywords for more details).
#pragma shader_feature _ BLUE RED GREEN
These keywords are also preprocessor define symbols, and Rider can enable these through the shader variants widget, and will then process the appropriate preprocessor branch. When a keyword is enabled, it is highlighted as bold and underlined.
The keyword in the #pragma
is also highlighted. It's also possible to enable and disable keywords through the alt+enter context menu, either in the #pragma
or wherever the symbol is used.
One thing to note: Unity allows multiple keywords to be enabled, but only the first in a pragma directive is considered to be active. All other keywords are suppressed, and will not be active. Rider marks suppressed keywords with a strikethrough, and the symbol is not defined. Rider does not automatically disable other keywords in the pragma because it is possible to enable multiple conflicting keywords in code, and it is also possible to define the same keyword in multiple pragmas. The alt+enter menu can be used on a suppressed keyword to disable the keyword(s) that cause it to be suppressed.
The shader variants widget is a great way of providing context to Rider's code analysis, so you can choose which shader variant you're editing, and make use of Rider's analysis and other rich functionality.