当前位置: 首页 > 知识库问答 >
问题:

环境照明和镜面照明在GLSL中无法正常工作

宇文峰
2023-03-14

在我的照明场景中,由于某种原因,环境照明根本不起作用。无论朝哪个方向,整个模型都是相同的亮度。我试图消除衰减,但仍然有相同的结果。除此之外,无论相机位于何处,镜面照明都会一直闪烁。它应该根据球员的位置而发光。以下是环境问题的截图:Imgur。通用域名格式

如您所见,球体背向光线的部分(位于[0.0,4.0,0.0])与面向光线的部分颜色相同。环境因子应该是片段颜色的0.2。

顶点着色器源:

layout(location = 0) in vec3 positions;
layout(location = 1) in vec2 texCoords;
layout(location = 2) in vec3 normals;

out vec3 new_normal;
out vec3 worldPos_out;
out vec2 pass_texCoords;

struct Matrices {
    mat4 projection;
    mat4 worldMatrix;
    mat4 modelMatrix;
    mat3 normalMatrix;
};

uniform Matrices mat;

void main(void)
{
    pass_texCoords = texCoords;

    vec4 newPosition = vec4(positions, 1);

    vec4 worldPos = (mat.modelMatrix * newPosition);
    mat4 Camera = mat.projection * mat.worldMatrix;
    gl_Position = (Camera *  worldPos);

    new_normal = mat.normalMatrix * normals;
    worldPos_out = worldPos.xyz;
}

片段着色器源:

in vec3 new_normal;
in vec3 worldPos_out;
in vec2 pass_texCoords;

out vec4 outColor;
uniform vec3 viewPos;

#define MAX_LIGHTS 50

struct Material {
    sampler2D diffuseMap;
    sampler2D specularMap;
    vec3 specular;
    float shininess;
};
uniform Material material;

struct Light {
    vec3 position;
    vec3 color;

    vec3 ambient;
    vec3 diffuse;
    vec3 specular;

    float radius;
};
uniform Light Lights[MAX_LIGHTS];
uniform int numLights;

struct Math {
    float constant;
    float linear;
    float quadratic;
} math;

vec3 applyPointLight(Light light, vec3 normal, vec3 fragPos, vec3 viewDir, vec3 surfaceColor, vec3 surfaceSpecular) {
    vec3 lightDir = normalize(light.position - fragPos);
    //Diffuse shading
    float diff = max(dot(normal, lightDir), 0.0);
    //Specular shading
    vec3 reflectDir = reflect(-lightDir, normal);
    float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
    //Attenuation
    float distance = length(light.position - fragPos);
    float attenuation = 5.0 / (math.constant + math.linear * distance +
                        math.quadratic * (distance * distance));

    vec3 ambient = light.ambient * surfaceColor;
    vec3 diffuse = light.diffuse * surfaceColor * light.color;
    vec3 specular = light.specular * surfaceSpecular * light.color;
    ambient *= attenuation;
    diffuse *= attenuation;
    specular *= attenuation;

    return (ambient + diffuse + specular);
}

void main(void)  {
    vec3 surfaceColor = vec3(texture(material.diffuseMap, pass_texCoords));
    vec3 surfaceSpecular = vec3(texture(material.specularMap, pass_texCoords));

    vec3 unitNormal = normalize(new_normal);
    vec3 viewDir = normalize(viewPos - worldPos_out);

    math.constant = 1.0;
    math.linear = 0.09;
    math.quadratic = 0.032;

    vec3 linearColor;
    for(int i = 0; i < numLights; i++)
        linearColor += applyPointLight(Lights[i], unitNormal, worldPos_out, viewDir, surfaceColor, surfaceSpecular);

    float gamma = 2.2;
    vec3 fragColor;
    fragColor.rgb = pow(linearColor.rgb, vec3(1.0/gamma));

    outColor = vec4(linearColor, 1.0);
}

共有1个答案

厉钊
2023-03-14

在您的apple yPointLight函数中,您没有使用diffspec变量,它们可能是对漫反射和镜面的依赖光的更改。看看以下是否有效:

vec3 diffuse = light.diffuse * surfaceColor * light.color * diff;
vec3 specular = light.specular * surfaceSpecular * light.color * spec;
 类似资料:
  • 我正在尝试实现Phong照明。在一些教程中,镜面反射照明添加到环境光和漫反射照明中,然后总照明乘以纹理颜色。我还看到了一个教程,其中在添加环境光和漫反射光后,分别添加了镜面反射照明和纹理颜色。 这是一个片段着色器,既有选项,也有屏幕截图。 > 选项1。镜面反射将添加到环境光和漫反射 选择2。镜面反射是单独添加的。 在这些截图中,shineDump值为32.0f,镜面强度为0.5f。 哪一个看起来正

  • 本章介绍如何使用JOGL将光照效果应用于对象。 要设置光照,最初使用glEnable()方法启用光照。 然后使用GLLightingFunc接口的GLLightingFunc glLightfv(int light, int pname, float[] params, int params_offset)方法为GLLightingFunc 。 该方法有四个参数。 下表描述了gllightfv()

  • 我正在尝试在片段着色器中实现法线贴图和照明。但我的密码似乎不起作用。我的想法是将ModelMatrix的额外副本传递给片段着色器,以便它可以变换存储在纹理中的法线。但反射光实际上发生在另一侧。 [更新]在得到一些建议后,我在顶点着色器中计算了TBN矩阵,将TBN基变换为世界空间,将光位置和眼位置转换为切线空间。但这一次,这颗行星根本就不发光!只显示环境光。然后我发现这是因为漫反射组件的计算结果为负

  • 我使用的是Laravel,当我尝试运行时,它会显示以下错误: 照明\数据库\查询异常: SQLSTATE[42000]:语法错误或访问冲突: 1071指定的密钥太长;最大密钥长度为767字节(SQL:更改表添加唯一()) 在 /Users/soksan/Desktop/TestLaravel/multiUsers/vendor/laravel/framework/src/Illuminate/Da

  • 我正在为体素游戏开发一个3通道延迟照明系统,但是我在像素化照明和环境遮挡方面有问题。 第一阶段将屏幕上每个像素的颜色、位置和法线渲染成单独的纹理。这部分工作正常: 第二个着色器为屏幕上的每个像素计算环境光遮挡值,并将其渲染为纹理。此部分工作不正常,已像素化: 原始遮挡数据: 第三个着色器使用颜色、位置、法线和遮挡纹理将游戏场景渲染到屏幕上。这一阶段的照明也是像素化的: SSAO(第二遍)片段着色器

  • 我有一个由2个网格(平面、立方体)、一个灯和一个相机组成的场景。我想使用GLSL着色器和OpenGL的阴影映射技术在我的场景中显示阴影。 以下是我得到的结果(为了简单起见,我的立方体和平面都是蓝色和蓝色): 这是FBO和深度纹理初始化: 以下是我的顶点着色器的内容: 还有我的片段着色器: 正如你所见,模型上有一些工件,我不知道如何取出它们。但是阴影看起来是正确的,所以我的着色器中输入的变量也应该是