Shader筆記3 - 模糊(Blur)

? ? ? ? 模糊效果在游戲中經(jīng)常會(huì)用到,有的為了突出前景會(huì)把背景給模糊化览露,有的是因?yàn)橐恍┘寄苄枰:Ч怼D:莝hader中較為簡(jiǎn)單的一種應(yīng)用。

原理

? ? ?? 把一個(gè)點(diǎn)的像素值用它周?chē)狞c(diǎn)的像素值的加權(quán)平均代替差牛。

? ? ? ?先說(shuō)下這個(gè)模糊算法的大致思路命锄,我們?cè)谄沃髦锌梢缘玫疆?dāng)前像素點(diǎn)的顏色值,要想讓這個(gè)顏色變得模糊偏化,就要讓它與它周?chē)南袼攸c(diǎn)的顏色稍微接近一點(diǎn)脐恩,那么我們就需要拿到這個(gè)像素點(diǎn)周?chē)南袼攸c(diǎn)的顏色值,我們把這些個(gè)像素點(diǎn)的值加起來(lái)取平均值侦讨,就得到了一個(gè)區(qū)域內(nèi)的平均顏色驶冒。

? ? ? ? 如果直接使用這個(gè)顏色的話,最終的效果會(huì)變得很模糊韵卤,如果我們只是想稍微模糊一點(diǎn)的話骗污,就要讓這個(gè)平均值更接近于當(dāng)前像素點(diǎn)原本的顏色,為此怜俐,我們?nèi)【档臅r(shí)候?qū)γ總€(gè)像素點(diǎn)增加了一個(gè)權(quán)重的定義身堡,當(dāng)前像素點(diǎn)的權(quán)重最高,依次向周?chē)鷾p弱拍鲤,使得最后得到的均值的顏色更接近于當(dāng)前像素點(diǎn)原始的顏色贴谎。

直接上代碼

建一個(gè)頂點(diǎn)著色器命名為Blur.vert

//頂點(diǎn)著色器

//v_fragmentColor是從頂點(diǎn)著色器設(shè)置的顏色經(jīng)過(guò)光柵化階段的線性插值后傳給片段著色器的顏色。

//v_texCoord同樣是經(jīng)過(guò)線性插值而來(lái)的紋理坐標(biāo)季稳。

attribute vec4 a_position;

attribute vec2 a_texCoord;

attribute vec4 a_color;

//varying 頂點(diǎn)shader和片段shader之間相互傳遞的參數(shù)擅这。

varying vec4 v_fragmentColor;

varying vec2 v_texCoord;

void main()

{

? ? ? ? gl_Position = CC_PMatrix * a_position;

? ? ? ? v_fragmentColor = a_color;

? ? ? ? v_texCoord = a_texCoord;

}

precision mediump float是open es特有的精度限定符,原本的浮點(diǎn)數(shù)精度是double景鼠,opengl es為了提高渲染效率仲翎,限定精度為float類(lèi)型痹扇。

v_fragmentColor是從頂點(diǎn)著色器設(shè)置的顏色經(jīng)過(guò)光柵化階段的線性插值后傳給片段著色器的顏色。

v_texCoord同樣是經(jīng)過(guò)線性插值而來(lái)的紋理坐標(biāo)溯香。

CC_Texture0是一個(gè)采樣器鲫构,在加載Shader的時(shí)候,引擎會(huì)預(yù)先把這些uniform變量給加載進(jìn)來(lái)玫坛。

下面這部分代碼就是引擎預(yù)先加載進(jìn)來(lái)的uniform變量:

static const char * COCOS2D_SHADER_UNIFORMS =

? ? ? "uniform mat4 CC_PMatrix;\n"

? ? ? "uniform mat4 CC_MVMatrix;\n"

? ? ? "uniform mat4 CC_MVPMatrix;\n"

? ? ? "uniform mat3 CC_NormalMatrix;\n"

? ? ?"uniform vec4 CC_Time;\n"

? ? ? "uniform vec4 CC_SinTime;\n"

? ? ? "uniform vec4 CC_CosTime;\n"

? ? ? "uniform vec4 CC_Random01;\n"

? ? ? "uniform sampler2D CC_Texture0;\n"

? ? ? "uniform sampler2D CC_Texture1;\n"

? ? ? "uniform sampler2D CC_Texture2;\n"

? ? ? "uniform sampler2D CC_Texture3;\n"

? ? ? "http://CC INCLUDES END\n\n";

這些變量在shader里面如果沒(méi)有用到的話结笨,會(huì)被引擎給優(yōu)化掉。

texture2D()是shader的內(nèi)建方法湿镀,作用是從CC_Texture0采樣器中進(jìn)行紋理采樣炕吸,得到當(dāng)前片段的顏色值。

gl_FragColor是shader的內(nèi)建變量勉痴,表示當(dāng)前片段的顏色赫模,代碼中是把從采樣器中拿到的顏色值進(jìn)行一個(gè)變灰處理后,最后得到的顏色值再賦值給gl_FragColor蒸矛。gl_FragColor就是最終的顏色瀑罗。

建一個(gè)FragmentShader命名為Blur.frag

varying vec4 v_fragmentColor;

varying vec2 v_texCoord;

uniform vec2 resolution;//模糊對(duì)象的實(shí)際分辨率

uniform float blurRadius;//半徑

uniform float sampleNum;//間隔的段數(shù)

vec4 blur(vec2);

void main(void)

{

? ? ? ? vec4 col = blur(v_texCoord);

? ? ? ? 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;//單位坐標(biāo)

? ? ? ? ? ? ? ? float r = blurRadius;

? ? ? ? ? ? ? ? float sampleStep = r / sampleNum;

? ? ? ? ? ? ? ? float count = 0.0;

? ? ? ? ? ? ? ? //遍歷一個(gè)矩形,當(dāng)前的坐標(biāo)為中心點(diǎn)莉钙,遍歷矩形中每個(gè)像素點(diǎn)的顏色

? ? ? ? ? ? ? ?for(float x = -r; x < r; x += sampleStep)

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? ? ? for(float y = -r; y < r; y += sampleStep)

? ? ? ? ? ? ? ? ? ? ? ? ? ?{

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? float weight = (r - abs(x)) * (r - abs(y));//權(quán)重廓脆,p點(diǎn)的權(quán)重最高,向四周依次減少

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? col += texture2D(CC_Texture0, p + vec2(x * unit.x, y * unit.y)) * weight;

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? count += weight;

? ? ? ? ? ? ? ? ? ? ? ? ? ? ?}

? ? ? ? ? ? ? ? ? ?}

? ? ? ? ? ? ? ? ? ? ?//得到實(shí)際模糊顏色的值

? ? ? ? ? ? ? ? ? ? return col / count;

? ? ? ? ? }

? ? ? ? ? return texture2D(CC_Texture0, p);

}

使用示例

//精靈

auto splash = Sprite::create("HelloWorld.png");

splash->setPosition(100, 100);

this->addChild(splash, 1);

//vert:頂點(diǎn)著色器 ?frag:片段著色器

auto glprogram = GLProgram::createWithFilenames("Shaders/test/Blur.vert", "Shaders/test/Blur.frag");

auto glprogramstate = GLProgramState::getOrCreateWithGLProgram(glprogram);

splash->setGLProgramState(glprogramstate);

//設(shè)置屬性

Size size = sprite->getTexture()->getContentSizeInPixels();

glprogramstate->setUniformVec2("resolution", size); ?//設(shè)置圖片分辨率值

glprogramstate->setUniformFloat("blurRadius", 5);//像素點(diǎn)模糊處理的參考矩形的半徑

glprogramstate->setUniformFloat("sampleNum", 5);//選擇像素點(diǎn)的間隔的數(shù)量

效果



參考資料:https://www.cnblogs.com/cxiaojia/p/5195858.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末磁玉,一起剝皮案震驚了整個(gè)濱河市停忿,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蚊伞,老刑警劉巖席赂,帶你破解...
    沈念sama閱讀 216,919評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異时迫,居然都是意外死亡颅停,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,567評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)掠拳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)癞揉,“玉大人,你說(shuō)我怎么就攤上這事溺欧『笆欤” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,316評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵姐刁,是天一觀的道長(zhǎng)芥牌。 經(jīng)常有香客問(wèn)我,道長(zhǎng)聂使,這世上最難降的妖魔是什么壁拉? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,294評(píng)論 1 292
  • 正文 為了忘掉前任谬俄,我火速辦了婚禮,結(jié)果婚禮上弃理,老公的妹妹穿的比我還像新娘溃论。我一直安慰自己,他們只是感情好案铺,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,318評(píng)論 6 390
  • 文/花漫 我一把揭開(kāi)白布蔬芥。 她就那樣靜靜地躺著梆靖,像睡著了一般控汉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上返吻,一...
    開(kāi)封第一講書(shū)人閱讀 51,245評(píng)論 1 299
  • 那天姑子,我揣著相機(jī)與錄音,去河邊找鬼测僵。 笑死街佑,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的捍靠。 我是一名探鬼主播沐旨,決...
    沈念sama閱讀 40,120評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼榨婆!你這毒婦竟也來(lái)了磁携?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,964評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤良风,失蹤者是張志新(化名)和其女友劉穎谊迄,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體烟央,經(jīng)...
    沈念sama閱讀 45,376評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡统诺,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,592評(píng)論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了疑俭。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片粮呢。...
    茶點(diǎn)故事閱讀 39,764評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖钞艇,靈堂內(nèi)的尸體忽然破棺而出啄寡,到底是詐尸還是另有隱情,我是刑警寧澤香璃,帶...
    沈念sama閱讀 35,460評(píng)論 5 344
  • 正文 年R本政府宣布这难,位于F島的核電站,受9級(jí)特大地震影響葡秒,放射性物質(zhì)發(fā)生泄漏姻乓。R本人自食惡果不足惜嵌溢,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,070評(píng)論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蹋岩。 院中可真熱鬧赖草,春花似錦、人聲如沸剪个。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,697評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)扣囊。三九已至乎折,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間侵歇,已是汗流浹背骂澄。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,846評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留惕虑,地道東北人坟冲。 一個(gè)月前我還...
    沈念sama閱讀 47,819評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像溃蔫,于是被迫代替她去往敵國(guó)和親健提。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,665評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 描邊原理:在片段著色器里面伟叛,對(duì)于每個(gè)像素:1. 如果它是不透明的像素私痹,則不管,維持原本顏色痪伦;2. 如果透明侄榴,是...
    work_xiao閱讀 2,962評(píng)論 1 1
  • 本文主要介紹cocos2d-x如何使用OpenGL實(shí)現(xiàn)著色器程序,介紹可以通過(guò)GLSL語(yǔ)言實(shí)現(xiàn)的兩類(lèi)著色器...
    work_xiao閱讀 4,581評(píng)論 0 5
  • 轉(zhuǎn)載注明出處:點(diǎn)擊打開(kāi)鏈接 Shader(著色器)是一段能夠針對(duì)3D對(duì)象進(jìn)行操作网沾、并被GPU所執(zhí)行的程序癞蚕。Shad...
    游戲開(kāi)發(fā)小Y閱讀 3,359評(píng)論 0 4
  • 一:著色的原理 OpenGL著色語(yǔ)言(OpenGL Shading Language)是用來(lái)在OpenGL中著色編...
    wo不懂閱讀 997評(píng)論 0 2
  • 先貼一個(gè)案例,我們做類(lèi)似的圖片展示的時(shí)候辉哥,都會(huì)需要對(duì)相應(yīng)的圖片進(jìn)行裁剪以適應(yīng)我們現(xiàn)實(shí)的大小桦山,不然圖片就會(huì)被拉伸或者...
    Haer不變閱讀 2,458評(píng)論 0 2