Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inconsistent and buggy rendering using draw_set_transform() #49156

Closed
djrain opened this issue May 28, 2021 · 4 comments
Closed

Inconsistent and buggy rendering using draw_set_transform() #49156

djrain opened this issue May 28, 2021 · 4 comments

Comments

@djrain
Copy link

djrain commented May 28, 2021

Godot version:
3.3.2 stable

OS/device including version:
2020 Mac Mini
macOS Big Sur

Issue description:
Basically, calling draw_set_transform() outside a loop causes buggy rendering compared to inside the loop, even when it shouldn't make any difference.

In this example scene I have a Polygon2D, a Light2D, and a Node2D (called CircleRenderer). CircleRenderer has the following script which should simply draw a green circle over every point on the Polygon2D. Note that the polygon is positioned at (500, 500), while CircleRenderer is at the origin.

extends Node2D
tool

func _process(delta):
	update()

func _draw():
	var poly = $"../Polygon2D"
	#draw_set_transform(poly.global_position, 0, Vector2.ONE)
	for point in poly.polygon:
		draw_set_transform(poly.global_position, 0, Vector2.ONE)
		draw_circle(point, 50, Color.seagreen)

As it is, this code works as expected.

Now suppose I swap the call to draw_set_transform() with the commented out one. This should have the same effect, except for maybe being more efficient. When I do this however, the circles still draw in the correct positions, but weird things happen with all the circles after the first: the Light2D ceases to interact correctly with them, and also, the circles will suddenly disappear if the editor is zoomed in close enough and/or moved far enough. Both behaviors are shown here:

Screen.Recording.2021-05-27.at.5.56.33.PM.mov

Also, for some reason, this only seems to happen if the polygon's position is positive.

The rendering at runtime is the same. Issue is present in both GLES2 and 3, with or without batching.

Steps to reproduce:
Play with MRP example scene

Minimal reproduction project:
DrawSetTransformBug.zip

@lawnjelly
Copy link
Member

Simpler reproduction project, the poly and the texture rect aren't needed. Just move the 2d light and you get the light going off prematurely as you move it down:
djrain_DrawSetTransformBug.zip

func _draw():
	draw_set_transform(Vector2(0, 500), 0, Vector2.ONE)
	draw_circle(Vector2(500, 0), 50, Color.seagreen)
	draw_circle(Vector2(500, 200), 50, Color.seagreen)

I suspect this is something to do with AABBs being calculated wrongly in this situation.

@lawnjelly
Copy link
Member

The problem is in this test:

p_ci->global_rect_cache.intersects_transformed(light->xform_cache, light->rect_cache)

The global_rect_cache appears to be incorrect for the transformed circles.

@lawnjelly
Copy link
Member

Got it.

rasterizer.h, line 1046, in get_rect():

				if (found_xform) {
					r = xf.xform(r);
					found_xform = false;
				}

This is a loop where it goes through the commands to find the bounding rect. The problem is that is only applying the transform to the first command, then sets found_xform back to false, which is incorrect, because the transform also applies to later commands. The fix will probably be to just remove this line. I'll do some testing and see if this works.

@akien-mga
Copy link
Member

Fixed by #49160.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants