HLSL로 광각 / 어안 렌즈를 만들려면 어떻게해야합니까?


29

다양한 말단의 광각 렌즈의 효과를 달성하기 위해 구현해야하는 개념은 무엇입니까?

컨텐츠 파이프 라인의 다양한 단계를 참조하는 의사 코드 및 특정 설명과 소스 코드에서 HLSL로 전달해야하는 정보는 매우 유용합니다.

또한 광각 렌즈 구현과 어안 렌즈의 차이점은 무엇입니까?

답변:


37

광각 렌즈는 다른 일반 렌즈 모델과 다르게 작동해서는 안됩니다. 그것들은 더 큰 FOV ( D3DXMatrixPerspectiveFovLHDirectX를 사용한다고 가정합니다) 또는 더 큰 왼쪽 / 오른쪽 및 아래쪽 / 상단 값 (OpenGL glFrustum의미)을 가지고 있습니다.

정말 흥미로운 부분은 어안 렌즈 모델링에 있다고 생각합니다. 거기에 어안이 지진 이 소스와 함께 제공, 당신이 공부할 수있다.

진정한 어안 투영

그러나 어안 렌즈의 투영은 매우 비선형 적입니다. 보다 일반적인 (감시 카메라로 제한된 내 지식) 종류의 렌즈 M에서 공간 반점이 단위 반구의 표면에 투영 된 다음 해당 표면이 단위 디스크에 평행 투영됩니다.

           M
             x                 M: world position
              \                M': projection of M on the unit hemisphere
               \  ______       M": projection of M' on the unit disc (= the screen)
             M'_x'      `-.
             ,' |\         `.
            /   | \          \
           /    |  \          \
          |     |   \          |
__________|_____|____\_________|_________
                M"    O        1

더 재미있는 효과를 줄 수 있는 다른 어안 매핑 이 있습니다. 그것은 당신에게 달려 있습니다.

HLSL에서 어안 효과를 구현하는 두 가지 방법을 볼 수 있습니다.

방법 1 : 정점 셰이더에서 투영 수행

장점 : 코드에서 거의 변경할 필요가 없습니다. 프래그먼트 셰이더는 매우 간단합니다. 오히려 :

...
float4 screenPoint = mul(worldPoint, worldViewProjMatrix);
...

다음과 같이하십시오 (아마도 단순화 될 수 있습니다).

...
// This is optional, but it computes the z coordinate we will
// need later for Z sorting.
float4 out_Point = mul(in_Point, worldViewProjMatrix);

// This retrieves the world position so that we can project on
// the hemisphere. Normalise this vector and you get M'
float4 tmpPoint = mul(in_Point, worldViewMatrix);

// This computes the xy coordinates of M", which happen to
// be the same as M'.
out_Point.xy = tmpPoint.xy / length(tmpPoint.xyz);
...

단점 : 전체 렌더링 파이프 라인은 선형 변환에 대해 고려되었으므로 결과 투영은 정점에 대해 정확하지만 텍스처 좌표뿐만 아니라 모든 변화가 잘못되고 삼각형은 왜곡 된 것처럼 보이더라도 삼각형으로 표시됩니다.

해결 방법 : 더 많은 삼각형 세분으로 GPU에 세련된 지오메트리를 보내면 더 나은 근사치를 얻을 수 있습니다. 이 작업은 지오메트리 셰이더에서도 수행 될 수 있지만이 단계는 정점 셰이더 이후에 수행되므로 지오메트리 셰이더는 자체 추가 투영을 수행해야하기 때문에 상당히 복잡합니다.

방법 2 : 프래그먼트 셰이더에서 프로젝션 수행

또 다른 방법은 광각 투영을 사용하여 장면을 렌더링 한 다음 전체 화면 조각 셰이더를 사용하여 어안 효과를 얻기 위해 이미지를 왜곡하는 것입니다.

어안 화면에 점 M에 좌표가 있으면 반구 표면에 (x,y)좌표가 있음을 의미합니다 . 어떤이 좌표 한 의미 의 FOV로 렌더링 우리의 장면에서 그러한가 . (여기서 나의 수학에 대해 100 % 확신하지 못합니다. 오늘 밤 다시 확인하겠습니다).(x,y,z)z = sqrt(1-x*x-y*y)(ax,ay)thetaa = 1/(z*tan(theta/2))

따라서 프래그먼트 셰이더는 다음과 같습니다.

void main(in float4 in_Point : POSITION,
          uniform float u_Theta,
          uniform sampler2D u_RenderBuffer,
          out float4 out_FragColor : COLOR)
{
    z = sqrt(1.0 - in_Point.x * in_Point.x - in_Point.y * in_Point.y);
    float a = 1.0 / (z * tan(u_Theta * 0.5));
    out_FragColor = tex2D(u_RenderBuffer, (in_Point.xy - 0.5) * 2.0 * a);
}

장점 : 픽셀 정확도로 인한 왜곡없이 완벽한 투사를 얻을 수 있습니다.

단점 : FOV가 180도에 도달 할 수 없으므로 전체 장면을 물리적으로 볼 수 없습니다. 또한 FOV가 클수록 이미지 중앙의 정밀도가 떨어집니다. 정확하게 최대 정밀도를 원하는 위치입니다.

해결 방법 : 예를 들어 5와 같은 여러 렌더링 패스를 수행하여 큐브 손실 방식으로 투영을 수행하면 정밀도 손실을 개선 할 수 있습니다. 또 다른 매우 간단한 해결 방법은 최종 이미지를 원하는 FOV로 간단히 자르는 것입니다. 렌즈 자체에 180도 FOV가 있어도 일부만 렌더링 할 수 있습니다. 이것을 "풀 프레임"어안이라고합니다 (이것은 실제로 이미지를 자르면서 "풀"무언가를 얻는 느낌을주기 때문에 다소 아이러니합니다).

(참고 :이 유용하지만 명확하지 않은 경우 알려주세요. 이에 대한 자세한 기사를 작성하고 싶습니다.)


매우 유용하며 더 자세히 작성하고자하는 기사를 진심으로 환영합니다!
SirYakalot

더 나은 결과를 얻기 위해 두 가지 방법을 결합 할 수 있습니까? 먼저 VS에서 투영하여 모든 것을 볼 수 있고 PS에서 투영을 해제하고 다시 투영하여 올바른 UV 및 모든 것을 얻습니까? 원본에 올바르게 투사하지 않으려면 PS에 몇 가지 매개 변수를 더 보내야합니다.
Ondrej Petrzilka

3

맞아야 z = sqrt(1.0 - in_Point.x * in_Point.x - in_Point.y * in_Point.y)합니까?

내 GLSL 구현은 다음과 같습니다

#ifdef GL_ES
precision mediump float;
#endif

varying vec2 v_texCoord;
uniform sampler2D u_texture;
uniform float fovTheta; // FOV's theta

// fisheye
void main (void)
{   
    vec2 uv = v_texCoord - 0.5;
    float z = sqrt(1.0 - uv.x * uv.x - uv.y * uv.y);
    float a = 1.0 / (z * tan(fovTheta * 0.5));
//  float a = (z * tan(fovTheta * 0.5)) / 1.0; // reverse lens
    gl_FragColor = texture2D(u_texture, (uv* a) + 0.5);
}

안녕하세요 @Josh, fovTheta는 어떻게 계산 되었습니까?
tom

1
서식을 조정하기 위해이 답변 만 편집했습니다. @ bman을 직접 처리하고 싶습니다.
Josh
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.