跳到正文

着色器方言

一个需主动开启的开关,只针对一种特定情况:在 Linux 主机上运行 Windows 身份画像(persona)。如果不做处理,此时转译后的着色器源码与 renderer 字符串会指向两个不同的图形后端。

不一致之处

WEBGL_debug_shaders.getTranslatedShaderSource() 返回的是 ANGLE 当前启用的后端生成的内容。Windows 身份画像声明的是 Direct3D11 renderer,但在 Linux 主机上,应答的是 Vulkan 后端,返回的是一段 SPIR-V 转储。这两个值就摆在一起,要读出其中的矛盾,既不需要参考数据,也不需要群体基线——页面只需把两者比较一下:

javascript
const gl = document.createElement("canvas").getContext("webgl");
const info = gl.getExtension("WEBGL_debug_renderer_info");
gl.getParameter(info.UNMASKED_RENDERER_WEBGL);
// "ANGLE (Intel, Intel(R) UHD Graphics 770 (0x0000A780) Direct3D11 vs_5_0 ps_5_0, D3D11)"

const dbg = gl.getExtension("WEBGL_debug_shaders");
dbg.getTranslatedShaderSource(vertexShader);
// on Windows: "// INITIAL HLSL BEGIN ... #pragma warning( disable: 3081 ..."
// on Linux:   "Outputs: gl_Position ... Paste the following SPIR-V binary ..."   <- contradicts the renderer

这只在身份画像的操作系统与主机不同时才会出现。操作系统与主机一致的身份画像本身就是自洽的,这里无需任何处理。该选项只覆盖“非 Windows 主机上的 Windows 身份画像”;反过来——Windows 主机上的 Linux 或 macOS 身份画像——不在覆盖范围内,这种情况下请让身份画像与主机保持一致。

开启方法

启动时传入 shader_dialect(shaderDialect / ShaderDialect)。引擎仅针对这一查询把着色器重新转译为 HLSL;结果与 Windows 版构建报告的内容逐字节相同。

python
from clearcote import launch_persistent_context

ctx = launch_persistent_context("./profile", platform="windows", shader_dialect="hlsl")
javascript
import { launchPersistentContext } from "clearcote";

const ctx = await launchPersistentContext("./profile", { platform: "windows", shaderDialect: "hlsl" });
csharp
using Clearcote;

var ctx = await Clearcote.Clearcote.LaunchPersistentContextAsync("./profile", new LaunchOptions
{
    Platform = "windows",
    ShaderDialect = "hlsl",
});

当容器运行的是授权版构建(已设置 CLEARCOTE_LICENSE_KEY)时,官方 Docker 镜像会针对 CC_PLATFORM=windows 自动开启它;可用 CC_SHADER_DIALECT=hlsl 或 =0 覆盖。使用其他运行方式时,请在浏览器的运行环境中设置该环境变量——SDK 选项在底层设置的正是它:

bash
CLEARCOTE_SHADER_DIALECT=hlsl

之所以用环境变量而不是命令行参数,是因为这段代码运行在 GPU 进程中,而 GPU 进程收不到指纹开关。

为什么默认关闭

重新转译走的是一条与实际渲染不同的代码路径。如果某个着色器能被真实后端接受,却被 HLSL 转译器拒绝,该着色器就会回退到真实的方言——仅对它重新引入不一致。除此之外,该选项在其他各方面都刻意保持保守:

  • 渲染不受影响。着色器仍由真实后端编译和绘制;只有调试扩展的查询结果会改变。一次带像素回读的 WebGL 绘制,无论该选项开启与否,哈希都完全相同。
  • 在 Windows 上不起作用。如果当前后端本来就输出 HLSL,该选项什么也不做,因此即使设置了该变量,Windows 主机也不受任何影响。
  • 失败时以真实为准。任何转译失败都会返回后端的真实输出,而不是空结果或编造的结果。
  • SDK 只接受 "hlsl",其他值一律拒绝——拼写错误却悄无声息地不起作用,比直接报错更糟。如果你自己设置该变量,其值必须恰好是 hlsl(小写);引擎会忽略其他任何值。

运行要求

需要授权版构建(GitHub 免费版或 Pro),151 r15 或更高版本。开源版构建和更早的二进制会忽略该变量,继续报告其真实方言,因此请传入你的许可证密钥(license_key / CLEARCOTE_LICENSE_KEY),上面的示例才会生效。为什么与所声称的平台保持一致,比返回一个中性的第三种值更好,见检测原理;如何在容器中运行授权版引擎,见部署。