+2 votes

This tutorial outlines exactly what I want to do however I am really struggling to figure out how to implement it in Godot. If there is a better way to implement this same effect that's fine too!

I would be happy even just with a basic, single plane cross section, though I would use multiple planes if I could figure it out. I am also not planning on having overlapping objects like the layers of the earth in the tutorial, just cutting a single object is good enough for me! I am also not concerned with how lighting affects the cross section, shadows would be nice but if it's just a solid color that would be very much acceptable too.

Example of what I would like to achieve:
Cross Section Example

Thank you very much for any help or information!

in Engine by (121 points)
edited by

Well, it's not perfect and it's done differently but I've come up with something. I think the technique in the tutorial is better but I don't think stencil buffers are available in Godot. The main issue I am having now is with light and shadows. I would like for my cross-section shader to not affect the shadows of the original mesh, ie: I want the hidden parts to still cast shadows. What I have is #2 in the image below, what I want is #3 (Photoshopped).

enter image description here

Any suggestions on how to fix this would be very much appreciated!

For anyone interested, the shaders I used to make the cross section are as follows. There are two of them, the first one generates the red cross-section, take note of the render_modes, they are very important. The second draws the rest of the geometry that hasn't been cut away. I set the second shader as the "next pass" property of the first shader. Right now they just hide everything that has a Z position that is < 0.

Shader One:

shader_type spatial;
render_mode blend_mix, depth_draw_alpha_prepass, unshaded, cull_front;

varying vec4 world_pos;
uniform vec4 sectionColor : hint_color;

void vertex() {
    world_pos = WORLD_MATRIX * vec4(VERTEX, 1.0);  // get coords as world coords
    VERTEX -= (NORMAL * 0.001); // bias to stop z-fighting with neighboring meshes
}

void fragment() {
    if(world_pos.z >= 0.0){  
                ALBEDO = sectionColor.rgb;
            } else {
                discard;
            }
}

Shader Two:

shader_type spatial;
render_mode blend_mix,cull_back,diffuse_burley,specular_schlick_ggx;

varying vec4 world_pos;
uniform vec4 baseColor : hint_color;

void vertex() {
    world_pos = WORLD_MATRIX * vec4(VERTEX, 1.0);  // get coords as world coords
}

void fragment() {
    ALPHA = 1.0;
    if(world_pos.z >= 0.0){  
                ALBEDO = baseColor.rgb;
            } else {
                discard;
            }
}

There is likely a better way of doing this, and if there is I'd love to know about it. I haven't tried it on large complex meshes yet so I don't know how it will to performance wise.

After playing around with this some more... it just isn't going to work how I have done it. It might work for a very simple effect but it practice it just has too many problems. It looks like access to the stencil buffer/frame buffers is really required to pull this off. Hopefully that will be an addition in 3.1. Or perhaps someone knows of a different way to do this that will work in Godot 3.0.X?

1 Answer

0 votes

Never Give Up. I know it's been 2 years but I just started making these:
https://www.youtube.com/watch?v=ub7tFOmqikw
I didn't use stencil buffers, just had to know which vertices to alpha off

I was looking for some reference on it myself just this Thursday and I stumbled on your question. Idk why but it felt like I had to get off my bum and help you out.

There's more to come: sphere's and cylinders ,etc
(but you might have to wait a while for those)

I hope this helps and that I'm not to late

by (54 points)

plus you should watch these as references too:
https://www.youtube.com/watch?v=MAzkNgzWK9w
https://www.youtube.com/watch?v=HR3flKges_A
https://www.youtube.com/watch?v=_YTw-pFuWig

they're not Godot but this is where I started

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.

Categories