-
-
Notifications
You must be signed in to change notification settings - Fork 21.3k
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
GLES2 Batching + CPUParticles2D texture + Label = Rendering issue on iOS #38318
Comments
[Additional context/notes that are semi-related to the issue, but might not be directly related] I also just wanted to add some more info in case it helps. I've noticed some more issues with regards to using CPUParticles2D in 3.2.2.beta1 with the new "Use Batching" ON. If I use textures as my particles they seem to render very strangely. Sometimes they are rotated 90 degrees, sometimes they flicker on screen, sometimes they glitch out. Basically the rendering of texture particles seems very unpredictable. It works fine in 3.2.1.official and it works fine with "Use Batching" turned OFF. Sorry I can't provide any more specifics because I'm not 100% sure what all the causes are. My main project is much too complex to break down into tiny chunks. So the project I included in my main post above is only one sample project where I was able to reproduce some issues with the label. I guess I'm mainly adding this additional anecdotal context because hopefully it helps someone narrow it down. There definitely seems to be something strange happening with GLES2 + iOS + CPUParticles2D (with textures) and the new GLES2 batching feature in 3.2.2.beta1. So it might be worth digging into this specific intersection of components to see if anything stands out. Maybe someone who knows more about the new batching feature might have some insight on this. I'm happy to test other configurations and settings in my main project if it's helpful. Let me know if you need further information. Thanks! |
I also have an issue with CPUParticle2D on iOS before batching. #32837 |
Yes there do seem to be some pre-existing (non batching) bugs on iOS with CPUParticle2D, see #38211 also. I'll be investigating this soon (I have some fixes to push first). It may be tricky because I don't have iOS hardware etc, I'll have to use detective work, so may need some help at some point. @volzhs issue does look related, looks like it may be a state change / shader conditional that is getting out of sync, however the fact it is iOS only is interesting, that narrows it down a bit. Edit: Looking at the other issue #34637 I think it is unlikely to be a coincidence. I think the batch draw method, the ninepatch and other drawing methods are causing some interference. Possibly the texpixel_size uniform, I have to look at the shader for the particles. |
I had foolishly assumed particles were being drawn as rects, but they are multimeshes. Here is a frame diagnosis log for the project, the first item is a single multimesh, the second, a batched set of 5 rects (the text):
The interesting thing is, that the particles are being drawn BEFORE the text, and yet it is the particles that are drawing incorrectly when the text is present. This is leading me to believe that this (and similar bugs pre-existing) are due to iOS perhaps having a different set of OpenGL state defaults at the start of a frame, or not resetting the GL state where other devices are. If this is the problem it should be fairly easy to fix by ensuring some consistent GL state at the beginning of a frame. Well I say easy, but not entirely easy because I don't have one of the devices! 😁 Anyway I'll see whether we can systematically set everything in OpenGL to some default state at the beginning of a frame, that may be the answer. |
@lawnjelly when PR comes for this, I will test it on my iPad. 😄 |
Incidentally we can get a good idea whether it is the same issue as #32837 simply by replacing the text with a nine patch rect in this minimum reproduction project. And try with and without batching. If the theory above is correct it should show it showing the same behaviour with a nine patch rect, with or without batching. Not sure yet whether the order matters, particles or other primitives first. |
Just to confirm, are these other issues also occurring on iOS only, or on the desktop as well? Any issues that occur in the editor are far easier to debug (and indeed may have been fixed already). If they are iOS only as well, they could all be related as part of the iOS 'mega issue'. 😬 |
Me and @clayjohn have been discussing it, and we are suspecting it could be a UV issue in the particles, I gather you can make a custom shader? If so if anyone could make a shader that just interpolates red across the U value, and green across the V, or something like that, that will let us know whether the UVs are varying correctly over the particles? 👍 |
Here you go, Please attach this to your CPUParticles2D node and let us know what happens.
If our hunch is right, each particle will be a solid blue square. |
Yes all these issues I've only seen on iOS. Sorry I should have been more clear. I just tested it in an iPhone simulator (running from XCode) and the bug is reproducible there too. So that should be an easier way for you to test, you don't need to build on a hardware iPhone. None of the bugs I saw were present when running directly in Godot. I've only seen the issues on a hardware iPhone, hardware iPad, and iPhone simulator. I also tested a desktop MacOS build and the bug was not there either. I haven't tested Android at all (maybe someone else with an Android can test?). But so far it seems specific to iOS. |
Great work @nebs, really appreciate it. We are getting closer! So we now know it is the UVs, and also isn't purely a hardware issue. I have tested on Android and couldn't get it to occur there. Given that it appears in emulator that is pointing the finger towards a different state reset policy on new frames in iOS. |
Just a wild hunch, try changing the last letter of the text and see if the color changes. One idea @clayjohn suggested is that it is a 'leftover' UV from the last thing drawn (we are trying to work out why the UV would be that particular value). |
Ok so here's another strange update. So I noticed that in my game I'm seeing weird CPUParticles2D issues even when I hide the label. I also noticed in my game I use tilemaps. So I tried adding tilemaps to this test project and I was able to reproduce some more weird rendering. This time the particle textures are rendering, but it appears the UV is offset a bit which causes it to look off. Here's the updated sample project with a new tilemap that you can toggle: Here are screenshots from my tests. In these tests the Label is hidden. Only the tilemap and the CPUParticles2D are shown. The tilemap is behind the particles. If UV Shader applied and TileMap is hidden. [Looks Ok] If UV Shader applied and TileMap is visible. [Notice the colors look more desaturated, like the UV coordinates are offset] If shader is removed and TileMap is visible [Notice how the little godot guy is cutoff, suggesting again the UV is offset] I'm not sure if this is the same issue or something else. I'm happy to open a separate issue to keep things organized. But I figured this might be helpful here. So it looks like there's two ways to generate two slightly-related bugs:
|
I think they may be both manifestations of the same bug. @clayjohn noticed there was actually a slight gradient in your earlier example, and we were wondering whether there was a relationship with the UVs used to render the font for the text. |
I changed "HELLO" to "HELLA" and the color looks the same. But maybe there's a very subtle shift that I don't notice. Is that what you meant by changing the test? Or something else? |
Yup that's it. I checked in gimp and they may be subtlety different, it is harder to tell because of the rotation. Ah fantastic with the second screen shot, that really shows it! 😁 I'm off to bed now but I really think we are pinning this down, @clayjohn is looking at the glVertexAttrib calls to see if we are forgetting to reset. Many thanks and will catch again in the morning! |
@lawnjelly Here is one candidate: godot/drivers/gles2/rasterizer_canvas_base_gles2.cpp Lines 644 to 647 in c8ea779
This is in _draw_gui_primitive which is used in many of the drawing commands (including rect drawing). It doesn't have an option to disable the uv array when uvs are not used like other functions (draw_polygon for instance):godot/drivers/gles2/rasterizer_canvas_base_gles2.cpp Lines 440 to 447 in c8ea779
|
Thanks to #38346 for pointing me along an avenue to check, I've been looking at the CPUParticles2D::_update_particle_data_buffer() and it turns out that ptr[8] at least is containing I'm not sure whether this goes to the shader yet, but it is possible that the particle sending duff data could trigger strange errors on some hardware. Yes, I think it is getting sent as part of the vertex format. I'm guessing the Edit : Ah, may be false alarm, as it is compressing the color into a float, hence showing up in the debugger as CORRECTION |
One other thing I noticed with CPUParticles2D is that textures appear rotated 90 degrees when running on iOS and GLES2. This was happening even in older versions of Godot before the batch rendering stuff. I'm not sure if it's related to this bug or not but I thought I should mention it here in case it's useful information. If this is completely unrelated I can file a separate issue later. |
It could well be related, I think it is highly likely this whole class of bug is the same, and exhibits in different ways. I'm currently of the opinion that although it appears when you switch batching on, the bug may not be IN the batching... i.e. it is the same bug as the previous ninepatchrect bug (which has exact same visual results), and it was pre-existing and just happened to be hidden in some situations previously (i.e. it is likely to be a bug in the multi-mesh / particle code). |
Thanks for the quick response and work on this! I tried out #38378 in my local fork and built my test project under 3.2.2.beta.custom_build.8426ed265. Unfortunately it seems like the original bug is still there (the particles appear as a flat color when a label is present) when testing on an iPhone. I'm not sure if that PR was meant to solve that particular bug so if not then disregard this message, I just wanted to report my findings. I should note that I used the export template from 3.2.2.beta1 because for the custom build there's no download for it, so I'm not sure if that has any impact. Let me know if there's anything else I can do to test it out. Thanks again for all your work on this! |
@nebs You need the updated export templates to test the changes. If you use the 3.2.2.beta1 templates, then the code that runs on your device does not include anything after 3.2.2.beta1. That being said, #38378 is unlikely to have caused your particular issue, but we have a few ideas about what it might be. Stay tuned. :) |
Oh I see my bad, I wasn't quite sure what export templates were for. Thanks for clarifying. |
@nebs No problem, its good for you to learn now because we are going to need you to do a lot of testing. :P Neither of us have any IOS devices to test on. |
Haha. I'm definitely happy to help test this out on my iDevices. But in case you guys want to test it quicker, I was able to repro the bug in an iPhone simulator too so you should be able to test it even without an iOS device. |
@nebs referring to the images you posted in: I'm wondering if the offset UVs are the same or related to the UVs used to render the rect in the tilemap (the thing that looks like a bit of hay). This is what appeared to be happening with the text and the the blue color. It could be somehow reading the UVs from the previous VB (if the UV attribute call failed), or there could be an offset applied in the shader. It could be that when particles do work in iOS, it is only by accident (i.e. the UVs or offset coincidentally contained range 0 - 1). Stream of gibberish debugging thought, probably only of interest to clayjohn...Actually now I look at it, there are no UVs in the particle vertex format. The gravy thickens! 😁 Where do the UVs come from if TEXTURE_RECT is disabled? It isn't clear as there are no comments in the source, but INSTANCE_ATTRIB_BASE + 4 location is where the UV is specified in the shader, and the glVertexAttrib calls for that location look suspicious. I haven't worked out where the UVs are being set, as ATTRIB_BASE + 4 is being used for custom data in multimesh. Could also be an attribute numbering problem, assuming a certain location instead of querying? glBindAttribLocation is deprecated on iOS it seems - that's a possible: Although I'm amazed it's working at all if that was it... There is an if statement there for an atlas_texture, so it would be nice to confirm the original values going in are correct, but the issue has existed before the PR which added that (february 2020?). _update_mesh_texture() could be wrong values (unlikely), then it calls The other possibility is a problem reading the values. Reading the values wrong or a wrong state still seems most likely to me, because if there was a problem uploading the mesh_texture thing, you would have thought it wouldn't work at all. And likewise for precision etc issues in the shader.
If this is indeed the case then the call might very well fail, and it may end up using whatever UVs are currently in the pipeline (the ones from the previous drawing!). This sounds very promising, fingers crossed! 😁 Is also possible some iPhone flat out don't support half float in GLES2 in vertex format:
If this is the case, we might consider changing the default for particles to use GL_FLOAT, even if slightly larger, it may be widely supported and I'm reading some reports that half float is very slow on some hardware. |
Ok I have a potential fix: https://github.com/lawnjelly/godot/tree/ios_particle I'm not 100% sure it will fix it, but it is looking likely, so I would really appreciate if someone with the problem could add this snippet and recompile to try. Note that you would need to compile the export template for iOS for it to actually do anything (otherwise it will only be compiling the editor). If this does fix it, it will likely fix all the associated iOS particle problems (ninepatchrect etc). However I'll need to discuss with @clayjohn how to do a more sensible fix for a PR - it's a bit of a chicken and egg problem. The decision to compression is made in the visual_server, before it gets to the renderer, but only the renderer knows whether the feature might be supported (aside from large selections, like all IPHONE_ENABLED devices). Half float may be available in GLES3 but not GLES2 for example. |
Thanks for continuing to work on this! It sounds like we're getting close.
Is there a simple guide online for how to create the .tpz export template file for iOS? I tried following this guide but it just results in a bunch of .fat.a files. How do I generate the .tpz file that Godot is asking for? I tried using the misc/dist/ios_xcode folder and replacing files, zipping it, renaming it to iphone.zip and copy pasting an old template folder but I got a generic error that the template was wrong. I'm pretty sure I messed something up because the copy pasting of old templates and replacing files seems like a hacky approach. I'm sure there's some simpler method that I'm missing. I couldn't find any official Godot docs on this but maybe I missed a section. I'm fairly new to building the engine so sorry if this is obvious. I'd love to help out to test this but I'm having trouble finding a simple workflow for building + exporting for iOS from source. Any help is welcome! (Sorry to pollute this issue with this, but I think it would be helpful). |
@nebs that guide is the most up to date resource on building for iOS. See also the linked guide for exporting your game https://docs.godotengine.org/en/3.2/getting_started/workflow/export/exporting_for_ios.html#doc-exporting-for-ios the instructions shouldn't differ from what it says. You won't be creating your own tpz export file as you are doing your own custom export. You'll have to follow the instructions for linking your custom executable to xcode instead of the executable contained in the tpz export file |
The docs are indeed missing the step to pack the compiled libraries into the Here's how it's done for official templates: https://github.com/godotengine/godot-build-scripts/blob/master/build-release.sh#L175-L187 The simplest way would be to unzip the |
Good news, it appears this fixes the bug! I applied this change to my fork and the particles appear to render correctly on my iPhone even with the label and tile map present: But it would be great if someone else could verify on their end too. The only reason is because to get the export templates to work I had to do some Frankenstein combination of following the docs and applying some of what akien-mga mentioned and also having to rename some files to fit. I'm pretty sure I did it correctly because it exported without errors, but I'm just worried about an accidental false positive. But assuming I built things correctly it appears lawnjelly's commit is the correct fix for this bug. Good work guys! |
That's fantastic!! 😁 |
Well, i was reporting same bug but.... thats fast!!!. I have other problem with Gles2 batch and render of the rectangle of the camera in the editor, and the Z index inheritance.... will open other issue for that when i can archieve a minimal reproduction project. Interesting thing that the bug that was fixed here is that it was gone if you changed the Z index of the particles node. I suppose that it was because it doesn´t batch if Z index is different... |
Just a note that this bug has an experimental fix available in the latest 3.2.2 beta. Would appreciate if any of you guys with the issue can test, full instructions are in #38441 (it's slightly more involved because of my incompetance! 😀 ) |
Hey, I just tested 3.2.2.beta2. I can confirm that adding |
@HEAVYPOLY what version of the engine are you using? You may have to add |
@clayjohn 3.2.2.rc1. I added the gles2/batching/disable_half_float=true to my project manually in the Godot.project file, no change. I just tried with GLES3 and it's working correctly |
With the settings rename (#39068) the setting in RC1 is working and it is now: If the disable half float setting doesn't cure it (and the correct export template is being used) then this needs a new issue (preferably with the hardware version, the shader, and a minimum reproduction project). |
This issue can be closed in light of #38318 (comment) Further |
Godot version:
3.2.2.beta1.official
OS/device including version:
iPhone 6 running iOS 12.4.5
Issue description:
The CPUParticles2D texture particles are rendered as a flat color instead of showing the actual texture image.
This happens in a very specific scenario:
Below are some screenshots taken from my iPhone with various settings toggled:
If GLES2 Use Batching = OFF and Label is visible: [CORRECT]
If GLES2 Use Batching = ON and Label is hidden: [CORRECT]
If GLES2 Use Batching = ON and Label is visible: [WRONG]
As you can see the first two cases it works fine. But it breaks if Use Batching is ON and the Label is visible.
NOTE: I tested this exact same project in the official 3.2.1.official release and the bug is not there. So the bug is only introduced in 3.2.2.beta1 with the Use Batching=ON.
NOTE: Again, this bug is not visible when running inside Godot. You must export an iOS project and build with XCode on a device. I didn't try an iOS simulator.
Steps to reproduce:
To get the particle texture to render properly you can either: 1) Hide the label (just click the little eye icon) or 2) Open the project settings and under GLES2 turn OFF "Use Batching". Then export the project again and you should see the proper particle textures working again.
Minimal reproduction project:
ParticleBugTest.zip
The text was updated successfully, but these errors were encountered: