-
-
Notifications
You must be signed in to change notification settings - Fork 21.7k
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
Custom shader templates #94427
base: master
Are you sure you want to change the base?
Custom shader templates #94427
Conversation
ca97f22
to
b251e10
Compare
Should this feature really be called shader templates? It might cause confusion with "script templates" which work completely differently (I assumed this PR would allow a newly created shader to start with a different code preset). |
I agree with the comment above. I feel something like "scaffolding" could communicate the idea. |
Scaffolding generally refers to a template system that creates files/folders for you (like good old Yeoman), so I'd try to find a different term for that instead. The concept of overriding is more accurate here, although calling it a shader override may be mistaken for a material override (which is a different concept). I think it's important to highlight the fact that you are replacing core shaders here, not user-provided shaders. The core shaders are always written in GLSL, not the Godot shader language. Maybe core shader override? |
Your last paragraph made me think, if this is for overriding core shaders, why is it set per-shader instead of globally in project settings? |
b251e10
to
b02c977
Compare
Because you may want to combine different shaders. For instance you may want to only use this for your terrain shader. (that said, having a project settings that sets a default could be an interesting option) |
something that's Kind of like the Default Environment and Default Environment Background Color you can set in the project settings would be great.. |
Hmm, we could add it to the compositor, that might be a good place for this. |
Actually, thinking about this more, this is not possible because we could have the same shader compiled with multiple templates and we have no support for that. So we can do an all or nothing project setting, or keep it as is right now where we identify the template to use for each user shader. |
bd50859
to
75f60ec
Compare
918a194
to
c3df623
Compare
Fixed the issues around reloading the shader template, now when you modify the shader template, all shaders that use the template get recompiled automatically. |
c3df623
to
59f2d39
Compare
59f2d39
to
4f04ee3
Compare
@@ -339,6 +340,9 @@ class BaseMaterial3D : public Material { | |||
uint32_t feature_mask; | |||
uint32_t flags; | |||
|
|||
// shader template | |||
uint64_t shader_template_id; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This may be a breaking change, I am not sure what the implications of changing the material key are. However seeing shader templates effect the compiled shader, it has to be part of the key.
} | ||
|
||
void _unpack_vertex_attributes(vec4 p_vertex_in, vec3 p_compressed_aabb_position, vec3 p_compressed_aabb_size, | ||
#if defined(NORMAL_USED) || defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@clayjohn this is an interesting difference between the mobile and clustered implementation. We check more defines in the mobile renderer, but we're not consistent with it. I wonder if this is correct or left over from an older implementation?
759b521
to
78016e8
Compare
Added some extra logic so you can optionally specific templates for multiple renderers. A template in the format of:
Will be used regardless of the renderer selected and thus will fail when used with the wrong renderer. Alternatively you can create blocks for each renderer:
In this scenario, if the current renderer does not have any code in the template, a missing code error will be given. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested locally (rebased on top of master
20f4d26), it works as expected.
Some feedback:
- There is no shader compilation error when the shader template file doesn't exist:
You do get this message in the editor Output panel Resource file not found: res://notfound.gdtemplate (expected type: )
, but no error highlighting in the shader editor due to this.
- The
.gdtemplate
file extension is pretty generic. It could be a script template, a project template, anything – it's not very descriptive. I suggest using.gdshadertpl
which would make it more consistent with the existing.gdshaderinc
extension.
As a reminder, we'll need to contact KDE/Dolphin developers to add an icon for the new file extension we choose to use:
- I've gotten this error message from making a change in a
.gdtemplate
file then reloading the project:
Unknown shader type in shader template.
Could more context be added to this message (such as the type that was specified, and the line of the error)? The change was on https://github.com/BastiaanOlij/test-custom-shader-templates/blob/master/test.gdtemplate#L323, where I replaced the line with:
albedo_output_buffer = vec4(albedo * vec3(1.0, 0.0, 0.0), alpha);
(I'm not sure why that caused an error too, either way. It seems to be valid GLSL.)
I also tried reverting my change and reloading the project again, but I still get the error message and the material is no longer using the custom shader template:
The cube on the right should appear unshaded, but it appears shaded.
@Calinou agree with all you said there and I'll look into the error you reported, though I'm not planning on spending a lot of time on this until after 4.3 stable is out, I want to just gather feedback and then do a whole bunch of changes at once. When the shader template can't be loaded, it just defaults back to the built in template, hence your right cube showing up correctly. I think it would be better if the compilation just fails and it just defaults back to our white shader. I need to figure out how to make that happen because if the fault lies in the template, it finds it out too late, but when the fault lies in the template not being found we can piggy back on the existing logic for this. |
… shader templates)
78016e8
to
25a6152
Compare
25a6152
to
79e694b
Compare
Custom shader templates is a new feature in the rendering engine that allows you to override the built-in shaders into which user shaders are injected. While the inputs and outputs are fixed, this gives full control of the executed shader code.
NOTE This is an advanced feature that requires in-depth knowledge of the rendering engine to use. We should consider hiding this feature by hiding the property on the Shader resource unless a project setting is enabled. It should still load/save the property so advanced users can make plugins that make materials available that use a custom shader template. Also note that this feature is likely very version sensitive, while the include system (see #94193 which this PR is dependent on) will likely soften this, we can't completely remove this.
Also custom shader templates are renderer dependent, you can likely not use a template created for the Forward+ renderer on the mobile renderer or compatibility renderer.
Todos:
Add into separate PR for enabling this on compatibility renderer:
Add into additional follow up PR(s):
Known issues:
Very simple test project can be found here:
https://github.com/BastiaanOlij/test-custom-shader-templates
The readme on this project contains extra information about writing custom shader templates.
Live streams about this feature: