使用 Three.js 绘制纹理

发布于 2025-01-20 09:20:38 字数 103 浏览 3 评论 0原文

纹理泼溅可以与 Three.js 或其他 Javascript 3D 渲染框架一起使用吗?如果是的话,我想看看示例,甚至是大地形上的教程。如果它不起作用,还有其他方法绘制大地形图吗? 谢谢。

Does texture splatting works with Three.js or other Javascript 3D rendering framework? If yes I'd like to see example maybe even tutorial on large terrain. If it doesn't work is there any other way mapping large terrains?
Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

指尖凝香 2025-01-27 09:20:38

已接受的挑战!

首先,您可以编写一个灰度图像并将其用作高度图的顶点着色器,并包含不同的浮点(称为vamount)以传递到片段着色器以确定纹理(s)在这一点上显示(混合)。

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 );
}

接下来是片段着色器,它可以包括不同的高程所需的许多纹理,并且有一个很棒的内置功能,称为smookestep,使平滑过渡更易于计算。

这样的片段着色器的代码示例:

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;
}  

然后,您可以使用trex.shadermaterial将其用于给定的网格。以上代码在

​这可以帮助您入门。愉快的编码!

Challenge accepted!

First, you can write a vertex shader that takes a grayscale image and uses it as a heightmap, and includes a varying float (called vAmount below) to pass to the fragment shader to determine the texture(s) to display(blend) at that point.

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 );
}

Next comes the fragment shader, which can include however many textures you need for different elevations, and there is a great built-in function called smoothstep that makes smooth transitions much easier to calculate.

An example of code for such a fragment shader:

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;
}  

Then you can use a THREE.ShaderMaterial to use this for a given mesh. The above code is implemented at http://stemkoski.github.io/Three.js/Shader-Heightmap-Textures.html and produces a result like this:

enter image description here

Hope this helps you get started. Happy coding!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文