내 과제는 선형 대수와 컬러를 사용하여 실시간으로 2 차원 함수의 플롯을 생성하는 것입니다 (함수 정의에서 일반 C++로 이미지 버퍼를 계산해야한다는 것을 상상해보십시오, 예를 들어 f x, y) = x^2 + y^2). 출력은 3d plot과 같아야합니다. 지금까지 시도했다 3 개 방법 :렌더링 2 차원 함수 플롯
1 : 광선 추적 : 삼각형으로
나누기 (x, y) 평면을 따라서 삼각형으로 플롯 나누어, 각 정점의 z 값을 찾기. 각 광선과 삼각형을 교차시킵니다.
2 구 트레이싱 :
방법을 암시 표면 렌더링은 here 설명했다.
3 : 래스터 화 :
(1)의 역함수. 플롯을 삼각형으로 분할하고, 카메라 평면에 투영하고, 캔버스의 픽셀을 반복하고, 각각에 대해 "가장 가까운"투영 된 픽셀을 선택하십시오.
이러한 모든 방법이 느려집니다. 내 임무 중 일부는 카메라를 중심으로 움직이므로 각 프레임에서 플롯을 다시 렌더링해야합니다. 다른 정보원/다른 알고리즘/어떤 종류의 도움을 주시길 바랍니다. 고맙습니다.
편집
으로 여기 내 아주 기본적인 래스터 라이저에 대한 의사입니다 지적했다. 이 코드는 완벽하지는 않을 수도 있지만 일반적인 생각과 비슷해야합니다. 그러나 내 플롯을 200 삼각형으로 분할 할 때 (나는 충분히 기대하지 않습니다), 아무 것도 렌더링하지 않고도 이미 매우 천천히 실행됩니다. 나는 가시성을 위해 깊이 버퍼를 사용하지도 않는다.
참고을 : 난 그냥 다음과 같이 프레임 버퍼를 설정하여 속도를 테스트하고 싶어 내가 사용하고있는 자바 스크립트 프레임 워크에서 _
배열 색인을 표시하고 a..b
이 A에서 B로 목록을 구성한다.
/*
* Raster setup.
* The raster is a pxH x pxW array.
* Raster coordinates might be negative or larger than the array dimensions.
* When rendering (i.e. filling the array) positions outside the visible raster will not be filled (i.e. colored).
*/
pxW := Width of the screen in pixels.
pxH := Height of the screen in pixels.
T := Transformation matrix of homogeneous world points to raster space.
// Buffer setup.
colBuffer = apply(1..pxW, apply(1..pxH, 0)); // pxH x pxW array of black pixels.
// Positive/0 if the point is on the right side of the line (V1,V2)/exactly on the line.
// p2D := point to test.
// V1, V2 := two vertices of the triangle.
edgeFunction(p2D, V1, V2) := (
det([p2D-V1, V2-V1]);
);
fillBuffer(V0, V1, V2) := (
// Dehomogenize.
hV0 = V0/(V0_3);
hV1 = V1/(V1_3);
hV2 = V2/(V2_3);
// Find boundaries of the triangle in raster space.
xMin = min(hV0.x, hV1.x, hV2.x);
xMax = max(hV0.x, hV1.x, hV2.x);
yMin = min(hV0.y, hV1.y, hV2.y);
yMax = max(hV0.y, hV1.y, hV2.y);
xMin = floor(if(xMin >= 0, xMin, 0));
xMax = ceil(if(xMax < pxW, xMax, pxW));
yMin = floor(if(yMin >= 0, yMin, 0));
yMax = ceil(if(yMax < pxH, yMax, pxH));
// Check for all points "close to" the triangle in raster space whether they lie inside it.
forall(xMin..xMax, x, forall(yMin..yMax, y, (
p2D = (x,y);
i = edgeFunction(p2D, hV0.xy, hV1.xy) * edgeFunction(p2D, hV1.xy, hV2.xy) * edgeFunction(p2D, hV2.xy, hV0.xy);
if (i > 0, colBuffer_y_x = 1); // Fill all points inside the triangle with some placeholder.
)));
);
mapTrianglesToScreen() := (
tvRaster = homogVerts * T; // Triangle vertices in raster space.
forall(1..(length(tvRaster)/3), i, (
actualI = i/3 + 1;
fillBuffer(tvRaster_actualI, tvRaster_(actualI + 1), tvRaster_(actualI + 2));
));
);
// After all this, render the colBuffer.
이 방법에 대한 잘못된 점은 무엇입니까? 왜 이렇게 느린가요?
감사합니다.
감사 당신의 대답은 대단히 당신에게 있습니다.나는 투영 기하학에 익숙하다. 나는 나의 구현에 대해보다 명확한 설명을 게시하려고 노력했다. – Gerry
@Gerry JAVAScript는 제 차가 아니지만 코드를 빠르게 보면서 삼각형 코드가 너무 느리게 보입니다. 암시 적 삼각형 방정식을 기반으로하기 때문에 각 픽셀 당 너무 많은 계산을 수행합니다 (렌더링되지 않은 경우에도). 그래서 내 내기가 당신의 주된 병목입니다. 내 링크 된 답변의 코드를 비교하십시오. 볼록 다각형 뒤에있는 수학을 모르는 경우 거기에있는 하위 링크를 참조하십시오. – Spektre
@Gerry 올바르게 보시려면 다음을 수행하십시오 : 행렬 계산 + 일부 벡터 수학 및 조건 + 함수 하위 호출 각 렌더링 된 삼각형의 bbox의 각 픽셀. 그것은 당신이 SW를 렌더링하는 경우가 아닌 병렬 처리 할 수있는 전용 HW에 있지 않는 한 미친 짓이다. 비교를 위해 광산 접근법은 각 삼각형 당 3 배의 DDA와 수평선 집합으로 채우는 픽셀을 사용합니다. – Spektre