mirror of
https://github.com/YACReader/yacreader
synced 2026-03-02 10:50: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)
|
||||
if (vIsReflection > 0.5) {
|
||||
// Legacy reflection fade: ramp from 0.0 to 0.33 using texture V coordinate
|
||||
float gradientFade = mix(0.0, 0.33, vTexCoord.y);
|
||||
float gradientFade = mix(reflectionUp, reflectionDown, vTexCoord.y);
|
||||
shadingAmount *= gradientFade;
|
||||
}
|
||||
|
||||
// Final color: shaded RGB, keep source alpha
|
||||
fragColor = vec4(texColor.rgb * shadingAmount, texColor.a);
|
||||
// Subtle dithering to break up bands (very low amplitude, within 8-bit quantization)
|
||||
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
|
||||
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()) {
|
||||
PendingTextureUpload upload;
|
||||
@ -168,7 +168,7 @@ QImage ImageLoader3D::loadImage(const QString &fileName)
|
||||
break;
|
||||
}
|
||||
|
||||
return image;
|
||||
return image.convertToFormat(QImage::Format_RGBA8888);
|
||||
}
|
||||
|
||||
ImageLoader3D::ImageLoader3D(YACReaderFlow3D *flow)
|
||||
|
||||
@ -37,8 +37,8 @@ YACReaderFlow3D::YACReaderFlow3D(QWidget *parent, struct Preset p)
|
||||
|
||||
shadingTop = 0.8f;
|
||||
shadingBottom = 0.02f;
|
||||
reflectionUp = 0.f;
|
||||
reflectionBottom = 0.6f;
|
||||
reflectionUp = 0.0f;
|
||||
reflectionBottom = 0.33f;
|
||||
|
||||
setBackgroundColor(Qt::black);
|
||||
|
||||
@ -119,9 +119,9 @@ void YACReaderFlow3D::initialize(QRhiCommandBuffer *cb)
|
||||
|
||||
// Initialize default texture from image
|
||||
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();
|
||||
getResourceBatch()->uploadTexture(scene.defaultTexture.get(), defaultImage);
|
||||
getResourceBatch()->generateMips(scene.defaultTexture.get());
|
||||
@ -131,9 +131,9 @@ void YACReaderFlow3D::initialize(QRhiCommandBuffer *cb)
|
||||
#ifdef YACREADER_LIBRARY
|
||||
// Initialize mark textures
|
||||
if (!scene.markTexture) {
|
||||
QImage markImage(":/images/readRibbon.png");
|
||||
QImage markImage = QImage(":/images/readRibbon.png").convertToFormat(QImage::Format_RGBA8888);
|
||||
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();
|
||||
getResourceBatch()->uploadTexture(scene.markTexture.get(), markImage);
|
||||
getResourceBatch()->generateMips(scene.markTexture.get());
|
||||
@ -141,9 +141,9 @@ void YACReaderFlow3D::initialize(QRhiCommandBuffer *cb)
|
||||
}
|
||||
|
||||
if (!scene.readingTexture) {
|
||||
QImage readingImage(":/images/readingRibbon.png");
|
||||
QImage readingImage = QImage(":/images/readingRibbon.png").convertToFormat(QImage::Format_RGBA8888);
|
||||
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();
|
||||
getResourceBatch()->uploadTexture(scene.readingTexture.get(), readingImage);
|
||||
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)
|
||||
outInstanceData[22] = image.current.rot;
|
||||
|
||||
// Prepare uniform data
|
||||
outUniformData.viewProjectionMatrix = viewProjectionMatrix;
|
||||
outUniformData.backgroundColor = QVector3D(backgroundColor.redF(), backgroundColor.greenF(), backgroundColor.blueF());
|
||||
outUniformData.shadingColor = QVector3D(shadingColor.redF(), shadingColor.greenF(), shadingColor.blueF());
|
||||
// Prepare uniform data (copy float data into POD arrays)
|
||||
const float *vp = viewProjectionMatrix.constData();
|
||||
for (int m = 0; m < 16; ++m)
|
||||
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.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,
|
||||
|
||||
@ -112,14 +112,14 @@ protected:
|
||||
|
||||
// Uniform buffer data structure (must match shader layout)
|
||||
struct UniformData {
|
||||
QMatrix4x4 viewProjectionMatrix;
|
||||
QVector3D backgroundColor;
|
||||
float _pad0;
|
||||
QVector3D shadingColor;
|
||||
float _pad1;
|
||||
float viewProjectionMatrix[16]; // column-major 4x4
|
||||
float backgroundColor[3];
|
||||
float _pad0; // pad to vec4
|
||||
float shadingColor[3];
|
||||
float _pad1; // pad to vec4
|
||||
float reflectionUp;
|
||||
float reflectionDown;
|
||||
int isReflection;
|
||||
float isReflection;
|
||||
float _pad2;
|
||||
};
|
||||
|
||||
|
||||
@ -40,7 +40,7 @@ void YACReaderPageFlow3D::updateImageData()
|
||||
|
||||
// Create QRhiTexture from the loaded image and queue the pixel upload
|
||||
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()) {
|
||||
// Queue the image upload so it happens together with other resource updates
|
||||
@ -136,7 +136,7 @@ QImage ImageLoaderByteArray3D::loadImage(const QByteArray &raw)
|
||||
break;
|
||||
}
|
||||
|
||||
return image;
|
||||
return image.convertToFormat(QImage::Format_RGBA8888);
|
||||
}
|
||||
|
||||
ImageLoaderByteArray3D::ImageLoaderByteArray3D(YACReaderFlow3D *flow)
|
||||
|
||||
Reference in New Issue
Block a user