Light shadows?
#1
UPD. This feature already in game engine.

Is it necessary?
A little engine modification.
[Image: vNzQ4Nw.jpg]
[Image: vNzQ4OQ.jpg]

Source code (see post №10):
http://forum.cubers.net/thread-2116-post...l#pid33761
Thanks given by:
#2
Lighting in AC is poor as opposite Sauer engine. But if engine let players hide in dark corner it will add something to gameplay.
Thanks given by:
#3
O.o I didn't know that was possible with the Cube engine. Did you backport something?
Thanks given by:
#4
I just added occlusion test in lighting function:)
Thanks given by:
#5
Wow. Looks so progressive!
Thanks given by:
#6
Very nice.
Thanks given by:
#7
Some light effects may be more realistic:

[Image: vNzRhYQ]
[Image: vNzRhYw]
Thanks given by:
#8
I'd love seeing this creep into an official release. Haha.
Thanks given by:
#9
(23 Jan 11, 07:43PM)eftertanke Wrote: I'd love seeing this creep into an official release.

F1!
that would be good.

Thanks given by:
#10
Code changed:
In file worldlight.cpp:
replace function:
void lightray(float bx, float by, const persistent_entity &light, float fade = 1, bool flicker = false)     // done in realtime, needs to be fast
{
    disableraytable();
    float lx = light.x+(flicker ? (rnd(21)-10)*0.1f : 0);
    float ly = light.y+(flicker ? (rnd(21)-10)*0.1f : 0);
    float dx = bx-lx;
    float dy = by-ly;
    float dist = (float)sqrt(dx*dx+dy*dy);
    if(dist<1.0f) return;
    int reach = light.attr1;
    int steps = (int)(reach*reach*1.6f/dist); // can change this for speedup/quality?
    const int PRECBITS = 12;
    const float PRECF = 4096.0f;
    int x = (int)(lx*PRECF);
    int y = (int)(ly*PRECF);
    int fadescale = (int)(fade*PRECF);
    int l = light.attr2*fadescale;
    int stepx = (int)(dx/(float)steps*PRECF);
    int stepy = (int)(dy/(float)steps*PRECF);
    int stepl = (int)(l/(float)steps); // incorrect: light will fade quicker if near edge of the world

    if(maxtmus)
    {
        l /= lightscale;
        stepl /= lightscale;

        if(light.attr3 || light.attr4)      // coloured light version, special case because most lights are white
        {
            if(flicker)
            {
                int dimness = rnd((((255<<PRECBITS)-(int(light.attr2)+int(light.attr3)+int(light.attr4))*fadescale/3)>>(PRECBITS+4))+1);
                x += stepx*dimness;
                y += stepy*dimness;
            }

            if(OUTBORD(x>>PRECBITS, y>>PRECBITS)) return;

            int g = light.attr3*fadescale;
            int stepg = (int)(g/(float)steps);
            int b = light.attr4*fadescale;
            int stepb = (int)(b/(float)steps);
            g /= lightscale;
            stepg /= lightscale;
            b /= lightscale;
            stepb /= lightscale;
            loopi(steps)
            {
                sqr *s = S(x>>PRECBITS, y>>PRECBITS);
                s->r = min((l>>PRECBITS)+s->r, 255);
                s->g = min((g>>PRECBITS)+s->g, 255);
                s->b = min((b>>PRECBITS)+s->b, 255);
                if(SOLID(s)) return;
                if(isoccluded(light.x, light.y, x>>PRECBITS, y>>PRECBITS, 1)) return;
                x += stepx;
                y += stepy;
                l -= stepl;
                g -= stepg;
                b -= stepb;
                stepl -= 25;
                stepg -= 25;
                stepb -= 25;
            }
        }
        else        // white light, special optimized version
        {
            if(flicker)
            {
                int dimness = rnd((((255<<PRECBITS)-(light.attr2*fadescale))>>(PRECBITS+4))+1);
                x += stepx*dimness;
                y += stepy*dimness;
            }

            if(OUTBORD(x>>PRECBITS, y>>PRECBITS)) return;

            if(hdr.ambient > 0xFF) loopi(steps)
            {
                sqr *s = S(x>>PRECBITS, y>>PRECBITS);
                s->r = min((l>>PRECBITS)+s->r, 255);
                s->g = min((l>>PRECBITS)+s->g, 255);
                s->b = min((l>>PRECBITS)+s->b, 255);
                if(SOLID(s)) return;
                if(isoccluded(light.x, light.y, x>>PRECBITS, y>>PRECBITS, 1)) return;
                x += stepx;
                y += stepy;
                l -= stepl;
                stepl -= 25;
            }
            else loopi(steps)
            {
                sqr *s = S(x>>PRECBITS, y>>PRECBITS);
                s->r = s->g = s->b = min((l>>PRECBITS)+s->r, 255);
                if(SOLID(s)) return;
                if(isoccluded(light.x, light.y, x>>PRECBITS, y>>PRECBITS, 1)) return;
                x += stepx;
                y += stepy;
                l -= stepl;
                stepl -= 25;
            }
        }
    }
    else        // the old (white) light code, here for the few people with old video cards that don't support overbright
    {
        loopi(steps)
        {
            sqr *s = S(x>>PRECBITS, y>>PRECBITS);
            int light = l>>PRECBITS;
            if(light>s->r) s->r = s->g = s->b = (uchar)light;
            if(SOLID(s)) return;
            //if(isoccluded(light.x, light.y, x>>PRECBITS, y>>PRECBITS, 1)) return;
            x += stepx;
            y += stepy;
            l -= stepl;
        }
    }
}

Pay attention at "isoccluded" function. disableraytable was added to fix "FOV shadow" bug.

I think this feature will put mapping in a new "light":).
Thanks given by:
#11
(23 Jan 11, 08:22PM)RPG Wrote: I think this feature will put mapping in a new "light":).

Budum bum, ching!
Thanks given by:
#12
Wow, that looks pretty awesome!

Why hasn't this been done before? Is it heavy on resources? If this is compatible with the low-end machines, it definitely would be a great addition.

Damn, I do hope it is! :P
Thanks given by:
#13
Oh beautiful!

Who cares if it's heavy on resources, as long as it is optional. Besides, we have dynamic stencil shadows (killed my other computer when they were enabled) so why not :D
Thanks given by:
#14
The main problem is an idea. Technical solution is the second problem. As you see I changed only 4 lines of source, my first change was 1 line of code.

About speed. Lighting calculation done by CPU only. I have 3 GHz CPU and can't test that, but I think my improvement will not slow down the game. Function "isoccluded" very fast because it calls every frame many times. Light calculation happens only once - when map loads (or you edit light params).

Also you must know, that it is only "emulation" of shadows due to limitations of game engine. My code will not generate object shadows, it's possible only in Cube 2 engine. These shadows are "2D", so it is shadows only for walls, ignoring boxes or windows.
[Image: vNzRkMA]
As you can see only walls cast shadows, boxes can't.
Thanks given by:
#15
I see: Solids = shadow, everything else can't do it -- due to the 2D nature of AC map layout.
Thanks given by:
#16
Right. Better shadows - it's easier to take cube 2 and make AC mod:)
Thanks given by:
#17
Lawl.
Still, any sharp shadows as in your pics above are looking great!
Thanks given by:
#18
Well thanks for doing this for me. I've been bitching about the shadows for a while.
Thanks given by:
#19
Awesome, i was wondering if the shadow is always that dark or does it matter the brightness of the light, or would there be a way to get the shadow a lighter shade.
[/align]


Thanks given by:
#20
More lights will probably give a diffuse look.
Thanks given by:
#21
Fixed error in old white code (error while compilation). See post#10.

Official maps has huge amount of lights, so shadows effect is not as noticeable. To make maps more realistic, we must remake lights on all maps. When you create new map it is more noticeable.
Thanks given by:
#22
WOAH! This looks very nice!

This can give mapping a new edge :P
Thanks given by:
#23
What lines did you replace/modify exactly? You said it was only 4 lines or so. Did you just add them? Or did you have to modify some? Looks nice btw.
Thanks given by:
#24
http://ompldr.org/vNzRrZQ
Thanks given by:
#25
Nice!
That is some pretty neat code you have going on there :)
Thanks given by:
#26
So normal/bump mapping will be impossible to do with this lighting?
Thanks given by:
#27
No, bumpmapping/parallaxmapping is another technology. They are CPU hungry.

If you want parallax/bump - play cube 2.
Thanks given by:
#28
(24 Jan 11, 09:13AM)RPG Wrote: No, bumpmapping/parallaxmapping is another technology. They are CPU hungry.

If you want parallax/bump - play cube 2.

So I do :) but I wonder how ac will look like with this.
Thanks given by:
#29
The main principle of AC - to be simple and fast. I think there will never be slow visual effects.
Thanks given by:
#30
I think it looks great, but if implemented the lighting would have to be redone in a lot of maps.
Thanks given by: