Giter Site home page Giter Site logo

borup3 / lighting-system-2d Goto Github PK

View Code? Open in Web Editor NEW
65.0 4.0 8.0 961 KB

2D lighting system for GameMaker Studio

License: MIT License

Game Maker Language 84.57% GLSL 15.43%
gamemaker gamemaker-studio-2 gamemaker-studio gamemaker-language gamemaker-projects gms2

lighting-system-2d's Introduction

Lighting Demo

GameMaker Studio 2 Version

This project is known to work in GameMaker Studio Beta IDE v2.2.1.374 with Beta Runtime v2.2.1.286 as of January 15, 2019. This is the minimum version of GameMaker Studio 2 you must use. This system benefits massively from YYC, so it is recommended to use this compiler for releases.

Links

Shaun Spalding's introduction video: https://www.youtube.com/watch?v=RFRV3lhVOhg.
Website: http://thecode.cafe/posts/lighting-2d.
Demo project repository: https://github.com/borup3/Lighting-System-2D-Demos.
Marketplace: https://marketplace.yoyogames.com/assets/7820/lighting-system-2d.

2D Lighting for GameMaker Studio 2

I decided to write a lighting system for GameMaker Studio 2 because I wasn't super satisfied with the availability of lighting in the GameMaker ecosystem. One of my priorities were to demystify a system like this and ensure that everyone can pick it up, learn from it and understand what's going on, and integrate and adapt it to their game projects. That's not to say that this is by any means a "gold standard". It's not, but this is what I wrote and it's free and looks alright. I am releasing this system for free under the MIT License, and it is open-source so everyone can make it better and modify it to their heart's content. I welcome additions and bug fixes to the general design of the lighting system back into the repository so all users benefit from your cleverness - full credit is of course given.

Lighting Demo

This is a lightweight shader lighting system for dynamic pixel lights that composites multiple lights into a single surface. The surface is fitted to a "camera" that is used to perform the lighting pass. Instances that inherit from the object obj_shadow_caster are able to cast shadows, and lights are placed and configured in the game with instances of obj_light. It has good support for object variables.

It is my desire to provide a general lighting system that could be further customized to suit the needs of each specific game project it is used in. To get the best performance, or lighting quality, or whatever else, for your game you will probably end up modifying it to some extent. It might also work well for your game or prototype out-of-the-box by tweaking some of the knobs.

You can easily upgrade the lighting system, once integrated in your game, to a newer version by simply replacing the previous version's assets in your project. It also tracks various statistics (if you opt in) that help you optimize your use of the system.

Feature suggestions

  • Optimizations: trade-off with usability / learnability
  • Soft shadows
  • Multiple polygons per shadow caster
  • Shadow map layers: assign lights and shadow casters to different layers, producing per-layer shadow maps
  • Z axis and shadow caster height: use eLight.Z and remove eLight.ShadowLength and obj_shadow_caster.shadow_length hack

Known issues

  • light_trace_polygon doesn't produce a closed polygon, only an issue with shadows smaller than the shadow caster
  • Variables eLight.ShadowLength and obj_shadow_caster.shadow_length are a dirty hack to control shadow drops. See feature wishlist.

Demo

I have prepared a small demo of the lighting system to show what it's capable of in the hands of a moderately bad environment designer in a very short time span (60 minutes). This demo is a virtual tour of the different types of light in a single level. This demo is not by any means a gold (or even good) standard: for a game project you should do a lot of things different from this demo. Demos are always time sinks so I decided to leave it in its current sort of unimpressive state. You are of course free to improve this, or make better demos, too.

You can download the demo of the lighting system here: Lighting_Demo_01.zip (binary only).

Lighting Demo

Note that while this demo is not included with the lighting system project, a selection of testbed rooms are.

Lights

Lights are defined as a set of attributes that determine their behavior, so they are decoupled from the object that created them. These attributes include spatial information, rendering attributes like color, range and intensity and what type of light to use.

The following light types are supported at the time of writing:

  • Point Omnidirectional point emitter
  • Spot Conical point emitter
  • Area Unidirectional line emitter
  • Line Bidirectional line emitter
  • Directional Infinite directional light without an emitter source

These light types give you a lot of possibilities for lighting up your game worlds.

Shadow casters

A shadow caster is nothing more than a user-defined polygon and a bitmask enum to mark a shadow caster as static, dirty and so on. Shadow casters are by default non-static (for easier use by novices). Scripts are included to create a polygon from the axis-aligned or rotated bounding box of an instance and from a path resource for more complex polygons. This allows you to define complex polygons by tracing sprites on a room path layer and apply rotations with the path_orientation variable.

By toggling the global variable shadowCastersCullByCollisionMask you can control whether to cull shadow casters by their collision masks using an R-tree algorithm or linearly by their polygons. There may be a performance improvement to be had when using the R-tree algorithm, so the default value of this variable is true.

Documentation

I believe the code is sufficiently documented and with the addition of several test rooms and the demo project, I don't feel further documentation is required. For example, the lighting system contains only 4 objects: the initialization object, the renderer object, the light object and the shadow caster object.

lighting-system-2d's People

Contributors

borup3 avatar harperj0 avatar perdog avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

lighting-system-2d's Issues

macOS issue. light not appearing.

Hi,

This does not seem to work on macOS?

I'm getting a "lights turned off" look. Someone on youtube also commented on that.

image

image

Thanks

Support for HTML5

Would be cool to see this working in HTML5 (assuming its not already). I have tried with no luck, however it works fine in Windows.

Backwards blending

Backwards blending on the directional lights sometimes leaves what appears to be less bright versions of the main light. This undesirable effect is most noticeable on low resolution games with moving and rotating lights.

The bottom picture shows the temporary fix of setting the BLEND_TEXELS distance to 8.0 instead of 64.0. However this has diminishing effects on the blending quality.

lights2
lights4

Multiple Cameras / Viewports Support

Hey, I downloaded and tried this lighting system yesterday, it's really fantastic work! Thank you so much for open-sourcing it!

I did have a quick question though as I've only started using GMS2 a few days ago so I'm not mega-familiar with it yet... (although I have written an entire game engine myself (see https://github.com/irrelon/ige) so I'm not a noob either).

Does the lighting system support multiple viewports? I tested with a multi-viewport game but I am seeing a weird effect where the second viewport's shadows follow the position of the first viewport's camera.

I had a look in the lighting system source code and it looks like it should work because it's getting the active camera at time of render but I'm obviously missing something!

On the left viewport (the first vp and camera) the shadows look fine. On the second on the right, they are offset by the position of the left viewport's camera.

Here's a pic of what I mean:

Screenshot (1)

Random "trying to index a variable which is not an array" errors

Hi, I followed the tutorial step by step and I'm getting

_________________________________________
############################################################################################
ERROR in
action number 1
of Draw Event
for object obj_light_renderer:

trying to index a variable which is not an array
 at gml_Script_lighting_pre_composite (line 21) -                      outside_active_camera = !rectangle_in_rectangle(cached_polygon_area[0], cached_polygon_area[1], cached_polygon_area[2], cached_polygon_area[3],
############################################################################################
gml_Script_lighting_pre_composite (line 21)
gml_Script_composite_shadow_map (line 10) -        lighting_pre_composite();
gml_Object_obj_light_renderer_Draw_0 (line 8) -        exists = composite_shadow_map(global.worldLights);

If I create blank project and create the demo project I get

___________________________________________
############################################################################################
ERROR in
action number 1
of Draw Event
for object obj_light_renderer:

trying to index a variable which is not an array
 at gml_Script_light_trace_polygon (line 44) -        var vertex_count = polygon[ePolygon.Length];
############################################################################################
gml_Script_light_trace_polygon (line 44)
gml_Script_light_update (line 208) -                                    shadow = light_trace_polygon(id, light);
gml_Script_light_draw_shadow_map (line 40) -        var vertexbuffer = update ? light_update(light) : light[| eLight.VertexBuffer];
gml_Script_composite_shadow_map (line 122) -               light_draw_shadow_map(light, shadowMap, true);
gml_Object_obj_light_renderer_Draw_0 (line 8) -        exists = composite_shadow_map(global.worldLights);

Please help me make this work, I don't understand what am I doing wrong.

Issue with HTML5

Hello, first off thanks a lot for sharing this great engine. It works great on windows but in HTML5 the lights don't seem to work, the shadowmap is present but lights don't appear. Since there is no error i have no idea how to fix this. (using runtime 2.2.1.291)

Thanks in advance

Shadows to not render properly on MacOS

The shadows don't render correctly on MacOS resulting in either a flickering between no shadows or 100% shadows across the whole viewport. The issue has been occuring on a 2022 M1 Pro Macbook Pro with MacOS Ventura. Please let me know if someone else manages to re-produce the issue on their machine!

Can't create a surface with either a width or height of 0

FATAL ERROR in
action number 1
of Draw Event
for object obj_light_renderer:

Can't create a surface with either a width or height of 0
at gml_Script_shadow_map_ensure_exists (line 24) - shadowMap = surface_create(vw, vh);
############################################################################################

stack frame is
gml_Script_shadow_map_ensure_exists (line 24)
called from - gml_Script_composite_shadow_map (line 24) - var has_shadow_map = shadow_map_ensure_exists(eShadowMap.Global);
called from - gml_Object_obj_light_renderer_Draw_0 (line 8) - exists = composite_shadow_map(global.worldLights);

polygon_from_instance - Doesn't get bounding box for angles different than 0 degrees

As it can be seen on the screenshoot, in a case the instance we want to create polygons from has an angle different than 0 degrees, the polygons will be created taking into account the sprite width, instead the bounding box, which is a different behavious from the case of 0 degrees.

This should be fixed and also there could be an additional boolean argument in the function to alternate the polygon generation: either using the bounding box or the sprite dimensions (by deault true which means generate from bounding box).

image

How to change light color

I've tried changing the Light_color variable before (doesn't light at all) and after (doesn't change color) the event_inherit() function, but I can't figure it out.

var buffer = light[| eLight.VertexBuffer]; "argument 1 incorrect type (array) expecting a Number"

I have several lights in a scene. Whenever I change rooms, the following error is thrown.

ds_list_find_value argument 1 incorrect type (array) expecting a Number (YYGI32)
at gml_Script_light_destroy (line 8) - var buffer = light[| eLight.VertexBuffer];
############################################################################################
gml_Script_light_destroy (line 8)
gml_Object_i_Light_CleanUp_0 (line 4) - light_destroy(light);

When I inspect eLight.VertexBuffer in the debugger, the value shows as 14, not an array as the exception states.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.