我正在通過GLSL食譜,但我正在用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
注意:如果,在旋轉的實例中,我移動相機接近到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()不返回任何錯誤。 另外,我在着色器中有很多調試代碼來驗證傳入的值是否正確 - 它們是。
這裏有渲染,更新和調整方法:
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矩陣的方法:
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
}
最後這裏是我的頂點着色器:
#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);
}
正如我所說,如果發佈的代碼是不足以得到問題的根源,我很樂意發佈其餘的內容。 在此先感謝您提供的任何建議。
我是否正確地閱讀它,您的投影矩陣實際上並不是任何一種投影,而是身份?所以你基本上只是在相機周圍旋轉場景,然後被[NDC立方體的遠平面(右邊的那個))剪裁(http://www.songho.ca/opengl/)文件/ gl_projectionmatrix01.png)?您是否嘗試過使用投影? – peppe
你是正確的,我使用單位矩陣作爲我的投影矩陣。這確實限制了我的剪輯距離爲1.並且正如皮爾斯在他的回答中指出的那樣,這也解釋了將模型從相機移開進而導致對近平面進行裁剪的事實。在回答關於投影矩陣的問題時,是的,我已經嘗試過了,但目前我無法使用它。如果我遇到問題,我會繼續嘗試並在此發佈另一個問題。謝謝。 – PrioryOfScion