我正在制作一个有房间的程序,里面有各种对象。为此,我使用OpenGL 3.3版。 为了照亮房间,我在房间中间使用了点光源,并使用了立方体阴影贴图来创建阴影。 (要创建阴影立方体贴图,我要使用几何着色器,但我认为这与问题无关)
我的问题是,在具有英特尔高清图形GPU的笔记本电脑上,或者甚至在使用该内核的英特尔GPU的台式机上,一切都运行良好,但是当我使用英伟达1050ti时,一切都消失了,而我所看到的只是天空盒,在房间周围。 这是使用Nvidia时的结果
这就是它的外观
我进行了一些测试,以查找导致问题的原因。我尝试使用阴影立方体贴图而不是天空盒的立方体贴图来查看阴影立方体贴图纹理是否成功创建并且结果正确。我还尝试在片段着色器中将区域中没有阴影的片段颜色设置为红色,将阴影应设置为绿色的片段颜色设置为以下结果。
我还尝试渲染场景时不考虑阴影(我计算阴影因子),并且效果很好(当然没有阴影),这就是结果
我将问题缩小到片段着色器
因为不是我的所有物品都具有纹理,所以我有一个统一变量来测试是否存在纹理,如果有,它会对其进行采样。
vec4 mlpier =vec4(1.0,1.0,1.0,1.0);
if (texequip==1){
mlpier = vec4(texture(diffuseColorSampler,vertex_UV).rgb,1.0);
}
我的阴影计算功能是
float ShadowCalculation(vec3 vertex_pos_world){
// get vector between fragment position and light position
vec3 fragToLight = vertex_pos_world - light.lightPosition_worldspace;
// use the light to fragment vector to sample from the depth map
float closestDepth = texture(depthMap, fragToLight).r;
// it is currently in linear range between [0,1]. Re-transform back to original value
closestDepth *= farplane;
// now get current linear depth as the length between the fragment and light position
float currentDepth = length(fragToLight);
// now test for shadows
float bias = 0.05;
float shadow = (currentDepth-bias) < closestDepth ? 1.0 : 0.0;
return shadow;
}
最后我计算片段颜色的方式是
fragment_color = vec4(Ia + shadow_factor * ( Id * light.power / distance_sq + Is * light.power / distance_sq),1.0) * mlpier;
当我不与mlpier相乘时,将以正确的阴影渲染场景,但没有纹理
fragment_color = vec4(Ia + shadow_factor * ( Id * light.power / distance_sq + Is * light.power / distance_sq),1.0);
并且当我不与shadow_factor相乘时,将使用正确的纹理渲染场景,但没有阴影(如预期的那样)。
fragment_color = vec4(Ia + ( Id * light.power / distance_sq + Is * light.power / distance_sq),1.0)* mlpier;
但是我想做的是同时保留阴影和纹理。
更新:
我正在添加整个顶点和片段着色器代码
->顶点着色器
#version 330 core
// construct input layout for the corresponding attributes
// (vertexPosition_modelspace, vertexNormal_modelspace, vertexUV)
layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 1) in vec3 vertexNormal_modelspace;
layout(location = 2) in vec2 vertexUV;
// Output variables (position_modelspace, normal_modelspace and UV coordinates),
// that will be interpolated for each fragment
out vec3 vertex_position_modelspace;
out vec3 vertex_normal_modelspace;
out vec2 vertex_UV;
out vec4 st_shadow;
// uniforms (P, V, M)
uniform mat4 P;
uniform mat4 V;
uniform mat4 M;
uniform mat4 lightP;
uniform mat4 lightV;
void main()
{
// Output position of the vertex, in clip space : MVP * position
gl_Position = P * V * M * vec4(vertexPosition_modelspace, 1);
// propagate the position of the vertex to fragment shader
vertex_position_modelspace = vertexPosition_modelspace;
// propagate the normal of the vertex to fragment shader
vertex_normal_modelspace = vertexNormal_modelspace;
// propagate the UV coordinates
vertex_UV = vertexUV;
// create a shadow map texture coordinate by backwards-ising the position.
vec4 vertex_position_worldspace = M * vec4(vertex_position_modelspace,1.0);
st_shadow = lightP * lightV * vertex_position_worldspace;
st_shadow.xyz /= st_shadow.w;
st_shadow.xyz += vec3(1.0,1.0,1.0);
st_shadow.xyz *= 0.5;
}
->片段着色器
#version 330 core
// interpolated values from the vertex shaders (vertex_position_modelspace,
// vertex_normal_modelspace and vertex_UV coordinates)
in vec3 vertex_position_modelspace;
in vec3 vertex_normal_modelspace;
in vec2 vertex_UV;
in vec4 st_shadow;
// uniform variables (lightPosition_worldspace, V, M)
uniform vec3 light_position_worldspace;
uniform mat4 V;
uniform mat4 M;
uniform int texequip;
uniform float farplane;
// (diffuseColorSampler, specularColorSampler)
uniform sampler2D diffuseColorSampler;
uniform sampler2D texturemapSampler;
uniform sampler2D depth_map;
uniform samplerCube depthMap;
// Phong
// light properties
struct Light {
vec3 La;
vec3 Ld;
vec3 Ls;
vec3 lightPosition_worldspace;
float power;
};
uniform Light light;
// materials
struct Material {
vec3 Ka;
vec3 Kd;
vec3 Ks;
float Ns;
sampler2D texKa;
sampler2D texKd;
sampler2D texKs;
sampler2D texNs;
};
uniform Material mtl;
// output data
out vec4 fragment_color;
// for point light - cube shadow mapping
float ShadowCalculation(vec3 vertex_pos_world){
// get vector between fragment position and light position
vec3 fragToLight = vertex_pos_world - light.lightPosition_worldspace;
// use the light to fragment vector to sample from the depth map
float closestDepth = texture(depthMap, fragToLight).r;
// it is currently in linear range between [0,1]. Re-transform back to original value
closestDepth *= farplane;
// now get current linear depth as the length between the fragment and light position
float currentDepth = length(fragToLight);
// now test for shadows
float bias = 0.05;
float shadow = (currentDepth-bias) < closestDepth ? 1.0 : 0.0;
return shadow;
}
void phong();
void main(){
phong();
}
void phong() {
vec3 _Ks = mtl.Ks;
vec3 _Kd = mtl.Kd;
vec3 _Ka = mtl.Ka;
float _Ns = mtl.Ns;
// use texture for materials
if (_Ka.r < 0.0) _Ka = vec3(texture(mtl.texKa, vertex_UV).rgb);
if (_Kd.r < 0.0) _Kd = vec3(texture(mtl.texKd, vertex_UV).rgb);
if (_Ks.r < 0.0) _Ks = vec3(texture(mtl.texKs, vertex_UV).rgb);
if (_Ns < 0.0) _Ns = texture(mtl.texNs, vertex_UV).r;
vec3 vertex_position_worldspace = vec3(M * vec4(vertex_position_modelspace,1.0));
vec3 vertex_position_cameraspace = vec3(V * vec4(vertex_position_worldspace,1.0));
vec3 vertex_normal_cameraspace = vec3(V * M * vec4(vertex_normal_modelspace,0.0));
// model ambient intensity (Ia)
vec3 Ia = light.La * _Ka;
// model diffuse intensity (Id)
vec3 N = normalize(vertex_normal_cameraspace);
vec3 L = normalize((V * vec4(light.lightPosition_worldspace, 1)).xyz
- vertex_position_cameraspace);
float cosTheta = clamp(dot(L, N), 0, 1);
vec3 Id = light.Ld * _Kd * cosTheta;
// model specular intensity (Is)
vec3 R = reflect(-L, N);
vec3 E = normalize(- vertex_position_cameraspace);
float cosAlpha = clamp(dot(E, R), 0, 1);
float specular_factor = pow(cosAlpha, _Ns);
vec3 Is = light.Ls * _Ks * specular_factor;
//model the light distance effect
float distance = length(light.lightPosition_worldspace
- vertex_position_worldspace);
float distance_sq = distance * distance;
// check if the object has a texture or not
vec4 mlpier =vec4(1.0,1.0,1.0,1.0);
if (texequip==1){
mlpier = vec4(texture(diffuseColorSampler,vertex_UV).rgb,1.0);
}
// calculating the shadow factor
float shadow_factor = ShadowCalculation(vertex_position_worldspace);
// final fragment color
fragment_color = vec4(Ia +shadow_factor * ( Id * light.power / distance_sq + Is * light.power / distance_sq),1.0) * mlpier;
}