Jump to content

  • Log In with Google      Sign In   
  • Create Account


Predator034

Member Since 06 Dec 2012
Offline Last Active Jul 24 2013 08:22 AM
-----

Topics I've Started

Alpha blended lighting/render to texture (2D ambient, deferred lighting)

01 March 2013 - 03:24 PM

I'm trying to do terraria-like lighting, except not on a per-tile basis. e.g. http://cloud.steampowered.com/ugc/648743187051563480/80FE8DD1840E25A4FD5BF1EA529EC30CD7E0C329/

 

I'm using OpenGL, but nothing specific to it, the concept is generic.

 

Basically I want my entire scene to be black/dark unless there are light sources, like a torch. In which case there would be a radius where the light  bleeds off. Currently I render my game scene (tile map, then entities). Then I render the light points (torches) into an FBO (offscreen texture), and then I render that to the backbuffer using multiplicative blending.

 

Here's an example of what I'm doing..and trying to get to work http://i.imgur.com/CJvTkej.png

 

Light sources can be changed at runtime by the player, and there has to be support for a lot of them, which is why I am using this deferred approach to rendering them.

 

The lights are each rendered as a quad using the frag shader below, then the entire FBO is rendered as a fullscreen quad to the backbuffer using a simple passthrough shader.

 

 

 

Fragment shader code, to calculate lights. But the code itself is pretty screwed up because from the screenshot above, you can see that the ball of light is all concentrated in one area, more like a Sun than a Torch. So my lighting shader needs to be fixed, then I need someway to make non lit areas dark.

void main() {
    float distance = 8 * distance(frag_texcoord.xy, vec2(0.5, 0.5));
    fragColor = vec4(frag_color.rgb * (1/distance), frag_color.a * (2/ distance));
}

 

Anyways, not only do I need the areas that aren't in range of a light source to be darkened, but I also need to think of a way to handle the sky. I mean, some approach might be fine while i'm underground, but if I'm above ground where half the screen is sky and the bottom half is ground (and it's not symmetrical either, but can be jagged, however the user places blocks)...I wouldn't know how to make the sky *not* black.

 

Any thoughts, suggestions or somewhere to point me to? Because I'm super new to this lighting stuff (well, graphics programming altogether), and I've been trying to solve my lighting for a long time now, trying different approaches.

 

Thanks.


Timestep/game loop explanations needed

05 February 2013 - 04:42 PM

Hi there, I need some help with my game's timestep. And yes, I've read over the infamous and all-too reposted gaffer article: gafferongames.com/game-physics/fix-your-timestep/

 

 

Basically my current game loop code is broken and passes a deltatime through each update(elapsedTime) method. Then movements are multiplied based on that value, of course.

 

My game does need to be networked, but I'm hoping that such a thing doesn't change much, (essentially I'll just have the clients act as dumb input terminals and the server will tell everyone the state, it's only for a small number of players so it should be fine and as such will be authoritative).

 

The parts I do not understand about *this* solution, is how the State struct fits into all of this. Why is it only 1 dimensional? Do I add y (it's a 2d game) as well in a same similar manner, along with vy to make this usable for 2d?

 

 

Why is it interpolating the rendering itself and not collision and such?

 

If I have a world->update() call which updates all the entities and checks collision on them..what do I pass to them and how do I use this in a similar manner as I was doing?

 

I don't see how just interpolating the rendering would result in something usable?

 

Where do I place the input collection code and the update (collision/physics etc.) code, as well as networking. Especially since I have a handleEvents() { while (SDL_PollEvent(&event)) {.. }.. } Can I just place all of these in one area? Where, exactly, in the main loop?

 

I've scoured the internet and unfortunately have yet to find a *real* example that uses a fixed time step

 

 

  I'm posting the code below so that it's easy to talk about as I need to understand it, and a lot of it I do not, and so people can hopefully walk me through the parts I'm confused on.

 

Thanks, really hoping someone here can help me understand and use this code. Game loops seem to be an area where from a distance they seem obvious and simple/straight forward, but of course, that is not the case at all.

 


struct State
{
    float x;
    float v;
};


struct Derivative
{
    float dx;
    float dv;
};


State interpolate(const State &previous, const State &current, float alpha)
{
    State state;
    state.x = current.x*alpha + previous.x*(1-alpha);
    state.v = current.v*alpha + previous.v*(1-alpha);
    return state;
}


float acceleration(const State &state, float t)
{
    const float k = 10;
    const float b = 1;
    return - k*state.x - b*state.v;
}


Derivative evaluate(const State &initial, float t)
{
    Derivative output;
    output.dx = initial.v;
    output.dv = acceleration(initial, t);
    return output;
}


Derivative evaluate(const State &initial, float t, float dt, const Derivative &d)
{
    State state;
    state.x = initial.x + d.dx*dt;
    state.v = initial.v + d.dv*dt;
    Derivative output;
    output.dx = state.v;
    output.dv = acceleration(state, t+dt);
    return output;
}


void integrate(State &state, float t, float dt)
{
    Derivative a = evaluate(state, t);
    Derivative b = evaluate(state, t, dt*0.5f, a);
    Derivative c = evaluate(state, t, dt*0.5f, b);
    Derivative d = evaluate(state, t, dt, c);
    
    const float dxdt = 1.0f/6.0f * (a.dx + 2.0f*(b.dx + c.dx) + d.dx);
    const float dvdt = 1.0f/6.0f * (a.dv + 2.0f*(b.dv + c.dv) + d.dv);
    
    state.x = state.x + dxdt*dt;
    state.v = state.v + dvdt*dt;
}


int main()
{
    const int width = 640;
    const int height = 480;
    
    if (!openDisplay("Timestep", width, height))
        return 1;


    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0, 4.0/3.0, 1, 1000);


    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(0,0,150, 0,0,0, 0,1,0);
    
    glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
    glEnable(GL_POINT_SMOOTH);
    glPointSize(4);    
    
    glClearColor(0.3f, 0.3f, 0.3f, 1);


    State current;
    current.x = 100;
    current.v = 0;
    
    State previous = current;


    float t = 0.0f;
    float dt = 0.1f;
    
    float currentTime = 0.0f;
    float accumulator = 0.0f;
    
    while (!quit) 
    {            
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        
        const float newTime = time();
        float deltaTime = newTime - currentTime;
        currentTime = newTime;
        
        if (deltaTime>0.25f)
            deltaTime = 0.25f;
        
        accumulator += deltaTime;
        
        while (accumulator>=dt)
        {
            accumulator -= dt;
            previous = current;
            integrate(current, t, dt);
            t += dt;
        }
        
        State state = interpolate(previous, current, accumulator/dt);
        
        glBegin(GL_POINTS);
        glColor3f(1,1,1);
        glVertex3f(state.x, 0, 0);
        glEnd();
        
        updateDisplay();
    }
    
    closeDisplay();
    
    return 0;
}

 


PARTNERS