代码之家  ›  专栏  ›  技术社区  ›  Rob Kwasowski george

3.js:负θ圆柱体

  •  0
  • Rob Kwasowski george  · 技术社区  · 7 年前

    我想用一个“倒置”的圆柱体,把θ设为-6.3,这样内部就被归类为正面,这样圆柱体就可以进入另一个正常的圆柱体,顶部和底部都有环,形成一个管子。

    我之所以要做这一切,是为了让整个对象可以组合成一个网格与一个单一的材料。如果不将“Talength”设置为负,则必须有一个“side”设置为“BackSide”的重复材质,因此不能将其全部设置为一个网格。

    我已经完成了下面的例子中我所说的(你可以用鼠标缩放和移动)。负的θ圆柱体在左边,而正常的θ圆柱体在右边。

    我遇到的问题是,你可以看到左边的圆柱体比右边的要暗得多。右边的看起来更逼真。

    我在想也许是因为它认为光是从不同的方向来的,它实际上是从哪里来的。

    有没有什么方法可以解决这个问题,使倒置的圆柱体看起来像背面的圆柱体,这样我就可以有一个这样的管作为一个单一的网格?

    width = window.innerWidth
    height = window.innerHeight
    
    renderer = new THREE.WebGLRenderer({antialias: true})
    renderer.setClearColor(0x8e8ed7)
    renderer.setPixelRatio(window.devicePixelRatio)
    renderer.setSize(width, height)
    document.body.appendChild(renderer.domElement)
    
    scene = new THREE.Scene()
    camera = new THREE.PerspectiveCamera(35, width / height, 0.1, 3000)
    camera.position.set(0, 50, 100)
    
    controls = new THREE.OrbitControls(camera)
    controls.minDistance = 40
    controls.maxDistance = 1300
    
    scene.add(camera, new THREE.AmbientLight(0xffffff, 0.48))
    light = new THREE.PointLight(0xffffff, 0.55)
    
    light.position.copy( camera.position );
    light.position.y -= 80
    light.position.x += 100
    camera.add(light)
    
    requestAnimationFrame(function animate(){
      requestAnimationFrame(animate)
      renderer.render(scene, camera)
    })
    
    material = new THREE.MeshPhongMaterial({color: 0xFF7E14, specular: 0x111111, shininess: 75})
    material2= new THREE.MeshPhongMaterial({color: 0xFF7E14, specular: 0x111111, shininess: 75, side: THREE.BackSide})
    
    tube_a = new THREE.Mesh(new THREE.CylinderGeometry(6,6,20,32,1,true,0,-6.3), material)
    tube_aa = new THREE.Mesh(new THREE.CylinderGeometry(6,6,20,32,1,true,0,6.3), material2)
    tube_b = new THREE.Mesh(new THREE.CylinderGeometry(8.1375,8.1375,20,32,1,true), material)
    ring = new THREE.Mesh(new THREE.RingGeometry(6,8.1375,32), material)
    
    group1 = new THREE.Group()
    
    ta1 = tube_a.clone()
    group1.add(ta1)
    tb1 = tube_b.clone()
    group1.add(tb1)
    r = ring.clone()
    r.position.y -= 10
    r.rotateX((9*Math.PI)/18)
    group1.add(r)
    r = ring.clone()
    r.position.y += 10
    r.rotateX((27*Math.PI)/18)
    group1.add(r)
    group1.position.x -= 15
    scene.add(group1)
    
    group2 = new THREE.Group()
    
    ta2 = tube_aa.clone()
    group2.add(ta2)
    tb2 = tube_b.clone()
    group2.add(tb2)
    r = ring.clone()
    r.position.y -= 10
    r.rotateX((9*Math.PI)/18)
    group2.add(r)
    r = ring.clone()
    r.position.y += 10
    r.rotateX((27*Math.PI)/18)
    group2.add(r)
    group2.position.x += 15
    scene.add(group2)
    <script src="http://threejs.org/build/three.min.js"></script>
    <script src="http://threejs.org/examples/js/controls/OrbitControls.js"></script>
    1 回复  |  直到 7 年前
        1
  •  1
  •   Rabbid76    7 年前

    我遇到的问题是,你可以看到左边的圆柱体比右边的要暗得多。右边的看起来更逼真。

    你必须更新顶点法向量 Geometry.computeVertexNormals() 生成网格后,要解决此问题:

    tube_a = new THREE.Mesh(new THREE.CylinderGeometry(6,6,20,32,1,true,0,-6.3), material)
    tube_a.geometry.computeVertexNormals();
    

    width = window.innerWidth
    height = window.innerHeight
    
    renderer = new THREE.WebGLRenderer({antialias: true})
    renderer.setClearColor(0x8e8ed7)
    renderer.setPixelRatio(window.devicePixelRatio)
    renderer.setSize(width, height)
    document.body.appendChild(renderer.domElement)
    
    scene = new THREE.Scene()
    camera = new THREE.PerspectiveCamera(35, width / height, 0.1, 3000)
    camera.position.set(0, 50, 100)
    
    controls = new THREE.OrbitControls(camera)
    controls.minDistance = 40
    controls.maxDistance = 1300
    
    scene.add(camera, new THREE.AmbientLight(0xffffff, 0.48))
    light = new THREE.PointLight(0xffffff, 0.55)
    
    light.position.copy( camera.position );
    light.position.y -= 80
    light.position.x += 100
    camera.add(light)
    
    requestAnimationFrame(function animate(){
      requestAnimationFrame(animate)
      renderer.render(scene, camera)
    })
    
    material = new THREE.MeshPhongMaterial({color: 0xFF7E14, specular: 0x111111, shininess: 75})
    material2= new THREE.MeshPhongMaterial({color: 0xFF7E14, specular: 0x111111, shininess: 75, side: THREE.BackSide})
    
    tube_a = new THREE.Mesh(new THREE.CylinderGeometry(6,6,20,32,1,true,0,-6.3), material)
    tube_a.geometry.computeVertexNormals();
    
    tube_aa = new THREE.Mesh(new THREE.CylinderGeometry(6,6,20,32,1,true,0,6.3), material2)
    tube_b = new THREE.Mesh(new THREE.CylinderGeometry(8.1375,8.1375,20,32,1,true), material)
    ring = new THREE.Mesh(new THREE.RingGeometry(6,8.1375,32), material)
    
    
    
    
    group1 = new THREE.Group()
    
    ta1 = tube_a.clone()
    group1.add(ta1)
    tb1 = tube_b.clone()
    group1.add(tb1)
    r = ring.clone()
    r.position.y -= 10
    r.rotateX((9*Math.PI)/18)
    group1.add(r)
    r = ring.clone()
    r.position.y += 10
    r.rotateX((27*Math.PI)/18)
    group1.add(r)
    group1.position.x -= 15
    scene.add(group1)
    
    group2 = new THREE.Group()
    
    ta2 = tube_aa.clone()
    group2.add(ta2)
    tb2 = tube_b.clone()
    group2.add(tb2)
    r = ring.clone()
    r.position.y -= 10
    r.rotateX((9*Math.PI)/18)
    group2.add(r)
    r = ring.clone()
    r.position.y += 10
    r.rotateX((27*Math.PI)/18)
    group2.add(r)
    group2.position.x += 15
    scene.add(group2)
    
    function resize() {
        
        var aspect = window.innerWidth / window.innerHeight;
        renderer.setSize(window.innerWidth, window.innerHeight);
        camera.aspect = aspect;
        camera.updateProjectionMatrix();
        //controls.handleResize();
      }
    
    window.onresize = resize;
    <script src="http://threejs.org/build/three.min.js"></script>
    <script src="http://threejs.org/examples/js/controls/OrbitControls.js"></script>