You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Slang着色器编译为SPIR-V后矩阵访问异常(每4个浮点数跳过3个)的问题咨询

Slang着色器编译为SPIR-V后矩阵访问异常(每4个浮点数跳过3个)的问题咨询

我正在尝试为Vulkan框架学习Slang着色器语言,写了一个最基础的全白着色器,但编译出的SPIR-V在N卡Nsight中反编译后显示矩阵访问逻辑异常——每读取4个浮点数就会跳过3个,导致矩阵数据完全错乱,最终渲染结果不对。而对应的GLSL版本编译后却能正常工作,以下是详细信息:

我的Slang着色器代码

module white;

struct VertexIn {
    float3 position : Position;
};

struct Camera {
    float4x4 view;
    float4x4 projection;
    float4x4 inverseView;
    float4x4 inverseProjection;
};

struct PushConstants {
    float32_t4x4 model;
};

[[vk::binding(0)]] ConstantBuffer<Camera> camera;

[[shader("vertex")]]
float4 vertex(VertexIn in, uniform PushConstants pushConstants) : SV_Position {
    float4x4 mvp = camera.projection * camera.view * pushConstants.model;
    return mul(mvp, float4(in.position, 1.0f));
}

[[shader("fragment")]]
float4 fragment() : SV_Target {
    return float4(1.0, 1.0, 1.0, 1.0);
}

预期等效的GLSL代码(可正常工作)

顶点Shader

#version 460 core
// 忽略#pragma Position,只是自动关联属性位置的工具
#pragma Position
layout(location = 0) in vec3 inPosition;

layout(set = 0, binding = 0) uniform Camera {
    mat4 view;
    mat4 projection;
    mat4 inverseView;
    mat4 inverseProjection;
} camera;

layout(push_constant) uniform PushConstants {
    mat4 model;
} push;

void main() {
    gl_Position = camera.projection * camera.view * push.model * vec4(inPosition, 1.0);
}

片段Shader

#version 460 core
layout(location = 0) out vec4 FragColor;

void main() {
    FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}

问题现象

GLSL版本编译出的SPIR-V完全符合预期,能正常渲染全白物体,但Slang版本的顶点Shader编译出的SPIR-V被Nsight反编译后,出现了奇怪的矩阵构造和乘法逻辑:

#version 450

struct _MatrixStorage_float4x4_ColMajorstd140 {
    vec4 data[4];
};
struct _MatrixStorage_float4x4_ColMajorstd430 {
    vec4 data[4];
};
struct PushConstants_std430 {
    _MatrixStorage_float4x4_ColMajorstd430 model;
};

layout(set = 0, binding = 0, std140) uniform Camera_std140 {
    _MatrixStorage_float4x4_ColMajorstd140 view;
    _MatrixStorage_float4x4_ColMajorstd140 projection;
    _MatrixStorage_float4x4_ColMajorstd140 inverseView;
    _MatrixStorage_float4x4_ColMajorstd140 inverseProjection;
} camera;

layout(push_constant, std430) uniform EntryPointParams_std430 {
    PushConstants_std430 pushConstants;
} entryPointParams;

layout(location = 0) in vec3 in_position;

void main() {
    mat4 _170 = mat4(
        vec4(camera.projection.data[0].x, camera.projection.data[1].x, camera.projection.data[2].x, camera.projection.data[3].x),
        vec4(camera.projection.data[0].y, camera.projection.data[1].y, camera.projection.data[2].y, camera.projection.data[3].y),
        vec4(camera.projection.data[0].z, camera.projection.data[1].z, camera.projection.data[2].z, camera.projection.data[3].z),
        vec4(camera.projection.data[0].w, camera.projection.data[1].w, camera.projection.data[2].w, camera.projection.data[3].w));
    mat4 _198 = mat4(
        vec4(camera.view.data[0].x, camera.view.data[1].x, camera.view.data[2].x, camera.view.data[3].x),
        vec4(camera.view.data[0].y, camera.view.data[1].y, camera.view.data[2].y, camera.view.data[3].y),
        vec4(camera.view.data[0].z, camera.view.data[1].z, camera.view.data[2].z, camera.view.data[3].z),
        vec4(camera.view.data[0].w, camera.view.data[1].w, camera.view.data[2].w, camera.view.data[3].w));
    mat4 _232 = mat4(
        vec4(entryPointParams.pushConstants.model.data[0].x, entryPointParams.pushConstants.model.data[1].x, entryPointParams.pushConstants.model.data[2].x, entryPointParams.pushConstants.model.data[3].x),
        vec4(entryPointParams.pushConstants.model.data[0].y, entryPointParams.pushConstants.model.data[1].y, entryPointParams.pushConstants.model.data[2].y, entryPointParams.pushConstants.model.data[3].y),
        vec4(entryPointParams.pushConstants.model.data[0].z, entryPointParams.pushConstants.model.data[1].z, entryPointParams.pushConstants.model.data[2].z, entryPointParams.pushConstants.model.data[3].z),
        vec4(entryPointParams.pushConstants.model.data[0].w, entryPointParams.pushConstants.model.data[1].w, entryPointParams.pushConstants.model.data[2].w, entryPointParams.pushConstants.model.data[3].w));
    gl_Position = vec4(in_position, 1.0) * mat4((_170[0] * _198[0]) * _232[0], (_170[1] * _198[1]) * _232[1], (_170[2] * _198[2]) * _232[2], (_170[3] * _198[3]) * _232[3]);
}

观察到的核心问题是:矩阵的内存访问完全错乱,比如原本的矩阵

[[1, 2, 3, 4],
 [5, 6, 7, 8],
 [9, 10, 11, 12],
 [13, 14, 15, 16]]

被错误地读取为:

[[1, 2, 3, 4],
 [8, 9, 10, 11],
 [15, 16, 0, 0],
 [0, 0, 0, 0]]

我使用的Slang编译代码

std::vector<uint32_t> Coral::Core::SlangShader::CompileSlangToSpirV(const std::string& moduleName, const std::string& entryPointName) {
    using namespace slang;
    Slang::ComPtr<IGlobalSession> globalSession;
    SlangGlobalSessionDesc desc = {};
    createGlobalSession(&desc, globalSession.writeRef());

    TargetDesc targetDesc;
    targetDesc.format = SLANG_SPIRV;
    targetDesc.profile = globalSession->findProfile("vulkan");

    const char* searchPaths[] = {"shaders/slang"};
    PreprocessorMacroDesc fancyFlag = {"ENABLE_FANCY_FEATU

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 06:53:00