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:
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).


