Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (498)
Games in Android Showcase (117)
games submitted by our members
Games in WIP (563)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Problems with Modern OpenGL lighting  (Read 3397 times)
0 Members and 1 Guest are viewing this topic.
Offline Nouht

Senior Newbie





« Posted 2014-05-12 15:28:25 »

Hello. I am creating a 3D world where I send matrices to a shader to create this. I am now trying to light up my world but it is causing me trouble. This is something I've been struggling for weeks on.

Here's my fragment shader code:
#version 120

varying vec4 color;
varying vec4 normal;
varying vec4 vertex;

uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
uniform mat4 normalMatrix;

void main() {
   mat4 modelView = viewMatrix * modelMatrix;
   vec3 vertexPos = (modelView * vertex).xyz;
   vec3 surfaceNormal = normalize((normalMatrix*normal).xyz);
   vec3 lightDirection = normalize(gl_LightSource[0].position.xyz - vertexPos);
   float diffuseLightIntensity = max(0, dot(surfaceNormal, lightDirection));
    gl_FragColor.rgb = diffuseLightIntensity * color.rgb;
    gl_FragColor += gl_LightModel.ambient;
    vec3 reflectionDirection = normalize(reflect(-lightDirection, surfaceNormal));
    float specular = max(0.0, dot(surfaceNormal, reflectionDirection));
    
    if (diffuseLightIntensity != 0) {
        float fspecular = pow(specular, gl_FrontMaterial.shininess);
        gl_FragColor += fspecular;
    }
}

Here's my vertex shader code:
#version 120

varying vec4 color;
varying vec4 normal;
varying vec4 vertex;

uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
uniform mat4 normalMatrix;

void main() {
    color = gl_FrontMaterial.diffuse;
    normal = vec4(gl_Normal, 1.0);
    vertex = gl_Vertex;   
    gl_Position = projectionMatrix * viewMatrix * modelMatrix * gl_Vertex;
}

I have my own maths classes that send the code to the shader and they work fine. Am I missing something with the code? I think I'm drawing the vertices correctly, by using a VBO. Cheers.

Here's what the lighting looks like: http://i.imgur.com/BSEZ9qc.png
Offline Danny02
« Reply #1 - Posted 2014-05-12 18:44:30 »

there shouldn't be any matrices in the fragment shader. Calculate the position, normal and lightdir in the vertex shader. You only need to normalize the normal in the fragment shader.

your fragment shader should look something like this(from my code base):
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
    vec3 N = normalize(normal);

    vec3 color, dcolor;
    color = vec3(0.);
    dcolor = diffuse;

    float NdotL = dot(N, light_pos);

    if(NdotL > 0.0){
        float HdotN = dot(N, halfvector);
        vec3 scolor = specular;
        #ifdef SPECULAR_MAPPING
            scolor *= texture(specular_sampler, texcoord).rgb;
        #endif
        color += scolor * pow(max(HdotN, 0.), mat_spec_exp);
        color += dcolor * NdotL;
    }
    color += ambient * dcolor;


where "halfvector" is the vector with half the angle between the eye and the light vector. Calculating the lighting in eye-space instead of world-space(what you tried to do), makes it much easier to calculate this halfvector. Just place this in the vertex shader:
1  
2  
  vec3 normal = view_matrix * normal_matrix * in_normal;
  vec3 halfvector = normalize(normal + vec3(0,0,1))
Offline Nouht

Senior Newbie





« Reply #2 - Posted 2014-05-12 19:56:30 »

@Danny02

Hi, thanks for your reply. I've tried mess around with it and something is still wrong. Here is the code:

Vertex Shader:

#version 120

varying vec4 color;
varying vec3 vertex;
varying vec3 normal;

uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
uniform mat4 normalMatrix;

void main() {
    color = gl_Color;
    vertex = vec3(viewMatrix * modelMatrix * gl_Vertex);
    normal = vec3(normalize(normalMatrix * gl_Vertex));
    gl_Position = projectionMatrix * viewMatrix * modelMatrix * gl_Vertex;
}

Fragment Shader:
#version 120

varying vec4 color;
varying vec3 vertex;
varying vec3 normal;

vec3 lightSource = vec3(0, 10, 0);
vec4 ambientTerm = vec4(0.1, 0.1, 0.1, 1);
vec4 diffuse = vec4(0.5, 0.5, 0.5, 1);
vec4 specular = vec4(0.1, 0.1, 0.1, 1);
float shininess = 0.1;

void main() {
   vec3 light =  normalize(lightSource - vertex);
   vec3 eyeCoords = normalize(-vertex);
   vec3 reflection = normalize(-reflect(light, normal));
   
   vec4 diffuseTerm = diffuse * max(dot(normal, light), 0.0);
   diffuseTerm = clamp(diffuseTerm, 0.0, 1.0);
   
   vec4 specularTerm = specular * pow(max(dot(reflection, eyeCoords),0.0), 0.3 * shininess);
   specularTerm = clamp(specularTerm, 0.0, 1.0);
   
    gl_FragColor = color + ambientTerm + diffuseTerm+ specularTerm;
}
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Longarmx
« Reply #3 - Posted 2014-05-12 21:08:51 »

Have you tried to calculate it like this?

1  
glFragColor = color * (ambientTerm + diffuseTerm + specularTerm);

Offline Nouht

Senior Newbie





« Reply #4 - Posted 2014-05-12 21:30:21 »

@Longarmx

Yes, the colour gave a darker image, but the light keeps moving around the world with the camera.
Offline Danny02
« Reply #5 - Posted 2014-05-13 06:32:13 »

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
#version 120

varying vec4 color;
varying vec3 vertex;
varying vec3 normal;

uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
uniform mat4 normalMatrix;

void main() {
    color = gl_Color;
    vertex = vec3(viewMatrix * modelMatrix * gl_Vertex);
-    normal = vec3(normalize(normalMatrix * gl_Vertex));
+    normal = vec3(viewMatrix * normalMatrix * normal);
    gl_Position = projectionMatrix * viewMatrix * modelMatrix * gl_Vertex;
}

Fragment Shader:
#version 120

varying vec4 color;
varying vec3 vertex;
varying vec3 normal;

vec3 lightSource = vec3(0, 10, 0);
vec4 ambientTerm = vec4(0.1, 0.1, 0.1, 1);
vec4 diffuse = vec4(0.5, 0.5, 0.5, 1);
vec4 specular = vec4(0.1, 0.1, 0.1, 1);
float shininess = 0.1;

void main() {
+   vec3 N = normalize(normal);
   vec3 light =  normalize(lightSource - vertex);
   vec3 eyeCoords = normalize(-vertex);
-   vec3 reflection = normalize(-reflect(light, normal));
+   vec3 reflection = reflect(light, N);
   
   vec4 diffuseTerm = diffuse * max(dot(N, light), 0.0);
-   diffuseTerm = clamp(diffuseTerm, 0.0, 1.0);
   
   vec4 specularTerm = specular * pow(max(dot(reflection, eyeCoords),0.0), 0.3 * shininess);
   specularTerm = clamp(specularTerm, 0.0, 1.0);
   
-    gl_FragColor = color + ambientTerm + diffuseTerm+ specularTerm;
+    gl_FragColor = color * (ambientTerm + diffuseTerm) + specularTerm;
}
Offline theagentd
« Reply #6 - Posted 2014-05-13 13:49:53 »

Your shininess should probably also be bumped up a lot. 5+ is a good start. Under 1 looks weird as hell.

Myomyomyo.
Offline Nouht

Senior Newbie





« Reply #7 - Posted 2014-05-13 22:17:33 »

Okay, the lighting kinda works but I can adjust it later. But whenever the camera rotates or moves the light seems to move. Any reason why?

Here is the updated shaders:

vs
#version 120

varying vec4 color;
varying vec4 vertex;
varying vec4 normal;

uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
uniform mat4 normalMatrix;

void main() {
    color = gl_Color;
   
   mat4 modelView = viewMatrix * modelMatrix;
    mat4 modelViewProjection = projectionMatrix * viewMatrix * modelMatrix;
   
    vertex = modelView * gl_Vertex;
    normal = normalMatrix * vec4(gl_Normal, 1.0);
    gl_Position = modelViewProjection * gl_Vertex;   
}


fs
#version 120

varying vec4 color;
varying vec4 vertex;
varying vec4 normal;

vec4 lightPos = vec4(5, 0, 5, 1.0);
vec4 ambientTerm = vec4(0.25, 0.25, 0.25, 1.0);
vec4 diffuse = vec4(0.5, 0.5, 0.5, 1.0);
vec4 specular = vec4(0.5, 0.5, 0.5, 1.0);
float shininess = 25;

void main() {
   vec4 N = normalize(normal);
   vec4 light = normalize(lightPos - vertex);
   vec4 eyeCoords = normalize(-vertex);
   vec4 reflection = reflect(light, N);
   
   vec4 diffuseTerm = diffuse * max(dot(N, light), 0.0);
   //diffuseTerm = clamp(diffuseTerm, 0.0, 1.0);
   
   vec4 specularTerm = specular * pow(max(dot(reflection, -eyeCoords), 0.0), shininess);
   specularTerm = clamp(specularTerm, 0.0, 1.0);
   
   gl_FragColor = color * (ambientTerm + diffuseTerm) + specularTerm;
}
Offline Danny02
« Reply #8 - Posted 2014-05-14 06:21:07 »

The light direction is constant in view space and not in world-space, because your lighting calculation happens in view space. Declare it as a uniform and transform it each frame into view-space on the CPU.

1  
2  
3  
4  
5  
6  
7  
Vec3 lightDir = ...;
Matrix4 view = ...;

Vec3 vsLightDir = view.mult(lightDir);
shader.updateLightDir(vsLightDir);

renderScene();
Offline Nouht

Senior Newbie





« Reply #9 - Posted 2014-05-14 07:52:01 »

Thanks everyone! It works now! http://i.imgur.com/hoTKoxP.png
If anyone is having the same issue just message me and I'll give you the code.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Riven
« League of Dukes »

JGO Overlord


Medals: 800
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #10 - Posted 2014-05-14 08:40:59 »

To get rid of the noticeable banding issues, you can add a random value (between 0 and 1/256th) to each fragment. Due to the rounding when writing to the framebuffer, you should get an ultra smooth gradient, not like noise at all - think of it as dithering.



Update: (I plugged in some arbitrary primes to make the dithering patterns less obvious)





Zoomed in: (top: banding, bottom: dithering, showing my poorly chosen constants)




Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline Simn
« Reply #11 - Posted 2014-05-14 13:54:02 »

Looking good Nouht! Still up to 0x10c? Grin

- Simn
Offline Nouht

Senior Newbie





« Reply #12 - Posted 2014-05-14 17:00:33 »

Cheers for that @Riven. Tried it, it works great!
Offline Nouht

Senior Newbie





« Reply #13 - Posted 2014-05-14 18:51:25 »

Another question: how would I modify this shader to add multiple lights? I've got a ArrayList with some lights and tried using a for-loop to cycle through the lights when I set a uniform, that just gives me lights blinking on and off after each other.
Offline Danny02
« Reply #14 - Posted 2014-05-14 21:47:35 »

They way most people did it was to have an uniform array with data for multiple lights. Such an array will have a constant size, which may be choosen either by performance or memory concerns.

If you have more lights in your scene then you can render at once, you can do two things. Either choose only the most important light sources for each object, or render each object in multiple passes.

Lets say you can only render 5 lights at the same time, but have many 13 lights in total:
1. somehow order the lights for each object(e.g. 1/distance² * intensity) and only select the top 5.
2. render all lights in 3 passes which are blended together. Only apply the ambient term once.
Offline Nouht

Senior Newbie





« Reply #15 - Posted 2014-05-15 13:44:30 »

@danny02

Thanks for that. So every time a make another pass at the render the last light in the array always seems to override the other lights, so it only renders the last one
Pages: [1]
  ignore  |  Print  
 
 

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

Grunnt (13 views)
2014-09-23 14:38:19

radar3301 (14 views)
2014-09-21 23:33:17

BurntPizza (31 views)
2014-09-21 02:42:18

BurntPizza (22 views)
2014-09-21 01:30:30

moogie (20 views)
2014-09-21 00:26:15

UprightPath (29 views)
2014-09-20 20:14:06

BurntPizza (33 views)
2014-09-19 03:14:18

Dwinin (48 views)
2014-09-12 09:08:26

Norakomi (75 views)
2014-09-10 13:57:51

TehJavaDev (105 views)
2014-09-10 06:39:09
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!