diff --git a/assets/effects/sprite-gaussian-blur.effect b/assets/effects/sprite-gaussian-blur.effect index 8ffb3df..4df48c1 100644 --- a/assets/effects/sprite-gaussian-blur.effect +++ b/assets/effects/sprite-gaussian-blur.effect @@ -104,9 +104,6 @@ CCProgram fs %{ /** * 获取权重(对应二维高斯函数公式) - * - * @param x - * @param y */ float getWeight(float x, float y) { return (1.0 / (2.0 * pi * pow(stDev, 2.0))) * pow(1.0 / e, (pow(x, 2.0) + pow(y, 2.0)) / (2.0 * pow(stDev, 2.0))); @@ -138,17 +135,40 @@ CCProgram fs %{ gl_FragColor = o; #if ENABLE_GAUSSIAN_BLUR - // 先计算所有权重的和 - const float size = ceil(stDev * 6.0); + const float size = floor(stDev * 6.0 + 1.0); const float halfSize = floor(size / 2.0); - float totalWeight = 0.0; - for(float x = -halfSize; x<= halfSize; x++) { - for (float y = -halfSize; y<= halfSize; y++) { - totalWeight += getWeight(x, y); - } - } - // 加权平均值 + // 步骤一:计算所有权重的和 + + // // v1:遍历所有点,每个点都计算权重 + // float totalWeight = 0.0; + // for(float x = -halfSize; x<= halfSize; x++) { + // for (float y = -halfSize; y<= halfSize; y++) { + // totalWeight += getWeight(x, y); + // } + // } + + // v2:因为分布是对称的,所以只计算原点、X轴正方向、Y轴正方向、第一象限的权重即可,相比起v1版本,减少很多循环计算 + + // 原点 + float totalWeight = getWeight(0.0, 0.0); + + // X轴正方向上的权重 * 2.0 就是整个X轴上的权重 + for(float x = 1.0; x <= halfSize; x++) { + totalWeight += getWeight(x, 0.0) * 2.0; + } + // Y轴正方向上的权重 * 2.0 就是整个Y轴上的权重 + for(float y = 1.0; y <= halfSize; y++) { + totalWeight += getWeight(0.0, y) * 2.0; + } + // 第一象限的权重 * 4.0 就是4个象限的权重 + for(float x = 1.0; x <= halfSize; x++) { + for (float y = 1.0; y<= halfSize; y++) { + totalWeight += getWeight(x, y) * 4.0; + } + } + + // 步骤二:加权平均值 vec4 finalColor = vec4(0.0, 0.0, 0.0, 0.0); float divider = 0.01; float onePxWidth = 1.0 / textureSize.x; diff --git a/assets/effects/sprite-gaussian-blur.effect.meta b/assets/effects/sprite-gaussian-blur.effect.meta index dc78088..7539272 100644 --- a/assets/effects/sprite-gaussian-blur.effect.meta +++ b/assets/effects/sprite-gaussian-blur.effect.meta @@ -5,11 +5,11 @@ { "glsl1": { "vert": "\nprecision highp float;\nuniform mat4 cc_matViewProj;\nuniform mat4 cc_matWorld;\n\nattribute vec3 a_position;\nattribute vec4 a_color;\nvarying vec4 v_color;\n\n#if USE_TEXTURE\nattribute vec2 a_uv0;\nvarying vec2 v_uv0;\n#endif\n\nvoid main () {\n vec4 pos = vec4(a_position, 1);\n\n #if CC_USE_MODEL\n pos = cc_matViewProj * cc_matWorld * pos;\n #else\n pos = cc_matViewProj * pos;\n #endif\n\n #if USE_TEXTURE\n v_uv0 = a_uv0;\n #endif\n\n v_color = a_color;\n\n gl_Position = pos;\n}\n", - "frag": "\nprecision highp float;\n\n#if USE_ALPHA_TEST\n \n uniform float alphaThreshold;\n#endif\n\nvoid ALPHA_TEST (in vec4 color) {\n #if USE_ALPHA_TEST\n if (color.a < alphaThreshold) discard;\n #endif\n}\n\nvoid ALPHA_TEST (in float alpha) {\n #if USE_ALPHA_TEST\n if (alpha < alphaThreshold) discard;\n #endif\n}\n\nvarying vec4 v_color;\n\n#if USE_TEXTURE\nvarying vec2 v_uv0;\nuniform sampler2D texture;\n#endif\n\n#if ENABLE_GAUSSIAN_BLUR\n\nuniform vec2 textureSize;\n/**\n * 获取权重(对应二维高斯函数公式)\n * \n * @param x \n * @param y\n */\nfloat getWeight(float x, float y) {\n return (1.0 / (2.0 * 3.141592653589793 * pow(0.84089642, 2.0))) * pow(1.0 / 2.718281828459045, (pow(x, 2.0) + pow(y, 2.0)) / (2.0 * pow(0.84089642, 2.0)));\n}\n\n/**\n * 获取权重的加权平均值\n */\nfloat getAverageWeight(float x, float y, float totalWeight) {\n return getWeight(x, y) / totalWeight;\n}\n\n#endif\n\nvoid main () {\n vec4 o = vec4(1, 1, 1, 1);\n\n #if USE_TEXTURE\n o *= texture2D(texture, v_uv0);\n #if CC_USE_ALPHA_ATLAS_TEXTURE\n o.a *= texture2D(texture, v_uv0 + vec2(0, 0.5)).r;\n #endif\n #endif\n\n o *= v_color;\n\n ALPHA_TEST(o);\n\n gl_FragColor = o;\n #if ENABLE_GAUSSIAN_BLUR\n\n const float size = ceil(0.84089642 * 6.0);\n const float halfSize = floor(size / 2.0);\n float totalWeight = 0.0; \n for(float x = -halfSize; x<= halfSize; x++) {\n for (float y = -halfSize; y<= halfSize; y++) {\n totalWeight += getWeight(x, y);\n }\n }\n\n vec4 finalColor = vec4(0.0, 0.0, 0.0, 0.0);\n float divider = 0.01; \n float onePxWidth = 1.0 / textureSize.x;\n float onePxHeight = 1.0 / textureSize.y;\n for(float x = -halfSize; x<= halfSize; x++) {\n for (float y = -halfSize; y<= halfSize; y++) {\n\n float weight = getAverageWeight(x, y, totalWeight);\n\n finalColor += texture2D(texture, v_uv0 + vec2(onePxWidth * x, onePxHeight * y)) * weight;\n }\n }\n gl_FragColor = finalColor;\n #endif\n}\n" + "frag": "\nprecision highp float;\n\n#if USE_ALPHA_TEST\n \n uniform float alphaThreshold;\n#endif\n\nvoid ALPHA_TEST (in vec4 color) {\n #if USE_ALPHA_TEST\n if (color.a < alphaThreshold) discard;\n #endif\n}\n\nvoid ALPHA_TEST (in float alpha) {\n #if USE_ALPHA_TEST\n if (alpha < alphaThreshold) discard;\n #endif\n}\n\nvarying vec4 v_color;\n\n#if USE_TEXTURE\nvarying vec2 v_uv0;\nuniform sampler2D texture;\n#endif\n\n#if ENABLE_GAUSSIAN_BLUR\n\nuniform vec2 textureSize;\n/**\n * 获取权重(对应二维高斯函数公式)\n */\nfloat getWeight(float x, float y) {\n return (1.0 / (2.0 * 3.141592653589793 * pow(0.84089642, 2.0))) * pow(1.0 / 2.718281828459045, (pow(x, 2.0) + pow(y, 2.0)) / (2.0 * pow(0.84089642, 2.0)));\n}\n\n/**\n * 获取权重的加权平均值\n */\nfloat getAverageWeight(float x, float y, float totalWeight) {\n return getWeight(x, y) / totalWeight;\n}\n\n#endif\n\nvoid main () {\n vec4 o = vec4(1, 1, 1, 1);\n\n #if USE_TEXTURE\n o *= texture2D(texture, v_uv0);\n #if CC_USE_ALPHA_ATLAS_TEXTURE\n o.a *= texture2D(texture, v_uv0 + vec2(0, 0.5)).r;\n #endif\n #endif\n\n o *= v_color;\n\n ALPHA_TEST(o);\n\n gl_FragColor = o;\n #if ENABLE_GAUSSIAN_BLUR\n\n const float size = floor(0.84089642 * 6.0 + 1.0);\n const float halfSize = floor(size / 2.0);\n\n float totalWeight = getWeight(0.0, 0.0);\n\n for(float x = 1.0; x <= halfSize; x++) {\n totalWeight += getWeight(x, 0.0) * 2.0;\n }\n\n for(float y = 1.0; y <= halfSize; y++) {\n totalWeight += getWeight(0.0, y) * 2.0;\n }\n\n for(float x = 1.0; x <= halfSize; x++) {\n for (float y = 1.0; y<= halfSize; y++) {\n totalWeight += getWeight(x, y) * 4.0;\n }\n }\n\n vec4 finalColor = vec4(0.0, 0.0, 0.0, 0.0);\n float divider = 0.01; \n float onePxWidth = 1.0 / textureSize.x;\n float onePxHeight = 1.0 / textureSize.y;\n for(float x = -halfSize; x<= halfSize; x++) {\n for (float y = -halfSize; y<= halfSize; y++) {\n\n float weight = getAverageWeight(x, y, totalWeight);\n\n finalColor += texture2D(texture, v_uv0 + vec2(onePxWidth * x, onePxHeight * y)) * weight;\n }\n }\n gl_FragColor = finalColor;\n #endif\n}\n" }, "glsl3": { "vert": "\nprecision highp float;\nuniform CCGlobal {\n vec4 cc_time;\n\n vec4 cc_screenSize;\n\n vec4 cc_screenScale;\n\n vec4 cc_nativeSize;\n\n mat4 cc_matView;\n mat4 cc_matViewInv;\n mat4 cc_matProj;\n mat4 cc_matProjInv;\n mat4 cc_matViewProj;\n mat4 cc_matViewProjInv;\n vec4 cc_cameraPos;\n\n vec4 cc_exposure;\n\n vec4 cc_mainLitDir;\n\n vec4 cc_mainLitColor;\n\n vec4 cc_ambientSky;\n vec4 cc_ambientGround;\n};\nuniform CCLocal {\n mat4 cc_matWorld;\n mat4 cc_matWorldIT;\n};\n\nin vec3 a_position;\nin vec4 a_color;\nout vec4 v_color;\n\n#if USE_TEXTURE\nin vec2 a_uv0;\nout vec2 v_uv0;\n#endif\n\nvoid main () {\n vec4 pos = vec4(a_position, 1);\n\n #if CC_USE_MODEL\n pos = cc_matViewProj * cc_matWorld * pos;\n #else\n pos = cc_matViewProj * pos;\n #endif\n\n #if USE_TEXTURE\n v_uv0 = a_uv0;\n #endif\n\n v_color = a_color;\n\n gl_Position = pos;\n}\n", - "frag": "\nprecision highp float;\n\n#if USE_ALPHA_TEST\n \n uniform ALPHA_TEST {\n float alphaThreshold;\n }\n#endif\n\nvoid ALPHA_TEST (in vec4 color) {\n #if USE_ALPHA_TEST\n if (color.a < alphaThreshold) discard;\n #endif\n}\n\nvoid ALPHA_TEST (in float alpha) {\n #if USE_ALPHA_TEST\n if (alpha < alphaThreshold) discard;\n #endif\n}\n\nin vec4 v_color;\n\n#if USE_TEXTURE\nin vec2 v_uv0;\nuniform sampler2D texture;\n#endif\n\n#if ENABLE_GAUSSIAN_BLUR\n\nuniform GaussianBlur {\n\n vec2 textureSize;\n\n}\n\n/**\n * 获取权重(对应二维高斯函数公式)\n * \n * @param x \n * @param y\n */\nfloat getWeight(float x, float y) {\n return (1.0 / (2.0 * 3.141592653589793 * pow(0.84089642, 2.0))) * pow(1.0 / 2.718281828459045, (pow(x, 2.0) + pow(y, 2.0)) / (2.0 * pow(0.84089642, 2.0)));\n}\n\n/**\n * 获取权重的加权平均值\n */\nfloat getAverageWeight(float x, float y, float totalWeight) {\n return getWeight(x, y) / totalWeight;\n}\n\n#endif\n\nvoid main () {\n vec4 o = vec4(1, 1, 1, 1);\n\n #if USE_TEXTURE\n o *= texture(texture, v_uv0);\n #if CC_USE_ALPHA_ATLAS_TEXTURE\n o.a *= texture2D(texture, v_uv0 + vec2(0, 0.5)).r;\n #endif\n #endif\n\n o *= v_color;\n\n ALPHA_TEST(o);\n\n gl_FragColor = o;\n #if ENABLE_GAUSSIAN_BLUR\n\n const float size = ceil(0.84089642 * 6.0);\n const float halfSize = floor(size / 2.0);\n float totalWeight = 0.0; \n for(float x = -halfSize; x<= halfSize; x++) {\n for (float y = -halfSize; y<= halfSize; y++) {\n totalWeight += getWeight(x, y);\n }\n }\n\n vec4 finalColor = vec4(0.0, 0.0, 0.0, 0.0);\n float divider = 0.01; \n float onePxWidth = 1.0 / textureSize.x;\n float onePxHeight = 1.0 / textureSize.y;\n for(float x = -halfSize; x<= halfSize; x++) {\n for (float y = -halfSize; y<= halfSize; y++) {\n\n float weight = getAverageWeight(x, y, totalWeight);\n\n finalColor += texture(texture, v_uv0 + vec2(onePxWidth * x, onePxHeight * y)) * weight;\n }\n }\n gl_FragColor = finalColor;\n #endif\n}\n" + "frag": "\nprecision highp float;\n\n#if USE_ALPHA_TEST\n \n uniform ALPHA_TEST {\n float alphaThreshold;\n }\n#endif\n\nvoid ALPHA_TEST (in vec4 color) {\n #if USE_ALPHA_TEST\n if (color.a < alphaThreshold) discard;\n #endif\n}\n\nvoid ALPHA_TEST (in float alpha) {\n #if USE_ALPHA_TEST\n if (alpha < alphaThreshold) discard;\n #endif\n}\n\nin vec4 v_color;\n\n#if USE_TEXTURE\nin vec2 v_uv0;\nuniform sampler2D texture;\n#endif\n\n#if ENABLE_GAUSSIAN_BLUR\n\nuniform GaussianBlur {\n\n vec2 textureSize;\n\n}\n\n/**\n * 获取权重(对应二维高斯函数公式)\n */\nfloat getWeight(float x, float y) {\n return (1.0 / (2.0 * 3.141592653589793 * pow(0.84089642, 2.0))) * pow(1.0 / 2.718281828459045, (pow(x, 2.0) + pow(y, 2.0)) / (2.0 * pow(0.84089642, 2.0)));\n}\n\n/**\n * 获取权重的加权平均值\n */\nfloat getAverageWeight(float x, float y, float totalWeight) {\n return getWeight(x, y) / totalWeight;\n}\n\n#endif\n\nvoid main () {\n vec4 o = vec4(1, 1, 1, 1);\n\n #if USE_TEXTURE\n o *= texture(texture, v_uv0);\n #if CC_USE_ALPHA_ATLAS_TEXTURE\n o.a *= texture2D(texture, v_uv0 + vec2(0, 0.5)).r;\n #endif\n #endif\n\n o *= v_color;\n\n ALPHA_TEST(o);\n\n gl_FragColor = o;\n #if ENABLE_GAUSSIAN_BLUR\n\n const float size = floor(0.84089642 * 6.0 + 1.0);\n const float halfSize = floor(size / 2.0);\n\n float totalWeight = getWeight(0.0, 0.0);\n\n for(float x = 1.0; x <= halfSize; x++) {\n totalWeight += getWeight(x, 0.0) * 2.0;\n }\n\n for(float y = 1.0; y <= halfSize; y++) {\n totalWeight += getWeight(0.0, y) * 2.0;\n }\n\n for(float x = 1.0; x <= halfSize; x++) {\n for (float y = 1.0; y<= halfSize; y++) {\n totalWeight += getWeight(x, y) * 4.0;\n }\n }\n\n vec4 finalColor = vec4(0.0, 0.0, 0.0, 0.0);\n float divider = 0.01; \n float onePxWidth = 1.0 / textureSize.x;\n float onePxHeight = 1.0 / textureSize.y;\n for(float x = -halfSize; x<= halfSize; x++) {\n for (float y = -halfSize; y<= halfSize; y++) {\n\n float weight = getAverageWeight(x, y, totalWeight);\n\n finalColor += texture(texture, v_uv0 + vec2(onePxWidth * x, onePxHeight * y)) * weight;\n }\n }\n gl_FragColor = finalColor;\n #endif\n}\n" } } ],