2017-12-27 30 views
3

OpenGL과 GLSL을 사용하여 방향 조명을 내 씬에 추가하고 싶습니다. 문제는 이론적으로 올바른 방법으로 잘못된 결과가 발생한다는 것입니다. 광의OpenGL 지향성 조명 쉐이더

방향은 월드 좌표에 주어진 카메라 좌표에 viewMatrix를 사용하여 변환된다 : I은 다음과 버텍스 셰이더

. 정점의 법선은 노멀 - 행렬 - 카메라 좌표를 사용하여 변환됩니다.

void main() { 
    vary_textureCoord = attribute_textureCoord; 
    vary_normal = mat3(normalMatrix) * attribute_normal; 

    vary_directionalLight_direction = viewMatrix * vec4(lightDir, 1.0); 

    gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(attribute_position, 1.0); 
} 

따라서 두 벡터가 모두 카메라 좌표에 있고 조각 쉐이더로 전달됩니다. 프래그먼트 셰이더는 법선과 빛의 방향을 사용하여 빛의 강도를 계산합니다.

void main() { 
    vec3 normalizedNormal = normalize(vary_normal); 
    vec4 color = texture(tex, vary_textureCoord); 

    float directionalLightIntensity = max(0.0, dot(normalizedNormal, normalize(-vary_directionalLight_direction.xyz))); 

    out_color = color * directionalLightIntensity; 
} 

이 셰이더는 빛이 정적이지 않고 카메라와 함께 움직이는 결과를 가져옵니다. 대신이 라인을 사용하여 버텍스 쉐이더를 변경하십시오 :

vary_directionalLight_direction = transpose(inverse(viewMatrix)) * vec4(lightDir, 1.0); 

원하는 결과가 있습니다. 그래서 내가 뭘 잘못하고 있고 어디에서 오해가 있니? 여기

전체 쉐이더 코드 :

Vertexshader :

# version 330 

layout(location = 0) in vec3 attribute_position; 
layout(location = 2) in vec2 attribute_textureCoord; 
layout(location = 3) in vec3 attribute_normal; 

uniform mat4 projectionMatrix; 
uniform mat4 viewMatrix; 
uniform mat4 modelMatrix; 
uniform mat4 normalMatrix; 
uniform vec3 lightDir; 

out vec2 vary_textureCoord; 
out vec3 vary_normal; 
out vec4 vary_directionalLight_direction; 

void main() { 
    vary_textureCoord = attribute_textureCoord; 
    vary_normal = mat3(normalMatrix) * attribute_normal; 

    vary_directionalLight_direction = viewMatrix * vec4(lightDir, 1.0); 

    gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(attribute_position, 1.0); 
} 

Fragmentshader : 변형 행렬은 다음과 같습니다

# version 330 

in vec2 vary_textureCoord; 
in vec3 vary_normal; 
in vec4 vary_directionalLight_direction; 

uniform sampler2D tex; 

out vec4 out_color; 

void main() { 
    vec3 normalizedNormal = normalize(vary_normal); 
    vec4 color = texture(tex, vary_textureCoord); 

    float directionalLightIntensity = max(0.0, dot(normalizedNormal, normalize(-vary_directionalLight_direction.xyz))); 

    out_color = color * directionalLightIntensity; 
} 

답변

1

:

(X-axis.x, X-axis.y, X-axis.z, 0) 
(Y-axis.x, Y-axis.y, Y-axis.z, 0) 
(Z-axis.x, Z-axis.y, Z-axis.z, 0) 
(trans.x, trans.y, trans.z, 1) 

당신이 t를 원하는 경우 o 위치를 변환하면 전체 변환 행렬을 위치에 적용해야합니다.

mat4 viewMatrix; 
vec3 pos; 
vec4 viewPos = viewMatrix * vec4(pos, 1.0); 

이렇게하면보기의 방향과 위치가 pos 위치에 적용됩니다.

그러나 방향은 원점이 없습니다. 방향은 오리엔테이션 만 있습니다.

vary_directionalLight_direction = vec4(mat3(viewMatrix) * lightDir, 1.0); 
: 이것은 당신이보기에 의해, 방향 벡터를 변환하려는 경우, 당신은 4 * 4 viewMatrix의 왼쪽 상단 3 * 3 부분으로 곱해야 의미