Код: Выделить всё
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;
[[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);
}
< /code>
Предполагается, что он очень похож на эти два шейдера GLSL: < /p>
#version 460 core
#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);
}
< /code>
#version 460 core
layout(location = 0) out vec4 FragColor;
void main() {
FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}
< /code>
Игнорировать позицию #pragma < /code>. Это просто способ автоматического расположения ссылок и атрибутов.#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]);
}
< /code>
После просмотра буферов из NSight я увидел, что в матрицах каждые 4 поплавка 3 пропускаются. Например: < /p>
[[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16]]
< /code>
читается как: < /p>
[[1, 2, 3, 4],
[8, 9, 10, 11],
[15, 16, 0, 0],
[0, 0, 0, 0]]
< /code>
Я использую API Slangc для компиляции шейдеров. Это функция, которую я использую для компиляции шейдеров: < /p>
std::vector Coral::Core::SlangShader::CompileSlangToSpirV(const std::string& moduleName,
const std::string& entryPointName) {
using namespace slang;
Slang::ComPtr 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_FEATURE", "1"};
CompilerOptionEntry entry0;
entry0.name = CompilerOptionName::GLSLForceScalarLayout;
CompilerOptionEntry entry1;
entry1.name = CompilerOptionName::Capability;
entry1.value.kind = CompilerOptionValueKind::String;
entry1.value.stringValue0 = "vk_mem_model";
CompilerOptionEntry entries[] = { entry0, entry1 };
targetDesc.compilerOptionEntries = entries;
targetDesc.compilerOptionEntryCount = 2;
SessionDesc sessionDesc;
sessionDesc.targets = &targetDesc;
sessionDesc.targetCount = 1;
sessionDesc.searchPaths = searchPaths;
sessionDesc.searchPathCount = 1;
sessionDesc.preprocessorMacros = &fancyFlag;
sessionDesc.preprocessorMacroCount = 1;
sessionDesc.defaultMatrixLayoutMode = SLANG_MATRIX_LAYOUT_COLUMN_MAJOR;
Slang::ComPtr session;
globalSession->createSession(sessionDesc, session.writeRef());
Slang::ComPtr diagnostics;
const auto module = Slang::ComPtr(session->loadModule(moduleName.c_str(), diagnostics.writeRef()));
if (diagnostics) {
std::cerr getBufferPointer()));
// std::println(std::cerr, "Program layout: {}", m_analysis.dump(4));
}
else {
std::cerr getBufferSize() / sizeof(uint32_t)};
}
Подробнее здесь: https://stackoverflow.com/questions/797 ... y-4-floats