Please can someone help me write a shader/function

General discussion about LÖVE, Lua, game development, puns, and unicorns.
Post Reply
User avatar
Gunroar:Cannon()
Party member
Posts: 1102
Joined: Thu Dec 10, 2020 1:57 am

Please can someone help me write a shader/function

Post by Gunroar:Cannon() »

I think this is something I could eventually do, but it's for a game jam and I don't really have the time (for the jam) to do this:

Could I please get help/someone posting a function that splits an image ("rect") into several randomly shaped pieces (like shards of glass) and then returns all pieces it in a sort of table, with each "shard" having variables that define how it should be drawn based on it's position in the image.

I imagine this needs knowledge in polygons and ...shaders maybe?

Please could you help?
The risk I took was calculated,
but man, am I bad at math.

-How to be saved and born again :huh:
User avatar
Gunroar:Cannon()
Party member
Posts: 1102
Joined: Thu Dec 10, 2020 1:57 am

Re: Please can someone help me write a shader/function

Post by Gunroar:Cannon() »

Okay, I learnt about the voronoi algorithm. But I just have a bunch of lines. How do I split them up into individual polygons?
viewtopic.php?t=78403&start=10
The risk I took was calculated,
but man, am I bad at math.

-How to be saved and born again :huh:
RNavega
Party member
Posts: 291
Joined: Sun Aug 16, 2020 1:28 pm

Re: Please can someone help me write a shader/function

Post by RNavega »

Hi. Try a 2D Delaunay triangulation.
1) Besides the 4 initial points of the image rectangle (its 4 corners), also add a bit of random points on the 4 edges of the rectangle, and a bit of points randomly inside the rectangle. All of these points then are your point cloud.

2) Triangulate the point cloud using the Delaunay algorithm. This seems to be an implementation in Lua: https://github.com/Yonaba/delaunay/blob ... launay.lua

3) The result is a list of triangles. You can make a Mesh object with all of those triangles, manipulate the vertices to animate them etc. The UV coordinates of the vertices are the points normalized to the rectangle area (so you map the points to a space that is analogous to the UV space).
images.jpg
images.jpg (165.07 KiB) Viewed 955 times
Optionally, animating some of the neighboring triangles together so they form a more complex piece.
User avatar
marclurr
Party member
Posts: 112
Joined: Fri Apr 22, 2022 9:25 am

Re: Please can someone help me write a shader/function

Post by marclurr »

Here's an example of drawing an image as uniform shards randomly scattered over the screen. The result is not aesthetically pleasing but demonstrates how to build the required mesh. U and V are the coordinates into the texture, and are in normalised space (i.e., 0 to 1). You should be able to modify this to work with the output of your triangulation routine to produce something nicer looking.

Code: Select all

local img = love.graphics.newImage("img.png")

local shards = {}

local cols, rows = 3, 3
local w = 1 / cols
local h = 1 / rows

local th = 64
local tw = 64
local rnd = love.math.random
for y = 0, cols -1 do
    for x = 0, rows -1 do
        local u = w * x
        local v = h * y

        local m1 = love.graphics.newMesh({
            {0, 0, u, v},
            {tw, 0, u + w, v},
            {tw, th, u +w, v+ h}
        }, "triangles")

        local m2 = love.graphics.newMesh({
            {0, 0, u, v},
            {tw, th, u +w, v+ h},
            {0, th, u, v +h}
        }, "triangles")

        m1:setTexture(img)
        m2:setTexture(img)

        
        table.insert(shards, {m1, {rnd(0, 800 - tw), rnd(0, 600 - th)}})
        table.insert(shards, {m2, {rnd(0, 800 - tw), rnd(0, 600 - th)}})
    end
end

function love.draw()
    love.graphics.clear()
    for i, sh in ipairs(shards) do
        local mesh, pos = unpack(sh)
        local x, y = unpack(pos)
        love.graphics.draw(mesh, x, y)
    end
    
end
[code]
RNavega
Party member
Posts: 291
Joined: Sun Aug 16, 2020 1:28 pm

Re: Please can someone help me write a shader/function

Post by RNavega »

By the way, Delaunay is related to Voronoi, you can get it by connecting the centers of neighboring Voronoi cells.
Delaunay-triangulation-solid-lines-and-Voronoi-diagram-dashed-lines-for-20-points.png
Delaunay-triangulation-solid-lines-and-Voronoi-diagram-dashed-lines-for-20-points.png (90.55 KiB) Viewed 945 times
User avatar
Gunroar:Cannon()
Party member
Posts: 1102
Joined: Thu Dec 10, 2020 1:57 am

Re: Please can someone help me write a shader/function

Post by Gunroar:Cannon() »

marclurr wrote: Sun May 26, 2024 2:18 pm Here's an example of ...
Oooh, nice. But these are only triangles (though I feel like the traingels can be added together to form other shapes)?

Is there a way to make this code, so it can cut polygons numerous times to make small ones (it works when done in the program.)

(from viewtopic.php?p=91122#p91122)
markgo wrote: Sun Mar 17, 2013 6:23 am There is an old demo for polygon splitting. The code is messy so I made my own and turned it into a small module. Very simple to use. Just plug in your cut line endpoints and the vertices of your polygon. CONVEX ONLY

Code: Select all

Usage:

table_of_polygons = polygoncut(cut_vertices,polygon_vertices)

polygons = polygoncut({x1,y1,x2,y2},{px,py,px1,py1,px2,py2,...})

for i,polygon in ipairs(polygons) do
	love.graphics.polygon('fill',unpack(polygon))
end
The module:

Code: Select all

local insert= table.insert

local function cross(dx,dy,dx2,dy2)
	return dx*dy2-dy*dx2
end

local polygonCut = function(cvertices,pvertices)
	local plen     = #pvertices
	local x,y,x2,y2= unpack(cvertices)
	local dx,dy    = x2-x,y2-y
	local polygons = {{},{}}
	local set      = polygons[1]
	local intersections = 0
	for i = 1,plen,2 do
		local x3,y3,x4,y4= pvertices[i],pvertices[i+1],pvertices[i+2] or pvertices[1],pvertices[i+3] or pvertices[2]
		insert(set,x3) insert(set,y3)
		local dx2,dy2    = x4-x3,y4-y3
		local denom      = cross(dx,dy,dx2,dy2)
		if denom ~= 0 then
			local tnum = cross((x3-x),(y3-y),dx2,dy2)
			local unum = cross((x3-x),(y3-y),dx,dy)
			local ct,pt= tnum/denom,unum/denom
			if ct >= 0 and ct <= 1 and pt >= 0 and pt <= 1 then
				local ix,iy = x+ct*dx,y+ct*dy
				if pt ~= 1 then
					if pt ~= 0 then
						insert(set,ix) insert(set,iy)
					end
					set = set == polygons[1] and polygons[2] or polygons[1]
					insert(set,ix) insert(set,iy)
					intersections = intersections+1
					
				end
			end
		end
	end
	if intersections == 2 then return polygons end
end

return polygonCut
The risk I took was calculated,
but man, am I bad at math.

-How to be saved and born again :huh:
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot] and 2 guests