히어로와 파이프라인이 같은 씬을 쓰던 것을 나눈다
게이트 씬을 파이프라인으로 옮기면서 히어로에도 남겨뒀더니 같은 그림이
페이지에 두 번 나왔다. 역할이 다르면 씬도 달라야 한다.
히어로 shader-plane 흐름 필드 노이즈를 두 번 접어 빛의 결을 만든다
공간을 만드는 재질. 아무것도 반응 안 한다
파이프라인 gate-scene 유리판 여섯 통과하면 그 단계가 켜진다. 주인공
재료 shader-plane 스테이지 필터 타일이 앉는 무대
히어로에는 무거운 씬을 임포트하지 않는다 — three.md §0 대로 셰이더 플레인 하나다.
lib/hero-scene.ts -> lib/gate-scene.ts 로 리네임했다. 이름이 용도와 다르면
다음 사람이 히어로 것인 줄 알고 고친다.
대비 실측: 캔버스 배경 최악 8.46:1(가장 밝은 중앙 여백), h1 자리 14.83:1.
readPixels 로 재려다 전부 0 이 나왔다 — preserveDrawingBuffer: false 면
버퍼가 비어 있다. 스크린샷 픽셀로 쟀고, 글자 없는 영역만 골랐다.
스킬 three.md
씬을 두 자리에 재사용하지 마라. 역할(주인공/재질/무대)로 나눠라
파일 이름을 용도와 맞춰라
WebGL 위 대비는 readPixels 가 아니라 스크린샷 픽셀로 잰다.
0 을 검정으로 착각하면 대비가 통과한 것처럼 보인다
This commit is contained in:
parent
af3a08397e
commit
91bb4ae9dc
5 changed files with 124 additions and 29 deletions
|
|
@ -1,33 +1,20 @@
|
|||
/**
|
||||
* 히어로 3D 씬 — 파이프라인 게이트.
|
||||
* 게이트 씬 — 유리판 여섯 장이 깊이 축에 서고, 스크롤하면 카메라가 통과한다.
|
||||
*
|
||||
* 유리 판 여섯 장이 깊이 축에 차례로 서 있다. 이 스킬의 여섯 단계다.
|
||||
* 스크롤하면 카메라가 판을 하나씩 통과하고, 지나온 판은 뒤에 남아 겹친다.
|
||||
* 파이프라인 섹션 전용이다. 한때 히어로 배경으로도 썼는데, 그러면 같은 그림이
|
||||
* 페이지에 두 번 나온다. 그리고 히어로에는 옆에서 반응할 콘텐츠가 없어서
|
||||
* 의미를 판독기가 자막으로 설명해야 했다 — 그림이 스스로 말하지 못한다는 뜻이다.
|
||||
* 히어로 배경은 `shader-plane.ts` 의 흐름 필드가 맡는다.
|
||||
*
|
||||
* 형태에 이유가 있다. 이 제품이 파는 것은 순서이고("순서를 바꾸지 마라"가
|
||||
* 절대 규칙이다), 순서를 깊이로 옮기는 것은 은유가 아니라 직역이다.
|
||||
* 판이 여섯인 이유도 여기서 나온다. 아래 Pipeline 섹션의 여섯 단계와 같은 수다.
|
||||
*
|
||||
* 조사 결론(research/three/08-proposal.md): 우리가 파는 것은 무형이라
|
||||
* 구체 오브젝트가 성립하지 않는다. GLB 는 쓰지 않는다. 지오메트리는 코드다.
|
||||
*
|
||||
* 구현 방식과 그 이유:
|
||||
* 배경 그라디언트를 렌더 타겟에 한 번 그리고, 유리 판이 그 텍스처를
|
||||
* UV 를 밀어서 샘플링한다. MeshPhysicalMaterial 의 transmission 은
|
||||
* 매 프레임 씬을 다시 렌더하므로 판 한 장만 있어도 비싸다.
|
||||
* references/three.md 가 그 비용을 경고한다. 렌더 타겟 한 장이면
|
||||
* 같은 인상을 훨씬 싸게 얻는다.
|
||||
*
|
||||
* 예산 규칙은 그대로 지킨다:
|
||||
* 성능 게이트는 references/three.md 그대로다.
|
||||
* - three 는 초기 번들에 없다. 화면에 가까워질 때만 받는다
|
||||
* - DPR 클램프 1.5
|
||||
* - DPR 클램프 1.5. 저사양이면 판을 여섯에서 셋으로 줄인다
|
||||
* - 화면 밖이거나 탭이 숨으면 그리지 않는다
|
||||
* - 저사양이면 판 수를 줄인다
|
||||
* - WebGL 이 없거나 모션을 줄이는 설정이면 아예 시작하지 않는다.
|
||||
* 그때 보이는 CSS 그라디언트가 폴백이 아니라 결과물이다
|
||||
*/
|
||||
|
||||
export interface HeroSceneOptions {
|
||||
export interface GateSceneOptions {
|
||||
canvas: HTMLCanvasElement;
|
||||
/** CSS 커스텀 프로퍼티 이름 */
|
||||
accentVar: string;
|
||||
|
|
@ -61,7 +48,7 @@ const NOISE = `
|
|||
}
|
||||
`;
|
||||
|
||||
export function mountHeroScene(opts: HeroSceneOptions): void {
|
||||
export function mountGateScene(opts: GateSceneOptions): void {
|
||||
if (matchMedia("(prefers-reduced-motion: reduce)").matches) return;
|
||||
const { canvas } = opts;
|
||||
|
||||
|
|
@ -76,7 +63,7 @@ export function mountHeroScene(opts: HeroSceneOptions): void {
|
|||
io.observe(canvas);
|
||||
}
|
||||
|
||||
async function boot({ canvas, accentVar, glowVar, onGate, progressFrom }: HeroSceneOptions): Promise<void> {
|
||||
async function boot({ canvas, accentVar, glowVar, onGate, progressFrom }: GateSceneOptions): Promise<void> {
|
||||
let THREE: typeof import("three");
|
||||
try {
|
||||
THREE = await import("three");
|
||||
Loading…
Add table
Add a link
Reference in a new issue