libkwineffects/kwinglutils: fix saturation calculation with wide color gamut and document it
This commit is contained in:
parent
84ce4751d9
commit
6272d1d9f3
4 changed files with 29 additions and 5 deletions
|
@ -430,6 +430,8 @@ void GLShader::resolveLocations()
|
|||
|
||||
mVec2Location[Offset] = uniformLocation("offset");
|
||||
|
||||
m_vec3Locations[Vec3Uniform::PrimaryBrightness] = uniformLocation("primaryBrightness");
|
||||
|
||||
mVec4Location[ModulationConstant] = uniformLocation("modulation");
|
||||
|
||||
mFloatLocation[Saturation] = uniformLocation("saturation");
|
||||
|
@ -470,6 +472,12 @@ bool GLShader::setUniform(GLShader::Vec2Uniform uniform, const QVector2D &value)
|
|||
return setUniform(mVec2Location[uniform], value);
|
||||
}
|
||||
|
||||
bool GLShader::setUniform(Vec3Uniform uniform, const QVector3D &value)
|
||||
{
|
||||
resolveLocations();
|
||||
return setUniform(m_vec3Locations[uniform], value);
|
||||
}
|
||||
|
||||
bool GLShader::setUniform(GLShader::Vec4Uniform uniform, const QVector4D &value)
|
||||
{
|
||||
resolveLocations();
|
||||
|
@ -783,6 +791,7 @@ QByteArray ShaderManager::generateFragmentSource(ShaderTraits traits) const
|
|||
}
|
||||
if (traits & ShaderTrait::AdjustSaturation) {
|
||||
stream << "uniform float saturation;\n";
|
||||
stream << "uniform vec3 primaryBrightness;\n";
|
||||
}
|
||||
|
||||
stream << "\n"
|
||||
|
@ -841,9 +850,6 @@ QByteArray ShaderManager::generateFragmentSource(ShaderTraits traits) const
|
|||
} else if (traits & ShaderTrait::UniformColor) {
|
||||
stream << " result = geometryColor;\n";
|
||||
}
|
||||
if (traits & ShaderTrait::AdjustSaturation) {
|
||||
stream << " result.rgb = mix(vec3(dot(result.rgb, vec3(0.2126, 0.7152, 0.0722))), result.rgb, saturation);\n";
|
||||
}
|
||||
if (traits & ShaderTrait::TransformColorspace) {
|
||||
// sRGB -> output colorspace & linear
|
||||
stream << " if (sourceNamedTransferFunction == 0) {\n";
|
||||
|
@ -851,6 +857,12 @@ QByteArray ShaderManager::generateFragmentSource(ShaderTraits traits) const
|
|||
stream << " }\n";
|
||||
stream << " result.rgb = doTonemapping(colorimetryTransform * result.rgb, maxHdrBrightness);\n";
|
||||
}
|
||||
if (traits & ShaderTrait::AdjustSaturation) {
|
||||
// this calculates the Y component of the XYZ color representation for the color,
|
||||
// which roughly corresponds to the brightness of the RGB tuple
|
||||
stream << " float Y = dot(result.rgb, primaryBrightness);\n";
|
||||
stream << " result.rgb = mix(vec3(Y), result.rgb, saturation);\n";
|
||||
}
|
||||
if (traits & ShaderTrait::Modulate) {
|
||||
stream << " result *= modulation;\n";
|
||||
}
|
||||
|
|
|
@ -121,6 +121,10 @@ public:
|
|||
Vec2UniformCount
|
||||
};
|
||||
|
||||
enum class Vec3Uniform {
|
||||
PrimaryBrightness = 0
|
||||
};
|
||||
|
||||
enum Vec4Uniform {
|
||||
ModulationConstant,
|
||||
Vec4UniformCount
|
||||
|
@ -150,6 +154,7 @@ public:
|
|||
bool setUniform(MatrixUniform uniform, const QMatrix3x3 &value);
|
||||
bool setUniform(MatrixUniform uniform, const QMatrix4x4 &matrix);
|
||||
bool setUniform(Vec2Uniform uniform, const QVector2D &value);
|
||||
bool setUniform(Vec3Uniform uniform, const QVector3D &value);
|
||||
bool setUniform(Vec4Uniform uniform, const QVector4D &value);
|
||||
bool setUniform(FloatUniform uniform, float value);
|
||||
bool setUniform(IntUniform uniform, int value);
|
||||
|
@ -177,6 +182,7 @@ private:
|
|||
bool mExplicitLinking : 1;
|
||||
int mMatrixLocation[MatrixCount];
|
||||
int mVec2Location[Vec2UniformCount];
|
||||
QHash<Vec3Uniform, int> m_vec3Locations;
|
||||
int mVec4Location[Vec4UniformCount];
|
||||
int mFloatLocation[FloatUniformCount];
|
||||
int mIntLocation[IntUniformCount];
|
||||
|
|
|
@ -155,7 +155,6 @@ void OffscreenData::paint(const RenderTarget &renderTarget, const RenderViewport
|
|||
{
|
||||
GLShader *shader = m_shader ? m_shader : ShaderManager::instance()->shader(ShaderTrait::MapTexture | ShaderTrait::Modulate | ShaderTrait::AdjustSaturation | ShaderTrait::TransformColorspace);
|
||||
ShaderBinder binder(shader);
|
||||
shader->setColorspaceUniformsFromSRGB(renderTarget.colorDescription());
|
||||
|
||||
const double scale = viewport.scale();
|
||||
|
||||
|
@ -185,11 +184,14 @@ void OffscreenData::paint(const RenderTarget &renderTarget, const RenderViewport
|
|||
QMatrix4x4 mvp = data.projectionMatrix();
|
||||
mvp.translate(window->x() * scale, window->y() * scale);
|
||||
|
||||
const auto toXYZ = renderTarget.colorDescription().colorimetry().toXYZ();
|
||||
shader->setUniform(GLShader::ModelViewProjectionMatrix, mvp * data.toMatrix(scale));
|
||||
shader->setUniform(GLShader::ModulationConstant, QVector4D(rgb, rgb, rgb, a));
|
||||
shader->setUniform(GLShader::Saturation, data.saturation());
|
||||
shader->setUniform(GLShader::Vec3Uniform::PrimaryBrightness, QVector3D(toXYZ(1, 0), toXYZ(1, 1), toXYZ(1, 2)));
|
||||
shader->setUniform(GLShader::TextureWidth, m_texture->width());
|
||||
shader->setUniform(GLShader::TextureHeight, m_texture->height());
|
||||
shader->setColorspaceUniformsFromSRGB(renderTarget.colorDescription());
|
||||
|
||||
const bool clipping = region != infiniteRegion();
|
||||
const QRegion clipRegion = clipping ? viewport.mapToRenderTarget(region) : infiniteRegion();
|
||||
|
|
|
@ -322,7 +322,11 @@ void ItemRendererOpenGL::renderItem(const RenderTarget &renderTarget, const Rend
|
|||
vbo->bindArrays();
|
||||
|
||||
GLShader *shader = ShaderManager::instance()->pushShader(shaderTraits);
|
||||
shader->setUniform(GLShader::Saturation, data.saturation());
|
||||
if (shaderTraits & ShaderTrait::AdjustSaturation) {
|
||||
const auto toXYZ = renderTarget.colorDescription().colorimetry().toXYZ();
|
||||
shader->setUniform(GLShader::Saturation, data.saturation());
|
||||
shader->setUniform(GLShader::Vec3Uniform::PrimaryBrightness, QVector3D(toXYZ(1, 0), toXYZ(1, 1), toXYZ(1, 2)));
|
||||
}
|
||||
shader->setColorspaceUniformsFromSRGB(renderTarget.colorDescription());
|
||||
|
||||
if (renderContext.hardwareClipping) {
|
||||
|
|
Loading…
Reference in a new issue