You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Perlin噪声平滑函数问题:JS动画模拟网格衔接异常排查

Perlin噪声网格衔接问题修复方案

核心问题分析

导致网格无法平滑衔接的关键问题有三个:

  • 固定fade参数:使用全局固定的FADE = .5作为fade函数输入,但Perlin噪声要求fade参数是区块在当前网格内的相对坐标(x/y方向0~1的动态值),固定值会让所有区块的插值权重一致,完全失去跨网格的平滑过渡能力。
  • 错误的向量归一化:对区块到网格顶点的偏移向量做了归一化,丢失了偏移的距离信息,导致点积无法正确反映位置差异,破坏平滑插值的基础。
  • 区块位置引用错误:遍历所有网格时,始终使用第一个网格的区块坐标BLOCK_LIST[0][k],导致不同网格内的区块计算逻辑完全一致,无法体现位置差异。

分步修复代码

1. 动态计算每个区块的fade参数

移除全局FADE变量,针对每个区块计算其在当前网格内的相对x、y坐标,生成横向和纵向的fade值:

// 移除全局的var FADE = .5;

// 在calculate函数中,先计算网格单元大小
const gridCellSize = GRIDSIZE / (VECTOR_COUNT - 1);

// 遍历区块时,计算当前区块的相对坐标
const blockX = BLOCK_LIST[i][k].senterX * (GRIDSIZE/100);
const blockY = BLOCK_LIST[i][k].senterY * (GRIDSIZE/100);
const relX = blockX / gridCellSize; // 转换为0~1的相对x
const relY = blockY / gridCellSize; // 转换为0~1的相对y
const fadeX = fade(relX);
const fadeY = fade(relY);

2. 修正点积计算的偏移向量

移除偏移向量的归一化步骤,直接使用原始偏移量计算点积:

// 以j=0(左上角顶点)为例,其他方向同理修改
if(j === 0) {
  const x = BLOCK_LIST[i][k].senterX * (GRIDSIZE/100);
  const y = BLOCK_LIST[i][k].senterY * (GRIDSIZE/100);
  dotList0.push(DOT(vector[j].angle, x, y));
} else if(j === 1) {
  const x = gridCellSize - BLOCK_LIST[i][k].senterX * (GRIDSIZE/100);
  const y = BLOCK_LIST[i][k].senterY * (GRIDSIZE/100);
  dotList1.push(DOT(vector[j].angle, -x, y));
} else if(j === 2) {
  const x = BLOCK_LIST[i][k].senterX * (GRIDSIZE/100);
  const y = gridCellSize - BLOCK_LIST[i][k].senterY * (GRIDSIZE/100);
  dotList2.push(DOT(vector[j].angle, x, -y));
} else if(j === 3) {
  const x = gridCellSize - BLOCK_LIST[i][k].senterX * (GRIDSIZE/100);
  const y = gridCellSize - BLOCK_LIST[i][k].senterY * (GRIDSIZE/100);
  dotList3.push(DOT(vector[j].angle, -x, -y));
}

3. 修复区块位置引用错误

将所有BLOCK_LIST[0][k]替换为当前网格的BLOCK_LIST[i][k],确保每个网格使用自己的区块坐标:

// 原错误代码
var x = BLOCK_LIST[0][k].senterX * (GRIDSIZE/100)

// 修改后
var x = BLOCK_LIST[i][k].senterX * (GRIDSIZE/100)

4. 修正双线性插值逻辑

使用动态计算的fadeX和fadeY分别进行横向和纵向插值:

// 建议将每个区块的fadeX、fadeY与dot值关联存储,示例如下(需根据实际数据结构调整)
for (var k = 0; k < DOT_LIST[0].length; k++) {
  // 假设已为每个区块存储了对应的fadeX和fadeY
  const fadeX = ...;
  const fadeY = ...;
  
  const topLerp = lerp(DOT_LIST[0][k], DOT_LIST[1][k], fadeX);
  const bottomLerp = lerp(DOT_LIST[2][k], DOT_LIST[3][k], fadeX);
  const finalValue = lerp(topLerp, bottomLerp, fadeY);
  
  // 调整normalize的范围,适配未归一化的点积值
  var color = Math.floor(normalize(finalValue, gridCellSize, -gridCellSize) * 255);
  colorList.push(color);
}

修复后验证

修复完成后,每个区块会根据自身在网格内的位置动态计算插值权重,相邻网格的边缘区块会共享顶点向量,从而实现跨网格的平滑过渡,解决衔接断裂的问题。

内容的提问来源于stack exchange,提问作者noodle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 23:32:03