Closed. This question is off-topic。它当前不接受答案。
                            
                        
                    
                
                            
                                
                
                        
                            
                        
                    
                        
                            想改善这个问题吗? Update the question,所以它是on-topic,用于堆栈溢出。
                        
                        2小时前关闭。
                                                                                            
                
        
因此,我一直试图在我的C ++ vulkan渲染引擎中使点光源工作,直到我添加实际的漫反射效果,一切似乎都可以正常工作。当我的点灯(由Gizmo指示的位置)在此花盆的右侧时,花盆将正确照亮,如下所示:

c++ - 点光源着色器的怪异行为-LMLPHP

但是,当光从这个花盆的左边离开时,它是完全黑暗的:

c++ - 点光源着色器的怪异行为-LMLPHP

我发现这很奇怪,因为点光源应仅将光散射到各个方向,但是几乎就像光源仅沿一种方向前进或物体法线存在问题一样,就像它们仅以一种方式瞄准一样。我觉得我在忽略着色器中的一些菜鸟错误:

顶点着色器

// shader uniform buffer
struct MVP {
    mat4 m;
    mat4 v;
    mat4 p;
    vec3 light_position;
};

// uniform buffer binding
layout(binding = 0) uniform Camera {
    MVP mvp;
} ubo;

// vertex attributes
layout(location = 0) in vec3 pos;
layout(location = 1) in vec2 uv;
layout(location = 2) in vec3 normal;

layout(location = 0) out vec4 out_color;
layout(location = 1) out vec2 out_uv;
layout(location = 2) out vec3 out_normal;
layout(location = 3) out vec3 out_pos;
layout(location = 4) out vec3 out_light_pos;

// DEBUG COLORS
vec3 colors[4] = vec3[](
    vec3(1.0, 0.0, 0.0),
    vec3(0.0, 1.0, 0.0),
    vec3(0.0, 0.0, 1.0),
    vec3(0.0, 0.0, 1.0)
);

void main() {
    // CAMERA SPACE
    gl_Position = ubo.mvp.p * ubo.mvp.v * ubo.mvp.m * vec4(pos, 1.0);
    out_pos = vec3(ubo.mvp.v * ubo.mvp.m * vec4(pos, 1.0));
    out_normal = mat3(transpose(inverse(ubo.mvp.v * ubo.mvp.m))) * normal;
    out_light_pos = vec3(ubo.mvp.v * vec4(ubo.mvp.light_position, 1.0));
    out_uv = uv;

    // DEBUG COLOR INDEX
    int index = gl_VertexIndex;
    clamp(index, 0, 4);

    out_color = vec4(colors[index], 1.0);
}


片段着色器

// in vars
layout(location = 0) in vec4 color;
layout(location = 1) in vec2 uv;
layout(location = 2) in vec3 normal;
layout(location = 3) in vec3 pos;
layout(location = 4) in vec3 light_pos;

// in uniforms
layout(set = 0, binding = 1) uniform sampler2D tex_sampler[24];
layout(push_constant) uniform pushConstants {
    int samplerIndex;
} pc;

// out vars
layout(location = 0) out vec4 final_color;

void main() {
    // LIGHT CONSTANTS
    float constant = 1.0f;
    float linear = 0.7;
    float quadratic = 1.8;
    vec3 light_color = vec3(1.0, 0.7725, 0.56);

    vec4 sampled = texture( tex_sampler[pc.samplerIndex], uv);

    // ambient
    float ambient_strength = 0.1f;
    vec3 ambient = ambient_strength * sampled.xyz;

    // diffuse
    vec3 norm = normalize(normal);
    vec3 light_dir = normalize(light_pos - pos);
    float diff = clamp(dot(norm, light_dir), 0, 1);
    // TODO: figure out why with diff it looks so weird?
    vec3 diffuse = light_color * diff * sampled.rgb;

    // specular
    vec3 view_dir = normalize(-pos);
    vec3 halfway_dir = normalize(light_dir + view_dir);
    vec3 reflect_dir = reflect(-light_dir, norm);
    float spec = pow(max(dot(view_dir, reflect_dir), 0.0), 32.0f);
    vec3 specular = vec3(1.0, 1.0, 1.0) * spec * sampled.rgb;

    // distance between the light and the vertex
    float distance = length(light_pos - pos);
    float attenuation = 1.0 / (constant + linear * distance + quadratic * (distance * distance));

    ambient = ambient * attenuation;
    diffuse = diffuse * attenuation;
    specular = specular * attenuation;

    vec3 result = ambient + diffuse + specular;
    final_color = vec4(result, sampled.a);
}


当我在diff中取出vec3 diffuse = light_color * diff * sampled.rgb时,一切看起来都很好,但是显然没有考虑法线,只是根据距离照亮了顶点。我认为这可能与我的Sponza模型的法线不正确有关,但是我尝试了3种不同的版本,它们都遇到相同的问题。盯着它看了两天,非常感谢任何帮助或调试想法。

最佳答案

窗帘不封闭。它是一个表面,其法向矢量指向相机或远离相机。如果法向矢量指向远离相机的方向,则必须将其反转。这样就得到了两个侧面光源模型,并且可以照亮曲面的两个侧面:

vec3 view_dir = normalize(-pos);
vec3 norm     = normalize(normal);

if (dot(view_dir, norm) < 0.0)
    norm *= -1.0;

09-08 10:11