会员: 密码:  免费注册 | 忘记密码 | 会员登录 网页功能: 加入收藏 设为首页 网站搜索  
游戏开发 > 程序设计 > 3D图形
地面纹理的产生
发表日期:2007-01-19 16:08:20作者: 出处:  

产生地面纹理的方法有很多种,下面介绍一种根据地面高度产生混合纹理的方法。

准备工作:四张贴图,分别为雪地,岩石,草地,沙子。
一张高度图,也就是一张256级灰度的位图。
为简单起见,这五张图的大小最好一样。

目的:产生过渡自然的纹理和3D山脉。
 原理:根据高度改变混合因子,再按该因子对贴图上对应的点进行Alpha混合。


高度图


最终生成的纹理图


最终效果图

步骤:
1.读出每张贴图对应象素的RGB值。
2.从高度图中获得对应点的高度。
3.根据高度计算混合因子,混合第一步得出的RGB值,并写入新纹理的对应位置。
4.重复步骤1,直到所有象素被处理完(如贴图的大小是256*256,则从(0,0)处理到(255,255)),
便可得到一张新的纹理。
5.根据高度图,计算多边形顶点坐标,并设置纹理坐标。
6.剩下的事就交给D3D去做了。

如何计算混合因子?
我们假定山顶是雪地,依次下来是岩石,草地,沙子。
雪地 256-192
岩石 192-128
草地 128-64
沙子 64-0 
以下是计算混合因子的函数:
float texfactor(float h1, float h2)//计算雪地的权重时h1=256,岩石h1=192,
{                                  //草地h1=128,沙子h1=64;h2为该点的实际高度。
    float percent;
    percent = (64.0f - (h1 - h2)) / 64.0f;
    if(percent < 0.0f) percent = 0.0f;
    else if(percent > 1.0f) percent = 1.0f;
    return percent;
}
以下是作混合的函数:
bitmap tex_gen(bitmap tex[4], bitmap heightmap)
{
    float tex_fact[4];	//每种纹理的权重
    float hmap_height;	//在点(x,y)处的高度
    bitmap final_tex;	//最后返回的纹理

    unsigned char new_r, new_g, new_b; //要返回的新的RGB值
    unsigned char old_r[4], old_g[4], old_b[4]; //在点(x,y)处各种纹理的RGB值

    for (int y=0; y<256; y++) //遍历256*256的位图
        for (int x=0; x<256; x++)
        {
            hmap_height=heightmap.getheight(x,y); //取得(x,y)处的高度值

            tex_fact[0]=texfactor(256, hmap_height);//计算第一种地形的权重
            tex_fact[1]=texfactor(192, hmap_height);//计算第二种地形的权重
            tex_fact[2]=texfactor(128, hmap_height);//[...]
            tex_fact[3]=texfactor( 64, hmap_height);//[...]

            for (int i=0; i<4; i++) //读出各种纹理的RGB值
                tex[i].getcolor (&old_r[i], &old_g[i], &old_b[i]);

            new_r=((tex_fact[0]*old_r[0]) + (tex_fact[1]*old_r[1]) + (tex_fact[2]*old_r[2]) + (tex_fact[0]*old_r[3])); //Compose new r value for final texture
            new_g=((tex_fact[0]*old_g[0]) + (tex_fact[1]*old_g[1]) + (tex_fact[2]*old_g[2]) + (tex_fact[0]*old_g[3])); //Same for g
            new_b=((tex_fact[0]*old_b[0]) + (tex_fact[1]*old_b[1]) + (tex_fact[2]*old_b[2]) + (tex_fact[0]*old_b[3])); //and b

            final_tex.setcolor(x,y, new_r, new_g, new_b); //把新的RGB值写到新纹理对应点上
        }

    return final_tex;
}

多边形顶点的位置坐标同样根据高度图设置,注意纹理坐标(u,v)要跟贴图紧密对应, 否则就得不到预期的效果了。

返回顶部】 【打印本页】 【关闭窗口

关于我们 / 给我留言 / 版权举报 / 意见建议 / 网站编程QQ群   
Copyright ©2003- 2024 Lihuasoft.net webmaster(at)lihuasoft.net 加载时间 0.00307