-
-
Notifications
You must be signed in to change notification settings - Fork 21k
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
Fix missing shader params in headless export #76121
Fix missing shader params in headless export #76121
Conversation
Applying this on top of 4.0.3 solved my shader params missing from headless exports. I am going to do some wider testing to see if there are any other material side effects from this change. Thank you @cgsdev0 |
This PR kind of works, but it will only export uniforms that previously have their values set and saved in the inspector ui. After applying this PR, adding new uniforms in the shader code no longer appear in the inspector UI, because The --headless export problem is a pretty tricky as in the headless mode many Godot servers are not initialized and instead use dummy versions. For example to fix some mesh --headless export issues people have been patching the dummy MeshStorage to keep enough mesh data so that export works. Same kind of issues plague shader uniforms, multimesh etc. I feel it would required some major refactoring to make --headless export reliable, currently it's pretty much a combination of ad-hoc hacks to fix any errors that people encounter when exporting their specific projects using --headless. |
Thanks for the additional testing @bitsawer - I'll probably roll this back in our build and just avoid headless for the time being. |
thanks for this comment - I feel like this is the piece that I was lacking understanding of |
Hey, what's the state of this? |
See bitsawer's comment above |
fcb165b
to
ea196f2
Compare
in the spirit of the existing 'ad-hoc hacks', we could gate this change behind a check to see if we're in headless mode. It's not really a long-term solution, but it should at least fix this issue without regressions in the editor. I've pushed an updated commit with this change. |
I think that can be a reasonable solution with some changes. It's a hack, but considering what other hacks we have been doing for headless export it's a pretty minor one. A small, nice local hack that should work pretty well. Still, other maintainers are free to offer their opinions if they find a solution like this acceptable. I suggest some changes, for example static bool is_headless_exporting() {
#ifdef TOOLS_ENABLED
if (OS::get_singleton()->get_cmdline_args().find("--headless")) {
for (const String &arg: OS::get_singleton()->get_cmdline_args()) {
if (arg.begins_with("--export")) {
return true;
}
}
}
#endif
return false;
} And then maybe use it like this, with static const bool as a small performance optimization and to make sure it can't change during runtime. static const bool is_exporting = is_headless_exporting();
if (is_exporting) {
// Hacky solution to make --headless exports include shader parameters.
for (const KeyValue<StringName, Variant> &P : param_cache) {
list.push_back(PropertyInfo(P.value.get_type(), P.key));
}
} else {
shader->get_shader_uniform_list(&list, true);
} I haven't tested or even compiled these, so please try this out first if you decide to adopt this solution. |
I think considering the criticality of this issue, we can be okay with a hack for 4.1.1 and then find better solutions that require significant refactors later. Losing uniform on export is pretty critical imo. Reminder for people reading, clay's opinion and bitsawer's one definitely override mine, it's their expertise way more than mine, but from the point of view of a professional, i think this is a really critical issue that if it can be addressed quickly, even with a hack, it's better than being unable to export the game on CI until a refactor (which takes way more effort and time) is done. |
Previously, requesting the shader parameter list from the rendering server would be a no-op when using the dummy rendering server. This would cause the params to be lost during a headless export. This change uses the param_cache of the ShaderMaterial instead of the rendering server to avoid this issue. Addresses godotengine#66842
ea196f2
to
af815d1
Compare
@bitsawer that change seems reasonable to me. Let me know if you think there's a better central place to move the I'll do some further testing of this change once the CI builds are done |
good find! could be a little cleaner with this, as I don't think it needs to check if it's an export context, there could be other things like unit tests etc that rely on the shader having the correct parameters: const bool headless = DisplayServer::get_singleton()->get_name() == "headless";
if (headless) {
// we have to use the cached parameters as we can't query it from the display server
for (const KeyValue<StringName, Variant> &P : param_cache) {
list.push_back(PropertyInfo(P.value.get_type(), P.key));
}
} else {
shader->get_shader_uniform_list(&list, true);
} Some shorthand could be added to display server like: static bool DisplayServer::is_headless() const {
return DisplayServer::get_singleton()->get_name() == "headless"
}
// or this
bool DisplayServer::is_headless() const {
return get_name() == "headless"
} |
The proposed fix doesn't seem to preserve texture parameters on materials. MRP: 66842.zip It seems like more info might need to be added to the PropertyInfo to preserve them, but I couldn't figure out what exactly. |
Just an update on this PR. I think we should aim to solve it properly. The ideal solution is that we store enough data on the DummyRenderingServer to allow the call to |
Fixed this in #87392 Headless export from #87392 (I never opened the project in the editor) |
@clayjohn i dont think i have bandwidth for this any time soon feel free to take over the branch and/or close the PR |
Fixes #66842
I'm not confident this change is 100% correct; I did some testing with my project where I first observed the behavior, and the change did resolve the issue.
This is the function we used to call previously:
godot/scene/resources/shader.cpp
Lines 117 to 141 in a7276f1
I don't really understand what this group logic is doing, and I think my change potentially loses that information. Definitely open to feedback, this is my first time exploring the Godot codebase 😄
(This change isn't needed for 3.x)