線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:2074
推到 Plurk!
推到 Facebook!

地形陰影貼圖快速計算

 
axsoft
版主


發表:681
回覆:1056
積分:969
註冊:2002-03-13

發送簡訊給我
#1 引用回覆 回覆 發表時間:2002-11-27 13:56:40 IP:61.218.xxx.xxx 未訂閱
地形陰影貼圖快速計算  by Mircea Marghidanu  翻譯:Dreams woo    資料來源:http://www.gameres.com/Visual/3D/Roam/SceneShadow.htm    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 <= 0 ) || ( v.z >= w-1 ) || ( v.z <= 0 ))){
    // 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 (f>1.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. Note For any questions or suggestions, feel free to e-mail me at nervus@go.ro The full sources for this article can be found at http://nervus.go.ro/ in the Downloads section. The sources are free, you can do whatever you want with them, but if you include them in your project, or use this algorithm for any commercial or non-commercial use, please give me credit. Bibliography Global Illumination Compendium March 16, 2000, Philip Dutr? phil@graphics.cornell.edu Program of Computer Graphics Cornell University http://www.graphics.cornell.edu/~phil/GI/ 聯盟----Visita網站http://www.vista.org.tw ---[ 發問前請先找找舊文章 ]---
系統時間:2024-04-25 7:20:43
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!