how to change cam perspective (fov && angle)?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
girng
Prole
Posts: 39
Joined: Fri Sep 07, 2018 5:42 am

how to change cam perspective (fov && angle)?

Post by girng » Thu Sep 13, 2018 12:57 am

i saw this game when i visiting defold website
https://risingwave.itch.io/smash-bash-d ... the-desert

developer has stated he uses a "fov" and camera perspective. is it possible to do this, with let's say hump's camera addon?

example: https://forum.defold.com/t/view-like-in ... ed/12917/9
We have a perspective camera, which is looking onto the ground under some angle (22.5 degrees on x axis worked well for us). FOV is 1.0177028.

girng
Prole
Posts: 39
Joined: Fri Sep 07, 2018 5:42 am

Re: how to change cam perspective (fov && angle)?

Post by girng » Thu Sep 13, 2018 3:19 am

viewtopic.php?p=223057#p223057

user here posted a shader that might be able to do it =]

gonna try this out later. am excited

JoshGrams
Prole
Posts: 29
Joined: Sat May 27, 2017 10:58 am

Re: how to change cam perspective (fov && angle)?

Post by JoshGrams » Sun Sep 16, 2018 9:23 am

Defold is a 3D engine, Love2D is a 2D engine. If you want to do 3D-ish stuff like Smash Bash you're probably better off using an engine designed to support 3D. It is possible to do 3D in Love, but it's significantly more work than in something like Defold.

girng
Prole
Posts: 39
Joined: Fri Sep 07, 2018 5:42 am

Re: how to change cam perspective (fov && angle)?

Post by girng » Sun Sep 16, 2018 9:57 am

JoshGrams wrote:
Sun Sep 16, 2018 9:23 am
Defold is a 3D engine, Love2D is a 2D engine. If you want to do 3D-ish stuff like Smash Bash you're probably better off using an engine designed to support 3D. It is possible to do 3D in Love, but it's significantly more work than in something like Defold.
I'm pretty sure you can achieve the same effect in love2d without " a lot of work"

User avatar
zorg
Party member
Posts: 2413
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: how to change cam perspective (fov && angle)?

Post by zorg » Sun Sep 16, 2018 10:03 am

Löve is a framework; what you accomplish with it is your business; it uses OpenGL, which is able to handle both 2D, 3D, or any Dimensions you want it to, be it 2.5 or 4.

But yeah, the bigger issue is that for perspective projections (textures rendered correctly when "slanted"), you do need to use a separate shader, because that's not something you can just toggle.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.

JoshGrams
Prole
Posts: 29
Joined: Sat May 27, 2017 10:58 am

Re: how to change cam perspective (fov && angle)?

Post by JoshGrams » Mon Sep 17, 2018 11:37 am

There are two things going on in that game: the ground is rendered on an inclined plane, and the vertical things are rendered standing straight up. Since he's in Defold, he's rendering things in proper 3D (using the depth buffer to determine which things are in front of which other things). But if you're never going to rotate the camera (he never does), the depth buffer is unnecessary. You can just write a vertex shader to give the perspective squashing to the ground, and then reset to the normal shader and draw the upright images (sorted from farthest away to nearest, which is easy if you're looking at it straight along one axis).

In the ground vertex shader you'll want to transform the corners of the ground tiles from world to screen coordinates. If you're going to do mouse picking or anything you'll also need the inverse transform (screen to world). I did this recently for a game I'm working on. I think I can extract it fairly easily: I'll take a look tonight and try to post a quick demo.

girng wrote:
Sun Sep 16, 2018 9:57 am
I'm pretty sure you can achieve the same effect in love2d without "a lot of work"
Yes, that's why I didn't say "a lot of work". :)

But in Defold, where the rendering is all 3D by default (though the collision/physics is 2D) it's completely trivial: you probably don't have to write any code at all or use any special shaders or anything that isn't built into the engine. In LOVE you'll have to write or find a custom shader or library to deal with the 3D stuff. Depending on your skill level that may not be a problem, but it is, as I said, "significantly more work" than placing some objects and a built-in camera.

Defold has its issues and quirks, and you may have other reasons for wanting to use (or continue to use Love). If you're happy to learn a bit of math and like to have total control over how things work, then Love is a better choice. If you just want to place a bunch of sprites and have them rendered in 3D, and you don't mind the workflow imposed by a visual editor, then there are other engines which will serve you much better.
zorg wrote:
Sun Sep 16, 2018 10:03 am
Löve is a framework; what you accomplish with it is your business; it uses OpenGL, which is able to handle both 2D, 3D, or any Dimensions you want it to, be it 2.5 or 4.
That's like saying "all Turing-complete programming languages are equally powerful." It's obviously true in the theoretical sense, but in practice it's totally unhelpful, because there can be major differences in the suitability of different languages for different tasks. Even if you write a custom shader, you'd still (AFAICT) have to rewrite any drawing primitives that you want to use. You can't just magically pass
3D coordinates and angles to love.graphics.draw, love.graphics.circle, etc.


Edit: here you go. This doesn't handle scrolling the ground because that was more work and I couldn't be bothered. But it should get you started.

Code: Select all

local function groundToScreen(x, y)
	-- Apply any translation/rotation etc. first.
	-- Then do the perspective transform
	local z = 1 - cosAngle * y/h
	x, y = w/2 + (x - w/2) / z,  y * sinAngle / z
	return x, y
end

local function screenToGround(x, y)
	-- Undo the perspective transform first.
	local z = sinAngle / (sinAngle + y/h * cosAngle)
	x, y = w/2 + (x - w/2) * z,  y / sinAngle * z
	-- Then undo any rotation/translation etc.
	return x, y
end

function love.load()
	angle = 0.2 * math.pi
	cosAngle, sinAngle = math.sin(angle), math.cos(angle)
	w, h = love.graphics.getDimensions()
	groundShader = love.graphics.newShader([[
		uniform vec2 size;
		uniform float cosAngle, sinAngle;

		vec4 position(mat4 m, vec4 p) {
			p.z = 1.0 - p.y / size.y * cosAngle;
			p.y *= sinAngle / p.z;
			p.x = 0.5 * size.x + (p.x - 0.5 * size.x) / p.z;
			return m * p;
		}
	]])
end

local function standingRect(left, bottom, width, height)
	local pixelLeft, pixelBottom = groundToScreen(left, bottom)
	local pixelRight = groundToScreen(left + width, bottom)
	local pixelWidth = pixelRight - pixelLeft
	local pixelHeight = height * pixelWidth / width
	return pixelLeft, pixelBottom - pixelHeight, pixelWidth, pixelHeight
end

local function pointInRect(x, y, left, top, width, height)
	local inHorizontal = x >= left and x < left + width
	local inVertical = y >= top and y < top + height
	return inHorizontal and inVertical
end

local function mouseInGroundRect(x, y, w, h)
	local mx, my = screenToGround(love.mouse.getPosition())
	return pointInRect(mx, my, x, y, w, h)
end

function love.draw()
	w, h = love.graphics.getDimensions()
	cosAngle, sinAngle = math.cos(angle), math.sin(angle)
	love.graphics.setShader(groundShader)
	groundShader:send("size", {w, h})
	groundShader:send("cosAngle", cosAngle)
	groundShader:send("sinAngle", sinAngle)
	for y = 0, 11 do
		for x = 0, 15 do
			if (x + y) % 2 == 0 then
				if mouseInGroundRect(x * 50, y * 50, 50, 50) then
					love.graphics.setColor(0.4, 0.4, 0.3)
				else
					love.graphics.setColor(0.3, 0.3, 0.25)
				end
				love.graphics.rectangle('fill', x * 50, y * 50, 50, 50)
			end
		end
	end

	love.graphics.setShader()
	love.graphics.setColor(0.3, 0.2, 0.5)
	love.graphics.rectangle('fill', standingRect(250, 350, 50, 100))
end
--Josh

User avatar
Nikki
Prole
Posts: 18
Joined: Wed Jan 25, 2017 5:42 pm

Re: how to change cam perspective (fov && angle)?

Post by Nikki » Wed Sep 19, 2018 1:56 pm

Edit: here you go. This doesn't handle scrolling the ground because that was more work and I couldn't be bothered. But it should get you started.
Wow this piece of code is something great.
I was following that original link in OP's post https://forum.defold.com/t/view-like-in ... ed/12917/8
over there is link to some more explanation https://simonschreibt.de/gat/dont-starv ... arallax-7/

which shows the the upright rectangles/sprites have a small transformation to them swell.
Image

I feel funny asking it, but my shader and 3d skills are quite subpar, could you show this shader too?
I am trying to achieve it but failing miserably and hope you have it sort of at hand.


edit: I am thinking and experimenting a bit more with this upright rectangles nd am thinking it would be easier and lighter to just fiddle with the vertex data directly, because you would need to know the dimensions of the upright rectangle to calculate its deformation (its not like the ground only depending on the screen width and height), but I might be missing something.

JoshGrams
Prole
Posts: 29
Joined: Sat May 27, 2017 10:58 am

Re: how to change cam perspective (fov && angle)?

Post by JoshGrams » Thu Sep 20, 2018 8:52 pm

Nikki wrote:
Wed Sep 19, 2018 1:56 pm
the upright rectangles/sprites have a small transformation to them as well.
could you show this shader too?
I am trying to achieve it but failing miserably and hope you have it sort of at hand.
Yeah, that's an actual 3D perspective view. The tops of the upright rectangles are bigger because they're closer to the camera. If you want to do that in a vertex shader, you need the full 3D coordinates of all the corners. Otherwise how do you know which ones are "on the ground" and which ones are up in the air? Any x/y position could be interpreted as some position on the ground, so the shader can't tell.

And if you want actual 3D then you definitely want to use proper matrix math and just use a perspective camera matrix. It will be easier than trying to work out just the part of the math that does what you want. Even for the extremely simplified version that I gave, it almost wasn't worth the time it took me to work out the specialized math.

You might have a look at CPML for the matrix math? I haven't used it but it looks fine.

Matrices actually aren't that scary: they're just a coordinate system, with a vector for each of the axes, and one to say where the origin is. They're just usually described with tons of jargon (I apologize for my fellow mathematicians who have done such a poor job explaining things). If you want, I can give you a quick intro to how it all works.

But I'd just draw the upright rectangles without the deformation. It's probably not worth your time. And if you want 3D...as I said before, I'd use an engine designed for 3D. Obviously you can do it with LOVE, but it will take a significant amount of time to build the tools that you would have already available in something like Defold (which also uses Lua and works on most platforms). Do you want to spend your time making games, or do you want to spend your time working around the problems caused by using the wrong tool for the job? I'm not trying to sell you on Defold in general: I tried it and then came back to LOVE because it's more my style. But for learning 3D it'll be easier than trying to learn and build everything from scratch. And as much as I love LOVE, it's not yet (and maybe ever) an efficient or easy-to-use tool for making 3D games. That example I posted may look cool, and look very simple, but that's because it is a solution to a very carefully chosen and extremely limited problem, and it has tons of limitations. Trying to extend it to do fancier things is likely more trouble than it's worth.

--Josh

Post Reply

Who is online

Users browsing this forum: No registered users and 10 guests