GLSL着色器是否有可读取信息的最大限制?

问题描述 投票:0回答:1

我在 C++ 20 中将 OpenGL 4.5 与 GLFW 和 GLAD 一起使用,我正在尝试制作一个着色器,使用 Blinn-Phong 算法计算不同功能(点、方向、点)的多个光源,但每次我尝试计算不止一个,它只是行不通(统一位置搞砸了,它再也找不到任何东西)。 这是片段着色器:

#version 330

in vec3 fragNormal;
in vec2 fragTexCoord;
in vec3 fragPos;

uniform vec3 viewPos;
uniform sampler2D ourTexture;

out vec4 outColor;

struct DirLight {
    vec3 direction;

    vec3 color;

    float ambient;
    float diffuse;
    float specular;
};

struct PointLight {
    vec3 position;
    vec3 direction;

    vec3 color;

    float ambient;
    float diffuse;
    float specular;

    float constant;
    float linear;
    float quadratic;
};

struct SpotLight {
    vec3 position;
    vec3 direction;

    vec3 color;

    float ambient;
    float diffuse;
    float specular;

    float constant;
    float linear;
    float quadratic;

    float cutOff;
    float outerCutOff;
};

struct Material {
    vec3 diffuse;
    vec3 ambient;
    vec3 specular;

    float shininess;
};

#define NB_MAX_LIGHT 50

uniform DirLight dirLights[NB_MAX_LIGHT];
uniform PointLight pointLights[NB_MAX_LIGHT];
uniform SpotLight spotLights[NB_MAX_LIGHT];

uniform Material material;

uniform int nbDirLight;
uniform int nbPointLight;
uniform int nbSpotLight;

vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir)
{
    vec3 lightDir = normalize(-light.direction);

    float diffuse = max(dot(lightDir, normal), 0.0)  * light.diffuse;

    vec3 haflwaydir = normalize(lightDir + viewDir);

    float spec = pow(max(dot(viewDir, haflwaydir), 0.0), material.shininess);

    float specular = spec * light.specular;

    return ((light.ambient * material.ambient) + (diffuse * material.diffuse) + (specular * material.specular)) * light.color;
}

vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir)
{
    //cal point
    vec3 lightDir = normalize(light.position - fragPos);
    float dist = length(light.position - fragPos);
    float attenuation = 1.0 / (light.constant + light.linear * dist + light.quadratic * (dist * dist));
    float diffuse = max(dot(lightDir, normal), 0.0) * light.diffuse * attenuation;
    vec3 haflwaydir = normalize(lightDir + viewDir);
    float spec = pow(max(dot(viewDir, haflwaydir), 0.0), material.shininess);
    float specular = spec * light.specular * attenuation;

    //spot part
    float theta = dot(lightDir, normalize(-light.direction));
    float epsilon = (light.cutOff - light.outerCutOff);
    float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0, 1.0);
    float ambient = light.ambient * intensity;
    diffuse *= intensity;
    specular *= intensity;

    return ((ambient * material.ambient) + (diffuse * material.diffuse) + (specular * material.specular)) * light.color;
}

vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir)
{
    vec3 lightDir = normalize(light.position - fragPos);
    float dist = length(light.position - fragPos);
    float attenuation = 1.0 / (light.constant + light.linear * dist + light.quadratic * (dist * dist));
    float diffuse = max(dot(lightDir, normal), 0.0) * light.diffuse * attenuation;
    vec3 haflwaydir = normalize(lightDir + viewDir);
    float spec = pow(max(dot(viewDir, haflwaydir), 0.0), material.shininess);
    float specular = spec * light.specular * attenuation;

    return ((light.ambient * material.ambient) + (diffuse * material.diffuse) + (specular * material.specular)) * light.color;
}

void main() {
    vec3 norm = normalize(fragNormal);
    vec3 viewDir = normalize(viewPos - fragPos);

    vec3 result = vec3(0);

    for(int i = 0; i < nbDirLight; i++)
        result += CalcDirLight(dirLights[i], norm, viewDir);


    for(int j = 0; j < nbPointLight; j++)
        result += CalcPointLight(pointLights[j], norm, fragPos, viewDir);


    for(int k = 0; k < nbSpotLight; k++)
        result += CalcSpotLight(spotLights[k], norm, fragPos, viewDir);

    outColor =  vec4(result, 1.0) * texture(ourTexture, fragTexCoord);
}

对于顶点着色器:

#version 330

layout(location = 0) in vec3 inPosition;
layout(location = 1) in vec3 inNormal;
layout(location = 2) in vec2 inTexCoord;

out vec3 fragNormal;
out vec2 fragTexCoord;
out vec3 fragPos;
out vec3 fragViewPos;

uniform mat4 model;
uniform mat4 viewProj;

void main() {
    gl_Position = viewProj * model * vec4(inPosition, 1.0);
    fragNormal =  mat3(transpose(inverse(model))) * inNormal;
    fragTexCoord = inTexCoord;
    fragPos = vec3(model * vec4(inPosition, 1.0));
}

当我尝试使用 CalcSpotLight 时,“着色器”再也找不到任何制服了。

those are the Uniform that the shader can't find (it return -1)

GetUniform 的代码是:

{
    unsigned int result = RENDERER.GetUniformLocation(shaderProgram, name);

    if (result == -1)
        std::cout << name << " not found in uniform" << std::endl;

    return result;
}
,
int Renderer::GetUniformLocation(unsigned int pProgram, const char* pName)
{
    return glGetUniformLocation(pProgram, pName);
}

我尝试只使用 2 盏灯,它工作,我尝试只将 1.0f 添加到 vec4 结果并且它工作,但是当我尝试在函数中计算时它不再工作了。

c++ opengl visual-c++ glsl glfw
1个回答
-2
投票

嘿,我正在和他一起做这个项目,非常感谢帮助!

© www.soinside.com 2019 - 2024. All rights reserved.