2013-06-28 56 views
1

我想在LWJGL中創建一些基本的光照着色器。除了當我改變相機的旋轉時,一切似乎都在工作,照明改變。我認爲這是因爲當我旋轉相機時,法線的旋轉也被搞亂了。OpenGL在着色器中的正常轉換

這是我原來的頂點着色器:

uniform vec3 lightDir; 
varying vec3 normal; 

void main() 
{  
    normal = gl_NormalMatrix*gl_Normal; 
    gl_Position = ftransform(); 
} 

我的片段着色器:

varying vec3 normal; 

void main(){ 
    vec3 color = vec3(1,1,1); 
    vec3 lightDir = vec3(1,1,0); 
    float inten = 1; 
    color = color*dot(normal, lightDir)*inten; 
    gl_FragColor = vec4(color,1); 

} 

要改造我用鏡頭:

public static void applyTranslations() { 
    glPushAttrib(GL_TRANSFORM_BIT); 
    glMatrixMode(GL_MODELVIEW); 
    glRotatef(pitch, 1, 0, 0); 
    glRotatef(yaw, 0, 1, 0); 
    glRotatef(roll, 0, 0, 1); 
    glTranslatef(-x, -y, -z); 
    glPopAttrib(); 
} 

我意識到,轉化的這種方法相機可能實際上是改變了模型,而相機保持靜態,這將哈我弄錯了法線,所以我試圖輸入一個包含模型旋轉的統一矩陣來轉換法線,但這似乎也不起作用。現在整個模型都是黑色的。 (這是工作之前,除了旋轉) 我用它來傳遞更改着色器:

Vector3f scale, rot, trans; 
Matrix3f modelMatrix = new Matrix3f(); 
modelMatrix.setIdentity(); 
scale = new Vector3f(1,1,1); 
rot = new Vector3f(xRot,yRot,zRot); 
trans = new Vector3f(x,y,z); 

Matrix4f.scale(scale, modelMatrix, modelMatrix); 
Matrix4f.translate(trans, modelMatrix, modelMatrix); 
Matrix4f.rotate((float) Math.toRadians(rot.z), new Vector3f(0,0,1), modelMatrix, modelMatrix); 
Matrix4f.rotate((float) Math.toRadians(rot.y), new Vector3f(0,1,0), modelMatrix, modelMatrix); 
Matrix4f.rotate((float) Math.toRadians(rot.x), new Vector3f(1,0,0), modelMatrix, modelMatrix); 

FloatBuffer modelBuff = BufferUtils.createFloatBuffer(9); 
modelMatrix.store(modelBuff); 

int loc = ARBShaderObjects.glGetUniformLocationARB(e.m.shader.programID, "modelMatrix"); 
ARBShaderObjects.glUniformMatrix4ARB(loc, false, modelBuff); 

然後,我改變了我的頂點着色器:

uniform vec3 lightDir; 
uniform modelMatrix; 
varying vec3 normal; 

void main() 
{  
    normal = modelMatrix*gl_Normal; 
    gl_Position = ftransform(); 
} 

難道這就是我應該做的創建和傳遞轉換矩陣?還有沒有使用glRotatef()旋轉相機的另一種方法?

回答

0

vec3 lightDir = vec3(1,1,0)是固定的,而normal在每次相機改變時都被轉換。

爲了防止這種情況,請確保lightDirnormal處於相同的空間。在變換normal之前計算dot或者通過gl_NormalMatrix變換lightDir然後計算dot

除了要實現的效果之外,片段着色器中還存在一個問題:normal未歸一化。這是因爲單位矢量的線性插值並不總是產生單位矢量。

你應該做的是一樣的東西:

color*dot(normalize(normal), transform_to_same_space(lightDir))*inten; 

在第二部分中的一些小問題:

你聲明modelMatrix沒有一個類型。

您無法使用4x4矩陣轉換vec3。你可以使用0填充gl_Normal,因爲它是一個向量,或者將矩陣向下舍入爲float3x3

您使用Matrix4f.scaleVector3f(1,1,1)和翻譯將不會影響載體,所以modelMatrix是正交的。 但是,在一般情況下,您應該將gl_Normal轉換爲modelMatrix的轉置逆。