2d light implemetations

what about 2d light? Are some implemetations exist? I work on my own impl but i have some problem. I need to get collision shape. How can i achieve it?

I need 2d light and shadow like this:http://ncase.me/sight-and-light/

I work on my impl.
I do raycast around light source. But i need to get collision shape. How can i achieve it?

go.property("rays", 30)
function init(self)
  self.my_interesting_groups = {hash("block")}
end

function update(self, dt)
    update_ray_cast_table(self)
	local degree=2*3.141592563/self.rays
	local vec = vmath.vector3(0, 1000, 0)
	for i=1,30 do
		local rotation=vmath.rotate(vmath.quat_rotation_z(degree*i), vec)
		ray_cast(self,rotation,i)
	end
end

function update_ray_cast_table(self)
	if(self.ray_cast ~= nil) then
		for key, value in pairs(self.ray_cast) do
    		print(key, value.id)
    		print(key, value.request_id)
		end
	end	
	self.ray_cast={}
end

function ray_cast(self,direction,number)
	end_point=go.get_position()+direction
	physics.ray_cast(go.get_position(), end_point, self.my_interesting_groups,number)
end

function on_message(self, message_id, message, sender)
    if message_id == hash("ray_cast_response") then
    	table.insert(self.ray_cast,message)
        msg.post("@render:", "draw_line", { start_point = go.get_position(), end_point = message.position, color = vmath.vector4(1, 1, 1, 1)})
    end
end
1 Like

I find all points that i need. Now i need to create visibility polygon and draw it to light map.How can i achieve it?

Apart from generating the polygons (a good, interactive tutorial here ), I think the problematic issue is actually rendering custom shapes (since we don’t support it yet).

But, it should be possible to render a box, using a custom shader, and pass in the actual vertices as render constants. It should suffice, since each edge projected, from the light’s perspective, onto one of the screen boundaries, will form a 4 vertex polygon.

thx, but i do not understand what you mean. I can create custom shader. But i can’t change verticles for fragment shader. As i think by default fragment shader use 4 vericles(box). Ok i can draw box. I can make a constants. But how can i change this constants in runtime(changing constanst sound awesome :slight_smile: )

You want to change the vertices in the vertex shader. However, this is tricky, since 1) we’re using OpenGLES 2.0 which doesn’t feature gl_VertexID, and 2) We currently only support 4 user defined constants per shader.

However, a simple test allowed me to modify the vertices of my box, using a custom material and custom shader. The yellow rectangle is the original location of my box, and the gradient polygon is my custom vertices (pretend there’s a light source in the bottom left corner):

Setting render constants is straight forward. Copy the material and shaders you wish to use into your project (from the builtins folder), and then add extra constants into the material file. See the manual for further reference.

In my test, I pass 3 constants: the center of the box, and the 4 vertices:

    go.set("#sprite", "center", vmath.vector4(pos.x, pos.y, 0, 0))
    go.set("#sprite", "p1p2", vmath.vector4(p1.x, p1.y, p2.x, p2.y))
    go.set("#sprite", "p3p4", vmath.vector4(p3.x, p3.y, p4.x, p4.y))

Using a technique this, you could render them into a stencil buffer an use that for rendering the scene. See this flashlight example

I’ve uploaded this (very basic) example of the custom box here

Hopefully, we can soon render custom shapes a bit more easily :wink:

7 Likes

Awesome, thank you. :+1: As i understand one material 4 vertices. So if add a lot of sprite to game object ,i can create as much polygons as i need :slight_smile:. I will be waiting for custom shapes render :wink:. For my prototype dynamic light is not must have, predefined is also good.

You can use custom collada model (flat polygon, as many vertices as you wish inside, let’s say 100x2) and re-arrange vertices in shader so bottom vertex is always in your light position and top is the end of the ray. You just need a way to hide excessive vertices, e.g. by putting top and bottom at light position.

Do you understand the idea? If not, push me in defold.slack (abadonna) and I can try to describe it in Russian :slight_smile:

3 Likes

I make some improvements of your example. Lights now described only by angle. As i understand stencil buffer is describe draw pixel or not. I need to see what is under black pixels but like there is no light here.
So i need to draw frame with shader(to make frame darker).It will be frame without light
Then draw same frame with stencil_buffer. It will draw all light zone. I am right? or there are some other solutions?

go.property("angle",90)
local size=3000
--todo fixed grad
local function update_points(self)
    local pos = go.get_position()
    local half_angle=self.angle/2
    local degree_to_rad=1*math.pi/180
    local line= pos+vmath.vector3(0,-1,0)*size
    local rotation=vmath.quat_rotation_z(-half_angle*degree_to_rad)
    self.point1=vmath.rotate(rotation, line)
    local rotation=vmath.quat_rotation_z(half_angle*degree_to_rad)
    self.point2=vmath.rotate(rotation, line)
    msg.post("@render:", "draw_line", { start_point = pos, end_point = self.point1, color = vmath.vector4(1, 1, 1, 1) } )
    msg.post("@render:", "draw_line", { start_point = pos, end_point = self.point2, color = vmath.vector4(1, 1, 1, 1) } )
end

function init(self)
    update_points(self)
end

function update(self, dt)
	update_points(self)
    local pos = go.get_position()

    -- let's pretend the light source is in the bottom left corner :)
    local p1 = pos + vmath.vector3( 1, 1, 0)
    local p2 = pos + vmath.vector3( -1, 1, 0)

    go.set("#sprite", "center", vmath.vector4(pos.x, pos.y, 0, 0))
    go.set("#sprite", "p1p2", vmath.vector4(p1.x, p1.y, p2.x, p2.y))
    go.set("#sprite", "p3p4", vmath.vector4(self.point1.x, self.point1.y, self.point2.x, self.point2.y))
end

1 Like

up old topic :slight_smile: Does anyone have some progress on the 2d light and shadow?

1 Like

The example by @d954mas is the one and only 2D light and shadow project I’m aware of:

You can also check lighting without shadows by @britzl :


But personally, lighting is still not so well explained for Defold, so you need to check out solutions from other engines/games and try to adapt them.

Maybe you could be interested in something like @jhonny.goransson presented here:

2 Likes

@Pawel thanks, but I’m finding something like @d954mas mentioned in the start:
shadow_light
I created gif from https://ncase.me/sight-and-light/

the example of @d954mas is old (4 years ago) and no works now… but really looks like what I wanna to get!

I haven’t checked lumiere yet, will check now! thanks.

3 Likes

I can’t agree, I did the above screen of this working project today! :smiley:

1 Like

wow, really? I tested in 1.2.172 and 1.2.173 (windows) and got the followin error: