2016-07-16 5 views
-1

나는 www.learnopengl.com 튜토리얼을 따라 왔고 설명 된 방법을 사용하여 모델을로드하려고 시도했습니다. 그것은 매우 끝날 때까지 작동하여 나노 점을 2 포인트 조명으로로드하도록 요청합니다. 튜토리얼의 정확한 코드를 카메라, 메쉬, 모델 및 셰이더 클래스로 복사했지만 문제는 조각 셰이더와 같습니다. 간단한 하나를 시도해 보면 :learnopengl tutorial 2 포인트 빛을위한 프래그먼트 셰이더

#version 330 core 

in vec2 TexCoords; 

out vec4 color; 

uniform sampler2D texture_diffuse1; 

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

, 모델이로드되고 텍스처도로드됩니다. 그러나 질감 조명이 점에 주어진 솔루션을하려고하면은 검은 색 :

#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); 
} 

는 또한 메쉬 클래스를 수정에서 프레 그먼트 쉐이더에 설명 된대로 :

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

에 :

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

동일한 문제가있는 사람이 있습니까?

+0

왜 downvote? 설명이 유용 할 것입니다. –

+0

쉐이더 컴파일 오류를 보셨습니까? –

+0

나는 아무 것도 없어. 그것은 잘 컴파일하지만 검은 질감을 보여주는 실행. 유니폼은 메인보다 다른 기능에서 접근 할 수 없습니까? –

답변

0

GLSL이 기능을 좋아하지 않는 것처럼 보입니다. CalcPointLight() 코드를 main()에두면 작동합니다!

#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); 
} 

편집 : GLSL sampler2D in struct :이 답을 찾을. sampler2D와 같은 은폐 형을 포함하는 구조체를 인스턴스화 할 수 없습니다.

EDIT1 : 그들은 전역으로 정의되어 있기 때문에 당신은 실제로 인수로 전달하지 않고 기능에 해당 변수를 사용할 수 있습니다

#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); 
}