简体   繁体   English

GLSL移动点灯

[英]GLSL Moving Point Light

I have been writing a point light shader for my LWJGL + Java application. 我一直在为我的LWJGL + Java应用程序编写点光源着色器。 I am writing it based off of this tutorial . 我是根据本教程编写的。 My problem is when I "walk around" with the camera, the light moves as well. 我的问题是当我用相机“四处走动”时,灯光也会移动。 Also, when I rotate the sphere, the light rotates with it. 另外,当我旋转球体时,灯光也会随之旋转。

I believe that the problem is in the Vertex Shader , but I put the fragment shader in also just in case. 我相信问题出在Vertex Shader中 ,但我也将片段着色器放在以防万一。

Example 1 (No movement) 示例1(不移动)
例子1

Example 2 (Moved Left and rotated the camera) 示例2(向左移动并旋转相机)
例子2

Vertex Shader 顶点着色器

#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;
}

Fragment Shader 片段着色器

#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));
}


I already tried the solution presented in this question , it did not solve my problem. 我已经尝试过此问题中提出的解决方案,但没有解决我的问题。

Just from a quick glance, looks like you're multiplying the light's position by the view and model matrix: 乍一看,就好像您将光源的位置乘以视图和模型矩阵:

vec4 vert = view * model * light_Pos;

This means that whenever you walk around/move the camera you're changing the view matrix which affects the light's position, and likewise your when you move the sphere you're changing the model matrix which is also affects the light's position. 这意味着,每当您走动/移动摄像机时,您都在更改会影响灯光位置的视图矩阵,同样,当您移动球体时,您也在更改也会影响灯光位置的模型矩阵。

In other words if you want the light to be stationary in relation to the world then don't transform it by any matrices. 换句话说,如果您希望光相对于世界是静止的,则不要通过任何矩阵对其进行变换。

The problem is that your normal, Out.lDir and Out.eye are not in the same coordinate system. 问题在于您的法线,Out.lDir和Out.eye不在同一坐标系中。 Normal is in your model's coords while the other too are in the eye space. 法线位于模型的坐标中,而其他坐标也位于眼部空间中。 Try to pass eye position as a uniform in a similar way to light_Pos. 尝试以与light_Pos类似的方式将眼睛位置作为制服传递。

Light_Pos and Eye_Pos are now in world coord system. Light_Pos和Eye_Pos现在处于世界坐标系中。 Now just calulate 现在算一下

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

and

Out.eye = vec3(eye_Pos);

It should work. 它应该工作。 When performing spatial operations always make sure that all points / vectors are in the same coorinate system. 执行空间操作时,请始终确保所有点/向量都在同一坐标系中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM