私はGLSL Cookbookを使っていますが、C#でプログラミングしていますので、OpenTKを使ってコードを変換しようとしています。 私は現在Phong Shadingの例を使っていますが、ライティングの仕組みを正しく動作させることができますが、私が使用しているトーラスモデルでは、Z距離が1より大きい要素はレンダリングされませんカメラ。ここOpenGLのシーンがz距離1でクリッピングされるのはなぜですか?
は(X回転= 0、Y = 0回転、camera.z = 1、model.z = 0) Torus Rendering Correctly
ここでは、印加されるXとYの回転にある(正しく描画例でありますX回転= -0.5、Y回転= 0.5、camera.z = 1、model.z = 0) Torus rotated showing clipping
注、回転の例では、Iは、Z位置に近いカメラを動かす場合0.4の場合、トーラスはクリッピングすることなく現れます。なぜカメラを近づけば、クリッピングが起こりにくいのか分かりません。
コードがたくさんあるので、投稿するのを避けようとします。もし私がもう投稿する必要があるなら、私はそうすることを喜んでします。
void InitProgram()
{
// Compile and link shaders
Compile();
// Turn on depth testing
GL.Enable(EnableCap.DepthTest);
// Torus centred at (0,0,0), outer radius = 0.7, inner
// radius = 0.3, 50 segments, 50 rings
_torus = new VboTorus(0.7f, 0.3f, 50, 50);
// Setup model matrix
_model = Matrix4.Identity;
_model *= Matrix4.CreateRotationX(-0.5f);
_model *= Matrix4.CreateRotationY(0.5f);
// Setup view matrix
_view = Matrix4.LookAt(0f, 0f, 0.4f, 0f, 0f, 0.0f, 0f, 1f, 0f);
// Setup projection matrix
_projection = Matrix4.Identity;
// Position the light
var lightPos = new Vector4(5f, 5f, 2f, 1f);
// Bind lighting attributes
BindLightUniformBlock(lightPos);
// Bind material attributes
BindMaterialUniformBlock();
// Output any errors
var pil = GL.GetProgramInfoLog(_pgmId);
Console.WriteLine(pil);
}
注:GetProgramInfoLog()すべてのエラーを返しません
は、ここに私の初期化ブロックです。 また、シェーダーに渡される値が正しいことを確認するために、多くのデバッグコードがありました。最終的にここに
private void SetMatrices()
{
var modelView = _view*_model;
var uniformIndices = new int[3];
GL.GetUniformIndices(_pgmId, 3, new[] { "modelViewMatrix", "normalMatrix", "mvpMatrix" }, uniformIndices);
GL.UniformMatrix4(uniformIndices[0], false, ref modelView); // Set modelView matrix uniform
var normMatrix = new float[]
{
modelView.M11, modelView.M21, modelView.M31,
modelView.M12, modelView.M22, modelView.M32,
modelView.M13, modelView.M23, modelView.M33
};
GL.UniformMatrix3(uniformIndices[1], 1, false, normMatrix); // Set normal matrix uniform
var temp = _projection*modelView;
GL.UniformMatrix4(uniformIndices[2], false, ref temp); // Set lightPosition uniform
}
そして、私の頂点シェーダは、次のとおりです。ここで
protected override void OnUpdateFrame(FrameEventArgs e)
{
base.OnUpdateFrame(e);
if (Keyboard[Key.Escape])
Exit();
GL.UseProgram(_pgmId);
}
protected override void OnRenderFrame(FrameEventArgs e)
{
base.OnRenderFrame(e);
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
SetMatrices();
_torus.Render();
GL.Flush();
SwapBuffers();
}
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
GL.Viewport(0, 0, Width, Height);
}
は私M、V & P行列を設定するための方法であって、ここで は、レンダリング、アップデートやサイズを変更する方法です。
#version 430
layout (location = 0) in vec3 vertexPosition;
layout (location = 1) in vec3 vertexNormal;
layout(std140) uniform lightInfo {
vec4 position;
vec3 ambientIntensity;
vec3 diffuseIntensity;
vec3 specularIntensity;
} light;
layout(std140) uniform materialInfo {
vec3 ambientReflectivity;
vec3 diffuseReflectivity;
vec3 specularReflectivity;
float shininess;
} material;
uniform mat4 modelViewMatrix;
uniform mat3 normalMatrix;
uniform mat4 mvpMatrix;
out vec3 lightIntensity;
void main()
{
// Convert normal and position to eye coords
vec3 tNorm = normalize(normalMatrix * vertexNormal);
vec4 eyeCoords = modelViewMatrix * vec4(vertexPosition, 1.0);
vec3 s = normalize(vec3(light.position - eyeCoords));
vec3 v = normalize(-eyeCoords.xyz);
vec3 r = reflect(-s, tNorm);
vec3 ambient = light.ambientIntensity * material.ambientReflectivity;
float sDotN = max(dot(s, tNorm), 0.0);
vec3 diffuse = light.diffuseIntensity * material.diffuseReflectivity * sDotN;
// The diffuse shading equation
vec3 spec = vec3(0.0);
if(sDotN > 0.0)
{
spec = light.specularIntensity * material.specularReflectivity * pow(max(dot(r, v), 0.0), material.shininess);
}
lightIntensity = ambient + diffuse + spec;
// Convert position to clip coordinates and pass along
gl_Position = mvpMatrix * vec4(vertexPosition, 1.0);
}
私が言ったように、投稿されたコードでは十分ではない場合問題の根本は、私は残りの部分を投稿して満足しています。 アドバイスをいただきありがとうございます。
私はあなたの投影行列は実際にはどんな種類の投影ではなく、アイデンティティであることを正しく読んでいますか?だから、あなたは基本的にlookAtのせいでカメラの周りのシーンを回転させていて、NDCキューブの遠方の平面(右のもの)で切り取っています(http://www.songho.ca/opengl/ファイル/ gl_projectionmatrix01.png)?代わりにプロジェクションを試しましたか? – peppe
私は、私の投影行列として単位行列を使用している点で正しいです。これは本当に私にクリッピング距離が1になることを制限します。そして、彼の答えでderhassが指摘しているように、モデルをカメラから遠くに移動させると、近くの平面に対してクリッピングが発生するという事実も考慮されます。投影行列に関するご質問に答えて、私はそれを試しましたが、現時点では動作させることができません。私は問題があれば、ここで別の質問を投稿しようとし続けます。ありがとう。 – PrioryOfScion