日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

bloom(转)

發(fā)布時間:2025/5/22 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 bloom(转) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

轉(zhuǎn)載:http://www.cnblogs.com/kenkao/archive/2011/08/25/2153752.html

感謝原創(chuàng)者。

?

又稱“全屏泛光”,是大名鼎鼎的虛幻3游戲引擎中最通用的后期特效技術(shù)~

Bloom特效的實現(xiàn)主要依賴于PostProcess框架,即實時繪制當前場景到一后臺渲染表面,而后針對其對應(yīng)貼圖進行像素級渲染~

大家還記得我們之前實現(xiàn)的水面效果中的反射和折射貼圖嗎?此即為PostProcess的典型應(yīng)用,與Bloom特效有異曲同工之妙。

下面,我們就來揭秘這個Bloom特效的實現(xiàn)流程~

本節(jié)我們實現(xiàn)的Bloom特效,在流程上總共分為4步:

1.提取原場景貼圖中的亮色;

2.針對提取貼圖進行橫向模糊;

3.在橫向模糊基礎(chǔ)上進行縱向模糊;

4.所得貼圖與原場景貼圖疊加得最終效果圖。

所用到的Shader主要有三個,分別對應(yīng)如上4個步驟中的第1步、第2、3步和第4步。我們來看源代碼:

?

BloomExtract.fx /*-------------------------------------

代碼清單:BloomExtract.fx
來自:http://create.msdn.com/en-US/(AppHub)

-------------------------------------*/

//提取原始場景貼圖中明亮的部分
//這是應(yīng)用全屏泛光效果的第一步

sampler?TextureSampler?:?register(s0);

floatBloomThreshold;

float4?ThePixelShader(float2?texCoord?:?TEXCOORD0)?:?COLOR0
{
????//提取原有像素顏色
float4?c?=tex2D(TextureSampler,?texCoord);

????//在BloomThreshold參數(shù)基礎(chǔ)上篩選較明亮的像素
returnsaturate((c?-BloomThreshold)?/(1-BloomThreshold));
????
}

technique?BloomExtract
{
????pass?Pass1
????{
????????PixelShader?=compile?ps_2_0?ThePixelShader();
????}
}

?

GaussianBlur.fx /*-------------------------------------

代碼清單:GaussianBlur.fx
來自:http://create.msdn.com/en-US/(AppHub)

-------------------------------------*/

//高斯模糊過濾
//這個特效要應(yīng)用兩次,一次為橫向模糊,另一次為橫向模糊基礎(chǔ)上的縱向模糊,以減少算法上的時間復(fù)雜度
//這是應(yīng)用Bloom特效的中間步驟

sampler?TextureSampler?:?register(s0);

#defineSAMPLE_COUNT?15

//偏移數(shù)組
float2?SampleOffsets[SAMPLE_COUNT];
//權(quán)重數(shù)組
floatSampleWeights[SAMPLE_COUNT];

float4?ThePixelShader(float2?texCoord?:?TEXCOORD0)?:?COLOR0
{
????float4?c?=0;
????
????//按偏移及權(quán)重數(shù)組疊加周圍顏色值到該像素
????//相對原理,即可理解為該像素顏色按特定權(quán)重發(fā)散到周圍偏移像素
for(inti?=0;?i?<SAMPLE_COUNT;?i++)
????{
????????c?+=tex2D(TextureSampler,?texCoord?+SampleOffsets[i])?*SampleWeights[i];
????}
????
????returnc;
}

technique?GaussianBlur
{
????pass?Pass1
????{
????????PixelShader?=compile?ps_2_0?ThePixelShader();
????}
}

?

BloomCombine.fx /*-------------------------------------

代碼清單:BloomCombine.fx
來自:http://create.msdn.com/en-US/(AppHub)

-------------------------------------*/

//按照特定比例混合原始場景貼圖及高斯模糊貼圖,產(chǎn)生泛光效果
//這是全屏泛光特效的最后一步

//模糊場景紋理采樣器
sampler?BloomSampler?:?register(s0);

//原始場景紋理及采樣器定義
texture?BaseTexture;
sampler?BaseSampler?=sampler_state
{
????Texture???=(BaseTexture);
????MinFilter?=Linear;
????MagFilter?=Linear;
????MipFilter?=Point;
????AddressU??=Clamp;
????AddressV??=Clamp;
};

floatBloomIntensity;
floatBaseIntensity;

floatBloomSaturation;
floatBaseSaturation;

//減緩顏色的飽和度
float4?AdjustSaturation(float4?color,?floatsaturation)
{
????//人眼更喜歡綠光,因此選取0.3,?0.59,?0.11三個值
floatgrey?=dot(color,?float3(0.3,?0.59,?0.11));
????returnlerp(grey,?color,?saturation);
}

float4?ThePixelShader(float2?texCoord?:?TEXCOORD0)?:?COLOR0
{
????//提取原始場景貼圖及模糊場景貼圖的像素顏色
float4?bloom?=tex2D(BloomSampler,?texCoord);
????float4?base=tex2D(BaseSampler,?texCoord);
????
????//柔化原有像素顏色
bloom?=AdjustSaturation(bloom,?BloomSaturation)?*BloomIntensity;
????base=AdjustSaturation(base,?BaseSaturation)?*BaseIntensity;
????
????//結(jié)合模糊像素值微調(diào)原始像素值
base*=(1-saturate(bloom));
????
????//疊加原始場景貼圖及模糊場景貼圖,即在原有像素基礎(chǔ)上疊加模糊后的像素,實現(xiàn)發(fā)光效果
returnbase+bloom;
}

technique?BloomCombine
{
????pass?Pass1
????{
????????PixelShader?=compile?ps_2_0?ThePixelShader();
????}
}

?

三個Shader均來自于微軟WP7開發(fā)者俱樂部,如有引用,敬請標明AppHub字樣及其站點網(wǎng)址:http://create.msdn.com/en-US/,以示對作者原創(chuàng)版權(quán)的尊重!

?

具備相應(yīng)的Shader之后,下面我們來看如何運用他們來實現(xiàn)Bloom特效的四個關(guān)鍵步驟~

因為最終的效果貼圖本質(zhì)上是一張與屏幕大小相同的紋理,因此,我們使用原來構(gòu)建的CSpriteBatch進行繪制。而CSpriteBatch提供的接口是針對于CTexture2D的,所以我們首先要增強并完善CTexture2D類的功能~

以下提供兩個函數(shù),使得CTexture2D可以直接產(chǎn)生渲染貼圖,并允許獲取其后臺渲染表面:

?

boolCTexture2D::CreateRenderTarget(UINT?SizeX,?UINT?SizeY)
{
????//創(chuàng)建渲染貼圖
HRESULT?hr;
????hr?=D3DXCreateTexture(g_pD3DDevice,?SizeX,?SizeY,?1,
????????D3DUSAGE_RENDERTARGET,?D3DFMT_A8R8G8B8,?D3DPOOL_DEFAULT,?&m_pTexture);
????if(FAILED(hr))
????????returnfalse;
????m_Width??=SizeX;
????m_Height?=SizeY;
????m_SurRect.top????=0;
????m_SurRect.left???=0;
????m_SurRect.right??=m_Width;
????m_SurRect.bottom?=m_Height;
????returntrue;
}

boolCTexture2D::GetRenderSurface(IDirect3DSurface9**pOutSurface)
{
????//獲得貼圖的渲染表面
HRESULT?hr;
????hr?=m_pTexture->GetSurfaceLevel(0,?pOutSurface);
????if(FAILED(hr))
????????returnfalse;
????else
????????returntrue;
}

?

之后,就可以著手構(gòu)建我們的CBloomEffect效果類了:

?

/*-------------------------------------

代碼清單:BloomEffect.h
來自:http://www.cnblogs.com/kenkao

-------------------------------------*/

#include?"D3DEffect.h"
#include?"Texture2D.h"

#pragmaonce

//Bloom參數(shù)體
typedef?struct_BloomParam
{
????char*_Name;??????????????//Bloom特效名稱
float_BloomThreshold;????//飽和度
float_BlurAmount;????????//模糊程度
float_BloomIntensity;????//模糊劇烈度
float_BaseIntensity;?????//原始劇烈度
float_BloomSaturation;???//模糊飽和度
float_BaseSaturation;????//原始飽和度
_BloomParam(){}
????_BloomParam(char*name,?floatbloomThreshold,?floatblurAmount,
????????floatbloomIntensity,?floatbaseIntensity,
????????floatbloomSaturation,?floatbaseSaturation)
????{
????????_Name?=name;??_BloomThreshold?=bloomThreshold;?_BlurAmount?=blurAmount;
????????_BloomIntensity?=bloomIntensity;???_BaseIntensity?=baseIntensity;
????????_BloomSaturation?=bloomSaturation;?_BaseSaturation?=baseSaturation;
????}

}BloomParam;

classCBloomEffect
{
public:
????CBloomEffect(void);
????~CBloomEffect(void);
public:
????voidCreate();???????//創(chuàng)建Bloom特效
voidRelease();??????//釋放Bloom特效
voidDrawScene();????//場景繪制
voidBegin();????????//開啟Bloom
voidEnd();??????????//關(guān)閉Bloom
public:
????voidSetParam(BloomParam*pParam){m_pParam?=pParam;}??//參數(shù)體設(shè)置
BloomParam*GetParam()??????????????????{returnm_pParam;}????//參數(shù)體獲取
private:
????voidPostScene();???????????????????//Bloom場景投遞
voidPostSurface(???????????????????//應(yīng)用特效投遞貼圖到特定緩存表面,本質(zhì)就是將一個貼圖應(yīng)用Shader之后的效果寫入另一個貼圖
CTexture2D*pTexture,??????????//后臺紋理
IDirect3DSurface9*pSurface,???//渲染表面
CD3DEffect*pEffect);??????????//目標特效
boolLoadContent();?????????????????//加載內(nèi)容
boolGetSurfaces();?????????????????//獲取渲染表面
private:
????floatComputeGaussian(floatn);?????????????????//計算高斯模糊參數(shù)
voidSetBlurEffectParam(floatdx,?floatdy);???//計算偏移數(shù)組及權(quán)重數(shù)組
private:
????CD3DEffect*m_pBloomExtractEffect;??//Bloom依次用到的三個特效
CD3DEffect*m_pGaussianBlurEffect;
????CD3DEffect*m_pBloomCombineEffect;
private:
????CTexture2D*m_pResolveTarget;???//原始貼圖
CTexture2D*m_pTexture1;????????//模糊貼圖
CTexture2D*m_pTexture2;????????//臨時模糊貼圖
IDirect3DSurface9*m_pResolveSurface;??//原始貼圖渲染表面
IDirect3DSurface9*m_pSurface1;????????//模糊貼圖渲染表面
IDirect3DSurface9*m_pSurface2;????????//臨時貼圖渲染表面
IDirect3DSurface9*m_pOriSurface;??????//初始渲染表面
private:
????BloomParam*m_pParam;??????????????????//Bloom參數(shù)體
};

?

BloomEffect.cpp

?

該類共產(chǎn)生了3個渲染表面,并在渲染過程中發(fā)生了相互疊加,嗯…有點混亂…

我們不妨來看一看每個步驟所得到的渲染效果,而后再針對4個步驟進行分析。如下是我在渲染過程中提取的效果圖:

有了這個流程圖,大家的思路是不是清晰了一些呢?下面,大家結(jié)合這個流程圖來分析各個步驟:

第一步:

應(yīng)用BloomExtract特效提取原始場景貼圖m_pResolveTarget中較明亮的顏色繪制到m_pTexture1貼圖中(m_pResolveTarget--->m_pTexture1)

第二步:

應(yīng)用GaussianBlur特效,在m_pTexture1貼圖基礎(chǔ)上進行橫向高斯模糊到m_pTexture2貼圖(m_pTexture1--->m_pTexture2)

第三步:

再次應(yīng)用GaussianBlur特效,在橫向模糊之后的m_pTexture2貼圖基礎(chǔ)上進行縱向高斯模糊,得到最終的模糊貼圖m_pTexture1(m_pTexture2--->m_pTexture1)

注意:此時,m_pTexture1貼圖即為最終的模糊效果貼圖

如果大家不明白高斯模糊的內(nèi)部原理,可以參看老師為大家翻譯的這篇文章:http://shiba.hpe.sh.cn/jiaoyanzu/WULI/showArticle.aspx?articleId=518&classId=4

第四步:

應(yīng)用BloomCombine特效,疊加原始場景貼圖m_pResolveTarget及兩次模糊之后的場景貼圖m_pTexture1,從而實現(xiàn)發(fā)光效果(m_pResolveTarget+m_pTexture1)

怎么樣?大家明白了嗎?呵呵~

?

我們來看主體代碼:

D3DGame.cpp

?

對Bloom參數(shù)體各個成員變量數(shù)值進行交叉組合,則我們可以得到一系列不同的Bloom效果:

?

?

?

?

還在羨慕那些專業(yè)游戲中美輪美奐的后期特效嗎?現(xiàn)在我們也有能力實現(xiàn)了~ 大家趕快動手嘗試一下吧 ^ ^

以上,謝謝~

轉(zhuǎn)載于:https://www.cnblogs.com/zengqh/archive/2012/10/09/2716447.html

總結(jié)

以上是生活随笔為你收集整理的bloom(转)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。