1
\$\begingroup\$

I have a hexagonal grid of fields, each field has a certain terrain type. I assign every vertex of hexagon with terrain type and pass it as attribute to vertex and then fragment shader. Then I use the extrapolated value to blend terrain textures together.

For instance: 1 is grassy, 2 is desert.

Vertex shader:

varying vec2 vUv;
attribute float terrainType;
varying float vTerrainType;

void main()
{
   vUv = uv;
   vTerrainType = terrainType;
   vec4 mvPosition;
   mvPosition = modelViewMatrix * vec4( position, 1.0 );
   gl_Position = projectionMatrix * mvPosition;
}

Fragment shader:

uniform vec3 diffuse;
uniform float opacity;
varying vec2 vUv;
varying float vTerrainType;
uniform sampler2D map;
uniform sampler2D map1;

void main()
{
   gl_FragColor = vec4( diffuse, opacity );
   vec4 texelColor = texture2D( map, vUv ) * (2.0 - vTerrainType) + texture2D( map1, vUv ) * (vTerrainType - 1.0);
   gl_FragColor = gl_FragColor * texelColor;
}

Implementation is WebGL, if it makes any difference.

The result looks really unnatural, so is there any way to make it smoother and rounder?

enter image description here

\$\endgroup\$
  • \$\begingroup\$ This is not procedural texturing. This is usually called terrain blending. \$\endgroup\$ – Sarge Borsch Sep 8 '15 at 17:36
1
\$\begingroup\$

As you can see, the artifact originates from the interpolation of your vTerrainType varying accross the triangles.

Thus, one possibility to fix the issue would be to subdivide the hexagons in such a way that they have a nicer defined border region of consistent thickness.

Another more complicated but more powerful method would be to compute the distance of each pixel to the border of its hexagon. However, for this you need a lot of information about the field itself - each pixel needs to determine to which hexagon it belongs and where its borders are. Once you have the distance, you can use it to perform blending. Applying functions like clamp(pow(borderDistance, someExponent)*someScale, 0.0, 1.0) to this function would allow you even smoother transitions.

\$\endgroup\$
  • \$\begingroup\$ Basically if I have the entire UV map I can know which UV coordinate belongs to which field, but for that I'll have to pass big chunks of data to fragment shader. Is that what you mean by complicated method? So basically, let's say I pass the UV coordinates of each vertex for each hexagon as uniform. Then I can know how far from the border of two terrain types the pixel is and then I can apply appropriate transformation to blend. Is that correct? \$\endgroup\$ – user1617735 Sep 9 '15 at 9:24
  • \$\begingroup\$ I am not sure what you mean with UV data - I thought the texture coordinates are repeating independently of the terrain type? What I meant was, that you could upload the field sizes, the field position and a map of all field-types (probably as a texture). This would allow every pixel not only to compute its own field type but also the field types of its neighbors and how far they are away. \$\endgroup\$ – Wumpf Sep 9 '15 at 9:42
  • \$\begingroup\$ More and better answer would be great, I am also not very satisfied with my proposed solutions. \$\endgroup\$ – Wumpf Sep 9 '15 at 9:45
  • \$\begingroup\$ Terrain textures are not repeating independently, because the hexes are not equally sized in reality. The image I've linked was just a hexagon map on plane just to test the shader. In reality the hexagons are on a sphere and they are not equally sized. The geometry is also UV mapped and one texture for each terrain type is used for each terrain type. Each field also has terrain type assigned to it. I've mentioned UV map, because it would be much easier to operate distance in UV units, rather than coordinates in 3D. That way I'll be able to know which pixel would belong to which hex. \$\endgroup\$ – user1617735 Sep 9 '15 at 10:32
  • \$\begingroup\$ Finally implemented this solution, even though I still have weird artifacts on some of the edges, because it seems like distance to border of desert isn't calculated correctly, it looks much better than my previous shot. Although hexagonal origin of the map is still pretty apparent and doesn't look completely natural, as you can see. Question is, can I improve this further by "curving" the edges some futher more? See attached image for reference ---> prntscr.com/8iebge \$\endgroup\$ – user1617735 Sep 20 '15 at 11:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.