2015-01-17 4 views
1
내가 opengl.org에있는 다음 퐁 조명 쉐이더를 통해 읽고 있었다

다음과 같이퐁 조명

Phong Illumination in Opengl.org

정점과 프래그먼트 쉐이더이었다 :

버텍스 쉐이더 :

varying vec3 N; 
varying vec3 v; 
void main(void) 
{  
    v = vec3(gl_ModelViewMatrix * gl_Vertex);  
    N = normalize(gl_NormalMatrix * gl_Normal); 
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; 
} 

조각 쉐이더 :

varying vec3 N; 
varying vec3 v;  
void main (void) 
{ 
    vec3 L = normalize(gl_LightSource[0].position.xyz - v); 
    vec3 E = normalize(-v); // we are in Eye Coordinates, so EyePos is (0,0,0) 
    vec3 R = normalize(-reflect(L,N)); 

    //calculate Ambient Term: 
    vec4 Iamb = gl_FrontLightProduct[0].ambient;  

    //calculate Diffuse Term: 
    vec4 Idiff = gl_FrontLightProduct[0].diffuse * max(dot(N,L), 0.0); 
    Idiff = clamp(Idiff, 0.0, 1.0);  

    // calculate Specular Term: 
    vec4 Ispec = gl_FrontLightProduct[0].specular 
       * pow(max(dot(R,E),0.0),0.3*gl_FrontMaterial.shininess); 
    Ispec = clamp(Ispec, 0.0, 1.0); 
    // write Total Color: 
    gl_FragColor = gl_FrontLightModelProduct.sceneColor + Iamb + Idiff + Ispec;  
} 

그는 뷰어 벡터 또는 v을 계산하는 방법에 대해 궁금합니다. 정점 위치에 gl_ModelViewMatrix을 곱하면 결과가 뷰 행렬이되고 뷰 좌표는 월드 좌표와 비교하여 대부분 회전합니다.

따라서 동일한 좌표계에 있지 않으므로 v에서 빛 위치를 빼서 L 벡터를 계산할 수 없습니다. 또한 L과 N 사이의 내적 결과는 좌표가 동일하지 않기 때문에 정확하지 않습니다. 나는 그것에 관해 오른쪽인가?

답변

4

그래서 우리는 같은 좌표계에 있지 않기 때문에 L 위치 벡터에서 L을 계산하기 위해 간단히 빛 위치를 빼낼 수 없습니다. 또한 L과 N 사이의 내적 결과는 좌표가 동일하지 않기 때문에 이 정확하지 않습니다. 나는 그것에 관해 오른쪽인가?

gl_LightSource[0].position.xyz 번호

은 당신이 GL_POSITION을 설정 하지 값입니다. GL은 glLight() 호출시 자동으로 위치를 현재 GL_MODELVIEW 행렬로 곱합니다. 조명 계산은 고정 함수 GL에서 시각 공간에서 완전히 수행됩니다. 따라서 VN은 시각 공간으로 변환되어야하고 gl_LightSource[].position은 이미 시각 공간으로 변환되므로 코드가 정확하고 실제로 다른 좌표 공간을 혼합하지 않습니다.

사용중인 코드는 특정 문제를 포함하여 GL의 이전 고정 기능 기능을 많이 사용하여 더 이상 사용되지 않는 기능에 의존합니다. mordern GL에서는 내장 된 유니폼과 속성이 존재하지 않으므로 직접 정의해야하며 원하는대로 해석 할 수 있습니다.

당연히 그 규칙을 무시하고 내장 좌표계와 함께 조명 계산에 다른 좌표 공간을 사용할 수도 있습니다. 그리고 위치를 설정할 때 다른 행렬을 단순히 다르게 선택하여 해석하십시오 (일반적으로 조명의 세계 공간 위치는 다음과 같습니다). GL_MODELVIEW 행렬에는 뷰 변환 만 포함되어 있으므로 일부 고정 된 광원의 눈 - 공간 라이트 위치가 표시되지만 원하는대로 설정할 수 있습니다. 그러나 제시된 코드는 고정 함수 파이프 라인에 대한 "드롭 인 (drop-in)"대체 코드로 작동하기 때문에 고정 함수 파이프 라인과 동일한 방식으로 내장 된 유니폼과 특성을 해석합니다.

+0

아, 알겠습니다. 그래서,'gl_NormalMatrix'는 오래된 고정 함수 파이프 라인의 model_view 행렬을 포함하고 또한'gl_LightSource'는 뷰 좌표로 변환됩니다. 그런 다음 코드가 작동합니다. 사실 OpenGL Phong 조명 쉐이더를 검사하고 있었고 뷰 좌표에서 퐁 조명 계산을 수행하고있었습니다. – mmostajab

+0

@ mmostajab : 글쎄,'gl_NormalMatrix'는 modelview 행렬에서 파생 된 것이지, 똑같은 것은 아닙니다. 그 이유는 어떤 경우에는 법선이 다르게 변형되어야하기 때문입니다. "비뚤어 짐"작업을 생각하십시오. 정상 방향 dircetly에 적용하면, 결과로 생기는 법선은 더 이상 표면에 수직 방향으로 올라가지 않습니다. (그들이 전에 있다고 가정). 더 자세한 설명은 [이 lighthouse3d 튜토리얼] (http://www.lighthouse3d.com/tutorials/glsl-tutorial/the-normal-matrix/)에서 제공됩니다. – derhass