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

MultiMesh2D + Line2D or Polygon2D changes color of MultiMesh #40901

Closed
tavurth opened this issue Jul 31, 2020 · 6 comments
Closed

MultiMesh2D + Line2D or Polygon2D changes color of MultiMesh #40901

tavurth opened this issue Jul 31, 2020 · 6 comments

Comments

@tavurth
Copy link
Contributor

tavurth commented Jul 31, 2020

Godot version:
Screenshot 2020-07-31 at 13 22 09

OS/device including version:
Screenshot 2020-07-31 at 13 22 21

Issue description:
When adding a MultiMeshInstance2D after a Line2D or Polygon2D node, the color of the MultiMesh changes (becoming more faded).

An example repository can be found here

Actual result:
Screenshot 2020-07-31 at 13 24 20

Expected result
Screenshot 2020-07-31 at 13 24 25

Expected result can be achieved by changing the order of the nodes (i.e. put the MultiMesh instance before the Line2D)

Expected result can also be achieved by setting "Show Behind Parent" to true, but this does not work in all cases.

Expected result can also be achieved by setting the color to Color(3, 0, 0, 1), although Color(2, 0, 0, 1) still leaves the MultiMesh looking dimmed.

Note that the Line2D and Multimesh can be anywhere in the tree (any depth), as long as the MultiMesh is rendered later than the Line2D this effect occurs, causing this to be particularly difficult bug to track down.

@tavurth
Copy link
Contributor Author

tavurth commented Jul 31, 2020

After some experimentation the color of the Line2D/Polygon2D seems to directly modulate the MultiMeshInstance2D color.

To reproduce this drag the color picker for the Line2D around. When white, the MultiMesh will be coloured normally, but in other cases, such as a bright blue, the MultiMesh will have a color difference.

My temporary fix for this will be to add a single Line2D, placed between the first Line2D and the MultiMesh in the node tree. Two points, color white.

Screenshot 2020-07-31 at 20 54 14

This effectively resets the color modulation which is set by the first line.

Edit: I've now tested with Polygon2D and found the same result. It seems likely that somewhere we're not setting the color back to white after modulating to draw the polygon.

@tavurth tavurth changed the title MultiMesh2D + Line2D changes color of MultiMesh MultiMesh2D + Line2D or Polygon2D changes color of MultiMesh Jul 31, 2020
@tavurth
Copy link
Contributor Author

tavurth commented Aug 8, 2020

After doing some more testing and digging through the sources, it appears that this issue is not present with other kinds of 2D nodes such as Sprites or Meshes, just the multi-mesh.

I was looking here, and here

However, the likelyhood of this area being the problem is reduced as If multimesh.set_instance_color is called during setup, and then another line is moved in behind it afterwards, the problem persists. (The code there is also simple enough that I don't see a bug if there is one)

I would suggest that there's some place we draw the Multimesh, and we forget to reset the modulation at the beginning of the draw loop. However I've not found it yet as I'm unfamiliar with Godot's source.

After looking some more I found that mm->modulate is not set in the RenderingServerCanvas::canvas_item_add_multimesh method, but rather in the gles2 rasterizer for canvas modules.

However beyond that I'd assume that INSTANCE_ATTRIB_BASE + 3 is somehow not setting the color properly. Without any color set on the MultiMesh instances, the color should be drawn as white (glVertexAttrib4f(INSTANCE_ATTRIB_BASE + 3, 1.0, 1.0, 1.0, 1.0);) but this does not seem to be happening.

I'd assume therefore that the attribute used to pass the color is being improperly mixed inside a shader somewhere, but I'm not sure which or where to look.

Hmm, seems like this part is relevant:
https://github.com/tavurth/godot/blob/master/drivers/gles2/shaders/scene.glsl#L353

@clayjohn
Copy link
Member

clayjohn commented Aug 8, 2020

Great work! It looks like many draw commands start with a line like this (from regular mesh drawing):

glDisableVertexAttribArray(RS::ARRAY_COLOR);
glVertexAttrib4fv(RS::ARRAY_COLOR, r->modulate.components);

Copying this into the multimesh command should solve this

glVertexAttrib4f(RS::ARRAY_COLOR, 1, 1, 1, 1);
glDisableVertexAttribArray(RS::ARRAY_COLOR);

@tavurth
Copy link
Contributor Author

tavurth commented Aug 8, 2020

glVertexAttrib4f(RS::ARRAY_COLOR, 1, 1, 1, 1);
glDisableVertexAttribArray(RS::ARRAY_COLOR);

Thanks for the hint! :) I'll try build it on Godot 3.x (as my sample repo doesn't work yet on 4.x) and get back to you!

@tavurth
Copy link
Contributor Author

tavurth commented Aug 8, 2020

Sadly adding the above lines to the start of the render process in the Multimesh switch did not fix the issue:

Screenshot 2020-08-08 at 10 28 48

I think it's because a few lines lower we specifically enable color vertex attributes based on the users node configuration?

If so, bypassing this would break (I assume) the modulation ability of the Node2D parent class. Any thoughts?

@clayjohn
Copy link
Member

Fixed by #47582

@clayjohn clayjohn added this to the 3.4 milestone Aug 23, 2021
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

3 participants