Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/259.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么我的OpenGL场景剪辑的z距离为1?_C#_Opengl_Glsl_Opentk_Vertex Shader - Fatal编程技术网

C# 为什么我的OpenGL场景剪辑的z距离为1?

C# 为什么我的OpenGL场景剪辑的z距离为1?,c#,opengl,glsl,opentk,vertex-shader,C#,Opengl,Glsl,Opentk,Vertex Shader,我正在阅读GLSL食谱,但我正在使用C#编程,所以我尝试使用OpenTK转换代码。 我目前正在处理一个Phong着色示例,我可以使照明机制正常工作,但我使用的圆环模型不会渲染任何距离摄影机Z距离大于1的元素 下面是正确渲染的示例(x旋转=0,y旋转=0,camera.z=1,model.z=0) 这里应用了X和Y旋转(X旋转=-0.5,Y旋转=0.5,camera.z=1,model.z=0) 注意:在旋转的示例中,如果我将相机移近Z位置0.4,则圆环体将不进行剪裁。我不知道为什么把相机移近

我正在阅读GLSL食谱,但我正在使用C#编程,所以我尝试使用OpenTK转换代码。 我目前正在处理一个Phong着色示例,我可以使照明机制正常工作,但我使用的圆环模型不会渲染任何距离摄影机Z距离大于1的元素

下面是正确渲染的示例(x旋转=0,y旋转=0,camera.z=1,model.z=0)

这里应用了X和Y旋转(X旋转=-0.5,Y旋转=0.5,camera.z=1,model.z=0)

注意:在旋转的示例中,如果我将相机移近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 );
}
正如我所说,如果发布的代码不足以找到问题的根源,我很乐意发布其余的代码。
提前感谢您提供的任何建议。

我想说一切都按预期进行。OpenGL的剪辑空间约定是沿着规范化设备空间中所有3个轴的[-1,1]立方体。由于使用标识作为投影矩阵,因此眼睛空间将与NDC相同。换言之,可视范围将从相机后面的-1个单位变为相机前面的一个单位


更糟糕的是,典型的OpenGL惯例是眼睛空间是右手的(z指向你,相机是朝-z方向看),NDC/窗口空间是左手的(z轴指向屏幕)。投影矩阵通常进行翻转。因为你使用的是标识,所以你也不明白这一点——所以它可能感觉很不直观,但是当相机是
z_win=1

的时候,你是在对通常用作近平面的东西进行剪裁,你的投影矩阵实际上不是任何类型的投影,而是标识吗?所以你基本上只是在镜头周围旋转场景,然后被镜头剪辑?你试过用投影代替吗?你是对的,我用单位矩阵作为投影矩阵。这确实将我的剪辑距离限制为1。正如德哈斯在他的回答中指出的那样,这也解释了一个事实,即将模型移离相机更远会导致对近平面的剪切。在回答你关于投影矩阵的问题时,是的,我已经试过了,但是我现在无法让它工作。如果我有问题,我会继续尝试并在这里发布另一个问题。谢谢。关于左手坐标系和右手坐标系的转换,观点非常好。我一点也没想到。我曾尝试应用基于屏幕比例的透视矩阵,并在z方向上从0.01剪裁到100,但目前还没有成功。如果我仍然有问题,我会在这里发布另一个问题。