티스토리 뷰
RBRT의 경우 적분 형태이고;
PBR 관련 문서 중에 FrostBite였나 거긴 shader code가 첨부되어있다
하지만 바로 이해가 안되므로 설명을 찾아다녔다
GameDev 2009
https://www.gamedev.net/forums/topic/552315-glsl-area-light-implementation/
여러곳에서 사용되었다. 문제점은 존재하는 듯
댓글 중에 "FWIW, ever read this? It's mathematically correct and should be entirely feasible for real-time use. You can even do spherical and n-sided polygonal lights :)"
저기에 this는 아래 논문이다. 길고 이해도 안되서 접음
Area Light Sources for Real-Time Graphics, John Snyder
우선 구현부를 보면
vec3 right = normalize(vec3(gl_ModelViewMatrix*gl_LightSource.ambient));
구형 방식에다가 right를 ambient에 넣어서 대신 전달해서 먼지 이해하기 힘들다
좀 정리된 소스는 아래서 찾을 수 있었다
https://github.com/darrenmothersele/openFrameworks/blob/master/gl/ofMaterial.cpp
main branch에서는 shader로 분리된듯?
"areaLight"로 검색하면 된다
https://github.com/openframeworks/openFrameworks/tree/master/examples/gl/areaLightExample
해당 라이트는 우선 diffuse/specular로 나뉘는데 주요 연산은 단순히 light plane에
project 하여 벡터의 크기와 비교하는 것이다.
specular는 반사된 광원을 그리게 되는데
vec3 lightPos = light.position.xyz;
vec3 right = light.right;
// light plane normal, front direction
vec3 direction = light.spotDirection;
vec3 up = light.up;
float width = light.width * 0.5;
float height = light.height * 0.5;
vec3 r = reflect(normalize(uCameraPos - positionW), normalW);
vec3 e = linePlaneIntersect(positionW, r, lightPos, direction);
float specAngle = dot(r, direction);
if (specAngle > 0.0)
{
vec3 dirSpec = e - lightPos;
vec2 dirSpec2D = vec2(dot(dirSpec, right), dot(dirSpec, up));
vec2 nearestSpec2D = vec2(clamp(dirSpec2D.x, -width, width), clamp(dirSpec2D.y, -height, height));
// to get sharp edge line
float edgeFactor = 5.0;
specular += clamp(length(nearestSpec2D - dirSpec2D)*edgeFactor, 0, 1);
}
무식하게 단순화 시키면 결국 아래서 부터 시작한 거다
vec3 right = vec3(1, 0, 0);
// plane normal, front direction
vec3 planeNormal = vec3(0, -1, 0);
vec3 up = vec3(0, 0, 1);
float width = 5 * 0.5;
float height = 5 * 0.5;
if (positionW.x < width && positionW.x > -width &&
positionW.z < height && positionW.z > -height)
specular = vec3(1, 0, 0);
GPU Pro 5 - kill zone
specular/diffuse를 위해 one sample importance sampling을 한다는데 찾아보자
Ray-MMD
Area light의 소스는 Ray-MMD에서 최초로 봄. Referece는 FrostBite 라고 함.
https://computergraphics.stackexchange.com/questions/4139/physically-based-area-lights
twitter를 보면, LTC도 있다
https://twitter.com/Rui_cg/status/948148339530452992
GameDev 2013
https://www.gamedev.net/forums/topic/644255-improved-area-lighting-algorithm/
2013년의 three.js에는 ArKano22 방식으로 구현되어있었나 봄
https://va3c.github.io/three.js/examples/webgldeferred_arealights.html
Three.js
현재의 RectAreaLight 는 'Real-Time Polygonal-Light Shading with Linearly Transformed Cosines' 기반으로 되어있나 봄
https://github.com/mrdoob/three.js/issues/8718
Real-Time Area Lighting: a Journey From Research to Production
http://blog.selfshadow.com/publications/s2016-advances/
확실히 linear transform으로 90에 가까워질수록 오차가 크다
Real-Time Polygonal-Light Shading with Linearly Transformed Cosines
'Game > Graphics' 카테고리의 다른 글
Shader Uniform variable (0) | 2018.02.22 |
---|---|
Framebuffer (0) | 2018.02.20 |
GLSL include handling (0) | 2018.02.15 |
OpenGL profiler (0) | 2018.02.14 |
Modernize OpenGL (DSA) (0) | 2018.02.14 |
- Total
- Today
- Yesterday