2017-03-22 2 views
1

내 과제는 선형 대수와 컬러를 사용하여 실시간으로 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. 

이 방법에 대한 잘못된 점은 무엇입니까? 왜 이렇게 느린가요?

감사합니다.

답변

4

내가 제대로 코딩 된 경우 (모든 libs가없는) 순수 SW 래스터 라이저에 표준 시스템에 > 20 FPS를 얻어야한다 그래서 정말 복잡하지 3#으로 갈 것입니다. 내 느린 API과 같이 PutPixel 또는 SetPixel과 같은 느린 것을 사용하고 있거나 미친 짓을하고 있습니다. 당신이 어떻게하는지에 대한 코드 또는 더 나은 설명을 보지 않고서는 자세히 설명하기가 어렵습니다. 이 작업을 수행하는 데 필요한 모든 정보가 여기에 있습니다

각각의 하위 링크도 보이나요 ...

+0

감사 당신의 대답은 대단히 당신에게 있습니다.나는 투영 기하학에 익숙하다. 나는 나의 구현에 대해보다 명확한 설명을 게시하려고 노력했다. – Gerry

+0

@Gerry JAVAScript는 제 차가 아니지만 코드를 빠르게 보면서 삼각형 코드가 너무 느리게 보입니다. 암시 적 삼각형 방정식을 기반으로하기 때문에 각 픽셀 당 너무 많은 계산을 수행합니다 (렌더링되지 않은 경우에도). 그래서 내 내기가 당신의 주된 병목입니다. 내 링크 된 답변의 코드를 비교하십시오. 볼록 다각형 뒤에있는 수학을 모르는 경우 거기에있는 하위 링크를 참조하십시오. – Spektre

+0

@Gerry 올바르게 보시려면 다음을 수행하십시오 : 행렬 계산 + 일부 벡터 수학 및 조건 + 함수 하위 호출 각 렌더링 된 삼각형의 bbox의 각 픽셀. 그것은 당신이 SW를 렌더링하는 경우가 아닌 병렬 처리 할 수있는 전용 HW에 있지 않는 한 미친 짓이다. 비교를 위해 광산 접근법은 각 삼각형 당 3 배의 DDA와 수평선 집합으로 채우는 픽셀을 사용합니다. – Spektre