문제

GLSL을 사용하여 OpenGL에서 포인트 조명을 구현하려고합니다. 필요한 모든 데이터를 셰이더로 보냅니다. 단순화를 위해 여기서는 확산광 만 사용합니다.

내 예는 단일 광원으로 비추고 싶은 거대한 삼각형을 보여줍니다. 광원은 작은 파란색 삼각형으로 표시됩니다.

확산 빛의 경우 빛과 표면 사이의 각도를 알아야합니다. 그러므로 나는 정상과 빛의 방향을 계산합니다. 그런 다음 도트 제품은 나에게 -1에서 1 사이의 숫자를 제공하는 반면 0과 1 사이의 모든 것은 조명됩니다.

그러나 여기서 나는이 각도가 내 예에서 잘못 계산되기 때문에 붙어 있습니다. 셰이더를 디버그하기가 어렵 기 때문에 표면의 색상으로 여러 출력을 사용했습니다. 나는 정상을 삼각형의 색상으로 사용했고 빛이 어디에 있든 표면은 항상 녹색이었습니다. 즉, 정상은 y 축을 가리므로 제대로 계산됩니다. 즉, 빛의 방향이 잘못되어야합니다. 그러나 그것이 잘못된 이유를 찾을 수 없습니다. 빛의 위치와 정점의 위치는 세계 공간에서 정점 셰이더로 전달되어 눈 공간으로 변환하고 빛의 방향을 계산하고이를 조각 셰이더로 전달합니다.

정점 셰이더 :

vec4 pos = modelview_matrix * <input vertex>;
vec4 lightPos = modelview_matrix * <light position>;

vec3 lightDir = normalize(lightPos.xyz - pos.xyz);

조각 셰이더 :

float NdotL = max(dot(normalize(<correct normal>), normalize(lightDir)), 0.0);
gl_FragColor = vec4(1.0, NdotL, 0.0, 1.0);

나는 보간이 정말 이상하다는 것을 보여주는이 예제의 일부 사진을 추가했습니다. 내가 붙여 넣은 코드가 올바른지 또는 더 많은 코드를 알아야하는지 여부를 알고 싶습니다. 또한이 보간 동작이 정상입니까 아니면 내 코드의 버그입니까?

http://img41.imageshack.us/img41/3566/interpolation.png http://img189.imageshack.us/img189/3566/interpolation.png

특히 첫 번째 그림은 빛의 중심 지점이 아니다 빛 바로 아래에서 바로 아래에서 삼각형의 중심으로 약간 움직였습니다.

"POS"를 파편 셰이더로 전달한 다음 (즉, 보간) Fragment Shader에서 "LightDir"를 계산하면 모든 것이 잘 작동합니다.

도움이 되었습니까?

해결책

정점 셰이더에서 Lightdir를 정규화하면 벡터를 보간 할 때 얻은 결과에 영향을 미쳐 방정식의 길이를 빼앗아 보간의 "속도"에 영향을 미칩니다.

(시각적) 설명을 원한다면 종이에 2D로 그려보십시오. 먼저 선 (삼각형)과 포인트 (광원)를 그립니다. 라인의 양쪽 끝에 라이트 소스에 두 줄 (LightDir)을 추가 한 다음 Lightdir 라인을 축소 (정상화)하여 길이가 같은 길이를 갖고 둘 다 광원에서 만나도록하십시오. 정규화 된 Lightdir 라인의 양쪽 끝을 연결하면 비 평면 선이 나타납니다 (광원이 첫 번째 줄의 중간에 있지 않은 경우). 이제 선 중 하나의 중간을 정확히 통과하는 선을 그려면 다른 줄의 중간을 통과하지는 않지만 왼쪽이나 오른쪽에 약간 닿을 것임을 알 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top