GLSL移动点光源

时间:2015-07-08 23:11:05

标签: java opengl glsl shader lwjgl

我一直在为我的LWJGL + Java应用程序编写一个点光着色器。我是根据this tutorial编写的。我的问题是当我用相机走动" 时,灯光也会移动。此外,当我旋转球体时,光线随之旋转
我相信问题出现在顶点着色器中,但我也将片段着色器放在以防万一。

示例1(无移动)
Example 1

示例2(向左移动并旋转相机)
Example 2

顶点着色器

#version 330

in vec4 in_Position;
in vec3 in_Normal;
in vec2 in_TextureCoord;

uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;
uniform mat3 normal;

uniform vec4 light_Pos; //Set to 0, 3, 0, 1

out Data {
    vec3 normal;
    vec3 eye;
    vec3 lDir;
    vec2 st;
} Out;

void main(void) {
    vec4 vert = view * model * light_Pos;
    vec4 pos = model * view * in_Position;
    Out.normal = normalize(in_Normal);
    Out.lDir = vec3(vert - pos);
    Out.eye = vec3(-pos);
    Out.st = in_TextureCoord;
    gl_Position = projection * view * model * in_Position;
}

片段着色器

#version 330

uniform sampler2D texture_diffuse;

in Data {
    vec3 normal;
    vec3 eye;
    vec3 lDir;
    vec2 st;
} In;

out vec4 color;

void main(void) {
    vec4 diffuse = texture(texture_diffuse, In.st);
    vec4 spec = vec4(0.0);

    vec3 n = normalize(In.normal);
    vec3 l = normalize(In.lDir);
    vec3 e = normalize(In.eye);

    float i = max(dot(n,l), 0.0);
    if (i > 0.0) {
        vec3 h = normalize(l+e);
        float intSpec = max(dot(h,n), 0.0);
        spec = vec4(1) * pow(intSpec, 50);  //50 is the shininess
    }
    color = max(i * diffuse + spec, vec4(0.2));
}


我已经尝试了this question中提出的解决方案,但它并没有解决我的问题。

2 个答案:

答案 0 :(得分:1)

只需快速浏览一下,看起来就像是将光线的位置乘以视图和模型矩阵:

vec4 vert = view * model * light_Pos;

这意味着无论何时走动/移动相机,您都需要更改影响光线位置的视图矩阵,同样,当您移动球体时,您需要更改模型矩阵这也影响了光的位置。

换句话说,如果你希望光线相对于世界是静止的,那么不要用任何矩阵对它进行变换。

答案 1 :(得分:1)

问题是您的法线,Out.lDir和Out.eye不在同一个坐标系中。正常在您的模型的坐标中,而另一个也在眼睛空间中。尝试以与light_Pos类似的方式将眼睛位置作为制服传递。

Light_Pos和Eye_Pos现在处于世界坐标系统中。现在只是calulate

vec4 pos = model * in_Position;
vec4 vert = light_Pos;

Out.eye = vec3(eye_Pos);

它应该工作。执行空间操作时,请始终确保所有点/矢量都在同一个坐标系中。