You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用深度FBO实现阴影贴图出现异常问题求助

OpenGL阴影贴图Clear调用导致渲染异常(Silk.Net)

我用Silk.Net进行OpenGL交互,加载.obj文件获取模型与材质数据,原本所有功能运行正常。参照LearnOpenGL教程添加阴影贴图功能时,仅绑定帧缓冲、纹理但不进行任何操作,着色器与渲染仍正常;但只要执行Clear()调用,屏幕就会变黑——还发现着色器中未设置的AlphaTexture莫名返回全1.0值,部分计算也出现错误。已经耗费大量时间排查,急需帮助,以下是相关代码:

帧缓冲初始化代码(Light.cs)

public unsafe void InitShadowMap(GL gl)
{
    // Generate framebuffer
    _shadowMapFbo = gl.GenFramebuffer();
    gl.BindFramebuffer(FramebufferTarget.Framebuffer, _shadowMapFbo);

    // Generate depth texture
    ShadowMap = gl.GenTexture();
    gl.BindTexture(TextureTarget.Texture2D, ShadowMap);
    gl.TexImage2D(TextureTarget.Texture2D, 0, InternalFormat.DepthComponent, ShadowWidth, ShadowHeight, 0, PixelFormat.DepthComponent, PixelType.Float, null);

    // Set texture parameters
    gl.TexParameterI(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToBorder);
    gl.TexParameterI(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToBorder);
    gl.TexParameterI(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
    gl.TexParameterI(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);

    // Set border color
    float[] borderColor = { 1.0f, 1.0f, 1.0f, 1.0f };
    gl.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureBorderColor, borderColor);

    // Attach depth texture as FBO's depth buffer
    gl.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment, TextureTarget.Texture2D, ShadowMap, 0);
    gl.DrawBuffer(DrawBufferMode.None);
    gl.ReadBuffer(ReadBufferMode.None);

    // Check if framebuffer is complete
    if (gl.CheckFramebufferStatus(FramebufferTarget.Framebuffer) != GLEnum.FramebufferComplete)
    {
        Console.WriteLine("Framebuffer not complete");
    }

    // Unbind framebuffer
    gl.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
}

帧缓冲绑定代码

public void BindFramebuffer(GL gl)
{
    gl.BindFramebuffer(FramebufferTarget.Framebuffer, _shadowMapFbo);
    gl.Viewport(0, 0, ShadowWidth, ShadowHeight);
    gl.Clear(ClearBufferMask.DepthBufferBit); // even just this breaks everything
}

渲染逻辑代码(Scene.cs)

public unsafe void Draw(GL gl, Shader shader)
{
    int[] oldViewport = new int[4];
    gl.GetInteger(GetPName.Viewport, (Span<int>)oldViewport);
    Lights[0].BindFramebuffer(gl);
    _shadowShader!.Use(gl);
    var lightSpaceMatrix = Lights[0].GetLightSpaceMatrix();
    gl.UniformMatrix4(_shadowShader.GetUniformLocation(gl, ViewMatrixVariableName), 1, false, (float*)&lightSpaceMatrix);
    // Program.CheckError();
    // // Program.CheckError();
    // foreach (var obj in Objects)
    // {
    //     obj.Draw(gl, _shadowShader, false);
    // }
    gl.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
    // Program.CheckError();
    shader.Use(gl);
    // Program.CheckError();
    gl.UniformMatrix4(shader.GetUniformLocation(gl, LightSpaceMatrixVariableName), 1, false, (float*)&lightSpaceMatrix);
    // Program.CheckError();
    gl.Viewport(oldViewport[0], oldViewport[1], (uint)oldViewport[2], (uint)oldViewport[3]);
    // Program.CheckError();
    //
    gl.ActiveTexture(TextureUnit.Texture15);
    // Program.CheckError();
    gl.BindTexture(TextureTarget.Texture2D, Lights[0].ShadowMap);
    // Program.CheckError();
    gl.Uniform1(shader.GetUniformLocation(gl, ShadowMapVariableName), 15);
    // Program.CheckError();
    //
    gl.Clear(ClearBufferMask.DepthBufferBit | ClearBufferMask.ColorBufferBit);
    SetViewerPosition(gl, shader);
    SetViewMatrix(gl, shader);
    SkyBox?.Draw(gl, shader);
    foreach (var obj in Objects)
    {
        obj.Draw(gl, shader);
    }
}

即使不对着色器添加任何阴影相关代码,渲染也会异常,因此我认为不是着色器的问题(着色器同样参照了LearnOpenGL教程,文件位于Resources目录下)。

内容的提问来源于stack exchange,提问作者CodeForFun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 05:28:11