I new to game engines . I have some basic questions :
If I have say , 200 polygon2d
nodes then are all of them re-rendered every frame ?
How can I know if a Node was redrawn ? Is there a method that is called before a node is redrawn ?
Is there a way to prevent a Node from re-rendering ?
Are all nodes rendered every frame even if they aren't changed ?
- Edited
- Best Answerset by druboi
druboi If I have say , 200 polygon2d nodes then are all of them re-rendered every frame ?
Yes, but the engine employs a number of optimizations to draw only what is actually needed.
How can I know if a Node was redrawn ?
If it's on screen - it is redrawn.
Is there a method that is called before a node is redrawn ?
_process()
is called every frame. You can track the visibility of a visual node using visibility notifications and enable/disable the _process()
accordingly. Note that for 2D (i.e. canvas items) there are two stages to "drawing it". One is creating its final texture (which may not happen every frame depending on the node type) and other is putting it onto final framebuffer (which happens every frame if the node is visible by the camera i.e. not culled). The former you can intercept by draw notification while the latter you can't.
Is there a way to prevent a Node from re-rendering ?
What exactly you're set to accomplish here?
I was changing the window size and new polygon nodes are create for every _on_resized
call.
As the polygon count increase the fps drop. It old nodes don't change however , so I was if there if any optimisation I could make there.
Thanks !
- Edited
druboi
You're creating nodes in _draw()
?
Best to post the minimal version of your _draw()
function that still causes the problems.
How and when _draw()
is called is determined by the engine. If it thinks it's time to redraw the node that has custom draw implemented - it will call it. Note that this also depends on the stretch mode in your project settings. If it's disabled, every window resize will trigger redraw.
- Edited
Just drawing circles of random radius. I want to prevent it from redrawing when the screen resizes. Is it possible in someway with saving the random values ?
`
func getRandomRadius()->float:
return float(randi_range(10 , 30))
func _draw() -> void:
var radius = getRandomRadius()
var pos := Vector2(radius , 30.0)
while pos.y < size.y:
print("pos",pos)
draw_circle(pos , radius, Color.MAROON)
radius = getRandomRadius()
if pos.x + 10.0 + radius < size.x:
pos += Vector2(radius + 10.0 , 0.0)
else:
pos = Vector2(radius , pos.y + 70.0)
`
- Edited
druboi Generate the radius sequence in _ready()
and store it in an array so _draw()
can read from it.
Alternatively, use RandomNumberGenerator object
If you initialize if with the same seed before starting to draw, it will always produce the same sequence of pseudorandom numbers.
druboi look into
https://docs.godotengine.org/en/stable/classes/class_resourceuid.html
xyz its as related as - "Can you make me a sandwich?"
@kuligs2 Thanks ! I'm new to this , no need to make a meal of it.
@xyz As I understand then there is no way to "bake" what I have already drawn on to a "canvas", so that further draw calls don't have have re-render the past drawing. In ProcessingJS , you have to call background() to clear the screen before every draw call , I was trying something similar.
I think Subviewport have an update option to additively render to the canvas. But I can't get it to work , is this possible ?
Thanks again !
- Edited
druboi Yes, you can do only one time drawing with subviewports. But I'm pretty sure your goal is achievable via less involved means. Today's graphics hardware can do a lot and it's built to perpetually redraw frames. Drawing 200 things each frame is pretty much nothing for a modern GPU.
If you want more specific suggestions, describe your actual final goal, not your attempted or presupposed solutions.
Conceptually, game engines are somewhat different from rendering frameworks like Processing. In a sense, Processing is much more primitive and low level. It's just a rendering api that doesn't keep any persistent state of drawn objects between frames (unless you manually code it). Game engines, on the other hand, are designed specifically to maintain such state, in a form of scene graphs, nodes etc...
Engines mostly spare you from dealing with explicit draw calls. That's the engine's responsibility, and in fact one of the main benefits of using an engine. You only need to manage "high level" persistent objects.
So if you need to show 200 things, just instantiate 200 objects (e.g. Sprites nodes) into a scene and let the engine take care of drawing them. It will do its best to optimize the draw calls.
- Edited
I have been trying to implement some processing sketches in Godot. I realise now that almost all sketches in Processing re-render the whole drawing every frame , (except some painting algorithms). I understand that despite the urge to , I shouldn't try to over optimise by trying to reuse what was rendered earlier because that is not how GPUs work. So your explanation is spot on and very helpful.
Thanks again for your time !
@xyz
I have question related our discussion . Say I create a visual using a Shader , say something like a shadow or a shape using equations. If I am using this visual as a static graphic , then is it more performant for me to create a texture out of the shader output and use that instead ? or does Godot already do that under the hood ?
- Edited
druboi Depends on how complex the shader is. In most cases it's actually ok to just run the shader frame-to-frame. Only if the shader does very complex/lengthy code (that hinders realtime framerate) and the generated image is not meant to be changed or animated. But in that case why use realtime shaders at all? You can pre-render the thing in a 3D app whose shaders are even more versatile than gpu shaders.
If a shader is assigned to an object in Godot, it'll run every frame. In fact shaders are the thing that render the frame. If they don't run - nothing is drawn.
Again, today's graphic hardware is made for brute force. You can throw a lot at it without hearing it complain