• Advertisement
  • Popular Tags

  • Popular Now

  • Advertisement
  • Similar Content

    • By Achivai
      Hey, I am semi-new to 3d-programming and I've hit a snag. I have one object, let's call it Object A. This object has a long int array of 3d xyz-positions stored in it's vbo as an instanced attribute. I am using these numbers to instance object A a couple of thousand times. So far so good. 
      Now I've hit a point where I want to remove one of these instances of object A while the game is running, but I'm not quite sure how to go about it. At first my thought was to update the instanced attribute of Object A and change the positions to some dummy number that I could catch in the vertex shader and then decide there whether to draw the instance of Object A or not, but I think that would be expensive to do while the game is running, considering that it might have to be done several times every frame in some cases. 
      I'm not sure how to proceed, anyone have any tips?
    • By fleissi
      Hey guys!

      I'm new here and I recently started developing my own rendering engine. It's open source, based on OpenGL/DirectX and C++.
      The full source code is hosted on github:
      https://github.com/fleissna/flyEngine

      I would appreciate if people with experience in game development / engine desgin could take a look at my source code. I'm looking for honest, constructive criticism on how to improve the engine.
      I'm currently writing my master's thesis in computer science and in the recent year I've gone through all the basics about graphics programming, learned DirectX and OpenGL, read some articles on Nvidia GPU Gems, read books and integrated some of this stuff step by step into the engine.

      I know about the basics, but I feel like there is some missing link that I didn't get yet to merge all those little pieces together.

      Features I have so far:
      - Dynamic shader generation based on material properties
      - Dynamic sorting of meshes to be renderd based on shader and material
      - Rendering large amounts of static meshes
      - Hierarchical culling (detail + view frustum)
      - Limited support for dynamic (i.e. moving) meshes
      - Normal, Parallax and Relief Mapping implementations
      - Wind animations based on vertex displacement
      - A very basic integration of the Bullet physics engine
      - Procedural Grass generation
      - Some post processing effects (Depth of Field, Light Volumes, Screen Space Reflections, God Rays)
      - Caching mechanisms for textures, shaders, materials and meshes

      Features I would like to have:
      - Global illumination methods
      - Scalable physics
      - Occlusion culling
      - A nice procedural terrain generator
      - Scripting
      - Level Editing
      - Sound system
      - Optimization techniques

      Books I have so far:
      - Real-Time Rendering Third Edition
      - 3D Game Programming with DirectX 11
      - Vulkan Cookbook (not started yet)

      I hope you guys can take a look at my source code and if you're really motivated, feel free to contribute :-)
      There are some videos on youtube that demonstrate some of the features:
      Procedural grass on the GPU
      Procedural Terrain Engine
      Quadtree detail and view frustum culling

      The long term goal is to turn this into a commercial game engine. I'm aware that this is a very ambitious goal, but I'm sure it's possible if you work hard for it.

      Bye,

      Phil
    • By tj8146
      I have attached my project in a .zip file if you wish to run it for yourself.
      I am making a simple 2d top-down game and I am trying to run my code to see if my window creation is working and to see if my timer is also working with it. Every time I run it though I get errors. And when I fix those errors, more come, then the same errors keep appearing. I end up just going round in circles.  Is there anyone who could help with this? 
       
      Errors when I build my code:
      1>Renderer.cpp 1>c:\users\documents\opengl\game\game\renderer.h(15): error C2039: 'string': is not a member of 'std' 1>c:\program files (x86)\windows kits\10\include\10.0.16299.0\ucrt\stddef.h(18): note: see declaration of 'std' 1>c:\users\documents\opengl\game\game\renderer.h(15): error C2061: syntax error: identifier 'string' 1>c:\users\documents\opengl\game\game\renderer.cpp(28): error C2511: 'bool Game::Rendering::initialize(int,int,bool,std::string)': overloaded member function not found in 'Game::Rendering' 1>c:\users\documents\opengl\game\game\renderer.h(9): note: see declaration of 'Game::Rendering' 1>c:\users\documents\opengl\game\game\renderer.cpp(35): error C2597: illegal reference to non-static member 'Game::Rendering::window' 1>c:\users\documents\opengl\game\game\renderer.cpp(36): error C2597: illegal reference to non-static member 'Game::Rendering::window' 1>c:\users\documents\opengl\game\game\renderer.cpp(43): error C2597: illegal reference to non-static member 'Game::Rendering::window' 1>Done building project "Game.vcxproj" -- FAILED. ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========  
       
      Renderer.cpp
      #include <GL/glew.h> #include <GLFW/glfw3.h> #include "Renderer.h" #include "Timer.h" #include <iostream> namespace Game { GLFWwindow* window; /* Initialize the library */ Rendering::Rendering() { mClock = new Clock; } Rendering::~Rendering() { shutdown(); } bool Rendering::initialize(uint width, uint height, bool fullscreen, std::string window_title) { if (!glfwInit()) { return -1; } /* Create a windowed mode window and its OpenGL context */ window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL); if (!window) { glfwTerminate(); return -1; } /* Make the window's context current */ glfwMakeContextCurrent(window); glViewport(0, 0, (GLsizei)width, (GLsizei)height); glOrtho(0, (GLsizei)width, (GLsizei)height, 0, 1, -1); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glfwSwapInterval(1); glEnable(GL_SMOOTH); glEnable(GL_DEPTH_TEST); glEnable(GL_BLEND); glDepthFunc(GL_LEQUAL); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); glEnable(GL_TEXTURE_2D); glLoadIdentity(); return true; } bool Rendering::render() { /* Loop until the user closes the window */ if (!glfwWindowShouldClose(window)) return false; /* Render here */ mClock->reset(); glfwPollEvents(); if (mClock->step()) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glfwSwapBuffers(window); mClock->update(); } return true; } void Rendering::shutdown() { glfwDestroyWindow(window); glfwTerminate(); } GLFWwindow* Rendering::getCurrentWindow() { return window; } } Renderer.h
      #pragma once namespace Game { class Clock; class Rendering { public: Rendering(); ~Rendering(); bool initialize(uint width, uint height, bool fullscreen, std::string window_title = "Rendering window"); void shutdown(); bool render(); GLFWwindow* getCurrentWindow(); private: GLFWwindow * window; Clock* mClock; }; } Timer.cpp
      #include <GL/glew.h> #include <GLFW/glfw3.h> #include <time.h> #include "Timer.h" namespace Game { Clock::Clock() : mTicksPerSecond(50), mSkipTics(1000 / mTicksPerSecond), mMaxFrameSkip(10), mLoops(0) { mLastTick = tick(); } Clock::~Clock() { } bool Clock::step() { if (tick() > mLastTick && mLoops < mMaxFrameSkip) return true; return false; } void Clock::reset() { mLoops = 0; } void Clock::update() { mLastTick += mSkipTics; mLoops++; } clock_t Clock::tick() { return clock(); } } TImer.h
      #pragma once #include "Common.h" namespace Game { class Clock { public: Clock(); ~Clock(); void update(); bool step(); void reset(); clock_t tick(); private: uint mTicksPerSecond; ufloat mSkipTics; uint mMaxFrameSkip; uint mLoops; uint mLastTick; }; } Common.h
      #pragma once #include <cstdio> #include <cstdlib> #include <ctime> #include <cstring> #include <cmath> #include <iostream> namespace Game { typedef unsigned char uchar; typedef unsigned short ushort; typedef unsigned int uint; typedef unsigned long ulong; typedef float ufloat; }  
      Game.zip
    • By lxjk
      Hi guys,
      There are many ways to do light culling in tile-based shading. I've been playing with this idea for a while, and just want to throw it out there.
      Because tile frustums are general small compared to light radius, I tried using cone test to reduce false positives introduced by commonly used sphere-frustum test.
      On top of that, I use distance to camera rather than depth for near/far test (aka. sliced by spheres).
      This method can be naturally extended to clustered light culling as well.
      The following image shows the general ideas

       
      Performance-wise I get around 15% improvement over sphere-frustum test. You can also see how a single light performs as the following: from left to right (1) standard rendering of a point light; then tiles passed the test of (2) sphere-frustum test; (3) cone test; (4) spherical-sliced cone test
       

       
      I put the details in my blog post (https://lxjk.github.io/2018/03/25/Improve-Tile-based-Light-Culling-with-Spherical-sliced-Cone.html), GLSL source code included!
       
      Eric
    • By Fadey Duh
      Good evening everyone!

      I was wondering if there is something equivalent of  GL_NV_blend_equation_advanced for AMD?
      Basically I'm trying to find more compatible version of it.

      Thank you!
  • Advertisement
  • Advertisement
Sign in to follow this  

OpenGL 2D OpenGL lightning using shaders

This topic is 966 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello everybody smile.png

I've been following Ben Arnold's youtube channel tutorials (https://www.youtube.com/user/makinggameswithben) on making a game ( and a game engine ) ... He had a tutorial on making simple 2D lighting effects using shaders.
However, after implementing that, it doesn't really satisfy me :/ , I mean, the light barely looks like it really "lights up" the scene, and, my biggest problem is that i want the scene to be completely black, and the light will shine through and "reveal" the real texture color of the walls and ground and everything. But, when i set the walls color to black, or its alpha value, the light has no affect on it..

Should it be like that ? I've tried so many modifications to my shaders and played with them but could not get what i want..

 

That is what I have at the moment:

10fc5kw.png

 

As you can see, I do have a light that makes the surrounding bricks look brighter, but it doesn't look quite "correct", and also, as i have mentioned, if the entire scene is completely dark, the light wont make the texture light up in the darkness.

 

I want to achieve an effect similar to this: (for example pay attention to second 0:48 and forwards..)

 

Like in this video where if a place is dark, the light hits it and makes it visible in it colors again..

 

I have a separate shader for this light point and for the scene.. I can provide the code samples if needed ...
any help with that would be greatly appreciated, I am thoroughly confused smile.png

 

p.s. I did actually check out the source code from github, of the game in the video, but it is like so much more complicated and different than what i am doing, plus a lot of the code and the comments are in croatian ...

 

Share this post


Link to post
Share on other sites
Advertisement

Should it be like that ? I've tried so many modifications to my shaders and played with them but could not get what i want..

The texture and alpha should be as when the object is fully lit. It is the light that makes a scene bright or dark, not the scenery.

 

Then in the shader compute / sample a light value (some gray, usually, where black means unlit and white means full lit) and multiply (component by component) that light value with the texture color value. Regardless of the texture color value, when multiplied with the extreme 0,0,0,1 (no light) will yield in black, and multiply with extreme 1,1,1,1 (full light) will yield in the texture's color; anything in-between will yield in shades of the texture color.

Edited by haegarr

Share this post


Link to post
Share on other sites

Hello again smile.png

 

 

The texture and alpha should be as when the object is fully lit. It is the light that makes a scene bright or dark, not the scenery.

 

haegarr, thanks for that. I have returned the colors of the scenery to its "initial" color and alpha..

As you had advised, I have changed my shaders so that the "main" shader now has a sampler2D of both the light and of the original texture, however, I when I multiply the light with the initial color ... I get a completely black scene with nothing visible but a single light point that follows my mouse...

 

But, if i don't include the light sampler in the calculations, (thus the final calculation involved the original texture color, ambience, and the color passed from the vertex shader), then then i get the same result as in the screenshot in my previous post... why ?? blink.png

 

anyway, as i said previously, i have a separate shader for this light point, and a separate one for the scene, so, in the scene shader -  I have tried to remove the light sampler, instead do the light point calculations inside the scene sahder, and include it in the calculation with the texture sampler .... again, playing around with it gave me either a completely black screen, a black screen with a single light point, or the original scene with strange artifacts and is was like as if this little light point was sitting inside every brick texture, I don't know I cant even explain tongue.png ...

 

At the moment, that is how my shaders look:

 

scene.fs

#version 130

in vec2 fragmentPosition;
in vec4 fragmentColor;
in vec2 fragmentUV; 

uniform sampler2D texture; // base texture
uniform sampler2D lightMap; 

uniform vec4 ambientColor; // ambiemce

void main() {

    vec3 ambient = ambientColor.rgb * ambientColor.a;
    vec4 temp = texture2D(texture, fragmentUV);
    vec4 textureColor = texture2D(lightMap, fragmentUV);

    gl_FragColor = temp * vec4(ambient, 1) * fragmentColor;

}

pointLight.fs

#version 130

in vec2 fragmentPosition;
in vec4 fragmentColor;
in vec2 fragmentUV;

//uniform vec2 lightLocation;
//uniform sampler2D texture;

void main() {
    float distance = length(fragmentUV);
    vec4 color = vec4(fragmentColor.rgb - distance, fragmentColor.a);

    gl_FragColor = color;// * fragmentColor;
}

with these two i get the same result as in the screenshot from the previous post.. and, If i make the ambient light completely dark, then again, the light has no effect on the scene ...
And just a final question  -  In the video from the previous post, those completely dark areas - why are they dark ? I mean, is the original texture color black, or is it the ambient light that makes it look like that ? why then when light hits it, the original color is revealed, unlike in my case ?

 

I think I now understand less than before ?! wacko.png

Share this post


Link to post
Share on other sites

What you want to get in the end is something like

    screen_color := scene_color * clamped( ambient_light + spot_light )

           = clamped( scene_color * ambient_light + scene_color * spot_light )

for each pixel on the screen, so that when the sum of light is 1 the scene_color (read from texture) is fully visible, and if the sum of light is less then 1 (down to 0) then the screen becomes darker (down to black).

 

You try to do this in 2 passes with the main frame buffer as storage for the intermediate screen color, like so:

    screen_color := scene_color * ambient_light

    screen_color := blend(screen_color, spot_light)

 

I assume this because you do not sample a "screen" texture in the light pass shader. So, how have you configured the blending? It may be configured so that it simply overwrites the result from the first pass. It need to be configured so that the formula from the top of this post is implemented.

 

BTW: How is your fragmentColor computed?

 

However, I suggest you to unify both passes into one. That allows you to do the blending within the shader.

Share this post


Link to post
Share on other sites

hy :)

Thanks haegarr...

For your question -

In the scene vertex Shader I have 

in vec2 vertexColor;
out vec2 fragmentColor;

void main(){
    .... gl_Position stuff

    fragmentColor = vertexColor;
}

I think vertexColor gets to the shader from the vbo (right? I'm not keen enough to be sure)...

 

Now, Ive tried to unify both fragment shaders into one (the light shader and the scene).. doing the light calculations in the scene shader, and I got a really weired result:

I have use small .png picuters of bricks, for walls and floor, and, every brick texture was fully lit (i.e in its original color) at its top tight, and completely dark in bottom left.. and was mixed in between - well i hope you know what i mean ...

 

No matter how I twist it and play with the shaders - I end up with either the original thing, or this, or a single light point on a black screen, or nothing at all.. wacko.png

I'm sure its not as complicated, Its just that something is wrong uh ?

Which got me thinking, maybe its not a problem with the shaders, but with code I use in the game ?

In my draw function I do ClearColor, Clear depth and color bits, get projection matrix from the camera, and then:

shaderProgram.use();

get uniforms
glActiveTexture()
set uniforms

spriteBatch.begin()
draw map and people
spriteBatch.end()
spriteBatch.renderBatch()

shaderProgram.unuse();

I have the same for the light (but now its commented out because I unified both shaders)  only difference is that for the light i use a different instance of shaderProgram, and ActiveTexture() is set to GL_TEXTURE1 ...

 

maybe thats wrong ?? like.. Im not sure what to ask wacko.png

Share this post


Link to post
Share on other sites

hy smile.png

in vec2 vertexColor;
out vec2 fragmentColor;

void main(){
    .... gl_Position stuff

    fragmentColor = vertexColor;
}


Did you copy this directly from your shader or is the use "vec2" a typo?

Share this post


Link to post
Share on other sites

The code snippets you provided so far are not sufficient for an analysis. So I'll describe what to do, now with more details (the following is the most basic way; it can be fleshed out, of course):

 

1. You have a mesh, obviously shaped as a quad. Each vertex has the mandatory position and a texture co-ordinate.

 

2. You have a texture that stores the color as it looks like when being fully lit. This is because you can darken a color easily, but brighten it would introduce inaccuracies and is not possible at all if being black. Set this texture for sampling in the fragment shader.

 

3. You have a scene constant ambient light intensity given as RGB value. Set this value as uniform to the fragment shader.

 

4. You have a spot light with an intensity given as RGB, a position given in screen co-ordinates, and an radial extent given in screen co-ordinates. Set these values as uniforms to the fragment shader.

 

5. In the fragment shader, use the UV co-ordinates to sample the color texture.

 

6. Calculate the distance from the current fragment to the spot light position.

 

7. Attenuate the intensity triple of the spot light accordingly to the distance calculate in 6.

 

8. Add the ambient intensity triple to the result of 7.

 

9. Clamp the result of 8. to (1,1,1).

 

10. Multiply the result of 9. by the sampled texture color.

 

11. Write the result of 10., extended by the homogeneous 1, as fragment color. Do not use the build-in blending engine here.

Edited by haegarr

Share this post


Link to post
Share on other sites

thank you very much  haegarr smile.png

Well, I have revised my shaders and followed your instructions.. and actually, I think I'm now closer to something cool smile.png

 

11ca4g8.png

 

As you can see I have a light point that follows my mouse, and it lights up a circular area, in a color that I pass as a uniform, however, now I've got another problem tongue.png

Obviously, the entire scene is completely dark, and I don't know why... (my ambient color is like a dark blue, and I've checked, it is applied only where there is light from the light point...).. What's wrong ?

 

Here is my fragment shader as of now :

#version 130

in vec2 fragmentPosition;
in vec4 fragmentColor;
in vec2 fragmentUV; 

uniform sampler2D texture; 

uniform vec4 ambientColor;
uniform vec2 lightPos;
uniform vec3 lightIntensity;

void main() {
    vec4 temp = texture2D(texture, fragmentUV);
	
    float distance = length(lightPos - fragmentPosition);
    vec3 lightColor = vec3(lightIntensity.rgb - distance);
    vec3 ambient = ambientColor.rgb * ambientColor.a;

    vec3 final = lightColor * ambient;
    //final = clamp(final, 0, 1);
    
    gl_FragColor = vec4(final * temp.rgb, 1);
}

The clamping is commented out.. however, when I clamp between e.g 0.1 and 1, some light does shine through in the scene and it is not completely dark..

what do you mean by saying I should clamp to 1, 1, 1 ?

 

 

Share this post


Link to post
Share on other sites
What's wrong ?

Ambient light and spot light are to be added instead of multiplied!

 

The clamping is commented out.. however, when I clamp between e.g 0.1 and 1, some light does shine through in the scene and it is not completely dark..
what do you mean by saying I should clamp to 1, 1, 1 ?

Clamp each channel to [0.0, 1.0]. The reason is because the light addition may yield in values above 1. That is a typical problem in LDR lighting.

final = clamp( final, 0.0, 1.0 );

If you clamp to [0.1, 1.0] you'll have a minimum lighting value of 0.1, and hence, of course, the scene can never get totally dark. But it is the role of the ambient light to provide the base brightness of the scene.

Edited by haegarr

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement