Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: [Re-Solved] Layer lighting help  (Read 212 times)

0 Members and 1 Guest are viewing this topic.

Recoil

  • Jr. Member
  • **
  • Posts: 62
    • View Profile
[Re-Solved] Layer lighting help
« on: June 13, 2019, 10:09:47 pm »
I'm revisiting my lighting code for my engine so it has a much better working effect.  All of the examples I have come across say to use a lightmap over the screen and set the blend mode to multiply.  I have tried using different "lightmaps" to see if mixing with the blending options helps but so far none of them seem to work correctly.  To save time I will omit the testing results that I have got using each one.

I had some initial success drawing a black png image over the whole screen and setting the blend mode to alpha, then for each light instance drawing a smaller blurred light image with transparent background, and the blend mode set to add on top of the black layer.  However, that isn't really providing the type of lighting effect I see done with other engines, so it's back to the drawing board and here to see if someone can help me with the logic behind my code.

This is the order I am drawing my layers to the render window:
Lower tiles
Player
NPC's
Upper tiles
Night layer (alpha blend)
Light layer (add blend)
UI

I am attaching the current light image I am using as well as the result using approx. 86% opacity.  When I set the opacity to 100% the black is fully black, and the lights are blurred fully white and I am unable to see underneath.  My goal is to be able to increase the black to 100% to hide objects outside of the light sources, while being able to see the characters and map under the lights.

If it will help I can add the list of results I have gotten using different lighting images and blending modes.
« Last Edit: June 17, 2019, 10:32:36 pm by Recoil »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32080
    • View Profile
    • SFML's website
    • Email
Re: Layer lighting help
« Reply #1 on: June 14, 2019, 11:11:32 am »
The usual approach is to draw lights to a render-texture (initially filled with black background), then draw this RT with Multiply blend mode so that black areas remain black, and white becomes transparent.
Laurent Gomila - SFML developer

Recoil

  • Jr. Member
  • **
  • Posts: 62
    • View Profile
Re: Layer lighting help
« Reply #2 on: June 14, 2019, 04:03:38 pm »
Thanks for your help Laurent.  No joke, when I initially tried messing with the lighting I attempted to do just that: clear a Render Texture with black -> draw light spots to the Render Texture -> draw the Render Texture to the game screen with multiply blend.  Previously I had issues with the whole screen just being black, so I settled on drawing the way I was with Alpha/Add.

But I tried it again, and it worked!  Well, to an extent.  Drawing the previous way the lights show where they are supposed to, and stay where they are supposed to.  Drawing the new way achieves the visual results I was wanting (thanks) but now the lights are off for some reason, and when I move the player down the lights move down, but not going left to right.

It's been a minute since I have worked on the engine, so it gives me something to tinker with for now.  I really appreciate the help though!

FRex

  • Hero Member
  • *****
  • Posts: 1831
    • View Profile
    • My GitHub page
    • Email
Re: Layer lighting help
« Reply #3 on: June 14, 2019, 07:01:17 pm »
Lights (of whatever colors) should be drawn with additive blending to the black texture (the order doesn't matter either), than that texture should be multiplied with the world (that is "100% lit" if drawing the lighting texture is off).

Here's an example: https://en.sfml-dev.org/forums/index.php?topic=22180.msg156718#msg156718
ZipSavings, script to count rar/7z/zip savings: https://goo.gl/vvBj5M
LuaConsole: https://goo.gl/X4kRUk
FoxRaycaster: https://goo.gl/27nVS8
Small Games - Heart, Routing and Snek: https://goo.gl/15ZGWE https://goo.gl/k5gwWD https://goo.gl/4nKPnT
Botes - a notes app in Pascal: https://goo.gl/bzTqsi

Recoil

  • Jr. Member
  • **
  • Posts: 62
    • View Profile
Re: Layer lighting help
« Reply #4 on: June 14, 2019, 10:51:29 pm »
So I have some success fixing this.  I am having to call RenderTexture.Display(), which fixed the inversion issue (for some reason).  However, I could not draw the Render Texture directly to the Render Window, so I had to create a new Sprite and draw the RenderTexture.Texture to that, then draw the Sprite to the Render Window.

I know, complicated, but halfway working...

That is until I started noticing my FPS dropped from ~120 to ~16.  Then things became very sluggish after a few minutes, and I noticed my game was increasing 1mb of memory every few seconds.

So, here is my current process on the light code (pseudo code):

Draw a new RenderTexture.
Clear the RenderTexture.
Loop through each tile for a light source.
When it finds one it creates a new Sprite of the light image.
Draws the RenderTexture.Draw(Sprite, New RenderStates(BlendMode.Add))
Disposes of that Sprite before continuing on to the next light source.

RenderTexture.Display()
Create new Sprite of Overlay.Texture
Sprite.Draw(RenderWindow, New RenderStates(BlendMode.Multiply))
RenderTexture.Dispose
Sprite.Dispose
 

Even removing the lights altogether and just drawing the render texture over the screen drops the FPS and causes the memory leaks.  Bypassing the light code jumps my FPS back up to 120 and there is no leak in memory.  This is the first time I have run into memory leak issues so I am lost on how to track them down since I am disposing of everything after it is used.

Recoil

  • Jr. Member
  • **
  • Posts: 62
    • View Profile
Re: Layer lighting help
« Reply #5 on: June 15, 2019, 04:37:37 am »
Just in case anyone else finds this in the searches...

Solution here

So I was making a new Render Texture every draw frame just in case the window was resized.  I moved my new call when I initialize everything at program startup.  I set a boolean (RedrawNightTexture) to get checked in my drawing loop each iteration.  I set the boolean to true if the form was Maximized/Minimized/Resized/SizeChanged events...not sure if I need all those.

When I set the boolean to True on RedrawNightTexture, I dispose of the old RenderTexture before calling a new one.  No clue if this is even needed, but why not.  My memory leak stopped, and my FPS gets up to ~160 at normal size, and ~110 when it is maximized.  So I believe my problem, and the problems of fixing those problems, have all been resolved.

A side note - I had to change the size of the RenderTexture  tor the main forms GameScreen picturebox that my game is being drawn to, instead of the RenderWindow.  For some reason without that I was only able to get the texture drawn to the proper size when I would drag-resize the form down from a larger size.  Not sure if that info is even needed, but it may help someone else  ;)
« Last Edit: June 15, 2019, 04:45:41 am by Recoil »

Recoil

  • Jr. Member
  • **
  • Posts: 62
    • View Profile
Re: [Solved] Layer lighting help
« Reply #6 on: June 16, 2019, 03:32:16 pm »
Can someone  help me understand what may be going wrong with this?

The first image attached (Test4) is using a Gaussian blurred white circle created in Photoshop.  This is a really nice lighting effect.

The second image (Test5) is drawing a radial gradient with a 45 point triangle fan in code for the lights.  My issue with this one is the veining effect when the edges of lights intersect - the edge should not be darker than the area it is going into.

I'm hoping to add more dynamic lighting for my engine without using images.  To be able to set size, intensity, color, etc for each light source independently from the rest.  I'm not entirely sure what would cause the effect I am getting in the second method to display the way it does.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32080
    • View Profile
    • SFML's website
    • Email
Re: [Solved-ish] Layer lighting help
« Reply #7 on: June 17, 2019, 07:48:35 am »
How do you render your triangle fan (blending mode, fragment shader, ...)?
Laurent Gomila - SFML developer

Recoil

  • Jr. Member
  • **
  • Posts: 62
    • View Profile
Re: [Solved-ish] Layer lighting help
« Reply #8 on: June 17, 2019, 02:11:24 pm »
On both of the previous examples I am drawing both the .png and triangle fan onto the black overlay with BlendMode.Add, and then displaying the black overlay with BlendMode.Multiply.

The .png image is just a Gaussian blurred white circle made in Photoshop with transparent background, but it also works if the background is black with the same effect

The center point of the triangle fan is white, and the outer points of the 360 degree fan are black.  I have yet to even try to get shaders working on this thing, I am completely lost in that regard.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32080
    • View Profile
    • SFML's website
    • Email
Re: [Solved-ish] Layer lighting help
« Reply #9 on: June 17, 2019, 03:17:17 pm »
Quote
The center point of the triangle fan is white, and the outer points of the 360 degree fan are black.
And they all have alpha == 255, right?
Laurent Gomila - SFML developer

Recoil

  • Jr. Member
  • **
  • Posts: 62
    • View Profile
Re: [Solved-ish] Layer lighting help
« Reply #10 on: June 17, 2019, 07:02:12 pm »
And they all have alpha == 255, right?

Yes and no.  In those images the alpha value is turned all the way up to 255 for the black and white areas of the RenderTexture overlay and triangle fan light source.  I have a day/night system that changes the lighting value, so the alpha value on the RenderTexture, and .png or triangle fan increases as the level changes.

I am probably doing this all backwards though now that I think about it.  I'll have to come back after I try a few things.

Edit:

Okay, so I had to go back and pretty much change all my lighting levels, and which way they increased/decreased.  Before when I increased the alpha value (0->255) I was setting how dark the level was.  It was because how I was +/- the level in the engine timer.

Even though using the .png light was working, it threw me off on how I was calculating the alpha values for the circle fan shape gradient.  Now I get the same effect if I am using the .png or the circle fan, with no Venn diagram effect  :-[
« Last Edit: June 17, 2019, 08:24:14 pm by Recoil »