游戏开发论坛

 找回密码
 立即注册
搜索
查看: 4961|回复: 7

开源游戏引擎World Craft中的无缝地形实现 v1.0

[复制链接]

22

主题

191

帖子

217

积分

中级会员

Rank: 3Rank: 3

积分
217
QQ
发表于 2008-9-23 00:49:00 | 显示全部楼层 |阅读模式
由于格式和图片原因,我还是直接上传pdf好了。

sf_200892304919.rar

300 KB, 下载次数:

22

主题

191

帖子

217

积分

中级会员

Rank: 3Rank: 3

积分
217
QQ
 楼主| 发表于 2008-9-23 00:51:00 | 显示全部楼层

Re: 开源游戏引擎World Craft中的无缝地形实现 v1.0

这里是第二部分:

sf_200892305041.rar

237.93 KB, 下载次数:

22

主题

191

帖子

217

积分

中级会员

Rank: 3Rank: 3

积分
217
QQ
 楼主| 发表于 2008-9-23 00:51:00 | 显示全部楼层

Re:开源游戏引擎World Craft中的无缝地形实现 v1.0

贴上原文,大概看一下。。。。


World Craft中的无缝地形实现 v1.0
熊家煜,QY_TEK

Emile:Xjyhust@gmail.com

主页:http://blog.csdn.net/xjyhust

简单说明:
这份文档不是论文,我称之为笔记,或者.note;这份文档free for all,你可以随便使用。如果你想引用,请注明出处http://blog.csdn.net/xjyhust,以及作者 熊家煜。 Ok,由于这个文档只是v1.0,所以缺少很多实际的测试结果,在后面的版本中我会加进来;但是里面的技术是不会有太大的变化的。最后,希望这个文档对你有用。

无缝地形技术简介
mesh部分,使用分块的高度图来保存信息;纹理部分,每块地形使用8张diffuser纹理,4张normal map纹理,使用调色板纹理查询权值进行混合。分别对待场景编辑器和引擎运行时的地形处理方法,使效率和灵活性都能得到保障。

无缝网格的实现
地形的实现,主要针对2D的高度图,保存的精度是float 32bit。为了支持超大的无缝地形,必须将地形进行分块,在运行期间,内存中只保存可视的一块区域。

LOD的实现
地形分块以后的最小单位,我们先称之为brick。离摄像机较近的brick,有较为细节的lod,定义这个时候的lod为低lod;离摄像机较远的brick,有较为粗略的lod,定义这个时候的lod为高lod。(不要弄错了,近处lod低,远处lod高。)

Lod的大致方法就是,lod为level 0时,渲染每个顶点;level为1时,每2个顶点渲染一个顶点;level 为i时,每(2的i次方)个顶点渲染一个顶点...... 具体参看下图:



    Level i                         Level i + 1

为了解决地形“龟裂”的问题,需要对不同level之间缺少的顶点进行处理。有几种不同的处理方式,我的方式是:

假设这个时候level i和level i+1相接,我将level i+1的brick和level i-1临界的那条边界上缺少的顶点加入原有的三角形列表中:



为了解决这个边界“龟裂”的问题,我们需要有不同的三角带。由于在World Craft中,lod的分布都是按照环形的:



所以每个lod的三角带需要有这样五种不同的情况,对于level 为i的brick。情况一,他只和level为i的brick相接;情况二至五,他有且仅有一侧和level i-1的brick相接。

性能和优化
对于brick渲染的优化,我们引入了一个sheet的概念。Sheet是一个更大的划分单位,在我的实践过程中,sheet为4*4个brick或者8*8个brick组成(根据brick的大小不同),sheet共用一个vertex buffer,这样可以使效率更高一些,虽然也是draw n次,但是不需要修改vertex buffer,只要修改index buffer,对待lod相同的brick,index buffer也是一样的,只需要修改偏移量。引入sheet,也是为了后面的texture的优化需要,不需要频繁的切换material,也不用写过于复杂的sort就可以达到优化的目的。

编辑器和引擎运行时的不同
有这样几个原因使我们有理由分开对待这两种情况:

1. 编辑器需要及时的相应用户的输入,这就要求每一次对地形的改变在较短时间内完成

2. 引擎不需要灵活性,所以渲染的数据需要尽量的优化

编辑器中没有sheet的实现(只有概念),即每个brick有单独的vertex buffer,brick要尽可能的小,比如,17*17大小。这样做大大减小了vertex buffer的修改范围,用户的修改会及时得到反馈,不会出现太长的“假死”。

而引擎运行时,sheet的大小为513*513或者257*257,每个brick的大小为65*65或者33*33。我比较倾向513*513的sheet和33*33的brick。(具体是多少比较合理,在这份.note里面我没有列出详细的比较数据,在v2.0里面会列出一些测试的实际数据)

World Craft的地形编辑
World Craft中,使用一个较大的height map来表示一个sheet的,比如513*513大小的height map,然后每个brick的大小为17*17,对应height map的某个17*17的区域,由于brick单独使用vertex buffer,所以,相邻的brick之间共用height map上的17个pixel。

以rise/lower地形笔刷为例,具体的流程如下:

1. 判断鼠标拾取点(和地形相交的点)

2. 计算拾取点所对应的height map上的点

3. 将笔刷(一样也是32bit-float的位图)正确的操作到height map上

4. 更新所影响到的区域(只更新区域内的brick)

有几点需要注意的地方:

1. 更新brick的时候,只更新顶点的position,而不更新normal,否则速度会很慢;normal的更新只在每次鼠标抬起的时候进行;最后的效果非常不错。

2. 涂刷height map的时候,引入一个笔刷密度的概念,表示每隔多少像素才进行一次涂刷;当鼠标移动过快或者过慢的时候,不会产生不均匀的效果。大概的方法就是:记录每次的图刷点,如果图刷点之间的累计距离超过了笔刷密度的定义,就在最近的涂刷路径上的正确地方进行涂刷。

3. 顶点normal的更新,是自己写得,没有用到nvidia的nvMeshMender库,不知道为什么,用nvMeshMender的时候速度奇慢,也许是网格类型的mesh的顶点重复比较多。

顶点normal的计算


如上图,对于每个顶点vert(图中的黑点),计算其周围的6个三角形的normal,然后取平均值。我不知道这个是不是正确的算法,反正最后的效果是正确的。 ;)

无缝纹理的实现
纹理调色板
纹理调色板的做法就是:调色板纹理上的点对应的rgba值作为权值,分别表示使用4张不同纹理的权值。如果调色板上的点只有红色,那么就是表示最后地形上面的该点只使用了第一张纹理;如果调色板的点有4中不同的颜色,分别为0.1,0.2,0.3,0.4,地形上最后的颜色就是0.1份纹理1,0.2份纹理2,0.3纹理3,0.4份纹理4的混合。具体的算法后面有hlsl给出。

为什么这样做,而不是使用一张全局的纹理?具体原因我之前的一篇blog也说道了,这里我直接粘贴过来:

简单的重复纹理是现在最常用的方法,但是效果一般。使用全局的纹理,如果纹理不是超级大,效果也是很一般:一般高度图中的两个像素之间的距离就是对应真实地形中的一米,一米的世界,要用贴图来表现细节,就是用512*512大小的贴图,或者是256*256的,那么,如果用不重复的纹理,实现一个1公里*1公里的世界,需要的贴图大小是256k * 256k,如果效果稍微差一点,就算是一米内只有64个像素,那样也是64k*64k的纹理。。。所以这样算下来,使用全局的贴图的唯一办法就是用detailed map,而我觉得,这是个丑陋的做法,对于一个以室外场景为主的mmo的网游来说,地形是给人印象最大的图像元素,而用统一的细节来欺骗效果的做法,给人的印象自然很糟糕。

使用八张不同的纹理
使用8张不同的纹理,进行混合,还需另外两张不同的调色板,加上8张normal map,一共加起来是18张纹理,这在某些硬件上面不能实现(好像是只有dx10的硬件才能实现),另外在设置寄存器的时候需要改变相当多的变量。

比较节约的做法就是使用texture atlas,参考nvidia的相应工具(还有代码和文档)。将每4张颜色纹理“打包”成一个纹理,这样,最后就是2大张颜色纹理,两大张normal map;两张调色板纹理,一共是6张纹理,在所有ps2_0以上的硬件上都可以实现。

使用atlas的时候,需要注意纹理坐标的改变,原来的纹理坐标是[0, 1],应该转换到[0 +texOffset, 1 ? texOffset],其中texOffset= 1 / ( 2*tex_width);



        整合后的diffuse map                                           整合后的normal map

具体实现 pixel shader
texture g_palTex;

texture g_tex0; // Base color texture

sampler tex0 =

sampler_state

{

Texture = < g_tex0 >;

MipFilter = point;

MinFilter = point;

MagFilter = linear;

addressu =wrap;

addressv =wrap;

addressw =wrap;

};

sampler palTex =

sampler_state

{

Texture = < g_palTex >;

MipFilter = linear;

MinFilter = linear;

MagFilter = linear;

};

struct VS_OUTPUT

{

float4 position : POSITION;

float4 texCoord : TEXCOORD0;

float3 diffuse : TEXCOORD1;

float3 normal : TEXCOORD2;

};

float4 RenderWithTexturePS( VS_OUTPUT i ) : COLOR

{

float2 coord0 = i.texCoord.xy * g_fTexRepeat;

coord0 = frac( coord0 );

coord0 = coord0 * 0.5;

float2 coord1 = coord0 + float2( 0.5, 0 );

float2 coord2 = coord0 + float2( 0, 0.5 );

float2 coord3 = coord0 + float2( 0.5, 0.5 );

float4 palColor = tex2D( palTex, i.texCoord.zw ).rgba;

palColor = normalize( palColor );

float4 vDiffuse = tex2D( tex0, coord0 ) * palColor.x +

tex2D( tex0, coord1 ) * palColor.y +

tex2D( tex0, coord2 ) * palColor.z +

tex2D( tex0, coord3 ) * palColor.w;

return vDiffuse * float4( i.diffuse, 1 );

}

以上实现为:一张调色板纹理,一大张diffuse map(4张不同的纹理整合成的)。顶点中的texCoord.xy为局部的diffuse 纹理的坐标,texCoord.zw为全局的调色板纹理坐标。

22

主题

191

帖子

217

积分

中级会员

Rank: 3Rank: 3

积分
217
QQ
 楼主| 发表于 2008-9-23 00:54:00 | 显示全部楼层

Re:开源游戏引擎World Craft中的无缝地形实现 v1.0

如果分包下载太麻烦,可以查看我的blog:
http://blog.csdn.net/xjyhust/archive/2008/09/23/2964067.aspx
或者,从csdn上下载完整的,单个的pdf
http://download.csdn.net/source/643603

12

主题

128

帖子

128

积分

注册会员

Rank: 2

积分
128
发表于 2008-9-23 14:51:00 | 显示全部楼层

Re:开源游戏引擎World Craft中的无缝地形实现 v1.0

多谢.

12

主题

128

帖子

128

积分

注册会员

Rank: 2

积分
128
发表于 2008-9-23 14:55:00 | 显示全部楼层

Re:开源游戏引擎World Craft中的无缝地形实现 v1.0

唉....我看见了差距....

75

主题

385

帖子

400

积分

中级会员

Rank: 3Rank: 3

积分
400
发表于 2008-9-23 19:03:00 | 显示全部楼层

Re:开源游戏引擎World Craft中的无缝地形实现 v1.0

有代码么?

12

主题

128

帖子

128

积分

注册会员

Rank: 2

积分
128
发表于 2008-9-24 10:09:00 | 显示全部楼层

Re:开源游戏引擎World Craft中的无缝地形实现 v1.0

bs楼上. 代码不会自己写么.
这得多少代码才写得清楚.
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-21 05:58

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表