mirror of
https://github.com/YACReader/yacreader
synced 2026-03-02 19:00:04 -05:00
Fix the fragment shader to work with any background color
There now some dither to avoid banding in the gradients.
This commit is contained in:
@ -51,11 +51,19 @@ void main()
|
|||||||
|
|
||||||
// For reflections, apply a gradient fade using reflection uniforms (darker further away)
|
// For reflections, apply a gradient fade using reflection uniforms (darker further away)
|
||||||
if (vIsReflection > 0.5) {
|
if (vIsReflection > 0.5) {
|
||||||
// Legacy reflection fade: ramp from 0.0 to 0.33 using texture V coordinate
|
float gradientFade = mix(reflectionUp, reflectionDown, vTexCoord.y);
|
||||||
float gradientFade = mix(0.0, 0.33, vTexCoord.y);
|
|
||||||
shadingAmount *= gradientFade;
|
shadingAmount *= gradientFade;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Final color: shaded RGB, keep source alpha
|
// Subtle dithering to break up bands (very low amplitude, within 8-bit quantization)
|
||||||
fragColor = vec4(texColor.rgb * shadingAmount, texColor.a);
|
float rnd = fract(sin(dot(gl_FragCoord.xy, vec2(12.9898,78.233))) * 43758.5453);
|
||||||
|
// scale to roughly +/- 0.5/255 range (adjust strength if needed)
|
||||||
|
float dither = (rnd - 0.5) / 255.0;
|
||||||
|
|
||||||
|
float shadedAmountDithered = clamp(shadingAmount + dither, 0.0, 1.0);
|
||||||
|
|
||||||
|
fragColor = vec4(
|
||||||
|
mix(backgroundColor, texColor.rgb, shadedAmountDithered),
|
||||||
|
texColor.a
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
@ -37,7 +37,7 @@ void YACReaderComicFlow3D::updateImageData()
|
|||||||
|
|
||||||
// Create QRhiTexture from the loaded image
|
// Create QRhiTexture from the loaded image
|
||||||
if (m_rhi) {
|
if (m_rhi) {
|
||||||
QRhiTexture *texture = m_rhi->newTexture(QRhiTexture::BGRA8, img.size(), 1, QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips);
|
QRhiTexture *texture = m_rhi->newTexture(QRhiTexture::RGBA8, img.size(), 1, QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips);
|
||||||
|
|
||||||
if (texture->create()) {
|
if (texture->create()) {
|
||||||
PendingTextureUpload upload;
|
PendingTextureUpload upload;
|
||||||
@ -168,7 +168,7 @@ QImage ImageLoader3D::loadImage(const QString &fileName)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return image;
|
return image.convertToFormat(QImage::Format_RGBA8888);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageLoader3D::ImageLoader3D(YACReaderFlow3D *flow)
|
ImageLoader3D::ImageLoader3D(YACReaderFlow3D *flow)
|
||||||
|
|||||||
@ -37,8 +37,8 @@ YACReaderFlow3D::YACReaderFlow3D(QWidget *parent, struct Preset p)
|
|||||||
|
|
||||||
shadingTop = 0.8f;
|
shadingTop = 0.8f;
|
||||||
shadingBottom = 0.02f;
|
shadingBottom = 0.02f;
|
||||||
reflectionUp = 0.f;
|
reflectionUp = 0.0f;
|
||||||
reflectionBottom = 0.6f;
|
reflectionBottom = 0.33f;
|
||||||
|
|
||||||
setBackgroundColor(Qt::black);
|
setBackgroundColor(Qt::black);
|
||||||
|
|
||||||
@ -119,9 +119,9 @@ void YACReaderFlow3D::initialize(QRhiCommandBuffer *cb)
|
|||||||
|
|
||||||
// Initialize default texture from image
|
// Initialize default texture from image
|
||||||
if (!scene.defaultTexture) {
|
if (!scene.defaultTexture) {
|
||||||
QImage defaultImage(":/images/defaultCover.png");
|
QImage defaultImage = QImage(":/images/defaultCover.png").convertToFormat(QImage::Format_RGBA8888);
|
||||||
|
|
||||||
scene.defaultTexture.reset(m_rhi->newTexture(QRhiTexture::BGRA8, defaultImage.size(), 1, QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips));
|
scene.defaultTexture.reset(m_rhi->newTexture(QRhiTexture::RGBA8, defaultImage.size(), 1, QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips));
|
||||||
scene.defaultTexture->create();
|
scene.defaultTexture->create();
|
||||||
getResourceBatch()->uploadTexture(scene.defaultTexture.get(), defaultImage);
|
getResourceBatch()->uploadTexture(scene.defaultTexture.get(), defaultImage);
|
||||||
getResourceBatch()->generateMips(scene.defaultTexture.get());
|
getResourceBatch()->generateMips(scene.defaultTexture.get());
|
||||||
@ -131,9 +131,9 @@ void YACReaderFlow3D::initialize(QRhiCommandBuffer *cb)
|
|||||||
#ifdef YACREADER_LIBRARY
|
#ifdef YACREADER_LIBRARY
|
||||||
// Initialize mark textures
|
// Initialize mark textures
|
||||||
if (!scene.markTexture) {
|
if (!scene.markTexture) {
|
||||||
QImage markImage(":/images/readRibbon.png");
|
QImage markImage = QImage(":/images/readRibbon.png").convertToFormat(QImage::Format_RGBA8888);
|
||||||
if (!markImage.isNull()) {
|
if (!markImage.isNull()) {
|
||||||
scene.markTexture.reset(m_rhi->newTexture(QRhiTexture::BGRA8, markImage.size(), 1, QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips));
|
scene.markTexture.reset(m_rhi->newTexture(QRhiTexture::RGBA8, markImage.size(), 1, QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips));
|
||||||
scene.markTexture->create();
|
scene.markTexture->create();
|
||||||
getResourceBatch()->uploadTexture(scene.markTexture.get(), markImage);
|
getResourceBatch()->uploadTexture(scene.markTexture.get(), markImage);
|
||||||
getResourceBatch()->generateMips(scene.markTexture.get());
|
getResourceBatch()->generateMips(scene.markTexture.get());
|
||||||
@ -141,9 +141,9 @@ void YACReaderFlow3D::initialize(QRhiCommandBuffer *cb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!scene.readingTexture) {
|
if (!scene.readingTexture) {
|
||||||
QImage readingImage(":/images/readingRibbon.png");
|
QImage readingImage = QImage(":/images/readingRibbon.png").convertToFormat(QImage::Format_RGBA8888);
|
||||||
if (!readingImage.isNull()) {
|
if (!readingImage.isNull()) {
|
||||||
scene.readingTexture.reset(m_rhi->newTexture(QRhiTexture::BGRA8, readingImage.size(), 1, QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips));
|
scene.readingTexture.reset(m_rhi->newTexture(QRhiTexture::RGBA8, readingImage.size(), 1, QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips));
|
||||||
scene.readingTexture->create();
|
scene.readingTexture->create();
|
||||||
getResourceBatch()->uploadTexture(scene.readingTexture.get(), readingImage);
|
getResourceBatch()->uploadTexture(scene.readingTexture.get(), readingImage);
|
||||||
getResourceBatch()->generateMips(scene.readingTexture.get());
|
getResourceBatch()->generateMips(scene.readingTexture.get());
|
||||||
@ -605,13 +605,25 @@ void YACReaderFlow3D::prepareDrawData(const YACReader3DImageRHI &image, bool isR
|
|||||||
// Store per-instance rotation in the instance data (new slot at index 22)
|
// Store per-instance rotation in the instance data (new slot at index 22)
|
||||||
outInstanceData[22] = image.current.rot;
|
outInstanceData[22] = image.current.rot;
|
||||||
|
|
||||||
// Prepare uniform data
|
// Prepare uniform data (copy float data into POD arrays)
|
||||||
outUniformData.viewProjectionMatrix = viewProjectionMatrix;
|
const float *vp = viewProjectionMatrix.constData();
|
||||||
outUniformData.backgroundColor = QVector3D(backgroundColor.redF(), backgroundColor.greenF(), backgroundColor.blueF());
|
for (int m = 0; m < 16; ++m)
|
||||||
outUniformData.shadingColor = QVector3D(shadingColor.redF(), shadingColor.greenF(), shadingColor.blueF());
|
outUniformData.viewProjectionMatrix[m] = vp[m];
|
||||||
|
|
||||||
|
outUniformData.backgroundColor[0] = backgroundColor.redF();
|
||||||
|
outUniformData.backgroundColor[1] = backgroundColor.greenF();
|
||||||
|
outUniformData.backgroundColor[2] = backgroundColor.blueF();
|
||||||
|
outUniformData._pad0 = 0.0f;
|
||||||
|
|
||||||
|
outUniformData.shadingColor[0] = shadingColor.redF();
|
||||||
|
outUniformData.shadingColor[1] = shadingColor.greenF();
|
||||||
|
outUniformData.shadingColor[2] = shadingColor.blueF();
|
||||||
|
outUniformData._pad1 = 0.0f;
|
||||||
|
|
||||||
outUniformData.reflectionUp = reflectionUp;
|
outUniformData.reflectionUp = reflectionUp;
|
||||||
outUniformData.reflectionDown = reflectionBottom;
|
outUniformData.reflectionDown = reflectionBottom;
|
||||||
outUniformData.isReflection = isReflection ? 1 : 0;
|
outUniformData.isReflection = isReflection ? 1.0f : 0.0f;
|
||||||
|
outUniformData._pad2 = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void YACReaderFlow3D::executeDrawWithOffset(QRhiCommandBuffer *cb, QRhiTexture *texture,
|
void YACReaderFlow3D::executeDrawWithOffset(QRhiCommandBuffer *cb, QRhiTexture *texture,
|
||||||
|
|||||||
@ -112,14 +112,14 @@ protected:
|
|||||||
|
|
||||||
// Uniform buffer data structure (must match shader layout)
|
// Uniform buffer data structure (must match shader layout)
|
||||||
struct UniformData {
|
struct UniformData {
|
||||||
QMatrix4x4 viewProjectionMatrix;
|
float viewProjectionMatrix[16]; // column-major 4x4
|
||||||
QVector3D backgroundColor;
|
float backgroundColor[3];
|
||||||
float _pad0;
|
float _pad0; // pad to vec4
|
||||||
QVector3D shadingColor;
|
float shadingColor[3];
|
||||||
float _pad1;
|
float _pad1; // pad to vec4
|
||||||
float reflectionUp;
|
float reflectionUp;
|
||||||
float reflectionDown;
|
float reflectionDown;
|
||||||
int isReflection;
|
float isReflection;
|
||||||
float _pad2;
|
float _pad2;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -40,7 +40,7 @@ void YACReaderPageFlow3D::updateImageData()
|
|||||||
|
|
||||||
// Create QRhiTexture from the loaded image and queue the pixel upload
|
// Create QRhiTexture from the loaded image and queue the pixel upload
|
||||||
if (m_rhi) {
|
if (m_rhi) {
|
||||||
QRhiTexture *texture = m_rhi->newTexture(QRhiTexture::BGRA8, img.size(), 1, QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips);
|
QRhiTexture *texture = m_rhi->newTexture(QRhiTexture::RGBA8, img.size(), 1, QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips);
|
||||||
|
|
||||||
if (texture->create()) {
|
if (texture->create()) {
|
||||||
// Queue the image upload so it happens together with other resource updates
|
// Queue the image upload so it happens together with other resource updates
|
||||||
@ -136,7 +136,7 @@ QImage ImageLoaderByteArray3D::loadImage(const QByteArray &raw)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return image;
|
return image.convertToFormat(QImage::Format_RGBA8888);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageLoaderByteArray3D::ImageLoaderByteArray3D(YACReaderFlow3D *flow)
|
ImageLoaderByteArray3D::ImageLoaderByteArray3D(YACReaderFlow3D *flow)
|
||||||
|
|||||||
Reference in New Issue
Block a user