Skip to main content
deleted 22 characters in body
Source Link
Figwig
  • 196
  • 1
  • 11
vec3 randomVec3(vec2 xy, int seed)
{
 
  seed*=3;
  return vec3(gold_noise(xy, seed * 3), gold_noise(xy, seed * 3 +1), gold_noise(xy, seed *3 +2));
}
vec3 randomVec3(vec2 xy, int seed)
{
 
  seed*=3;
  return vec3(gold_noise(xy, seed * 3), gold_noise(xy, seed * 3 +1), gold_noise(xy, seed *3 +2));
}
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));
}
Added more code and an addtional image, plus better formatting on the code
Source Link
Figwig
  • 196
  • 1
  • 11

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

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

Source Link
Figwig
  • 196
  • 1
  • 11

Random world Points in GLSL for tree placement

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)
{

  seed*=3;
  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!