分享
 
 
 

在游戏制作中如何实现伪体积光照效果

王朝other·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

伪体积光照

1、 引言(Introduction)

在今天的许多演示及游戏中,你可能会看到各种类型的体积效果,就如上图所示。一个可行的想法是使用数学技巧也能做出如此令人惊奇的效果。该文的目的就是给你这个演示的实现方法 ― 它真的很容易。

In many demos and games these days you see various volumetric effects like on the picture above. One might think that it takes amazing skills in both programming as well as mathematics to do such effects. The aim of this tutorial is to show one way of doing it - and it's even an easy way!

2、理论(Theory)

首先,请你看一眼这两张纹理:

First, take a look at these two textures:

左图

右图

这是我们要做的事情:

This is what we do:

1)使用彩色纹理绘制对象“射出”的光(左图)。

Draw the object 'emitting' the light using the colour-texture (the one on the left).

2)稍微变化对象的比例。

Slightly scale the object.

3)在混合方式下使用掩码纹理绘制对象(右图)。

Draw the object using the mask-texture (the one on the right) in a blend mode.

4)重复2与3点 ― 你重复次数愈多,它看起来会更加漂亮(上面的效果我循环了50次)。

Repeat points 2 and 3 - the more times you repeat them, the better it looks (the image above loops 50 times).

3、实现(Implementation)

这方法不受任何特定应用程序接口(它将会与硬件及软件一起工作)的限制,但是我想声明的是,它受到象素填充率的限制(在GF3的640x480下运行为50帧,而Quadro2上仅仅为25帧)。

This method is not limited to any specific API's (it'll work with both hardware and software), apart from the fact, that it is *very* fillrate limited (i get 50fps on gf3 in 640x480, but only 25fps on quadro2).

这里是核心的OpenGL代码(你只需将其放进你自己的程序框架或演示系统中):

Here is the needed code for OpenGL (you need to put this into your own framework or demosystem):

GLuint texture[2];

// Load the textures into this array.

GLUquadricObj *sphere;

// This is our object - you can use your own geometric data if you like.

// Call this function from your initroutine.

void InitQuadric()

// Initialise the quadric object.

{

sphere = gluNewQuadric();

// Create new quadric.

gluQuadricNormals(sphere, GLU_SMOOTH);

// Set normals to be smooth.

gluQuadricTexture(sphere, GL_TRUE);

// Enable texturemapping.

}

// This is the main routine - call this every frame.

void DrawVolLight()

{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// Clear screen and depthbuffer

static float angle = 0.0f;

// Variable to control rotation of the object.

glLoadIdentity();

// Reset the modelview matrix.

glTranslatef(0.0f, 0.0f, -15.0f);

// Move the object in place.

glRotatef(angle, 1.2f, 0.4f, 0.7f);

// Rotate the object.

glEnable(GL_TEXTURE_2D);

// Enable texturemapping.

glBindTexture(GL_TEXTURE_2D, texture[0]);

// Use the colour-texture.

glColor4f(1.0f, 1.0f, 1.0f, 1.0f);

// Full colour and no blending.

gluSphere(sphere, 2, 32, 16);

// Draw the object.

glBlendFunc(GL_SRC_ALPHA, GL_ONE);

// Setup blending.

glBindTexture(GL_TEXTURE_2D, texture[1]);

// Use the mask-texture.

glEnable(GL_BLEND);

// Turn on blending.

glDepthMask(GL_NEVER);

// Don't write to depth buffer

static float numlayers = 50;

// This it the amount of loops - higher values equals better looking (and slower) light.

for (float n = 0; n

// The loop!

{

float scale = 1+n/numlayers;

// calculate the scale-factor.

float color = 1.0f/n+sin(angle/10)/16; // Calculate the percentage of colour used in the blending.

glLoadIdentity();

// Reset the modelview matrix.

glTranslatef(0.0f, 0.0f, -15.0f);

// Position the object.

glRotatef(angle, 1.2f, 0.4f, 0.7f);

// Rotate the object.

glScalef(scale, scale, scale);

// Scale the object (the coordinatesystem actually)

glColor4f(color, color, color, 1.0f);

// Set the amount of colour (used for blending).

gluSphere(sphere, 2, 32, 16);

// Draw the object using the mask-texture

}

glDepthMask(GL_TRUE);

// Make it possilbe to write to the depth-buffer again.

glDisable(GL_BLEND);

// Disable blending.

angle = 0.02*(GetTickCount()-startticks);

// Set up rotation angle for the next fram

glFlush();

// Flush the GL-pipeline (force GL to finish everything it's doing).

}

在实践中,我可能需要调整光照体积。其由调节glColor4f的值完成。

In my implementation, i have made it possible to adjust the volume of the light. It is done by modulating the glColor4f values.

这也就是光源看起来为什么好象在搏动的原因。

This is what makes the light look like it's pulsing.

4、后记(Afterword)

我知道的这个方法是使用了巨量的填充率,它可能会不适合以后的游戏。但是请你注意,它看起来非常好,而且实现过程简单。假如你有任何改进或建议欢迎给我来信。对了,文末的附带的资源是一个执行版(包括纹理)。

I know that this method is a fillrate-eater and that it is probably not suitable for games for the next year or two. Nevertheless! It looks good and it is not too hard to do. Improvements / suggestions are welcome! Let me know if you make you own implementation.Download.Binary version (including textures) of my implementation can be downloaded here

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有