UnityTips HLSL 的 #pragma 指令
2024-02-18 本文已影响0人
暴走TA
简介: 今天记录几个 pragma 的编译小用法
unity版本: 2022.3.14
管线:URP
相关官方文档: 官网文档链接
#pragma 是什么
当我们在 Unity 中写 Shader 时,大家对 #pragma 必然不陌生。#pragma 是一个预处理指令,一般用来为 shader 编译器提供额外的编译信息,例如:
-
指定 frag 函数
-
指定 vert 函数
-
API 剔除
-
变体编译指令等等
-
目标版本
#pragma target 3.0 #pragma exclude_renderers vulkan #pragma vertex vert #pragma fragment frag
#pragma 可以写在任何地方,我们一般为了便于管理,一般写在着色器的头部
#pragma 除了支持 HLSL 标准的定义外,unity 还做了专属的pragma扩展
小特性
可以写在 #if #endif 宏定义包裹内
判断条件必须满足以下标准
- 自定义的 #define 内容
- 属于平台关键字:SHADER_API_MOBILE, SHADER_API_DESKTOP, UNITY_NO_RGBM, UNITY_USE_NATIVE_HDR, UNITY_FRAMEBUFFER_FETCH_AVAILABLE, UNITY_NO_CUBEMAP_ARRAY
- UNITY_VERSION 版本宏
unity 专属的 pragma
必须写在 .shader 文件内,如果专属的 pragma 写在了 include 文件内,则需要使用 #include_with_pragmas 进行引用,否则编译器将忽略 include 文件内的 pragma 指令
Surface 着色器相关专属宏定义
#pragma surface <surface function> <lighting model> <optional parameters>
Shader stages
- #pragma vertex <name> 顶点着色器
- #pragma fragment <name> 片元着色器
- #pragma geometry <name> 几何着色器
- #pragma hull <name> 外壳着色器
- #pragma domain <name> 域细分着色器
Shader 变体和关键字
- #pragma multi_compile <keywords> 编译所有组合
- #pragma shader_feature <keywords> 编译用到的组合
- #pragma hardware_tier_variants <values> 只在内置管线生效,根据硬件设置编译
- #pragma skip_variants <list of keywords> 剔除指定关键字的相关组合
GPU requirement 和 shader model
- #pragma target <value> 标明着色器的目标模型版本,运行环境低于此版本则着色器不生效并使用回滚机制找到另一个合适的着色器
- #pragma require <value> 标明着色器需要的 GPU 特性,运行环境不满足则当前
图形库API
- #pragma only_renderers <value> 只在指定的图形库渲染
- #pragma exclude_renderers <value> 不在指定的图形库渲染
其它 pragma 指令
- #pragma instancing_options <options> instancing 选项
- #pragma once
- #pragma enable_d3d11_debug_symbols 生成测试变体,并禁用编译优化操作,这个操作会降低着色器性能, 增加着色器文件大小,这个功能目前支持 Vulkan DX11 DX12 和一些支持的 console 平台
- #pragma skip_optimizations <value> 禁用指定渲染 API 的编译优化
- #pragma hlslcc_bytecode_disassembly
- #pragma disable_fastmath 启用高精度数学计算处理Nan,相关问题,目前仅支持 metal 平台
- #pragma editor_sync_compilation 强制同步编译,仅在 Editor 下生效
- #pragma enable_cbuffer 开启cbuffer宏,即使当前的平台不支持 常亮 buffer
标准 HLSL 的 pragma
指令只可以写在 include 文件内,如果写在了 .shader 文件内则 或则使用 #include_with_pragmas 进行了引用,则编译器会忽略这些标准的编译指令
标准的 pragma 有以下几个