1

我正在尝试实现如下所示的斜坡效果:( 来源:splashdamage.com

基于分布模式混合纹理很容易。基本上,就是这个(HLSL):

Result = lerp(SampleA, SampleB, DistributionPatternSample);

哪个有效,但没有坡道。 http://aaronm.nuclearglory.com/private/stackoverflow/result1.png

我的第一个猜测是加入“斜坡因子”我可以这样做:

Result = lerp(A, B, (1.0f - Ramp)*Distribution);

但是,这不起作用,因为如果 Ramp 也是 1.0,则结果将为零,导致只使用“A”。这就是当 Ramp 为 1.0f 时使用该方法得到的结果:http: //aaronm.nuclearglory.com/private/stackoverflow/result2.png

我试图将斜坡与分布相乘,这显然是不正确的。(认为​​值得一试并尝试发现有趣的效果。没有发现有趣的效果。)

我还尝试从分布中减去斜坡,如下所示:

Result = lerp(A, B, saturate(Distribution - Ramp));

但问题在于渐变是为了控制混合的锐度。所以,这也没有真正做任何事情。

我希望有人能告诉我我需要做什么才能在数学上做到这一点。我试图避免分支,因为这是着色器代码。我可以通过将结果相乘来模拟分支,但我不想这样做。我也希望有人可以向我解释为什么数学是以锐度的方式制定的。在不知道如何使用数学的情况下乱扔数学可能会很麻烦。

对于上下文,该顶部图像是从这里拍摄的: http://wiki.splashdamage.com/index.php/A_Simple_First_Megatexture

我了解 MegaTextures(剪辑贴图方法)和虚拟纹理(更高级的方法)如何工作得很好。所以我不需要任何解释。我只是想在着色器中实现这种特殊的混合。

作为参考,这是我正在使用的分布模式纹理。
http://aaronm.nuclearglory.com/private/stackoverflow/distribution.png

4

1 回答 1

1

它们的斜坡宽度本质上只是分布图上的对比度变化。一个粗略的版本是一个简单的重新缩放和钳位。

我们想要保留的是 0.5 映射到 0.5,并且纹理在宽度为 w 的区域上从 0 变为 1。

这给

x = 0.5 + (x-0.5)/w

这意味着最终的 HLSL 将如下所示:

Result = lerp(A, B, clamp( 0.5 + (Distribution-0.5)/w, 0, 1) );

现在,如果这最终在边缘看起来参差不齐,您可以切换到使用平滑步。在这种情况下,你会得到

Result = lerp(A, B, smoothstep( 0.5 + (Distribution-0.5)/w, 0, 1) );

然而,这里要记住的一件事是,这种类型的阈值处理最适合平滑分布模式。我不确定你的是否足够光滑(除非那是大型纹理的小版本,在这种情况下你可能没问题。)

于 2012-07-27T01:35:26.843 回答