feat(site): 리퀴드 글래스 굴절을 올바른 변위 지도로 다시 붙인다
All checks were successful
ci / build (push) Successful in 29s

앞선 커밋에서 "backdrop-filter 체인에서 displacement 가 안 먹는다" 고 적고
데모를 뺐다. 틀렸다. svg-filters.md 에 이미 적혀 있던 두 규칙을 안 지킨 것이다.

- 변위 지도는 노이즈가 아니다. feTurbulence 로 만들면 값이 중립(128)으로
  수렴해 scale 을 아무리 키워도 곱해지는 값이 0 이다.
- feImage 의 크기는 요소 크기와 같아야 한다. 자동으로 안 맞춰준다.

가장자리에서 안쪽으로 미는 그라디언트를 직접 그렸다. linearGradient 한 장으로는
R 과 G 를 따로 못 만들므로 지도를 두 장 놓고 displacement 를 두 번 건다.
쓰지 않는 축에는 128 고정인 B 채널을 물려 이동량을 0 으로 만든다.

실측: 평균 채널차 1.66(난류 지도) → 9.29(그린 지도), 최대 126.
배경에 격자를 깔아 확인했다 — 패널 가장자리에서 격자 셀이 눌린다.

svg-filters.md 에 지도 두 장 기법과 확인 방법을 기록했다.
This commit is contained in:
Yun Chan 2026-08-20 23:30:15 +09:00
parent ae2980872b
commit 9a09678dee
4 changed files with 154 additions and 6 deletions

View file

@ -646,3 +646,42 @@ Chrome 151 에서 실측하면 computed 값이 `none` 이 아니라 `url("#id")`
> 진단법: 굴절이 안 보일 때 `scale` 부터 올리지 마라. 지도를 화면에 직접 그려
> **128 이 아닌 픽셀이 실제로 있는지** 먼저 봐라. 없으면 지도가 문제다.
### 지도를 SVG 로 그릴 때 — R 과 G 를 한 장에 못 담는다
`linearGradient` 하나로는 R 과 G 를 각각 다르게 변화시킬 수 없다.
겹쳐 그리면 뒤엣것이 앞엣것을 덮고, 블렌드 모드로는 채널이 섞인다.
**지도를 두 장 놓고 displacement 를 두 번 건다.** 쓰지 않는 축에는
128 로 고정된 `B` 채널을 물려 이동량을 0 으로 만든다.
```xml
<filter id="lens" color-interpolation-filters="sRGB" x="0" y="0" width="100%" height="100%">
<feImage href={MAP_X} x="0" y="0" width="216" height="72" result="mx"/>
<feDisplacementMap in="SourceGraphic" in2="mx" scale="30"
xChannelSelector="R" yChannelSelector="B" result="dx"/>
<feImage href={MAP_Y} x="0" y="0" width="216" height="72" result="my"/>
<feDisplacementMap in="dx" in2="my" scale="30"
xChannelSelector="B" yChannelSelector="G"/>
</filter>
```
지도 한 장은 가장자리에서만 중립을 벗어나는 그라디언트다.
data URI 안에서 `#` 은 URI 를 끊으므로 색은 `rgb()` 로 적는다.
```js
`<svg xmlns="http://www.w3.org/2000/svg" width="216" height="72">` +
`<defs><linearGradient id="g" x1="0" y1="0" x2="1" y2="0">` +
`<stop offset="0" stop-color="rgb(255,128,128)"/>` + // 왼쪽 끝: +X 최대
`<stop offset="0.30" stop-color="rgb(128,128,128)"/>` + // 가운데: 중립
`<stop offset="0.70" stop-color="rgb(128,128,128)"/>` +
`<stop offset="1" stop-color="rgb(0,128,128)"/>` + // 오른쪽 끝: -X 최대
`</linearGradient></defs>` +
`<rect width="216" height="72" fill="url(#g)"/></svg>`
```
**확인 방법**: 배경에 격자를 깔아라. 사진만 놓으면 무엇이 어떻게 밀렸는지 알 수 없다.
제대로 걸리면 **패널 가장자리에서 격자 셀이 눌린다** — 그것이 렌즈의 지문이다.
실측: 필터 전후 평균 채널차 1.66(난류 지도) → **9.29**(그린 지도), 최대 126.
`backdrop-filter` 앞의 `blur()` 는 약하게 둬라. 세게 걸면 굴절이 뭉개져서
지도를 고쳐도 차이가 안 보인다.