2017-11-13 12 views
1

私は、曲面と2つの平面をマージしてThree.Jsで図形を作成しました。私は材料にMeshLambertMaterialを使用しました。垂直面と曲面は完全に結合します。しかし、水平面がカーブと結合するところには目立つような硬い線があります。照明は整列していないようです。私は3つの平面が滑らかな陰影を持つ1つのオブジェクトとして現れるようにしたい。私は何か間違っているのですか?Three.js平面上のマテリアルが照明と一致しない

codepen

addShape() { 
       var radius =58, height=100, startAngle=THREE.Math.degToRad(0), endAngle=THREE.Math.degToRad(90), horizontalSegments=25, verticalSegments=25; 
       var width = radius * 2 * Math.PI; 
       var plane = new THREE.PlaneGeometry(width, height, horizontalSegments, verticalSegments); 
       var index = 0; 

       for(var i=0; i<=verticalSegments; i++) { 
        for(var j=0; j<=horizontalSegments; j++) { 
         var angle = startAngle + (j/horizontalSegments)*(endAngle - startAngle); 
         plane.vertices[index].z = radius * Math.cos(angle); 
         plane.vertices[index].x = radius * Math.sin(angle); 
         index++; 
        } 
       } 
       var material = new THREE.MeshLambertMaterial({color: 0xa2cddd, side: THREE.DoubleSide}); 
       var mesh = new THREE.Object3D(); 
       var curve = new THREE.Mesh(plane, material); 
       curve.rotation.z = THREE.Math.degToRad(-90) 


       var plane1 = new THREE.PlaneGeometry(height, height, horizontalSegments, verticalSegments); 
       var side1 = new THREE.Mesh(plane1, material); 
       side1.rotation.z = THREE.Math.degToRad(270) 
       side1.position.z = radius; 
       side1.position.x = -radius * 0.85; 

       var plane2 = new THREE.PlaneGeometry(height, height, 1, 1); 
       var side2 = new THREE.Mesh(plane2); 
       side2.rotation.y = THREE.Math.degToRad(90) 
       side2.position.x = radius * 1.0 
       side2.position.z = -radius * 0.8; 

       plane.mergeMesh(side1); 
       plane.mergeMesh(side2); 
       mesh.rotation.y = THREE.Math.degToRad(180); 
       mesh.add(curve); 
       this.mesh = mesh; 
       this.scene.add(mesh); 
      } 
addLight() { 
    let light1 = new THREE.PointLight(0xffffff, 1, 200); 
    light1.position.set(0, 20, 10); 
    this.scene.add(light1); 

    let light2 = new THREE.AmbientLight(0x404040); // soft white light 
    this.scene.add(light2); 
    } 

enter image description here

+0

あなたの法線を更新していないように見えます。カーブに沿った法線は、カーブの中心に向かうように更新して、必要な効果を達成する必要があります。 – TheJim01

答えて

2

あなたが頂点法線を計算する必要がまず第一。これにはTHREE.Geometry.computeVertexNormalsを使用してください。
さらに、あなたはこのソリューションをTHREE.PlaneGeometry 1のバンドを描く場合は、あなたが好きなように、開始角度と終了角度を選択し、で飛行機ができ、物事を簡素化することができますTHREE.Geometry

plane.computeVertexNormals(); 


を参照してください。開始と終了は常に湾曲部にシームレスに接続できるようになります:

var radius = 58, height = 100, 
    startAngle = THREE.Math.degToRad(-20), 
    endAngle = THREE.Math.degToRad(110), 
    horSegs = 25, vertSegs = 25, 
    startLen = 100, endLen = 100; 
var width = startLen + endLen + radius * (endAngle-startAngle); 
var plane = new THREE.PlaneGeometry(width, height, horSegs+2, vertSegs); 

var index = 0; 
for (var i = 0; i <= vertSegs; i++) { 
    plane.vertices[index].z = radius * Math.cos(startAngle) + startLen * Math.sin(startAngle); 
    plane.vertices[index].x = radius * Math.sin(startAngle) - startLen * Math.cos(startAngle); 
    index++; 
    for (var j = 0; j <= horSegs; j++) { 
    var angle = startAngle + j/horSegs * (endAngle - startAngle); 
    plane.vertices[index].z = radius * Math.cos(angle); 
    plane.vertices[index].x = radius * Math.sin(angle); 
    index++; 
    } 
    plane.vertices[index].z = radius * Math.cos(endAngle) - endLen * Math.sin(endAngle); 
    plane.vertices[index].x = radius * Math.sin(endAngle) + endLen * Math.cos(endAngle); 
    index++; 
} 
plane.computeVertexNormals(); 


は、コードスニペットを参照してください。

class World { 
 
    constructor() { 
 
    this.scene = new THREE.Scene(); 
 
    this.renderer = new THREE.WebGLRenderer(); 
 
    this.renderer.setClearColor(0x000000); 
 
    document.body.appendChild(this.renderer.domElement); 
 
    this.resize(); 
 

 
    // this.addCube(); 
 
    this.addShape(); 
 
    this.addLight(); 
 

 
    requestAnimationFrame(this.render.bind(this)); 
 
    window.addEventListener("resize", this.resize.bind(this)); 
 
    } 
 

 
    update() { 
 
    if (this.cube) this.cube.rotation.y += 0.01; 
 
    if (this.mesh) this.mesh.rotation.y += 0.01; 
 
    } 
 

 
    addLight() { 
 
    let light1 = new THREE.PointLight(0xffffff, 1, 200); 
 
    light1.position.set(0, 20, 10); 
 
    this.scene.add(light1); 
 

 
    let light2 = new THREE.AmbientLight(0x404040); // soft white light 
 
    this.scene.add(light2); 
 
    } 
 

 
    
 
    addShape() { 
 
    var radius = 58, height = 100, 
 
     startAngle = THREE.Math.degToRad(-20), 
 
     endAngle = THREE.Math.degToRad(110), 
 
     horSegs = 25, vertSegs = 25, 
 
     startLen = 100, endLen = 100; 
 
    var width = startLen + endLen + radius * (endAngle-startAngle); 
 
    var plane = new THREE.PlaneGeometry(width, height, horSegs+2, vertSegs); 
 
    
 
    var index = 0; 
 
    for (var i = 0; i <= vertSegs; i++) { 
 
     plane.vertices[index].z = radius * Math.cos(startAngle) + startLen * Math.sin(startAngle); 
 
     plane.vertices[index].x = radius * Math.sin(startAngle) - startLen * Math.cos(startAngle); 
 
     index++; 
 
     for (var j = 0; j <= horSegs; j++) { 
 
     var angle = startAngle + j/horSegs * (endAngle - startAngle); 
 
     plane.vertices[index].z = radius * Math.cos(angle); 
 
     plane.vertices[index].x = radius * Math.sin(angle); 
 
     index++; 
 
     } 
 
     plane.vertices[index].z = radius * Math.cos(endAngle) - endLen * Math.sin(endAngle); 
 
     plane.vertices[index].x = radius * Math.sin(endAngle) + endLen * Math.cos(endAngle); 
 
     index++; 
 
    } 
 
    plane.computeVertexNormals(); 
 

 
    var material = new THREE.MeshLambertMaterial({ 
 
     color: 0xa2cddd, 
 
     side: THREE.DoubleSide 
 
    }); 
 
    
 
    var mesh = new THREE.Object3D(); 
 
    var curve = new THREE.Mesh(plane, material); 
 
    curve.rotation.z = THREE.Math.degToRad(-90); 
 

 
    mesh.add(curve); 
 
    this.mesh = mesh; 
 
    this.scene.add(mesh); 
 
    } 
 

 
    render() { 
 
    this.update(); 
 
    requestAnimationFrame(this.render.bind(this)); 
 
    this.renderer.render(this.scene, this.camera); 
 
    } 
 

 
    resize() { 
 
    this.camera = new THREE.PerspectiveCamera(
 
     75, 
 
     window.innerWidth/window.innerHeight, 
 
     0.1, 
 
     1000 
 
    ); 
 

 
    this.camera.position.z = 200; 
 

 
    this.renderer.setSize(window.innerWidth, window.innerHeight); 
 
    } 
 
} 
 

 
var _w = new World();
<script src="https://threejs.org/build/three.min.js"></script>

+1

完璧、ありがとうございます。 – fatlinesofcode

関連する問題