使用Three.js进行纹理混合

11

纹理平铺技术在Three.js或其他JavaScript 3D渲染框架中是否可行?如果是,我希望能看到大型地形的示例甚至教程。如果不可行,是否有其他映射大型地形的方法? 谢谢。


1
这里有一些相关信息:http://www.chandlerprall.com/2011/06/blending-webgl-textures/ - Stemkoski
1个回答

41

接受挑战!

首先,您可以编写一个顶点着色器,将灰度图像用作高度图,并包含一个浮点变量(下面称为vAmount),以传递给片段着色器来确定在该点显示(混合)的纹理。

uniform sampler2D bumpTexture;
uniform float bumpScale;

varying float vAmount;
varying vec2 vUV;

void main() 
{
    vUV = uv;
    vec4 bumpData = texture2D( bumpTexture, uv );

    vAmount = bumpData.r; // assuming map is grayscale it doesn't matter if you use r, g, or b.

    // move the position along the normal
    vec3 newPosition = position + normal * bumpScale * vAmount;

    gl_Position = projectionMatrix * modelViewMatrix * vec4( newPosition, 1.0 );
}

接下来是片元着色器,可以包括您需要的不同高度的纹理,还有一个很棒的内置函数叫做smoothstep,可以使平滑过渡更容易计算。

这是一个针对此类片元着色器的示例代码:

uniform sampler2D oceanTexture;
uniform sampler2D sandyTexture;
uniform sampler2D grassTexture;
uniform sampler2D rockyTexture;
uniform sampler2D snowyTexture;

varying vec2 vUV;

varying float vAmount;

void main() 
{
    vec4 water = (smoothstep(0.01, 0.25, vAmount) - smoothstep(0.24, 0.26, vAmount)) * texture2D( oceanTexture, vUV * 10.0 );
    vec4 sandy = (smoothstep(0.24, 0.27, vAmount) - smoothstep(0.28, 0.31, vAmount)) * texture2D( sandyTexture, vUV * 10.0 );
    vec4 grass = (smoothstep(0.28, 0.32, vAmount) - smoothstep(0.35, 0.40, vAmount)) * texture2D( grassTexture, vUV * 20.0 );
    vec4 rocky = (smoothstep(0.30, 0.50, vAmount) - smoothstep(0.40, 0.70, vAmount)) * texture2D( rockyTexture, vUV * 20.0 );
    vec4 snowy = (smoothstep(0.50, 0.65, vAmount))                                   * texture2D( snowyTexture, vUV * 10.0 );
    gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0) + water + sandy + grass + rocky + snowy;
}  

然后您可以使用THREE.ShaderMaterial将其用于给定的网格。上面的代码已在http://stemkoski.github.io/Three.js/Shader-Heightmap-Textures.html实现,生成以下结果:enter image description here希望这可以帮助您入门。祝编码愉快!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接