아래는 내 Value Noise 구현이며, 지형 생성에 사용하고 있습니다. 지형의 길이 (Y 크기)가 너비 (X 크기)보다 길면 이상한 아티팩트가 생성되지만 그렇지 않은 경우에는 이상한 아티팩트가 생성됩니다.다른 모든 행을 고정하는 것은 값 소음 알고리즘 구현에서 옮겨 놓습니다.
나는 몇 시간 동안 이것을보고있었습니다. 이 문제의 원인은 무엇입니까?
합니다 (demo에서 스크린 샷 당신이 할 수있는 브라우저 콘솔에서 코드를 엉망 아래 코드 뒤에 THREE.Terrain.Value = ValueNoise; rebuild();
으로 바꾸어 결과를 즉시 참조하십시오.).
1 : 1 화면 비율 :
1 : 1.1 종횡비 :
/**
* Generate a heightmap using white noise.
*
* @param {Vector3[]} g The terrain vertices.
* @param {Object} options Settings
* @param {Number} scale The resolution of the resulting heightmap.
* @param {Number} segments The width of the target heightmap.
* @param {Number} range The altitude of the noise.
* @param {Number[]} data The target heightmap.
*/
function WhiteNoise(g, options, scale, segments, range, data) {
if (scale > segments) return;
var i = 0,
j = 0,
xl = segments,
yl = segments,
inc = Math.floor(segments/scale),
k;
// Walk over the target. For a target of size W and a resolution of N,
// set every W/N points (in both directions).
for (i = 0; i <= xl; i += inc) {
for (j = 0; j <= yl; j += inc) {
k = j * xl + i;
data[k] = Math.random() * range;
/* c b *
* l t */
var t = data[k],
l = data[ j * xl + (i-inc)] || t, // left
b = data[(j-inc) * xl + i ] || t, // bottom
c = data[(j-inc) * xl + (i-inc)] || t; // corner
// Interpolate between adjacent points to set the height of
// higher-resolution target data.
for (var lastX = i-inc, x = lastX; x < i; x++) {
for (var lastY = j-inc, y = lastY; y < j; y++) {
if (x === lastX && y === lastY) continue;
var px = ((x-lastX)/inc),
py = ((y-lastY)/inc),
r1 = px * b + (1-px) * c,
r2 = px * t + (1-px) * l;
data[y * xl + x] = py * r2 + (1-py) * r1;
}
}
}
}
// Assign the temporary data back to the actual terrain heightmap.
// Accumulate additively across multiple calls to WhiteNoise.
for (i = 0, xl = options.xSegments + 1; i < xl; i++) {
for (j = 0, yl = options.ySegments + 1; j < yl; j++) {
k = j * xl + i;
g[k].z += data[k] || 0;
}
}
}
/**
* Generate random terrain using value noise.
*
* The basic approach of value noise is to generate white noise at a
* smaller octave than the target and then interpolate to get a higher-
* resolution result. This is then repeated at different resolutions.
*
* @param {Vector3[]} g The terrain vertices.
* @param {Object} options Settings
*/
ValueNoise = function(g, options) {
// Set the segment length to the smallest power of 2 that is greater
// than the number of vertices in either dimension of the plane
var segments = Math.max(options.xSegments, options.ySegments) + 1, n;
for (n = 1; Math.pow(2, n) < segments; n++) {}
segments = Math.pow(2, n);
// Store the array of white noise outside of the WhiteNoise function to
// avoid allocating a bunch of unnecessary arrays; we can just
// overwrite old data each time WhiteNoise() is called.
var data = new Array(segments*(segments+1));
// Layer white noise at different resolutions.
var range = options.maxHeight - options.minHeight;
for (var i = 2; i < 7; i++) {
WhiteNoise(g, options, Math.pow(2, i), segments, range * Math.pow(2, 2.4-i*1.2), data);
}
// Clamp and stretch the results
THREE.Terrain.Clamp(g, {
maxHeight: options.maxHeight,
minHeight: options.minHeight,
stretch: true,
});
};
나는 인터넷을 사랑합니다. [Committed] (https://github.com/IceCreamYou/THREE.Terrain/commit/eef8f9002e51e3d419c83f7ac03142f6ed82e029), 감사합니다. 나는 fencepost 오류에 대해 잘 모르겠지만 내가 잠시를 조사 할 것입니다. – IceCreamYou
나는 또한 fencepost에 대해 100 % 확신하지는 않지만 조금 좋아 보인다. 예를 들어, 보조 행렬의 크기가 64 인 경우 인덱스 0과 64에서 두 경계를 모두 사용합니다. 즉, 양방향으로 65 개의 배열이 필요하며 평면 인덱스를 계산할 때 65를 사용해야합니다. 지표는 두 번째 이미지에서 고독한 스파이크가 될 수 있습니다.이 스파이크는 가까운 가장자리에서 이상한 랩 어라운드처럼 보입니다. –
아무리 노력해도 fencepost 오류를 얻을 수 없었습니다. 그런데'data'에'Float32Array'를 사용하고 유물을 얻었으므로 여러분이 제안한 크기로 만들었고 다시 작동하기 시작했습니다. 그래서 두 번 감사드립니다. :-) ([commit] (https://github.com/IceCreamYou/THREE.Terrain/commit/0e8ca7903507f4a7d08898fa925425c3373cd983)) – IceCreamYou