在Three.js中将纹理设置为几何

时间:2019-05-15 02:23:36

标签: three.js glsl

我有这个几何:Picture

我想添加与雪一样的山脉等效果:
Texture splatting with Three.js

背景很少,我从Three.js提供给着色器的信息是什么

//importing grass and snow textures:
var grassTexture = new THREE.ImageUtils.loadTexture( 'images/grass-512.jpg' );
grassTexture.wrapS = grassTexture.wrapT = THREE.RepeatWrapping;
var snowTexture = new THREE.ImageUtils.loadTexture( 'images/snow-512.jpg' );
snowTExture.wrapS = snowTExture.wrapT = THREE.RepeatWrapping;

this.customUniforms = {
 grassTexture:  { value: grassTexture },
 snowTexture:   { value: snowTexture },

};
var customMaterial = new THREE.ShaderMaterial({
 uniforms: customUniforms,
 side: THREE.DoubleSide,
 vertexShader:   document.getElementById( 'vertexShader'   ).textContent,
 fragmentShader: document.getElementById( 'fragmentShader' ).textContent,
});
//creating mesh, geometry is the model in picture.
mesh = new THREE.Mesh(geometry, customMaterial);

顶点和片段着色器:

//vertexShader:
varying vec2 vUV;

void main(){
 vUV = uv;
 gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}

我得到了完整的红色模特:

//fragmentShader:
void main(){
 gl_FragColor = vec4(1, 0.0, 0.0, 1.0) ;
}

我想要的纹理在snowTexture中较高,而grassTexture中较低。

uniform sampler2D grassTexture;  
uniform sampler2D snowTexture;
varying vec2 vUV;
//Something like this?:
vec4 grass = texture2D( grassTexture, vUV);
vec4 snow = texture2D( snowTexture, vUV);
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0) + grass + snow;

1 个答案:

答案 0 :(得分:0)

这确实不难理解,让我向您介绍逻辑。

在您的情况下,您不想使用置换图。因此,您需要在vertexShader上设置一个varying height,以将顶点的上坐标[0,1]映射到fragmentShader。

//vertexShader:
varying vec2 vUV;
varying float height;

void main() {

  vUV = uv;

  float maxPosition = 30.0; // this is an example value.
  height = max( 0.0, min(1.0, position.y/maxPosition ) ); // assuming +y is up

  gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );

}

现在,您可以从fragmentShader访问height,并使用该信息来选择过渡的发生位置。

uniform sampler2D grassTexture;  
uniform sampler2D snowTexture;

varying vec2 vUV;
varying float height;

void main(){

  vec4 grass = (1.0 - smoothstep( 0.48, 0.52, height)) * texture2D( grassTexture, vUV);
  vec4 snow =  (smoothstep(0.48, 0.52, height) - 0.0) * texture2D( snowTexture, vUV);

  gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0) + grass + snow;

}

提供的链接使用函数smoothstep在纹理之间进行逐步过渡。我们可以使用跟随模式( a - b ) * textureColor创建过渡。

在这种情况下,a控制纹理何时开始为片段颜色做出贡献。 b控制纹理何时停止起作用。

换句话说,您的草纹理已经开始在各个高度起作用,因此我们将a映射到1.0。它停止贡献约0.5,因此我们在b接近0.5时给予平滑的淡入。

另一方面,您的积雪纹理只会开始贡献约0.5。因此,当a接近0.5时,我们会为其提供平滑的淡入。它永远不会停止贡献,因此我们将b设置为0.0。

希望这可以为您清除一切。