Quick Syntax
hlsl
float3 worldPos = center + corner.x * cameraRight * size.x
+ corner.y * cameraUp * size.y;
float fog = saturate((viewDistance - fogStart) / max(fogEnd - fogStart, 1e-5));
color.rgb = lerp(color.rgb, fogColor, fog);Billboard는 quad의 local corner를 camera right·up 축으로 펼칩니다. Fog distance는 clip-space z가 아니라 일관된 world 또는 view-space 거리로 계산합니다.
구현 선택
CPU에서 quad vertex를 만들 수 있지만 particle 수가 많으면 point 또는 instance data만 보내고 VS·GS에서 확장할 수 있습니다. Geometry shader 확장이 항상 가장 빠른 것은 아니므로 instanced quad와 실제 GPU 측정을 비교합니다.
Spherical billboard는 camera의 right·up을 모두 쓰고 cylindrical billboard는 world up을 고정해 수직을 유지합니다. Transparent particle은 blend mode, depth test, depth write와 정렬 정책을 함께 정해야 합니다.
자주 틀리는 점
fogEnd == fogStart인 설정으로 나누지 않습니다.- Particle alpha texture를 잘못된 premultiplied/straight blend state와 섞지 않습니다.
- Camera 뒤의 billboard가 방향을 뒤집는지 확인합니다.
- Fog를 이미 tone-mapped color에 적용할지 HDR lighting 전에 적용할지 renderer 계약을 고정합니다.
참고 링크
2 sources