Java-Gaming.org Hi !
Featured games (91)
games approved by the League of Dukes
Games in Showcase (798)
Games in Android Showcase (234)
games submitted by our members
Games in WIP (865)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1] 2
  ignore  |  Print  
  Tile by tile lighting how would i do this  (Read 18081 times)
0 Members and 1 Guest are viewing this topic.
Offline tommohawkaction
« Posted 2015-06-20 16:38:04 »

Here is my code
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
private Color getLightBrightness(List<MasterTile> lights,Color current, MasterTile tile){
      Color brightNess = current;
      int n = 1 - 0 + 1;
     
      Vector2 tileCoords = new Vector2(tile.getX()/MasterTile.TILE_WIDTH,tile.getY()/MasterTile.TILE_HEIGHT);
      for(int i = 0;i < lights.size();i++){
         MasterTile t = lights.get(i);
         float distance =  tileCoords.dst(t.getX()/MasterTile.TILE_WIDTH, t.getY()/MasterTile.TILE_HEIGHT);
         distance %= n;
         System.out.println(distance);
         //Utils.mixColours(current, LIGHT, distance);
      }
     
     
      return brightNess;
   }



Here is what i am trying to do
Offline tommohawkaction
« Reply #1 - Posted 2015-06-20 17:13:29 »

How would i do this with a shader? examples?
Offline tommohawkaction
« Reply #2 - Posted 2015-06-20 17:22:16 »

I am going for this effect
[youtube]https://www.youtube.com/watch?v=PVmAP7LdR_gMmB9b5njVbA[/youtube]
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline MrPizzaCake

Senior Devvie


Medals: 8
Exp: 3 years


Hello, another wonderful human being :)


« Reply #3 - Posted 2015-06-20 17:53:51 »

I'd make light brightness (1f to 0f) be the value (in the HSV color model) of the tile's texture (if you want to have brighter lights than 1f, I'd use Math.max(light.brightness, 1f)). Normal light source with brightness 1f would have a reach of, for example, 5 tiles. You'd then divide the brightness of the light by the distance from the light source.

PS: I'm too lazy to write it in a shader or a program, but if you wish, I can write it in pseudo-code.
PPS: Please, only one post. If you want to expand your post, edit the original one, don't reply to it. Thank you.

How am I? Tough question, since emotions are confusing as heck Tongue
Offline tommohawkaction
« Reply #4 - Posted 2015-06-20 18:39:56 »

I am not completely sure what you mean?
:/
Offline chrislo27
« Reply #5 - Posted 2015-06-20 18:55:36 »

MrPizzaCake means use the light brightness as the brightness value in the HSB (not HSV!) colour model. HSB stands for hue, saturation, and brightness. Then in order to get the brightness of a tile, you would take its position from a light source (perhaps the nearest source since it'll have the most effect) and take the light source's brightness and divide it by the distance away and that's the tile's brightness.

Personally how I do it is by overlaying a shadow on top of the tile which is the "darkness" of each block. I have to use a shader to mask the lightmap onto the terrain so it doesn't cover the background.

You can see how I do it more in depth here. Note that it seems a bit more complex but can make really good looking effects.
Offline MrPizzaCake

Senior Devvie


Medals: 8
Exp: 3 years


Hello, another wonderful human being :)


« Reply #6 - Posted 2015-06-20 19:21:08 »

...HSB (not HSV!)...

Sorry, I often get 'em confused Tongue

How am I? Tough question, since emotions are confusing as heck Tongue
Offline TritonDreyja
« Reply #7 - Posted 2015-06-20 21:55:55 »

As i can see, it's my lighting effect youre looking for Cheesy

well its pretty simple, albeit limited. no shaders or raycasting involved, it is just a floodfill algorithm tweaked to fit my tile system.

http://www.java-gaming.org/index.php?topic=26363.0 is the article (last post) that got me somewhere after months of headaches, though you will have to find a way to make it work with your system. I used to algorithm from before he rounded off so it keeps the retro look.

My code looks something like this just so you can see what an example of a system implemented version would be(more complex things since i also have color lighting and a separate array for light tiles)

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  
public void applyLightRec(int x, int y, int lastLight, int xt, int yt, int r, int g, int b, int alph) {
         int x1 = (int) (xt + ( TritonForge.pixel.width / TileArt.tileSize) + 2);
         int y1 = (int) (yt + ( TritonForge.pixel.height / TileArt.tileSize) + 2);
         if (x < xt-10 || x > x1+10)return;
         if (y < yt-10 || y > y1+10)return;
         int newLight = lastLight+getLightBlockingAmmountAt(x, y);
         if (newLight >= getLight(x, y)) return;
         
         Light u = light[x][y-1];
         Light d = light[x][y+1];
         Light ri = light[x+1][y];
         Light l = light[x-1][y];
         
         light[x][y].r = r;
         light[x][y].gr = g;
         light[x][y].b = b;
         light[x][y].alph = alph;
         light[x][y].lighting = newLight;
         Color col = new Color(r,g,b,alph);
         Color col1 = new Color(u.r,u.gr,u.b,u.alph);
         Color col2 = new Color(ri.r,ri.gr,ri.b,ri.alph);
         Color col3 = new Color(d.r,d.gr,d.b,d.alph);
         Color col4 = new Color(l.r,l.gr,l.b,l.alph);
         Color new1 = blend(col,col1);
         Color new2 = blend(col,col2);
         Color new3 = blend(col,col3);
         Color new4 = blend(col,col4);
         applyLightRec(x+1, y, newLight, xt, yt,new1.getRed(),new1.getGreen(),new1.getBlue(), new1.getAlpha());
         applyLightRec(x, y+1, newLight, xt, yt,new3.getRed(),new3.getGreen(),new3.getBlue(), new3.getAlpha());
         applyLightRec(x-1, y, newLight, xt, yt,new4.getRed(),new4.getGreen(),new4.getBlue(), new4.getAlpha());
         applyLightRec(x, y-1, newLight, xt, yt,new2.getRed(),new2.getGreen(),new2.getBlue(), new2.getAlpha());
      }


Best of luck
Offline chrislo27
« Reply #8 - Posted 2015-06-20 22:35:59 »

As i can see, it's my lighting effect youre looking for Cheesy
-snip-

Actually, that's pretty much identical to mine. It's recursive and has a diamond shape. The shape OP is looking for is rounded.

Yours does look a lot simpler than mine programmatically Tongue
Offline TritonDreyja
« Reply #9 - Posted 2015-06-21 03:02:05 »

As i can see, it's my lighting effect youre looking for Cheesy
-snip-

Actually, that's pretty much identical to mine. It's recursive and has a diamond shape. The shape OP is looking for is rounded.

Yours does look a lot simpler than mine programmatically Tongue

Well there is a rounded version in the thread i linked him to
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline chrislo27
« Reply #10 - Posted 2015-06-21 04:02:33 »


Well there is a rounded version in the thread i linked him to
Ah, I overlooked that as I skimmed the post. Sorry!

Also this is more related to your code TritonDreyja, but I don't really think you should be creating a new Color object for every recursion of the lighting update. Maybe store a bunch of shared Color objects that you can re-use over and over (I had to use around 7 of them Pointing).
Offline tommohawkaction
« Reply #11 - Posted 2015-06-21 14:03:09 »

I have been trying for hours now and I don't seem to be getting anywhere
I would like to mention I am using Libgdx


Vertex Shader
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  
#version 100
attribute vec4 a_position;
attribute vec4 a_color;

uniform mat4 u_projModelView;


uniform vec3 lightPos;
uniform vec4 lightColour;
uniform vec4 lightSunColour;



varying vec4 v_col;
void main()
{
   v_col = lightSunColour;

   float distance = length(lightPos.xy - a_position.xy);
   
   float a = distance;
   vec4 light = vec4(a,a,a,1.0) * lightColour;
   v_col += light;




    v_col = a_color;
   gl_Position =  u_projModelView * a_position;
}


I am getting no results from this
and I am sending the base colour as transparent so i can see all of the other tiles under it and the sun colour as white and the light colour as yellow


.. Sorry
Offline tommohawkaction
« Reply #12 - Posted 2015-06-21 14:49:52 »

Well first problem i am having is that libgdx is not accepting my uniforms.... WTF

1  
2  
3  
4  
5  
6  
      UNIFORM_LIGHT_POS = shader.getUniformLocation("lightPos");
      System.out.println(UNIFORM_LIGHT_POS);
      UNIFORM_LIGHT_COLOUR = shader.getUniformLocation("lightColour");
      System.out.println(UNIFORM_LIGHT_COLOUR);
      UNIFORM_SUNLIGHT_COLOUR = shader.getUniformLocation("lightSunColour");
      System.out.println(UNIFORM_SUNLIGHT_COLOUR);


result
1  
2  
3  
-1
0
-1


vertex
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
#version 100
attribute vec4 a_position;
attribute vec4 a_color;

uniform mat4 u_projModelView;

uniform vec3 lightPos;
uniform vec4 lightColour;
uniform vec4 lightSunColour;


varying vec4 v_col;
void main()
{

    v_col = lightColour;
   gl_Position =  u_projModelView * a_position;
}


fragment
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
#version 100
#ifdef GL_ES
precision mediump float;
#endif

varying vec4 v_col;

void main()
{
gl_FragColor = v_col;
}



I think my problem is something to do with the ShapeRenderer
Offline KaiHH

JGO Kernel


Medals: 732



« Reply #13 - Posted 2015-06-21 15:22:17 »

Well first problem i am having is that libgdx is not accepting my uniforms.... WTF
This is correct behaviour of OpenGL, since these uniforms are not active (i.e. used in a way that influences any output).
In the documentation of mentioned glGetUniformLocation it says:
Quote
This function returns -1 if name does not correspond to an active uniform variable in program [...]
Offline tommohawkaction
« Reply #14 - Posted 2015-06-21 15:26:48 »

but my output was never yellow which what "lightColour" equals to

How would i do this?? been at this for over 2 days now... kinda getting annoyed as i am not getting anywhere

Okay here is what i have so far, the ShapeRenderer cannot do lighting with shaders unless the lights are static throughout the whole game(which they aren't)
the SpriteBatch is possible but I cannot draw a shadow mask like ShapeRenderer so I would need to create a image to get that working (Which I don't want to) and then when trying to change the SpriteBatch shader I realized that I had to have a texture and there was no way getting round this.... I HAVE NO IDEA WHAT TO DO

This is how my tiles are working

I have one layer which is the ground then i have the top layer and then i will render players and creatures etc (weather) and then i have another layer which is the light layer and all of the things i have tried are not getting me anywhere :?
Offline tommohawkaction
« Reply #15 - Posted 2015-06-21 16:46:08 »

Managed to get something working using the ShapeRenderer but the FPS has gone down to 12 instead of 120



Can somebody help me via skype
Skype: tommohawkaction
Offline chrislo27
« Reply #16 - Posted 2015-06-21 18:15:02 »

Are you batching all the shadows or starting/ending the shape renderer batch for each tile? If so stop doing that. Also make sure you're culling off the tiles that aren't visible and not rendering them.
Offline tommohawkaction
« Reply #17 - Posted 2015-06-21 18:45:25 »

Here is my renderer

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  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
shapeRenderer.setProjectionMatrix(camera.combined);

      int camX = (int) (camera.position.x + (MasterTile.TILE_WIDTH / 2) - camera.viewportWidth / 2) / MasterTile.TILE_WIDTH;
      int camY = (int) (camera.position.y + (MasterTile.TILE_HEIGHT / 2) - camera.viewportHeight / 2) / MasterTile.TILE_HEIGHT;
      int camZoomFixX = (int) (((camera.zoom - 1) * 100) / (MasterTile.TILE_WIDTH / 10));
      int camZoomFixY = (int) (((camera.zoom - 1) * 100) / (MasterTile.TILE_WIDTH / 10));
      int offset = 1;

      if (camZoomFixX < 0)
         camZoomFixX = 0;
      if (camZoomFixY < 0)
         camZoomFixY = 0;

      int startX = camX - (camZoomFixX + offset);
      int toX = (camX + TileRenderer.AMOUNT_WIDTH) + (camZoomFixX + offset);
      int startY = camY - (camZoomFixY + offset);
      int toY = (camY + TileRenderer.AMOUNT_HEIGHT) + (camZoomFixY + offset);

      Gdx.gl.glEnable(GL20.GL_BLEND);
      Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);

      // Lights
      shapeRenderer.begin(ShapeType.Filled);
      {

         for (int x = startX; x < toX; x++) {
            for (int y = startY; y < toY; y++) {
               if (x < 0 || x > TileRenderer.map.getWidth() - 1 || y < 0 || y > TileRenderer.map.getHeight() - 1)
                  continue;
               Color tileColor = sunlight;

               for (int x1 = startX; x1 < toX; x1++) {
                  for (int y1 = startY; y1 < toY; y1++) {
                     if (x1 < 0 || x1 > TileRenderer.map.getWidth() - 1 || y1 < 0 || y1 > TileRenderer.map.getHeight() - 1)
                        continue;

                     LightTile lightTile = lights[x1][y1];
                     if (lightTile == null)
                        continue;


                     float distance = Vector2.dst(x1,y1, x, y);
                     distance = (float) (Math.floor(distance));
                     if (distance > 3) {
                        distance -= 3.1f;

                     }else if (distance > 2) {
                        distance -= 2.3f;

                     }else if (distance > 1) {
                        distance -= 1.5f;

                     } else {
                        distance -= 0.8f;
                     }
                     
                     if(distance < 0){
                        distance = 0;
                     }

                     tileColor = Utils.mixColours(tileColor, Color.WHITE, distance);

                     System.out.println(distance);

                  }
               }

               shapeRenderer.setColor(tileColor);
               shapeRenderer.rect(x * MasterTile.TILE_WIDTH, y * MasterTile.TILE_HEIGHT, MasterTile.TILE_WIDTH, MasterTile.TILE_HEIGHT);

            }
         }
      }

      shapeRenderer.end();

      Gdx.gl.glDisable(GL20.GL_BLEND);
Offline Opiop
« Reply #18 - Posted 2015-06-21 18:49:35 »

Print statements are expensive, remove that and you might see a boost in FPS. Also, I'm pretty sure the ShapeRenderer class is slow, but I don't know why. I would just use textures,
Offline tommohawkaction
« Reply #19 - Posted 2015-06-21 18:50:30 »

So how would i do this using a texture?? a transparent texture?
Offline MrPizzaCake

Senior Devvie


Medals: 8
Exp: 3 years


Hello, another wonderful human being :)


« Reply #20 - Posted 2015-06-21 18:50:45 »

What opiop65 said. And please, use that wonderful thing called Pastebin Pointing

How am I? Tough question, since emotions are confusing as heck Tongue
Offline Opiop
« Reply #21 - Posted 2015-06-21 18:53:53 »

You can change the color of the spritebatch before rendering a texture, it will "tint" it. Are you rendering a transparent texture over your tiles right now? That's a waste of resources, just use the tinting functions of the spritebatch.
Offline BurntPizza

« JGO Bitwise Duke »


Medals: 486
Exp: 7 years



« Reply #22 - Posted 2015-06-21 18:55:38 »

Ninja'd by opiop, but yeah just use a plain white pixel as a texture, tint and set size + transparency at each call to spritebatch.

And please, use that wonderful thing called Pastebin Pointing

If it's his own thread specifically for this issue, I think longer code snippets are fine. Besides, none of these are even over 100 lines.
Offline MrPizzaCake

Senior Devvie


Medals: 8
Exp: 3 years


Hello, another wonderful human being :)


« Reply #23 - Posted 2015-06-21 18:59:36 »

If it's his own thread specifically for this issue, I think longer code snippets are fine. Besides, none of these are even over 100 lines.

Well, it's kinda annoying having to continuously scroll up-and-down between writing a reply and trying to orient in the code, but that's just my opinion >.>

How am I? Tough question, since emotions are confusing as heck Tongue
Offline chrislo27
« Reply #24 - Posted 2015-06-21 19:29:11 »

As the others have said, use a 1x1 white texture. You can create it at the beginning using Pixmap or load it from a file. I highly prefer using the white texture rather than ShapeRenderer because I can draw it in between batches rather than stopping the SpriteBatch and starting the ShapeRenderer batch.

Also, if you like to peek in my source code for my lighting engine, you can do so here.

However I use recursion to create a diamond shape rather than a circular shape.
Offline TritonDreyja
« Reply #25 - Posted 2015-06-22 05:11:50 »


Well there is a rounded version in the thread i linked him to
Ah, I overlooked that as I skimmed the post. Sorry!

Also this is more related to your code TritonDreyja, but I don't really think you should be creating a new Color object for every recursion of the lighting update. Maybe store a bunch of shared Color objects that you can re-use over and over (I had to use around 7 of them Pointing).

I don't know if i should start replying on this thread based on my own needs, but i am curious as to how you would use predefined colors. I need to blend with a full RGB range so that the transitions are smooth, but what you mentioned seems to use less resources. maybe message me, or say a bit more on this thread if you feel it could benefit everyone.
Offline BurntPizza

« JGO Bitwise Duke »


Medals: 486
Exp: 7 years



« Reply #26 - Posted 2015-06-22 05:17:00 »

If you haven't profiled and seen that these color objects are causing a performance problem, then trying to avoid creating them would be a waste of time.
Besides, holding a cache of potentially thousands/millions of color objects (if you really need full RGB range) would most likely be a much larger strain on 'resources' then just creating them on the fly.
Offline tommohawkaction
« Reply #27 - Posted 2015-06-22 17:34:43 »

Thank you for everyone's help
I am trying to figure out what is the best way of doing this as mine isn't as perfect as I like it



CODE

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  
         for (int x = startX; x < toX; x++) {
            for (int y = startY; y < toY; y++) {
               if (x < 0 || x > TileRenderer.map.getWidth() - 1 || y < 0 || y > TileRenderer.map.getHeight() - 1)
                  continue;
               Color tileColor = sunlight;
               
               float min = Float.MAX_VALUE;

               for(int i = 0;i < lights.size;i++){

                     MasterTile tile = lights.get(i);
                     if (tile == null)
                        continue;


                     float distance = Vector2.dst(tile.getX()/MasterTile.TILE_WIDTH,tile.getY()/MasterTile.TILE_HEIGHT, x, y);
                     distance = (float) (Math.floor(distance));
                     if(distance < min){
                     min = distance;
                     }else{
                        continue;
                     }
                     if (distance > 3) {
                        distance -= 3.1f;

                     }else if (distance > 2) {
                        distance -= 2.3f;

                     }else if (distance > 1) {
                        distance -= 1.5f;

                     } else {
                        distance -= 0.8f;
                     }
                     
                     if(distance < 0){
                        distance = 0;
                     }

                     tileColor = Utils.mixColours(tileColor, Color.WHITE, distance);
                     tileColor = Utils.mixColours(tileColor, sunlight, sunlight.a);


                  }
           
Offline KaiHH

JGO Kernel


Medals: 732



« Reply #28 - Posted 2015-06-22 18:12:00 »

Your lighting code is weird, if I may say, with some number of strange constants. Usually, whenever I see lighting code that has more than two constants in it, or those two constants are not 0.0f and 1.0f, I suspect a mistake in the code/design.
For a given point/tile you compute the shortest distance to any of the existing light sources and that will currently determine the tile's irradiance.
This is wrong for the reason that in real life each light source "adds"/contributes light to a given area/tile.
With your current code, even if you had five lights and a tile directly adjacent to all of the five lights, that tile would only receive one light source's worth of light, so to say.
In other words: With your current code, more light sources would not make a tile brighter. This is physically illogical.
Usually, you would need to compute each light's contribution to a given tile/point separately (and not just the minimum of the distances over all lights), and then sum those contributions together.
This will then result in that marked spot being brighter.
Offline tommohawkaction
« Reply #29 - Posted 2015-06-22 19:39:05 »

The distance is the distance from the light to the current tile
How would I fix my problem then? not completely sure.... Roll Eyes
the reason why i am doing this

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
                     if (distance > 4)
                        continue;
                     if (distance > 3) {
                        distance -= 3.1f;

                     } else if (distance > 2) {
                        distance -= 2.3f;

                     } else if (distance > 1) {
                        distance -= 1.5f;

                     } else {
                        distance -= 0.8f;
                     }


is because the alpha for the light is between 1 and 0
Pages: [1] 2
  ignore  |  Print  
 
 

 
Riven (81 views)
2019-09-04 15:33:17

hadezbladez (4336 views)
2018-11-16 13:46:03

hadezbladez (1547 views)
2018-11-16 13:41:33

hadezbladez (4462 views)
2018-11-16 13:35:35

hadezbladez (871 views)
2018-11-16 13:32:03

EgonOlsen (4152 views)
2018-06-10 19:43:48

EgonOlsen (4855 views)
2018-06-10 19:43:44

EgonOlsen (2803 views)
2018-06-10 19:43:20

DesertCoockie (3707 views)
2018-05-13 18:23:11

nelsongames (3998 views)
2018-04-24 18:15:36
Java Gaming Resources
by philfrei
2019-05-14 16:15:13

Deployment and Packaging
by philfrei
2019-05-08 15:15:36

Deployment and Packaging
by philfrei
2019-05-08 15:13:34

Deployment and Packaging
by philfrei
2019-02-17 20:25:53

Deployment and Packaging
by mudlee
2018-08-22 18:09:50

Java Gaming Resources
by gouessej
2018-08-22 08:19:41

Deployment and Packaging
by gouessej
2018-08-22 08:04:08

Deployment and Packaging
by gouessej
2018-08-22 08:03:45
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!