2016-07-16 4 views
-1

Ich habe www.learnopengl.com Tutorial gefolgt und versucht, Modelle mit der beschriebenen Methode zu laden. Es funktioniert bis zum Ende, wo es Sie bittet, den Nanosuit mit 2 Punktlichtern zu laden. Ich habe den genauen Code aus dem Tutorial kopiert: Kamera-, Netz-, Modell- und Shader-Klassen, aber das Problem ist mit dem Fragment-Shader. Wenn ich einen einfachen wie:learnopengl Tutorial Fragment Shader für 2 Punkte Licht

#version 330 core 

in vec2 TexCoords; 

out vec4 color; 

uniform sampler2D texture_diffuse1; 

void main() 
{  
    color = vec4(texture(texture_diffuse1, TexCoords)); 
} 

versuchen, wird das Modell geladen und die Texturen zu. Aber wenn die Lösung für 2 Punkte Beleuchtung der Textur gegeben versuchen ist schwarz:

#version 330 core 
struct Material { 
    sampler2D texture_diffuse1; 
    sampler2D texture_specular1; 
    float shininess; 
}; 
/* Note: because we now use a material struct again you want to change your 
mesh class to bind all the textures using material.texture_diffuseN instead of 
texture_diffuseN. */ 

struct PointLight { 
    vec3 position; 

    float constant; 
    float linear; 
    float quadratic; 

    vec3 ambient; 
    vec3 diffuse; 
    vec3 specular; 
}; 

#define NR_POINT_LIGHTS 2 

in vec3 fragPosition; 
in vec3 Normal; 
in vec2 TexCoords; 

out vec4 color; 

uniform vec3 viewPos; 
uniform PointLight pointLights[NR_POINT_LIGHTS]; 
uniform Material material; 

// Function prototypes 
vec3 CalcPointLight(PointLight light, Material mat, vec3 normal, vec3 fragPos, vec3 viewDir); 

void main() 
{  
    vec3 result; 
    vec3 viewDir = normalize(viewPos - fragPosition); 
    vec3 norm = normalize(Normal); 

    for(int i = 0; i < NR_POINT_LIGHTS; i++) 
     result += CalcPointLight(pointLights[i], material, norm, fragPosition, viewDir); 

    color = vec4(result, 1.0f); 
} 


// Calculates the color when using a point light. 
vec3 CalcPointLight(PointLight light, Material mat, vec3 normal, vec3 fragPos, vec3 viewDir) 
{ 
    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), mat.shininess); 
    // Attenuation 
    float distance = length(light.position - fragPos); 
    float attenuation = 1.0f/(light.constant + light.linear * distance + light.quadratic * (distance * distance));  
    // Combine results 
    vec3 ambient = light.ambient * vec3(texture(mat.texture_diffuse1, TexCoords)); 
    vec3 diffuse = light.diffuse * diff * vec3(texture(mat.texture_diffuse1, TexCoords)); 
    vec3 specular = light.specular * spec * vec3(texture(mat.texture_specular1, TexCoords)); 
    ambient *= attenuation; 
    diffuse *= attenuation; 
    specular *= attenuation; 
    return (ambient + diffuse + specular); 
} 

I modifiziert auch die Mesh-Klasse von im Fragment Shader beschrieben:

glUniform1i(glGetUniformLocation(shader.Program, (name + number).c_str()), i); 

zu:

glUniform1i(glGetUniformLocation(shader.Program, ("material." + name + number).c_str()), i); 

Hat jemand das gleiche Problem?

+0

Warum die downvote? Eine Erklärung wäre nützlich. –

+0

Haben Sie sich Ihre Kompilierungsfehler beim Shadern angesehen? –

+0

Ich habe keine. Es kompiliert gut, aber es läuft schwarze Texturen. Sind die Uniformen nicht von anderen Funktionen als Main zugänglich? –

Antwort

0

Es scheint wie GLSL Funktion nicht mag. Wenn ich CalcPointLight() Code nehme und es in main() platziere, funktioniert es!

#version 330 core 
struct Material { 
    sampler2D texture_diffuse1; 
    sampler2D texture_specular1; 
    float shininess; 
}; 
/* Note: because we now use a material struct again you want to change your 
mesh class to bind all the textures using material.texture_diffuseN instead of 
texture_diffuseN. */ 

struct PointLight { 
    vec3 position; 

    float constant; 
    float linear; 
    float quadratic; 

    vec3 ambient; 
    vec3 diffuse; 
    vec3 specular; 
}; 

#define NR_POINT_LIGHTS 2 

in vec3 fragPosition; 
in vec3 Normal; 
in vec2 TexCoords; 

out vec4 color; 

uniform vec3 viewPos; 
uniform PointLight pointLights[NR_POINT_LIGHTS]; 
uniform Material material; 

void main() 
{ 
    vec3 result; 
    vec3 viewDir = normalize(viewPos - fragPosition); 
    vec3 norm = normalize(Normal); 

    vec3 lightDir = normalize(pointLights[0].position - fragPosition); 

    // Diffuse shading 
    float diff = max(dot(norm, lightDir), 0.0); 

    // Specular shading 
    vec3 reflectDir = reflect(-lightDir, norm); 
    float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); 

    // Attenuation 
    float distance = length(pointLights[0].position - fragPosition); 
    float attenuation = 1.0f/(pointLights[0].constant + pointLights[0].linear * distance + pointLights[0].quadratic * (distance * distance)); 

    // Combine results 
    vec3 ambient = pointLights[0].ambient * vec3(texture(material.texture_diffuse1, TexCoords)); 
    vec3 diffuse = pointLights[0].diffuse * diff * vec3(texture(material.texture_diffuse1, TexCoords)); 
    vec3 specular = pointLights[0].specular * spec * vec3(texture(material.texture_specular1, TexCoords)); 
    ambient *= attenuation; 
    diffuse *= attenuation; 
    specular *= attenuation; 
    result = ambient+diffuse+specular; 

    color = vec4(result, 1.0f); 
} 

Edit: die Antwort dort gefunden: GLSL sampler2D in struct. Sie können eine Struktur nicht instanziieren, die einen undurchsichtigen Typ wie Sampler2D enthält.

Edit1: Sie können tatsächlich diese Variablen in einer Funktion verwenden, ohne sie als Argumente zu übergeben, da sie global definiert sind:

#version 330 core 
struct Material { 
    sampler2D texture_diffuse1; 
    sampler2D texture_specular1; 
    float shininess; 
}; 
/* Note: because we now use a material struct again you want to change your 
mesh class to bind all the textures using material.texture_diffuseN instead of 
texture_diffuseN. */ 

struct PointLight { 
    vec3 position; 

    float constant; 
    float linear; 
    float quadratic; 

    vec3 ambient; 
    vec3 diffuse; 
    vec3 specular; 
}; 

#define NR_POINT_LIGHTS 2 

in vec3 fragPosition; 
in vec3 Normal; 
in vec2 TexCoords; 

out vec4 color; 

uniform vec3 viewPos; 
uniform PointLight pointLights[NR_POINT_LIGHTS]; 
uniform Material material; 

vec3 CalcLights(int i); 

void main() 
{ 
    vec3 result; 
    for(int i=0; i<NR_POINT_LIGHTS; i++) 
     result += CalcLights(i); 
    color = vec4(result, 1.0f); 
} 

vec3 CalcLights(int i) //viewPos fragPosition pointLights[] Normal material TexCoords 
{ 
    vec3 viewDir = normalize(viewPos - fragPosition); 
    vec3 norm = normalize(Normal); 

    vec3 lightDir = normalize(pointLights[i].position - fragPosition); 

    // Diffuse shading 
    float diff = max(dot(norm, lightDir), 0.0); 

    // Specular shading 
    vec3 reflectDir = reflect(-lightDir, norm); 
    float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); 

    // Attenuation 
    float distance = length(pointLights[i].position - fragPosition); 
    float attenuation = 1.0f/(pointLights[i].constant + pointLights[i].linear * distance + pointLights[i].quadratic * (distance * distance)); 

    // Combine results 
    vec3 ambient = pointLights[0].ambient * vec3(texture(material.texture_diffuse1, TexCoords)); 
    vec3 diffuse = pointLights[0].diffuse * diff * vec3(texture(material.texture_diffuse1, TexCoords)); 
    vec3 specular = pointLights[0].specular * spec * vec3(texture(material.texture_specular1, TexCoords)); 
    ambient *= attenuation; 
    diffuse *= attenuation; 
    specular *= attenuation; 

    return (ambient+diffuse+specular); 
} 
Verwandte Themen