西西軟件園多重安全檢測下載網(wǎng)站、值得信賴的軟件下載站!
軟件
軟件
文章
搜索

首頁編程開發(fā)其它知識 → 使用投影紋理進(jìn)行模型貼花(Mesh Decals)

使用投影紋理進(jìn)行模型貼花(Mesh Decals)

相關(guān)軟件相關(guān)文章發(fā)表評論 來源:BoYueGame時間:2011/1/7 11:46:31字體大。A-A+

作者:BoYueGame點擊:359次評論:6次標(biāo)簽: 紋理

  • 類型:圖像處理大。50.0M語言:中文 評分:10.0
  • 標(biāo)簽:
立即下載

在游戲中貼花最常見的地方就是用鼠標(biāo)選擇一個目標(biāo)后,地上出現(xiàn)的一個圓圈,或者范圍魔法在施放時的提示區(qū)域。
這個紋理會隨著模型和地圖的表面進(jìn)地扭曲,而非一個平面,所以,我們不論怎么做,都會進(jìn)行一個“投影”的思想,才能讓貼上去的紋理在某一個方向上看的時候,是一個完整的畫面。(我們地上的圈,就是從上往下貼的,所以你從上往下看時,會看到一個完整無扭曲的圖片)。
什么? 地上是一圈?是的,但是呢,我們的紋理是方的。 我們看到是圈,并不表示我們要把紋理貼到一個圈上。
下面是我在RenderMonkey里測試的結(jié)果。

 


OK,圍觀完畢,下面簡單說一下如何實現(xiàn)。


用投影紋理進(jìn)行貼花分為三部。

1、正常渲染模型。

無它!

2、根據(jù)投影方向,投影半徑找到投影時需要渲染的三角形組。

這種貼花的效率損耗就是花在這里了,所以三角形剔除算法要比較高效才行。

3、將此三角形組進(jìn)行渲染,紋理映射時采用投影紋理。

渲染時,要打開全局混合開關(guān)。

下面是投影紋理的HLSL代碼,以及相關(guān)解釋。
VS:

struct VS_INPUT
{
float4 Position : POSITION0;
float2 Texcoord : TEXCOORD0;
};

struct VS_OUTPUT
{
float4 Position : POSITION0;
float2 Texcoord : TEXCOORD0;
float3 WorldPos : TEXCOORD1;
};

VS_OUTPUT vs_main( VS_INPUT Input )
{
VS_OUTPUT Output;

Output.Position = mul( Input.Position, matViewProjection );
Output.Texcoord = Input.Texcoord;
Output.WorldPos = Input.Position;
return( Output );
}

VS所做的工作并沒有什么特別的,僅是需要多向PS傳遞一個空間位置。

PS:
sampler2D baseMap;
sampler2D Texture1; //貼這張紋理時,其UV尋址方式最好為CLAMP
struct PS_INPUT
{
float2 Texcoord : TEXCOORD0;
float3 WorldPos : TEXCOORD1;
};

float4 ps_main( PS_INPUT Input ) : COLOR0
{
float3 Center = float3(0, 0, 20);//投影中心,Y值被忽略。
float Radius = 4;//投影范圍
float3 UVector = float3(1, 0, 0)/(2 * Radius);//將世界坐標(biāo)變換到紋理投影空間坐標(biāo)并規(guī)范化到0-1之間(正投影)
float3 VVector = float3(0, 0, 1)/(2 * Radius);//同上
float2 coord;
coord.x = dot(Input.WorldPos - Center, UVector) + 0.5;
coord.y = dot(Input.WorldPos - Center, VVector) + 0.5;
// if(coord.x < 1 && coord.y < 1 && coord.x>0 && coord.y>0)
return tex2D( Texture1, coord);
//else
//return 0;
}

PS所做的工作就是將世界坐標(biāo)轉(zhuǎn)換到投影空間,再轉(zhuǎn)換為紋理坐標(biāo)。

需要說明一點的是,為了測試方便,我僅假設(shè)此時攝相機(jī)觀察和投影方向為-Y方向。所以

dot(Input.WorldPos - Center, UVector)+0.5

上面這句話其實相當(dāng)于是mul(Input.WorldPos,matProjTexture)/2.0+0.5;

另外,對于

// if(coord.x < 1 && coord.y < 1 && coord.x>0 && coord.y>0)

這句話,我寫在這里,是作為裁剪使用,若沒有這個. 就算你設(shè)置為了CLAMP,那么當(dāng)你的紋理邊緣的ALPHA不為0時,你會看到

紋理會左右延伸。


而若你未選擇CLAMP尋址方式,那你的效果就百般神奇了。 也可以將上面屏蔽的代碼解開,用于裁剪。

 結(jié)尾:

一、投影紋理進(jìn)行模型貼花時,主要是進(jìn)行三角面剔除,使在渲染貼花時,提交最少的三角面。

二、在貼花PASS中,需要將全局混合開啟,并設(shè)置相應(yīng)的SRCBLEND(SRC_ALPHA)和DESTBLEND(DEST_ALPHA)值。括號內(nèi)為我用的值。

當(dāng)然,如果你不想讓貼花與場景(模型)混合,則可以不開啟!

三、請注意紋理的尋址方式以及紋理邊緣的ALPHA情況。 若紋理邊緣ALPHA不為0,則可以手工進(jìn)行裁剪。

四、本文僅是采用了固定的投影方向和SHADER內(nèi)部定義變量的方式來進(jìn)行貼花渲染!〔⑶遥⑽催M(jìn)行模型三角面剔除。所以若要使用,則需要注意第一個問題。

五、本文靈感來源于此貼:http://forums.create.msdn.com/forums/p/34339/198791.aspx

六、支持郵件交流:BoYueGame#Gmail#com

    相關(guān)評論

    閱讀本文后您有什么感想? 已有人給出評價!

    • 8 喜歡喜歡
    • 3 頂
    • 1 難過難過
    • 5 囧
    • 3 圍觀圍觀
    • 2 無聊無聊

    熱門評論

    最新評論

    第 1 樓 重慶九龍坡聯(lián)通 網(wǎng)友 客人 發(fā)表于: 2011/1/7 9:49:39
    你可以轉(zhuǎn)載,但為何要故意隱藏出處,并且刪掉我文中的所有鏈接? 大家可以看原文 http://www.cppblog.com/Leaf/archive/2011/01/07/138093.html

    支持( 0 ) 蓋樓(回復(fù))

    發(fā)表評論 查看所有評論(6)

    昵稱:
    表情: 高興 可 汗 我不要 害羞 好 下下下 送花 屎 親親
    字?jǐn)?shù): 0/500 (您的評論需要經(jīng)過審核才能顯示)