Open campbellgoe opened 5 years ago
The Perlin generator is defined here:
The Simplex generator is defined similarly.
You can define your own generator which passes different values to noise.perlin()
or noise.simplex()
.
In the provided generators, the X/Y values passed to those functions are i / divisor, j / divisor
. i
/j
are the X/Y indices, respectively, of the vertex whose height is being calculated. divisor
essentially defines the scale of the features in the generated noise. For your use case you would probably just want to pass different values of i
/j
depending on the location of the affected tile relative to your origin tile.
The other thing to pay attention to is that every call to THREE.Terrain.Perlin()
or THREE.Terrain.Simplex()
currently re-seeds noise
. If you were to write your own generator method, you would want to only seed noise
once rather than on each call.
Thanks. I figured that was the correct bit of code to add the offset, and that the random needed to remain the same for each tile.
Although somehow still have a seam, as seen here:
But that's probably a problem with my implementation.
For example
Terrain.simplex(
(i + ox * (options.xSegments + 1)) / divisor,
(j + oy * (options.ySegments + 1)) / divisor
) * range;
Where ox, oy are offsets such as (-1,-1), (0,-1), (1, -1), (-1, 0)...
i and j go from 0
through options.xSegments + 1
, so I am assuming perfect offsets will be multiples of options.xSegments + 1
, however as seen in the image above, there are very small seams.
If the logic above is correct (which I'm not sure about) then it likely means a bit of variation may be arising due to a random seed being improperly set/not set.
It could be due to do with the height range, if one tile/chunk has a different natural height range, could it be being distorted on the y axis relative to other tiles/chunks?
Sorry for asking questions here, if there's a better place, I'd be happy to ask there instead.
Make sure you are passing in exactly the same arguments to noise.simplex for vertices that should have identical locations. My guess is there’s a floating point precision issue somewhere in your code. If you had a seeding issue, the edges of your tiles would not come close to lining up. It seems more likely that you are just passing in X/Y offsets that are very slightly different than expected.
On Jul 28, 2019, at 11:59 PM, George Campbell notifications@github.com wrote:
For example
Terrain.simplex( (i + ox (options.xSegments + 1)) / divisor, (j + oy (options.ySegments + 1)) / divisor ) * range; Where ox, oy are offsets such as (-1,-1), (0,-1), (1, -1), (-1, 0)... i and j go from 0 through options.xSegments + 1, so I am assuming perfect offsets will be multiples of options.xSegments + 1, however as seen in the image above, there are very small seams. If the logic above it correct (which I'm not sure about) then it likely means a bit of variation may be arising due to a random seed being improperly set/not set. Sorry for asking questions here, if there's a better place, I'd be happy to ask there instead.
— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub, or mute the thread.
I've done as much as I could to ensure the x,y inputs for the noise function were correct and each chunk edge had the same correct corresponding x,y coords. However, I was still unable to get the chunks perfectly connecting.
Here is a 2x2 grid of 1024x1024 terrains with 15x15 segments, and this gives me these results:
I find this very odd, as surely the noise function should output the same values for the same x,y coordinates.
I think a solution so I can move on would be to just snap these edges together, and that shouldn't be noticeable.
I think a solution so I can move on would be to just snap these edges together, and that shouldn't be noticeable.
That's what I would do. That said, I'd still be willing to bet that the arguments you're passing to noise.simplex
are very slightly different for vertices that should be at the same X/Y coordinates due to floating point precision issues. The only way to know would be to log the those values.
(Or is it possible there's some other generator or something else other than the simplex generator that's affecting the points on your terrain plane?)
After setting each seams / edge verticies Z all to 0, I get this:
Whereas setting the edge seams Z to 100 removes the seam.
Seam begins to appear somewhere between 92 and 93 z. Setting the edge verticies to less than this amount makes the seam appear.
Could it be due to Clamp ?
* Rescale the heightmap of a terrain to keep it within the maximum range.
...
function Clamp(g, options) {
...
for (i = 0; i < l; i++) {
g[i].z = options.easing((g[i].z - min) / actualRange) * range + optMin;
}
}```
Yes, disabling Clamp in the Normalize function fixed it. The seams are no more!
Good catch! Clamp
does indeed rescale / stretch the terrain vertically, so if your max or min Z values are different on the different terrains, it would make the edges misaligned. Without Clamp
, you don't get easing
, and depending on the generation function used you could end up with values outside of the desired max/min Z-values. However there should probably be a way to disable it for use cases like this!
A related issue I am getting is with the shading/shadows as seen below in the sand version:
In addition to what I mentioned in #27, there's probably an additional factor here around how the shadow interpolation works. Honestly I don't really understand the details and haven't spent much time looking at it since 2014, but I think that the shadows are vertex based and so the calculations won't come out the same for edge vertices with significantly different slopes on either side. Fixing this probably requires using different shadow fragments which might require using a different base texture.
I found a solution to shadow seams thanks to thrax.
The idea is to generate terrain with the outer segments overlapping the other tiles, then computeVertexNormals, and finally to trim the excess segments so the tiles no longer overlap.
In other words:
This ensures the shadows take into account neighbouring vertexes at tile extremes.
Good idea!
Terrain.simplex( (i + ox * (options.xSegments + 1)) / divisor, (j + oy * (options.ySegments + 1)) / divisor ) * range;
Where ox, oy are offsets such as (-1,-1), (0,-1), (1, -1), (-1, 0)... i and j go from
0
throughoptions.xSegments + 1
, so I am assuming perfect offsets will be multiples ofoptions.xSegments + 1
, however as seen in the image above, there are very small seams. If the logic above is correct (which I'm not sure about) then it likely means a bit of variation may be arising due to a random seed being improperly set/not set.
Did you ever finished your project? I'm struggling at the moment with making it seamless:
I tried with your noise modification:
g[j * xl + i] += noise.simplex((i + options.offsetX * (options.xSegments + 1)) / divisor, (j + options.offsetY * (options.ySegments + 1)) / divisor) * range;
But no luck at all...
THREE.Terrain.Simplex = function(g, options) {
noise.seed(options.seed);
var range = (options.maxHeight - options.minHeight) * 0.5,
divisor = (Math.min(options.xSegments, options.ySegments) + 1) * 2 / options.frequency;
for (var i = 0, xl = options.xSegments + 1; i < xl; i++) {
for (var j = 0, yl = options.ySegments + 1; j < yl; j++) {
g[j * xl + i] += noise.simplex((i + options.offsetX * (options.xSegments + 1)) / divisor, (j + options.offsetY * (options.ySegments + 1)) / divisor) * range;
}
}
};
I also removed the Clamp function, like you commented on here and I'm using the following options:
const options = {
easing: THREE.Terrain.Linear,
heightmap:THREE.Terrain.Simplex,
steps: 2,
xSegments: 127,
ySegments: 127,
maxHeight: 200,
stretch:false,
offsetX:tileX,
offsetY:tileY,
minHeight: -100,
seed:0.7281564856921896,
xSize: 1024,
ySize: 1024,
}
Edit: I think it has to do with the steps.
Yes, the problem is at stepping.
These two have exactly the same settings, except step
, I'm variating it from 1 to 2.
Any ideas on how to make it seamless? And using something like step
, which creates more desired results.
I think the problem lays here: https://github.com/IceCreamYou/THREE.Terrain/blob/5de9c5ca8a6f5604010a0cab913a83b362145cbe/src/filters.js#L337
So, I replaced the Step
function with one of my own that does not require neighborhood checking, cause that's what messes it up when you divide it in chunks; you don't know who your neighborhood is unless you load it, but that doesn't work cause it's an infinite cycle.
Made it really rough, will post it when I have it cleaned up.
Feature request:
It would be great to be able to set an x and y offset for perlin / simplex noise, and potentially other noise functions.
The usage in my case would be to create tiles of THREE.Terrain, each positioned next to each-other, with the same simplex noise seed, but with its x, y axes offset so they match the position, and the edges of the tiles match up. Then you will be able to create many tiles of terrain, loading nearby tiles and unloaded distance tiles.
I did try to implement this by just adding an offsetX and offsetY in the simplex function, but the results were not as expected and I wasn't sure how to do this.
Thanks.