Gui in 3d?



Quick question hopefully with an easy answer: i’m making a game entirely out of GUI nodes, and I was wondering if it would be possible to render GUI nodes using a perspective camera. I guess I’d have to make some changes to the render script. Is this an impossible dream?

Basically I want to set my level select screen up so that each level is in a book that the player opens. The only thing i need to do is rotate the book cover when the player clicks on the book.

I might try doing it in 2D and cheating, but if i can just use a perspective camera, that would make things a lot easier.



You should be able to draw a custom GUI render predicate to a render target which shares a texture with a GO/sprite that can then be orientated around in 3D space.



Mm hm. Mm hm. I know what some of those words mean. I will have to investigate but i think i will just find another way of doing this, because i have no idea how to even start doing that.



Okay… another quick fix would be to render GUI behind GOs. That would be easy to change in the render script, right? just move the GUI render stuff up to the top.



Yes, that shouldn’t be a problem I think



Okay, I have to admit that i was actually hoping for some practical advice. I’ve got @ross.grams rendercam, but it’s not rendering sprites at all and 3D rotated gui nodes are rendered. I am looking at the rendercam script but i don’t understand any of it. I’ve also never dealt with materials before.

For now I will try using stencils, clipping and ingenuity to make this in 2D.



You should study each part one at a time, you will get it. Like how to use render targets would be good to play with. Here’s a sample (1.0 MB)

Then another thing to learn how to do would be to render something to a render target texture resource that is also used by a sprite. It should be possible. :smiley:

1 Like


Like banksy said: if you learn how to cheat, you never have to learn anything else!!!

Here’s my solution using just two additional GUI nodes and 3 additional animations (compared to animating rotation.y of a single one gui node).

There’s still some stuff i need to fix:

  • I’d like to improve the easing.

  • I’d like to adjust the scale.y for each letter of the front cover individually, which will involve creating one letter per label. but that’s not hard

  • I’d like to not cheat a little bit: the scale.y of the triangles at the top and bottom of the cover continue to increase even once the Y rotation has passed 180 degrees. Ideally, I’d like to automatically do some maths that calculates the scale of those triangles according to the scale.x of the cover, but maths makes me sad especially when i have to calculate curves.

  • Code

      				--start the anims!
      			local halftime = 0.8
      			local bookdelay = 0.2
      			local height = 90 -- perspective
      			local textfade = 0.7 -- between 0,1. It's a divider.
      			local easing = gui.EASING_INOUTSINE
      			--whole node anim
      			gui.animate(v, "scale", 1, go.EASING_OUTCUBIC, 2)
      			gui.animate(v, "position", vmath.vector3(self.screenwidth/2, self.screenheight/2, 0), go.EASING_OUTCUBIC, 2, 0, stateup)
      			--book opening anim
      			gui.animate(gui.get_node("covertext1"), "color.w", 0, gui.EASING_INQUINT, halftime*textfade, bookdelay)
      			gui.animate(gui.get_node("cover1"), "scale.x", -0.3, easing, halftime, bookdelay)
      			gui.animate(gui.get_node("toptriangle1"), "scale.y", height, easing, halftime, bookdelay)
      			gui.animate(gui.get_node("bottomtriangle1"), "scale.y", height/2, easing, halftime, bookdelay)
  • vid:

1 Like


…basically, I need to know the function by which

if x = 1 then y = 0
if x = 0 then y = 1
if x = -1 then y = 0

and yes i know it’s related to SIN COS and TAN but I found maths class difficult (due to constant distractions by an amateur rapper called MC whitesnake who used to sit next to me)



Hmm, there’s a few questions that require long answers in this thread…

Render Predicate - This just means a group of things that get rendered together. If you open a material file, at the bottom it will have a tag set. Sprites and things have the “tile” tag, gui has the “gui” tag, etc.

In your render script init() you will see this:

self.tile_pred = render.predicate({"tile"})

…which defines a predicate of all things with a material with the “tile” tag. When you want to draw that stuff, in your render script, you do:


Drawing GUI in persective
Yeah, theoretically you could just move render.draw(self.gui_pred) up to where sprites are drawn (next to render.draw(self.tile_pred)), in your render script. I’ve never actually tried it though, so it may mess up. GUI nodes ignore their Z position…I’m not sure how that would work with a perspective camera. I would suggest using game objects and sprites or models instead, unless there’s a reason why you must use GUI. If all you’ll ever need is the book cover, faking it with two triangles is a good idea.

"Flipping" 0-1
(1 - x) is the function you’re looking for.
1 - 1 = 0
1 - 0 = 1

1 - 0.5 = 0.5
1 - 0.25 = 0.75
1 - 0.75 = 0.25, etc.



Hi Ross!

Thanks so much for your detailed answer. I realised after what Pkeod said that it would involve a lot more knowledge than I have right now; and I have so much other stuff I should learn before i get into rendering. And, as you said, faking it with triangles wasn’t too hard.

I didn’t fully explain the flipping thing, but I have now realised that what I need is something like math.cos(X*math.pi) in order to calculate the curve by which to scale the height of the triangles, as well as the height of the letters, which I will also distort according to their X position.

I do have just one more quick question: in my updated version, I animate the scale.x of the GUI node that works as the book cover, and then in my function update(self, dt) I set the height of the triangles using math.cos(scale.x*math.pi). But the thing is, that’s the only thing in my update function. and I’d like to know if I could eliminate the need for an update function by somehow only changing the height of the triangle during the animation.