Perlin noise应用于平面/球体网格及pv.sample_function相关问题咨询
针对你提出的三个PyVista Perlin噪声相关问题,解答如下:
1. 如何将Perlin噪声应用到球体网格实现轻微形变
不需要通过pv.sample_function生成网格再修改,直接对已有的球体网格逐点采样噪声、沿法向偏移即可,能保证形变是沿球体表面凹凸的自然效果:
- 先用
pv.Sphere()生成基础球体网格 - 创建Perlin噪声对象,遍历球体所有顶点坐标,调用噪声对象的
EvaluateFunction(x,y,z)方法拿到对应坐标的噪声值,存为球体的点数据 - 调用
mesh.warp_by_scalar()时开启normal=True参数,即可让球体沿自身表面法线方向按噪声值偏移,调整factor参数可以控制形变幅度。
示例代码片段:
import pyvista as pv # 生成基础球体 sphere = pv.Sphere(radius=5) # 生成低频噪声,用于球体的轻微形变 noise = pv.perlin_noise(amplitude=1, freq=(2, 2, 2), phase=(0, 0, 0)) # 逐点采样噪声值存为点数据 sphere['noise_val'] = [noise.EvaluateFunction(*point) for point in sphere.points] # 沿法线偏移得到形变球体 deformed_sphere = sphere.warp_by_scalar(scalars='noise_val', factor=0.3, normal=True) deformed_sphere.plot()
2. 能否对同一个网格多次应用Perlin噪声实现嵌套波浪效果
完全可以,这个逻辑就是分形布朗运动(FBM)噪声的核心实现思路,你不需要分别对网格应用噪声,直接把多个不同参数的Perlin噪声的采样值相加,作为最终的偏移量即可。
你给出的两个平面实现可以直接合并得到大波浪叠高细节砾石纹理的效果,示例代码如下:
# 沿用你原有代码的平滑绘制函数 def smooth_and_plot(sampled : pv.core.grid.UniformGrid): mesh = sampled.warp_by_scalar('scalars') mesh = mesh.extract_surface() # 做简单清理和平滑,减少Perlin noise伪影 mesh = mesh.smooth(n_iter=100, inplace=True, relaxation_factor=0.07) mesh.plot() def combined_bumpy_gravel_plane(): # 大波浪低频噪声 low_freq_noise = pv.perlin_noise(0.5, (0.5, 0.7, 0), (-10, -10, -10)) # 高细节砾石噪声 high_freq_noise = pv.perlin_noise(0.2, (180, 180, 50), (0, 0, 0)) # 自定义采样函数:叠加两层噪声值 def combined_noise(x,y,z): return low_freq_noise.EvaluateFunction(x,y,z) + high_freq_noise.EvaluateFunction(x,y,z) # 采样网格 sampled = pv.sample_function( combined_noise, bounds=(-10, 2, -10, 10, -10, 10), dim=(500, 500, 1) ) smooth_and_plot(sampled)
如果需要更多层的细节,继续叠加更多「频率越高、振幅越低」的噪声即可。
3. frequency参数中的第三个值的作用
Perlin噪声的frequency参数三个值分别对应x、y、z三个坐标轴方向的噪声频率,数值越高对应轴方向的噪声纹理越密。
你之前调整没看到效果,是因为你当前采样的是2D平面,dim=(500,500,1)代表z轴方向只采样1层,所有采样点的z坐标是固定的,所以z方向的频率变化自然不会体现在最终的2D平面效果上。
如果要验证第三个参数的效果,可以把采样dim的第三维改成大于1的值(比如dim=(200,200,200))生成3D体噪声,或是对存在z坐标分布的3D网格(比如之前的球体)采样噪声,调整第三个frequency值就能看到z方向的噪声疏密变化了。
内容的提问来源于stack exchange,提问作者Michael Hüppe
相关产品推荐
相关产品推荐

