Skip to content

Conversation

@Fahien
Copy link
Contributor

@Fahien Fahien commented Nov 12, 2024

Here's a bunch of code adding some Vulkan raytracing stuff to the rendering device:

  • Vulkan implementations in RenderingDeviceDriverVulkan
  • Raytracing instruction list in RenderingDeviceGraph
  • Functions to create acceleration structures and raytracing pipelines in RenderingDevice

There's more in the fahien/raytracing-test branch, with code handling raygen, miss, and closest-hit shaders, but it's a hack on top of the forward clustered renderer, and it needs some "guided" refactoring.

Here's a sample which uses GDScript to drive the renderer: raytracing-gdscript-demo

I hope this changes would look useful to jump-start raytracing support.

Relevant for godotengine/godot-proposals#5162

@Fahien Fahien requested a review from a team as a code owner November 12, 2024 12:21
@Chaosus
Copy link
Member

Chaosus commented Nov 12, 2024

Commits needs to be squashed (see https://docs.godotengine.org/en/latest/contributing/workflow/pr_workflow.html).

@Chaosus Chaosus added this to the 4.4 milestone Nov 12, 2024
@Fahien Fahien force-pushed the fahien/raytracing-base branch from d5f4b02 to 4ff001d Compare November 12, 2024 13:24
@DarioSamo
Copy link
Contributor

DarioSamo commented Nov 12, 2024

I had a very brief look and it looks pretty good to me, although I'd hold off on making changes that add a new rendering method. Are you planning on sticking to only supporting the hit shader workflow or would you also like to add ray query support as well?

If you'd like to test your rendering without adding a new rendering method, keep in mind you can also use GDScript to drive the renderer and it should be pretty sufficient to test it out. This is also a simple way you can provide us with a demo project to test it out.

@octanejohn
Copy link

i see that you started on a renderer too on that repo, i think your renderer could be tested/based on the godot ideas

https://gist.github.com/reduz/c5769d0e705d8ab7ac187d63be0099b5

@Fahien Fahien force-pushed the fahien/raytracing-base branch 3 times, most recently from 3eea43f to 2e1d952 Compare November 16, 2024 09:14
@Fahien Fahien requested review from a team as code owners November 16, 2024 09:14
@Fahien Fahien force-pushed the fahien/raytracing-base branch from 2e1d952 to 61a9d1c Compare November 16, 2024 15:16
@Fahien Fahien requested a review from a team as a code owner November 16, 2024 15:16
@Fahien Fahien force-pushed the fahien/raytracing-base branch 2 times, most recently from b456ef5 to a784c7d Compare November 17, 2024 14:23
@Fahien
Copy link
Contributor Author

Fahien commented Nov 17, 2024

@DarioSamo

I had a very brief look and it looks pretty good to me, although I'd hold off on making changes that add a new rendering method. Are you planning on sticking to only supporting the hit shader workflow or would you also like to add ray query support as well?

Just focusing on the hit shader for now.

If you'd like to test your rendering without adding a new rendering method, keep in mind you can also use GDScript to drive the renderer and it should be pretty sufficient to test it out. This is also a simple way you can provide us with a demo project to test it out.

There you go: https://github.com/Fahien/godot-raytracing-gdscript-demo

@Fahien Fahien force-pushed the fahien/raytracing-base branch 2 times, most recently from de229f2 to 2474b4d Compare November 17, 2024 17:06
@a-johnston
Copy link
Contributor

a-johnston commented Nov 19, 2024

This is very cool to see! Last night I took a look at how hard it might be adding metal support and while it's definitely out of my wheelhouse here's a commit to at least get it building on macos + a new method to guard user code from invoking raytracing when it isn't supported (also includes some precommit changes) a-johnston@a220083

ed: I have some (probably very misguided and) incomplete changes on https://github.com/a-johnston/godot/tree/raytracing-metal but giving up where it is. Currently it blows up for spirv_cross::CompilerError: A memory declaration object must be used in TraceRayKHR. when in the raytracing renderer but there are other issues past that point. Also notable that this has a lot of conflicts with the hddagi branch, although that's too be expected, if one or the other is going to be merged soon.

@AThousandShips AThousandShips modified the milestones: 4.4, 4.x Nov 20, 2024
@DarioSamo
Copy link
Contributor

What follows from my side as well is that I'll test the PR locally, as I was told by somebody else that there were problems that'd make it crash the GPU when used. I'll report back if I find any issues.

@DarioSamo
Copy link
Contributor

RenderingShaderContainerD3D12 has a build error with dev_build=yes.

DEV_ASSERT(!reflection_data.is_compute); // Could be supported if needed, but it's pointless as of now.

Updating it to the proper pipeline type fixes it.

@DarioSamo
Copy link
Contributor

RenderingShaderContainer::reflect_spirv does not set the pipeline type.

diff --git a/servers/rendering/rendering_shader_container.cpp b/servers/rendering/rendering_shader_container.cpp
index 3609e52c10..296d9e41d6 100644
--- a/servers/rendering/rendering_shader_container.cpp
+++ b/servers/rendering/rendering_shader_container.cpp
@@ -242,12 +242,38 @@ Error RenderingShaderContainer::reflect_spirv(const String &p_shader_name, Span<
        LocalVector<ReflectShaderStage> &r_refl = r_shader.shader_stages;
        r_refl.resize(spirv_size);

+       bool pipeline_type_detected = false;
        for (uint32_t i = 0; i < spirv_size; i++) {
                RDC::ShaderStage stage = p_spirv[i].shader_stage;
                RDC::ShaderStage stage_flag = (RDC::ShaderStage)(1 << stage);
                r_refl[i].shader_stage = stage;
                r_refl[i]._spirv_data = p_spirv[i].spirv;

+               if (!pipeline_type_detected) {
+                       switch (stage) {
+                       case RDC::SHADER_STAGE_VERTEX:
+                       case RDC::SHADER_STAGE_FRAGMENT:
+                       case RDC::SHADER_STAGE_TESSELATION_CONTROL:
+                       case RDC::SHADER_STAGE_TESSELATION_EVALUATION:
+                               r_shader.pipeline_type = RDC::PIPELINE_TYPE_RASTERIZATION;
+                               break;
+                       case RDC::SHADER_STAGE_COMPUTE:
+                               r_shader.pipeline_type = RDC::PIPELINE_TYPE_COMPUTE;
+                               break;
+                       case RDC::SHADER_STAGE_RAYGEN:
+                       case RDC::SHADER_STAGE_ANY_HIT:
+                       case RDC::SHADER_STAGE_CLOSEST_HIT:
+                       case RDC::SHADER_STAGE_MISS:
+                       case RDC::SHADER_STAGE_INTERSECTION:
+                               r_shader.pipeline_type = RDC::PIPELINE_TYPE_RAYTRACING;
+                               break;
+                       default:
+                               DEV_ASSERT(false && "Unknown shader stage.");
+                       }
+
+                       pipeline_type_detected = true;
+               }
+
                const Vector<uint64_t> &dynamic_buffers = p_spirv[i].dynamic_buffers;

                if (stage == RDC::SHADER_STAGE_COMPUTE) {

@DarioSamo
Copy link
Contributor

With those changes, the gdscript demo runs!

@Fahien Fahien force-pushed the fahien/raytracing-base branch 3 times, most recently from 30b3e97 to 350317e Compare December 23, 2025 13:31
Copy link
Contributor

@DarioSamo DarioSamo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think I have any further changes to request. Thanks a lot to @Fahien for the work and refactoring it along the way!

This is a fairly low risk merge as it only adds functions to RenderingDevice that will not be currently used by any of Godot's renderers yet. Users can fire up code in gdscript to use it if they wish, but they must check for the device to explicitly support the feature first. On top of that, only Vulkan is implemented and D3D12/Metal implementations will remain pending to do after this is merged.

I consider those to be out of the scope of this PR, and having it be part of the codebase before those are developed will help establish a base on top of which others can reliably build on.

@Fahien Fahien force-pushed the fahien/raytracing-base branch 2 times, most recently from 85f23dd to da81105 Compare December 23, 2025 13:54
@coobenguy
Copy link

image At the moment when I run the demo project I get this error saying my rendering device isnt supported which I dont believe should be the case? I have a RTX 2070 Super and my drivers are up to date so I dont think I should have this problem. I do also have a GTX 1080 but after disabling that I still get the errors

@Fahien Fahien force-pushed the fahien/raytracing-base branch from da81105 to 5701522 Compare December 25, 2025 10:52
@Fahien
Copy link
Contributor Author

Fahien commented Dec 25, 2025

@coobenguy At the moment when I run the demo project I get this error saying my rendering device isnt supported which I dont believe should be the case? I have a RTX 2070 Super and my drivers are up to date so I dont think I should have this problem. I do also have a GTX 1080 but after disabling that I still get the errors

Thank you for testing this! It should be fixed now.

@Fahien Fahien force-pushed the fahien/raytracing-base branch 2 times, most recently from fc7cef6 to 06a74eb Compare January 1, 2026 16:14
Copy link
Member

@Calinou Calinou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested locally on Windows + NVIDIA, it works as expected. Code looks good to me.

Note that if you run the test project on OpenGL, you get this error on this line:

	if rd.has_feature(RenderingDevice.SUPPORTS_RAYTRACING_PIPELINE):
Cannot call method 'has_feature' on a null value.

I suppose a null check avoids the issue. This is not an issue with the PR, but I'm noting it nonetheless in case someone is copying this code for their own project.

@Fahien Fahien force-pushed the fahien/raytracing-base branch from 06a74eb to 84e285e Compare January 6, 2026 16:45
@leandro-benedet-garcia
Copy link
Contributor

Tested under linux, shows the green tris on red background as expected.

However.

I receive these two warnings:

W 0:00:00:076   init: FIFO protocol not found! Frame pacing will be degraded.
  <C++ Source>  platform/linuxbsd/wayland/wayland_thread.cpp:4743 @ init()
W 0:00:00:865   GDScript::reload: Integer division. Decimal part will be discarded.
  <GDScript Error>INTEGER_DIVISION
  <GDScript Source>raytracing.gd:113 @ GDScript::reload()

They might be nothing, but alas.

Also,
If I try to execute like this:
image

E 0:00:01:158   raytracing.gd:73 @ _set_screen_texture_data(): Expected Image data size of 1135x638x16 (RGBAFloat without mipmaps) = 11586080 bytes, got 11943936 bytes instead.
  <C++ Error>   Method/function failed.
  <C++ Source>  core/io/image.cpp:2441 @ initialize_data()
  <Stack Trace> raytracing.gd:73 @ _set_screen_texture_data()
                raytracing.gd:141 @ _render()
                raytracing.gd:51 @ _process()

E 0:00:01:158   raytracing.gd:74 @ _set_screen_texture_data(): The new image dimensions must match the texture size.
  <C++ Error>   Condition "p_image->get_width() != w || p_image->get_height() != h" is true.
  <C++ Source>  scene/resources/image_texture.cpp:98 @ update()
  <Stack Trace> raytracing.gd:74 @ _set_screen_texture_data()
                raytracing.gd:141 @ _render()
                raytracing.gd:51 @ _process()

E 0:00:01:158   raytracing.gd:74 @ _set_screen_texture_data(): The new image dimensions must match the texture size.
  <C++ Error>   Condition "p_image->get_width() != w || p_image->get_height() != h" is true.
  <C++ Source>  scene/resources/image_texture.cpp:98 @ update()
  <Stack Trace> raytracing.gd:74 @ _set_screen_texture_data()
                raytracing.gd:141 @ _render()
                raytracing.gd:51 @ _process()

E 0:00:01:211   raytracing.gd:73 @ _set_screen_texture_data(): Expected Image data size of 1135x638x16 (RGBAFloat without mipmaps) = 11586080 bytes, got 11943936 bytes instead.
  <C++ Error>   Method/function failed.
  <C++ Source>  core/io/image.cpp:2441 @ initialize_data()
  <Stack Trace> raytracing.gd:73 @ _set_screen_texture_data()
                raytracing.gd:141 @ _render()
                raytracing.gd:51 @ _process()

E 0:00:01:211   raytracing.gd:74 @ _set_screen_texture_data(): The new image dimensions must match the texture size.
  <C++ Error>   Condition "p_image->get_width() != w || p_image->get_height() != h" is true.
  <C++ Source>  scene/resources/image_texture.cpp:98 @ update()
  <Stack Trace> raytracing.gd:74 @ _set_screen_texture_data()
                raytracing.gd:141 @ _render()
                raytracing.gd:51 @ _process()

Which probably just means that I am trying to execute it with the image being too small than it should

My specs are:

  • RTX 4060
  • AMD Ryzen 5 5600 6-Core Processor
  • Gentoo Kernel 6.12.58-gentoo-dist

@Repiteo Repiteo requested a review from clayjohn January 26, 2026 20:53
@Repiteo
Copy link
Contributor

Repiteo commented Jan 27, 2026

@Fahien Anything else you'd want adjusted on this PR, or is it good to merge as-is?

@Fahien
Copy link
Contributor Author

Fahien commented Jan 27, 2026

@Repiteo: Anything else you'd want adjusted on this PR, or is it good to merge as-is?

It's good to go, thanks! :)

- Vulkan implementations in `RenderingDeviceDriverVulkan`.
- Raytracing instruction list in `RenderingDeviceGraph`.
- Functions to create acceleration structures and raytracing pipelines
  in `RenderingDevice`.
- Raygen, Miss, and ClosestHit shader stages support.
- GDScript bindings.
- Update classes documentation.
- Unimplemented placeholders for Metal and D3D12.
- Build acceleration structure command.
- Expose a shader preprocessor define.
- Align build scratch address.
- Create STB after creating the pipeline.
- Separate acceleration structure barriers.
- Use transforms in TLAS instances.
- AnyHit and Intersection stages.
- Optionally set acceleration structure build input buffer usage.
- Introduce instances buffer.
- Move scratch buffers to RenderingDevice.
- Rename AccelerationStructureGeometryBits.
- Use regular buffer creation and free routines for scratch buffer.
- Store trackers in acceleration structures.
- Bump Shader SPIR-V version to 1.4
- Add Position attribute location in blas_create.
- Encapsulate MoltenVK check in preprocessor macro.
- Split SUPPORTS_RAYTRACING for pipeline and query.
@Fahien Fahien force-pushed the fahien/raytracing-base branch from 84e285e to 27e4f24 Compare January 27, 2026 15:18
@Repiteo Repiteo modified the milestones: 4.x, 4.7 Jan 27, 2026
@Repiteo Repiteo merged commit 04a2ae7 into godotengine:master Jan 27, 2026
20 checks passed
@Repiteo
Copy link
Contributor

Repiteo commented Jan 27, 2026

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.