2014-01-11 4 views
0

GLSL 쉐이더에서 반사 하이라이트를 사용하려고하지만 올바르게 작동하지 않습니다. 나는 하스켈을 사용하고 있지만, 중요하지 않아야한다.GLSL 올바른 반사광

유니폼 대신 OpenGL의 행렬을 사용하고 있습니다.

다음은 어떻게 플레이어를 "변형시키는"방법입니다.

glLoadIdentity 

glPushAttrib gl_TRANSFORM_BIT 

-- Rotate Player 
let (xr, yr, zr) = playerRotation player 
glRotatef xr (-1) 0 0 
glRotatef yr 0 (-1) 0 
glRotatef zr 0 0 (-1) 

-- Translate Player 
let (x, y, z) = playerPosition player 
glTranslatef (-x) (-y) (-z) 

-- Reset attributes to former state? 
glPopAttrib 

코드 섹션 이후에 나는 실제 렌더링 가능한 모든 객체를 렌더링합니다. 그래서 GLSL의 관점에서, 카메라는 (0, 0, 0)에 있고, 나머지는 플레이어의 위치와 반비례로 변형됩니다. 꽤 표준.

정점 :

#version 400 core 

layout(location = 0) in vec3 position; 
layout(location = 1) in vec3 normal; 
layout(location = 2) in vec2 texCoord; 
layout(location = 3) in vec3 color; 
layout(location = 4) in float textureId; 

out vec3 fragColor; 
out vec3 vertex; 
out vec2 textureCoord; 
out vec3 norm; 
out int texId; 

void main() 
{ 
    vertex = position; 
    textureCoord = texCoord; 
    norm = normal; 
    fragColor = color; 
    // Excuse this 
    texId = int(textureId); 

    gl_Position = gl_ModelViewProjectionMatrix * vec4(position, 1.0); 
} 

조각 :

#version 400 

in vec3 fragColor; 
in vec3 vertex; 
in vec3 norm; 
in vec2 textureCoord; 
in int texId; 

out vec4 outColor; 

// Not used 
layout(location = 6) uniform vec3 cameraPosition; 
layout(location = 7) uniform sampler2D[7] textures; 

vec3 lightPos = vec3(3, 1, 0); 

void main() 
{ 
    //Position of vertex in modelview space 
    vec3 vertexPosition = (gl_ModelViewMatrix * vec4(vertex, 1.0)).xyz; 

    //Surface normal of current vertex 
    vec3 surfaceNormal = normalize((gl_NormalMatrix * norm).xyz); 

    //Direction light has traveled to get to vertexPosition 
    vec3 lightDirection = normalize(lightPos - vertexPosition); 

    //Basically how much light is hitting the vertex 
    float diffuseLightIntensity = max(0.0, dot(surfaceNormal, lightDirection)); 

    //"Main color"(diffuse) of vertex 
    vec3 diffColor = diffuseLightIntensity * fragColor; 

    //Adjust color depending upon distance from light 
    diffColor /= max(distance(lightPos, vertexPosition)/10, 1); 

    //Lowest light level possible 
    vec3 ambColor = vec3(0.01, 0.01, 0.01); 

    //"View vector" 
    vec3 viewVec = normalize(-vertexPosition); 

    //Direction light is reflected off of surface normal 
    vec3 reflectionDirection = normalize(reflect(-lightDirection, surfaceNormal)); 

    //The intensity of reflection (specular) 
    float specular = max(0.0, dot(reflectionDirection, viewVec)); 

    float shininess = 2.0; 

    float totalSpec = pow(specular, shininess); 

    totalSpec /= max(distance(gl_LightSource[0].position.xyz, vertexPosition)/4, 1); 

    vec3 specColor = vec3(totalSpec, totalSpec, totalSpec); 

    // Excuse this 
    if(texId != -1) 
    { 
     vec4 textureColor = texture(textures[texId], textureCoord); 
     outColor = vec4(ambColor, 1.0) + textureColor + vec4(specColor, 1.0); 
    } 
    else 
    { 
     outColor = vec4(ambColor, 1.0) + vec4(diffColor + specColor, 1.0); 
    } 
} 

내가

그래서 다음과 같은 쉐이더은 기본적으로 빛이 사방 플레이어가 다음과 같이 보이게 작동하지 않습니다 플레이어의 위치를 ​​ glUniform을 사용하여 cameraPosition으로 전달하기 만하면됩니다.

주어진 변수로 반사 하이라이트를 어떻게 만들 수 있습니까?

답변

2

카메라 위치에 관계없이 우리가 항상 똑같은 빛의 방향으로 보입니다. 버텍스 쉐이더에서 라이트 위치를 정의하고, 모델 뷰 매트릭스를 사용하여이를 변환 한 다음 프래그먼트 셰이더로 전달하십시오.