模糊效果在游戏中经常会用到,有的为了突出前景会把背景给模糊化,有的是因为一些技能需要模糊效果。模糊是shader中较为简单的一种应用。cocos2dx 3.x给的demo中,就有sprite的模糊的效果。

先说下这个模糊算法的大致思路,我们在片段着色器中可以得到当前像素点的颜色值,要想让这个颜色变得模糊,就要让它与它周围的像素点的颜色稍微接近一点,那么我们就需要拿到这个像素点周围的像素点的颜色值,我们把这些个像素点的值加起来取平均值,就得到了一个区域内的平均颜色。

如果直接使用这个颜色的话,最终的效果会变得很模糊,如果我们只是想稍微模糊一点的话,就要让这个平均值更接近于当前像素点原本的颜色,为此,我们取均值的时候对每个像素点增加了一个权重的定义,当前像素点的权重最高,依次向周围减弱,使得最后得到的均值的颜色更接近于当前像素点原始的颜色。

看代码:

#ifdef GL_ES
precision mediump float;
#endif varying vec4 v_fragmentColor;
varying vec2 v_texCoord; uniform vec2 resolution;//模糊对象的实际分辨率
uniform float blurRadius;//半径
uniform float sampleNum;//间隔的段数 vec4 blur(vec2); void main(void)
{
vec4 col = blur(v_texCoord); //* v_fragmentColor.rgb;
gl_FragColor = vec4(col) * v_fragmentColor;
} vec4 blur(vec2 p)
{
if (blurRadius > 0.0 && sampleNum > 1.0)
{
vec4 col = vec4(0);
vec2 unit = 1.0 / resolution.xy;//单位坐标 float r = blurRadius;
float sampleStep = r / sampleNum; float count = 0.0;
//遍历一个矩形,当前的坐标为中心点,遍历矩形中每个像素点的颜色
for(float x = -r; x < r; x += sampleStep)
{
for(float y = -r; y < r; y += sampleStep)
{
float weight = (r - abs(x)) * (r - abs(y));//权重,p点的权重最高,向四周依次减少
col += texture2D(CC_Texture0, p + vec2(x * unit.x, y * unit.y)) * weight;
count += weight;
}
}
//得到实际模糊颜色的值
return col / count;
} return texture2D(CC_Texture0, p);
}

精度限定符和varying变量等的一些基础的知识在前面的博客中遇到的已经说过。

uniform变量是顶点着色器和片段着色器共享使用的变量,uniform的值不能被改变。

uniform变量是由宿主程序设置的,代码如下:

void EffectBlur::setTarget(EffectSprite *sprite)
{
Size size = sprite->getTexture()->getContentSizeInPixels();
_glprogramstate->setUniformVec2("resolution", size);
#if (CC_TARGET_PLATFORM != CC_PLATFORM_WINRT)
_glprogramstate->setUniformFloat("blurRadius", _blurRadius);
_glprogramstate->setUniformFloat("sampleNum", _blurSampleNum);
#endif
}

这里宿主程序设置了resolutionblurRadiussampleNum三个uniform变量。渲染的时候,顶点着色器和片段着色器都可以用到这三个变量的值。

resolution是当前渲染node的实际分辨率。

blurRadius是像素点模糊处理的参考矩形的半径

sampleNum选择像素点的间隔的数量,相邻像素点的间距等于blurRadius / sampleNum

blur函数就是计算该像素点的最终颜色,参数p是当前像素点的坐标,我们以p点为中点以2r为边长得到一个矩形,这个矩形中每隔sampleStep长度的像素点是当前像素点的颜色参考像素。每个像素点会乘以一个weight权重,这个weight越靠近p点值越高,目的是为了让最终的值更接近于p点的像素颜色,然后各个像素点乘以权重后的颜色加起来,得到col,把各个权重也加起来得到count。最终的颜色值就是col/count

效果图如下:

模糊前:



模糊后:

Cocos2d-x shader学习2: 模糊(Blur)的更多相关文章

  1. 【Unity Shaders】Shader学习资源和Surface Shader概述

    写在前面 写这篇文章的时候,我断断续续学习Unity Shader半年了,其实还是个门外汉.我也能体会很多童鞋那种想要学好Shader却无从下手的感觉.在这个期间,我找到一些学习Shader的教程以及 ...

  2. Java数据库学习之模糊查询(like )

    Java数据库学习之模糊查询(like ): 第一种方式:直接在SQL语句中进行拼接,此时需要注意的是parm在SQL语句中需要用单引号拼接起来,注意前后单引号之间不能空格 String sql = ...

  3. Unity Shader 学习之旅

    Unity Shader 学习之旅 unityshader图形图像 纸上学来终觉浅,绝知此事要躬行 美丽的梦和美丽的诗一样 都是可遇而不可求的——席慕蓉 一.渲染流水线 示例图 Tips:什么是 GP ...

  4. Unity Shader 学习之旅之SurfaceShader

    Unity Shader 学习之旅之SurfaceShader unity shader 图形图像  如果大地的每个角落都充满了光明 谁还需要星星,谁还会 在夜里凝望 寻找遥远的安慰——江河 官方文档 ...

  5. Shader 学习工具篇 可视化公式工具ZGrapher

    大家好,我是怒风,本篇介绍公式可视化公式工具ZGrapher,尝试通过可视化的方式分析一下Shader中应用的公式,以求帮助初学者快速理解Shader编程中的一些常用公式 本篇的目的两个, 第一,介绍 ...

  6. Shader学习笔记

    Shader学习笔记 例子: Shader "SrfShader1"{ //定义显示在Inspector中的变量,并从Inspector中获取值 Properties{ _Colo ...

  7. 第四章 开始Unity Shader学习之旅(2)

    目录 1. 强大的援手:Unity提供的内置文件和变量 1.1 内置的包含文件 1.2 内置的变量 2. Unity提供的Cg/HLSL语义 2.1 什么是语义 2.2 Unity支持的语义 2.3 ...

  8. Unity shader学习之屏幕后期处理效果之运动模糊

    运动模糊,代码如下: using UnityEngine; public class MotionBlurRenderer : PostEffectRenderer { [Range(0.1f, 0. ...

  9. Unity shader学习之屏幕后期处理效果之均值模糊

    均值模糊,也使用卷积来实现,之不过卷积中每个值均相等,且相加等于1. 代码如下, 子类: using UnityEngine; public class MeanBlurRenderer : Post ...

随机推荐

  1. 兼容ie6及以上的阴影滤镜的写法

    .subnav{ width: 220px; _width:160px; min-height: 168px; border: 1px solid #d0d8da; background: #fff; ...

  2. Apache自带压力测试工具ab用法简介

    ab命令原理 ab命令会创建很多的并发访问线程,模拟多个访问者同时对某一URL进行访问.它的测试目标是基于URL的,因此,既可以用来测试Apache的负载压力,也可以测试nginx.lighthttp ...

  3. B-JUI 实践 之 带搜索与编辑的Datagrid

    使用B-JUI 1.31版本 DataGrid 页直接上代码: <div class="bjui-pageHeader" style="background-col ...

  4. HTML5 Canvas、内联 SVG、Canvas vs. SVG

    canvas 元素用于在网页上绘制图形. 什么是 Canvas? HTML5 的 canvas 元素使用 JavaScript 在网页上绘制图像. 画布是一个矩形区域,您可以控制其每一像素. canv ...

  5. weblogic 集群部署时上传jsp不更新问题

    在进行集群部署的时候,进行“源可访问性”设置的时候,要注意选择“我要使部署能够通过下列位置进行访问”: 前提是必须有共享存储:

  6. C++中的RAII技法

    Resource Acquisition Is Initialization or RAII, is a C++ programming technique which binds the life ...

  7. MyBatis java.sql.SQLSyntaxErrorException: ORA-00911: 无效字符

    http://blog.sina.com.cn/s/blog_6da7fcff0101jewf.html 查看SQL语句是否多加了分号";"

  8. aJax请求结果中包含form的问题

    jsp页面a.jsp如下: <form action='login' id='formId' method='post'> <input name='user'> </f ...

  9. 如何在Crystal框架项目中内置启动Zookeeper服务?

    当Crystal框架项目需要使用到Zookeeper服务时(如使用Dubbo RPC时,需要注册服务到Zookeeper),而独立部署和启动Zookeeper服务不仅繁琐,也容易出现错误. 在小型项目 ...

  10. UOJ #278. 【UTR #2】题目排列顺序(排序水题)

    #278. [UTR #2]题目排列顺序 丢个传送门:http://uoj.ac/problem/278 描述 “又要出题了.” 宇宙出题中心主任 —— 吉米多出题斯基,坐在办公桌前策划即将到来的 U ...