| 導購 | 订阅 | 在线投稿
分享
 
 
 

多層紋理混合Muti_TextureBlend

來源:互聯網  2008-05-19 00:45:26  評論

Introduction

標題地形渲染是一個非常大的標題,本文將集中介紹對地形的光照和陰影的渲染。在下圖中你將看 到這種技術的效果。

使用本技術産生的地形陰影

法則描述

本法則實際上非常簡單,對于每一個柵格點,我們選擇從燈光坐標點發出的光線到地圖的交點。 由于只選擇射線L下面的點因此非常快。如下圖:

讓我們了解下面的符號:

A = 目標點

B = 燈光位置的投影坐標( vector B = vector(sun_pos.x, 0, sun_pos.z) );

C = 燈光位置坐標;

L = 光線矢量 ( L = A - C );

P = 光線經過路線的所有投影點;

X(P) = 投影點P在光線矢量上的坐標(用于單獨計算LERP)。

點P用來參與從點A到點B之間的2D線計算。對于任意點P,如果在高度圖中它的值大于點X(P) 的Y值,那麽就選擇他。這樣我們就知道光線L與高度圖相交,那麽點A的光照值就等于'ambient_color_value', 接著我們就可以處理下一個目標點。

如果所有的P類型的點都測試完沒有發現交點,那麽點A的光照值就使用下面的公式

Illum(A) = ambient_color_value + (L dot N)

值的範圍爲[0,1]。

執行運算

如果上面的運算你還不明白,下面的代碼將幫助你。最重要的函數是intersect_map。這個函數 檢查目標點是否被遮擋。測試光線是否與高度圖有相交。這個函數調用高度圖中每一個點。當發現一 個交點時,就停止測試,接著測試下一個(如右圖中的點)。就象我在運算法則描述中的那樣,如果 目標點沒有被遮擋,它的光照值使用上面的公式。

函數genLightmap 用于産生光照圖。它測試和照亮高度圖中所有點。

注意:如果你使用下面的代碼,你應當知道法線被從每個部件是FLOAT類型壓縮爲一個字節。

int intersect_map(const vector3& iv,const ray& r,Image* hm,float fHeightScale){

int w,hits;

float d,h,D;

vector3 v,dir;

v = iv + r.direction;

w = hm-w;

hits = 0;

while (!(( v.x = w-1 ) || ( v.x = w-1 ) || ( v.z

// length of lightdir's projection

D = Magnitude(vector3(v.x,0,v.z)-vector3(r.origin.x,0,r.origin.z));

d = Magnitude(iv-v);

// light direction

h = iv.y + (d*r.origin.y) / D;

// X(P) point

// check if height in point P is bigger than point X's height

if (hm-data[ifloor(v.z)* w + ifloor(v.x)] * fHeightScale h){

hits++;

// if so, mark as hit, and skip this work point.

break;

};

dir = r.direction;

dir.y = 0;

v += Normalize(dir);

// fetch new working point

};

return hits;

};

Image* genLightmap(char* normal,Image* hm,vector3 fSunDir,int w,float fAmbient){

int i,j,hits;

float f,dot;

vector3 n,fVertex;

Image* lmap;

ray r;

float fHeightScale = 10.0f / 255.0f;

lmap = new Image(w,w,1);

if (!lmap){printf("(!) Error: cannot alloc lightmap!\n");return 0;};

for (j=0; jdata[j*w+i] * fHeightScale;

fVertex.z = j;

f = fAmbient ;

r.origin = fVertex + fSunDir * 2000.0f;

r.direction = fSunDir;

// checks current working point for intersection

if (!intersect_map(fVertex,r,hm,fHeightScale)){

// compute the lighting equation

n.x = (float)(normal[3*(j*w+i)+0]);

n.y = (float)(normal[3*(j*w+i)+1]);

n.z = (float)(normal[3*(j*w+i)+2]);

f += 0.5f*(1.0f+DotProduct(Normalize(n),Normalize(fSunDir)));

if (f1.0f) f = 1.0f;

};

dot = f * 255.0f;

lmap-data[j*w+i] = (unsigned char)dot;

};

};

return lmap;

};

在你成功的建立你自己的光照圖後,你或許將要使用它。我將告訴你如何把他添加到你的引擎中, 這裏有兩個方法:一是把他當作光照圖使用,另外一個方法是設置地形坐標的每一個點的顔色爲它相 應陰影圖中的顔色。

Terrain color map

Terrain shadow map

王朝网络

Final terrain texture

Lightmapping

如果你打算把陰影圖當作光照圖使用,你應當把他當作紋理部件的一部分,如果你准備使用這項技 術,你應該設置紋理的環境光模式爲modulate。在OPENGL中,代碼如下

glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);

顔色部件

當使用陰影圖象素作爲地形圖元的顔色部件時,你應當爲每一個頂點部件使用單獨的緩沖。 By doing this, you will be able to send the data returned by genLightmap directly to the renderer, by setting the color array pointer to the address of the returned data. In OpenGL, this is done with the glColorPointer function.

  Introduction   標題地形渲染是一個非常大的標題,本文將集中介紹對地形的光照和陰影的渲染。在下圖中你將看 到這種技術的效果。               使用本技術産生的地形陰影   法則描述   本法則實際上非常簡單,對于每一個柵格點,我們選擇從燈光坐標點發出的光線到地圖的交點。 由于只選擇射線L下面的點因此非常快。如下圖:         讓我們了解下面的符號:   A = 目標點   B = 燈光位置的投影坐標( vector B = vector(sun_pos.x, 0, sun_pos.z) );   C = 燈光位置坐標;   L = 光線矢量 ( L = A - C );   P = 光線經過路線的所有投影點;   X(P) = 投影點P在光線矢量上的坐標(用于單獨計算LERP)。   點P用來參與從點A到點B之間的2D線計算。對于任意點P,如果在高度圖中它的值大于點X(P) 的Y值,那麽就選擇他。這樣我們就知道光線L與高度圖相交,那麽點A的光照值就等于'ambient_color_value', 接著我們就可以處理下一個目標點。   如果所有的P類型的點都測試完沒有發現交點,那麽點A的光照值就使用下面的公式   Illum(A) = ambient_color_value + (L dot N)   值的範圍爲[0,1]。   執行運算   如果上面的運算你還不明白,下面的代碼將幫助你。最重要的函數是intersect_map。這個函數 檢查目標點是否被遮擋。測試光線是否與高度圖有相交。這個函數調用高度圖中每一個點。當發現一 個交點時,就停止測試,接著測試下一個(如右圖中的點)。就象我在運算法則描述中的那樣,如果 目標點沒有被遮擋,它的光照值使用上面的公式。   函數genLightmap 用于産生光照圖。它測試和照亮高度圖中所有點。   注意:如果你使用下面的代碼,你應當知道法線被從每個部件是FLOAT類型壓縮爲一個字節。         int intersect_map(const vector3& iv,const ray& r,Image* hm,float fHeightScale){   int w,hits;   float d,h,D;   vector3 v,dir;   v = iv + r.direction;   w = hm-w;   hits = 0;   while (!(( v.x = w-1 ) || ( v.x = w-1 ) || ( v.z   // length of lightdir's projection   D = Magnitude(vector3(v.x,0,v.z)-vector3(r.origin.x,0,r.origin.z));   d = Magnitude(iv-v);   // light direction   h = iv.y + (d*r.origin.y) / D;   // X(P) point   // check if height in point P is bigger than point X's height   if (hm-data[ifloor(v.z)* w + ifloor(v.x)] * fHeightScale h){   hits++;   // if so, mark as hit, and skip this work point.   break;   };   dir = r.direction;   dir.y = 0;   v += Normalize(dir);   // fetch new working point   };   return hits;   };   Image* genLightmap(char* normal,Image* hm,vector3 fSunDir,int w,float fAmbient){   int i,j,hits;   float f,dot;   vector3 n,fVertex;   Image* lmap;   ray r;   float fHeightScale = 10.0f / 255.0f;   lmap = new Image(w,w,1);   if (!lmap){printf("(!) Error: cannot alloc lightmap!\n");return 0;};   for (j=0; jdata[j*w+i] * fHeightScale;   fVertex.z = j;   f = fAmbient ;   r.origin = fVertex + fSunDir * 2000.0f;   r.direction = fSunDir;   // checks current working point for intersection   if (!intersect_map(fVertex,r,hm,fHeightScale)){   // compute the lighting equation   n.x = (float)(normal[3*(j*w+i)+0]);   n.y = (float)(normal[3*(j*w+i)+1]);   n.z = (float)(normal[3*(j*w+i)+2]);   f += 0.5f*(1.0f+DotProduct(Normalize(n),Normalize(fSunDir)));   if (f1.0f) f = 1.0f;   };   dot = f * 255.0f;   lmap-data[j*w+i] = (unsigned char)dot;   };   };   return lmap;   };   在你成功的建立你自己的光照圖後,你或許將要使用它。我將告訴你如何把他添加到你的引擎中, 這裏有兩個方法:一是把他當作光照圖使用,另外一個方法是設置地形坐標的每一個點的顔色爲它相 應陰影圖中的顔色。         Terrain color map         Terrain shadow map    [url=/bbs/detail_1440388.html][img]http://images.wangchao.net.cn/images/upload/images/lsdn/1211129126773.jpg[/img][/url]   Final terrain texture   Lightmapping   如果你打算把陰影圖當作光照圖使用,你應當把他當作紋理部件的一部分,如果你准備使用這項技 術,你應該設置紋理的環境光模式爲modulate。在OPENGL中,代碼如下   glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);   顔色部件   當使用陰影圖象素作爲地形圖元的顔色部件時,你應當爲每一個頂點部件使用單獨的緩沖。 By doing this, you will be able to send the data returned by genLightmap directly to the renderer, by setting the color array pointer to the address of the returned data. In OpenGL, this is done with the glColorPointer function.
󰈣󰈤
王朝萬家燈火計劃
期待原創作者加盟
 
 
 
>>返回首頁<<
 
 
 
 
 熱帖排行
 
 
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有