Rendercam - Universal Camera Library

Hey all!

I finally got sick of rewriting render scripts, camera functions, and screen-to-world transform code over and over again (and hearing of other people doing the same), so I’ve put together a library to handle all the basic camera types that I could think of and most of the common camera-related functions. It’s similar to Defold Orthographic, only it supports perspective cameras too.

Rendercam gives you a simple render script, a camera game object, and a controlling lua module. Together they support:

  • Perspective and Orthographic cameras
  • Fixed aspect ratio viewports (or not)
  • Setting a specific world-space view area
  • Four options for how the view changes for different resolutions and window sizes
  • Switching between multiple cameras
  • Zooming
  • Panning
  • Shaking
  • Recoil
  • Lerped camera following
  • Screen-to-world transforms
  • Screen-to-world-ray transform for full 3D games
  • World-to-screen transform, with an option for each GUI adjust mode

It’s very simple to use, just install the library (dependency link), hook up the render script, and add the camera game object. All the camera settings are just properties on the camera’s script component. See the github page for full documentation.

Disclaimer:
At this time I’ve only just “finished” the library. Consider it a beta. I think I’ve tried all the features with my small test project (which you can grab from github if you want), and everything seems to work, but it hasn’t been through a “real world” test yet. So, if you feel like trying it out, let me know what you think! I’m sure there are things that need improving. I plan to do some small trial projects with it myself, but I would really appreciate some outside feedback. Thanks!

36 Likes

Fantastic! Thank you for sharing this.

2 Likes

Sounds great!

but, I am not sure, doesnt britzl also made something similar already?

1 Like

I’ve created a camera solution for orthographic camera projections only. Ross’ solution works for both.

3 Likes

This sounds great! I was looking for a perspective camera :slight_smile:

I tryed your example but dont understand how i get things to draw on different z values. The model seems to be only a rectangle.
I also played around with camera settings but didnt see any changes.

Maybe a more detailed example would be great in future.

2 Likes

Ah, Sorry! Yeah, that example is not really designed as a tutorial, just my own test-bed. I’ll do a real one ASAP!

However, that example: The starting camera is orthographic. The model is mostly in front of the origin, so if you set the “nearZ” of the camera to a bigger negative number you can see more of it. Also, use the 1, 2, and 3 keys to switch between different cameras. Mouse wheel to zoom, and middle-click-drag to pan around.

Also, based on a little FPS test I just did, I pushed a commit that changes one of the settings so it makes more sense for 3D cameras.

. . . It’s a bit of a challenge to deal with 3D stuff since the editor is only 2D . . .

2 Likes

OK, I updated the example project a bit. Hopefully now it’s somewhat helpful. I plan to polish it more and add some more camera types and maybe little controllable demos, but that will take more time.

I also started a little FPS test. It was only a matter of minutes to set up the camera and start moving things around. Thanks to d954mas for the mouse lock extension from his Save Shelter game, which makes mouse-look control possible!

rendercam_fps_test_2

12 Likes

Great job with this! I’ll switch to using this in my materials projects. I want to contribute a third person example with a character walking around and some collision shapes for colliding with the player and with camera blocking volumes. There’s a talk on GDC talk on camera mistakes with some things I want to implement https://www.youtube.com/watch?v=C7307qRmlMI There is also dynamic camera style features which could be made such as https://forums.unrealengine.com/community/work-in-progress/41262-market-place-dynamic-camera-system-ala-god-of-war-early-demo https://www.youtube.com/watch?v=4Z_ds-aMG0c Then also 3D space spline based camera rails. I want to make these kinds of things but if others beat me to it I wouldn’t be upset. :angel: Once there are more examples like this out there, then it will get more developers who want to make 3D game to give Defold a chance.

There are only a few features left before Defold is really ready to make 3d games… editor 2 better 3d support in viewport, better collision shapes, procedural mesh generation, cubemaps working, navmesh solution… then some more wishlist features like built in decal support, culling, better animation blending, baked lighting, a light model / built in pbr, a modular shader system like glslify with a blueprint like editor, and so on. Future is super bright!

Something interesting happening here?

7 Likes

Thanks Pkeod! Yeah, it’s possible I will beat you to some of those things, and possibly not. Some of those have been on my mind too, but there are always way too many projects to work on!

Haha, that’s a lot of things! I don’t think Defold will be competing with Unreal or Unity anytime soon, but we can dream. Dynamic cast shadows is one of the big things I see missing on the rendering side.

Yeah, I noticed that rendering bug (hard to miss it), but haven’t committed a fix yet. It only happens if the background grid sprite is in “Add” blending mode, only with the perspective camera, and only in that quadrant where the sprite is closer to the camera than the model. For some reason Defold likes to get stuck in the wrong blending mode in some situations. It’s easily fixed by resetting the blend func by hand after sprites are rendered, though I’m not sure why that’s necessary. There’s a bug report in here somewhere . . . :confused:

3 Likes

For certain 3D projects Unity or Unreal are extreme overkill and introduce unnecessary overhead. I’m hopeful that Defold can take up use for those kinds of projects but even quality matching a AAA game being produced with Defold should be possible if the parts come together.

5 Likes

oh nice! Proper camera setup is so nice. We’ve just had a workshop in a team, and 3D support is something that gonna get lots of attention from the dev team. Is does motivate us a lot what our community shares on the forums and especially on the Asset Portal.

So please don’t be shy. Each cool small piece you share really does matter to the team.

6 Likes

@Oleg_The_Evangelist Cool! I think better support for 3D materials and things can help 2D projects too. The threads I’ve seen about 2D lighting seem to have gotten stuck on some of this stuff. It’s also motivating for me (us?) to have such great support from the Defold team!

A couple updates:

  • I added a screen_to_world_plane function which makes screen to world transforms much more convenient for 3D cameras. Just give it screen_x, screen_y, define a plane with a normal vector and any point on the plane, and bingo! You get the correct point on that plane no matter how the camera (or the plane) is angled.

  • I put it up on the asset portal!

9 Likes

Hello @ross.grams. First of all Rendercam is great. Thank you, I love it.

I would like to use a shader with it. Nothing fancy. Lets say Grading (https://www.defold.com/tutorials/grading/)
Looks like it is possible. It “looks” (not sure if it works correct and efficient) fine until I resize the window. I don’t know much about the shaders but I guess setting view and projection cause a problem.

How can I handle the update correctly with Rendercam?

function update(self)
	
	-- Set view and projection with latest matrices calculated by the module
	render.set_view(rendercam.calculate_view())
	render.set_projection(rendercam.calculate_proj())

	-- Set viewport (x and y will be zero unless using a fixed aspect ratio)
	render.set_viewport(vp.x, vp.y, vp.width, vp.height)

	-- ** Render Target
	render.enable_render_target(self.target) 
	
    render.set_depth_mask(true)
    ...
	-- GUI Rendering
	...

	-- ** Disable Render Target
	render.disable_render_target(self.target) 

	render.clear({[render.BUFFER_COLOR_BIT] = self.clear_color}) 

	render.set_viewport(vp.x, vp.y, vp.width, vp.height)
	render.set_view(vmath.matrix4()) 
	render.set_projection(vmath.matrix4())

	render.enable_texture(0, self.target, render.BUFFER_COLOR_BIT) 
	render.draw(self.grade_pred) 
	render.disable_texture(0, self.target) 

	
end
4 Likes

Thanks Selim! I’m glad this is making life easier for some people!

When you create your render target you give it color_params and depth_params tables, and both of these contain width and height values. Those need to be updated if the window changes size. I’m definitely not an expert on this and it’s been a while since I messed with render targets, but the way I did it last time was to delete and recreate the render target with the new width and height. However, there is a render.set_render_target_size function which sounds like it should do the trick without any rigmarole (but I haven’t tried it).

I will take a closer look at this tomorrow and make an example project for you, if you don’t figure it out first.

4 Likes

Thank you @ross.grams. Looks like “render.set_render_target_size” do the trick :slight_smile:
But if it’s not too much trouble, I love to see your example for better understanding.

Some results…

Terrible bloom:

Color grade:

B&W:

Original:

13 Likes

Love the gfx!

2 Likes

Thank you @britzl
Still got lots of things to do :expressionless:

2 Likes

Nice! Looks cool.

Here’s my little demo project: (Also a “technical demo” for @sven, for my lighting and line-of-sight setup. A follow-up for that Simple 2D Lighting thread.)
-original link removed- (it crashed everywhere except on windows)
Updated working project link: rendercam_targets_lighting_3.zip (432.1 KB)

6 Likes

I’m getting the following error on OSX

WARNING:GRAPHICS: ERROR: 0:43: ‘’ does not operate on ‘vec4’ and 'int’
ERROR: 0:45: '
’ does not operate on ‘int’ and ‘vec4’

Changing from int to float (2->2.0 and 4->4.0) on line #43 and #45 in render_target.fp solves the above problems but results in a crash:

ERROR:GRAPHICS: gl error 1282: invalid operation

2 Likes

Ach, yeah sorry, I’m not as careful as I should be about keeping numbers floats instead of ints in shaders. On windows it doesn’t seem to care at all. But it still crashes for you after that’s fixed, eh? That’s a problem . . . A google search for that error didn’t turn up anything specific, though maybe some relation to reading multiple textures . . . It’s a pain that I don’t get these errors myself. Does Defold use different OpenGL versions based on the system?

1 Like