0
\$\begingroup\$

I'm doing tree placement in the geometry shader in GLSL. I've made a seeded random vec3 function based on gold noise that looks like this:

vec3 randomVec3(vec2 xy, int seed)
{
  return vec3(gold_noise(xy, seed * 3), gold_noise(xy, seed * 3 +1), gold_noise(xy, seed *3 +2));
}

This works, but generates strange patterns in the trees. I can't find anything on making random numbers that isn't based on the fragment coord and unseeded - each run of the geo shader needs to generate 15~ random vec3s for trees based on a seed (area on the planet combined with an index for each tree). Here is my results so far:

enter image description here

enter image description here

You can see the diagonal patterns going through the tree clusters. This is what I want to reduce.

Thanks!

Edit: Here is my code that places trees in full

float gold_noise(in vec2 xy, in float seed)
{
    return fract(tan(distance(xy*PHI, xy)*seed)*xy.x);
}




void drawInstanceOnSphere(vec4 worldPos, vec2 sphericalCoords)
{
  //...Draws an instance at the correct height and rotation based on the 
world position and spherical coords of the desired instance
}

//Generates a psuedo random vec3 based on a coord and a seed
vec3 randomVec3(vec2 xy, int seed)
{
return vec3(gold_noise(xy, seed * 3), gold_noise(xy, seed * 3 +2), gold_noise(xy, seed *3 +4));
}

//Places a set of trees
void placeTrees()
{
  //All following code assumes planet positon of 0,0,0, and no planet rotation
  //Find the point on the planet closest to the camera
  vec4 closestPoint = normalize(cameraPos) * radius;

  // if the surface is close enough
  if(distance(closestPoint, cameraPos) < 3000)
  {
    //Tree placement is based off this mechaninsim - a geo shader can draw 15
 trees per run before it becomes inefficient. Divide the spherical coords by 1000
 to generate a 1000x1000 grid across the planet. Each point becomes a new seed - 
all trees will look the same in this "quadrant". This mean each shader run can 
increase their own seed offset by 1 for each tree. I can then run 9 instances on 
this shader, choosing the 9 closest "quadrants" to the player.


    //What are we dividing the spherical coords from ?
    float quadrantDiff = 1000;

    //Quadrant.xy is fed from the C++ code. Centre of the world map would be 0.5, 0.5
    vec2 quadrantCoord = quadrant.xy;

    //Get our world point from this coord. Centre of the world map with radius 3150 and origin 0,0,0 would be 0,0,-3150
    vec4 quadrantWorldPoint = (vec4(getWorldPoint(quadrantCoord),0));

    //Draw 15 trees
    for (int treeCount = 0; treeCount < 15; treeCount++)
    {
      //Range number - is fudge, looks okay
      float range = 8000 / quadrantDiff;

      //Position of the tree is the quadrantCentre point plus a random vec3,
 then normalized and multiplied by the radius to place it on the sphere. 
Additional height to match terrain is added in the "draw on sphere" method

      vec4 treePos = normalize(quadrantWorldPoint + range *  (vec4(2.0 * randomVec3(quadrantCoord, int( treeCount + 15 * seedOffset)) - vec3(1),1))) * radius;

      //Get the tree's spherical coord for heightmap lookup
      vec2 treeCoord = getAdjustedTexCoord(getTexCoordFromPos(treePos));
      //Draw this tree
      drawInstanceOnSphere(treePos, treeCoord);
    }
  }

}

Here is another image showing the diagonal lines being worse. The centre quad seed for this image is (0.532, 0.532).

enter image description here

\$\endgroup\$
6
  • 2
    \$\begingroup\$ Can you show us your gold noise function? \$\endgroup\$ Commented Mar 6, 2020 at 23:34
  • \$\begingroup\$ Yes - it's this one stackoverflow.com/a/28095165/5438234. I haven't changed the function \$\endgroup\$ Commented Mar 7, 2020 at 11:40
  • \$\begingroup\$ I'd like to reproduce this problem so I can test potential solutions, but to do that I'll need to see how you use this random function to choose tree locations. How do you vary the inputs between calls, and what do you use the three output values for? \$\endgroup\$ Commented Mar 7, 2020 at 13:28
  • \$\begingroup\$ I'll update the question now with my full positional code :) \$\endgroup\$ Commented Mar 7, 2020 at 13:32
  • \$\begingroup\$ Is there a particular reason you are using the gold noise? The author makes some claims, but doesn't link to any supporting evidence. For something like this I would go with Poisson disc sampling + Perlin or Simplex noise; for example. \$\endgroup\$ Commented Mar 9, 2020 at 14:14

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.