简体   繁体   中英

GLSL Moving Point Light

I have been writing a point light shader for my LWJGL + Java application. 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 , but I put the fragment shader in also just in case. ,但我也将片段着色器放在以防万一。

Example 1 (No movement)
例子1

Example 2 (Moved Left and rotated the camera)
例子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. 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 and Eye_Pos are now in world coord system. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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