0

I have this geometry: Picture

I want to add the same effect that mountains are with snow texture and so on:
Texture splatting with Three.js

Little background what info I give to shaders from 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);

Vertex and fragment shaders:

//vertexShader:
varying vec2 vUV;

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

I get full red model with this:

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

I want textures that are higher with snowTexture and lower with 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;

isostart1
  • 9
  • 1
  • 5
  • What is the content of `bumpTexture`? Does it contain normal vectors and/or displacement height? If it is a plane geometry, then you can do. `newPosition = position + normalize(bumpnormal) * bumpheight);`. This will work if the geometry consists of a tessellated plane and the normal vector of the plane in model space is (0, 0, 1). More exact, if the normal vectors from the map are in model space. – Rabbid76 May 15 '19 at 05:02
  • Basically i want the vertexshader to go through all the already created vertices, not move them anywhere, right now when I applied it, it creates a whole new set of vertices. BumpTexture contains my texture from three.js that I loaded with loader function – isostart1 May 15 '19 at 12:52
  • It's very hard to understand what you mean in OP and what you mean by "go through all vertices", I suggest that you edit your post and try to make it more clear. The link you provided uses a texture as a displacement map to controls the height of the vertices. If this is not what you want, then perhaps this is not a good starting point. – ScieCode May 15 '19 at 14:37
  • 1
    Okay, I changed it, maybe now you can understand better. – isostart1 May 15 '19 at 15:08

1 Answers1

1

This really not that hard to understand, let me walk you through the logic.

In your case, you don't want to use a displacement map. So, you need to set up a varying height on your vertexShader to map your vertices up-coordinates [0,1] to your 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 );

}

Now you can access height from your fragmentShader and use that information to select where you want your transitions to occur.

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;

}

The link provided uses function smoothstep to make a gradual transition between the textures. We can create transitions using the follow pattern ( a - b ) * textureColor.

In this case, a controls when the texture starts to contribute to the fragment color. b controls when the texture stops contributing.

In other words, your grass texture will have already started contributing at every height, so we map a to 1.0. It stops contributing around 0.5, so we give b a smooth fade-out as it approaches that 0.5.

Your snow texture, on the other hand, will only start contributing around 0.5. So, we give a a smooth fade-in as it approaches 0.5. It will never stop contributing, so we set b as 0.0.

Hope this clears things up for you.

ScieCode
  • 1,706
  • 14
  • 23
  • Glad I was able to help. – ScieCode May 15 '19 at 18:03
  • I have a follow up question, how can I make it that sand start from 0 and goes to 10% height, grass takes over to 40% and so on to the top, not value, because every time I make my mountains taller, the textures is just like one is like 99% the other is for 1%. I made my z heights to always start from 0. In the link example, he bumps up the scale and it seems like the % of textures stay the same.. – isostart1 May 16 '19 at 16:37
  • You are correct, we are mapping the % manually. Since you don't want the displacement map. This needs to be updated every time you change the maximum height of your geometry. You could pass a maxHeight uniform from your .js code to inform these changes, instead of having to alter inside the GLSL – ScieCode May 16 '19 at 16:41
  • to map a new texture, you use the same pattern I specified above. `sand = ( 1.0 - smoothstep( 0.38, 0.42, height) ) * texture2D`. Then you need to update your the grass texture to only start at 40%. I suggest that you experiment with the pattern I provided, I won't be able to keep helping indefinitely. – ScieCode May 16 '19 at 16:44
  • 1 last question, i get the sand part and that, but when i bring it my uniform with value do i need to ```height= position.z/ value. – isostart1 May 16 '19 at 16:55
  • I dont get the min and max too i removed it and it did nothing :D only add some square looking meshes not smooth. okay thanks i dont bother you anymore :) – isostart1 May 16 '19 at 16:56