three.js - Threejs 立方体没有显示其边缘

标签 three.js

我正在深入 Threejs 的世界。我采用了其中一个示例项目并对其进行了修改。我刚刚添加了一些带有颜色的立方体几何形状。问题是,立方体几何形状显示没有边缘。你无法辨别面孔的尽头,它都被漂白了。不确定这是照明问题还是 Material 问题。我的代码如下。

<!DOCTYPE html>
<html lang="en">
<head>
    <title>three.js webgl - cloth simulation</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    <link type="text/css" rel="stylesheet" href="main.css">
    <style>
        body {
            background-color: #cce0ff;
            color: #000;
        }
        a {
            color: #080;
        }
    </style>
</head>

<body>

    <div id="info">Simple Cabinet Box in 3D Space<br/>
    </div>
    <script type="module">
        import * as THREE from '../build/three.module.js';
        //import Stats from './jsm/libs/stats.module.js';
        import { GUI } from './jsm/libs/dat.gui.module.js';
        import { OrbitControls } from './jsm/controls/OrbitControls.js';

        function plane( width, height )
        {
            return function ( u, v, target )
            {
                const x = ( u - 0.5 ) * width;
                const y = ( v + 0.5 ) * height;
                const z = 0;
                target.set( x, y, z );
            };
        }

        let container;
        let camera, scene, renderer;

        init();
        animate( 0 );

        function init() {
            container = document.createElement( 'div' );
            document.body.appendChild( container );

            // scene
            scene = new THREE.Scene();
            scene.background = new THREE.Color( 0xffffff );

            // camera
            camera = new THREE.PerspectiveCamera( 30, window.innerWidth / window.innerHeight, 1, 10000 );
            camera.position.set( 0, 0, 100 );

            // lights
            //scene.add( new THREE.AmbientLight( 0x666666 ) );
            const light = new THREE.DirectionalLight( 0xdfebff, 1 );
            light.position.set( 50, 200, 100 );
            light.position.multiplyScalar( 1.3 );
            light.castShadow = true;
            light.shadow.mapSize.width = 1024;
            light.shadow.mapSize.height = 1024;
            const d = 300;
            light.shadow.camera.left = - d;
            light.shadow.camera.right = d;
            light.shadow.camera.top = d;
            light.shadow.camera.bottom = - d;
            light.shadow.camera.far = 1000;
            scene.add( light );


            //cabinet properties
            const c_width = 24;
            const c_height = 34.5;
            const c_depth = 23.125;
            const c_left_side_thickness = 0.75;

            //Left End
            const geometry = new THREE.BoxGeometry( c_left_side_thickness, c_height, c_depth);
            const material = new THREE.MeshBasicMaterial( { color: 0xC2B8B6 } );
            const left_side = new THREE.Mesh( geometry, material );
            left_side.position.set((c_width/2)*-1 + c_left_side_thickness/2,0,0);

            const right_side = new THREE.Mesh( geometry, material );
            right_side.position.set(c_width/2 - c_left_side_thickness/2,0,0);

            const geometry2 = new THREE.BoxGeometry( c_width - c_left_side_thickness * 2, c_left_side_thickness, c_depth);
            const bottom = new THREE.Mesh( geometry2, material );
            bottom.position.set(0,(c_height/2)*-1 + c_left_side_thickness/2,0);

            const top = new THREE.Mesh( geometry2, material );
            top.position.set(0,c_height / 2 - c_left_side_thickness/2,0);

            const cabinet = new THREE.Group();
            cabinet.add( left_side );
            cabinet.add( right_side );
            cabinet.add( bottom );
            cabinet.add( top );

            scene.add( cabinet );

            //
            // const geometry2 = new THREE.BoxGeometry( 10, 10, 10 );
            // const edges = new THREE.EdgesGeometry( geometry2 );
            // const line = new THREE.LineSegments( edges, new THREE.LineBasicMaterial( { color: 0xffffff } ) );
            // line.position.set(0,100,0);
            // scene.add( line );

            // ground
            const loader = new THREE.TextureLoader();
            const groundTexture = loader.load( 'textures/terrain/grasslight-big.jpg' );
            groundTexture.wrapS = groundTexture.wrapT = THREE.RepeatWrapping;
            groundTexture.repeat.set( 25, 25 );
            groundTexture.anisotropy = 16;
            groundTexture.encoding = THREE.sRGBEncoding;
            const groundMaterial = new THREE.MeshLambertMaterial( { map: groundTexture } );
            let mesh = new THREE.Mesh( new THREE.PlaneGeometry( 20000, 20000 ), groundMaterial );
            mesh.position.y = - 250;
            mesh.rotation.x = - Math.PI / 2;
            mesh.receiveShadow = true;
            scene.add( mesh );

            // renderer
            renderer = new THREE.WebGLRenderer( { antialias: true } );
            renderer.setPixelRatio( window.devicePixelRatio );
            renderer.setSize( window.innerWidth, window.innerHeight );

            container.appendChild( renderer.domElement );

            renderer.outputEncoding = THREE.sRGBEncoding;
            renderer.shadowMap.enabled = true;

            // controls
            const controls = new OrbitControls( camera, renderer.domElement );
            controls.maxPolarAngle = Math.PI * 0.5;
            controls.minDistance = 100;
            controls.maxDistance = 500;

            window.addEventListener( 'resize', onWindowResize );

            if ( typeof TESTING !== 'undefined' )
            {
                for ( let i = 0; i < 50; i ++ )
                {
                    simulate( 500 - 10 * i );
                }
            }
        }

        function onWindowResize()
        {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize( window.innerWidth, window.innerHeight );
        }

        function animate( now )
        {
            requestAnimationFrame( animate );
            render();
        }

        function render()
        {
            renderer.render( scene, camera );
        }
    </script>
</body>

最佳答案

您必须为盒子使用发光 Material (例如 MeshPhongMaterial)。 MeshBasicMaterial 是一种无光照 Material ,不会对光照产生 react 。另外,在方向旁边使用环境光将使场景看起来更自然。

let container;
let camera, scene, renderer;

init();
animate(0);

function init() {
  container = document.createElement('div');
  document.body.appendChild(container);

  // scene
  scene = new THREE.Scene();
  scene.background = new THREE.Color(0xffffff);

  // camera
  camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 1, 10000);
  camera.position.set(0, 0, 100);

  // lights
  scene.add( new THREE.AmbientLight( 0xffffff, 0.4 ) );
  
  const light = new THREE.DirectionalLight(0xffffff, 0.8);
  light.position.set(50, 200, 100);
  light.position.multiplyScalar(1.3);
  light.castShadow = true;
  light.shadow.mapSize.width = 1024;
  light.shadow.mapSize.height = 1024;
  const d = 300;
  light.shadow.camera.left = -d;
  light.shadow.camera.right = d;
  light.shadow.camera.top = d;
  light.shadow.camera.bottom = -d;
  light.shadow.camera.far = 1000;
  scene.add(light);

  //cabinet properties
  const c_width = 24;
  const c_height = 34.5;
  const c_depth = 23.125;
  const c_left_side_thickness = 0.75;

  //Left End
  const geometry = new THREE.BoxGeometry(c_left_side_thickness, c_height, c_depth);
  const material = new THREE.MeshPhongMaterial({
    color: 0xC2B8B6
  });
  const left_side = new THREE.Mesh(geometry, material);
  left_side.position.set((c_width / 2) * -1 + c_left_side_thickness / 2, 0, 0);

  const right_side = new THREE.Mesh(geometry, material);
  right_side.position.set(c_width / 2 - c_left_side_thickness / 2, 0, 0);

  const geometry2 = new THREE.BoxGeometry(c_width - c_left_side_thickness * 2, c_left_side_thickness, c_depth);
  const bottom = new THREE.Mesh(geometry2, material);
  bottom.position.set(0, (c_height / 2) * -1 + c_left_side_thickness / 2, 0);

  const top = new THREE.Mesh(geometry2, material);
  top.position.set(0, c_height / 2 - c_left_side_thickness / 2, 0);

  const cabinet = new THREE.Group();
  cabinet.add(left_side);
  cabinet.add(right_side);
  cabinet.add(bottom);
  cabinet.add(top);

  scene.add(cabinet);

  // ground
  const loader = new THREE.TextureLoader();
  const groundTexture = loader.load('https://threejs.org/examples/textures/terrain/grasslight-big.jpg');
  groundTexture.wrapS = groundTexture.wrapT = THREE.RepeatWrapping;
  groundTexture.repeat.set(25, 25);
  groundTexture.anisotropy = 16;
  groundTexture.encoding = THREE.sRGBEncoding;
  const groundMaterial = new THREE.MeshLambertMaterial({
    map: groundTexture
  });
  let mesh = new THREE.Mesh(new THREE.PlaneGeometry(20000, 20000), groundMaterial);
  mesh.position.y = -250;
  mesh.rotation.x = -Math.PI / 2;
  mesh.receiveShadow = true;
  scene.add(mesh);

  // renderer
  renderer = new THREE.WebGLRenderer({
    antialias: true
  });
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(window.innerWidth, window.innerHeight);

  container.appendChild(renderer.domElement);

  renderer.outputEncoding = THREE.sRGBEncoding;
  renderer.shadowMap.enabled = true;

  // controls
  const controls = new THREE.OrbitControls(camera, renderer.domElement);
  controls.maxPolarAngle = Math.PI * 0.5;
  controls.minDistance = 100;
  controls.maxDistance = 500;

  window.addEventListener('resize', onWindowResize);

}

function onWindowResize() {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
}

function animate() {
  requestAnimationFrame(animate);
  render();
}

function render() {
  renderer.render(scene, camera);
}
<script src="https://cdn.jsdelivr.net/npm/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="b8ccd0caddddf88896898a809688" rel="noreferrer noopener nofollow">[email protected]</a>/build/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d9adb1abbcbc99e9f7e8ebe1f7e9" rel="noreferrer noopener nofollow">[email protected]</a>/examples/js/controls/OrbitControls.js"></script>

关于three.js - Threejs 立方体没有显示其边缘,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67387096/

相关文章:

javascript - 三个JS : Create Triangle Strip

three.js - 如何沿x轴三个js翻转 Sprite 的纹理?

javascript - 在浏览器中使用 ThreeJS 或 X3DOM 参数化和编辑模型

javascript - 为什么在 Threejs 渲染函数中的 while 循环不更新每一帧?

three.js - A 框架视锥体剔除

javascript - 如何改变GridHelper线条的粗细?

javascript - 使用 React-Three-Renderer 的 Sprite 标签(包括 MVCE)

javascript - Three.js 在哪里设置 Material 的默认着色器?

Three.js 不那么强烈的环境光?

javascript - 事件监听器完成后运行函数