DirectX11 地形水波纹理示例Demo
2015-10-04 00:05
253 查看
地形水波纹理示例Demo
1. 地形水波纹理示例Demo介绍
在本例中,我们要为地形和水体添加纹理。首先,我们要在地形上平铺一幅草地纹理。 由于地形网格很大,如果我们直接拉伸纹理,那么每个三角形只能得到很少的几个纹理元素。换句话说,这里无法为表面提供足够高的纹理分辨率;我们会受到倍增问题的影响。所以,我们要在地面网格上平铺草地纹理,进而获得较高的分辨率。其次,我们要通过一个时间函数对水体纹理进行平移,使水体显得更真实一些。2. 生成网格纹理坐标
图8.16是一个建立在xz平面上的m×n网格以及一个在规范化纹理空间[0,1]2中的对应网格。可以看到,xz平面上的第ij个网格顶点的纹理坐标对应于纹理空间中的第ij个网格顶点的坐标。第ij个顶点对应的纹理空间坐标为:uij = j ∙ ∆u
vij = i ∙ ∆v
其中,∆u = 1/(n-1) ,∆v = 1/(m-1) 。
(空间中的网格顶点vij的纹理坐标等于uv空间中的第ij个网格顶点Tij的坐标。)
因此,我们可以使用如下代码为地面网格生成纹理坐标:
void GeometryGenerator::CreateGrid(float width, float depth, UINT m, UINT n, MeshData& meshData) { UINT vertexCount = m*n; UINT faceCount = (m-1)*(n-1)*2; // // 创建顶点 // float halfWidth = 0.5f*width; float halfDepth = 0.5f*depth; float dx = width / (n-1); float dz = depth / (m-1); float du = 1.0f / (n-1); float dv = 1.0f / (m-1); meshData.Vertices.resize(vertexCount); for(UINT i = 0; i < m; ++i) { float z = halfDepth - i*dz; for(UINT j = 0; j < n; ++j) { float x = -halfWidth + j*dx; meshData.Vertices[i*n+j].Position = XMFLOAT3(x, 0.0f, z); meshData.Vertices[i*n+j].Normal = XMFLOAT3(0.0f, 1.0f, 0.0f); meshData.Vertices[i*n+j].TangentU = XMFLOAT3(1.0f, 0.0f, 0.0f); // 在网格上拉伸纹理 meshData.Vertices[i*n+j].TexC.x = j*du; meshData.Vertices[i*n+j].TexC.y = i*dv; } } … }
3. 纹理平铺
前面提到,我们希望在地形网格上平铺一幅草地纹理。但是,目前计算出来的纹理坐标是在单位区间[0,1]2中的,无法产生平铺。所以,我们要指定重复寻址模式并通过一个纹理变换矩阵将纹理坐标扩大5倍。这样,纹理坐标会被映射到[0,5]2区间内,使纹理在地形网格表面平铺5×5次:XMMATRIX grassTexScale = XMMatrixScaling(5.0f, 5.0f, 0.0f); XMStoreFloat4x4(&mGrassTexTransform, grassTexScale); … Effects::BasicFX->SetTexTransform(XMLoadFloat4x4(&mGrassTexTransform)); … activeTech->GetPassByIndex(p)->Apply(0, md3dImmediateContext); md3dImmediateContext->DrawIndexed(mLandIndexCount, 0, 0);
4. 纹理动画
我们要通过一个位于UpdateScene方法中的时间函数在纹理空间中平移纹理坐标,使水体纹理在网格上移动。我们为每帧提供一个很小的位移量,以得到一个平滑动画。我们同时使用无缝纹理和重复寻址模式,以使纹理坐标在平移时不出现间断。下面的代码示范了如何为水体纹理计算位移量,并生成和设定水体的纹理矩阵:// 平铺水面纹理 XMMATRIX wavesScale = XMMatrixScaling(5.0f, 5.0f, 0.0f); // 根据时间平移纹理 mWaterTexOffset.y += 0.05f*dt; mWaterTexOffset.x += 0.1f*dt; XMMATRIX wavesOffset = XMMatrixTranslation(mWaterTexOffset.x, mWaterTexOffset.y, 0.0f); // 组合缩放和平移 XMStoreFloat4x4(&mWaterTexTransform, wavesScale*wavesOffset); … Effects::BasicFX->SetTexTransform(XMLoadFloat4x4(&mWaterTexTransform)); … activeTech->GetPassByIndex(p)->Apply(0, md3dImmediateContext);
5. 程序运行结果截图
项目完整源代码请到DirectX11 龙书官网下载。相关文章推荐
- 类与对象
- 机器学习导论笔记——绪论
- AMD与CMD区别
- Android java 中如何优雅的结束线程
- 笔记:学习 Java同步机制 -Synchronization
- java 事件处理
- 【Python之旅】第五篇(四):基于Python Sockct多线程的简版SSH程序
- 【Python之旅】第五篇(四):基于Python Sockct多线程的简版SSH程序
- 数据结构【线性表(二)链表】项目之自建算法库—单链表
- spring boot实战之内嵌容器tomcat配置
- 浅谈使用PHP开发微信支付的流程
- php开发微信支付获取用户地址
- jquery 实现输入邮箱时自动补全下拉提示功能
- jQuery插件Timelinr 实现时间轴特效
- javascript日期格式化方法汇总
- 推荐10 个很棒的 jQuery 特效代码
- openwrt路由在中继模式下掉线检测重启脚本
- 关于TOAD/plsql使用instantclient的设置
- 网站关键词优化--如何确6定目标关键词
- ueditor1.4.3 jsp版在ssh下的配置