-
Notifications
You must be signed in to change notification settings - Fork 3
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
Godot 4 Ultimate Flexible Outline and X-Ray Shader #3
Comments
Having outline support will be useful to implement godotengine/godot-proposals#2795. For drawing outlines, the built-in approach could work much better for meshes that don't use smooth vertices exclusively if Godot could generate better outline meshes. This can already be done manually in 3D authoring software, but it requires exporting a separate copy of the mesh for use as an outline. An X-ray shader will likely require godotengine/godot-proposals#1298 to be implemented to be done properly. PS: Remember that for GitHub video previews to work, you need to have a blank line before and after the video URL. |
Currently, I am looking for an outline solution that doesn't require changing the engine itself - an implementation with the current features. But of course that would welcome as well.
I already managed to create a X-Ray with
Thanks, fixed. |
@Calinou In the end there's really no way of doing it currently with what we have in Godot 4? Even if many approaches are mixed? |
I saw an x-ray shader in I think GDQuest's collection you linked, and I know I saw a solution somewhere but that one involves a freaking stack of 3+ viewports... was unusable in practice. |
Unfortunately it has all the flaws that need to be solved that I linked in the Issue.
I also tested this one with viewports. It provides no way of changing color in runtime unless you create 3 more viewports for each color. And regardless, it's buggy in Godot 4, it creates artifacts. |
No, not without modifying the engine source code to implement godotengine/godot-proposals#1298. It's probably not very difficult, but Vulkan exposes this differently compared to OpenGL. In the meantime, if you want selected characters' positions to be visible through walls, you can use a Sprite3D with a "ring" texture around the character's feet that is set to be visible through walls. This is similar to what many RTS games do when selecting units. |
Howdy! I've been exploring this road, I hope y'all don't mind if I add some notes here. I've experimented with various outline/silhouette shaders, without stencil support, using godotengine/godot#73527 and some solutions to godotengine/godot#73158. With those solutions in place, it's possible to make a nice silhouette shader for a single character in the opaque pass. However, depth prepass cannot be used with this type of shader, and there are some other small issues especially with overlapping silhouettes. Viewport-based solutions are entirely unwieldy and basically are not an option for typical games. It seems to me that stencil buffer support is absolutely necessary to get a good silhouette that doesn't have these problems. To me, the ideal scenario would be using a That is how the Unity Quick Outline addon is designed, and it is very effective with minimal issues. I've also been observing how other games draw silhouettes, and this approach seems common. That is the design I will be working on in my personal endeavors. |
Thanks for the contribution @apples !
100%. |
Progress update: Godot 4.0 seems to have a working stencil buffer, but stencil operations are currently not exposed through the Material APIs. To implement this, I had to add the relevant fields to These fields are reproduced in the shader using render modes I added:
A bit wordy, and requires a (surprisingly small) parser modification to allow for the numeric parameters, but it gets the job done. When combined with godotengine/godot#73527, I can achieve the results shown above. Note: It seems like all the necessary APIs are exposed via RenderingDevice, but I'm not savvy enough with that API to implement anything using it. But it seems like this might be able to implement stencil effects entirely from script? My current working branch can be found here: https://github.com/apples/godot/tree/depth-function+stencil-buffer |
@apples this is great! Tested out your branch and it works well. This feature should definitely be added officially! |
@apples thanks a lot for this, this is great! |
Looks like stencil support will be merged soon: godotengine/godot#80710 |
I think it's still on hold, the code is approved but I don't think they want to merge it until the render priority issue is figured out |
I'm probably missing something obvious here but I've done the same thing combined with checking the depth texture to see if we're occluded, and if not just set alpha to zero. It seems to work but I haven't tested it extensively. Only problem I've come across so far is how to specify objects that actually always should occlude, for example enemies. That can be worked around by setting enemy material transparency to depth pre-pass. shader_type spatial;
render_mode depth_draw_never, depth_test_disabled, unshaded;
// This shader draws a semi-transparent single-color overlay when the object is
// occluded. When not occluded, ALPHA is set to zero. Use this in a next_pass
// material.
uniform vec3 overlay = vec3(0.3, 0.3, 0.9);
uniform float opacity = 0.5;
uniform float bias = 0.1;
uniform sampler2D depth_texture: source_color, hint_depth_texture;
void fragment() {
// Convert depth texture coordinate from screen space to clip space to
// view space
float clip_depth = texture(depth_texture, SCREEN_UV).r;
vec3 clip_space = vec3(SCREEN_UV * 2.0 - 1.0, clip_depth);
vec4 view_space = INV_PROJECTION_MATRIX * vec4(clip_space, 1.0);
view_space.xzy /= view_space.w;
// Set non-zero alpha if we are further away from the camera than whatever
// is in the depth texture
ALPHA = opacity * float(-view_space.z + bias < -VERTEX.z);
ALBEDO = overlay;
} |
Almost two years since starting this discussion, I finally managed to accomplish in Godot an outline decorator with a set of features similarly to that one from Unity.
Final result in Godot 4.2.2-stable: GodotSmoothOutline.mp4Compare it to the Unity GIF (that uses the asset "Quick Outline") that I shared in the original post above, and my Godot version looks even smoother. Notice that Unity's "easy performant outline" is still much better and more flexible https://assetstore.unity.com/packages/vfx/shaders/fullscreen-camera-effects/easy-performant-outline-2d-3d-urp-hdrp-and-built-in-renderer-157187 - I think it is going to be possible to create something like this one in Godot only after stencil buffers are added to the engine. I am not ready to share it yet, but I'm just happy that this is finally done. |
Godot 4 lacks proper Outline and X-Ray/Silhouette shader solutions, meanwhile Unity and Unreal Engine provide multiple professional solutions for outlines. All current Godot 3 samples and open-source projects work to a certain degree, but all of them have flaws and/or are broken in a way or another with Godot 4.
In the end, neither of the existing Godot 3's solutions would be currently usable in games that require Outlines and X-Rays, i.e. the majority of 3D games nowadays use either Outlines and/or X-ray.
The current solutions either break the mesh existing material or create depth and culling problems, especially with animated skeletal meshes. The link of solutions tested are at the bottom.
This image is taken from a Unity project using Quick Outline.
Objective
The aim of the project Godot 4 Ultimate Flexible Outline and X-Ray Shader is to provide a flexible solution for:
See each feature in more details below, with sample images/videos.
The samples below were produced in Unity using a free solution called Quick Outline (open-source). The idea is to replicate Quick Outline for Godot.
But in our case, it doesn't matter whether it's made through post-processing, multiple material passes, cull masks, etc. The only requirement is that it must have the features listed below. Unfortunately Godot still doesn't have stencil buffers - which requires creativity and hacky ways to implement this.
Open-Source and Paid Work
Everything implemented will be open-source, available for anyone to use, and to help strengthen Godot - especially considering that this is a MUST for the majority of 3D games nowadays.
This way, any help is appreciated. And if you want to do this, but as paid work, feel free to let me know. I have a personal budget that I am willing to invest in order to sponsor this project.
If you are interested, you can open a PR, leave a comment this issue or send me an email: https://alfredbaudisch.com/contact
Features
Customizable Colors At Runtime
This image is taken from a Unity project using Quick Outline.
Toggeable At Runtime
toggleOutline.mp4
This video is taken from a Unity project using Quick Outline.
Respect the Mesh's Existing/Underlying Material
The solution should support any underlying material. For example, if the skeletal mesh has its own Material, it must be possible to still use it. It doesn't matter if the material appears in the first or pass for example, as long the existing mesh material can be used, no matter whether it's a default PBR Material or a custom material with a custom shader.
It's also OK to make adjustments to the material overrides or overlays, the important thing is that the mesh's original visuals are still shown.
For example, this character material work as is, even with the outline:
This image is taken from a Unity project using Quick Outline.
Support for Static Meshes and Skeletal Animated Meshes
All previous examples show the characters walking on purpose, highlighting that the outline works with skinned meshes and deformations.
Occlusion XRay/Silhouette
Preferable there should be an option to choose between Outline + Silhouette, just the Outline or just the Silhouette when occluded. But to make things simpler, showing only the Silhouette when occluded is more than enough.
xRay.mp4
This video is taken from a Unity project using Quick Outline.
Base Project
A Godot 4-beta3 base project is provided with the same characters from the Unity samples below. The main goal with this project is to replicate the features of Unity's Quick Outline with Godot 4 in the Base Project: GodotUltimateOutline-BaseProject.zip
References
Godot 3 Outline Projects
Unity
The text was updated successfully, but these errors were encountered: