-
Notifications
You must be signed in to change notification settings - Fork 4
Cross-section rendering #8
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
Cross-section rendering #8
Conversation
1fd7321
to
a54c515
Compare
movie_render.mp4 |
d2f25dc
to
61c687a
Compare
Man first this formatter says too few newlines at end of file, then it says too many. Needs to make up its mind 😞 |
The current UVW maps for the box and orthoplex were tediously hand-unwrapped by me, because I wanted to have some kind of test mesh but didn't have a general algorithm for unwrapping them. It's very possible I made a mistake. But I would be surprised if the whole thing is wrong. |
61c687a
to
d5cb88e
Compare
Ok, I'll take a closer look some time soon. Normals were also messed up in a similar way when I tried passing them in, so could be one of the fields I'm stashing data in is getting messed with and breaking things. |
d5cb88e
to
eff36d6
Compare
Did some more digging and found out that the normal is getting normalized somewhere in the pipeline but I couldn't figure out where. Also found some weird processing happening where data is getting clamped into [0,1]: https://github.com/godotengine/godot/blob/45fc515ae3574e9c1f9deacaa6960dec68a7d38b/servers/rendering_server.cpp#L712C1-L717C8 Looks a bit better with a fix for the normalization but there are still some seams in the middle of faces which seems off. They're at least continuous now. Before: 4d_pre_normalization_fix.mp4After: 4d_normalization_fix.mp4Thinking I need to take a different approach. This is definitely hacky and there isn't really enough space to fit all the data I need. What do you think about switching to using ImmediateMesh and doing the cross-section on the CPU? Could maybe do a compute/geometry shader which would only work on the Forward+ renderer as far as I know, but I can't find any examples. |
@HenryWConklin I think it's most performant to do it on the GPU, but any approach you can get working is better than wireframe-only, so a CPU-based solution would be welcome. Also, about the visual of the box, did you test with both 40-cell and 48-cell BoxTetraDecomp settings? |
eff36d6
to
004f650
Compare
Figured it out, I was using the wrong UVW coords. Turns out they're not indexed like the positions so I was reading the wrong UVW coords out of the array. The other samples were all 40-cell, 40 and 48 cell cubes look identical now. 4d_fix_40cell.mp44d_orthoplex.mp4Still no smooth normals support, but I added support for Texture3D: 4d_orthoplex_textured.mp4 |
@HenryWConklin Ah, that makes sense. And yes, they are duplicated to allow for different tets on the same vertices to have different teture coordinates at those vertices. This is vital even for simple shapes. |
004f650
to
e1486e9
Compare
d94a2a2
to
6e47fd8
Compare
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.
Thanks for your patience with this! It's a super cool feature for sure.
One important aspect of this module is that I am keeping it able to be compiled as both a module and a GDExtension. As usual when any work happens on this module, this PR has revealed problems with a mismatched API between the engine and GDExtension, so I did a few detours to fix a few of those problems: godotengine/godot#107139, godotengine/godot#107141, godotengine/godot-cpp#1789.
The new render/cross_section/
folder isn't referenced in the GDExtension SConstruct, so it's currently not compiled at all for GDExtension. It needs to be added:

I also added the header builders script from godotengine/godot-cpp#1789 in commit 6e5ae5d (be sure to rebase your PR!) which should allow for env.GLSL_HEADER("../../render/cross_section/cross_section_shader.glsl")
in the GDExtension SConstruct. However, I'm getting an error TypeError: 'tuple' object is not callable:
, which is strange because I swear the same build system code was working earlier when I was testing on top of your PR before I pushed that commit. I don't know what's different between then and now. Maybe some fresh eyes will help. Either way, ideally, we want this header to be able to generate with the GDExtension build.
e1486e9
to
88383f1
Compare
Got the GLSL header working, seems like it was just a stray comma in the definition for GLSL_HEADER making a 1-element tuple. GDExtension complies now with all the source files included. I haven't been able to get it to run to test it out though. I run into some odd errors from the method registration that cause crashes on loading the project. The full editor/module build still works though. This bit in G4MFItem4D seems like it's shadowing a property from Resource which causes some errors saying the set_name and get_name methods aren't defined, then throwing errors if you do re-bind them:
And I get some kind of segfault from a class in physics, seems like it's interpreting something as a pointer that is not a pointer but I didn't dig too far. |
88383f1
to
0e83598
Compare
0e83598
to
83791bb
Compare
Moved everything to a separate world3d which fixes the weird rendering in the 3D preview, should be more robust overall. I am getting an error message now on the first frame when running a scene, seems like the 4D rendering server gets called in |
@HenryWConklin That might cause things to be a frame late in some cases. I think it's better to check for null things in RenderingServer and silently skip rendering that frame if null. |
83791bb
to
1fbf462
Compare
Yeah, makes sense. I think there's also a DRAW notification on some types of nodes but seems like that would be a lot of refactoring. Tried some things and found a work around doing some manual RID stuff. Actual error happens here: https://github.com/godotengine/godot/blob/e1b4101e3460dd9c6ba0b7f8d88e9751b8383f5b/servers/rendering/renderer_scene_cull.cpp#L488 Coming from here: https://github.com/godotengine/godot/blob/e1b4101e3460dd9c6ba0b7f8d88e9751b8383f5b/servers/rendering/renderer_viewport.cpp#L1236 It's trying to clean up the old world on the viewport but it's somewhere in the middle of being created where the RID is valid but hasn't been initialized or something. |
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.
Sorry for being a bit slow to review this. I've made some changes on master which will help with this.
In general I'm happy to merge this sooner rather than later, to get something in which we can build on top of further, even if it's missing features like 4D shadows, lighting, editor gizmos, etc, those could always be added later.
Please run doctool: ./bin/godot.something.exe --doctool .
(replace godot.something.exe
with your executable) and fill out the descriptions in the generated documentation XML.
543624d
to
ee9d3b7
Compare
No worries on being slow, I've been meaning to add more to this and haven't been. Have most of the change to add support for wireframes to the cross-section renderer, but I can send that as another PR. Need to do some research for the shadow effect so might be a while but I'm interested in working on it. Should be in a good state to merge, let me know if you want any other changes! |
ee9d3b7
to
b84ed24
Compare
The albedo source of the material, an enum specific to tetrahedral meshes. Can be a single color, per-vertex, per-cell, per-cell UVW coordinates, 4D texture, or a combination of single color and the other color sources. | ||
</member> | ||
<member name="texture" type="Texture3D" setter="set_texture" getter="get_texture"> | ||
The albedo texture of the material as a Texture3D. Used by the cross-section renderer. Used when albedo_source is [constant TETRA_COLOR_SOURCE_TEXTURE4D_ONLY] or [constant TETRA_COLOR_SOURCE_TEXTURE4D_AND_SINGLE]. |
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.
That's actually not what the Texture4D color source is meant to be used for. Texture4D is when you have a 4D texture which directly maps 4D coordinates to a 4D texture without using the cell UVW map. The TETRA_COLOR_SOURCE_CELL_UVW_ONLY
and TETRA_COLOR_SOURCE_CELL_UVW_AND_SINGLE
options are for using a cell UVW map to map cells onto a 3D texture. Maybe it could be renamed for clarity.
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.
Ah ok, fixed. Is texture 4D a thing? Not sure I've seen that as a supported type anywhere. Might need to be a shader or a sprite sheet type thing with some manual sampling.
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.
It's not a thing in Godot yet, but can be done with shaders. See https://www.youtube.com/watch?v=Ir8oft_qAMQ&t=3m35s
207f1a7
to
a05d063
Compare
Pipes all the right data to the GPU, still need to implement the actual cross-section logic. - Added a new rendering engine, CrossSectionRenderingEngine4D - Added method to Mesh4D to compute a special cross-section mesh that can be cross-sectioned in a vertex shader. - Added a method to Material4D to get a ShaderMaterial used for cross-section rendering
a05d063
to
766f5d0
Compare
Supports UVW texture coords but not pre-computed normals due to limits on mesh data. Also supports sampling from Texture3Ds.
Fixes the floating meshes in the 3D preview, transforms aren't set correctly using the 3D preview camera. Also makes sure 4d objects are visible across all 4d viewports.
766f5d0
to
b354ec8
Compare
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.
Awesome work, thank you!
Color albedo; | ||
Variant texture; | ||
switch (_albedo_source) { | ||
case TETRA_COLOR_SOURCE_SINGLE_COLOR: | ||
albedo = _albedo_color; | ||
// Setting to a Nil variant resets to the default texture, which is white. | ||
texture = Variant(); | ||
break; | ||
case TETRA_COLOR_SOURCE_CELL_UVW_ONLY: | ||
albedo = Color(1.0, 1.0, 1.0); | ||
texture = _texture; | ||
break; | ||
case TETRA_COLOR_SOURCE_CELL_UVW_AND_SINGLE: | ||
albedo = _albedo_color; | ||
texture = _texture; | ||
break; | ||
default: | ||
albedo = Color(1.0, 1.0, 1.0); | ||
texture = Variant(); | ||
break; | ||
} |
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.
The TetraColorSource enum is intended for safe user-friendly setting, but when reading, there are bitwise flags available to simplify this. That code can be replaced with this:
const ColorSourceFlags flags = get_albedo_source_flags();
const Color albedo = (flags & Material4D::COLOR_SOURCE_FLAG_SINGLE_COLOR) ? _albedo_color : Color(1.0, 1.0, 1.0);
// Setting to a Nil variant resets to the default texture, which is white.
const Variant texture = (flags & Material4D::COLOR_SOURCE_FLAG_CELL_UVW) ? Variant(_texture) : Variant();
I've pushed this in commit f2b29bd
For #5
Adds a renderer that slices a 4D tetrahedron mesh on the GPU in the vertex shader. Works by packing data wherever it fits on Godot's rendering server and reinterpreting it in the shader.
In a decent state but there are a couple issues I'm aware of:
3D editor preview is broken, the preview camera's transform isn't passed to the shader so 4D meshes stay fixed in place and don't move with the camera view, probably means adding support for 3D camerasUVWs look off, can't tell if they're wrong on the 4D mesh or getting mangled on the way to the shader. Haven't had the brainpower to delve into the fourth dimension and debug that.next_pass
for the first shader, may need another surface on the mesh as well