簡體   English   中英

頂點着色器 glsl qt 中的紋理映射

[英]Texture mapping in vertex shader glsl qt

我正在嘗試使用 QOpenGLWindow 在 opengl 中通過紋理映射實現每個頂點照明。 但是渲染的 object 是黑色的。 如果我在片段着色器中進行相同的紋理映射,它工作正常。

//Vertex Shader        
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;
layout (location = 2) in vec3 tangent;
layout (location = 3) in vec3 bitangent;
layout (location = 4) in vec2 texCoords;

out vec4 afragColor;

vec3 fragPos;
out vec2 fragTexCoords;
mat3 TBN;

uniform sampler2D diffuseMap;
uniform sampler2D specularMap;
uniform sampler2D bumpMap;

vec3 calcAmbientLight(int idx, vec3 color, float ambient) {
    return ambient * color * vec3(ambientLight[idx].color);
}

vec3 calcDirectionalLight(int idx, vec3 normal, vec3 color, float diff, float spec) {
    vec3 lightDir = normalize(-vec3(directionalLight[idx].direction));
    vec3 viewDir = normalize(vec3(viewPos) - fragPos);
    vec3 reflectDir = reflect(-lightDir, normal);

    vec3 result = vec3(0.0f);
    result += diff * color * max(dot(normal, lightDir), 0.0f);
    result += spec * color * pow(max(dot(viewDir, reflectDir), 0.0f), material.shininess);

    return result * vec3(directionalLight[idx].color);
}

vec3 calcPointLight(int idx, vec3 normal, vec3 color, float diff, float spec) {
    vec3 lightDir = normalize(vec3(pointLight[idx].pos) - fragPos);
    vec3 viewDir = normalize(vec3(viewPos) - fragPos);
    vec3 reflectDir = reflect(-lightDir, normal);
    float dis = length(vec3(pointLight[idx].pos) - fragPos);

    vec3 result = vec3(0.0f);
    result += diff * color * max(dot(normal, lightDir), 0.0f);
    result += spec * color * pow(max(dot(viewDir, reflectDir), 0.0f), material.shininess);

    float attenuation = 1.0f / (pointLight[idx].attenuation[3]
                            + pointLight[idx].attenuation[2] * dis
                            + pointLight[idx].attenuation[1] * dis * dis);
    result *= attenuation * pointLight[idx].attenuation[0] + (1.0f - pointLight[idx].attenuation[0]);

    return result * vec3(pointLight[idx].color);
}

vec3 calcSpotLight(int idx, vec3 normal, vec3 color, float diff, float spec) {
    vec3 lightDir = normalize(vec3(spotLight[idx].pos) - fragPos);
    vec3 viewDir = normalize(vec3(viewPos) - fragPos);
    vec3 reflectDir = reflect(-lightDir, normal);
    float dis = length(vec3(spotLight[idx].pos) - fragPos);
    float theta = dot(lightDir, normalize(-vec3(spotLight[idx].direction)));
    float intensity = (theta - spotLight[idx].cutOff[1]) / (spotLight[idx].cutOff[0] - spotLight[idx].cutOff[1]);

    vec3 result = vec3(0.0f);
    result += diff * color * max(dot(normal, lightDir), 0.0f);
    result += spec * color * pow(max(dot(viewDir, reflectDir), 0.0f), material.shininess);

    float attenuation = 1.0f / (spotLight[idx].attenuation[3]
                            + spotLight[idx].attenuation[2] * dis
                            + spotLight[idx].attenuation[1] * dis * dis);
    result *= attenuation * spotLight[idx].attenuation[0] + (1.0f - spotLight[idx].attenuation[0]);

    return result * vec3(spotLight[idx].color) * clamp(intensity, 0.0f, 1.0f);
}


void main() {
    vec3 T = normalize(mat3(modelMat) * tangent);
    vec3 B = normalize(mat3(modelMat) * bitangent);
    vec3 N = normalize(mat3(normalMat) * normal);
    
    fragPos = vec3(modelMat * vec4(position, 1.0f));
    fragTexCoords = texCoords;
    TBN = mat3(T, B, N);

    mat4 MVP = projMat * viewMat * modelMat;

    vec3 color  = material.useDiffuseMap == 1 ? texture(diffuseMap, fragTexCoords).rgb : vec3(material.color);
    float spec  = material.useSpecularMap == 1 ? texture(specularMap, fragTexCoords).r : material.specular;
    vec3 normal = material.useBumpMap == 1 ? texture(bumpMap, fragTexCoords).rgb * 2 - 1 : vec3(0, 0, 1);
    normal = normalize(TBN * normalize(normal));

    afragColor = vec4(0, 0, 0, 1);

    for (int i = 0; i < ambientLightNum; i++)
        afragColor += vec4(calcAmbientLight(i, color, material.ambient), 1);

    for (int i = 0; i < directionalLightNum; i++)
        afragColor += vec4(calcDirectionalLight(i, normal, color, material.diffuse, spec), 1);

    for (int i = 0; i < pointLightNum; i++)
        afragColor += vec4(calcPointLight(i, normal, color, material.diffuse, spec), 1);

    for (int i = 0; i < spotLightNum; i++)
        afragColor += vec4(calcSpotLight(i, normal, color, material.diffuse, spec), 1);

    if (highlighted == 1)
        afragColor += vec4(0.2, 0.2, 0.2, 0);

    if (selected == 1)
        afragColor += vec4(0, 0, 0.4, 0);

    gl_Position = MVP * vec4(position, 1.0f);
    if (sizeFixed == 1) {
        float w = (MVP * vec4(0.0f, 0.0f, 0.0f, 1.0f)).w / 100;
        gl_Position = MVP * vec4(position * w, 1.0f);
    }
}






//Fragment Shader

out vec4 fragColor;

in vec4 afragColor;
void main() {
    fragColor = afragColor;

}

我覺得像頂點着色器返回一個非常暗的顏色,但也不做紋理映射。 謝謝

頂點着色器只針對每個頂點執行。 因此,僅查找圖元的頂點(角)的紋理。 頂點着色器的 output 沿片段進行插值。 您不能在頂點着色器中執行此算法。 您需要在片段着色器中為每個片段執行此操作。
“Per Vertex Lighting”僅對恆定漫射光有意義。 在鏡面高光和紋理貼圖的情況下,光分布不是線性的,無法用線性插值計算。 Per-vertex Lighting 僅用於非常簡單的光照模型,現在一般不使用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM