Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d08f7b25 authored by Lucas Dupin's avatar Lucas Dupin Committed by Android (Google) Code Review
Browse files

Merge "Blur shader polish"

parents 3afee20d 8caf4935
Loading
Loading
Loading
Loading
+14 −3
Original line number Diff line number Diff line
@@ -42,9 +42,20 @@ status_t BlurFilter::setAsDrawTarget(const DisplaySettings& display) {
    ATRACE_NAME("BlurFilter::setAsDrawTarget");

    if (!mTexturesAllocated) {
        const uint32_t fboWidth = floorf(display.physicalDisplay.width() * kFboScale);
        const uint32_t fboHeight = floorf(display.physicalDisplay.height() * kFboScale);
        mCompositionFbo.allocateBuffers(fboWidth, fboHeight);
        mDisplayWidth = display.physicalDisplay.width();
        mDisplayHeight = display.physicalDisplay.height();
        mCompositionFbo.allocateBuffers(mDisplayWidth, mDisplayHeight);

        // Let's use mimap filtering on the offscreen composition texture,
        // this will drastically improve overall shader quality.
        glBindTexture(GL_TEXTURE_2D, mCompositionFbo.getTextureName());
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 3);
        glBindTexture(GL_TEXTURE_2D, 0);

        const uint32_t fboWidth = floorf(mDisplayWidth * kFboScale);
        const uint32_t fboHeight = floorf(mDisplayHeight * kFboScale);
        mBlurredFbo.allocateBuffers(fboWidth, fboHeight);
        allocateTextures();
        mTexturesAllocated = true;
+3 −1
Original line number Diff line number Diff line
@@ -30,7 +30,7 @@ namespace gl {
class BlurFilter {
public:
    // Downsample FBO to improve performance
    static constexpr float kFboScale = 0.35f;
    static constexpr float kFboScale = 0.25f;

    explicit BlurFilter(GLESRenderEngine& engine);
    virtual ~BlurFilter(){};
@@ -54,6 +54,8 @@ protected:
    GLFramebuffer mCompositionFbo;
    // Frame buffer holding the blur result.
    GLFramebuffer mBlurredFbo;
    uint32_t mDisplayWidth;
    uint32_t mDisplayHeight;

private:
    bool mTexturesAllocated = false;
+10 −9
Original line number Diff line number Diff line
@@ -77,12 +77,14 @@ status_t GaussianBlurFilter::prepare(uint32_t radius) {
    // set uniforms
    auto width = mVerticalPassFbo.getBufferWidth();
    auto height = mVerticalPassFbo.getBufferHeight();
    auto radiusF = fmax(1.0f, radius * kFboScale);
    glViewport(0, 0, width, height);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, mCompositionFbo.getTextureName());
    glGenerateMipmap(GL_TEXTURE_2D);
    glUniform1i(mVTextureLoc, 0);
    glUniform2f(mVSizeLoc, width, height);
    glUniform1f(mVRadiusLoc, radius * kFboScale);
    glUniform1f(mVRadiusLoc, radiusF);
    mEngine.checkErrors("Setting vertical-diagonal pass uniforms");

    drawMesh(mVUvLoc, mVPosLoc);
@@ -96,7 +98,7 @@ status_t GaussianBlurFilter::prepare(uint32_t radius) {
    glBindTexture(GL_TEXTURE_2D, mVerticalPassFbo.getTextureName());
    glUniform1i(mHTextureLoc, 0);
    glUniform2f(mHSizeLoc, width, height);
    glUniform1f(mHRadiusLoc, radius * kFboScale);
    glUniform1f(mHRadiusLoc, radiusF);
    mEngine.checkErrors("Setting vertical pass uniforms");

    drawMesh(mHUvLoc, mHPosLoc);
@@ -122,8 +124,7 @@ string GaussianBlurFilter::getFragmentShader(bool horizontal) const {
        uniform vec2 uSize;
        uniform float uRadius;

        in mediump vec2 vUV;

        mediump in vec2 vUV;
        out vec4 fragColor;

        #define PI 3.14159265359
@@ -131,7 +132,7 @@ string GaussianBlurFilter::getFragmentShader(bool horizontal) const {
        #define MU 0.0
        #define A 1.0 / (THETA * sqrt(2.0 * PI))
        #define K 1.0 / (2.0 * THETA * THETA)
        #define MAX_SAMPLES 12
        #define MAX_SAMPLES 10

        float gaussianBellCurve(float x) {
            float tmp = (x - MU);
@@ -139,14 +140,14 @@ string GaussianBlurFilter::getFragmentShader(bool horizontal) const {
        }

        vec3 gaussianBlur(sampler2D texture, mediump vec2 uv, float size,
                          vec2 direction, float radius) {
                          mediump vec2 direction, float radius) {
            float totalWeight = 0.0;
            vec3 blurred = vec3(0.);
            int samples = min(int(floor(radius / 2.0)), MAX_SAMPLES);
            int samples = min(int(ceil(radius / 2.0)), MAX_SAMPLES);
            float inc = radius / (size * 2.0);

            for (int i = -samples; i <= samples; i++) {
                float normalized = (float(i) / float(samples));
                float normalized = float(i) / float(samples);
                float weight = gaussianBellCurve(normalized);
                float radInc = inc * normalized;
                blurred += weight * (texture(texture, uv + radInc * direction)).rgb;;
@@ -162,7 +163,7 @@ string GaussianBlurFilter::getFragmentShader(bool horizontal) const {
            #else
            vec3 color = gaussianBlur(uTexture, vUV, uSize.y, vec2(0.0, 1.0), uRadius);
            #endif
            fragColor = vec4(color.r, color.g, color.b, texture(uTexture, vUV).a);
            fragColor = vec4(color, 1.0);
        }

    )SHADER";
+28 −33
Original line number Diff line number Diff line
@@ -86,12 +86,14 @@ status_t LensBlurFilter::prepare(uint32_t radius) {
    // set uniforms
    auto width = mVerticalDiagonalPassFbo.getBufferWidth();
    auto height = mVerticalDiagonalPassFbo.getBufferHeight();
    auto radiusF = fmax(1.0f, radius * kFboScale);
    glViewport(0, 0, width, height);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, mCompositionFbo.getTextureName());
    glGenerateMipmap(GL_TEXTURE_2D);
    glUniform1i(mVDTexture0Loc, 0);
    glUniform2f(mVDSizeLoc, width, height);
    glUniform1f(mVDRadiusLoc, radius * kFboScale);
    glUniform2f(mVDSizeLoc, mDisplayWidth, mDisplayHeight);
    glUniform1f(mVDRadiusLoc, radiusF);
    glUniform1i(mVDNumSamplesLoc, kNumSamples);
    mEngine.checkErrors("Setting vertical-diagonal pass uniforms");

@@ -108,8 +110,8 @@ status_t LensBlurFilter::prepare(uint32_t radius) {
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, mVerticalDiagonalPassFbo.getSecondaryTextureName());
    glUniform1i(mCTexture1Loc, 1);
    glUniform2f(mCSizeLoc, width, height);
    glUniform1f(mCRadiusLoc, radius * kFboScale);
    glUniform2f(mCSizeLoc, mDisplayWidth, mDisplayHeight);
    glUniform1f(mCRadiusLoc, radiusF);
    glUniform1i(mCNumSamplesLoc, kNumSamples);
    mEngine.checkErrors("Setting vertical pass uniforms");

@@ -134,7 +136,6 @@ string LensBlurFilter::getFragmentShader(bool forComposition) const {
    shader += R"SHADER(
        precision lowp float;

        #define BOKEH_ANGLE 0.0
        #define PI 3.14159265359

        uniform sampler2D uTexture0;
@@ -142,7 +143,7 @@ string LensBlurFilter::getFragmentShader(bool forComposition) const {
        uniform float uRadius;
        uniform int uNumSamples;

        in mediump vec2 vUV;
        mediump in vec2 vUV;

        #if DIRECTION == 0
        layout(location = 0) out vec4 fragColor0;
@@ -152,61 +153,55 @@ string LensBlurFilter::getFragmentShader(bool forComposition) const {
        out vec4 fragColor;
        #endif

        vec4 blur(const sampler2D tex, in vec2 uv, const vec2 direction, float radius,
                  in int samples, float intensity) {
            vec4 finalColor = vec4(vec3(0.0), 1.0);
            float blurAmount = 0.0;
        const vec2 verticalMult = vec2(cos(PI / 2.0), sin(PI / 2.0));
        const vec2 diagonalMult = vec2(cos(-PI / 6.0), sin(-PI / 6.0));
        const vec2 diagonal2Mult = vec2(cos(-5.0 * PI / 6.0), sin(-5.0 * PI / 6.0));

        vec3 blur(const sampler2D tex, vec2 uv, const vec2 direction, float radius,
                  int samples, float intensity) {
            vec3 finalColor = vec3(0.0);
            uv += direction * 0.5;

            for (int i = 0; i < samples; i++){
                float delta = radius * float(i) / float(samples);
                vec4 color = texture(tex, uv + direction * delta);
                vec3 color = texture(tex, uv + direction * delta).rgb;
                color.rgb *= intensity;
                color *= color.a;
                blurAmount += color.a;
                finalColor += color;
            }

            return finalColor / blurAmount;
            return finalColor / float(samples);
        }

        vec4 blur(const sampler2D tex, in vec2 uv, const vec2 direction, float radius,
                  in int samples) {
        vec3 blur(const sampler2D tex, vec2 uv, const vec2 direction, float radius,
                  int samples) {
            return blur(tex, uv, direction, radius, samples, 1.0);
        }

        vec4[2] verticalDiagonalLensBlur (vec2 uv, sampler2D texture, vec2 resolution,
                                          float radius, int samples) {
            float coc = texture(texture, uv).a;

            // Vertical Blur
            vec2 blurDirV = (coc / resolution.xy) * vec2(cos(BOKEH_ANGLE + PI / 2.0),
                sin(BOKEH_ANGLE + PI / 2.0));
            vec3 colorV = blur(texture, uv, blurDirV, radius, samples).rgb * coc;
            vec2 blurDirV = 1.0 / resolution.xy * verticalMult;
            vec3 colorV = blur(texture, uv, blurDirV, radius, samples);

            // Diagonal Blur
            vec2 blurDirD = (coc / resolution.xy) * vec2(cos(BOKEH_ANGLE - PI / 6.0),
                sin(BOKEH_ANGLE - PI / 6.0));
            vec3 colorD = blur(texture, uv, blurDirD, radius, samples).rgb * coc;
            vec2 blurDirD = 1.0 / resolution.xy * diagonalMult;
            vec3 colorD = blur(texture, uv, blurDirD, radius, samples);

            vec4 composed[2];
            composed[0] = vec4(colorV, coc);
            composed[0] = vec4(colorV, 1.0);
            // added * 0.5, to remap
            composed[1] = vec4((colorD + colorV) * 0.5, coc);
            composed[1] = vec4((colorD + colorV) * 0.5, 1.0);

            return composed;
        }

        vec4 rhombiLensBlur (vec2 uv, sampler2D texture0, sampler2D texture1, vec2 resolution,
                             float radius, int samples) {
            float coc1 = texture(texture0, uv).a;
            float coc2 = texture(texture1, uv).a;

            vec2 blurDirection1 = coc1 / resolution.xy * vec2(cos(BOKEH_ANGLE - PI / 6.0), sin(BOKEH_ANGLE - PI / 6.0));
            vec3 color1 = blur(texture0, uv, blurDirection1, radius, samples).rgb * coc1;
            vec2 blurDirection1 = 1.0 / resolution.xy * diagonalMult;
            vec3 color1 = blur(texture0, uv, blurDirection1, radius, samples);

            vec2 blurDirection2 = coc2 / resolution.xy * vec2(cos(BOKEH_ANGLE - 5.0 * PI / 6.0), sin(BOKEH_ANGLE - 5.0 * PI / 6.0));
            vec3 color2 = blur(texture1, uv, blurDirection2, radius, samples, 2.0).rgb * coc2;
            vec2 blurDirection2 = 1.0 / resolution.xy * diagonal2Mult;
            vec3 color2 = blur(texture1, uv, blurDirection2, radius, samples, 2.0);

            return vec4((color1 + color2) * 0.33, 1.0);
        }