个人中心

联系我们

搜索 登录 免费注册
界面美化
业务优化
开发工具
图像管理
文档管理
Parasoft

文章详情

将 Triton 与地形和浅水相结合

2023-07-06 15:43:32

将 Triton 与地形和浅水相结合


如果你的应用包括地形以及开放的海洋,有几种方法可以在海岸线取得良好的效果。


最好的方法是向Triton提供地形的高度图,其中包括测深数据。如果使用Triton::Environment::SetHeightMap()提供一个高度图,水在海岸附近将自动变得更加透明,波浪将被减弱以减少任何深度精度的伪影。注意只在高度贴图发生变化时才调用SetHeightMap;Triton需要将纹理复制到系统内存中,而你并不想每一帧都这样做。请确保在创建海洋对象时启用破浪标志,以充分利用高度图的数据。


如果你已经提供了一个有效的高度图,你也可以使用Triton::Environment::SetBreakingWavesParameters()来模拟海浪在海岸线上的破裂。这将产生高波长的海浪,当它们接近海岸线时,海浪的速度会减慢,并带有泡沫和位移效果。从空中看,它们看起来很不错,但是由于性能的原因,海浪在破碎时不会真正地卷曲在自己身上并产生水雾颗粒。你需要指定世界对当地海岸线的方向,这样海浪就会沿着正确的方向前进;一般来说,你把其他参数设置为默认值就可以了。重要的是,你在高度图中的水深数据是真实的;当水变得越来越浅时,海浪就会开始出现,真实的深度信息将导致海浪出现在离岸边适当的距离,并遵循海岸线的轮廓。


除了浮点高度地图纹理,Triton::Environment::SetHeightMap()还需要一个矩阵来将世界坐标转换为纹理坐标。下面是一个计算这个矩阵并使用OpenGL创建适当格式的高度地图纹理的例子;它创建了一个正交投影,从10000米的高度俯视整个地形,坐标系中Y是 "向上",地形的范围从(minX,minZ)到(maxX,maxZ)。


glEnable(GL_TEXTURE_2D);

glGenTextures(1, &heightMap);

glBindTexture(GL_TEXTURE_2D, heightMap);

glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

 

glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE32F_ARB, HEIGHT_MAP_DIM, HEIGHT_MAP_DIM, 0, GL_LUMINANCE, GL_FLOAT, (void*)heightData);

 

glMatrixMode(GL_TEXTURE);

glPushMatrix();

glLoadIdentity();

 

const GLdouble bias[16] = {

        0.5, 0.0, 0.0, 0.0,

        0.0, 0.5, 0.0, 0.0,

        0.0, 0.0, 0.5, 0.0,

        0.5, 0.5, 0.5, 1.0};

glLoadMatrixd(bias);

 

double xrange = maxX - minX;

double zrange = maxZ - minZ;

 

glOrtho(-(xrange * 0.5), xrange * 0.5, -(zrange * 0.5), zrange * 0.5, -1.0, 1.0);

 

double eyex = minX + xrange * 0.5;

double eyey = 10000.0;

double eyez = minZ + zrange * 0.5;

 

double centerx = eyex;

double centery = 0;

double centerz = eyez;

 

double upx = 0;

double upz = -1.0;

double upy = 0;

 

gluLookAt(eyex, eyey, eyez, centerx, centery, centerz, upx, upy, upz);

 

glGetDoublev(GL_TEXTURE_MATRIX, heightMapMatrix);

glPopMatrix();

glMatrixMode(GL_MODELVIEW);


然后你会像这样把产生的高度贴图纹理和矩阵传递给Triton:


tritonEnvironment->SetHeightMap((Triton::TextureHandle)heightMap, Triton::Matrix4(heightMapMatrix));


DirectX9用户应该参考Triton::Envrionment::SetHeightMap()的文档,以了解关于Triton期望的纹理类型的重要信息。


OpenSceneGraph用户可以参考SDK中的OSGDynamicHeightMap样本。这个样本从摄像机周围的场景中自动生成一个高度图,并将其反馈给Triton以实现平滑的海岸线混合。这个样本还包括一个顶点程序的代码,可以为地心或ECEF地形计算出精确的高度图数据。


如果你的地形没有可用的高度图,如果你的相机在海岸线附近,一定要调用Triton::Ocean::SetDepth()。这个方法允许你指定摄像机位置的海底深度和表面法线。在浅水区,这个信息被用来使海岸附近的海浪更加明显,并使海岸线附近的水更加透明。如果你的地形包括在水面下延伸到近海一段距离的纹理几何体,你的海底会影响海岸附近的海洋颜色。我们网站提供的Triton演示程序说明了启用 "海滩 "复选框时的这种效果。


对于处理没有高度地图的水/陆边界,最简单的方法是依靠深度缓冲区。你需要确保你的深度缓冲区有足够的精度,这样才能很好地工作。如果你的系统支持的话,使用32位的深度缓冲器,并确保你的近景和远景剪辑平面设置得尽可能接近。如果深度缓冲区的精度问题在远处是个问题,你也可以使用Triton::Ocean::SetDepthOffset()方法来强制水的深度值更接近摄像机。一般来说,0.01的值似乎可以让事情变得清晰。


如果你有一个深度缓冲区的副本,其中包括地形,但不包括海卫一的水,你也可以看看Triton::Environment::SetDepthMap()方法,作为SetHeightMap()的替代。然而,这个方法有几个注意事项,最好使用SetHeightMap()。


如果你现有的地形数据库包括海洋表面的几何图形,你可能最好使用Triton::Ocean::SetPatchShader()将Triton的着色器应用到你现有的水面几何图形上。同样的技术可以用来渲染较小的水体,而不是由Triton::Ocean::Draw()渲染的无限大的海洋。更多信息请参见渲染用户定义的几何体斑块。


如果你的地形包括低于模拟海平面的陆地区域,你将需要防止Triton在这些区域渲染海浪。一个简单的解决方案是在向模版缓冲区写入时渲染你的地形,然后在调用Triton::Ocean::Draw()时启用模版测试。或者,使用Triton::Ocean::SetPatchShader()和你自己的水网,对场景中水的渲染位置进行更多选择。另一个解决方案是一种叫做 "深度遮蔽 "的技术,在绘制海洋之前,在你希望保持无水的海平面以下区域绘制一个透明的多边形,但要写上深度。例如,深度遮蔽是防止水出现在船体内部的一个好方法。


你可以用Triton::Environment::SetSeaLevel()来调整Triton的海平面。


联系我们

周一至周日 8:00-23:00

免费热线

023-62585653

Gavin:13082556879

Jillian:17558866126

Angela:13057566525

开发外包

ERP-一体化

小程序

企业微信客服二维码

企业微信客服

版权所有:重庆庚乾信息科技有限公司 ©2025 Gengqian Information Technology Co., Ltd. 渝ICP备2022008063号-2 渝公网安备50010702505508

版权所有:重庆庚乾信息科技有限公司

©2025 Gengqian Information Technology Co., Ltd. 渝ICP备2022008063号-2 渝公网安备50010702505508