地形阴影渲染

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

地形阴影贴图快速计算

时间:2007-12-05来源:作者:图腾收集发布人:admin 点击:97次

关键字:迅雷快车Baidu贴图地形阴影计算快速目录 1 引言 2 算法描述 3 算法实现 4 光照贴图 5 颜色部件原文:Fast Computation of Terrain Shadow Maps 译者:Dreams Woo1、引言(Introduction)地形渲染是一个覆盖内容非常广的主题。本文将集中介绍对地形的光照和阴影的渲染。在下图中,你将看到这一技术的

目录

1 引言

2 算法描述

3 算法实现

4 光照贴图

5 颜色部件

原文:Fast Computation of Terrain Shadow Maps

译者:Dreams Woo

1、引言(Introduction)

地形渲染是一个覆盖内容非常广的主题。本文将集中介绍对地形的光照和阴影的渲染。在下图中,你将看到这一技术的应用效果。

2、算法描述(Algorithm description)

本法则实际上非常简单,对于每一个栅格点,我们选择从灯光坐标点发出的光线到地图的交点。由于只选择射线L下面的点因此非常快。如下图1:

让我们了解下面的符号:

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]。

3、算法实现(Algorithm implementation)

假如上面的运算你还不明白,下面的代码将帮助你。最重要的函数是intersect_map。这个函数检查目标点是否被遮挡。测试光线是否与高度图有相交。这个函数调用高度图中每一个点。当发现一个交点时,就停止测试,接着测试下一个(如下图2中的点)。就象我在运算法则描述中的那样,假如目标点没有被遮挡,它的光照值使用上面的公式。

函数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

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

{

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

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; j

{

for (i=0; i

{

fVertex.x = i;

fVertex.y = hm->data[j*w+i] * fHeightScale;

fVertex.z = j;

f = fAmbient;

r.origin = fVertex + fSunDir * 2000.0f;

r.direction = fSunDir;

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

{

// checks current working point for intersection

// computing 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;

};

相关文档
最新文档