Use the fragment shader to calculate the shading effect for a more uniform shading than the one based on vertex

This commit is contained in:
luisangelsm
2026-01-18 18:23:04 +01:00
parent 7384d50721
commit 41b02725d7
7 changed files with 58 additions and 32 deletions

View File

@ -194,9 +194,9 @@ void YACReaderFlow3D::initialize(QRhiCommandBuffer *cb)
// Create instance buffer for per-draw instance data
if (!scene.instanceBuffer) {
// Allocate buffer for per-instance data (model matrix + shading + opacity + flipFlag)
// mat4 (16 floats) + vec4 (4 floats) + float (1 float) + float (1 float) = 22 floats
scene.instanceBuffer.reset(m_rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::VertexBuffer, 22 * sizeof(float)));
// Allocate buffer for per-instance data (model matrix + shading + opacity + flipFlag + rotation)
// mat4 (16 floats) + vec4 (4 floats) + float (opacity) + float (flipFlag) + float (rotation) = 23 floats
scene.instanceBuffer.reset(m_rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::VertexBuffer, 23 * sizeof(float)));
scene.instanceBuffer->create();
}
@ -333,7 +333,7 @@ void YACReaderFlow3D::ensurePipeline()
QRhiVertexInputLayout inputLayout;
inputLayout.setBindings({
{ 5 * sizeof(float) }, // Per-vertex data (position + texCoord)
{ 22 * sizeof(float), QRhiVertexInputBinding::PerInstance } // Per-instance data
{ 23 * sizeof(float), QRhiVertexInputBinding::PerInstance } // Per-instance data
});
inputLayout.setAttributes({
// Per-vertex attributes
@ -347,7 +347,8 @@ void YACReaderFlow3D::ensurePipeline()
{ 1, 5, QRhiVertexInputAttribute::Float4, 12 * sizeof(float) }, // row 3
{ 1, 6, QRhiVertexInputAttribute::Float4, 16 * sizeof(float) }, // shading vec4
{ 1, 7, QRhiVertexInputAttribute::Float, 20 * sizeof(float) }, // opacity
{ 1, 8, QRhiVertexInputAttribute::Float, 21 * sizeof(float) } // flipFlag (1.0 = reflection)
{ 1, 8, QRhiVertexInputAttribute::Float, 21 * sizeof(float) }, // flipFlag (1.0 = reflection)
{ 1, 9, QRhiVertexInputAttribute::Float, 22 * sizeof(float) } // rotation
});
scene.pipeline->setVertexInputLayout(inputLayout);
@ -408,7 +409,7 @@ void YACReaderFlow3D::render(QRhiCommandBuffer *cb)
bool isReflection;
bool isMark;
QRhiTexture *texture;
float instanceData[22];
float instanceData[23];
UniformData uniformData;
};
@ -482,7 +483,7 @@ void YACReaderFlow3D::render(QRhiCommandBuffer *cb)
}
// Ensure instance buffer is large enough for all draws
auto requiredInstanceSize = static_cast<quint32>(draws.size() * 22 * sizeof(float));
auto requiredInstanceSize = static_cast<quint32>(draws.size() * 23 * sizeof(float));
if (!scene.instanceBuffer || scene.instanceBuffer->size() < requiredInstanceSize) {
scene.instanceBuffer.reset(m_rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::VertexBuffer, requiredInstanceSize));
if (!scene.instanceBuffer->create()) {
@ -514,8 +515,8 @@ void YACReaderFlow3D::render(QRhiCommandBuffer *cb)
// Update instance buffer with all instance data
for (int i = 0; i < draws.size(); ++i) {
int offset = i * 22 * sizeof(float);
batch->updateDynamicBuffer(scene.instanceBuffer.get(), offset, 22 * sizeof(float), draws[i].instanceData);
int offset = i * 23 * sizeof(float);
batch->updateDynamicBuffer(scene.instanceBuffer.get(), offset, 23 * sizeof(float), draws[i].instanceData);
}
// === PHASE 2: RENDER (DURING PASS) ===
@ -601,6 +602,9 @@ void YACReaderFlow3D::prepareDrawData(const YACReader3DImageRHI &image, bool isR
outInstanceData[i] = matData[i];
}
// Store per-instance rotation in the instance data (new slot at index 22)
outInstanceData[22] = image.current.rot;
// Prepare uniform data
outUniformData.viewProjectionMatrix = viewProjectionMatrix;
outUniformData.backgroundColor = QVector3D(backgroundColor.redF(), backgroundColor.greenF(), backgroundColor.blueF());
@ -637,7 +641,7 @@ void YACReaderFlow3D::executeDrawWithOffset(QRhiCommandBuffer *cb, QRhiTexture *
// Bind vertex buffers with offset into instance buffer
const QRhiCommandBuffer::VertexInput vbufBindings[] = {
{ scene.vertexBuffer.get(), 0 },
{ scene.instanceBuffer.get(), quint32(uniformSlot * 22 * sizeof(float)) }
{ scene.instanceBuffer.get(), quint32(uniformSlot * 23 * sizeof(float)) }
};
cb->setVertexInput(0, 2, vbufBindings);