Language: 
To browser these website, it's necessary to store cookies on your computer.
The cookies contain no personal information, they are required for program control.
  the storage of cookies while browsing this website, on Login and Register.

Author Topic:  Dynamic lighting  (Read 5578 times)

0 Members and 0 Guests are viewing this topic.

smacky

« on: 05, July 2009, 18:46:38 »
This is quite interesting.

Currently light is just a circular (well, square) mask concentrated on the light source.

This means light permeates opaque objects like walls. So if you have a light source completely walled in in all directions -- like this:
Code: [Select]
/-\
|*|
\-/

the light mask will still radiate outside the walls.

If light did not permeate opaque objects, it would offer a number of advantages, including:
  • more 'realistic'/atmospheric maps.
  • greater opportunity for special light effects which look cool.
  • light-sensitive spawns based on the actual brightness of the square rather than the map ambient light level.
  • greater scope for light-based puzzles.


It's quite tricky to code though! Here's a screenshot of progress so far (top=before, bottom=after):


There are some obvious problems:
  • Walls still glow on the outside when lit from the inside -- this can't be fixed until smooth movement I think.
  • There is a hard straight edge betwen quite brightly lit areas and areas blocked from the light source by a wall -- I think this can be solved with a bunch of sexy tables.


But it's a start! :happy:

EDIT: Forgot to mention (it's a big part of the point!) the light flows through open doors and is blocked by closed doors, etc. TBH so far it comes through a door you've just opened but I'm having difficulty then adjusting the mask again when you shut the door. I think this is just a simple matter though. Also, when walls, etc (anything blocksview 1) appear/disappear (as the result of a script for example), this will also change the light pattern.
« Last Edit: 05, July 2009, 20:28:27 by smacky »

grommit

« Reply #1 on: 05, July 2009, 23:06:50 »
Good stuff so far! It's a shame that lighting in general is so blocky - a rounded effect would be so much better, though I expect that's what you mean by using a bunch of sexy tables. I expect Laplace transforms come in somewhere (they usually do :) )1

1No, I never got to learn about them either.

tehill

« Reply #2 on: 05, July 2009, 23:34:43 »
The server knows maps and tiles but does not know pixels. So getting circular lighting from the server is a problem.

If this were a client side effect you could use a circular gradient that could be added to lighten in a circular pattern, or darken if you wanted. It would just have to scale the rgb values of each pixel based on the gradient pattern.

Of course it would probably end up being a bit more complicated to implement.
« Last Edit: 05, July 2009, 23:39:10 by tehill »

smacky

« Reply #3 on: 06, July 2009, 00:15:54 »
Yeah exactly.

The lighting above is purely server-side (the numbers, not the visuals of course). It needs to be for light-sensitive spawns, etc. to work.

As Tehill suggests, to get it looking nice we need to translate the squares into a circular gradient client-side, although I'm not sure how hard that will be -- anything from quite to bloody I'd guess. Hopefully not impossible.

Before that, I want to get the server-side stuff sorted out, get doors working properly. I think I figured out what was tripping me up, but I'm still getting the crashes I posted about earlier. Not entirely sure what's going on there yet.

ThePlaneskeeper

« Reply #4 on: 06, July 2009, 02:34:05 »
what might make it easier is adding another "layer" client side.  This layer would be the "light" layer, and apply a "mask" based on the light value of the tile.  So instead of the client trying to generate on the fly values for each pixel based on rules for a tile, it does it just by applying another alpha-based tile.  These could then be determined (which type of tile/filter goes where) by the light values of adjacent tiles.  Very little math involved.  On another note, if you are going to work on this, perhaps you could also allow it so that

1. Different colored lights could be used (and thus multiple filters could be applied to a single tile)
2. There could be a greater range from light to dark (are there 7 current shades?  I'd like about 20...)

smacky

« Reply #5 on: 07, July 2009, 13:38:30 »
I need a formula to convert a 0-255 value to a 0-n range, so that if the the higher the in number, the lower the out number. Does that make sense? This sort of thing makes my head hurt. Stoopid maths.

Put in 255, get out 0. Put in 0, get out n.

grommit

« Reply #6 on: 07, July 2009, 14:27:11 »
How about (n / 255) * (255 - x) ?

Easier maths would be to use 256, then you could then just shift.

So y = (n * (256 - (x + 1))) >> 8;

Which simplifies to

y = (n * (255 - x)) >> 8;

Hmm. That works for x = 255, but not if x = 0. Need to think a bit more.

Best so far:

y = (x == 0) ? 255 : (n * (255 - x)) >> 8;
« Last Edit: 07, July 2009, 14:38:22 by grommit »

ThePlaneskeeper

« Reply #7 on: 07, July 2009, 14:36:28 »
what?

so you need to invert the number?

like (X-255)*-1

That would give you the inverted value on a 0-255 scale...

if you mean to cut 255 into chunks of 20 or so...

I don't know what your going for...

* grommit says see above edited post...

* TPK says yeah... got it now, wasn't getting what you were going at, but i understand now...  Still don't know what smacky is doing though...
« Last Edit: 07, July 2009, 16:49:15 by ThePlaneskeeper »

smacky

« Reply #8 on: 07, July 2009, 16:15:49 »
Well I have absolutely (idea = 0) why it does, but this seems to work... Thanks. BTW I think you meant:
Quote
y = (x == 0) ? 255n : (n * (255 - x)) >> 8;

grommit

« Reply #9 on: 07, July 2009, 17:39:28 »
Yes - that was just to keep you on your toes. You'd probably get away with just the right hand half of the ?: conditional - depends how big n is. Maybe it should be 256 - x. Error would be virtually zero for small n, since you're converting the 255 -> 0 number to n-scale by multiplying by n /256 which is what the shift right 8 does, instead of n/255.

And this has to be integers of course, not float.
« Last Edit: 07, July 2009, 17:42:13 by grommit »

smacky

« Reply #10 on: 07, July 2009, 17:55:37 »
Yup, int only. And I need the special case if x == 0, so :) :)

smacky

« Reply #11 on: 08, July 2009, 00:49:05 »
This is what I am doing:

2. There could be a greater range from light to dark (are there 7 current shades?  I'd like about 20...)

I'm not entirely sure what it's doing or why it's doing whatever it;s doing the way I think it's doing it. ;) One or two of the comments don't seem to match the actual code, so I suspect the code has been changed but the comments have not.

But it is hardwired (in theory it's flexible, but in practice it's not) to 7 light levels. I've changed this so its a client option how many you have.

In itself this works well. ATM it looks the same whether you have 7 or 21, I am not sure why. I know you only have 7 darkness settiings in the server, plus 0 for true dark but in fact the actual brightness per square is 0-1280 or 0-255. It's very strange. It seems the server uses a 0-1280 value, which is then reduced to 0-255 range by the time it gets to the client which then reduces it to 0-7 only to use this value to look up in a table a 0-255 value again!

Something funny's going. on I need to sleep on it, but in theory we should be able to have each client displaying n light levels according to the user's settings, where increasing n looks nicer/'smoother' but costs more memory.

smacky

« Reply #12 on: 08, July 2009, 17:20:48 »
@Grommit: If I want to now use the 0-1279 range rather than 0-255, can i just do: y = (n * (1279 - x)) >> 11? Or do I need to keep my upper value on the bit threshhold (I'm sure that makes no technical sense, but my meaning is 8 bits is 0-255, 11 bits is 0-2047)?

And if I do y = (n * (2047 - x)) >> 11, does it matter if x itself is a lower range (ie, 0-1280), but just not higher than 2047?

EDIT: Forget this -- visually it must be 0-255.
« Last Edit: 08, July 2009, 18:12:48 by smacky »

ThePlaneskeeper

« Reply #13 on: 08, July 2009, 18:16:45 »
well for one thing, you only want 0-255 light values, because that is the technical limitation of RGB.  any more than that would be pointless, unless you are going for specific color light values.

The other thing is it might be limited to 8 values for transfer because of bandwidth.  If this is the case, making it 16 would be acceptable (to me) from an artistic point of view (I would add about 6-7 of those extra shade from current 0-3 because of the disparity between the darkness values).  If that means two byes?  (so 64 options? 16/64=4 different colors of lights usable in the game)

255 shades of light might be overkill, and i can see why it would be limited from a bandwidth point of view.  Even increasing it from 8 to any value would be at least doubling the bandwidth per tile.  I'm fairly confident when i looked at the code a while ago, i thought the server actually reduces it to 8 values...  Maybe I'm wrong.

Edit: you edited your post!

grommit

« Reply #14 on: 08, July 2009, 18:19:18 »
He he. I think the best you can do now is convert everything to double, then apply the formula, then convert back to integer. If that's not too compute-intensive (I don't know how many times you have to do this).

Something like:
Code: [Select]
y = (int)floor((double)(1279 - x) * (double)n / 1279.0 + 0.5);

where x, y and n are all integers.

The (1279 - x) gives you an integer value going the other way.

This is then cast to double.

We then multiply by the ratio of n to 1279, which gives us a number between n and 0 instead of between 1279 and 0.

We then add 0.5 so that the number is rounded (so 6.1 becomes 6.6 and 6.7 becomes 7.2).

Function floor then gives the next lower integral value (so our original 6.1 ends up as 6.0 and our original 6.7 ends up as 7.0).

Finally, we cast the result back to int.

Does that help?

(TPK has posted in between - he probably has valid points that should be considered before doing this.)

Tags:
 

Related Topics

  Subject / Started by Replies Last post
3 Replies
1011 Views
Last post 29, August 2005, 01:38:09
by Carleto
25 Replies
7426 Views
Last post 16, April 2006, 23:20:41
by longir
10 Replies
1565 Views
Last post 01, February 2008, 21:14:50
by smacky
2 Replies
1431 Views
Last post 10, December 2007, 17:13:16
by ThePlaneskeeper
13 Replies
2414 Views
Last post 19, August 2010, 11:46:19
by grommit