기존에 만들었던 씬에 Light와 PlaneGeometry를 추가했습니다.

light.zip

↑↑↑↑↑

소스 파일 입니다.



각 Light 에 대한 자세한 설명은 아래 URL에서 확인해 주시기 바랍니다.


https://threejs.org/docs/#api/en/lights/AmbientLight - 모든 오브젝트를 전역으로 빛을 비춰줍니다. 이 빛은 그림자가 생기지 않습니다.

https://threejs.org/docs/#api/en/lights/DirectionalLight - 특정 방향으로 빛을 방출합니다.(예시. 태양) 이 빛은 그림자가 생길 수 있습니다.

https://threejs.org/docs/#api/en/lights/HemisphereLight - 하늘색? 지상색? 장면 바로 위에서 광원을 방출합니다. 이 빛은 그림자가 생기지 않습니다.

https://threejs.org/docs/#api/en/lights/PointLight - 한 방향으로 빛을 방출합니다.(예시. 전구)

https://threejs.org/docs/#api/en/lights/RectAreaLight - 직사각형 평면에 균일하게 빛을 방출합니다.

https://threejs.org/docs/#api/en/lights/SpotLight - 원뿔 모양에 따라 빛의 방출 합니다. 이 빛은 그림자가 생길 수 있습니다.





<!DOCTYPE html>
<html>

<head>
    <meta charset=utf-8>
    <title>My first three.js app</title>
    <style>
        body {
            margin: 0;
        }

        canvas {
            width: 100%;
            height: 100%
        }
    </style>
</head>

<body>
    <div>
        <button id="am-light">AmbientLight</button>
        <button id="dic-light">DirectionalLight</button>
        <p>Light를 클릭하여 조명을 추가해 주세요.</p>
    </div>
    <!-- Three js -->
    <script src="https://threejs.org/build/three.min.js"></script>

    <!-- WebGL 지원유무 https://github.com/mrdoob/three.js/blob/master/examples/js/WebGL.js 참고 -->
    <script src="./WebGL.js"></script>

    <!-- OrbitControls.js allow the camera to orbit around a target 마우스와 카메라를 상호작용하게 합니다. -->
    <script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>

    <script>
        window.onload = function (e) {

            let scene = new THREE.Scene();
            let light;
            let camera;

            initThree();

            // AmbientLight 조명 추가 클릭 이벤트
            document.getElementById('am-light').onclick = () => {
                removeLight();
                addAmbientLight();
            }

            // DirectionalLight 조명 추가 클릭 이벤트
            document.getElementById('dic-light').onclick = () => {
                removeLight();
                addDirectionalLight();
            }

            /**
             * AmbientLight를 추가하는 함수
             *
             * @method addAmbientLight
             */
            function addAmbientLight() {
                /**
                 * AmbientLight는 Scene의 모든 오브젝트를 전역으로 빛을 비춰줍니다.
                 * 그러므로 빛의 방향이 없어 그림자는 존재하지 않습니다.
                 *
                 * AmbientLight(color : Integer, intensity : Float)
                 * color: optional, 조명 색상 값(RGB 값을 사용), 기본값은 0xffffff 입니다.
                 * intensity: optional, 조명의 밝기 수차, 기본값은 1 입니다.(값이 낮아 질 수록 어두워 집니다.)
                 */
                light = new THREE.AmbientLight(0xffffff, 0.2);
                scene.add(light);

                setShadowCamera();
            }

            /**
             * DirectionalLight를 추가하는 함수
             *
             * @method addDirectionalLight
             */
            function addDirectionalLight() {
                /**
                 * 특정 방향으로 빛을 방출합니다. 태양을 생각하면 쉬울거 같습니다.
                 * 그리고 이 조명은 그림자를 생기게 합니다.
                 *
                 * DirectionalLight(color : Integer, intensity : Float)
                 * color: optional, 빛의 색상, 기본값은 0xffffff(흰색) 입니다.
                 * intensity: optional, 빛의 강도, 기본값은 1 입니다.
                 */
                light = new THREE.DirectionalLight(0xffffff, 0.5);
                light.castShadow = true; // true 이면 광원이 그림자를 생성합니다. 기본값은 false 입니다.
                scene.add(light);

                setShadowCamera();
            }

            /**
             * 카메라에 조명 헬퍼를 생성하는 함수
             *
             * @method setShadowCamera
             */
            function setShadowCamera() {
                let helper = new THREE.CameraHelper(light.shadow.camera);
                scene.add(helper);
            }

            function removeLight() {
                scene.remove(light);
                light = null;
            }

            /**
             * Threejs 초기화 함수
             *
             * @method initThree
             */
            function initThree() {
                // 브라우저가 WebGL을 지원하는지 체크
                if (WEBGL.isWebGLAvailable()) {
                    console.log('이 브라우저는 WEBGL을 지원합니다.');
                } else {
                    console.log('이 브라우저는 WEBGL을 지원하지 않습니다.');
                }

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

                /**
                 * Anti Aliasing이란? 픽셀로 이루어진 화면은 우둘투둘하게 계단효과가 나타나게 되는데
                 * 이것을 부드럽게 만드는 옵션 입니다.
                 * 참고: http://www.itworld.co.kr/news/97807
                 */
                let renderer = new THREE.WebGLRenderer({
                    antialias: true
                });
                renderer.setSize(window.innerWidth, window.innerHeight);
                renderer.shadowMap.enabled = true;
                renderer.shadowMap.type = THREE.PCFSoftShadowMap;
                document.body.appendChild(renderer.domElement);

                let geometry = new THREE.BoxGeometry(1, 1, 1);

                /**
                 * scene 화면상에 XYZ(Red: X, Green: Y, Blue: Z) 축을 보여줍니다.
                 *
                 * AxisHelper(size : Number)
                 * size: optional 축의 크기, 기본값은 1입니다.
                 */
                let axes = new THREE.AxisHelper(10);
                scene.add(axes);

                /**
                 * 반사 하이라이트가 있는 표면(반짝이는 표현)으로 생성합니다.
                 * MeshBasicMaterial일 경우에는 그림자가 생기지 않습니다.
                 */
                let material = new THREE.MeshPhongMaterial({ color: 0x00ff00 });
                let cube = new THREE.Mesh(geometry, material);
                cube.position.set(0, 0.5, 0);
                scene.add(cube);

                /**
                 * 평면 지오메트리를 생성합니다.
                 *
                 * PlaneGeometry(width : Float, height : Float, widthSegments : Integer, heightSegments : Integer)
                 * width: X 축 방향의 폭, 기본값은 1 입니다.
                 * height: Y 축 높이, 기본값은 1 입니다.
                 * widthSegments: optional, 면의 너비에 따라 분할된 면수, 기본값은 1 입니다.
                 * heightSegments: optional, 축면의 높이에 따라 분할된 면수,기본값은 1 입니다.
                 */
                let planeGeomtry = new THREE.PlaneGeometry(10, 10, 1, 1);
                let planeMaterial = new THREE.MeshPhongMaterial({ color: 0xCCCCCC });
                let plane = new THREE.Mesh(planeGeomtry, planeMaterial);
                plane.rotation.x = -0.5 * Math.PI; // 평면지오메트리를 바닥에 일치하게 돌린다.
                scene.add(plane);

                camera.position.x = 0;
                camera.position.y = 10;
                camera.position.z = 5;

                controls = new THREE.OrbitControls(camera);
                controls.rotateSpeed = 1.0;
                controls.zoomSpeed = 1.2;
                controls.panSpeed = 0.8;
                controls.minDistance = 5;
                controls.maxDistance = 100;

                function animate() {
                    requestAnimationFrame(animate);

                    renderer.render(scene, camera);
                    controls.update();
                }

                animate();
            }
        }
    </script>
</body>

</html>




+ Recent posts