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

如何在Three.js中为立方球面实现跨六面连续的噪声纹理

问题:立方球面跨面连续噪声纹理实现

我正在开展一个项目,需使用Three.js的噪声为立方球面添加纹理,要求纹理在六个面间保持连续。目前我已通过六个平面创建了立方体,但将其转换为球面后,噪声纹理无法在各面间实现连续过渡。

效果对比

  • 带噪声的立方体:带噪声的立方体
  • 转换为球面后(纹理不连续):球面化后纹理不连续
  • 预期效果:预期连续纹理效果

立方体创建代码

var front = buildMesh(texture);
var fg = new THREE.Group(front)
fg.add(front)

var back = buildMesh(texture);
var bg = new THREE.Group(back)
bg.add(back)
bg.position.z = -w;
bg.rotation.y=(Math.PI)

var right = buildMesh(texture);
var rg = new THREE.Group(right)
rg.add(right)
rg.position.z = -((w)/2);
rg.position.x =  ((w)/2);
rg.rotation.y = (Math.PI/2)


var left = buildMesh(texture);
var lg = new THREE.Group(left)
lg.add(left)
lg.position.z = -((w)/2);
lg.position.x = -((w)/2);
lg.rotation.y=(-Math.PI/2)

var top = buildMesh(texture);
var tg = new THREE.Group(top)
tg.add(top)
tg.position.z = -((w)/2);
tg.position.y = ((w)/2);
tg.rotation.x=(-Math.PI/2)

var bot = buildMesh(texture);
var bog = new THREE.Group(bot)
bog.add(bot)
bog.position.z = -((w)/2);
bog.position.y = -((w)/2);
bog.rotation.x=(Math.PI/2)

var g = new THREE.Group()
g.add(fg)
g.add(bg)
g.add(lg)
g.add(rg)
g.add(tg)
g.add(bog)

scene.add(g)

function buildMesh(t){
  let geometry = new THREE.PlaneGeometry(w, w,50,50);
  uniforms = {u_tex: {value: t },wTl:{value:new THREE.Vector3()},ps:{value:new THREE.Vector3()}}; 
  let material = new THREE.ShaderMaterial({
    uniforms: uniforms,
    fragmentShader: fragmentShader(),
    vertexShader: vertexShader(),
    wireframe:false
  });

  var mesh = new THREE.Mesh(geometry, material);
  return mesh
}

localCenter计算代码

var sides = [
  ...fg.children,
  ...bg.children,
  ...rg.children,
  ...lg.children,
  ...tg.children,
  ...bog.children,
]

var cnt = centerPosition(g)
var localCenter = new THREE.Vector3();
for (let index = 0; index < sides.length; index++) {
  const element = sides[index];
  element.worldToLocal(localCenter.copy(cnt))
  element.material.uniforms['wTl'].value = localCenter
}

function centerPosition(g) {
  bbox.expandByObject(g);
  var center = new THREE.Vector3();
  bbox.getCenter(center);
  return center
}

着色器代码

function vertexShader(){
  return `
  varying vec2 vUv;
  uniform vec3 wTl;

 vec3 planeToSphere(vec3 p, vec3 localCenter){
    p = p - localCenter;
    p=normalize(p);
    float length = -length(p);
    p = p * length * (localCenter.z*1.0);
    p = p+localCenter;
    return p;
  }

    
varying vec3 v3n;
    void main() {
      vUv = uv;
      vec3 newPosition   =  planeToSphere(position,wTl) ;
      vec3 worldp = ( modelMatrix * vec4(newPosition,1.0)).xyz;
      float n = snoise(worldp*.04);
      v3n=vec3(n,n,n);
      vec3 finalp = newPosition+normal*n;
      gl_Position = projectionMatrix  * modelViewMatrix * vec4( finalp, 1.0 ) ;
    }
  
  `
}

function fragmentShader(){
  return `
    varying vec2 vUv;
    varying vec3 v3n;

    
    void main() {

      gl_FragColor  = vec4(v3n,1.0);

    }
`
}

恳请各位提供实现跨六面连续噪声纹理的指导。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 08:08:09