游戏开发论坛

 找回密码
 立即注册
搜索
查看: 4964|回复: 14

地形中如何实现六层纹理?

[复制链接]

75

主题

385

帖子

400

积分

中级会员

Rank: 3Rank: 3

积分
400
发表于 2009-1-8 16:29:00 | 显示全部楼层 |阅读模式
三层没问题,六层搞不好
TERRAIN.FX如下
//=============================================================================
// Terrain.fx by Frank Luna (C) 2004 All Rights Reserved.
//
// Blends three textures together with a blend map.
//=============================================================================


uniform extern float4x4 gViewProj;
uniform extern float3  gDirToSunW;
uniform extern texture gTex0;
uniform extern texture gTex1;
uniform extern texture gTex2;
uniform extern texture gTex3;
uniform extern texture gTex4;
uniform extern texture gTex5;
uniform extern texture gBlendMap;
uniform extern texture gBlendMap2;
static float gTexScale = 64.0f;

sampler Tex0S = sampler_state
{
        Texture = <gTex0>;
MinFilter = ANISOTROPIC;
        MaxAnisotropy = 8;
        MinFilter = LINEAR;
        MagFilter = LINEAR;
        //MipFilter = POINT;
        AddressU  = WRAP;
    AddressV  = WRAP;
};

sampler Tex1S = sampler_state
{
        Texture = <gTex1>;
        MinFilter = LINEAR;
        MagFilter = LINEAR;
        MipFilter = POINT;
        AddressU  = WRAP;
    AddressV  = WRAP;
};

sampler Tex2S = sampler_state
{
        Texture = <gTex2>;
        MinFilter = LINEAR;
        MagFilter = LINEAR;
        MipFilter = POINT;
        AddressU  = WRAP;
    AddressV  = WRAP;
};
sampler Tex3S = sampler_state
{
        Texture = <gTex3>;
        MinFilter = LINEAR;
        MagFilter = LINEAR;
        MipFilter = POINT;
        AddressU  = WRAP;
    AddressV  = WRAP;
};
sampler Tex4S = sampler_state
{
        Texture = <gTex4>;
        MinFilter = LINEAR;
        MagFilter = LINEAR;
        MipFilter = POINT;
        AddressU  = WRAP;
    AddressV  = WRAP;
};
sampler Tex5S = sampler_state
{
        Texture = <gTex5>;
        MinFilter = LINEAR;
        MagFilter = LINEAR;
        MipFilter = POINT;
        AddressU  = WRAP;
    AddressV  = WRAP;
};
sampler BlendMapS = sampler_state
{
        Texture = <gBlendMap>;
        MinFilter = LINEAR;
        MagFilter = LINEAR;
        MipFilter = POINT;
        AddressU  = WRAP;
    AddressV  = WRAP;
};
sampler BlendMap2S = sampler_state
{
        Texture = <gBlendMap2>;
        MinFilter = LINEAR;
        MagFilter = LINEAR;
        MipFilter = POINT;
        AddressU  = WRAP;
    AddressV  = WRAP;
};

struct OutputVS
{
    float4 posH         : POSITION0;
    float2 tiledTexC    : TEXCOORD0;
    float2 nonTiledTexC : TEXCOORD1;
    float  shade        : TEXCOORD2;
};

OutputVS TerrainVS(float3 posW : POSITION0,  // We assume terrain geometry is specified
                   float3 normalW : NORMAL0, // directly in world space.
                   float2 tex0: TEXCOORD0)
{
    // Zero out our output.
        OutputVS outVS = (OutputVS)0;
       
        // Just compute a grayscale diffuse and ambient lighting
        // term--terrain has no specular reflectance.  The color
        // comes from the texture.
    outVS.shade = saturate(max(0.0f, dot(normalW, gDirToSunW)) + 0.3f);
   
        // Transform to homogeneous clip space.
        outVS.posH = mul(float4(posW, 1.0f), gViewProj);
       
        // Pass on texture coordinates to be interpolated in rasterization.
        outVS.tiledTexC    = tex0 * gTexScale; // Scale tex-coord to tile.
        outVS.nonTiledTexC = tex0; // Blend map not tiled.
       
        // Done--return the output.
    return outVS;
}

float4 TerrainPS(float2 tiledTexC : TEXCOORD0,
                 float2 nonTiledTexC : TEXCOORD1,
                 float shade : TEXCOORD2) : COLOR
{
        // Layer maps are tiled
    float3 c0 = tex2D(Tex0S, tiledTexC).rgb;
    float3 c1 = tex2D(Tex1S, tiledTexC).rgb;
    float3 c2 = tex2D(Tex2S, tiledTexC).rgb;
   
    // Blendmap is not tiled.
    //float3 B = tex2D(BlendMapS, nonTiledTexC).rgb;
float4 B = tex2D(BlendMapS, nonTiledTexC);
        // Find the inverse of all the blend weights so that we can
        // scale the total color to the range [0, 1].
    float totalInverse = 1.0f / (B.r + B.g + B.b);
   
    // Scale the colors by each layer by its corresponding weight
    // stored in the blendmap.  
    c0 *= B.r * totalInverse;
    c1 *= B.g * totalInverse;
    c2 *= B.b * totalInverse;
   
//float3 final = (B.r*lerp(c0,c3,B.a)
//                        +B.g*lerp(c1,c4,B.a)
//                        +c2)* shade;


//lerp(tex2D(s7, vTexture3),tex2D(s3, vTexture3),B.a)

    // Sum the colors and modulate with the shade to brighten/darken.
   // float3 final = (c0 + c1 + c2) * shade;
//float4 vfade = tex2D(s0, vTexture0);
    float4 B2 = tex2D(BlendMap2S, nonTiledTexC);   
    float totalInverse2 = 1.0f / (B2.r + B2.g + B2.b);
    float3 c3 = tex2D(Tex3S, tiledTexC).rgb;
    float3 c4 = tex2D(Tex4S, tiledTexC).rgb;
    float3 c5 = tex2D(Tex5S, tiledTexC).rgb;
    c3 *= B2.r * totalInverse2;
    c4 *= B2.g * totalInverse2;
    c5 *= B2.b * totalInverse2;
/* float r1=(B.r*B.r/(B.r+B2.r))*((B.r+B2.r)/510);
float g1=(B.g*B.g/(B.g+B2.g))*((B.g+B2.g)/510);
float b1=(B.b*B.b/(B.b+B2.b))*((B.b+B2.b)/510);

float r2=(B2.r*B2.r/(B2.r+B.r))*((B2.r+B.r)/510);
float g2=(B2.g*B2.g/(B2.g+B.g))*((B2.g+B.g)/510);
float b2=(B2.b*B2.b/(B2.b+B.b))*((B2.b+B.b)/510);

c0 *=r1*(2.0f/(B.r + B.g + B.b+B2.r + B2.g + B2.b));
c1 *=g1*(2.0f/(B.r + B.g + B.b+B2.r + B2.g + B2.b));
c2 *=b1*(2.0f/(B.r + B.g + B.b+B2.r + B2.g + B2.b));

c3 *=r2*(2.0f/(B.r + B.g + B.b+B2.r + B2.g + B2.b));
c4 *=g2*(2.0f/(B.r + B.g + B.b+B2.r + B2.g + B2.b));
c5 *=b2*(2.0f/(B.r + B.g + B.b+B2.r + B2.g + B2.b));
*/
//+c3+c4+c5
//    float3 final = (c0 + c1 + c2);
float3 final;

//if (B2.a!=B.a)
final = ((c0+c1+c2)*(1-B.a)+(c3* + c4 + c5)*B.a)* shade;
//if (B2.a==B.a)
//final = (c0 + c1 + c2)* shade;
   // float3 final = ((c0*(1-1/B2.a),c3*(1/B2.a)) + (c1*(1-1/B2.a),c4*(1/B2.a)) + c2) * shade;
    // Blendmap is not tiled.
    //float3 B = tex2D(BlendMapS, nonTiledTexC).rgb;

//    return final;
return float4(final, 1.0f);
   }

technique TerrainTech
{
    pass P0
    {
        vertexShader = compile vs_2_0 TerrainVS();
        pixelShader  = compile ps_2_0 TerrainPS();
    }
}

75

主题

385

帖子

400

积分

中级会员

Rank: 3Rank: 3

积分
400
 楼主| 发表于 2009-1-8 16:30:00 | 显示全部楼层

Re: 地形中如何实现六层纹理?



75

主题

385

帖子

400

积分

中级会员

Rank: 3Rank: 3

积分
400
 楼主| 发表于 2009-1-8 16:33:00 | 显示全部楼层

Re: 地形中如何实现六层纹理?

119

主题

1367

帖子

1393

积分

金牌会员

Rank: 6Rank: 6

积分
1393
发表于 2009-1-8 23:25:00 | 显示全部楼层

Re:地形中如何实现六层纹理?

简单的比例分配问题:

// Layer maps are tiled
    float3 c0 = tex2D(Tex0S, tiledTexC).rgb;
    float3 c1 = tex2D(Tex1S, tiledTexC).rgb;
    float3 c2 = tex2D(Tex2S, tiledTexC).rgb;
    float3 c3 = tex2D(Tex3S, tiledTexC).rgb;
    float3 c4 = tex2D(Tex4S, tiledTexC).rgb;
    float3 c5 = tex2D(Tex5S, tiledTexC).rgb;

    // 两张混合纹理,一张搞定三层,alpha混合纹理是nontiled
    float4 A = tex2D(BlendMapSA, nonTiledTexC).argb;
    float4 B = tex2D(BlendMapSB, nonTiledTexC).argb;
   
    //6层纹理的插值
    float totalInverse = 1.0f / (A.r + A.g + A.b + B.r + B.g + B.b);
   
    //A.a代表光照
    //A.r A.g A.b B.r B.g.B.b代表的是6层混合纹理的alpha通道
    c0 *= A.r * totalInverse;
    c1 *= A.g * totalInverse;
    c2 *= A.b * totalInverse;
   
    c3 *= B.r * totalInverse;
    c4 *= B.g * totalInverse;
    c5 *= B.b * totalInverse;

easy吧,别想太复杂了

75

主题

385

帖子

400

积分

中级会员

Rank: 3Rank: 3

积分
400
 楼主| 发表于 2009-1-9 00:00:00 | 显示全部楼层

Re: 地形中如何实现六层纹理?

非常感谢!!!

有个问题,如果这样如何处理
如第一个BlendMap
R为草地
G为沙地
B为河石
如第二个BlendMap
R为河草地
G为白沙地
B为红石
如果一个地方已为第一个BlendMap 的R为草地
现刷为第二个BlendMap 的B为红石
结果却是草地和红石的混合
不是想要的红石

45

主题

1163

帖子

1165

积分

金牌会员

Rank: 6Rank: 6

积分
1165
发表于 2009-1-9 08:45:00 | 显示全部楼层

Re:地形中如何实现六层纹理?

^_^ 原来是多加了一层权重纹理

75

主题

385

帖子

400

积分

中级会员

Rank: 3Rank: 3

积分
400
 楼主| 发表于 2009-1-13 12:43:00 | 显示全部楼层

Re: 地形中如何实现六层纹理?

sf_2009113124239.jpg

59

主题

984

帖子

1200

积分

金牌会员

Rank: 6Rank: 6

积分
1200
发表于 2009-1-13 17:21:00 | 显示全部楼层

Re:地形中如何实现六层纹理?

是用6层纹理之前,应该先分析是否需要6层纹理
wow的大部分地形只用了三层diffuse map,但效果已经非常不错了

19

主题

638

帖子

638

积分

高级会员

Rank: 4

积分
638
发表于 2009-1-13 17:27:00 | 显示全部楼层

Re:地形中如何实现六层纹理?

好歹也考虑下效率啊,tex2D()是很代价很高的操作,没必要对每个像素都做8次……

119

主题

1367

帖子

1393

积分

金牌会员

Rank: 6Rank: 6

积分
1393
发表于 2009-1-13 17:36:00 | 显示全部楼层

Re: Re:地形中如何实现六层纹理?

qrli: Re:地形中如何实现六层纹理?

好歹也考虑下效率啊,tex2D()是很代价很高的操作,没必要对每个像素都做8次……


有什么高招也介绍介绍啊?
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-1-20 12:41

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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