백페이스 컬링

Backface culling

카메라 반대쪽을 향한 면(뒷면)은 애초에 그리지 않고 건너뛰어, 필요 없는 계산을 아끼는 최적화.

다른 이름: Face cullingmaterial.side
···
html
<div class="sub-caps"><span>single-sided · culled</span><span>double-sided</span></div>
css
.sub-caps{position:absolute;left:0;right:0;bottom:6%;display:flex;justify-content:space-around;font-size:clamp(8px,2.4vmin,12px);color:#dfe3ffcc;text-align:center;padding:0 3%}
js
import * as THREE from 'three';
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(Math.min(devicePixelRatio, 2));
document.body.appendChild(renderer.domElement);
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x0b0b14);
const camera = new THREE.PerspectiveCamera(42, 1, 0.1, 100);
camera.position.set(0, 0.3, 6);

const geo = new THREE.PlaneGeometry(2.1, 2.6);
const single = new THREE.Mesh(geo, new THREE.MeshStandardMaterial({ color: 0xff9a5a, side: THREE.FrontSide, roughness: 0.5 }));
single.position.x = -1.7;
const double = new THREE.Mesh(geo, new THREE.MeshStandardMaterial({ color: 0x8ecbff, side: THREE.DoubleSide, roughness: 0.5 }));
double.position.x = 1.7;
scene.add(single, double);
const key = new THREE.DirectionalLight(0xffffff, 1.7); key.position.set(3, 4, 5); scene.add(key);
scene.add(new THREE.AmbientLight(0xffffff, 0.55));

function resize() { renderer.setSize(innerWidth, innerHeight); camera.aspect = innerWidth / innerHeight; camera.updateProjectionMatrix(); }
addEventListener('resize', resize); resize();
renderer.setAnimationLoop((t) => {
  const r = t * 0.0005;
  single.rotation.y = r; double.rotation.y = r;
  renderer.render(scene, camera);
});

닫힌 형태(속이 꽉 찬 것처럼 보이는 큐브, 캐릭터 등)는 안쪽 면이 항상 바깥쪽 면에 가려져서 카메라에 보이지 않습니다. 그런데도 그 안쪽 면까지 매번 그린다면 GPU가 아무도 안 보는 픽셀을 계산하느라 절반의 노력을 낭비하는 셈입니다. 백페이스 컬링은 각 면의 방향(법선)이 카메라를 향하는지 등지는지를 미리 판별해서, 등지고 있으면 아예 그리기 단계에서 제외해 버립니다.

이건 성능 최적화이자 동시에 함정이기도 합니다 — 얇은 평면이나 옷처럼 뒷면도 봐야 하는 오브젝트에 기본 설정(단면만 그리기)을 그대로 두면, 반대쪽에서 보는 순간 아예 사라져 버립니다. three.js의 material.side는 FrontSide(기본, 컬링 있음)·BackSide·DoubleSide(양면 다 그림, 컬링 없음) 중에서 고르게 해줍니다.

Blender·Maya·C4D의 뷰포트에도 "백페이스 컬링" 토글이 있어서, 실시간 렌더러가 실제로 어떤 면을 버리는지 미리 확인하게 해줍니다. 게임 엔진에서 벽이나 지형 안쪽처럼 절대 안 보이는 면은 아예 모델링 단계에서 지워버리는 것도 같은 이유의 최적화입니다.

언제 쓰나

실시간 성능을 아낄 때는 기본값(컬링 켜짐)을 유지하고, 천이나 얇은 판처럼 양면이 다 보여야 하면 DoubleSide로 바꾸세요.