Night day effect

Night day effect
0

Hi

I’m developing a 2D Racing Game (Top-Down) and I want to make a “night effect”. The idea is that you can drive in a night road, with the car lights on.

So, I need to make a night effect and lights effects.
Suggestions?

I didn’t find examples in effecthub.com :confused:

What about using the same concept as god rays?

What’s that?

I am thinking something like this: https://www.youtube.com/watch?v=ENK6Abpj-kg

This game was made with Cocos.

I’m actually interested in this, can you share a few screenshots of your game so I can think about some ideas? I started a top down racer a few years ago that felt like F-Zero, but the way you drove the car was based on your previous finger touchs you chose to control the direction.

Yes, no problem. Previews:

Anyway I will publish the link to stores here when I finish it. It’s taking me a lot of work because of the levels. I’m designing each level manually using Tiled Maps.

The point is, I want to make night levels. Or, at least, try to do it.
So I need that effects. I’ve no experience designing effects, i would like to get an existing one and maybe edit it.

Suggestions? Examples?
I’m creating the effects using ParticleSystemQuad so I would need the plist file.

what about applying a shader to a day time map to make it a night time map? if you can share this repo with me (privately of course), I can try to help out a bit on my weekend.

This can work just fine. I laid mine out as a data structure of vectors and such that house making the level, making the road and how it twists and turns, obstacles, way points, etc.

This game was made with cocos2d-x has the light effect as well.

1 Like

I’m not an expert here, but what I believe is best is using shaders. I think how it’s usually done is that you render your scene to an image, render your lighting to a separate image, and use a shader to lighten/darken your scene using the lighting image.

Off the top of my head, in cocos2d-x it would be something like adding a RenderTexture (RenderTexture A) to your scene, rendering your scene to it, rendering your lights to another RenderTexture (RenderTexture B), then applying a shader to your first RenderTexture A, with a reference to the texture of RenderTexture B.

You may want to look online for 2D dynamic lighting shaders and adjust them - if necessary - to work with cocos2d-x, which shouldn’t be a very difficult thing to do.

3 Likes

this sounds like a great plan.

1 Like

There is an easier solution, but I’m sure there are downsides to it. Basically place a transparent black filter over the screen and then remove the areas with light using the light sprite’s blending function. Here is some bad example code that should work:

auto size = Director::getInstance()->getWinSize();
	
// how light the scene is where no light is being shined
const float ambientLight = .1f;
// the alpha value to set the "darkness" layer
const float darkness = 1.f - ambientLight;

// add something for the light to illuminate
auto background = LayerColor::create(Color4B::BLUE);
this->addChild(background, 0);
	
// creates a transparent black that sits over the level to give the illusion
// of darkness
auto renderTexture = RenderTexture::create(size.width, size.height);
this->addChild(renderTexture, 10);
renderTexture->setPosition(size / 2.f);

// start with full darkness
renderTexture->clear(0, 0, 0, darkness);

// the light - the shape of the sprite determines the shape of the light and
// the alpha value of each pixel determines how strong the light
auto light = Sprite::create("res/Light.png");
// don't add the light to the scene or else the sprite will be shown, but retain
// so that it can be used later
light->retain();

// this method works by placing a transparent black filter over the screen and
// then cutting holes in that filter to give the illusion of light being shined.
// GL_ONE prevents the light sprite from being drawn on screen, while
// GL_ONE_MINUS_ALPHA_ZERO reduces the alpha value of the pixels the light is being
// drawn on top of by the alpha value of that light's pixel.
light->setBlendFunc({ GL_ZERO, GL_ONE_MINUS_SRC_ALPHA });
	
// add some interaction
auto mLstnr = EventListenerMouse::create();
_eventDispatcher->addEventListenerWithFixedPriority(mLstnr, 1);

mLstnr->onMouseMove = [=](EventMouse* event) {
	// reset the "darkness" layer to remove the effect 
	renderTexture->beginWithClear(0, 0, 0, darkness);

	// position the light and draw it onto the render texture
	light->setPosition(event->getLocationInView());
	light->visit();
	
	renderTexture->end();
};

Note: This is quick, bad code intended to be copied into a test scene or something, just so you can see it in action. It is not intended to be put in an actual project. For example, light is retained but never released, which means it will never be removed from memory if you change to another scene.

Also, you will need you need to change Light.png to an image already in your project, or add an image with that filename.

The main limitation to this method is that because you can’t add the lights to your scene, so they don’t automatically move with your scene/camera does. That means that you need to update the position of your static lights, e.g. street lights, every time the camera/scene pans, and update your dynamic lights, e.g. headlights, every time the scene/camera pans or the light itself moves, e.g. the car moves forward. One way I was thinking of doing this was to store the node space position the light would be if it were added to the scene with a reference to the parent node and light, and then whenever you update the position of your lights, just convert the node space position to world space using the parent node.

I haven’t actually created a game with this method before, so I’m not sure if there are other issues, such as performance.

There are likely ways to improve this too. For example, if you can figure out how to get the lights to keep their proper positions, you can actually add a second camera to the scene, add your lights to the scene, render the lights to that camera by setting their camera mask, having that camera render to a texture, and then use that texture as your “light” with the RenderTexture method. (This second camera method might actually be preferable. You could add your static lights like the scene like you would any other node, and you would just need to manually move the dynamic lights, e.g. headlights, if you can’t figure out how to have them render properly.)

this is cool, lets try and test it. Perhaps I can find time this weekend