2011-04-19 6 views
2

내 GLSL 버텍스 쉐이더로 버텍스를 올바르게 표시하는 데 며칠 후, 이제 조명 위로 이동했습니다! OpenGL 조명/법선에 대한 나의 이해는 상상력의 어떤 스트레칭으로도 그리 좋지 않으므로 나와 함께 감내하십시오. 나는 그들이 정상적으로 표시되게하기 위해 나의 법선에 적용 할 필요가있는 번역을 확신하지 못합니다. 내 조명을 설정하는 응용 프로그램 코드는 다음과 같습니다.비표준 투영 행렬을 사용하는 GLSL 법선

final float diffuseIntensity = 0.9f; 
    final float ambientIntensity = 0.5f; 

    final float position[] = { 0f, 0f, 25000f, 0f}; 
    gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, position, 0); 
    final float diffuse[] = { 0, diffuseIntensity, 0, 1f}; 
    gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, diffuse, 0); 
    final float ambient[] = { ambientIntensity, ambientIntensity, ambientIntensity, 1f}; 
    gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, ambient, 0); 

지금까지 꽤 표준적인 것입니다.

void main() 
{ 
// P is the camera matrix, model_X_matrices are the relative translation/rotation etc of the model currently being rendered. 
vec4 pos = gl_ProjectionMatrix * P * modelTranslationMatrix * modelRotationMatrix * modelScaleMatrix * gl_Vertex; 

gl_Position = pos; 

gl_TexCoord[0] = gl_MultiTexCoord0; 

gl_FrontColor = gl_Color;   
} 

그것은 내가 세계로 gl_Normal 좌표를 변환 할 필요가 나의 이해입니다 : 이제 때문에 응용 프로그램의 요구 사항, 여기에 (약간 이상한) 버텍스 쉐이더입니다.

vec4 normal = modelTranslationMatrix * modelRotationMatrix * modelScaleMatrix * vec4(gl_Normal); 

을 그리고 나는 (이미 세계 공간에서 응용 프로그램 코드에서 선언) 빛의 위치를 ​​얻을 필요가있을 것이다 : 내 쉐이더를 들어, 나는이 될 것이라고 생각합니다. 나는 이것을 다음과 같이 행할 것이라고 생각한다 :

vec3 light_position = gl_LightSource[0].position.xyz; 

그리고 나서 정상 위치와 밝은 위치의 내적을 찾아 확산 값을 찾는다.

또한 조각 쉐이더에서이 확산 값으로 색상을 곱하면됩니다. 모든 것이 작동해야합니다. 나는 정상적인 좌표를 올바르게 변환하는 방법을 정말로 모르겠습니다. 내 가정이 맞습니까, 아니면 제가 완전히 공을 벗어 났습니까?

편집 : 일반 매트릭스 (gl_NormalMatrix)가, 내가 올바른 방법은 세계 공간에서 정상을 계산하는 추측하고있어 gl_ModelView 행렬의 단지 3 × 3 역이다 독서 후으로 gl_Normal을 곱하는 것입니다 modelTranslationMatrix * modelRotationMatrix * modelScaleMatrix의 역? 이 값을 여전히 P 행렬로 곱해야 할 필요가 있습니까? 그렇지 않으면 일반 계산과 관련이 없습니까?

답변

1

사전에 modelTranslationMatrix * modelRotationMatrix * modelScaleMatrix을 작성하고 단일 제복으로 만 전달해야합니다. 나는 이것이 세 질문 실현하지만 난 그냥 나 자신 나는이 함께 strugling 이후

법선은 모델 뷰 행렬의 역행렬의 전치 곱, 세부 사항은 우수한 문서에 설명되어 있습니다, 여기에 http://www.lighthouse3d.com/tutorials/glsl-tutorial/the-normal-matrix/

+0

게시 한 것처럼 정확히 완료했습니다! 그러나 여전히 제대로 작동하지 않습니다 ... 이제는 테스트 모델 (입방체)의 2 면만이 객체의 회전에 관계없이 볼 수 있습니다. 다른면은 투명합니다. 나는 정말로 확실하지 않다. 왜 ... –

+0

Backface Culling이 가능합니까? 노멀은 일반적으로 투명도 컬링에 영향을주지 않지만 무언가는 프리 머 티브의 와인딩을 바꿀 수 있습니다. – datenwolf

+0

모든 도징이 사용되지 않습니다. 모든 법선에 -1을 곱해서 도움이되는지 확인해 보겠습니다. –

0

발견 내 대답을 나눌 줄 알았다.

OpenGL의 벡터는 점 (즉, 축당 하나의 좌표)과 동의어로 표시됩니다. 이것이 의미하는 바는 방향이 원점에서 좌표로의 변환에 의해 정의된다는 것입니다. 개념 수학 벡터를 번역 할 때 방향을 변경하지 마십시오. 원문을 번역하지 않고 인 OpenGL 벡터를 번역하면이됩니다.

그리고 (또는 사용자 정의 행렬 스택이 무엇이든) 모델 뷰 행렬에 의해 법선 벡터를 변환에 대한 잘못된거야 - 일반적으로 그 회전 번역 포함됩니다 말하기 (그리고 질문에 확장,하지만 여기에도가 어느 쪽도 아니다). 변환을 적용하여 법선의 방향을 변경합니다. 긴 이야기는 짧습니다 : 버텍스를 멀리 떨어 뜨리면 법선들이 카메라 - 버텍스 벡터에 평행하게됩니다.

인체 공학적는

vec4 normal = modelTransformMatrix * vec4(gl_Normal); 

보다는

당신은 실제로
vec3 normal = mat3(modelTransformMatrix) * gl_Normal; 

가 따라서 번역 용어를 제외하고 있지만 회전, 크기 및 전단을 유지합니다.

카메라 매트릭스를 사용하는 방법은 원하는 작업에 따라 다릅니다. 중요한 것은 방정식의 모든 값이 같은 좌표 공간에 있다는 것입니다. 즉, 카메라의 투영 거리를 곱하면 문제가 발생할 가능성이 있습니다. 카메라가 3D 좌표계에서 화면 좌표 + 깊이로 투영되도록 설정되어 있기 때문입니다. 일반적으로 월드 공간에서 조명을 계산합니다. 모델 변환을 곱하고 카메라 투영법을 곱하면됩니다.