2012-12-11 2 views
0

이전에이 유형의 질문을 보았지만 그 대답은 완전한 대답이 아니므로 코드를 게시하고 누구나 제공 할 수 있는지 확인합니다. 통찰력. 기본적으로이 코드는 작동하지만 마법의 z 오프셋 (높이 * 1.205) [너비에 관계없이] 이유는 모르겠다.원근감을 유지하면서 픽셀 해상도에서 WebGL 캔버스 사용하기

크기를 설정하고 정렬 벡터 생성 : 정렬 벡터 그리기

gl.viewportWidth = gl.canvas.width; 
gl.viewportHeight = gl.canvas.height; 
gl.viewportHalfWidth = gl.viewportWidth/2; 
gl.viewportHalfHeight = gl.viewportHeight/2; 
gl.viewportAspect = gl.viewportWidth/gl.viewportHeight; 
gl.viewportZoom = -gl.viewportHeight * 1.205; 
if (gl.alignmentTest) { 
    gl.alignmentVertices = (new Buffer( // TL, TM, BM, BR, TR, BL, TL 
     [ 1.0,      -1.0,     0.0, 
     gl.viewportHalfWidth - 0.5,  -1.0,     0.0, 
     gl.viewportHalfWidth - 0.5, -(gl.viewportHeight - 1.0), 0.0, 
     gl.viewportWidth - 1.0,  -(gl.viewportHeight - 1.0), 0.0, 
     gl.viewportWidth - 1.0,   -1.0,     0.0, 
      1.0,     -(gl.viewportHeight - 1.0), 0.0, 
      1.0,      -1.0,     0.0], 3)).post(); 
} 

을 : 문제

gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 
gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight); 
mat4.perspective(45, gl.viewportAspect, 0.1, 1000.0, gl.perspective.current); 
gl.perspective.post(); //^writes directly to current perspective buffer 

gl.modelView.resetToIdentity(); 

gl.enable(gl.BLEND); 
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); 

// Translate to pixel resolution 
gl.modelView.push(); 
gl.modelView.translate([-gl.viewportHalfWidth, gl.viewportHalfHeight, gl.viewportZoom]); 
gl.modelView.post(); 

// Alignment test? 
if (gl.alignmentTest && gl.alignmentVertices) { 
    gl.red.useAsAttribute(gl.shaderProg.vertexColour); 
    gl.zero.vec2.useAsAttribute(gl.shaderProg.vertexTextureCoord); 
    gl.alignmentVertices.drawAsPrimitives(gl.shaderProg.vertexPosition, gl.LINE_STRIP); 
} 

gl.disable(gl.BLEND); 

의 선은 다음과 같습니다

gl.viewportZoom = -gl.viewportHeight * 1.205; 

과 :

gl.modelView.translate([-gl.viewportHalfWidth, gl.viewportHalfHeight, gl.viewportZoom]); 

이 코드는 의 경우 크기에서 작동합니다. http://oi49.tinypic.com/2my9ir7.jpg

그리고 다른 400x600에서 : http://oi46.tinypic.com/i2irh3.jpg

그래서 질문입니다 : 왜 1.205의 마법 배율이 존재

여기에 700x300의 스크린 샷이다? 또는 내가 필요로하게하기 위해 무엇을 잘못 할 수 있습니까?

+0

귀하의 질문을 이해할 수 있는지 잘 모르겠습니다. 3x 수학을 사용하여 1x1 픽셀로 그려주는 쿼드를 그립니다. 첫 번째 확실한 대답은 "왜 3d 수학을 사용하여 2D를 그립니까?"입니다. "2D 수학으로 2D 그리기"(http://goo.gl/xQvx1).하지만 어떤 이유로 3D로 그려야하는 경우 두 번째 대답은 "이 이력서 행렬 사용"입니다. – gman

+0

드로잉하는 기본 요소는 이 특별한 인터페이스는 고전적인 2D 오브젝트를 3D 공간에 통합 할 필요가 있고 3D 오브젝트를 2D 인터페이스 내에서 조작 할 수 있도록 허용해야하므로 WebGL 공간을 캔버스 경계선에 비례하여 정렬해야합니다. 두 개를 따로 따로 취급하는 것이 이상적이 아니며 문제가되지 않아야합니다. 잘 작동하고 실제로 해킹되지 않는 경우도 있습니다. 왜 마법 번호가 필요한지 알고 싶습니다. 올바른 번호로 교체 할 수 있습니다. 계산. – jimmetry

+0

"WebGL 공간"이 없습니다 .WebGL은 픽셀의 사각형이며 사용자가 제공하는 일부 GLSL 함수입니다 .WebGL은 공백을 정의하지 않습니다. 귀하의 질문 제목 그래서 그것은 이해가 되니? "캔버스에서 1x1 픽셀로 표시되도록 3D 공간에서 질감이있는 유닛 쿼드를 정렬하려면 어떻게해야합니까?" – gman

답변

3

나는 수학을 계산하지 못했지만, 그 원인은 FOV와 near plane의 perspective 투영 행렬에서 발생한다고 생각합니다. 1 : 1 픽셀을 얻으려고하는 대부분의 응용 프로그램은 투시 투영을 사용하지 않습니다.

원근감을 사용해야하는 이유가 있다면 FOV 기반 원근감 계산을 사용하지 말고 대신 frustum 기반 (glFrustum- 모두)을 사용하십시오. 실제로 투영 절두체의 효과를 유도하는 것이 훨씬 쉽습니다. 손으로 조정하지 않고 첫 번째 원칙에서 수정 요인을 찾아 낼 수 있습니다.


이것은 본질적으로 삼각 문제입니다. 뷰 프러스 텀 또는 뷰 피라미드를 상상해보십시오 (즉, 가까운 평면과 먼 평면으로 절단되지 않음). 그것은 "카메라 위치"와 4 개의 경 사진면에 팁을 가지고 있습니다. 일반적으로 정의 된 FOV는 상단면과 하단면 사이의 각도와 같습니다 (이 때문에 너비가 영향을주지 않습니다). 그러나 사용자가 원하는 매개 변수는 각도가 아니며 경사도 (Z와 X 또는 Y 이동 비율) - 임의의 수치가 나오는 곳입니다.

만약 우리가 the documentation for good ol' gluPerspective (당신의 원근법 연산이 사용하는 것과 같은 수학을 사용한다고 가정 함)을 보면, 그것은 f = cotangent(fovy/2)입니다. 이것은 정확히 우리가 신경 쓰는 계산입니다. (이것을 재현하려한다면, 수학 라이브러리의 대부분의 삼각 함수는 각도가 아닌 라디안 단위의 각도를 취합니다.) 2의 인수는 FOV가 일반적으로 전체 뷰 각도로 측정되기 때문에 발생하지만 관심 값은 다음과 같습니다. 그것의 절반, 즉 "직선"과 "보기 가장자리"사이의 각도.

알고 계신 것처럼, 코탄센트 (또는 접선) 함수의 값은 기울기로 해석 될 수 있습니다.이 슬로프 f은 Z 이동과 X 또는 Y 이동 사이의 비율을 정확하게 알려줍니다. 예를 들어, 어떤 값을 d 값으로 개체의 크기를 조절하고 Z 축을 따라 f*d만큼 이동하면 크기가 변경되지 않습니다. 이것은 당신의 viewportZoom 이미 일을 정확히 할 수있다 :

당신의 1.205에 꽤 가까운
f/2 = cot(45°/2)/2 ≈ 1.207106 

. 이것이 실제로 사실이라면, 나는 2의 요인이 어디에서 오는지를 해결하지 못했습니다.

f (또는 tan(fovy/2)에 따라 최종적으로 어느 것이 더 편리할까요?) 계산하고 둘 다 사용하여 "확대/축소"거리와 투영 행렬을 계산하면됩니다.


은 (그건 그렇고, 당신의 코드가 WebGL을, 예를 들어 Buffer, post, drawAsPrimitives없는 물건을 많이, 등 당신이 사용하고있는 라이브러리 언급 한 경우 잠재적으로 도움이 될 것입니다 포함되어 있습니다.)

+0

감사합니다. 처음에 그것이 FOV와 관련 있다고 생각했지만, 그렇다면 폭이 영향을 미칠 것으로 예상했습니다. FOV의 작동 방식을 설명하는 훌륭한 자료를 알고 있습니까? 내가 본 모든 것 "이것은 당신의 시야입니다 .45로 설정하십시오." 2D 오브젝트, 3D 오브젝트 및 두 번째 캔버스 오버레이 (인터페이스 편집 용)가 혼합되어 있으므로 전체 원근감과 1 : 1 픽셀이 필요합니다. 나는 절두체에 관해서는 아무 것도 모르지만, 투영 행렬에 의존하고 있다고 생각합니다. 어쩌면 나는 무언가를 이해하지 못하고있다. – jimmetry

+0

(라이브러리에 관해서 : 그것은 내 자신의 것이고, 그것은 매우 불완전합니다. 사람들이 그것을 사용하고 싶다면 그것을 공유하게되어 기쁠 것입니다. 그러나 질문의 ​​범위에 대해 직관적이라고 생각했습니다.) – jimmetry

+0

@jimmetry I 'm FOV 수학에 대한 토론을 추가했습니다. –

관련 문제