Closed. This question is off-topic。它当前不接受答案。
想改善这个问题吗? Update the question,所以它是on-topic,用于堆栈溢出。
2小时前关闭。
因此,我一直试图在我的C ++ vulkan渲染引擎中使点光源工作,直到我添加实际的漫反射效果,一切似乎都可以正常工作。当我的点灯(由Gizmo指示的位置)在此花盆的右侧时,花盆将正确照亮,如下所示:
但是,当光从这个花盆的左边离开时,它是完全黑暗的:
我发现这很奇怪,因为点光源应仅将光散射到各个方向,但是几乎就像光源仅沿一种方向前进或物体法线存在问题一样,就像它们仅以一种方式瞄准一样。我觉得我在忽略着色器中的一些菜鸟错误:
顶点着色器
片段着色器
当我在
想改善这个问题吗? Update the question,所以它是on-topic,用于堆栈溢出。
2小时前关闭。
因此,我一直试图在我的C ++ vulkan渲染引擎中使点光源工作,直到我添加实际的漫反射效果,一切似乎都可以正常工作。当我的点灯(由Gizmo指示的位置)在此花盆的右侧时,花盆将正确照亮,如下所示:
但是,当光从这个花盆的左边离开时,它是完全黑暗的:
我发现这很奇怪,因为点光源应仅将光散射到各个方向,但是几乎就像光源仅沿一种方向前进或物体法线存在问题一样,就像它们仅以一种方式瞄准一样。我觉得我在忽略着色器中的一些菜鸟错误:
顶点着色器
// 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