임의의 카메라에서 광선을 투사하는 방법은 무엇입니까?
-
18-09-2019 - |
문제
저는 광선 추적기를 작성 중입니다(차이가 있는 경우 왼손 좌표를 사용).원리를 스스로 가르치기 위한 것이므로 OpenGL이나 피사계 심도와 같은 복잡한 기능을 (아직) 사용하지 않습니다.내 카메라는 임의의 위치와 방향을 가질 수 있습니다.나는 그것들을 세 개의 벡터를 통해 표시합니다. location
, look_at
, 그리고 sky
, 이는 다음과 같이 동작합니다. 동등한 POV-Ray 벡터.그것의 "영화"는 또한 width
그리고 height
.(그만큼 focal
길이는 거리에 따라 결정됩니다. position
에게 look_at
.)
내 문제는 광선을 투사하는 방법을 모른다는 것입니다.수량은 2개 있는데, vx
그리고 vy
, 이는 광선이 끝나야 하는 위치를 나타냅니다.둘 다 -1에서 1까지 다양합니다.둘 다 -1이면 카메라 위치에서 "필름"의 왼쪽 상단 모서리로 광선을 캐스팅합니다.둘 다 1이면 오른쪽 하단;둘 다 0이면 중앙이고;나머지는 분명합니다.
나는 광선에 대한 방정식을 도출할 만큼 벡터 산술에 익숙하지 않습니다.그렇게 하는 방법에 대한 설명을 부탁드립니다.
해결책
당신은 이미 수행해야 할 작업을 아주 잘 설명했습니다.시야는 카메라와 광선을 투사할 "필름" 사이의 거리에 따라 결정됩니다.카메라가 필름에서 멀어질수록 시야는 좁아집니다.
카메라가 가리키는 비트맵 이미지로 영화를 상상해 보세요.비트맵에서 한 단위 떨어진 곳에 카메라를 배치한다고 가정해 보겠습니다.그런 다음 비트맵의 각 픽셀을 통해 광선을 투사해야 합니다.
벡터는 매우 간단합니다.카메라 위치를 (0,0,0)에 놓고 비트맵 필름 바로 앞에 중앙을 (0,0,1)에 두는 경우 오른쪽 하단의 광선은 - 짜잔 - (1, 1,1), 왼쪽 하단에 있는 것은 (-1,1,1)입니다.
즉, 오른쪽 하단과 왼쪽 하단의 차이는 (2,0,0)입니다.
수평 비트맵 해상도가 1000이어야 한다고 가정하면 다음과 같이 최종 라인 픽셀을 반복할 수 있습니다.
width = 1000;
cameraToBottomLeft = (-1,1,1);
bottomLeftToBottomRight = (2,0,0);
for (x = 0; x < width; x++) {
ray = cameraToBottomLeft + (x/width) * bottomLeftToBottomRight;
...
}
그것이 분명하다면 선에 대해 동등한 외부 루프를 추가하기만 하면 필요한 모든 광선을 얻을 수 있습니다.
그런 다음 카메라와 필름의 거리, 수평 및 수직 해상도에 대한 적절한 변수를 추가할 수 있습니다.완료되면 행렬 변환을 사용하여 Look 벡터와 Up 벡터를 변경할 수 있습니다.
컴퓨터 그래픽에 대해 머리를 감고 싶다면 입문 교과서 큰 도움이 될 수 있습니다.나는 사용했다 이 하나 대학에서, 나는 그것을 좋아했다고 생각합니다.