使用 Three.js 产生纹理 [英] Texture splatting with Three.js

查看:26
本文介绍了使用 Three.js 产生纹理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

纹理拼贴是否适用于 Three.js 或其他 Javascript 3D 渲染框架?如果是的话,我想看示例,甚至可能是大地形上的教程.如果它不起作用,还有其他方法可以绘制大型地形吗?谢谢.

解决方案

接受挑战!

首先,您可以编写一个顶点着色器,它采用灰度图像并将其用作高度图,并包含一个可变的浮点数(下面称为 vAmount)以传递给片段着色器以确定纹理(s) 在那个时候显示(混合).

uniform sampler2D bumpTexture;统一浮动凹凸比例;变化的浮动 vAmount;不同的 vec2 vUV;无效主(){vUV = 紫外线;vec4 凹凸数据 = 纹理 2D(凹凸纹理,紫外线);vAmount = 凹凸数据.r;//假设地图是灰度的,使用 r、g 或 b 都没有关系.//沿法线移动位置vec3 newPosition = 位置 + 正常 *bumpScale * vAmount;gl_Position = 投影矩阵 * 模型视图矩阵 * vec4( newPosition, 1.0 );}

接下来是片段着色器,它可以包含不同高度所需的多种纹理,并且有一个很棒的内置函数 smoothstep 可以使平滑过渡更容易计算.

此类片段着色器的代码示例:

uniform sampler2D OceanTexture;均匀采样器2D SandyTexture;统一采样器2D草纹理;统一的采样器 2D 岩石纹理;统一采样器2D雪地纹理;不同的 vec2 vUV;变化的浮动 vAmount;无效主(){vec4 water = (smoothstep(0.01, 0.25, vAmount) - smoothstep(0.24, 0.26, vAmount)) * texture2D(海洋纹理,vUV * 10.0);vec4 sandy = (smoothstep(0.24, 0.27, vAmount) - smoothstep(0.28, 0.31, vAmount)) * texture2D(sandyTexture, vUV * 10.0);vec4 草 = (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) + 水 + 沙地 + 草 + 岩石 + 雪地;}

然后您可以使用 THREE.ShaderMaterial 将其用于给定的网格.以上代码在http://stemkoski.github.io/Three 实现.js/Shader-Heightmap-Textures.html 并产生如下结果:

希望这可以帮助您入门.快乐编码!

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.

解决方案

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:

Hope this helps you get started. Happy coding!

这篇关于使用 Three.js 产生纹理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆