wam
w__am 개발노트
wam
  • 분류 전체보기 (165)
    • CS 지식 (10)
      • 자료구조 (0)
      • 알고리즘 (0)
      • 컴퓨터 구조 (0)
      • 운영체제 (0)
      • 네트워크 (7)
      • 데이터베이스 (0)
      • 디자인 패턴 (3)
    • Frontend (131)
      • Three.js (64)
      • NPM (1)
      • Nest.js (19)
      • React (10)
      • Apollo (7)
      • TypeScript (2)
      • JavaScript (12)
      • HTML, CSS (1)
      • Jest (3)
      • E2E (5)
      • Cypress (7)
    • Database (12)
      • TypeORM (12)
    • IT 지식 (8)
      • 클라우드 서비스 (3)
      • 네트워크 (1)
      • 데이터 포맷 (2)
      • 기타 (2)
    • IT Book (2)
    • 유용한 사이트 (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록
  • 🐱 Github

인기 글

태그

  • type-graphql
  • 데이터 포맷
  • 초기 환경설정
  • 디자인 패턴
  • mapped types
  • joi 에러
  • reactive variables
  • three.js 구성 요소
  • gridhelper
  • 렌더링 성능 최적화
  • 원형적인 움직임
  • 스코프
  • Decorators
  • Interface
  • 오프-프레미스(off-premise) 방식
  • e.preventdefault()
  • 함수의 범위
  • isabstract
  • axeshelper
  • threejs 개발 할 때 도움을 줄 수 있는 유틸리티
  • react 성능 최적화
  • 함수 선언문
  • API
  • 함수 표현식
  • getelapsedtime()
  • math.sin()
  • 함수 리터럴
  • 삼각함수
  • getdelta()
  • math.cos()

최근 글

관리자

글쓰기 / 스킨편집 / 관리자페이지
hELLO · Designed By 정상우.
wam

w__am 개발노트

조명, 그림자(Shadow) 처리하기
Frontend/Three.js

조명, 그림자(Shadow) 처리하기

2024. 11. 8. 22:32

 

그림자 추가

  /* Renderer 만들기 : html에 캔버스 미리 만들기 */
  const canvas = document.querySelector("#three-canvas");
  const renderer = new THREE.WebGLRenderer({
    canvas,
    antialias: true
  });
  renderer.setSize(window.innerWidth, window.innerHeight);
  renderer.setPixelRatio(window.devicePixelRatio > 1 ? 2 : 1);

  // 그림자 설정
  renderer.shadowMap.enabled = true;
  // renderer.shadowMap.type = THREE.PCFShadowMap;
  // renderer.shadowMap.type = THREE.BasicShadowMap;
  // renderer.shadowMap.type = THREE.PCFSoftShadowMap;

렌더러에서 그림자가 설정될 수 있게 세팅해줘야 한다.

조명, 각각의 물체에서도 그림자를 설정해줘야 그림자가 설정된다.

 

 

renderer.shadowMap.type 설정

  • THREE.js에서 renderer.shadowMap.type 설정은 그림자의 품질과 렌더링 성능에 영향을 주는 옵션이다.
  • 이 속성은 그림자가 어떻게 렌더링될지를 결정한다.
  • 각 옵션은 그림자의 디테일 수준과 성능에 차이가 있다.

 

 

THREE.BasicShadowMap

  • 기본적인 그림자 맵이다.
  • 속도가 가장 빠르지만, 그림자가 뚜렷하지 않고 저해상도로 표현된다.
  • 대형 그림자나 정밀한 그림자 표현이 필요하지 않은 경우 적합하다.
  • 3D이면서 픽셀 아트처럼 사용할 경우 적합하며 shadow.mapSize의 속성 크기를 줄여 조정하기도 한다.

 

 

THREE.PCFShadowMap

  • Percentage Closer Filtering (PCF) 방식으로 렌더링한다.
  • 그림자가 부드럽게 보이며, 기본 그림자 맵보다 디테일이 향상된다.
  • 다만 성능이 약간 저하될 수 있다.

 

 

THREE.PCFSoftShadowMap

  • PCF 방식에 추가적인 소프트 처리를 적용하여, 그림자가 매우 부드럽게 표현된다.
  • 가장 높은 품질의 그림자를 제공하지만, 성능이 더 많이 요구된다.

 

 

이러한 옵션을 선택할 때는 필요한 그림자 품질과 렌더링 성능을 고려해야 한다.

 

 

 

그림자는 기본적으로 두 가지를 세팅을 해준다. (CastShadow , Receive Shadow)

  /* Light 만들기 */
  // AmbientLight : 전체적으로 은은하게 깔아주는 조명
  const ambientLight = new THREE.AmbientLight("white", 0.5);
  scene.add(ambientLight);

  // DirectionalLight : 태양광 같은 조명
  const light = new THREE.DirectionalLight("red", 0.5);
  light.position.x = -5;
  light.position.y = 3;
  scene.add(light);

  // lightHelper: 조명을 시각적으로 확인하는 법
  const lightHelper = new THREE.DirectionalLightHelper(light);
  scene.add(lightHelper);

  // 조명에 그림자 설정
  light.castShadow = true; // 그림자를 만들 수 있는 조명이되는 것
  light.shadow.mapSize.width = 1024; // 기본값 512
  light.shadow.mapSize.height = 1024;
  light.shadow.camera.near = 1;
  light.shadow.camera.far = 30;
  // light.shadow.radius = 15; // 기본값인 THREE.PCFShadowMap에서만 적용, 그림자의 가장자리 부드러움을 조절
  
    /* Mesh 만들기 : Geometry + Material */
  const plane = new THREE.Mesh(planeGeometry, material1); // 평면 바닥에 깔기
  const box = new THREE.Mesh(boxGeometry, material2);
  const sphere = new THREE.Mesh(sphereGeometry, material3);

  plane.rotation.x = -Math.PI * 0.5;
  box.position.set(1, 1, 0);
  sphere.position.set(-1, 1, 0);

  // 물체에 그림자 설정
  plane.receiveShadow = true;
  box.castShadow = true;
  box.receiveShadow = true;
  sphere.castShadow = true;
  sphere.receiveShadow = true;

  scene.add(plane, box, sphere);

CastShadow, 다른 물체의 그림자가 생기게 영향을 줄 건지

Receive Shadow, 그 영향을 받아서 나한테 그림자가 그려지게 할 건지

 

 

plane에 그림자를 생기게 하려면 box, sphere에 CastShadow = true를 해줘야 한다. (바닥이기 때문에 그림자를 생기게 할 필요가없어 CastShadow = true를 해주지 않아도 된다. )

plane는 그 영향을 받아서 그림자를 그려야 되니까 receiveShadow = true 를 해주면 된다.

box, sphere도 서로의 물체가 그림자가 생길 거리에 있고 그림자 영향을 받고 싶다면 receiveShadow = true 를 해주면 된다.

 

 

light.castShadow = true;

  • 그림자를 만들 수 있는 조명이 되는 것
  • 특정 광원이 장면에서 그림자를 투사하도록 한다.
  • 즉, 이 광원이 빛을 비추는 모든 오브젝트에 그림자가 생길 수 있게 한다.
  • 이 설정이 없으면 광원은 단순히 빛만 비출 뿐, 그림자를 생성하지 않는다.
  • 만약 광원에 light.castShadow = true;가 되어 있어도, 장면에 있는 오브젝트들에 object.castShadow = true; 설정이 없으면 아무런 그림자가 생기지 않는다.
  • 반대로, object.castShadow = true;가 되어 있어도 광원이 castShadow = true;가 아니면 그림자가 생기지 않는다.

 

 

light.shadow.mapSize = true;

  • 그림자가 매끄럽지 않을 때 shadow.mapSize = true; 설정해 주기
  • 그림자 맵의 해상도를 설정하는 속성
  • 그림자의 선명도와 품질을 결정하는 중요한 요소이다.
  • 해상도는 width와 height로 설정되며, 예를 들어 shadow.mapSize.width = 1024 및 shadow.mapSize.height = 1024처럼 사용할 수 있다.
  • 높은 mapSize를 설정하면 그림자가 더 선명하고 자연스러워지지만, 성능에 부담을 줄 수 있다.
  • 반대로 낮은 값을 사용하면 성능이 향상되지만, 그림자가 픽셀화되어 보이거나 뭉개진 느낌을 줄 수 있다.
  • 보통, 화면에 보이는 오브젝트의 크기와 디테일을 고려하여 적절한 mapSize 값을 설정하는 것이 좋다. (보통 1024 ~ 2048로 세팅한다.)

 

 

light.shadow.radius

  • 기본값인 THREE.PCFShadowMap에서만 적용한다.
  • 그림자의 가장자리 부드러움을 조절하는 속성
  • 이 값이 클수록 그림자의 가장자리가 더 부드럽고 흐릿해지며, 경계선이 퍼지면서 부드러운 느낌이 들어 더욱 자연스러운 효과를 줄 수 있다.
  • 작은 값일수록 그림자 가장자리가 선명하고 날카롭게 보인다.

 

 

light.shadow.camera.near, light.shadow.camera.far

조명의 그림자 범위 정하기

 

 

object.castShadow = true;

  • 설정은 특정 광원(light)이 그림자를 투사하도록 만드는 것이다.
  • 이를 통해 광원이 물체에 그림자를 생성할 수 있다.

 

 

THREE.js에서 그림자를 구현할 때는 고려할 사항

  • 카메라 설정
    • 그림자가 투사될 범위와 품질에 영향을 미친다.
    • 림자의 범위를 조절하려면 광원의 그림자 카메라(light.shadow.camera) 속성들을 설정해야 한다.
  • 받는 객체 설정
    • 그림자가 투사되는 객체(object.receiveShadow = true;)가 그림자를 받을 수 있게 설정되어야 한다.
  • 렌더러 설정
    • 렌더러에서 그림자 맵을 활성화 해야 한다
    • (renderer.shadowMap.enabled = true;).

이러한 설정이 모두 맞아야 최종 장면에서 그림자가 정상적으로 나타난다.

 

 

object.receiveShadow = true;

  • 3D 그래픽에서 오브젝트가 다른 오브젝트로부터 그림자를 받는 기능을 말한다.
  • 이 설정이 활성화되면, 해당 오브젝트가 빛에 의해 투사된 다른 오브젝트의 그림자를 받을 수 있다.
  • 이를 통해 현실감 있는 장면을 만들 수 있다.
  • 예를 들어, 바닥이나 벽과 같은 오브젝트가 주변 오브젝트의 그림자를 받을 수 있도록 설정하면, 빛의 방향과 강도에 따라 보다 자연스러운 그림자 효과를 줄 수 있다.
  • 리시브 쉐도우는 보통 렌더링 엔진에서 오브젝트마다 개별적으로 활성화하거나 비활성화할 수 있으며, 사용되는 경우 성능에 영향을 줄 수 있다.
  • 따라서 중요한 오브젝트에만 이 옵션을 적용하는 것이 좋다.

 

 

저작자표시 변경금지 (새창열림)

'Frontend > Three.js' 카테고리의 다른 글

조명, SpotLight_스포트라이트 효과_무대 조명이나 손전등과 같은 빛을 표현  (0) 2024.11.10
조명, PointLight _ 특정 지점에서 빛이 모든 방향으로 퍼져나가는 조명 효과_ 전구나 촛불 같은 광원을 표현  (0) 2024.11.10
조명, Light 애니메이션  (0) 2024.11.03
삼각함수를 이용해 원형적인 움직임을 구현하기  (0) 2024.11.03
시간 흐름 측정, getDelta()와 getElapsedTime()  (0) 2024.11.03
    'Frontend/Three.js' 카테고리의 다른 글
    • 조명, SpotLight_스포트라이트 효과_무대 조명이나 손전등과 같은 빛을 표현
    • 조명, PointLight _ 특정 지점에서 빛이 모든 방향으로 퍼져나가는 조명 효과_ 전구나 촛불 같은 광원을 표현
    • 조명, Light 애니메이션
    • 삼각함수를 이용해 원형적인 움직임을 구현하기
    wam
    wam

    티스토리툴바