DirectX11:基于高度的纹理混合

时间:2015-12-17 21:35:21

标签: c++ directx texture-mapping direct3d11

我目前在我的地形项目中使用斜率量混合了3个纹理。我这样做是通过对每个纹理进行采样,确定斜率并根据两个纹理之间的lerp设置纹理颜色。这是我的像素着色器的片段:

static const float TEX_LOW_BOUND    = 0.4f;
static const float TEX_HIGH_BOUND   = 0.7f; 

...    

float4 texColour;
float4 lowColour = lowerTex.Sample(SWrap, pin.Tex);
float4 midColour = middleTex.Sample(SWrap, pin.Tex);
float4 hiColour  = upperTex.Sample(SWrap, pin.Tex);
float slope      = 1.0f - pin.Normal.y;

if (slope < TEX_LOW_BOUND)
{
    texColour = lerp(lowColour, midColour, slope / TEX_LOW_BOUND);
}
else if (slope >= TEX_LOW_BOUND && slope < TEX_HIGH_BOUND)
{
    texColour = lerp(midColour, hiColour, (slope - TEX_LOW_BOUND) * (1.0f / (TEX_HIGH_BOUND - TEX_LOW_BOUND)));
}
else if (slope >= TEX_HIGH_BOUND)
{
    texColour = hiColour;
}

我想添加一个最终的雪纹理,以适用于一定高度。我使用:

在顶点着色器中获取高度值
vout.WHeight = mul(vin.Pos, worldMatrix).y;

然后我可以在我的像素着色器中使用此设置将纹理颜色设置为高于某个高度的雪:

if (pin.WHeight > 35.0f)
{
    texColour = snowTex.Sample(SWrap, pin.Tex);
}

产生以下内容:

Snow above a certain height

如何将雪的边缘与其他纹理混合,以使边缘不那么刺耳。请记住,其他纹理可能已经被剔除,我想保持纹理颜色。

感谢您的时间

1 个答案:

答案 0 :(得分:1)

你可以在添加雪帽的颜色时基本上做同样的事情,但你需要的是一个远程输入来确定它是否接近边缘。有几种方法可以做到这一点。一种方法可以是将像素值与颜色加法或减法相混合,然后在颜色值的范围内进行归一化。另一种是应用多个纹理混合。正如您在if (pin.WHeight > 35.0f) 上面的条件中所述,我们知道35.0f是开始应用雪纹理之前的最大高度值。根据您的预期结果,您的基于范围的输入可能类似于:if ( height > 34.8f && height < 35.2f ) { apply texture blending or color blending; }

另一种方法是使用相同的范围输入在原始图层顶部使用透明度渐变图层的alpha值来生成所需的输出。

这种方法或算法的唯一之处在于它可能看起来不像您想要的那样逼真。这是因为所有的雪帽都具有完全相同的高度值,从而创造了一个不切实际的边界。

与原始方法接近的建议可能会更好。将纹理或颜色应用于雪帽时,您可以使用非确定性算法,在最小范围内随机选择特定高度以应用纹理 - 纹理混合,然后在特定高度以上的任何内容将平滑为纯白色。这样每个山顶都会有一个白色的帽子,但并不是所有的高度在下限都是一样的。

相关问题