A_A_S05 2024-09-21 12:33 采纳率: 66.7%
浏览 5
已结题

opengl多点光源阴影贴图渲染算法问题

我在用opengl尝试实现一个多点光源阴影贴图的功能,但现在渲染出来的图像总是有问题,主要是最大的平面上的阴影无法显示,这是为什么?
显示错误如下:

img

这是我的代码,目前是有阴影实现的,但是显示的很奇怪,调试了很久也没搞明白哪里有问题(感觉是算法问题),glGetError也没有报错

...//初始化

    glEnable(GL_DEPTH_TEST);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    Shader shader("D:/cppalbum/shader/lighting/pointDepth/multiDepthVert.glsl",
        "D:/cppalbum/shader/lighting/pointDepth/multiDepthFrag.glsl");
    Shader simpleDepthShader("D:/cppalbum/shader/lighting/pointDepth/cubeVert.glsl",
        "D:/cppalbum/shader/lighting/pointDepth/cubeFrag.glsl",
        "D:/cppalbum/shader/lighting/pointDepth/cubeGeo.glsl");
    Shader lightBoxShader("D:/cppalbum/shader/lighting/delay/lightVert.glsl",
        "D:/cppalbum/shader/lighting/delay/lightFrag.glsl");
    shader.use();
    shader.setInt("diffuseTexture", 0);
    shader.setInt("depthMap", 1);


    float planeVertices[] = {
        // positions            // normals         // texcoords
         25.0f, -0.5f,  25.0f,  0.0f, 1.0f, 0.0f,  25.0f,  0.0f,
        -25.0f, -0.5f,  25.0f,  0.0f, 1.0f, 0.0f,   0.0f,  0.0f,
        -25.0f, -0.5f, -25.0f,  0.0f, 1.0f, 0.0f,   0.0f, 25.0f,

         25.0f, -0.5f,  25.0f,  0.0f, 1.0f, 0.0f,  25.0f,  0.0f,
        -25.0f, -0.5f, -25.0f,  0.0f, 1.0f, 0.0f,   0.0f, 25.0f,
         25.0f, -0.5f, -25.0f,  0.0f, 1.0f, 0.0f,  25.0f, 25.0f
    };
    unsigned int planeVBO;
    glGenVertexArrays(1, &planeVAO);
    glGenBuffers(1, &planeVBO);
    glBindVertexArray(planeVAO);
    glBindBuffer(GL_ARRAY_BUFFER, planeVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(planeVertices), planeVertices, GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
    glEnableVertexAttribArray(2);
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
    glBindVertexArray(0);

    unsigned int woodTexture = loadTexture("D:/cppalbum/texture/Wooden_floor.jpg");


    // create depth texture

    shader.use();
    shader.setInt("diffuseTexture", 0);
    shader.setInt("shadowMap", 1);

    const unsigned int SHADOW_WIDTH = 1024, SHADOW_HEIGHT = 1024;
    unsigned int depthMapFBO;
    glGenFramebuffers(1, &depthMapFBO);
    // create depth cubemap texture
    unsigned int depthCubeMapArray;
    glGenTextures(1, &depthCubeMapArray);
    glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, depthCubeMapArray);
    // 为每个立方体贴图分配内存
    glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_DEPTH_COMPONENT,
        SHADOW_WIDTH, SHADOW_HEIGHT, 2 * 6, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
    // 设置纹理参数
    glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
    glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthCubeMapArray, 0);

    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
        std::cout << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!" << std::endl;
    glBindFramebuffer(GL_FRAMEBUFFER, 0);






    glm::vec3 lightPos[2] = {
        glm::vec3(-2.0f, 4.0f, -1.0f),
        glm::vec3(-3.0f, 5.0f, -2.0f)
    };


    //主循环
    // ------------------------------------------------------------------
    while (!glfwWindowShouldClose(window))
    {
        // per-frame time logic
        // --------------------
        float currentFrame = static_cast<float>(glfwGetTime());
        deltaTime = currentFrame - lastFrame;
        lastFrame = currentFrame;

        // input
        // -----
        processInput(window);


        glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
        glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        float near_plane = 1.0f;
        float far_plane = 25.0f;
        glm::mat4 shadowProj = glm::perspective(glm::radians(90.0f), (float)SHADOW_WIDTH / (float)SHADOW_HEIGHT, near_plane, far_plane);
        for (int i = 0; i < 2; ++i)
        {
            std::vector<glm::mat4> shadowTransforms;
            shadowTransforms.push_back(shadowProj *
                glm::lookAt(lightPos[i], lightPos[i] + glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)));
            shadowTransforms.push_back(shadowProj *
                glm::lookAt(lightPos[i], lightPos[i] + glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)));
            shadowTransforms.push_back(shadowProj *
                glm::lookAt(lightPos[i], lightPos[i] + glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f)));
            shadowTransforms.push_back(shadowProj *
                glm::lookAt(lightPos[i], lightPos[i] + glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f)));
            shadowTransforms.push_back(shadowProj *
                glm::lookAt(lightPos[i], lightPos[i] + glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, -1.0f, 0.0f)));
            shadowTransforms.push_back(shadowProj *
                glm::lookAt(lightPos[i], lightPos[i] + glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, -1.0f, 0.0f)));
            glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT);
            glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthCubeMapArray, 0, i * 6);
            glClear(GL_DEPTH_BUFFER_BIT);
            simpleDepthShader.use();
            for (unsigned int j = 0; j < 6; ++j)
                simpleDepthShader.setMat4("shadowMatrices[" + std::to_string(j) + "]", shadowTransforms[j]);
            simpleDepthShader.setFloat("far_plane", far_plane);
            simpleDepthShader.setVec3("lightPos", lightPos[i]);
            renderScene(simpleDepthShader);
        }
        glBindFramebuffer(GL_FRAMEBUFFER, 0);


        glViewport(0, 0, SCR_WIDTH, SCR_HEIGHT);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        shader.use();
        glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
        glm::mat4 view = camera.GetViewMatrix();
        shader.setMat4("projection", projection);
        shader.setMat4("view", view);
        // set lighting uniforms
        for (unsigned int i = 0; i < 2; ++i)
            shader.setVec3("lightPos[" + std::to_string(i) + "]", lightPos[i]);
        shader.setVec3("viewPos", camera.Position);
        shader.setInt("shadows", shadows); // enable/disable shadows by pressing 'SPACE'
        shader.setFloat("far_plane", far_plane);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, woodTexture);
        glActiveTexture(GL_TEXTURE1);
        glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, depthCubeMapArray);
        renderScene(shader);
        lightBoxShader.use();
        lightBoxShader.setMat4("projection", projection);
        lightBoxShader.setMat4("view", view);
        lightBoxShader.setVec3("lightColor", glm::vec3(1.0f, 1.0f, 1.0f));
        glm::mat4 model = glm::mat4(1.0f);
        for (int i = 0; i < 2; ++i)
        {
            model = glm::mat4(1.0f);
            model = glm::translate(model, lightPos[i]);
            model = glm::scale(model, glm::vec3(0.1f, 0.1f, 0.1f));
            lightBoxShader.setMat4("model", model);
            renderCube();
        }


        cout << glGetError() << endl;

        



        // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
        // -------------------------------------------------------------------------------
        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    // optional: de-allocate all resources once they've outlived their purpose:
    // ------------------------------------------------------------------------
    glfwTerminate();
    return 0;
}

void renderScene(const Shader& shader)
{
    // floor
    glm::mat4 model = glm::mat4(1.0f);
    shader.setMat4("model", model);
    glBindVertexArray(planeVAO);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    // cubes
    model = glm::mat4(1.0f);
    model = glm::translate(model, glm::vec3(0.0f, 1.5f, 0.0));
    model = glm::scale(model, glm::vec3(0.5f));
    shader.setMat4("model", model);
    renderCube();
    model = glm::mat4(1.0f);
    model = glm::translate(model, glm::vec3(2.0f, 0.0f, 1.0));
    model = glm::scale(model, glm::vec3(0.5f));
    shader.setMat4("model", model);
    renderCube();
    model = glm::mat4(1.0f);
    model = glm::translate(model, glm::vec3(-1.0f, 0.0f, 2.0));
    model = glm::rotate(model, glm::radians(60.0f), glm::normalize(glm::vec3(1.0, 0.0, 1.0)));
    model = glm::scale(model, glm::vec3(0.25));
    shader.setMat4("model", model);
    renderCube();
}

unsigned int cubeVAO = 0;
unsigned int cubeVBO = 0;
void renderCube()
{
    // initialize (if necessary)
    if (cubeVAO == 0)
    {
        float vertices[] = {
            // back face
            -1.0f, -1.0f, -1.0f,  0.0f,  0.0f, -1.0f, 0.0f, 0.0f, // bottom-left
             1.0f,  1.0f, -1.0f,  0.0f,  0.0f, -1.0f, 1.0f, 1.0f, // top-right
             1.0f, -1.0f, -1.0f,  0.0f,  0.0f, -1.0f, 1.0f, 0.0f, // bottom-right         
             1.0f,  1.0f, -1.0f,  0.0f,  0.0f, -1.0f, 1.0f, 1.0f, // top-right
            -1.0f, -1.0f, -1.0f,  0.0f,  0.0f, -1.0f, 0.0f, 0.0f, // bottom-left
            -1.0f,  1.0f, -1.0f,  0.0f,  0.0f, -1.0f, 0.0f, 1.0f, // top-left
            // front face
            -1.0f, -1.0f,  1.0f,  0.0f,  0.0f,  1.0f, 0.0f, 0.0f, // bottom-left
             1.0f, -1.0f,  1.0f,  0.0f,  0.0f,  1.0f, 1.0f, 0.0f, // bottom-right
             1.0f,  1.0f,  1.0f,  0.0f,  0.0f,  1.0f, 1.0f, 1.0f, // top-right
             1.0f,  1.0f,  1.0f,  0.0f,  0.0f,  1.0f, 1.0f, 1.0f, // top-right
            -1.0f,  1.0f,  1.0f,  0.0f,  0.0f,  1.0f, 0.0f, 1.0f, // top-left
            -1.0f, -1.0f,  1.0f,  0.0f,  0.0f,  1.0f, 0.0f, 0.0f, // bottom-left
            // left face
            -1.0f,  1.0f,  1.0f, -1.0f,  0.0f,  0.0f, 1.0f, 0.0f, // top-right
            -1.0f,  1.0f, -1.0f, -1.0f,  0.0f,  0.0f, 1.0f, 1.0f, // top-left
            -1.0f, -1.0f, -1.0f, -1.0f,  0.0f,  0.0f, 0.0f, 1.0f, // bottom-left
            -1.0f, -1.0f, -1.0f, -1.0f,  0.0f,  0.0f, 0.0f, 1.0f, // bottom-left
            -1.0f, -1.0f,  1.0f, -1.0f,  0.0f,  0.0f, 0.0f, 0.0f, // bottom-right
            -1.0f,  1.0f,  1.0f, -1.0f,  0.0f,  0.0f, 1.0f, 0.0f, // top-right
            // right face
             1.0f,  1.0f,  1.0f,  1.0f,  0.0f,  0.0f, 1.0f, 0.0f, // top-left
             1.0f, -1.0f, -1.0f,  1.0f,  0.0f,  0.0f, 0.0f, 1.0f, // bottom-right
             1.0f,  1.0f, -1.0f,  1.0f,  0.0f,  0.0f, 1.0f, 1.0f, // top-right         
             1.0f, -1.0f, -1.0f,  1.0f,  0.0f,  0.0f, 0.0f, 1.0f, // bottom-right
             1.0f,  1.0f,  1.0f,  1.0f,  0.0f,  0.0f, 1.0f, 0.0f, // top-left
             1.0f, -1.0f,  1.0f,  1.0f,  0.0f,  0.0f, 0.0f, 0.0f, // bottom-left     
             // bottom face
             -1.0f, -1.0f, -1.0f,  0.0f, -1.0f,  0.0f, 0.0f, 1.0f, // top-right
              1.0f, -1.0f, -1.0f,  0.0f, -1.0f,  0.0f, 1.0f, 1.0f, // top-left
              1.0f, -1.0f,  1.0f,  0.0f, -1.0f,  0.0f, 1.0f, 0.0f, // bottom-left
              1.0f, -1.0f,  1.0f,  0.0f, -1.0f,  0.0f, 1.0f, 0.0f, // bottom-left
             -1.0f, -1.0f,  1.0f,  0.0f, -1.0f,  0.0f, 0.0f, 0.0f, // bottom-right
             -1.0f, -1.0f, -1.0f,  0.0f, -1.0f,  0.0f, 0.0f, 1.0f, // top-right
             // top face
             -1.0f,  1.0f, -1.0f,  0.0f,  1.0f,  0.0f, 0.0f, 1.0f, // top-left
              1.0f,  1.0f , 1.0f,  0.0f,  1.0f,  0.0f, 1.0f, 0.0f, // bottom-right
              1.0f,  1.0f, -1.0f,  0.0f,  1.0f,  0.0f, 1.0f, 1.0f, // top-right     
              1.0f,  1.0f,  1.0f,  0.0f,  1.0f,  0.0f, 1.0f, 0.0f, // bottom-right
             -1.0f,  1.0f, -1.0f,  0.0f,  1.0f,  0.0f, 0.0f, 1.0f, // top-left
             -1.0f,  1.0f,  1.0f,  0.0f,  1.0f,  0.0f, 0.0f, 0.0f  // bottom-left        
        };
        glGenVertexArrays(1, &cubeVAO);
        glGenBuffers(1, &cubeVBO);
        // fill buffer
        glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
        // link vertex attributes
        glBindVertexArray(cubeVAO);
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
        glEnableVertexAttribArray(1);
        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
        glEnableVertexAttribArray(2);
        glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glBindVertexArray(0);
    }
    // render Cube
    glBindVertexArray(cubeVAO);
    glDrawArrays(GL_TRIANGLES, 0, 36);
    glBindVertexArray(0);
}

//其他不会有问题的函数

这是multiDepthFrag.glsl,应该也不会是别的着色器的问题


#version 420 core
out vec4 FragColor;

in VS_OUT {
    vec3 FragPos;
    vec3 Normal;
    vec2 TexCoords;
} fs_in;

uniform sampler2D diffuseTexture;
uniform samplerCubeArray depthMap;

uniform vec3 lightPos[2];
uniform vec3 viewPos;

uniform float far_plane;
uniform bool shadows;

vec3 sampleOffsetDirections[20] = vec3[]
(
   vec3( 1,  1,  1), vec3( 1, -1,  1), vec3(-1, -1,  1), vec3(-1,  1,  1), 
   vec3( 1,  1, -1), vec3( 1, -1, -1), vec3(-1, -1, -1), vec3(-1,  1, -1),
   vec3( 1,  1,  0), vec3( 1, -1,  0), vec3(-1, -1,  0), vec3(-1,  1,  0),
   vec3( 1,  0,  1), vec3(-1,  0,  1), vec3( 1,  0, -1), vec3(-1,  0, -1),
   vec3( 0,  1,  1), vec3( 0, -1,  1), vec3( 0, -1, -1), vec3( 0,  1, -1)
);

float ShadowCalculation(vec3 fragPos,int i)
{
    // Get vector between fragment position and light position
    vec3 fragToLight = fragPos - lightPos[i];
    float currentDepth = length(fragToLight);
    // Now test for shadows
    float shadow = 0.0;
    float bias = 0.05; 
    int samples = 20;
    float viewDistance = length(viewPos - fragPos);
    float diskRadius = (1.0 + (viewDistance / far_plane)) / 25.0;
    for (int j=0;j<samples;++j)
    {
        float closestDepth = texture(depthMap, vec4(fragToLight + sampleOffsetDirections[j] * diskRadius,i)).r;
        closestDepth *= far_plane;   // Undo mapping [0;1]
        if(currentDepth - bias > closestDepth)
            shadow += 1.0;
    }
    shadow /= samples;

    return shadow;
}

void main()
{           
    vec3 color = texture(diffuseTexture, fs_in.TexCoords).rgb;
    vec3 normal = normalize(fs_in.Normal);
    vec3 lightColor = vec3(0.3);
    // Ambient
    vec3 ambient = 0.3 * color;
    vec3 lighting = vec3(0.0f);
    int lightNum=2;
    float lightNums = lightNum;
    float shadowFactor = 0.0;
    vec3 diffuse= vec3(0.0f);
    vec3 specular= vec3(0.0f);
    // Diffuse
    for (int i=0;i<lightNum;++i)
    {
        vec3 lightDir = normalize(lightPos[i] - fs_in.FragPos);
        float diff = max(dot(lightDir, normal), 0.0);
        diffuse += (diff * lightColor);
    // Specular
        vec3 viewDir = normalize(viewPos - fs_in.FragPos);
        vec3 reflectDir = reflect(-lightDir, normal);
        float spec = 0.0;
        vec3 halfwayDir = normalize(lightDir + viewDir);  
        spec = pow(max(dot(normal, halfwayDir), 0.0), 64.0);
        specular += (spec * lightColor);    
    // Calculate shadow                    
        if (shadows)
        {
            shadowFactor += ShadowCalculation(fs_in.FragPos, i);
        }
    }
    specular /= lightNums;
    diffuse /= lightNums;
    shadowFactor = min(shadowFactor, 1.0);
    lighting += (ambient + (1.0 - shadowFactor) * (diffuse + specular));
    lighting *= color;
    FragColor = vec4(lighting, 1.0f);
    
}
  • 写回答

10条回答 默认 最新

  • 叫兽-郭老师 Java领域新星创作者 2024-09-21 12:34
    关注

    🕒下午好,题主!目前:🟢[在线]
    📢参考通义千问、由郭老师整理提供!
    📣今日诗号:落花人独立,微雨燕双飞。

    你遇到的问题是深度立方体贴图数组的阴影贴图渲染错误,导致最大平面无法显示阴影。主要原因可能是以下几个方面:

    1. glFramebufferTextureLayer 使用错误:

    • 在你的代码中,glFramebufferTextureLayer 函数调用中,layer 参数使用了 0,这意味着你每次都在更新立方体贴图数组的第一个立方体贴图的深度附件。你需要根据循环变量 i 来更新不同的立方体贴图层,例如 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthCubeMapArray, 0, i * 6 + j);

    2. 阴影计算中的错误:

    • 深度比较:ShadowCalculation 函数中,你正确地将采样深度乘以了 far_plane,但需要注意的是,texture 函数返回的深度值已经在 [0, 1] 范围内,不需要再次进行映射。
    • PCF 采样偏移: 你的 sampleOffsetDirections 数组定义了 20 个方向,但你的循环只采样了前 samples 个方向。你需要确保 samples 的值不超过数组大小,或者使用模运算符 % 来循环使用数组元素。

    修改后的代码:

    // ... 其他代码 ...
    
    // 主循环
    while (!glfwWindowShouldClose(window))
    {
        // ... 其他代码 ...
    
        glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
        // ... 其他代码 ...
    
        for (int i = 0; i < 2; ++i)
        {
            // ... 其他代码 ...
    
            glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT);
            
            for (unsigned int j = 0; j < 6; ++j) {
                glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthCubeMapArray, 0, i * 6 + j); // 注意这里的 layer 参数
                glClear(GL_DEPTH_BUFFER_BIT);
    
                // ... 其他代码 ...
            }
    
            // ... 其他代码 ...
        }
        
        // ... 其他代码 ...
    }
    
    // ... 其他代码 ...
    
    float ShadowCalculation(vec3 fragPos, int i) {
        // ... 其他代码 ...
    
        for (int j = 0; j < samples; ++j)
        {
            float closestDepth = texture(depthMap, vec4(fragToLight + sampleOffsetDirections[j % 20] * diskRadius, i)).r;  // 注意这里的模运算符
            // closestDepth *= far_plane;   // 不需要进行映射
            if (currentDepth - bias > closestDepth)
                shadow += 1.0;
        }
    
        // ... 其他代码 ...
    }
    

    其他建议:

    • 检查你的着色器代码,确保光源位置、视角位置等变量传递正确。
    • 尝试使用调试工具,例如 RenderDoc 或 NVIDIA Nsight Graphics,来检查深度缓冲区内容和阴影贴图采样结果,以便更直观地定位问题。
    • 逐步添加功能,例如先实现单个光源的阴影,然后再扩展到多个光源,这样更容易排查问题。

    希望以上建议能够帮助你解决阴影渲染问题!

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(9条)

报告相同问题?

问题事件

  • 系统已结题 9月29日
  • 已采纳回答 9月21日
  • 创建了问题 9月21日

悬赏问题

  • ¥15 如何解除Uniaccess管控
  • ¥15 微信小程序跳转关联公众号
  • ¥15 Java AES 算法 加密采用24位向量报错如何处理?
  • ¥15 使用X11可以找到托盘句柄,监控到窗口点击事件但是如何在监听的同时获取托盘中应用的上下文菜单句柄
  • ¥45 字符串操作——数组越界问题
  • ¥15 Loss下降到0.08时不在下降调整学习率也没用
  • ¥15 QT+FFmpeg使用GPU加速解码
  • ¥15 为什么投影机用酷喵播放电影放一段时间就播放不下去了?提示发生未知故障,有什么解决办法吗?
  • ¥15 来个会搭建付费网站的有偿
  • ¥100 有能够实现人机模式的c/c++代码,有图片背景等,能够直接进行游戏