所以我对阴影痤疮有疑问(据我所知),但问题是我还没有实现任何类型的阴影。我已经实现了 Phong Lighting 模型(遵循 learnopengl 教程)。
我使用的是 Windows 11,但在我尝试过的任何其他平台(Mac、Linux 和 Android)上也会发生这种情况。
我使用的是 SDL (2.26.5) + OpenGL(OpenGL 版本:4.0.0 NVIDIA 537.58,供应商:NVIDIA Corporation,GPU:NVIDIA GeForce RTX 3060/PCIe/SSE2,GLSL:4.00 NVIDIA 通过 Cg 编译器)。
深度测试(我也尝试过GL_LEQUAL,效果一样,有人说可以解决问题)
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
这些是顶点和片段着色器:
#version 330 core
layout(location = 0) in vec3 in_pos;
layout(location = 1) in vec3 in_normal;
layout(location = 2) in vec2 in_text_coord;
layout(location = 3) in mat4 in_model;
out vec3 normal;
out vec2 text_coord;
out vec3 frag_pos;
out mat4 model_matrix;
uniform mat4 view_projection_matrix;
void main(){
mat4 _model = in_model;
gl_Position = view_projection_matrix * _model * vec4(in_pos, 1);
normal = in_normal;
frag_pos = in_pos;
text_coord = in_text_coord;
model_matrix = _model;
}
#version 330 core
const int RDE_MAX_POINT_LIGHTS = 10;
const int RDE_MAX_SPOT_LIGHTS = 10;
in vec3 normal;
in vec2 text_coord;
in vec3 frag_pos;
out vec4 color_out;
struct rde_material {
float shininess;
vec3 Ka;
vec3 Kd;
vec3 Ks;
int using_render_texture;
};
struct rde_directional_light {
vec3 direction;
vec3 ambient_color;
vec3 diffuse_color;
vec3 specular_color;
};
struct rde_point_light {
vec3 position;
vec3 ambient_color;
vec3 diffuse_color;
vec3 specular_color;
float constant;
float linear;
float quadratic;
int used;
};
struct rde_spot_light {
vec3 position;
vec3 direction;
vec3 ambient_color;
vec3 diffuse_color;
vec3 specular_color;
float constant;
float linear;
float quadratic;
float cut_off;
float outer_cut_off;
int used;
};
uniform vec3 camera_pos;
uniform rde_directional_light directional_light;
uniform rde_point_light point_lights[RDE_MAX_POINT_LIGHTS];
uniform rde_spot_light spot_lights[RDE_MAX_SPOT_LIGHTS];
uniform rde_material material;
uniform sampler2D tex_ka;
uniform sampler2D tex_kd;
uniform sampler2D tex_ks;
uniform sampler2D tex_bump;
uniform sampler2D render_texture;
vec3 directional_light_calc() {
vec3 _ambient = material.Ka * directional_light.ambient_color * texture(tex_kd, text_coord).rgb;
vec3 _norm = normalize(normal);
vec3 _light_dir = normalize(-directional_light.direction);
float _diff = max(dot(_norm, _light_dir), 0.0);
vec3 _diffuse = material.Kd * directional_light.diffuse_color * _diff * texture(tex_kd, text_coord).rgb;
vec3 _view_dir = normalize(camera_pos + frag_pos);
vec3 _reflect_dir = reflect(-_light_dir, _norm);
float _spec = pow(max(dot(_view_dir, _reflect_dir), 0.0), material.shininess);
vec3 _specular = material.Ks * directional_light.specular_color * _spec * texture(tex_ks, text_coord).rgb;
vec3 _final_light = _ambient + _diffuse + _specular;
return _final_light;
}
vec3 point_light_calc(int _i) {
rde_point_light _light = point_lights[_i];
if(_light.used < 0) return vec3(0.0, 0.0, 0.0);
vec3 _ambient = material.Ka * _light.ambient_color * texture(tex_kd, text_coord).rgb;
vec3 _norm = normalize(normal);
vec3 _light_dir = normalize(_light.position - frag_pos);
float _diff = max(dot(_norm, _light_dir), 0.0);
vec3 _diffuse = material.Kd * _light.diffuse_color * _diff * texture(tex_kd, text_coord).rgb;
vec3 _view_dir = normalize(camera_pos + frag_pos);
vec3 _reflect_dir = reflect(-_light_dir, _norm);
float _spec = pow(max(dot(_view_dir, _reflect_dir), 0.0), material.shininess);
vec3 _specular = material.Ks * _light.specular_color * _spec * texture(tex_ks, text_coord).rgb;
float _distance = length(_light.position - frag_pos);
float _attenuation = 1.0 / (_light.constant + _light.linear * _distance + _light.quadratic * (_distance * _distance));
_ambient *= _attenuation;
_diffuse *= _attenuation;
_specular *= _attenuation;
return (_ambient + _diffuse + _specular);
}
vec3 spot_light_calc(int _i) {
rde_spot_light _light = spot_lights[_i];
if(_light.used < 0) return vec3(0.0, 0.0, 0.0);
vec3 _light_dir = normalize(_light.position - frag_pos);
float _theta = dot(_light_dir, normalize(-_light.direction));
float _epsilon = (_light.cut_off - _light.outer_cut_off);
float _intensity = clamp((_theta - _light.outer_cut_off) / _epsilon, 0.0, 1.0);
vec3 _ambient = material.Ka * _light.ambient_color * texture(tex_kd, text_coord).rgb;
vec3 _norm = normalize(normal);
float _diff = max(dot(_norm, _light_dir), 0.0);
vec3 _diffuse = material.Kd * _light.diffuse_color * _diff * texture(tex_kd, text_coord).rgb;
vec3 _view_dir = normalize(camera_pos + frag_pos);
vec3 _reflect_dir = reflect(-_light_dir, _norm);
float _spec = pow(max(dot(_view_dir, _reflect_dir), 0.0), material.shininess);
vec3 _specular = material.Ks * _light.specular_color * _spec * texture(tex_ks, text_coord).rgb;
float _distance = length(_light.position - frag_pos);
float _attenuation = 1.0 / (_light.constant + _light.linear * _distance + _light.quadratic * (_distance * _distance));
_ambient *= _attenuation;
_diffuse *= _attenuation * _intensity;
_specular *= _attenuation * _intensity;
return (_ambient + _diffuse + _specular);
}
void normal_rendering() {
// This is for textures with some kind of transparency
if(texture(tex_kd, text_coord).a < 0.05) discard;
vec3 _final_light = vec3(0.0);
_final_light += directional_light_calc();
for(int _i = 0; _i < RDE_MAX_POINT_LIGHTS; _i++) {
_final_light += point_light_calc(_i);
}
for(int _i = 0; _i < RDE_MAX_SPOT_LIGHTS; _i++) {
_final_light += spot_light_calc(_i);
}
color_out = vec4(_final_light, 1.0);
}
// This can be ignored
void render_texture_rendering() {
color_out = texture(render_texture, text_coord);
}
void main(){
if(material.using_render_texture == 0) {
// This is how it is rendered
normal_rendering();
} else {
// This can be ignored
render_texture_rendering();
}
}
我基本上遵循了learnopengl教程上的步骤,但是他们只使用立方体和简单的纹理,对于这些,我的引擎也工作得很好,没有这样的效果,但突然有一些纹理它发生得很糟糕。我不知道我是否在片段着色器上遗漏了某些内容,或者是否有任何其他 GL 函数/参数我没有正确设置。
我还没有使用抗锯齿,因为我使用自定义帧缓冲区(默认帧缓冲区已经发生了这种情况),据我所知,使用自定义帧缓冲区您需要手动实现抗锯齿。这可能是问题所在吗?没有吗?
还尝试过这个片段着色器:
#version 330 core
const int RDE_MAX_POINT_LIGHTS = 10;
const int RDE_MAX_SPOT_LIGHTS = 10;
in vec3 normal;
in vec2 text_coord;
in vec3 frag_pos;
out vec4 color_out;
struct rde_material {
float shininess;
vec3 Ka;
vec3 Kd;
vec3 Ks;
int using_render_texture;
};
struct rde_directional_light {
vec3 direction;
vec3 ambient_color;
vec3 diffuse_color;
vec3 specular_color;
};
struct rde_point_light {
vec3 position;
vec3 ambient_color;
vec3 diffuse_color;
vec3 specular_color;
float constant;
float linear;
float quadratic;
int used;
};
struct rde_spot_light {
vec3 position;
vec3 direction;
vec3 ambient_color;
vec3 diffuse_color;
vec3 specular_color;
float constant;
float linear;
float quadratic;
float cut_off;
float outer_cut_off;
int used;
};
uniform vec3 camera_pos;
uniform rde_directional_light directional_light;
uniform rde_point_light point_lights[RDE_MAX_POINT_LIGHTS];
uniform rde_spot_light spot_lights[RDE_MAX_SPOT_LIGHTS];
uniform rde_material material;
uniform sampler2D tex_ka;
uniform sampler2D tex_kd;
uniform sampler2D tex_ks;
uniform sampler2D tex_bump;
uniform sampler2D render_texture;
void main(){
color_out = vec4(texture(tex_kd, text_coord).rgb, 1.0);
}
但是渲染这些纹理的错误仍然存在,只是没有照明(一切都超级亮,但仅此而已)。
如果需要任何额外信息,只需在评论中询问,我会提供。
我遵循了 learnopengl 的所有步骤和教程,直到使用 Phong Lighting,这使得某些纹理看起来不错,而另一些则不然。我试图寻找我的问题,但只在实现阴影时发现类似的错误,所以我不知道如何解决这个问题。
所以问题是我没有使用Mipmapping。我不太理解它,所以我不想立即实现它,这导致了这个错误。遇到这个问题的人还可以研究其他问题,它被称为各向异性过滤https://www.khronos.org/opengl/wiki/Sampler_Object#Filtering