0

任意のカメラからオブジェクトをレンダリングする射影行列を作成したいと思います。任意の目の位置からオブジェクトを見る viewMatrix を設定することができましたが、射影行列の設定が困難です。

(x,y,z) を中心とし、中心から最も遠い点が r であるオブジェクトは、任意の向きで、原点 (x,y,z) の半径 r の球内に完全に囲むことができると仮定すると、視点を計算しました。マトリックスは次のとおりです。

float dist2Object = (float) Math.sqrt(vec.lengthSquared());

float objectRadius = (float) Math.sqrt(3 * Math.pow(0.5, 2));
float far = dist2Object + objectRadius;
float near = dist2Object - objectRadius;

// fov_2 = FOV / 2
float fov_2 = (float) (Math.asin(objectRadius / dist2Object));

float r = (float) (Math.tan(fov_2));
float frustum_length = far - near;

depthProjectionMatrix.m00 = 1 / r;
depthProjectionMatrix.m11 = depthProjectionMatrix.m00;
depthProjectionMatrix.m22 = -((far + near) / frustum_length);
depthProjectionMatrix.m23 = -1;
depthProjectionMatrix.m32 = -((2 * near * far) / frustum_length);
depthProjectionMatrix.m33 = 0;

私の例では:

  • vec はカメラからオブジェクトへのベクトルです
  • オブジェクトは、最も遠い頂点が (0.5, 0.5, 0.5) の立方体であり、ar は sqrt(0.75) になります。

私が知る限り、ジオメトリと三角法は正しいはずですが、次のフラグメント シェーダーを使用して座標をレンダリングします。

#version 150 core

in vec3 pCoord;

out vec4 out_Color;

void main(void) {
    out_Color = vec4(0,1,0,1);
    if(pCoord.x <= -1){
        out_Color = vec4(1,0,0,1);
    }
    if(pCoord.x >= 1){
        out_Color = vec4(0,0,1,1);
    }
    if(pCoord.z <= -1){
        out_Color = vec4(1,0,1,1);
    }
    if(pCoord.z >= 1){
        out_Color = vec4(1,0,1,1);
    }
}

画像に示すように、FOV が狭すぎて、ニア プレーンとファー プレーンも狭すぎることがわかります。

どうすればこれを修正できますか?

4

1 に答える 1

0

しばらくこれを行っていませんが、計算でビューポートのサイズが不足しているようです。これが私がプロジェクトに使用したものです。ここの行列は、m00 を使用する _11 で始まることに注意してください。

double aspectRatio = (double)this.viewPort.Width /(double)this.viewPort.Height;
double fov = Math.toRadians(fieldOfView/2.0);
double size = nearClip * Math.tan(fov);

double left = -size* aspectRatio, right = size* aspectRatio, bottom = -size , top = size ;

projectionMatrix.resetToZero();

// the values in comments are for non symetrical frustrum 

// First Column
projectionMatrix._11 = (float) (nearClip/right);//(float) ((2 * nearClip )/ (double)(right - left));

// Second Column
projectionMatrix._22 = (float)(nearClip/top);//(float) (2 * nearClip / (double)(top - bottom));

// Third Column
projectionMatrix._31 = 0;//(float) ((right + left) / (right - left));
projectionMatrix._32 = 0;//(float) ((top + bottom) / (top - bottom));
projectionMatrix._33 = -1*(farClip + nearClip) / (float)(farClip - nearClip);
projectionMatrix._34 = -1;

// Fourth Column
projectionMatrix._43 = -(2 * farClip * nearClip) / (float)(farClip - nearClip);
于 2014-07-04T11:55:52.180 に答える