effects/blur: Make shader code readable
At the moment, blur shader code is barely readable because the code is constructed at runtime. Since ShaderManager handles opengl context profiles when loading shaders from files, we can improve code readability by splitting shader code in the corresponding files. Note that ShaderManager adds "precision highp float;" for convenience (whether using "highp" is okay is up for debate).
This commit is contained in:
parent
a4b41c84e1
commit
c7ba0a2567
13 changed files with 189 additions and 134 deletions
|
@ -3,6 +3,7 @@
|
|||
|
||||
set(blur_SOURCES
|
||||
blur.cpp
|
||||
blur.qrc
|
||||
blurshader.cpp
|
||||
main.cpp
|
||||
)
|
||||
|
|
14
src/effects/blur/blur.qrc
Normal file
14
src/effects/blur/blur.qrc
Normal file
|
@ -0,0 +1,14 @@
|
|||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource prefix="/effects/blur/">
|
||||
<file>shaders/copy.frag</file>
|
||||
<file>shaders/copy_core.frag</file>
|
||||
<file>shaders/downsample.frag</file>
|
||||
<file>shaders/downsample_core.frag</file>
|
||||
<file>shaders/noise.frag</file>
|
||||
<file>shaders/noise_core.frag</file>
|
||||
<file>shaders/upsample.frag</file>
|
||||
<file>shaders/upsample_core.frag</file>
|
||||
<file>shaders/vertex.vert</file>
|
||||
<file>shaders/vertex_core.vert</file>
|
||||
</qresource>
|
||||
</RCC>
|
|
@ -8,10 +8,12 @@
|
|||
#include "blurshader.h"
|
||||
|
||||
#include <kwineffects.h>
|
||||
#include <kwinglplatform.h>
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QTextStream>
|
||||
static void ensureResources()
|
||||
{
|
||||
// Must initialize resources manually because the effect is a static lib.
|
||||
Q_INIT_RESOURCE(blur);
|
||||
}
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
@ -19,141 +21,27 @@ namespace KWin
|
|||
BlurShader::BlurShader(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
const bool gles = GLPlatform::instance()->isGLES();
|
||||
const bool glsl_140 = !gles && GLPlatform::instance()->glslVersion() >= kVersionNumber(1, 40);
|
||||
const bool core = glsl_140 || (gles && GLPlatform::instance()->glslVersion() >= kVersionNumber(3, 0));
|
||||
ensureResources();
|
||||
|
||||
QByteArray vertexSource;
|
||||
QByteArray fragmentDownSource;
|
||||
QByteArray fragmentUpSource;
|
||||
QByteArray fragmentCopySource;
|
||||
QByteArray fragmentNoiseSource;
|
||||
m_shaderDownsample.reset(ShaderManager::instance()->generateShaderFromFile(
|
||||
ShaderTrait::MapTexture,
|
||||
QStringLiteral(":/effects/blur/shaders/vertex.vert"),
|
||||
QStringLiteral(":/effects/blur/shaders/downsample.frag")));
|
||||
|
||||
const QByteArray attribute = core ? "in" : "attribute";
|
||||
const QByteArray texture2D = core ? "texture" : "texture2D";
|
||||
const QByteArray fragColor = core ? "fragColor" : "gl_FragColor";
|
||||
m_shaderUpsample.reset(ShaderManager::instance()->generateShaderFromFile(
|
||||
ShaderTrait::MapTexture,
|
||||
QStringLiteral(":/effects/blur/shaders/vertex.vert"),
|
||||
QStringLiteral(":/effects/blur/shaders/upsample.frag")));
|
||||
|
||||
QString glHeaderString;
|
||||
m_shaderCopysample.reset(ShaderManager::instance()->generateShaderFromFile(
|
||||
ShaderTrait::MapTexture,
|
||||
QStringLiteral(":/effects/blur/shaders/vertex.vert"),
|
||||
QStringLiteral(":/effects/blur/shaders/copy.frag")));
|
||||
|
||||
if (gles) {
|
||||
if (core) {
|
||||
glHeaderString += "#version 300 es\n\n";
|
||||
}
|
||||
|
||||
glHeaderString += "precision highp float;\n";
|
||||
} else if (glsl_140) {
|
||||
glHeaderString += "#version 140\n\n";
|
||||
}
|
||||
|
||||
QString glUniformString = "uniform sampler2D texUnit;\n"
|
||||
"uniform float offset;\n"
|
||||
"uniform vec2 renderTextureSize;\n"
|
||||
"uniform vec2 halfpixel;\n";
|
||||
|
||||
if (core) {
|
||||
glUniformString += "out vec4 fragColor;\n\n";
|
||||
}
|
||||
|
||||
// Vertex shader
|
||||
QTextStream streamVert(&vertexSource);
|
||||
|
||||
streamVert << glHeaderString;
|
||||
|
||||
streamVert << "uniform mat4 modelViewProjectionMatrix;\n";
|
||||
streamVert << attribute << " vec4 vertex;\n\n";
|
||||
streamVert << "\n";
|
||||
streamVert << "void main(void)\n";
|
||||
streamVert << "{\n";
|
||||
streamVert << " gl_Position = modelViewProjectionMatrix * vertex;\n";
|
||||
streamVert << "}\n";
|
||||
|
||||
streamVert.flush();
|
||||
|
||||
// Fragment shader (Dual Kawase Blur) - Downsample
|
||||
QTextStream streamFragDown(&fragmentDownSource);
|
||||
|
||||
streamFragDown << glHeaderString << glUniformString;
|
||||
|
||||
streamFragDown << "void main(void)\n";
|
||||
streamFragDown << "{\n";
|
||||
streamFragDown << " vec2 uv = vec2(gl_FragCoord.xy / renderTextureSize);\n";
|
||||
streamFragDown << " \n";
|
||||
streamFragDown << " vec4 sum = " << texture2D << "(texUnit, uv) * 4.0;\n";
|
||||
streamFragDown << " sum += " << texture2D << "(texUnit, uv - halfpixel.xy * offset);\n";
|
||||
streamFragDown << " sum += " << texture2D << "(texUnit, uv + halfpixel.xy * offset);\n";
|
||||
streamFragDown << " sum += " << texture2D << "(texUnit, uv + vec2(halfpixel.x, -halfpixel.y) * offset);\n";
|
||||
streamFragDown << " sum += " << texture2D << "(texUnit, uv - vec2(halfpixel.x, -halfpixel.y) * offset);\n";
|
||||
streamFragDown << " \n";
|
||||
streamFragDown << " " << fragColor << " = sum / 8.0;\n";
|
||||
streamFragDown << "}\n";
|
||||
|
||||
streamFragDown.flush();
|
||||
|
||||
// Fragment shader (Dual Kawase Blur) - Upsample
|
||||
QTextStream streamFragUp(&fragmentUpSource);
|
||||
|
||||
streamFragUp << glHeaderString << glUniformString;
|
||||
|
||||
streamFragUp << "void main(void)\n";
|
||||
streamFragUp << "{\n";
|
||||
streamFragUp << " vec2 uv = vec2(gl_FragCoord.xy / renderTextureSize);\n";
|
||||
streamFragUp << " \n";
|
||||
streamFragUp << " vec4 sum = " << texture2D << "(texUnit, uv + vec2(-halfpixel.x * 2.0, 0.0) * offset);\n";
|
||||
streamFragUp << " sum += " << texture2D << "(texUnit, uv + vec2(-halfpixel.x, halfpixel.y) * offset) * 2.0;\n";
|
||||
streamFragUp << " sum += " << texture2D << "(texUnit, uv + vec2(0.0, halfpixel.y * 2.0) * offset);\n";
|
||||
streamFragUp << " sum += " << texture2D << "(texUnit, uv + vec2(halfpixel.x, halfpixel.y) * offset) * 2.0;\n";
|
||||
streamFragUp << " sum += " << texture2D << "(texUnit, uv + vec2(halfpixel.x * 2.0, 0.0) * offset);\n";
|
||||
streamFragUp << " sum += " << texture2D << "(texUnit, uv + vec2(halfpixel.x, -halfpixel.y) * offset) * 2.0;\n";
|
||||
streamFragUp << " sum += " << texture2D << "(texUnit, uv + vec2(0.0, -halfpixel.y * 2.0) * offset);\n";
|
||||
streamFragUp << " sum += " << texture2D << "(texUnit, uv + vec2(-halfpixel.x, -halfpixel.y) * offset) * 2.0;\n";
|
||||
streamFragUp << " \n";
|
||||
streamFragUp << " " << fragColor << " = sum / 12.0;\n";
|
||||
streamFragUp << "}\n";
|
||||
|
||||
streamFragUp.flush();
|
||||
|
||||
// Fragment shader - Copy texture
|
||||
QTextStream streamFragCopy(&fragmentCopySource);
|
||||
|
||||
streamFragCopy << glHeaderString;
|
||||
|
||||
streamFragCopy << "uniform sampler2D texUnit;\n";
|
||||
streamFragCopy << "uniform vec2 renderTextureSize;\n";
|
||||
streamFragCopy << "uniform vec4 blurRect;\n";
|
||||
|
||||
if (core) {
|
||||
streamFragCopy << "out vec4 fragColor;\n\n";
|
||||
}
|
||||
|
||||
streamFragCopy << "void main(void)\n";
|
||||
streamFragCopy << "{\n";
|
||||
streamFragCopy << " vec2 uv = vec2(gl_FragCoord.xy / renderTextureSize);\n";
|
||||
streamFragCopy << " " << fragColor << " = " << texture2D << "(texUnit, clamp(uv, blurRect.xy, blurRect.zw));\n";
|
||||
streamFragCopy << "}\n";
|
||||
|
||||
streamFragCopy.flush();
|
||||
|
||||
// Fragment shader - Noise tiling
|
||||
QTextStream streamFragNoise(&fragmentNoiseSource);
|
||||
|
||||
streamFragNoise << glHeaderString << glUniformString;
|
||||
|
||||
streamFragNoise << "uniform vec2 noiseTextureSize;\n";
|
||||
streamFragNoise << "uniform vec2 texStartPos;\n";
|
||||
|
||||
streamFragNoise << "void main(void)\n";
|
||||
streamFragNoise << "{\n";
|
||||
streamFragNoise << " vec2 uvNoise = vec2((texStartPos.xy + gl_FragCoord.xy) / noiseTextureSize);\n";
|
||||
streamFragNoise << " \n";
|
||||
streamFragNoise << " " << fragColor << " = vec4(" << texture2D << "(texUnit, uvNoise).rrr, 0);\n";
|
||||
streamFragNoise << "}\n";
|
||||
|
||||
streamFragNoise.flush();
|
||||
|
||||
m_shaderDownsample.reset(ShaderManager::instance()->loadShaderFromCode(vertexSource, fragmentDownSource));
|
||||
m_shaderUpsample.reset(ShaderManager::instance()->loadShaderFromCode(vertexSource, fragmentUpSource));
|
||||
m_shaderCopysample.reset(ShaderManager::instance()->loadShaderFromCode(vertexSource, fragmentCopySource));
|
||||
m_shaderNoisesample.reset(ShaderManager::instance()->loadShaderFromCode(vertexSource, fragmentNoiseSource));
|
||||
m_shaderNoisesample.reset(ShaderManager::instance()->generateShaderFromFile(
|
||||
ShaderTrait::MapTexture,
|
||||
QStringLiteral(":/effects/blur/shaders/vertex.vert"),
|
||||
QStringLiteral(":/effects/blur/shaders/noise.frag")));
|
||||
|
||||
m_valid = m_shaderDownsample->isValid() && m_shaderUpsample->isValid() && m_shaderCopysample->isValid() && m_shaderNoisesample->isValid();
|
||||
|
||||
|
|
9
src/effects/blur/shaders/copy.frag
Normal file
9
src/effects/blur/shaders/copy.frag
Normal file
|
@ -0,0 +1,9 @@
|
|||
uniform sampler2D texUnit;
|
||||
uniform vec2 renderTextureSize;
|
||||
uniform vec4 blurRect;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec2 uv = vec2(gl_FragCoord.xy / renderTextureSize);
|
||||
gl_FragColor = texture2D(texUnit, clamp(uv, blurRect.xy, blurRect.zw));
|
||||
}
|
13
src/effects/blur/shaders/copy_core.frag
Normal file
13
src/effects/blur/shaders/copy_core.frag
Normal file
|
@ -0,0 +1,13 @@
|
|||
#version 140
|
||||
|
||||
uniform sampler2D texUnit;
|
||||
uniform vec2 renderTextureSize;
|
||||
uniform vec4 blurRect;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec2 uv = vec2(gl_FragCoord.xy / renderTextureSize);
|
||||
fragColor = texture(texUnit, clamp(uv, blurRect.xy, blurRect.zw));
|
||||
}
|
17
src/effects/blur/shaders/downsample.frag
Normal file
17
src/effects/blur/shaders/downsample.frag
Normal file
|
@ -0,0 +1,17 @@
|
|||
uniform sampler2D texUnit;
|
||||
uniform float offset;
|
||||
uniform vec2 renderTextureSize;
|
||||
uniform vec2 halfpixel;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec2 uv = vec2(gl_FragCoord.xy / renderTextureSize);
|
||||
|
||||
vec4 sum = texture2D(texUnit, uv) * 4.0;
|
||||
sum += texture2D(texUnit, uv - halfpixel.xy * offset);
|
||||
sum += texture2D(texUnit, uv + halfpixel.xy * offset);
|
||||
sum += texture2D(texUnit, uv + vec2(halfpixel.x, -halfpixel.y) * offset);
|
||||
sum += texture2D(texUnit, uv - vec2(halfpixel.x, -halfpixel.y) * offset);
|
||||
|
||||
gl_FragColor = sum / 8.0;
|
||||
}
|
21
src/effects/blur/shaders/downsample_core.frag
Normal file
21
src/effects/blur/shaders/downsample_core.frag
Normal file
|
@ -0,0 +1,21 @@
|
|||
#version 140
|
||||
|
||||
uniform sampler2D texUnit;
|
||||
uniform float offset;
|
||||
uniform vec2 renderTextureSize;
|
||||
uniform vec2 halfpixel;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec2 uv = vec2(gl_FragCoord.xy / renderTextureSize);
|
||||
|
||||
vec4 sum = texture(texUnit, uv) * 4.0;
|
||||
sum += texture(texUnit, uv - halfpixel.xy * offset);
|
||||
sum += texture(texUnit, uv + halfpixel.xy * offset);
|
||||
sum += texture(texUnit, uv + vec2(halfpixel.x, -halfpixel.y) * offset);
|
||||
sum += texture(texUnit, uv - vec2(halfpixel.x, -halfpixel.y) * offset);
|
||||
|
||||
fragColor = sum / 8.0;
|
||||
}
|
14
src/effects/blur/shaders/noise.frag
Normal file
14
src/effects/blur/shaders/noise.frag
Normal file
|
@ -0,0 +1,14 @@
|
|||
uniform sampler2D texUnit;
|
||||
uniform float offset;
|
||||
uniform vec2 renderTextureSize;
|
||||
uniform vec2 halfpixel;
|
||||
|
||||
uniform vec2 noiseTextureSize;
|
||||
uniform vec2 texStartPos;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec2 uvNoise = vec2((texStartPos.xy + gl_FragCoord.xy) / noiseTextureSize);
|
||||
|
||||
gl_FragColor = vec4(texture2D(texUnit, uvNoise).rrr, 0);
|
||||
}
|
18
src/effects/blur/shaders/noise_core.frag
Normal file
18
src/effects/blur/shaders/noise_core.frag
Normal file
|
@ -0,0 +1,18 @@
|
|||
#version 140
|
||||
|
||||
uniform sampler2D texUnit;
|
||||
uniform float offset;
|
||||
uniform vec2 renderTextureSize;
|
||||
uniform vec2 halfpixel;
|
||||
|
||||
uniform vec2 noiseTextureSize;
|
||||
uniform vec2 texStartPos;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec2 uvNoise = vec2((texStartPos.xy + gl_FragCoord.xy) / noiseTextureSize);
|
||||
|
||||
fragColor = vec4(texture(texUnit, uvNoise).rrr, 0);
|
||||
}
|
20
src/effects/blur/shaders/upsample.frag
Normal file
20
src/effects/blur/shaders/upsample.frag
Normal file
|
@ -0,0 +1,20 @@
|
|||
uniform sampler2D texUnit;
|
||||
uniform float offset;
|
||||
uniform vec2 renderTextureSize;
|
||||
uniform vec2 halfpixel;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec2 uv = vec2(gl_FragCoord.xy / renderTextureSize);
|
||||
|
||||
vec4 sum = texture2D(texUnit, uv + vec2(-halfpixel.x * 2.0, 0.0) * offset);
|
||||
sum += texture2D(texUnit, uv + vec2(-halfpixel.x, halfpixel.y) * offset) * 2.0;
|
||||
sum += texture2D(texUnit, uv + vec2(0.0, halfpixel.y * 2.0) * offset);
|
||||
sum += texture2D(texUnit, uv + vec2(halfpixel.x, halfpixel.y) * offset) * 2.0;
|
||||
sum += texture2D(texUnit, uv + vec2(halfpixel.x * 2.0, 0.0) * offset);
|
||||
sum += texture2D(texUnit, uv + vec2(halfpixel.x, -halfpixel.y) * offset) * 2.0;
|
||||
sum += texture2D(texUnit, uv + vec2(0.0, -halfpixel.y * 2.0) * offset);
|
||||
sum += texture2D(texUnit, uv + vec2(-halfpixel.x, -halfpixel.y) * offset) * 2.0;
|
||||
|
||||
gl_FragColor = sum / 12.0;
|
||||
}
|
24
src/effects/blur/shaders/upsample_core.frag
Normal file
24
src/effects/blur/shaders/upsample_core.frag
Normal file
|
@ -0,0 +1,24 @@
|
|||
#version 140
|
||||
|
||||
uniform sampler2D texUnit;
|
||||
uniform float offset;
|
||||
uniform vec2 renderTextureSize;
|
||||
uniform vec2 halfpixel;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec2 uv = vec2(gl_FragCoord.xy / renderTextureSize);
|
||||
|
||||
vec4 sum = texture(texUnit, uv + vec2(-halfpixel.x * 2.0, 0.0) * offset);
|
||||
sum += texture(texUnit, uv + vec2(-halfpixel.x, halfpixel.y) * offset) * 2.0;
|
||||
sum += texture(texUnit, uv + vec2(0.0, halfpixel.y * 2.0) * offset);
|
||||
sum += texture(texUnit, uv + vec2(halfpixel.x, halfpixel.y) * offset) * 2.0;
|
||||
sum += texture(texUnit, uv + vec2(halfpixel.x * 2.0, 0.0) * offset);
|
||||
sum += texture(texUnit, uv + vec2(halfpixel.x, -halfpixel.y) * offset) * 2.0;
|
||||
sum += texture(texUnit, uv + vec2(0.0, -halfpixel.y * 2.0) * offset);
|
||||
sum += texture(texUnit, uv + vec2(-halfpixel.x, -halfpixel.y) * offset) * 2.0;
|
||||
|
||||
fragColor = sum / 12.0;
|
||||
}
|
7
src/effects/blur/shaders/vertex.vert
Normal file
7
src/effects/blur/shaders/vertex.vert
Normal file
|
@ -0,0 +1,7 @@
|
|||
uniform mat4 modelViewProjectionMatrix;
|
||||
attribute vec4 vertex;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
gl_Position = modelViewProjectionMatrix * vertex;
|
||||
}
|
9
src/effects/blur/shaders/vertex_core.vert
Normal file
9
src/effects/blur/shaders/vertex_core.vert
Normal file
|
@ -0,0 +1,9 @@
|
|||
#version 140
|
||||
|
||||
uniform mat4 modelViewProjectionMatrix;
|
||||
in vec4 vertex;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
gl_Position = modelViewProjectionMatrix * vertex;
|
||||
}
|
Loading…
Reference in a new issue