Implement hooks into renderer

This commit is contained in:
Bastiaan Olij 2023-08-03 22:10:03 +10:00
parent 5f05e2b9b1
commit 5a98845655
64 changed files with 2432 additions and 132 deletions

View file

@ -159,6 +159,9 @@
<member name="attributes" type="CameraAttributes" setter="set_attributes" getter="get_attributes">
The [CameraAttributes] to use for this camera.
</member>
<member name="compositor" type="Compositor" setter="set_compositor" getter="get_compositor">
The [Compositor] to use for this camera.
</member>
<member name="cull_mask" type="int" setter="set_cull_mask" getter="get_cull_mask" default="1048575">
The culling mask that describes which [member VisualInstance3D.layers] are rendered by this camera. By default, all 20 user-visible layers are rendered.
[b]Note:[/b] Since the [member cull_mask] allows for 32 layers to be stored in total, there are an additional 12 layers that are only used internally by the engine and aren't exposed in the editor. Setting [member cull_mask] using a script allows you to toggle those reserved layers, which can be useful for editor plugins.

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Compositor" inherits="Resource" experimental="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
The compositor resource holds the configuration with which rendering of a viewport can be customised.
</brief_description>
<description>
The compositor resource holds the configuration with which rendering of a viewport can be customised.
[b]Note:[/b] This functionality is still experimental as more customisation of the rendering pipeline will be added in the near future.
</description>
<tutorials>
</tutorials>
<members>
<member name="compositor_effects" type="CompositorEffect[]" setter="set_compositor_effects" getter="get_compositor_effects" default="[]">
The custom [CompositorEffect]s that are applied during rendering of viewports using this compositor.
</member>
</members>
</class>

View file

@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="CompositorEffect" inherits="Resource" experimental="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
This resource allows for creating a custom rendering effect.
</brief_description>
<description>
This resource defines a custom rendering effect that can be applied to [Viewport]s through the viewports' [Environment]. You can implement a callback that is called during rendering at a given stage of the rendering pipeline and allows you to insert additional passes. Note that this callback happens on the rendering thread.
[b]Note:[/b] This functionality is still experimental, there will be changes to the implementation as we expose more of the rendering internals.
</description>
<tutorials>
</tutorials>
<methods>
<method name="_render_callback" qualifiers="virtual">
<return type="void" />
<param index="0" name="effect_callback_type" type="int" />
<param index="1" name="render_data" type="RenderData" />
<description>
Implement this function with your custom rendering code. [param effect_callback_type] should always match the effect callback type you've specified in [member effect_callback_type]. [param render_data] provides access to the rendering state, it is only valid during rendering and should not be stored.
</description>
</method>
</methods>
<members>
<member name="access_resolved_color" type="bool" setter="set_access_resolved_color" getter="get_access_resolved_color">
If [code]true[/code] and MSAA is enabled, this will trigger a color buffer resolve before the effect is run.
[b]Note:[/b] In [method _render_callback], to access the resolved buffer use:
[codeblock]
var render_scene_buffers : RenderSceneBuffersRD = render_data.get_render_scene_buffers()
var color_buffer = render_scene_buffers.get_texture("render_buffers", "color")
[/codeblock]
</member>
<member name="access_resolved_depth" type="bool" setter="set_access_resolved_depth" getter="get_access_resolved_depth">
If [code]true[/code] and MSAA is enabled, this will trigger a depth buffer resolve before the effect is run.
[b]Note:[/b] In [method _render_callback], to access the resolved buffer use:
[codeblock]
var render_scene_buffers : RenderSceneBuffersRD = render_data.get_render_scene_buffers()
var depth_buffer = render_scene_buffers.get_texture("render_buffers", "depth")
[/codeblock]
</member>
<member name="effect_callback_type" type="int" setter="set_effect_callback_type" getter="get_effect_callback_type" enum="CompositorEffect.EffectCallbackType">
The type of effect that is implemented, determines at what stage of rendering the callback is called.
</member>
<member name="enabled" type="bool" setter="set_enabled" getter="get_enabled">
If [code]true[/code] this rendering effect is applied to any viewport it is added to.
</member>
<member name="needs_motion_vectors" type="bool" setter="set_needs_motion_vectors" getter="get_needs_motion_vectors">
If [code]true[/code] this triggers motion vectors being calculated during the opaque render state.
[b]Note:[/b] In [method _render_callback], to access the motion vector buffer use:
[codeblock]
var render_scene_buffers : RenderSceneBuffersRD = render_data.get_render_scene_buffers()
var motion_buffer = render_scene_buffers.get_velocity_texture()
[/codeblock]
</member>
<member name="needs_normal_roughness" type="bool" setter="set_needs_normal_roughness" getter="get_needs_normal_roughness">
If [code]true[/code] this triggers normal and roughness data to be output during our depth pre-pass, only applicable for the Forward+ renderer.
[b]Note:[/b] In [method _render_callback], to access the roughness buffer use:
[codeblock]
var render_scene_buffers : RenderSceneBuffersRD = render_data.get_render_scene_buffers()
var roughness_buffer = render_scene_buffers.get_texture("forward_clustered", "normal_roughness")
[/codeblock]
</member>
<member name="needs_separate_specular" type="bool" setter="set_needs_separate_specular" getter="get_needs_separate_specular">
If [code]true[/code] this triggers specular data being rendered to a separate buffer and combined after effects have been applied, only applicable for the Forward+ renderer.
</member>
</members>
<constants>
<constant name="EFFECT_CALLBACK_TYPE_PRE_OPAQUE" value="0" enum="EffectCallbackType">
The callback is called before our opaque rendering pass, but after depth prepass (if applicable).
</constant>
<constant name="EFFECT_CALLBACK_TYPE_POST_OPAQUE" value="1" enum="EffectCallbackType">
The callback is called after our opaque rendering pass, but before our sky is rendered.
</constant>
<constant name="EFFECT_CALLBACK_TYPE_POST_SKY" value="2" enum="EffectCallbackType">
The callback is called after our sky is rendered, but before our back buffers are created (and if enabled, before subsurface scattering and/or screen space reflections).
</constant>
<constant name="EFFECT_CALLBACK_TYPE_PRE_TRANSPARENT" value="3" enum="EffectCallbackType">
The callback is called before our transparent rendering pass, but after our sky is rendered and we've created our back buffers.
</constant>
<constant name="EFFECT_CALLBACK_TYPE_POST_TRANSPARENT" value="4" enum="EffectCallbackType">
The callback is called after our transparent rendering pass, but before any build in post effects and output to our render target.
</constant>
<constant name="EFFECT_CALLBACK_TYPE_MAX" value="5" enum="EffectCallbackType">
Represents the size of the [enum EffectCallbackType] enum.
</constant>
</constants>
</class>

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="FramebufferCacheRD" inherits="Object" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
Framebuffer cache manager for Rendering Device based renderers.
</brief_description>
<description>
Framebuffer cache manager for Rendering Device based renderers. Provides a way to create a framebuffer and reuse it in subsequent calls for as long as the used textures exists. Framebuffers will automatically be cleaned up when dependent objects are freed.
</description>
<tutorials>
</tutorials>
<methods>
<method name="get_cache_multipass" qualifiers="static">
<return type="RID" />
<param index="0" name="textures" type="RID[]" />
<param index="1" name="passes" type="RDFramebufferPass[]" />
<param index="2" name="views" type="int" />
<description>
Creates, or obtains a cached, framebuffer. [param textures] lists textures accessed. [param passes] defines the subpasses and texture allocation, if left empty a single pass is created and textures are allocated depending on their usage flags. [param views] defines the number of views used when rendering.
</description>
</method>
</methods>
</class>

View file

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="RenderData" inherits="Object" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
Abstract render data object, holds frame data related to rendering a single frame of a viewport.
</brief_description>
<description>
Abstract render data object, exists for the duration of rendering a single viewport.
[b]Note:[/b] This is an internal rendering server object, do not instantiate this from script.
</description>
<tutorials>
</tutorials>
<methods>
<method name="get_camera_attributes" qualifiers="const">
<return type="RID" />
<description>
Returns the [RID] of the camera attributes object in the [RenderingServer] being used to render this viewport.
</description>
</method>
<method name="get_environment" qualifiers="const">
<return type="RID" />
<description>
Returns the [RID] of the environments object in the [RenderingServer] being used to render this viewport.
</description>
</method>
<method name="get_render_scene_buffers" qualifiers="const">
<return type="RenderSceneBuffers" />
<description>
Returns the [RenderSceneBuffers] object managing the scene buffers for rendering this viewport.
</description>
</method>
<method name="get_render_scene_data" qualifiers="const">
<return type="RenderSceneData" />
<description>
Returns the [RenderSceneData] object managing this frames scene data.
</description>
</method>
</methods>
</class>

View file

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="RenderDataExtension" inherits="RenderData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
This class allows for a RenderData implementation to be made in GDExtension.
</brief_description>
<description>
This class allows for a RenderData implementation to be made in GDExtension.
</description>
<tutorials>
</tutorials>
<methods>
<method name="_get_camera_attributes" qualifiers="virtual const">
<return type="RID" />
<description>
Implement this in GDExtension to return the [RID] for the implementations camera attributes object.
</description>
</method>
<method name="_get_environment" qualifiers="virtual const">
<return type="RID" />
<description>
</description>
</method>
<method name="_get_render_scene_buffers" qualifiers="virtual const">
<return type="RenderSceneBuffers" />
<description>
Implement this in GDExtension to return the [RID] of the implementations environment object.
</description>
</method>
<method name="_get_render_scene_data" qualifiers="virtual const">
<return type="RenderSceneData" />
<description>
Implement this in GDExtension to return the implementations [RenderSceneDataExtension] object.
</description>
</method>
</methods>
</class>

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="RenderDataRD" inherits="RenderData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
Render data implementation for the RenderingDevice based renderers.
[b]Note:[/b] This is an internal rendering server object, do not instantiate this from script.
</brief_description>
<description>
This object manages all render data for the rendering device based renderers.
[b]Note:[/b] This is an internal rendering server object only exposed for GDExtension plugins.
</description>
<tutorials>
</tutorials>
</class>

View file

@ -5,7 +5,7 @@
</brief_description>
<description>
Abstract scene buffers object, created for each viewport for which 3D rendering is done. It manages any additional buffers used during rendering and will discard buffers when the viewport is resized.
[b]Note:[/b] this is an internal rendering server object only exposed for GDExtension plugins.
[b]Note:[/b] This is an internal rendering server object, do not instantiate this from script.
</description>
<tutorials>
</tutorials>

View file

@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="RenderSceneBuffersRD" inherits="RenderSceneBuffers" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
Abstract render scene buffer implementation for the RenderingDevice based renderers.
Render scene buffer implementation for the RenderingDevice based renderers.
</brief_description>
<description>
This object manages all 3D rendering buffers for the rendering device based renderers. An instance of this object is created for every viewport that has 3D rendering enabled.
All buffers are organized in [b]contexts[/b]. The default context is called [b]render_buffers[/b] and can contain amongst others the color buffer, depth buffer, velocity buffers, VRS density map and MSAA variants of these buffers.
Buffers are only guaranteed to exist during rendering of the viewport.
[b]Note:[/b] this is an internal rendering server object only exposed for GDExtension plugins.
[b]Note:[/b] This is an internal rendering server object, do not instantiate this from script.
</description>
<tutorials>
</tutorials>
@ -58,27 +58,35 @@
<method name="get_color_layer">
<return type="RID" />
<param index="0" name="layer" type="int" />
<param index="1" name="msaa" type="bool" default="false" />
<description>
Returns the specified layer from the color texture we are rendering 3D content to.
If [param msaa] is [b]true[/b] and MSAA is enabled, this returns the MSAA variant of the buffer.
</description>
</method>
<method name="get_color_texture">
<return type="RID" />
<param index="0" name="msaa" type="bool" default="false" />
<description>
Returns the color texture we are rendering 3D content to. If multiview is used this will be a texture array with all views.
If [param msaa] is [b]true[/b] and MSAA is enabled, this returns the MSAA variant of the buffer.
</description>
</method>
<method name="get_depth_layer">
<return type="RID" />
<param index="0" name="layer" type="int" />
<param index="1" name="msaa" type="bool" default="false" />
<description>
Returns the specified layer from the depth texture we are rendering 3D content to.
If [param msaa] is [b]true[/b] and MSAA is enabled, this returns the MSAA variant of the buffer.
</description>
</method>
<method name="get_depth_texture">
<return type="RID" />
<param index="0" name="msaa" type="bool" default="false" />
<description>
Returns the depth texture we are rendering 3D content to. If multiview is used this will be a texture array with all views.
If [param msaa] is [b]true[/b] and MSAA is enabled, this returns the MSAA variant of the buffer.
</description>
</method>
<method name="get_internal_size" qualifiers="const">
@ -87,6 +95,12 @@
Returns the internal size of the render buffer (size before upscaling) with which textures are created by default.
</description>
</method>
<method name="get_msaa_3d" qualifiers="const">
<return type="int" enum="RenderingServer.ViewportMSAA" />
<description>
Returns the applied 3D MSAA mode for this viewport.
</description>
</method>
<method name="get_render_target" qualifiers="const">
<return type="RID" />
<description>
@ -152,14 +166,17 @@
<method name="get_velocity_layer">
<return type="RID" />
<param index="0" name="layer" type="int" />
<param index="1" name="msaa" type="bool" default="false" />
<description>
Returns the specified layer from the velocity texture we are rendering 3D content to.
</description>
</method>
<method name="get_velocity_texture">
<return type="RID" />
<param index="0" name="msaa" type="bool" default="false" />
<description>
Returns the velocity texture we are rendering 3D content to. If multiview is used this will be a texture array with all views.
If [param msaa] is [b]true[/b] and MSAA is enabled, this returns the MSAA variant of the buffer.
</description>
</method>
<method name="get_view_count" qualifiers="const">

View file

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="RenderSceneData" inherits="Object" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
Abstract render data object, holds scene data related to rendering a single frame of a viewport.
</brief_description>
<description>
Abstract scene data object, exists for the duration of rendering a single viewport.
[b]Note:[/b] This is an internal rendering server object, do not instantiate this from script.
</description>
<tutorials>
</tutorials>
<methods>
<method name="get_cam_projection" qualifiers="const">
<return type="Projection" />
<description>
Returns the camera projection used to render this frame.
[b]Note:[/b] If more than one view is rendered, this will return a combined projection.
</description>
</method>
<method name="get_cam_transform" qualifiers="const">
<return type="Transform3D" />
<description>
Returns the camera transform used to render this frame.
[b]Note:[/b] If more than one view is rendered, this will return a centered transform.
</description>
</method>
<method name="get_uniform_buffer" qualifiers="const">
<return type="RID" />
<description>
Return the [RID] of the uniform buffer containing the scene data as a UBO.
</description>
</method>
<method name="get_view_count" qualifiers="const">
<return type="int" />
<description>
Returns the number of views being rendered.
</description>
</method>
<method name="get_view_eye_offset" qualifiers="const">
<return type="Vector3" />
<param index="0" name="view" type="int" />
<description>
Returns the eye offset per view used to render this frame. This is the offset between our camera transform and the eye transform.
</description>
</method>
<method name="get_view_projection" qualifiers="const">
<return type="Projection" />
<param index="0" name="view" type="int" />
<description>
Returns the view projection per view used to render this frame.
[b]Note:[/b] If a single view is rendered, this returns the camera projection. If more than one view is rendered, this will return a projection for the given view including the eye offset.
</description>
</method>
</methods>
</class>

View file

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="RenderSceneDataExtension" inherits="RenderSceneData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
This class allows for a RenderSceneData implementation to be made in GDExtension.
</brief_description>
<description>
This class allows for a RenderSceneData implementation to be made in GDExtension.
</description>
<tutorials>
</tutorials>
<methods>
<method name="_get_cam_projection" qualifiers="virtual const">
<return type="Projection" />
<description>
Implement this in GDExtension to return the camera [Projection].
</description>
</method>
<method name="_get_cam_transform" qualifiers="virtual const">
<return type="Transform3D" />
<description>
Implement this in GDExtension to return the camera [Transform3D].
</description>
</method>
<method name="_get_uniform_buffer" qualifiers="virtual const">
<return type="RID" />
<description>
Implement this in GDExtension to return the [RID] of the uniform buffer containing the scene data as a UBO.
</description>
</method>
<method name="_get_view_count" qualifiers="virtual const">
<return type="int" />
<description>
Implement this in GDExtension to return the view count.
</description>
</method>
<method name="_get_view_eye_offset" qualifiers="virtual const">
<return type="Vector3" />
<param index="0" name="view" type="int" />
<description>
Implement this in GDExtension to return the eye offset for the given [param view].
</description>
</method>
<method name="_get_view_projection" qualifiers="virtual const">
<return type="Projection" />
<param index="0" name="view" type="int" />
<description>
Implement this in GDExtension to return the view [Projection] for the given [param view].
</description>
</method>
</methods>
</class>

View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="RenderSceneDataRD" inherits="RenderSceneData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
Render scene data implementation for the RenderingDevice based renderers.
</brief_description>
<description>
Object holds scene data related to rendering a single frame of a viewport.
[b]Note:[/b] This is an internal rendering server object, do not instantiate this from script.
</description>
<tutorials>
</tutorials>
</class>

View file

@ -118,6 +118,14 @@
Sets the camera_attributes created with [method camera_attributes_create] to the given camera.
</description>
</method>
<method name="camera_set_compositor">
<return type="void" />
<param index="0" name="camera" type="RID" />
<param index="1" name="compositor" type="RID" />
<description>
Sets the compositor used by this camera. Equivalent to [member Camera3D.compositor].
</description>
</method>
<method name="camera_set_cull_mask">
<return type="void" />
<param index="0" name="camera" type="RID" />
@ -918,6 +926,54 @@
Sets the texture [param repeat] mode to use for the canvas texture specified by the [param canvas_texture] RID.
</description>
</method>
<method name="compositor_create">
<return type="RID" />
<description>
Creates a new compositor and adds it to the RenderingServer. It can be accessed with the RID that is returned.
Once finished with your RID, you will want to free the RID using the RenderingServer's [method free_rid] method.
</description>
</method>
<method name="compositor_effect_create">
<return type="RID" />
<description>
Creates a new rendering effect and adds it to the RenderingServer. It can be accessed with the RID that is returned.
Once finished with your RID, you will want to free the RID using the RenderingServer's [method free_rid] method.
</description>
</method>
<method name="compositor_effect_set_callback">
<return type="void" />
<param index="0" name="effect" type="RID" />
<param index="1" name="callback_type" type="int" enum="RenderingServer.CompositorEffectCallbackType" />
<param index="2" name="callback" type="Callable" />
<description>
Sets the callback type ([param callback_type]) and callback method([param callback]) for this rendering effect.
</description>
</method>
<method name="compositor_effect_set_enabled">
<return type="void" />
<param index="0" name="effect" type="RID" />
<param index="1" name="enabled" type="bool" />
<description>
Enables/disables this rendering effect.
</description>
</method>
<method name="compositor_effect_set_flag">
<return type="void" />
<param index="0" name="effect" type="RID" />
<param index="1" name="flag" type="int" enum="RenderingServer.CompositorEffectFlags" />
<param index="2" name="set" type="bool" />
<description>
Sets the flag ([param flag]) for this rendering effect to [code]true[/code] or [code]false[/code] ([param set]).
</description>
</method>
<method name="compositor_set_compositor_effects">
<return type="void" />
<param index="0" name="compositor" type="RID" />
<param index="1" name="effects" type="RID[]" />
<description>
Sets the compositor effects for the specified compositor RID. [param effects] should be an array containing RIDs created with [method compositor_effect_create].
</description>
</method>
<method name="create_local_rendering_device" qualifiers="const">
<return type="RenderingDevice" />
<description>
@ -3016,6 +3072,14 @@
Sets the camera attributes ([param effects]) that will be used with this scenario. See also [CameraAttributes].
</description>
</method>
<method name="scenario_set_compositor">
<return type="void" />
<param index="0" name="scenario" type="RID" />
<param index="1" name="compositor" type="RID" />
<description>
Sets the compositor ([param compositor]) that will be used with this scenario. See also [Compositor].
</description>
</method>
<method name="scenario_set_environment">
<return type="void" />
<param index="0" name="scenario" type="RID" />
@ -4833,6 +4897,38 @@
Uses the fast filtering algorithm to process the radiance map. In general this results in lower quality, but substantially faster run times. If you need better quality, but still need to update the sky every frame, consider turning on [member ProjectSettings.rendering/reflections/sky_reflections/fast_filter_high_quality].
[b]Note:[/b] The fast filtering algorithm is limited to 256×256 cubemaps, so [method sky_set_radiance_size] must be set to [code]256[/code]. Otherwise, a warning is printed and the overridden radiance size is ignored.
</constant>
<constant name="COMPOSITOR_EFFECT_FLAG_ACCESS_RESOLVED_COLOR" value="1" enum="CompositorEffectFlags">
The rendering effect requires the color buffer to be resolved if MSAA is enabled.
</constant>
<constant name="COMPOSITOR_EFFECT_FLAG_ACCESS_RESOLVED_DEPTH" value="2" enum="CompositorEffectFlags">
The rendering effect requires the depth buffer to be resolved if MSAA is enabled.
</constant>
<constant name="COMPOSITOR_EFFECT_FLAG_NEEDS_MOTION_VECTORS" value="4" enum="CompositorEffectFlags">
The rendering effect requires motion vectors to be produced.
</constant>
<constant name="COMPOSITOR_EFFECT_FLAG_NEEDS_ROUGHNESS" value="8" enum="CompositorEffectFlags">
The rendering effect requires normals and roughness g-buffer to be produced (Forward+ only).
</constant>
<constant name="COMPOSITOR_EFFECT_FLAG_NEEDS_SEPARATE_SPECULAR" value="16" enum="CompositorEffectFlags">
The rendering effect requires specular data to be separated out (Forward+ only).
</constant>
<constant name="COMPOSITOR_EFFECT_CALLBACK_TYPE_PRE_OPAQUE" value="0" enum="CompositorEffectCallbackType">
The callback is called before our opaque rendering pass, but after depth prepass (if applicable).
</constant>
<constant name="COMPOSITOR_EFFECT_CALLBACK_TYPE_POST_OPAQUE" value="1" enum="CompositorEffectCallbackType">
The callback is called after our opaque rendering pass, but before our sky is rendered.
</constant>
<constant name="COMPOSITOR_EFFECT_CALLBACK_TYPE_POST_SKY" value="2" enum="CompositorEffectCallbackType">
The callback is called after our sky is rendered, but before our back buffers are created (and if enabled, before subsurface scattering and/or screen space reflections).
</constant>
<constant name="COMPOSITOR_EFFECT_CALLBACK_TYPE_PRE_TRANSPARENT" value="3" enum="CompositorEffectCallbackType">
The callback is called before our transparent rendering pass, but after our sky is rendered and we've created our back buffers.
</constant>
<constant name="COMPOSITOR_EFFECT_CALLBACK_TYPE_POST_TRANSPARENT" value="4" enum="CompositorEffectCallbackType">
The callback is called after our transparent rendering pass, but before any build in post effects and output to our render target.
</constant>
<constant name="COMPOSITOR_EFFECT_CALLBACK_TYPE_ANY" value="-1" enum="CompositorEffectCallbackType">
</constant>
<constant name="ENV_BG_CLEAR_COLOR" value="0" enum="EnvironmentBG">
Use the clear color as background.
</constant>

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="UniformSetCacheRD" inherits="Object" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
Uniform set cache manager for Rendering Device based renderers.
</brief_description>
<description>
Uniform set cache manager for Rendering Device based renderers. Provides a way to create a uniform set and reuse it in subsequent calls for as long as the uniform set exists. Uniform set will automatically be cleaned up when dependent objects are freed.
</description>
<tutorials>
</tutorials>
<methods>
<method name="get_cache" qualifiers="static">
<return type="RID" />
<param index="0" name="shader" type="RID" />
<param index="1" name="set" type="int" />
<param index="2" name="uniforms" type="RDUniform[]" />
<description>
Creates/returns a cached uniform set based on the provided uniforms for a given shader.
</description>
</method>
</methods>
</class>

View file

@ -18,6 +18,9 @@
<member name="camera_attributes" type="CameraAttributes" setter="set_camera_attributes" getter="get_camera_attributes">
The default [CameraAttributes] resource to use if none set on the [Camera3D].
</member>
<member name="compositor" type="Compositor" setter="set_compositor" getter="get_compositor">
The default [Compositor] resource to use if none set on the [Camera3D].
</member>
<member name="environment" type="Environment" setter="set_environment" getter="get_environment">
The [Environment] resource used by this [WorldEnvironment], defining the default properties.
</member>

View file

@ -2310,7 +2310,7 @@ void RasterizerSceneGLES3::_render_shadow_pass(RID p_light, RID p_shadow_atlas,
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data, RenderingMethod::RenderInfo *r_render_info) {
void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_compositor, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data, RenderingMethod::RenderInfo *r_render_info) {
GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
GLES3::Config *config = GLES3::Config::get_singleton();
RENDER_TIMESTAMP("Setup 3D Scene");

View file

@ -737,7 +737,7 @@ public:
void voxel_gi_set_quality(RS::VoxelGIQuality) override;
void render_scene(const Ref<RenderSceneBuffers> &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RenderingMethod::RenderInfo *r_render_info = nullptr) override;
void render_scene(const Ref<RenderSceneBuffers> &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_compositor, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RenderingMethod::RenderInfo *r_render_info = nullptr) override;
void render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override;
void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<RenderGeometryInstance *> &p_instances) override;

View file

@ -147,3 +147,16 @@ GH-84792
Validate extension JSON: Error: Field 'classes/RenderingServer/methods/environment_set_fog/arguments': size changed value in new API, from 10 to 11.
Added fog mode argument. Compatibility method registered.
GH-80214
--------
Validate extension JSON: Error: Field 'classes/RenderSceneBuffersRD/methods/get_color_layer/arguments': size changed value in new API, from 1 to 2.
Validate extension JSON: Error: Field 'classes/RenderSceneBuffersRD/methods/get_depth_layer/arguments': size changed value in new API, from 1 to 2.
Validate extension JSON: Error: Field 'classes/RenderSceneBuffersRD/methods/get_velocity_layer/arguments': size changed value in new API, from 1 to 2.
Validate extension JSON: JSON file: Field was added in a way that breaks compatibility 'classes/RenderSceneBuffersRD/methods/get_color_texture': arguments
Validate extension JSON: JSON file: Field was added in a way that breaks compatibility 'classes/RenderSceneBuffersRD/methods/get_depth_texture': arguments
Validate extension JSON: JSON file: Field was added in a way that breaks compatibility 'classes/RenderSceneBuffersRD/methods/get_velocity_texture': arguments
MSAA flag was added, compatibility functions exist for these.

View file

@ -465,6 +465,20 @@ void Camera3D::_attributes_changed() {
_update_camera_mode();
}
void Camera3D::set_compositor(const Ref<Compositor> &p_compositor) {
compositor = p_compositor;
if (compositor.is_valid()) {
RS::get_singleton()->camera_set_compositor(camera, compositor->get_rid());
} else {
RS::get_singleton()->camera_set_compositor(camera, RID());
}
_update_camera_mode();
}
Ref<Compositor> Camera3D::get_compositor() const {
return compositor;
}
void Camera3D::set_keep_aspect_mode(KeepAspect p_aspect) {
keep_aspect = p_aspect;
RenderingServer::get_singleton()->camera_set_use_vertical_aspect(camera, p_aspect == KEEP_WIDTH);
@ -533,6 +547,8 @@ void Camera3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_environment"), &Camera3D::get_environment);
ClassDB::bind_method(D_METHOD("set_attributes", "env"), &Camera3D::set_attributes);
ClassDB::bind_method(D_METHOD("get_attributes"), &Camera3D::get_attributes);
ClassDB::bind_method(D_METHOD("set_compositor", "compositor"), &Camera3D::set_compositor);
ClassDB::bind_method(D_METHOD("get_compositor"), &Camera3D::get_compositor);
ClassDB::bind_method(D_METHOD("set_keep_aspect_mode", "mode"), &Camera3D::set_keep_aspect_mode);
ClassDB::bind_method(D_METHOD("get_keep_aspect_mode"), &Camera3D::get_keep_aspect_mode);
ClassDB::bind_method(D_METHOD("set_doppler_tracking", "mode"), &Camera3D::set_doppler_tracking);
@ -551,6 +567,7 @@ void Camera3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "cull_mask", PROPERTY_HINT_LAYERS_3D_RENDER), "set_cull_mask", "get_cull_mask");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "environment", PROPERTY_HINT_RESOURCE_TYPE, "Environment"), "set_environment", "get_environment");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "attributes", PROPERTY_HINT_RESOURCE_TYPE, "CameraAttributesPractical,CameraAttributesPhysical"), "set_attributes", "get_attributes");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "compositor", PROPERTY_HINT_RESOURCE_TYPE, "Compositor"), "set_compositor", "get_compositor");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "h_offset", PROPERTY_HINT_NONE, "suffix:m"), "set_h_offset", "get_h_offset");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "v_offset", PROPERTY_HINT_NONE, "suffix:m"), "set_v_offset", "get_v_offset");
ADD_PROPERTY(PropertyInfo(Variant::INT, "doppler_tracking", PROPERTY_HINT_ENUM, "Disabled,Idle,Physics"), "set_doppler_tracking", "get_doppler_tracking");

View file

@ -34,6 +34,7 @@
#include "scene/3d/node_3d.h"
#include "scene/3d/velocity_tracker_3d.h"
#include "scene/resources/camera_attributes.h"
#include "scene/resources/compositor.h"
#include "scene/resources/environment.h"
class Camera3D : public Node3D {
@ -83,6 +84,7 @@ private:
Ref<Environment> environment;
Ref<CameraAttributes> attributes;
Ref<Compositor> compositor;
void _attributes_changed();
// void _camera_make_current(Node *p_camera);
@ -167,6 +169,9 @@ public:
void set_attributes(const Ref<CameraAttributes> &p_effects);
Ref<CameraAttributes> get_attributes() const;
void set_compositor(const Ref<Compositor> &p_compositor);
Ref<Compositor> get_compositor() const;
void set_keep_aspect_mode(KeepAspect p_aspect);
KeepAspect get_keep_aspect_mode() const;

View file

@ -46,6 +46,11 @@ void WorldEnvironment::_notification(int p_what) {
add_to_group("_world_camera_attributes_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()));
_update_current_camera_attributes();
}
if (compositor.is_valid()) {
add_to_group("_world_compositor_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()));
_update_current_compositor();
}
} break;
case Node3D::NOTIFICATION_EXIT_WORLD:
@ -59,6 +64,11 @@ void WorldEnvironment::_notification(int p_what) {
remove_from_group("_world_camera_attributes_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()));
_update_current_camera_attributes();
}
if (compositor.is_valid()) {
remove_from_group("_world_compositor_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()));
_update_current_compositor();
}
} break;
}
}
@ -85,6 +95,17 @@ void WorldEnvironment::_update_current_camera_attributes() {
get_tree()->call_group_flags(SceneTree::GROUP_CALL_DEFERRED, "_world_camera_attributes_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()), "update_configuration_warnings");
}
void WorldEnvironment::_update_current_compositor() {
WorldEnvironment *first = Object::cast_to<WorldEnvironment>(get_tree()->get_first_node_in_group("_world_compositor_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id())));
if (first) {
get_viewport()->find_world_3d()->set_compositor(first->compositor);
} else {
get_viewport()->find_world_3d()->set_compositor(Ref<Compositor>());
}
get_tree()->call_group_flags(SceneTree::GROUP_CALL_DEFERRED, "_world_compositor_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()), "update_configuration_warnings");
}
void WorldEnvironment::set_environment(const Ref<Environment> &p_environment) {
if (environment == p_environment) {
return;
@ -135,6 +156,31 @@ Ref<CameraAttributes> WorldEnvironment::get_camera_attributes() const {
return camera_attributes;
}
void WorldEnvironment::set_compositor(const Ref<Compositor> &p_compositor) {
if (compositor == p_compositor) {
return;
}
if (is_inside_tree() && compositor.is_valid()) {
remove_from_group("_world_compositor_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()));
}
compositor = p_compositor;
if (is_inside_tree() && compositor.is_valid()) {
add_to_group("_world_compositor_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()));
}
if (is_inside_tree()) {
_update_current_compositor();
} else {
update_configuration_warnings();
}
}
Ref<Compositor> WorldEnvironment::get_compositor() const {
return compositor;
}
PackedStringArray WorldEnvironment::get_configuration_warnings() const {
PackedStringArray warnings = Node::get_configuration_warnings();
@ -154,6 +200,10 @@ PackedStringArray WorldEnvironment::get_configuration_warnings() const {
warnings.push_back(RTR("Only one WorldEnvironment is allowed per scene (or set of instantiated scenes)."));
}
if (compositor.is_valid() && get_viewport()->find_world_3d()->get_compositor() != compositor) {
warnings.push_back(("Only the first Compositor has an effect in a scene (or set of instantiated scenes)."));
}
return warnings;
}
@ -165,6 +215,10 @@ void WorldEnvironment::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_camera_attributes", "camera_attributes"), &WorldEnvironment::set_camera_attributes);
ClassDB::bind_method(D_METHOD("get_camera_attributes"), &WorldEnvironment::get_camera_attributes);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "camera_attributes", PROPERTY_HINT_RESOURCE_TYPE, "CameraAttributesPractical,CameraAttributesPhysical"), "set_camera_attributes", "get_camera_attributes");
ClassDB::bind_method(D_METHOD("set_compositor", "compositor"), &WorldEnvironment::set_compositor);
ClassDB::bind_method(D_METHOD("get_compositor"), &WorldEnvironment::get_compositor);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "compositor", PROPERTY_HINT_RESOURCE_TYPE, "Compositor"), "set_compositor", "get_compositor");
}
WorldEnvironment::WorldEnvironment() {

View file

@ -33,6 +33,7 @@
#include "scene/main/node.h"
#include "scene/resources/camera_attributes.h"
#include "scene/resources/compositor.h"
#include "scene/resources/environment.h"
class WorldEnvironment : public Node {
@ -40,9 +41,11 @@ class WorldEnvironment : public Node {
Ref<Environment> environment;
Ref<CameraAttributes> camera_attributes;
Ref<Compositor> compositor;
void _update_current_environment();
void _update_current_camera_attributes();
void _update_current_compositor();
protected:
void _notification(int p_what);
@ -55,6 +58,9 @@ public:
void set_camera_attributes(const Ref<CameraAttributes> &p_camera_attributes);
Ref<CameraAttributes> get_camera_attributes() const;
void set_compositor(const Ref<Compositor> &p_compositor);
Ref<Compositor> get_compositor() const;
PackedStringArray get_configuration_warnings() const override;
WorldEnvironment();

View file

@ -153,6 +153,7 @@
#include "scene/resources/capsule_shape_2d.h"
#include "scene/resources/capsule_shape_3d.h"
#include "scene/resources/circle_shape_2d.h"
#include "scene/resources/compositor.h"
#include "scene/resources/compressed_texture.h"
#include "scene/resources/concave_polygon_shape_2d.h"
#include "scene/resources/concave_polygon_shape_3d.h"
@ -341,6 +342,8 @@ void register_scene_types() {
GDREGISTER_CLASS(SubViewport);
GDREGISTER_CLASS(ViewportTexture);
GDREGISTER_VIRTUAL_CLASS(CompositorEffect);
GDREGISTER_ABSTRACT_CLASS(MultiplayerPeer);
GDREGISTER_CLASS(MultiplayerPeerExtension);
GDREGISTER_ABSTRACT_CLASS(MultiplayerAPI);
@ -865,6 +868,7 @@ void register_scene_types() {
GDREGISTER_CLASS(PhysicsMaterial);
GDREGISTER_CLASS(World3D);
GDREGISTER_CLASS(Compositor);
GDREGISTER_CLASS(Environment);
GDREGISTER_VIRTUAL_CLASS(CameraAttributes);
GDREGISTER_CLASS(CameraAttributesPhysical);

View file

@ -0,0 +1,250 @@
/**************************************************************************/
/* compositor.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#include "compositor.h"
#include "servers/rendering_server.h"
/* Compositor Effect */
void CompositorEffect::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &CompositorEffect::set_enabled);
ClassDB::bind_method(D_METHOD("get_enabled"), &CompositorEffect::get_enabled);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "get_enabled");
ClassDB::bind_method(D_METHOD("set_effect_callback_type", "effect_callback_type"), &CompositorEffect::set_effect_callback_type);
ClassDB::bind_method(D_METHOD("get_effect_callback_type"), &CompositorEffect::get_effect_callback_type);
ADD_PROPERTY(PropertyInfo(Variant::INT, "effect_callback_type", PROPERTY_HINT_ENUM, "Pre Opaque,Post Opaque,Post Sky,Pre Transparent,Post Transparent"), "set_effect_callback_type", "get_effect_callback_type");
ClassDB::bind_method(D_METHOD("set_access_resolved_color", "enable"), &CompositorEffect::set_access_resolved_color);
ClassDB::bind_method(D_METHOD("get_access_resolved_color"), &CompositorEffect::get_access_resolved_color);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "access_resolved_color"), "set_access_resolved_color", "get_access_resolved_color");
ClassDB::bind_method(D_METHOD("set_access_resolved_depth", "enable"), &CompositorEffect::set_access_resolved_depth);
ClassDB::bind_method(D_METHOD("get_access_resolved_depth"), &CompositorEffect::get_access_resolved_depth);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "access_resolved_depth"), "set_access_resolved_depth", "get_access_resolved_depth");
ClassDB::bind_method(D_METHOD("set_needs_motion_vectors", "enable"), &CompositorEffect::set_needs_motion_vectors);
ClassDB::bind_method(D_METHOD("get_needs_motion_vectors"), &CompositorEffect::get_needs_motion_vectors);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "needs_motion_vectors"), "set_needs_motion_vectors", "get_needs_motion_vectors");
ClassDB::bind_method(D_METHOD("set_needs_normal_roughness", "enable"), &CompositorEffect::set_needs_normal_roughness);
ClassDB::bind_method(D_METHOD("get_needs_normal_roughness"), &CompositorEffect::get_needs_normal_roughness);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "needs_normal_roughness"), "set_needs_normal_roughness", "get_needs_normal_roughness");
ClassDB::bind_method(D_METHOD("set_needs_separate_specular", "enable"), &CompositorEffect::set_needs_separate_specular);
ClassDB::bind_method(D_METHOD("get_needs_separate_specular"), &CompositorEffect::get_needs_separate_specular);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "needs_separate_specular"), "set_needs_separate_specular", "get_needs_separate_specular");
BIND_ENUM_CONSTANT(EFFECT_CALLBACK_TYPE_PRE_OPAQUE)
BIND_ENUM_CONSTANT(EFFECT_CALLBACK_TYPE_POST_OPAQUE)
BIND_ENUM_CONSTANT(EFFECT_CALLBACK_TYPE_POST_SKY)
BIND_ENUM_CONSTANT(EFFECT_CALLBACK_TYPE_PRE_TRANSPARENT)
BIND_ENUM_CONSTANT(EFFECT_CALLBACK_TYPE_POST_TRANSPARENT)
BIND_ENUM_CONSTANT(EFFECT_CALLBACK_TYPE_MAX)
GDVIRTUAL_BIND(_render_callback, "effect_callback_type", "render_data");
}
void CompositorEffect::_validate_property(PropertyInfo &p_property) const {
if (p_property.name == "access_resolved_color" && effect_callback_type == EFFECT_CALLBACK_TYPE_POST_TRANSPARENT) {
p_property.usage = PROPERTY_USAGE_NONE;
}
if (p_property.name == "access_resolved_depth" && effect_callback_type == EFFECT_CALLBACK_TYPE_POST_TRANSPARENT) {
p_property.usage = PROPERTY_USAGE_NONE;
}
if (p_property.name == "needs_separate_specular" && effect_callback_type != EFFECT_CALLBACK_TYPE_POST_SKY) {
p_property.usage = PROPERTY_USAGE_NONE;
}
}
void CompositorEffect::set_enabled(bool p_enabled) {
enabled = p_enabled;
if (rid.is_valid()) {
RenderingServer *rs = RenderingServer::get_singleton();
ERR_FAIL_NULL(rs);
rs->compositor_effect_set_enabled(rid, enabled);
}
}
bool CompositorEffect::get_enabled() const {
return enabled;
}
void CompositorEffect::set_effect_callback_type(EffectCallbackType p_callback_type) {
effect_callback_type = p_callback_type;
notify_property_list_changed();
if (rid.is_valid()) {
RenderingServer *rs = RenderingServer::get_singleton();
ERR_FAIL_NULL(rs);
rs->compositor_effect_set_callback(rid, RenderingServer::CompositorEffectCallbackType(effect_callback_type), Callable(this, "_render_callback"));
}
}
CompositorEffect::EffectCallbackType CompositorEffect::get_effect_callback_type() const {
return effect_callback_type;
}
void CompositorEffect::set_access_resolved_color(bool p_enabled) {
access_resolved_color = p_enabled;
if (rid.is_valid()) {
RenderingServer *rs = RenderingServer::get_singleton();
ERR_FAIL_NULL(rs);
rs->compositor_effect_set_flag(rid, RS::CompositorEffectFlags::COMPOSITOR_EFFECT_FLAG_ACCESS_RESOLVED_COLOR, access_resolved_color);
}
}
bool CompositorEffect::get_access_resolved_color() const {
return access_resolved_color;
}
void CompositorEffect::set_access_resolved_depth(bool p_enabled) {
access_resolved_depth = p_enabled;
if (rid.is_valid()) {
RenderingServer *rs = RenderingServer::get_singleton();
ERR_FAIL_NULL(rs);
rs->compositor_effect_set_flag(rid, RS::CompositorEffectFlags::COMPOSITOR_EFFECT_FLAG_ACCESS_RESOLVED_DEPTH, access_resolved_depth);
}
}
bool CompositorEffect::get_access_resolved_depth() const {
return access_resolved_depth;
}
void CompositorEffect::set_needs_motion_vectors(bool p_enabled) {
needs_motion_vectors = p_enabled;
if (rid.is_valid()) {
RenderingServer *rs = RenderingServer::get_singleton();
ERR_FAIL_NULL(rs);
rs->compositor_effect_set_flag(rid, RS::CompositorEffectFlags::COMPOSITOR_EFFECT_FLAG_NEEDS_MOTION_VECTORS, needs_motion_vectors);
}
}
bool CompositorEffect::get_needs_motion_vectors() const {
return needs_motion_vectors;
}
void CompositorEffect::set_needs_normal_roughness(bool p_enabled) {
needs_normal_roughness = p_enabled;
if (rid.is_valid()) {
RenderingServer *rs = RenderingServer::get_singleton();
ERR_FAIL_NULL(rs);
rs->compositor_effect_set_flag(rid, RS::CompositorEffectFlags::COMPOSITOR_EFFECT_FLAG_NEEDS_ROUGHNESS, needs_normal_roughness);
}
}
bool CompositorEffect::get_needs_normal_roughness() const {
return needs_normal_roughness;
}
void CompositorEffect::set_needs_separate_specular(bool p_enabled) {
needs_separate_specular = p_enabled;
if (rid.is_valid()) {
RenderingServer *rs = RenderingServer::get_singleton();
ERR_FAIL_NULL(rs);
rs->compositor_effect_set_flag(rid, RS::CompositorEffectFlags::COMPOSITOR_EFFECT_FLAG_NEEDS_SEPARATE_SPECULAR, needs_separate_specular);
}
}
bool CompositorEffect::get_needs_separate_specular() const {
return needs_separate_specular;
}
CompositorEffect::CompositorEffect() {
RenderingServer *rs = RenderingServer::get_singleton();
if (rs != nullptr) {
rid = rs->compositor_effect_create();
rs->compositor_effect_set_callback(rid, RenderingServer::CompositorEffectCallbackType(effect_callback_type), Callable(this, "_render_callback"));
}
}
CompositorEffect::~CompositorEffect() {
RenderingServer *rs = RenderingServer::get_singleton();
if (rs != nullptr && rid.is_valid()) {
rs->free(rid);
}
}
/* Compositor */
void Compositor::_bind_methods() {
// compositor effects
ClassDB::bind_method(D_METHOD("set_compositor_effects", "compositor_effects"), &Compositor::set_compositor_effects);
ClassDB::bind_method(D_METHOD("get_compositor_effects"), &Compositor::get_compositor_effects);
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "compositor_effects", PROPERTY_HINT_ARRAY_TYPE, MAKE_RESOURCE_TYPE_HINT("CompositorEffect")), "set_compositor_effects", "get_compositor_effects");
}
Compositor::Compositor() {
RenderingServer *rs = RenderingServer::get_singleton();
if (rs != nullptr) {
compositor = rs->compositor_create();
}
}
Compositor::~Compositor() {
RenderingServer *rs = RenderingServer::get_singleton();
if (rs != nullptr && compositor.is_valid()) {
rs->free(compositor);
}
}
// Compositor effects
void Compositor::set_compositor_effects(const TypedArray<CompositorEffect> &p_compositor_effects) {
Array effect_rids;
effects.clear();
for (int i = 0; i < p_compositor_effects.size(); i++) {
// Cast to proper ref, if our object isn't a CompositorEffect resource this will be an empty Ref.
Ref<CompositorEffect> compositor_effect = p_compositor_effects[i];
// We add the effect even if this is an empty Ref, this allows the UI to add new entries.
effects.push_back(compositor_effect);
// But we only add a rid for valid Refs
if (compositor_effect.is_valid()) {
RID rid = compositor_effect->get_rid();
effect_rids.push_back(rid);
}
}
RenderingServer::get_singleton()->compositor_set_compositor_effects(compositor, effect_rids);
}
TypedArray<CompositorEffect> Compositor::get_compositor_effects() const {
TypedArray<CompositorEffect> arr;
for (uint32_t i = 0; i < effects.size(); i++) {
arr.push_back(effects[i]);
}
return arr;
}

View file

@ -0,0 +1,125 @@
/**************************************************************************/
/* compositor.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef COMPOSITOR_H
#define COMPOSITOR_H
#include "core/io/resource.h"
#include "core/object/gdvirtual.gen.inc"
#include "servers/rendering/storage/render_data.h"
/* Compositor Effect */
class CompositorEffect : public Resource {
GDCLASS(CompositorEffect, Resource);
public:
enum EffectCallbackType {
EFFECT_CALLBACK_TYPE_PRE_OPAQUE,
EFFECT_CALLBACK_TYPE_POST_OPAQUE,
EFFECT_CALLBACK_TYPE_POST_SKY,
EFFECT_CALLBACK_TYPE_PRE_TRANSPARENT,
EFFECT_CALLBACK_TYPE_POST_TRANSPARENT,
EFFECT_CALLBACK_TYPE_MAX
};
private:
RID rid;
bool enabled = true;
EffectCallbackType effect_callback_type = EFFECT_CALLBACK_TYPE_POST_TRANSPARENT;
bool access_resolved_color = false;
bool access_resolved_depth = false;
bool needs_motion_vectors = false;
bool needs_normal_roughness = false;
bool needs_separate_specular = false;
protected:
static void _bind_methods();
void _validate_property(PropertyInfo &p_property) const;
GDVIRTUAL2(_render_callback, int, const RenderData *)
public:
virtual RID get_rid() const override { return rid; }
void set_enabled(bool p_enabled);
bool get_enabled() const;
void set_effect_callback_type(EffectCallbackType p_callback_type);
EffectCallbackType get_effect_callback_type() const;
void set_access_resolved_color(bool p_enabled);
bool get_access_resolved_color() const;
void set_access_resolved_depth(bool p_enabled);
bool get_access_resolved_depth() const;
void set_needs_motion_vectors(bool p_enabled);
bool get_needs_motion_vectors() const;
void set_needs_normal_roughness(bool p_enabled);
bool get_needs_normal_roughness() const;
void set_needs_separate_specular(bool p_enabled);
bool get_needs_separate_specular() const;
CompositorEffect();
~CompositorEffect();
};
VARIANT_ENUM_CAST(CompositorEffect::EffectCallbackType)
/* Compositor */
class Compositor : public Resource {
GDCLASS(Compositor, Resource);
private:
RID compositor;
// Compositor effects
LocalVector<Ref<CompositorEffect>> effects;
protected:
static void _bind_methods();
public:
virtual RID get_rid() const override { return compositor; }
Compositor();
~Compositor();
// Compositor effects
void set_compositor_effects(const TypedArray<CompositorEffect> &p_compositor_effects);
TypedArray<CompositorEffect> get_compositor_effects() const;
};
#endif // COMPOSITOR_H

View file

@ -132,6 +132,19 @@ Ref<CameraAttributes> World3D::get_camera_attributes() const {
return camera_attributes;
}
void World3D::set_compositor(const Ref<Compositor> &p_compositor) {
compositor = p_compositor;
if (compositor.is_valid()) {
RS::get_singleton()->scenario_set_compositor(scenario, compositor->get_rid());
} else {
RS::get_singleton()->scenario_set_compositor(scenario, RID());
}
}
Ref<Compositor> World3D::get_compositor() const {
return compositor;
}
PhysicsDirectSpaceState3D *World3D::get_direct_space_state() {
return PhysicsServer3D::get_singleton()->space_get_direct_state(get_space());
}

View file

@ -32,6 +32,7 @@
#define WORLD_3D_H
#include "core/io/resource.h"
#include "scene/resources/compositor.h"
#include "scene/resources/environment.h"
#include "servers/physics_server_3d.h"
#include "servers/rendering_server.h"
@ -52,6 +53,7 @@ private:
Ref<Environment> environment;
Ref<Environment> fallback_environment;
Ref<CameraAttributes> camera_attributes;
Ref<Compositor> compositor;
HashSet<Camera3D *> cameras;
@ -77,6 +79,9 @@ public:
void set_camera_attributes(const Ref<CameraAttributes> &p_camera_attributes);
Ref<CameraAttributes> get_camera_attributes() const;
void set_compositor(const Ref<Compositor> &p_compositor);
Ref<Compositor> get_compositor() const;
_FORCE_INLINE_ const HashSet<Camera3D *> &get_cameras() const { return cameras; }
PhysicsDirectSpaceState3D *get_direct_space_state();

View file

@ -69,10 +69,16 @@
#include "physics_server_3d.h"
#include "physics_server_3d_wrap_mt.h"
#include "rendering/renderer_compositor.h"
#include "rendering/renderer_rd/framebuffer_cache_rd.h"
#include "rendering/renderer_rd/storage_rd/render_data_rd.h"
#include "rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h"
#include "rendering/renderer_rd/storage_rd/render_scene_data_rd.h"
#include "rendering/renderer_rd/uniform_set_cache_rd.h"
#include "rendering/rendering_device.h"
#include "rendering/rendering_device_binds.h"
#include "rendering/storage/render_data.h"
#include "rendering/storage/render_scene_buffers.h"
#include "rendering/storage/render_scene_data.h"
#include "rendering_server.h"
#include "servers/extensions/physics_server_2d_extension.h"
#include "servers/extensions/physics_server_3d_extension.h"
@ -259,10 +265,21 @@ void register_server_types() {
GDREGISTER_CLASS(RDShaderFile);
GDREGISTER_CLASS(RDPipelineSpecializationConstant);
GDREGISTER_ABSTRACT_CLASS(RenderData);
GDREGISTER_CLASS(RenderDataExtension);
GDREGISTER_CLASS(RenderDataRD);
GDREGISTER_ABSTRACT_CLASS(RenderSceneData);
GDREGISTER_CLASS(RenderSceneDataExtension);
GDREGISTER_CLASS(RenderSceneDataRD);
GDREGISTER_CLASS(RenderSceneBuffersConfiguration);
GDREGISTER_ABSTRACT_CLASS(RenderSceneBuffers);
GDREGISTER_CLASS(RenderSceneBuffersExtension);
GDREGISTER_ABSTRACT_CLASS(RenderSceneBuffersRD);
GDREGISTER_CLASS(RenderSceneBuffersRD);
GDREGISTER_CLASS(FramebufferCacheRD);
GDREGISTER_CLASS(UniformSetCacheRD);
GDREGISTER_CLASS(CameraFeed);

View file

@ -145,7 +145,7 @@ public:
void voxel_gi_set_quality(RS::VoxelGIQuality) override {}
void render_scene(const Ref<RenderSceneBuffers> &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RenderingMethod::RenderInfo *r_info = nullptr) override {}
void render_scene(const Ref<RenderSceneBuffers> &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_compositor, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RenderingMethod::RenderInfo *r_info = nullptr) override {}
void render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override {}
void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<RenderGeometryInstance *> &p_instances) override {}
@ -168,6 +168,12 @@ public:
if (is_environment(p_rid)) {
environment_free(p_rid);
return true;
} else if (is_compositor(p_rid)) {
compositor_free(p_rid);
return true;
} else if (is_compositor_effect(p_rid)) {
compositor_effect_free(p_rid);
return true;
} else if (RSG::camera_attributes->owns_camera_attributes(p_rid)) {
RSG::camera_attributes->camera_attributes_free(p_rid);
return true;

View file

@ -56,7 +56,7 @@
#define RB_TEX_REFLECTION SNAME("reflection")
// Forward declare RenderDataRD and RendererSceneRenderRD so we can pass it into some of our methods, these classes are pretty tightly bound
struct RenderDataRD;
class RenderDataRD;
class RendererSceneRenderRD;
namespace RendererRD {

View file

@ -67,7 +67,7 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_specular()
void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_normal_roughness_texture() {
ERR_FAIL_NULL(render_buffers);
if (!render_buffers->has_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_ROUGHNESS)) {
if (!render_buffers->has_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_NORMAL_ROUGHNESS)) {
RD::DataFormat format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
uint32_t usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
@ -77,11 +77,11 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_normal_rou
usage_bits |= RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
}
render_buffers->create_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_ROUGHNESS, format, usage_bits);
render_buffers->create_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_NORMAL_ROUGHNESS, format, usage_bits);
if (render_buffers->get_msaa_3d() != RS::VIEWPORT_MSAA_DISABLED) {
usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT;
render_buffers->create_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_ROUGHNESS_MSAA, format, usage_bits, render_buffers->get_texture_samples());
render_buffers->create_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_NORMAL_ROUGHNESS_MSAA, format, usage_bits, render_buffers->get_texture_samples());
}
}
}
@ -214,7 +214,7 @@ RID RenderForwardClustered::RenderBufferDataForwardClustered::get_depth_fb(Depth
case DEPTH_FB_ROUGHNESS: {
ensure_normal_roughness_texture();
RID normal_roughness_buffer = render_buffers->get_texture(RB_SCOPE_FORWARD_CLUSTERED, use_msaa ? RB_TEX_ROUGHNESS_MSAA : RB_TEX_ROUGHNESS);
RID normal_roughness_buffer = render_buffers->get_texture(RB_SCOPE_FORWARD_CLUSTERED, use_msaa ? RB_TEX_NORMAL_ROUGHNESS_MSAA : RB_TEX_NORMAL_ROUGHNESS);
return FramebufferCacheRD::get_singleton()->get_cache_multiview(render_buffers->get_view_count(), depth, normal_roughness_buffer);
} break;
@ -222,7 +222,7 @@ RID RenderForwardClustered::RenderBufferDataForwardClustered::get_depth_fb(Depth
ensure_normal_roughness_texture();
ensure_voxelgi();
RID normal_roughness_buffer = render_buffers->get_texture(RB_SCOPE_FORWARD_CLUSTERED, use_msaa ? RB_TEX_ROUGHNESS_MSAA : RB_TEX_ROUGHNESS);
RID normal_roughness_buffer = render_buffers->get_texture(RB_SCOPE_FORWARD_CLUSTERED, use_msaa ? RB_TEX_NORMAL_ROUGHNESS_MSAA : RB_TEX_NORMAL_ROUGHNESS);
RID voxelgi_buffer = render_buffers->get_texture(RB_SCOPE_FORWARD_CLUSTERED, use_msaa ? RB_TEX_VOXEL_GI_MSAA : RB_TEX_VOXEL_GI);
return FramebufferCacheRD::get_singleton()->get_cache_multiview(render_buffers->get_view_count(), depth, normal_roughness_buffer, voxelgi_buffer);
@ -1578,6 +1578,11 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
RENDER_TIMESTAMP("Prepare 3D Scene");
// get info about our rendering effects
bool ce_needs_motion_vectors = _compositor_effects_has_flag(p_render_data, RS::COMPOSITOR_EFFECT_FLAG_NEEDS_MOTION_VECTORS);
bool ce_needs_normal_roughness = _compositor_effects_has_flag(p_render_data, RS::COMPOSITOR_EFFECT_FLAG_NEEDS_ROUGHNESS);
bool ce_needs_separate_specular = _compositor_effects_has_flag(p_render_data, RS::COMPOSITOR_EFFECT_FLAG_NEEDS_SEPARATE_SPECULAR);
// sdfgi first
_update_sdfgi(p_render_data);
@ -1632,6 +1637,8 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
bool motion_vectors_required;
if (using_debug_mvs) {
motion_vectors_required = true;
} else if (ce_needs_motion_vectors) {
motion_vectors_required = true;
} else if (!is_reflection_probe && using_taa) {
motion_vectors_required = true;
} else if (!is_reflection_probe && using_fsr2) {
@ -1738,10 +1745,11 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
if (using_voxelgi) {
depth_pass_mode = PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI;
} else if (p_render_data->environment.is_valid()) {
if (environment_get_ssr_enabled(p_render_data->environment) ||
environment_get_sdfgi_enabled(p_render_data->environment) ||
if (using_ssr ||
using_sdfgi ||
environment_get_ssao_enabled(p_render_data->environment) ||
using_ssil ||
ce_needs_normal_roughness ||
get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_NORMAL_BUFFER ||
scene_state.used_normal_texture) {
depth_pass_mode = PASS_MODE_DEPTH_NORMAL_ROUGHNESS;
@ -1770,7 +1778,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
bool using_sss = rb_data.is_valid() && !is_reflection_probe && scene_state.used_sss && ss_effects->sss_get_quality() != RS::SUB_SURFACE_SCATTERING_QUALITY_DISABLED;
if (using_sss && !using_separate_specular) {
if ((using_sss || ce_needs_separate_specular) && !using_separate_specular) {
using_separate_specular = true;
color_pass_flags |= COLOR_PASS_FLAG_SEPARATE_SPECULAR;
color_framebuffer = rb_data->get_color_pass_fb(color_pass_flags);
@ -1880,6 +1888,17 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
clear_color = p_default_bg_color;
}
RS::ViewportMSAA msaa = rb->get_msaa_3d();
bool use_msaa = msaa != RS::VIEWPORT_MSAA_DISABLED;
bool ce_pre_opaque_resolved_color = use_msaa && _compositor_effects_has_flag(p_render_data, RS::COMPOSITOR_EFFECT_FLAG_ACCESS_RESOLVED_COLOR, RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_PRE_OPAQUE);
bool ce_post_opaque_resolved_color = use_msaa && _compositor_effects_has_flag(p_render_data, RS::COMPOSITOR_EFFECT_FLAG_ACCESS_RESOLVED_COLOR, RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_POST_OPAQUE);
bool ce_pre_transparent_resolved_color = use_msaa && _compositor_effects_has_flag(p_render_data, RS::COMPOSITOR_EFFECT_FLAG_ACCESS_RESOLVED_COLOR, RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_PRE_TRANSPARENT);
bool ce_pre_opaque_resolved_depth = use_msaa && _compositor_effects_has_flag(p_render_data, RS::COMPOSITOR_EFFECT_FLAG_ACCESS_RESOLVED_DEPTH, RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_PRE_OPAQUE);
bool ce_post_opaque_resolved_depth = use_msaa && _compositor_effects_has_flag(p_render_data, RS::COMPOSITOR_EFFECT_FLAG_ACCESS_RESOLVED_DEPTH, RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_POST_OPAQUE);
bool ce_pre_transparent_resolved_depth = use_msaa && _compositor_effects_has_flag(p_render_data, RS::COMPOSITOR_EFFECT_FLAG_ACCESS_RESOLVED_DEPTH, RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_PRE_TRANSPARENT);
bool debug_voxelgis = get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_VOXEL_GI_ALBEDO || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_VOXEL_GI_LIGHTING || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_VOXEL_GI_EMISSION;
bool debug_sdfgi_probes = get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_SDFGI_PROBES;
bool depth_pre_pass = bool(GLOBAL_GET("rendering/driver/depth_prepass/enable")) && depth_framebuffer.is_valid();
@ -1892,8 +1911,8 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
}
bool using_ssao = depth_pre_pass && !is_reflection_probe && p_render_data->environment.is_valid() && environment_get_ssao_enabled(p_render_data->environment);
if (depth_pre_pass) { //depth pre pass
if (depth_pre_pass) { //depth pre pass
bool needs_pre_resolve = _needs_post_prepass_render(p_render_data, using_sdfgi || using_voxelgi);
if (needs_pre_resolve) {
RENDER_TIMESTAMP("GI + Render Depth Pre-Pass (Parallel)");
@ -1912,28 +1931,42 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, nullptr, RID(), samplers);
bool finish_depth = using_ssao || using_ssil || using_sdfgi || using_voxelgi;
bool finish_depth = using_ssao || using_ssil || using_sdfgi || using_voxelgi || ce_pre_opaque_resolved_depth || ce_post_opaque_resolved_depth;
RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, depth_pass_mode, 0, rb_data.is_null(), p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, p_render_data->scene_data->view_count, 0, spec_constant_base_flags);
_render_list_with_draw_list(&render_list_params, depth_framebuffer, needs_pre_resolve ? RD::INITIAL_ACTION_LOAD : RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, needs_pre_resolve ? RD::INITIAL_ACTION_LOAD : RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, needs_pre_resolve ? Vector<Color>() : depth_pass_clear);
RD::get_singleton()->draw_command_end_label();
if (rb->get_msaa_3d() != RS::VIEWPORT_MSAA_DISABLED) {
if (use_msaa) {
RENDER_TIMESTAMP("Resolve Depth Pre-Pass (MSAA)");
RD::get_singleton()->draw_command_begin_label("Resolve Depth Pre-Pass (MSAA)");
if (depth_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS || depth_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI) {
for (uint32_t v = 0; v < rb->get_view_count(); v++) {
resolve_effects->resolve_gi(rb->get_depth_msaa(v), rb_data->get_normal_roughness_msaa(v), using_voxelgi ? rb_data->get_voxelgi_msaa(v) : RID(), rb->get_depth_texture(v), rb_data->get_normal_roughness(v), using_voxelgi ? rb_data->get_voxelgi(v) : RID(), rb->get_internal_size(), texture_multisamples[rb->get_msaa_3d()]);
resolve_effects->resolve_gi(rb->get_depth_msaa(v), rb_data->get_normal_roughness_msaa(v), using_voxelgi ? rb_data->get_voxelgi_msaa(v) : RID(), rb->get_depth_texture(v), rb_data->get_normal_roughness(v), using_voxelgi ? rb_data->get_voxelgi(v) : RID(), rb->get_internal_size(), texture_multisamples[msaa]);
}
} else if (finish_depth) {
for (uint32_t v = 0; v < rb->get_view_count(); v++) {
resolve_effects->resolve_depth(rb->get_depth_msaa(v), rb->get_depth_texture(v), rb->get_internal_size(), texture_multisamples[rb->get_msaa_3d()]);
resolve_effects->resolve_depth(rb->get_depth_msaa(v), rb->get_depth_texture(v), rb->get_internal_size(), texture_multisamples[msaa]);
}
}
RD::get_singleton()->draw_command_end_label();
}
}
{
if (ce_pre_opaque_resolved_color) {
// We haven't rendered color data yet so...
WARN_PRINT_ONCE("Pre opaque rendering effects can't access resolved color buffers.");
}
if (ce_pre_opaque_resolved_depth && !depth_pre_pass) {
// We haven't rendered depth data yet so...
WARN_PRINT_ONCE("Pre opaque rendering effects can't access resolved depth buffers.");
}
_process_compositor_effects(RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_PRE_OPAQUE, p_render_data);
}
RID normal_roughness_views[RendererSceneRender::MAX_RENDER_VIEWS];
if (rb_data.is_valid() && rb_data->has_normal_roughness()) {
for (uint32_t v = 0; v < rb->get_view_count(); v++) {
@ -1955,8 +1988,6 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
RENDER_TIMESTAMP("Render Opaque Pass");
RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, p_render_data, radiance_texture, samplers, true);
bool can_continue_color = !scene_state.used_screen_texture && !using_ssr && !using_sss;
bool can_continue_depth = !(scene_state.used_depth_texture || scene_state.used_normal_texture) && !using_ssr && !using_sss;
{
bool render_motion_pass = !render_list[RENDER_LIST_MOTION].elements.is_empty();
@ -2006,6 +2037,22 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
}
}
{
if (ce_post_opaque_resolved_color) {
for (uint32_t v = 0; v < rb->get_view_count(); v++) {
RD::get_singleton()->texture_resolve_multisample(rb->get_color_msaa(v), rb->get_internal_texture(v));
}
}
if (ce_post_opaque_resolved_depth) {
for (uint32_t v = 0; v < rb->get_view_count(); v++) {
resolve_effects->resolve_depth(rb->get_depth_msaa(v), rb->get_depth_texture(v), rb->get_internal_size(), texture_multisamples[msaa]);
}
}
_process_compositor_effects(RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_POST_OPAQUE, p_render_data);
}
if (debug_voxelgis) {
Projection dc;
dc.set_depth_correction(true);
@ -2040,11 +2087,11 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
RD::get_singleton()->draw_list_end();
RD::get_singleton()->draw_command_end_label();
}
if (rb->get_msaa_3d() != RS::VIEWPORT_MSAA_DISABLED) {
if (use_msaa) {
RENDER_TIMESTAMP("Resolve MSAA");
if (!can_continue_color) {
// Handle views individual, might want to look at rewriting our resolve to do both layers in one pass.
if (scene_state.used_screen_texture || using_separate_specular || ce_pre_transparent_resolved_color) {
for (uint32_t v = 0; v < rb->get_view_count(); v++) {
RD::get_singleton()->texture_resolve_multisample(rb->get_color_msaa(v), rb->get_internal_texture(v));
}
@ -2055,13 +2102,18 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
}
}
if (!can_continue_depth) {
if (scene_state.used_depth_texture || scene_state.used_normal_texture || using_separate_specular || ce_needs_normal_roughness || ce_pre_transparent_resolved_depth) {
for (uint32_t v = 0; v < rb->get_view_count(); v++) {
resolve_effects->resolve_depth(rb->get_depth_msaa(v), rb->get_depth_texture(v), rb->get_internal_size(), texture_multisamples[rb->get_msaa_3d()]);
resolve_effects->resolve_depth(rb->get_depth_msaa(v), rb->get_depth_texture(v), rb->get_internal_size(), texture_multisamples[msaa]);
}
}
}
{
// Don't need to check for depth or color resolve here, we've already triggered it.
_process_compositor_effects(RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_POST_SKY, p_render_data);
}
if (using_separate_specular) {
if (using_sss) {
RENDER_TIMESTAMP("Sub-Surface Scattering");
@ -2077,12 +2129,12 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
for (uint32_t v = 0; v < p_render_data->scene_data->view_count; v++) {
specular_views[v] = rb_data->get_specular(v);
}
_process_ssr(rb, color_only_framebuffer, normal_roughness_views, rb_data->get_specular(), specular_views, p_render_data->environment, p_render_data->scene_data->view_projection, p_render_data->scene_data->view_eye_offset, rb->get_msaa_3d() == RS::VIEWPORT_MSAA_DISABLED);
_process_ssr(rb, color_only_framebuffer, normal_roughness_views, rb_data->get_specular(), specular_views, p_render_data->environment, p_render_data->scene_data->view_projection, p_render_data->scene_data->view_eye_offset, !use_msaa);
RD::get_singleton()->draw_command_end_label();
} else {
//just mix specular back
RENDER_TIMESTAMP("Merge Specular");
copy_effects->merge_specular(color_only_framebuffer, rb_data->get_specular(), rb->get_msaa_3d() == RS::VIEWPORT_MSAA_DISABLED ? RID() : rb->get_internal_texture(), RID(), p_render_data->scene_data->view_count);
copy_effects->merge_specular(color_only_framebuffer, rb_data->get_specular(), !use_msaa ? RID() : rb->get_internal_texture(), RID(), p_render_data->scene_data->view_count);
}
}
@ -2116,6 +2168,28 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
_render_buffers_copy_depth_texture(p_render_data);
}
{
if (using_separate_specular) {
// Our specular will be combined back in (and effects, subsurface scattering and/or ssr applied),
// so if we've requested this, we need another copy.
// Fairly unlikely scenario though.
if (ce_pre_transparent_resolved_color) {
for (uint32_t v = 0; v < rb->get_view_count(); v++) {
RD::get_singleton()->texture_resolve_multisample(rb->get_color_msaa(v), rb->get_internal_texture(v));
}
}
if (ce_pre_transparent_resolved_depth) {
for (uint32_t v = 0; v < rb->get_view_count(); v++) {
resolve_effects->resolve_depth(rb->get_depth_msaa(v), rb->get_depth_texture(v), rb->get_internal_size(), texture_multisamples[msaa]);
}
}
}
_process_compositor_effects(RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_PRE_TRANSPARENT, p_render_data);
}
RENDER_TIMESTAMP("Render 3D Transparent Pass");
RD::get_singleton()->draw_command_begin_label("Render 3D Transparent Pass");
@ -2142,11 +2216,11 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
RD::get_singleton()->draw_command_begin_label("Resolve");
if (rb_data.is_valid() && rb->get_msaa_3d() != RS::VIEWPORT_MSAA_DISABLED) {
bool resolve_velocity_buffer = (using_taa || using_fsr2) && rb->has_velocity_buffer(true);
if (rb_data.is_valid() && use_msaa) {
bool resolve_velocity_buffer = (using_taa || using_fsr2 || ce_needs_motion_vectors) && rb->has_velocity_buffer(true);
for (uint32_t v = 0; v < rb->get_view_count(); v++) {
RD::get_singleton()->texture_resolve_multisample(rb->get_color_msaa(v), rb->get_internal_texture(v));
resolve_effects->resolve_depth(rb->get_depth_msaa(v), rb->get_depth_texture(v), rb->get_internal_size(), texture_multisamples[rb->get_msaa_3d()]);
resolve_effects->resolve_depth(rb->get_depth_msaa(v), rb->get_depth_texture(v), rb->get_internal_size(), texture_multisamples[msaa]);
if (resolve_velocity_buffer) {
RD::get_singleton()->texture_resolve_multisample(rb->get_velocity_buffer(true, v), rb->get_velocity_buffer(false, v));
@ -2156,6 +2230,10 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
RD::get_singleton()->draw_command_end_label();
{
_process_compositor_effects(RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_POST_TRANSPARENT, p_render_data);
}
RD::get_singleton()->draw_command_begin_label("Copy framebuffer for SSIL");
if (using_ssil) {
RENDER_TIMESTAMP("Copy Final Framebuffer (SSIL)");

View file

@ -48,8 +48,8 @@
#define RB_TEX_SPECULAR SNAME("specular")
#define RB_TEX_SPECULAR_MSAA SNAME("specular_msaa")
#define RB_TEX_ROUGHNESS SNAME("normal_roughnesss")
#define RB_TEX_ROUGHNESS_MSAA SNAME("normal_roughnesss_msaa")
#define RB_TEX_NORMAL_ROUGHNESS SNAME("normal_roughness")
#define RB_TEX_NORMAL_ROUGHNESS_MSAA SNAME("normal_roughness_msaa")
#define RB_TEX_VOXEL_GI SNAME("voxel_gi")
#define RB_TEX_VOXEL_GI_MSAA SNAME("voxel_gi_msaa")
@ -131,11 +131,11 @@ class RenderForwardClustered : public RendererSceneRenderRD {
RID get_specular_msaa(uint32_t p_layer) { return render_buffers->get_texture_slice(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_SPECULAR_MSAA, p_layer, 0); }
void ensure_normal_roughness_texture();
bool has_normal_roughness() const { return render_buffers->has_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_ROUGHNESS); }
RID get_normal_roughness() const { return render_buffers->get_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_ROUGHNESS); }
RID get_normal_roughness(uint32_t p_layer) { return render_buffers->get_texture_slice(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_ROUGHNESS, p_layer, 0); }
RID get_normal_roughness_msaa() const { return render_buffers->get_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_ROUGHNESS_MSAA); }
RID get_normal_roughness_msaa(uint32_t p_layer) { return render_buffers->get_texture_slice(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_ROUGHNESS_MSAA, p_layer, 0); }
bool has_normal_roughness() const { return render_buffers->has_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_NORMAL_ROUGHNESS); }
RID get_normal_roughness() const { return render_buffers->get_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_NORMAL_ROUGHNESS); }
RID get_normal_roughness(uint32_t p_layer) { return render_buffers->get_texture_slice(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_NORMAL_ROUGHNESS, p_layer, 0); }
RID get_normal_roughness_msaa() const { return render_buffers->get_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_NORMAL_ROUGHNESS_MSAA); }
RID get_normal_roughness_msaa(uint32_t p_layer) { return render_buffers->get_texture_slice(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_NORMAL_ROUGHNESS_MSAA, p_layer, 0); }
void ensure_voxelgi();
bool has_voxelgi() const { return render_buffers->has_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_VOXEL_GI); }

View file

@ -669,6 +669,8 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
// check if we need motion vectors
if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_MOTION_VECTORS) {
p_render_data->scene_data->calculate_motion_vectors = true;
} else if (_compositor_effects_has_flag(p_render_data, RS::COMPOSITOR_EFFECT_FLAG_NEEDS_MOTION_VECTORS)) {
p_render_data->scene_data->calculate_motion_vectors = true;
} else if (render target has velocity override) { // TODO
p_render_data->scene_data->calculate_motion_vectors = true;
} else {
@ -694,6 +696,34 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
bool using_subpass_post_process = true; // If true: we can do our post processing in a subpass
RendererRD::MaterialStorage::Samplers samplers;
RS::ViewportMSAA msaa = rb->get_msaa_3d();
bool use_msaa = msaa != RS::VIEWPORT_MSAA_DISABLED;
bool ce_has_post_opaque = _has_compositor_effect(RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_POST_OPAQUE, p_render_data);
bool ce_has_pre_transparent = _has_compositor_effect(RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_PRE_TRANSPARENT, p_render_data);
bool ce_has_post_transparent = _has_compositor_effect(RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_POST_TRANSPARENT, p_render_data);
if (ce_has_post_opaque) {
// As we're doing opaque and sky in subpasses we don't support this *yet*
WARN_PRINT_ONCE("Post opaque rendering effect callback is not supported in the mobile renderer");
}
// Using RenderingEffects limits our ability to do subpasses..
if (ce_has_pre_transparent) {
merge_transparent_pass = false;
using_subpass_post_process = false;
}
if (ce_has_post_transparent) {
using_subpass_post_process = false;
}
if (use_msaa && _compositor_effects_has_flag(p_render_data, RS::COMPOSITOR_EFFECT_FLAG_ACCESS_RESOLVED_DEPTH, RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_ANY)) {
// We'll be able to do this when we finish PR #78598
WARN_PRINT_ONCE("Depth buffer resolve for rendering effect callback is not supported in the mobile renderer");
}
// We don't need to check resolve color flag, it will be resolved for transparent passes regardless.
bool using_shadows = true;
if (p_render_data->reflection_probe.is_valid()) {
@ -881,6 +911,9 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
clear_color = p_default_bg_color;
}
// We don't have access to any rendered buffers but we may be able to effect mesh data...
_process_compositor_effects(RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_PRE_OPAQUE, p_render_data);
_pre_opaque_render(p_render_data);
uint32_t spec_constant_base_flags = 0;
@ -942,7 +975,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
c.push_back(cc); // Our render buffer.
if (rb_data.is_valid()) {
if (p_render_data->render_buffers->get_msaa_3d() != RS::VIEWPORT_MSAA_DISABLED) {
if (use_msaa) {
c.push_back(clear_color.srgb_to_linear() * inverse_luminance_multiplier); // Our resolve buffer.
}
if (using_subpass_post_process) {
@ -985,6 +1018,11 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
RD::get_singleton()->draw_command_end_label(); // Draw Sky
}
// rendering effects
if (ce_has_pre_transparent) {
_process_compositor_effects(RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_PRE_TRANSPARENT, p_render_data);
}
if (merge_transparent_pass) {
if (render_list[RENDER_LIST_ALPHA].element_info.size() > 0) {
// transparent pass
@ -1055,6 +1093,10 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
if (rb_data.is_valid() && !using_subpass_post_process) {
RD::get_singleton()->draw_command_begin_label("Post process pass");
if (ce_has_post_transparent) {
_process_compositor_effects(RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_POST_TRANSPARENT, p_render_data);
}
// If we need extra effects we do this in its own pass
RENDER_TIMESTAMP("Tonemap");

View file

@ -32,6 +32,10 @@
FramebufferCacheRD *FramebufferCacheRD::singleton = nullptr;
void FramebufferCacheRD::_bind_methods() {
ClassDB::bind_static_method("FramebufferCacheRD", D_METHOD("get_cache_multipass", "textures", "passes", "views"), &FramebufferCacheRD::get_cache_multipass_array);
}
void FramebufferCacheRD::_invalidate(Cache *p_cache) {
if (p_cache->prev) {
p_cache->prev->next = p_cache->next;
@ -52,6 +56,25 @@ void FramebufferCacheRD::_framebuffer_invalidation_callback(void *p_userdata) {
singleton->_invalidate(reinterpret_cast<Cache *>(p_userdata));
}
RID FramebufferCacheRD::get_cache_multipass_array(const TypedArray<RID> &p_textures, const TypedArray<RDFramebufferPass> &p_passes, uint32_t p_views) {
Vector<RID> textures;
Vector<RD::FramebufferPass> passes;
for (int i = 0; i < p_textures.size(); i++) {
RID texture = p_textures[i];
textures.push_back(texture); // store even if NULL
}
for (int i = 0; i < p_passes.size(); i++) {
Ref<RDFramebufferPass> pass = p_passes[i];
if (pass.is_valid()) {
passes.push_back(pass->base);
}
}
return FramebufferCacheRD::get_singleton()->get_cache_multipass(textures, passes, p_views);
}
FramebufferCacheRD::FramebufferCacheRD() {
ERR_FAIL_COND(singleton != nullptr);
singleton = this;

View file

@ -34,6 +34,7 @@
#include "core/templates/local_vector.h"
#include "core/templates/paged_allocator.h"
#include "servers/rendering/rendering_device.h"
#include "servers/rendering/rendering_device_binds.h"
class FramebufferCacheRD : public Object {
GDCLASS(FramebufferCacheRD, Object)
@ -195,6 +196,9 @@ class FramebufferCacheRD : public Object {
return rid;
}
private:
static void _bind_methods();
public:
template <typename... Args>
RID get_cache(Args... args) {
@ -301,6 +305,8 @@ public:
return _allocate_from_data(p_views, h, table_idx, p_textures, p_passes);
}
static RID get_cache_multipass_array(const TypedArray<RID> &p_textures, const TypedArray<RDFramebufferPass> &p_passes, uint32_t p_views = 1);
static FramebufferCacheRD *get_singleton() { return singleton; }
FramebufferCacheRD();

View file

@ -249,6 +249,73 @@ Ref<RenderSceneBuffers> RendererSceneRenderRD::render_buffers_create() {
return rb;
}
bool RendererSceneRenderRD::_compositor_effects_has_flag(const RenderDataRD *p_render_data, RS::CompositorEffectFlags p_flag, RS::CompositorEffectCallbackType p_callback_type) {
RendererCompositorStorage *comp_storage = RendererCompositorStorage::get_singleton();
if (p_render_data->compositor.is_null()) {
return false;
}
if (p_render_data->reflection_probe.is_valid()) {
return false;
}
ERR_FAIL_COND_V(!comp_storage->is_compositor(p_render_data->compositor), false);
Vector<RID> re_rids = comp_storage->compositor_get_compositor_effects(p_render_data->compositor, p_callback_type, true);
for (RID rid : re_rids) {
if (comp_storage->compositor_effect_get_flag(rid, p_flag)) {
return true;
}
}
return false;
}
bool RendererSceneRenderRD::_has_compositor_effect(RS::CompositorEffectCallbackType p_callback_type, const RenderDataRD *p_render_data) {
RendererCompositorStorage *comp_storage = RendererCompositorStorage::get_singleton();
if (p_render_data->compositor.is_null()) {
return false;
}
if (p_render_data->reflection_probe.is_valid()) {
return false;
}
ERR_FAIL_COND_V(!comp_storage->is_compositor(p_render_data->compositor), false);
Vector<RID> effects = comp_storage->compositor_get_compositor_effects(p_render_data->compositor, p_callback_type, true);
return effects.size() > 0;
}
void RendererSceneRenderRD::_process_compositor_effects(RS::CompositorEffectCallbackType p_callback_type, const RenderDataRD *p_render_data) {
RendererCompositorStorage *comp_storage = RendererCompositorStorage::get_singleton();
if (p_render_data->compositor.is_null()) {
return;
}
if (p_render_data->reflection_probe.is_valid()) {
return;
}
ERR_FAIL_COND(!comp_storage->is_compositor(p_render_data->compositor));
Vector<RID> re_rids = comp_storage->compositor_get_compositor_effects(p_render_data->compositor, p_callback_type, true);
for (RID rid : re_rids) {
Array arr;
Callable callback = comp_storage->compositor_effect_get_callback(rid);
arr.push_back(p_callback_type);
arr.push_back(p_render_data);
callback.callv(arr);
}
}
void RendererSceneRenderRD::_render_buffers_copy_screen_texture(const RenderDataRD *p_render_data) {
Ref<RenderSceneBuffersRD> rb = p_render_data->render_buffers;
ERR_FAIL_COND(rb.is_null());
@ -987,7 +1054,7 @@ void RendererSceneRenderRD::_post_prepass_render(RenderDataRD *p_render_data, bo
}
}
void RendererSceneRenderRD::render_scene(const Ref<RenderSceneBuffers> &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data, RenderingMethod::RenderInfo *r_render_info) {
void RendererSceneRenderRD::render_scene(const Ref<RenderSceneBuffers> &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_compositor, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data, RenderingMethod::RenderInfo *r_render_info) {
RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
@ -1067,6 +1134,7 @@ void RendererSceneRenderRD::render_scene(const Ref<RenderSceneBuffers> &p_render
render_data.lightmaps = &p_lightmaps;
render_data.fog_volumes = &p_fog_volumes;
render_data.environment = p_environment;
render_data.compositor = p_compositor;
render_data.camera_attributes = p_camera_attributes;
render_data.shadow_atlas = p_shadow_atlas;
render_data.occluder_debug_tex = p_occluder_debug_tex;
@ -1128,6 +1196,10 @@ void RendererSceneRenderRD::render_particle_collider_heightfield(RID p_collider,
bool RendererSceneRenderRD::free(RID p_rid) {
if (is_environment(p_rid)) {
environment_free(p_rid);
} else if (is_compositor(p_rid)) {
compositor_free(p_rid);
} else if (is_compositor_effect(p_rid)) {
compositor_effect_free(p_rid);
} else if (RSG::camera_attributes->owns_camera_attributes(p_rid)) {
RSG::camera_attributes->camera_attributes_free(p_rid);
} else if (gi.voxel_gi_instance_owns(p_rid)) {

View file

@ -47,58 +47,13 @@
#include "servers/rendering/renderer_rd/environment/sky.h"
#include "servers/rendering/renderer_rd/framebuffer_cache_rd.h"
#include "servers/rendering/renderer_rd/storage_rd/light_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/render_data_rd.h"
#include "servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h"
#include "servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h"
#include "servers/rendering/renderer_scene_render.h"
#include "servers/rendering/rendering_device.h"
#include "servers/rendering/rendering_method.h"
// For RenderDataRD, possibly inherited from RefCounted and add proper getters for our implementation classes
struct RenderDataRD {
Ref<RenderSceneBuffersRD> render_buffers;
RenderSceneDataRD *scene_data;
const PagedArray<RenderGeometryInstance *> *instances = nullptr;
const PagedArray<RID> *lights = nullptr;
const PagedArray<RID> *reflection_probes = nullptr;
const PagedArray<RID> *voxel_gi_instances = nullptr;
const PagedArray<RID> *decals = nullptr;
const PagedArray<RID> *lightmaps = nullptr;
const PagedArray<RID> *fog_volumes = nullptr;
RID environment;
RID camera_attributes;
RID shadow_atlas;
RID occluder_debug_tex;
RID reflection_atlas;
RID reflection_probe;
int reflection_probe_pass = 0;
RID cluster_buffer;
uint32_t cluster_size = 0;
uint32_t cluster_max_elements = 0;
uint32_t directional_light_count = 0;
bool directional_light_soft_shadows = false;
RenderingMethod::RenderInfo *render_info = nullptr;
/* Shadow data */
const RendererSceneRender::RenderShadowData *render_shadows = nullptr;
int render_shadow_count = 0;
LocalVector<int> cube_shadows;
LocalVector<int> shadows;
LocalVector<int> directional_shadows;
/* GI info */
const RendererSceneRender::RenderSDFGIData *render_sdfgi_regions = nullptr;
int render_sdfgi_region_count = 0;
const RendererSceneRender::RenderSDFGIUpdateData *sdfgi_update_data = nullptr;
uint32_t voxel_gi_count = 0;
};
class RendererSceneRenderRD : public RendererSceneRender {
friend RendererRD::SkyRD;
friend RendererRD::GI;
@ -145,6 +100,9 @@ protected:
bool _needs_post_prepass_render(RenderDataRD *p_render_data, bool p_use_gi);
void _post_prepass_render(RenderDataRD *p_render_data, bool p_use_gi);
bool _compositor_effects_has_flag(const RenderDataRD *p_render_data, RS::CompositorEffectFlags p_flag, RS::CompositorEffectCallbackType p_callback_type = RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_ANY);
bool _has_compositor_effect(RS::CompositorEffectCallbackType p_callback_type, const RenderDataRD *p_render_data);
void _process_compositor_effects(RS::CompositorEffectCallbackType p_callback_type, const RenderDataRD *p_render_data);
void _render_buffers_copy_screen_texture(const RenderDataRD *p_render_data);
void _render_buffers_copy_depth_texture(const RenderDataRD *p_render_data);
void _render_buffers_post_process_and_tonemap(const RenderDataRD *p_render_data);
@ -280,7 +238,7 @@ public:
virtual void base_uniforms_changed() = 0;
virtual void render_scene(const Ref<RenderSceneBuffers> &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RenderingMethod::RenderInfo *r_render_info = nullptr) override;
virtual void render_scene(const Ref<RenderSceneBuffers> &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_compositor, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RenderingMethod::RenderInfo *r_render_info = nullptr) override;
virtual void render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override;

View file

@ -43,7 +43,7 @@
#include "servers/rendering/storage/light_storage.h"
#include "servers/rendering/storage/utilities.h"
struct RenderDataRD;
class RenderDataRD;
namespace RendererRD {

View file

@ -0,0 +1,50 @@
/**************************************************************************/
/* render_data_rd.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#include "render_data_rd.h"
void RenderDataRD::_bind_methods() {
}
Ref<RenderSceneBuffers> RenderDataRD::get_render_scene_buffers() const {
return render_buffers;
}
RenderSceneData *RenderDataRD::get_render_scene_data() const {
return scene_data;
}
RID RenderDataRD::get_environment() const {
return environment;
}
RID RenderDataRD::get_camera_attributes() const {
return camera_attributes;
}

View file

@ -0,0 +1,97 @@
/**************************************************************************/
/* render_data_rd.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef RENDER_DATA_RD_H
#define RENDER_DATA_RD_H
#include "servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h"
#include "servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h"
#include "servers/rendering/storage/render_data.h"
class RenderDataRD : public RenderData {
GDCLASS(RenderDataRD, RenderData);
protected:
static void _bind_methods();
public:
// Access methods to expose data externally
virtual Ref<RenderSceneBuffers> get_render_scene_buffers() const override;
virtual RenderSceneData *get_render_scene_data() const override;
virtual RID get_environment() const override;
virtual RID get_camera_attributes() const override;
// Members are publicly accessible within the render engine.
Ref<RenderSceneBuffersRD> render_buffers;
RenderSceneDataRD *scene_data = nullptr;
const PagedArray<RenderGeometryInstance *> *instances = nullptr;
const PagedArray<RID> *lights = nullptr;
const PagedArray<RID> *reflection_probes = nullptr;
const PagedArray<RID> *voxel_gi_instances = nullptr;
const PagedArray<RID> *decals = nullptr;
const PagedArray<RID> *lightmaps = nullptr;
const PagedArray<RID> *fog_volumes = nullptr;
RID environment;
RID camera_attributes;
RID compositor;
RID shadow_atlas;
RID occluder_debug_tex;
RID reflection_atlas;
RID reflection_probe;
int reflection_probe_pass = 0;
RID cluster_buffer;
uint32_t cluster_size = 0;
uint32_t cluster_max_elements = 0;
uint32_t directional_light_count = 0;
bool directional_light_soft_shadows = false;
RenderingMethod::RenderInfo *render_info = nullptr;
/* Shadow data */
const RendererSceneRender::RenderShadowData *render_shadows = nullptr;
int render_shadow_count = 0;
LocalVector<int> cube_shadows;
LocalVector<int> shadows;
LocalVector<int> directional_shadows;
/* GI info */
const RendererSceneRender::RenderSDFGIData *render_sdfgi_regions = nullptr;
int render_sdfgi_region_count = 0;
const RendererSceneRender::RenderSDFGIUpdateData *sdfgi_update_data = nullptr;
uint32_t voxel_gi_count = 0;
};
#endif // RENDER_DATA_RD_H

View file

@ -0,0 +1,66 @@
/**************************************************************************/
/* render_scene_buffers_rd.compat.inc */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef DISABLE_DEPRECATED
RID RenderSceneBuffersRD::_get_color_texture_compat_80214() {
return _get_color_texture(msaa_3d != RS::VIEWPORT_MSAA_DISABLED);
}
RID RenderSceneBuffersRD::_get_color_layer_compat_80214(const uint32_t p_layer) {
return _get_color_layer(p_layer, msaa_3d != RS::VIEWPORT_MSAA_DISABLED);
}
RID RenderSceneBuffersRD::_get_depth_texture_compat_80214() {
return _get_depth_texture(msaa_3d != RS::VIEWPORT_MSAA_DISABLED);
}
RID RenderSceneBuffersRD::_get_depth_layer_compat_80214(const uint32_t p_layer) {
return _get_depth_layer(p_layer, msaa_3d != RS::VIEWPORT_MSAA_DISABLED);
}
RID RenderSceneBuffersRD::_get_velocity_texture_compat_80214() {
return _get_velocity_texture(msaa_3d != RS::VIEWPORT_MSAA_DISABLED);
}
RID RenderSceneBuffersRD::_get_velocity_layer_compat_80214(const uint32_t p_layer) {
return _get_velocity_layer(p_layer, msaa_3d != RS::VIEWPORT_MSAA_DISABLED);
}
void RenderSceneBuffersRD::_bind_compatibility_methods() {
ClassDB::bind_compatibility_method(D_METHOD("get_color_texture"), &RenderSceneBuffersRD::_get_color_texture_compat_80214);
ClassDB::bind_compatibility_method(D_METHOD("get_color_layer", "layer"), &RenderSceneBuffersRD::_get_color_layer_compat_80214);
ClassDB::bind_compatibility_method(D_METHOD("get_depth_texture"), &RenderSceneBuffersRD::_get_depth_texture_compat_80214);
ClassDB::bind_compatibility_method(D_METHOD("get_depth_layer", "layer"), &RenderSceneBuffersRD::_get_depth_layer_compat_80214);
ClassDB::bind_compatibility_method(D_METHOD("get_velocity_texture"), &RenderSceneBuffersRD::_get_velocity_texture_compat_80214);
ClassDB::bind_compatibility_method(D_METHOD("get_velocity_layer", "layer"), &RenderSceneBuffersRD::_get_velocity_layer_compat_80214);
}
#endif // DISABLE_DEPRECATED

View file

@ -29,6 +29,8 @@
/**************************************************************************/
#include "render_scene_buffers_rd.h"
#include "render_scene_buffers_rd.compat.inc"
#include "core/config/project_settings.h"
#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
@ -57,17 +59,18 @@ void RenderSceneBuffersRD::_bind_methods() {
ClassDB::bind_method(D_METHOD("clear_context", "context"), &RenderSceneBuffersRD::clear_context);
// Access to some core buffers so users don't need to know their names.
ClassDB::bind_method(D_METHOD("get_color_texture"), &RenderSceneBuffersRD::_get_color_texture);
ClassDB::bind_method(D_METHOD("get_color_layer", "layer"), &RenderSceneBuffersRD::_get_color_layer);
ClassDB::bind_method(D_METHOD("get_depth_texture"), &RenderSceneBuffersRD::_get_depth_texture);
ClassDB::bind_method(D_METHOD("get_depth_layer", "layer"), &RenderSceneBuffersRD::_get_depth_layer);
ClassDB::bind_method(D_METHOD("get_velocity_texture"), &RenderSceneBuffersRD::_get_velocity_texture);
ClassDB::bind_method(D_METHOD("get_velocity_layer", "layer"), &RenderSceneBuffersRD::_get_velocity_layer);
ClassDB::bind_method(D_METHOD("get_color_texture", "msaa"), &RenderSceneBuffersRD::_get_color_texture, DEFVAL(false));
ClassDB::bind_method(D_METHOD("get_color_layer", "layer", "msaa"), &RenderSceneBuffersRD::_get_color_layer, DEFVAL(false));
ClassDB::bind_method(D_METHOD("get_depth_texture", "msaa"), &RenderSceneBuffersRD::_get_depth_texture, DEFVAL(false));
ClassDB::bind_method(D_METHOD("get_depth_layer", "layer", "msaa"), &RenderSceneBuffersRD::_get_depth_layer, DEFVAL(false));
ClassDB::bind_method(D_METHOD("get_velocity_texture", "msaa"), &RenderSceneBuffersRD::_get_velocity_texture, DEFVAL(false));
ClassDB::bind_method(D_METHOD("get_velocity_layer", "layer", "msaa"), &RenderSceneBuffersRD::_get_velocity_layer, DEFVAL(false));
// Expose a few properties we're likely to use externally
ClassDB::bind_method(D_METHOD("get_render_target"), &RenderSceneBuffersRD::get_render_target);
ClassDB::bind_method(D_METHOD("get_view_count"), &RenderSceneBuffersRD::get_view_count);
ClassDB::bind_method(D_METHOD("get_internal_size"), &RenderSceneBuffersRD::get_internal_size);
ClassDB::bind_method(D_METHOD("get_msaa_3d"), &RenderSceneBuffersRD::get_msaa_3d);
ClassDB::bind_method(D_METHOD("get_use_taa"), &RenderSceneBuffersRD::get_use_taa);
}

View file

@ -305,20 +305,25 @@ public:
return samplers;
}
private:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Our classDB doesn't support calling our normal exposed functions
private:
RID _create_texture_from_format(const StringName &p_context, const StringName &p_texture_name, const Ref<RDTextureFormat> &p_texture_format, const Ref<RDTextureView> &p_view = Ref<RDTextureView>(), bool p_unique = true);
RID _create_texture_view(const StringName &p_context, const StringName &p_texture_name, const StringName &p_view_name, const Ref<RDTextureView> p_view = Ref<RDTextureView>());
Ref<RDTextureFormat> _get_texture_format(const StringName &p_context, const StringName &p_texture_name) const;
RID _get_texture_slice_view(const StringName &p_context, const StringName &p_texture_name, const uint32_t p_layer, const uint32_t p_mipmap, const uint32_t p_layers = 1, const uint32_t p_mipmaps = 1, const Ref<RDTextureView> p_view = Ref<RDTextureView>());
// For color and depth as exposed to extensions, we return the buffer that we're rendering into.
// Resolving happens after effects etc. are run.
RID _get_color_texture() {
if (msaa_3d != RS::VIEWPORT_MSAA_DISABLED && has_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR_MSAA)) {
return get_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR_MSAA);
// For color and depth as exposed to extensions:
// - we need separately named functions to access the layer,
// - we don't output an error for missing buffers but just return an empty RID.
RID _get_color_texture(bool p_msaa = false) {
if (p_msaa) {
if (has_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR_MSAA)) {
return get_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR_MSAA);
} else {
return RID();
}
} else if (has_internal_texture()) {
return get_internal_texture();
} else {
@ -326,9 +331,13 @@ private:
}
}
RID _get_color_layer(const uint32_t p_layer) {
if (msaa_3d != RS::VIEWPORT_MSAA_DISABLED && has_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR_MSAA)) {
return get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_COLOR_MSAA, p_layer, 0);
RID _get_color_layer(const uint32_t p_layer, bool p_msaa = false) {
if (p_msaa) {
if (has_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR_MSAA)) {
return get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_COLOR_MSAA, p_layer, 0);
} else {
return RID();
}
} else if (has_internal_texture()) {
return get_internal_texture(p_layer);
} else {
@ -336,9 +345,13 @@ private:
}
}
RID _get_depth_texture() {
if (msaa_3d != RS::VIEWPORT_MSAA_DISABLED && has_texture(RB_SCOPE_BUFFERS, RB_TEX_DEPTH_MSAA)) {
return get_texture(RB_SCOPE_BUFFERS, RB_TEX_DEPTH_MSAA);
RID _get_depth_texture(bool p_msaa = false) {
if (p_msaa) {
if (has_texture(RB_SCOPE_BUFFERS, RB_TEX_DEPTH_MSAA)) {
return get_texture(RB_SCOPE_BUFFERS, RB_TEX_DEPTH_MSAA);
} else {
return RID();
}
} else if (has_depth_texture()) {
return get_depth_texture();
} else {
@ -346,9 +359,13 @@ private:
}
}
RID _get_depth_layer(const uint32_t p_layer) {
if (msaa_3d != RS::VIEWPORT_MSAA_DISABLED && has_texture(RB_SCOPE_BUFFERS, RB_TEX_DEPTH_MSAA)) {
return get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_DEPTH_MSAA, p_layer, 0);
RID _get_depth_layer(const uint32_t p_layer, bool p_msaa = false) {
if (p_msaa) {
if (has_texture(RB_SCOPE_BUFFERS, RB_TEX_DEPTH_MSAA)) {
return get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_DEPTH_MSAA, p_layer, 0);
} else {
return RID();
}
} else if (has_depth_texture()) {
return get_depth_texture(p_layer);
} else {
@ -356,26 +373,35 @@ private:
}
}
RID _get_velocity_texture() {
if (msaa_3d != RS::VIEWPORT_MSAA_DISABLED && has_velocity_buffer(true)) {
return get_velocity_buffer(true);
} else if (has_velocity_buffer(false)) {
return get_velocity_buffer(false);
RID _get_velocity_texture(bool p_msaa = false) {
if (has_velocity_buffer(p_msaa)) {
return get_velocity_buffer(p_msaa);
} else {
return RID();
}
}
RID _get_velocity_layer(const uint32_t p_layer) {
if (msaa_3d != RS::VIEWPORT_MSAA_DISABLED && has_velocity_buffer(true)) {
return get_velocity_buffer(true, p_layer);
} else if (has_velocity_buffer(false)) {
return get_velocity_buffer(false, p_layer);
RID _get_velocity_layer(const uint32_t p_layer, bool p_msaa = false) {
if (has_velocity_buffer(p_msaa)) {
return get_velocity_buffer(p_msaa, p_layer);
} else {
return RID();
}
}
#ifndef DISABLE_DEPRECATED
RID _get_color_texture_compat_80214();
RID _get_color_layer_compat_80214(const uint32_t p_layer);
RID _get_depth_texture_compat_80214();
RID _get_depth_layer_compat_80214(const uint32_t p_layer);
RID _get_velocity_texture_compat_80214();
RID _get_velocity_layer_compat_80214(const uint32_t p_layer);
static void _bind_compatibility_methods();
#endif // DISABLE_DEPRECATED
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Everything after this needs to be re-evaluated, this is all old implementation
public:

View file

@ -34,6 +34,33 @@
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
#include "servers/rendering/rendering_server_default.h"
void RenderSceneDataRD::_bind_methods() {
}
Transform3D RenderSceneDataRD::get_cam_transform() const {
return cam_transform;
}
Projection RenderSceneDataRD::get_cam_projection() const {
return cam_projection;
}
uint32_t RenderSceneDataRD::get_view_count() const {
return view_count;
}
Vector3 RenderSceneDataRD::get_view_eye_offset(uint32_t p_view) const {
ERR_FAIL_UNSIGNED_INDEX_V(p_view, view_count, Vector3());
return view_eye_offset[p_view];
}
Projection RenderSceneDataRD::get_view_projection(uint32_t p_view) const {
ERR_FAIL_UNSIGNED_INDEX_V(p_view, view_count, Projection());
return view_projection[p_view];
}
RID RenderSceneDataRD::create_uniform_buffer() {
return RD::get_singleton()->uniform_buffer_create(sizeof(UBODATA));
}
@ -262,6 +289,6 @@ void RenderSceneDataRD::update_ubo(RID p_uniform_buffer, RS::ViewportDebugDraw p
RD::get_singleton()->buffer_update(uniform_buffer, 0, sizeof(UBODATA), &ubo);
}
RID RenderSceneDataRD::get_uniform_buffer() {
RID RenderSceneDataRD::get_uniform_buffer() const {
return uniform_buffer;
}

View file

@ -34,11 +34,14 @@
#include "render_scene_buffers_rd.h"
#include "servers/rendering/renderer_scene_render.h"
#include "servers/rendering/rendering_device.h"
#include "servers/rendering/storage/render_scene_data.h"
// This is a container for data related to rendering a single frame of a viewport where we load this data into a UBO
// that can be used by the main scene shader but also by various effects.
class RenderSceneDataRD {
class RenderSceneDataRD : public RenderSceneData {
GDCLASS(RenderSceneDataRD, RenderSceneData);
public:
bool calculate_motion_vectors = false;
@ -79,11 +82,20 @@ public:
float time;
float time_step;
virtual Transform3D get_cam_transform() const override;
virtual Projection get_cam_projection() const override;
virtual uint32_t get_view_count() const override;
virtual Vector3 get_view_eye_offset(uint32_t p_view) const override;
virtual Projection get_view_projection(uint32_t p_view) const override;
RID create_uniform_buffer();
void update_ubo(RID p_uniform_buffer, RS::ViewportDebugDraw p_debug_mode, RID p_env, RID p_reflection_probe_instance, RID p_camera_attributes, bool p_flip_y, bool p_pancake_shadows, const Size2i &p_screen_size, const Color &p_default_bg_color, float p_luminance_multiplier, bool p_opaque_render_buffers, bool p_apply_alpha_multiplier);
RID get_uniform_buffer();
virtual RID get_uniform_buffer() const override;
private:
static void _bind_methods();
RID uniform_buffer; // loaded into this uniform buffer (supplied externally)
// This struct is loaded into Set 1 - Binding 0, populated at start of rendering a frame, must match with shader code

View file

@ -32,6 +32,23 @@
UniformSetCacheRD *UniformSetCacheRD::singleton = nullptr;
void UniformSetCacheRD::_bind_methods() {
ClassDB::bind_static_method("UniformSetCacheRD", D_METHOD("get_cache", "shader", "set", "uniforms"), &UniformSetCacheRD::get_cache_array);
}
RID UniformSetCacheRD::get_cache_array(RID p_shader, uint32_t p_set, const TypedArray<RDUniform> &p_uniforms) {
Vector<RD::Uniform> uniforms;
for (int i = 0; i < p_uniforms.size(); i++) {
Ref<RDUniform> uniform = p_uniforms[i];
if (uniform.is_valid()) {
uniforms.push_back(uniform->base);
}
}
return UniformSetCacheRD::get_singleton()->get_cache_vec(p_shader, p_set, uniforms);
}
void UniformSetCacheRD::_invalidate(Cache *p_cache) {
if (p_cache->prev) {
p_cache->prev->next = p_cache->next;

View file

@ -34,6 +34,7 @@
#include "core/templates/local_vector.h"
#include "core/templates/paged_allocator.h"
#include "servers/rendering/rendering_device.h"
#include "servers/rendering/rendering_device_binds.h"
class UniformSetCacheRD : public Object {
GDCLASS(UniformSetCacheRD, Object)
@ -151,6 +152,9 @@ class UniformSetCacheRD : public Object {
return rid;
}
private:
static void _bind_methods();
public:
template <typename... Args>
RID get_cache(RID p_shader, uint32_t p_set, Args... args) {
@ -214,6 +218,8 @@ public:
return _allocate_from_uniforms(p_shader, p_set, h, table_idx, p_uniforms);
}
static RID get_cache_array(RID p_shader, uint32_t p_set, const TypedArray<RDUniform> &p_uniforms);
static UniformSetCacheRD *get_singleton() { return singleton; }
UniformSetCacheRD();

View file

@ -115,6 +115,12 @@ void RendererSceneCull::camera_set_camera_attributes(RID p_camera, RID p_attribu
camera->attributes = p_attributes;
}
void RendererSceneCull::camera_set_compositor(RID p_camera, RID p_compositor) {
Camera *camera = camera_owner.get_or_null(p_camera);
ERR_FAIL_NULL(camera);
camera->compositor = p_compositor;
}
void RendererSceneCull::camera_set_use_vertical_aspect(RID p_camera, bool p_enable) {
Camera *camera = camera_owner.get_or_null(p_camera);
ERR_FAIL_NULL(camera);
@ -401,6 +407,12 @@ void RendererSceneCull::scenario_set_camera_attributes(RID p_scenario, RID p_cam
scenario->camera_attributes = p_camera_attributes;
}
void RendererSceneCull::scenario_set_compositor(RID p_scenario, RID p_compositor) {
Scenario *scenario = scenario_owner.get_or_null(p_scenario);
ERR_FAIL_NULL(scenario);
scenario->compositor = p_compositor;
}
void RendererSceneCull::scenario_set_fallback_environment(RID p_scenario, RID p_environment) {
Scenario *scenario = scenario_owner.get_or_null(p_scenario);
ERR_FAIL_NULL(scenario);
@ -2623,12 +2635,13 @@ void RendererSceneCull::render_camera(const Ref<RenderSceneBuffers> &p_render_bu
}
RID environment = _render_get_environment(p_camera, p_scenario);
RID compositor = _render_get_compositor(p_camera, p_scenario);
RENDER_TIMESTAMP("Update Occlusion Buffer")
// For now just cull on the first camera
RendererSceneOcclusionCull::get_singleton()->buffer_update(p_viewport, camera_data.main_transform, camera_data.main_projection, camera_data.is_orthogonal);
_render_scene(&camera_data, p_render_buffers, environment, camera->attributes, camera->visible_layers, p_scenario, p_viewport, p_shadow_atlas, RID(), -1, p_screen_mesh_lod_threshold, true, r_render_info);
_render_scene(&camera_data, p_render_buffers, environment, camera->attributes, compositor, camera->visible_layers, p_scenario, p_viewport, p_shadow_atlas, RID(), -1, p_screen_mesh_lod_threshold, true, r_render_info);
#endif
}
@ -3008,7 +3021,7 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul
}
}
void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_camera_data, const Ref<RenderSceneBuffers> &p_render_buffers, RID p_environment, RID p_force_camera_attributes, uint32_t p_visible_layers, RID p_scenario, RID p_viewport, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, bool p_using_shadows, RenderingMethod::RenderInfo *r_render_info) {
void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_camera_data, const Ref<RenderSceneBuffers> &p_render_buffers, RID p_environment, RID p_force_camera_attributes, RID p_compositor, uint32_t p_visible_layers, RID p_scenario, RID p_viewport, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, bool p_using_shadows, RenderingMethod::RenderInfo *r_render_info) {
Instance *render_reflection_probe = instance_owner.get_or_null(p_reflection_probe); //if null, not rendering to it
// Prepare the light - camera volume culling system.
@ -3378,6 +3391,7 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c
} else {
camera_attributes = scenario->camera_attributes;
}
/* PROCESS GEOMETRY AND DRAW SCENE */
RID occluders_tex;
@ -3388,7 +3402,7 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c
}
RENDER_TIMESTAMP("Render 3D Scene");
scene_render->render_scene(p_render_buffers, p_camera_data, prev_camera_data, scene_cull_result.geometry_instances, scene_cull_result.light_instances, scene_cull_result.reflections, scene_cull_result.voxel_gi_instances, scene_cull_result.decals, scene_cull_result.lightmaps, scene_cull_result.fog_volumes, p_environment, camera_attributes, p_shadow_atlas, occluders_tex, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass, p_screen_mesh_lod_threshold, render_shadow_data, max_shadows_used, render_sdfgi_data, cull.sdfgi.region_count, &sdfgi_update_data, r_render_info);
scene_render->render_scene(p_render_buffers, p_camera_data, prev_camera_data, scene_cull_result.geometry_instances, scene_cull_result.light_instances, scene_cull_result.reflections, scene_cull_result.voxel_gi_instances, scene_cull_result.decals, scene_cull_result.lightmaps, scene_cull_result.fog_volumes, p_environment, camera_attributes, p_compositor, p_shadow_atlas, occluders_tex, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass, p_screen_mesh_lod_threshold, render_shadow_data, max_shadows_used, render_sdfgi_data, cull.sdfgi.region_count, &sdfgi_update_data, r_render_info);
if (p_viewport.is_valid()) {
RSG::viewport->viewport_set_prev_camera_data(p_viewport, p_camera_data);
@ -3425,6 +3439,20 @@ RID RendererSceneCull::_render_get_environment(RID p_camera, RID p_scenario) {
return RID();
}
RID RendererSceneCull::_render_get_compositor(RID p_camera, RID p_scenario) {
Camera *camera = camera_owner.get_or_null(p_camera);
if (camera && scene_render->is_compositor(camera->compositor)) {
return camera->compositor;
}
Scenario *scenario = scenario_owner.get_or_null(p_scenario);
if (scenario && scene_render->is_compositor(scenario->compositor)) {
return scenario->compositor;
}
return RID();
}
void RendererSceneCull::render_empty_scene(const Ref<RenderSceneBuffers> &p_render_buffers, RID p_scenario, RID p_shadow_atlas) {
#ifndef _3D_DISABLED
Scenario *scenario = scenario_owner.get_or_null(p_scenario);
@ -3435,12 +3463,13 @@ void RendererSceneCull::render_empty_scene(const Ref<RenderSceneBuffers> &p_rend
} else {
environment = scenario->fallback_environment;
}
RID compositor = scenario->compositor;
RENDER_TIMESTAMP("Render Empty 3D Scene");
RendererSceneRender::CameraData camera_data;
camera_data.set_camera(Transform3D(), Projection(), true, false);
scene_render->render_scene(p_render_buffers, &camera_data, &camera_data, PagedArray<RenderGeometryInstance *>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), environment, RID(), p_shadow_atlas, RID(), scenario->reflection_atlas, RID(), 0, 0, nullptr, 0, nullptr, 0, nullptr);
scene_render->render_scene(p_render_buffers, &camera_data, &camera_data, PagedArray<RenderGeometryInstance *>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), environment, RID(), compositor, p_shadow_atlas, RID(), scenario->reflection_atlas, RID(), 0, 0, nullptr, 0, nullptr, 0, nullptr);
#endif
}
@ -3514,7 +3543,7 @@ bool RendererSceneCull::_render_reflection_probe_step(Instance *p_instance, int
camera_data.set_camera(xform, cm, false, false);
Ref<RenderSceneBuffers> render_buffers = RSG::light_storage->reflection_probe_atlas_get_render_buffers(scenario->reflection_atlas);
_render_scene(&camera_data, render_buffers, environment, RID(), RSG::light_storage->reflection_probe_get_cull_mask(p_instance->base), p_instance->scenario->self, RID(), shadow_atlas, reflection_probe->instance, p_step, mesh_lod_threshold, use_shadows);
_render_scene(&camera_data, render_buffers, environment, RID(), RID(), RSG::light_storage->reflection_probe_get_cull_mask(p_instance->base), p_instance->scenario->self, RID(), shadow_atlas, reflection_probe->instance, p_step, mesh_lod_threshold, use_shadows);
} else {
//do roughness postprocess step until it believes it's done

View file

@ -80,6 +80,7 @@ public:
bool vaspect;
RID env;
RID attributes;
RID compositor;
Transform3D transform;
@ -107,6 +108,7 @@ public:
virtual void camera_set_cull_mask(RID p_camera, uint32_t p_layers);
virtual void camera_set_environment(RID p_camera, RID p_env);
virtual void camera_set_camera_attributes(RID p_camera, RID p_attributes);
virtual void camera_set_compositor(RID p_camera, RID p_compositor);
virtual void camera_set_use_vertical_aspect(RID p_camera, bool p_enable);
virtual bool is_camera(RID p_camera) const;
@ -324,6 +326,7 @@ public:
RID environment;
RID fallback_environment;
RID camera_attributes;
RID compositor;
RID reflection_probe_shadow_atlas;
RID reflection_atlas;
uint64_t used_viewport_visibility_bits;
@ -359,6 +362,7 @@ public:
virtual void scenario_set_environment(RID p_scenario, RID p_environment);
virtual void scenario_set_camera_attributes(RID p_scenario, RID p_attributes);
virtual void scenario_set_fallback_environment(RID p_scenario, RID p_environment);
virtual void scenario_set_compositor(RID p_scenario, RID p_compositor);
virtual void scenario_set_reflection_atlas_size(RID p_scenario, int p_reflection_size, int p_reflection_count);
virtual bool is_scenario(RID p_scenario) const;
virtual RID scenario_get_environment(RID p_scenario);
@ -1065,6 +1069,7 @@ public:
_FORCE_INLINE_ bool _light_instance_update_shadow(Instance *p_instance, const Transform3D p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario, float p_scren_mesh_lod_threshold, uint32_t p_visible_layers = 0xFFFFFF);
RID _render_get_environment(RID p_camera, RID p_scenario);
RID _render_get_compositor(RID p_camera, RID p_scenario);
struct Cull {
struct Shadow {
@ -1134,7 +1139,7 @@ public:
_FORCE_INLINE_ bool _visibility_parent_check(const CullData &p_cull_data, const InstanceData &p_instance_data);
bool _render_reflection_probe_step(Instance *p_instance, int p_step);
void _render_scene(const RendererSceneRender::CameraData *p_camera_data, const Ref<RenderSceneBuffers> &p_render_buffers, RID p_environment, RID p_force_camera_attributes, uint32_t p_visible_layers, RID p_scenario, RID p_viewport, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, bool p_using_shadows = true, RenderInfo *r_render_info = nullptr);
void _render_scene(const RendererSceneRender::CameraData *p_camera_data, const Ref<RenderSceneBuffers> &p_render_buffers, RID p_environment, RID p_force_camera_attributes, RID p_compositor, uint32_t p_visible_layers, RID p_scenario, RID p_viewport, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, bool p_using_shadows = true, RenderInfo *r_render_info = nullptr);
void render_empty_scene(const Ref<RenderSceneBuffers> &p_render_buffers, RID p_scenario, RID p_shadow_atlas);
void render_camera(const Ref<RenderSceneBuffers> &p_render_buffers, RID p_camera, RID p_scenario, RID p_viewport, Size2 p_viewport_size, uint32_t p_jitter_phase_count, float p_screen_mesh_lod_threshold, RID p_shadow_atlas, Ref<XRInterface> &p_xr_interface, RenderingMethod::RenderInfo *r_render_info = nullptr);
@ -1167,6 +1172,28 @@ public:
PASS2(sky_set_material, RID, RID)
PASS4R(Ref<Image>, sky_bake_panorama, RID, float, bool, const Size2i &)
// Compositor effect
PASS0R(RID, compositor_effect_allocate)
PASS1(compositor_effect_initialize, RID)
PASS1RC(bool, is_compositor_effect, RID)
PASS2(compositor_effect_set_enabled, RID, bool)
PASS3(compositor_effect_set_callback, RID, RS::CompositorEffectCallbackType, const Callable &)
PASS3(compositor_effect_set_flag, RID, RS::CompositorEffectFlags, bool)
// Compositor
PASS0R(RID, compositor_allocate)
PASS1(compositor_initialize, RID)
PASS1RC(bool, is_compositor, RID)
PASS2(compositor_set_compositor_effects, RID, const TypedArray<RID> &)
// Environment
PASS0R(RID, environment_allocate)
PASS1(environment_initialize, RID)

View file

@ -186,6 +186,64 @@ void RendererSceneRender::CameraData::set_multiview_camera(uint32_t p_view_count
}
}
/* Compositor effect API */
RID RendererSceneRender::compositor_effect_allocate() {
return compositor_storage.compositor_effect_allocate();
}
void RendererSceneRender::compositor_effect_initialize(RID p_rid) {
compositor_storage.compositor_effect_initialize(p_rid);
}
void RendererSceneRender::compositor_effect_free(RID p_rid) {
compositor_storage.compositor_effect_free(p_rid);
}
bool RendererSceneRender::is_compositor_effect(RID p_effect) const {
return compositor_storage.is_compositor_effect(p_effect);
}
void RendererSceneRender::compositor_effect_set_enabled(RID p_effect, bool p_enabled) {
compositor_storage.compositor_effect_set_enabled(p_effect, p_enabled);
}
void RendererSceneRender::compositor_effect_set_callback(RID p_effect, RS::CompositorEffectCallbackType p_callback_type, const Callable &p_callback) {
compositor_storage.compositor_effect_set_callback(p_effect, p_callback_type, p_callback);
}
void RendererSceneRender::compositor_effect_set_flag(RID p_effect, RS::CompositorEffectFlags p_flag, bool p_set) {
compositor_storage.compositor_effect_set_flag(p_effect, p_flag, p_set);
}
/* Compositor API */
RID RendererSceneRender::compositor_allocate() {
return compositor_storage.compositor_allocate();
}
void RendererSceneRender::compositor_initialize(RID p_rid) {
compositor_storage.compositor_initialize(p_rid);
}
void RendererSceneRender::compositor_free(RID p_rid) {
compositor_storage.compositor_free(p_rid);
}
bool RendererSceneRender::is_compositor(RID p_rid) const {
return compositor_storage.is_compositor(p_rid);
}
void RendererSceneRender::compositor_set_compositor_effects(RID p_compositor, const TypedArray<RID> &p_effects) {
Vector<RID> rids;
for (int i = 0; i < p_effects.size(); i++) {
RID rid = p_effects[i];
rids.push_back(rid);
}
compositor_storage.compositor_set_compositor_effects(p_compositor, rids);
}
/* Environment API */
RID RendererSceneRender::environment_allocate() {

View file

@ -35,6 +35,7 @@
#include "core/templates/paged_array.h"
#include "servers/rendering/renderer_geometry_instance.h"
#include "servers/rendering/rendering_method.h"
#include "servers/rendering/storage/compositor_storage.h"
#include "servers/rendering/storage/environment_storage.h"
#include "storage/render_scene_buffers.h"
#include "storage/utilities.h"
@ -42,6 +43,7 @@
class RendererSceneRender {
private:
RendererEnvironmentStorage environment_storage;
RendererCompositorStorage compositor_storage;
public:
enum {
@ -73,6 +75,27 @@ public:
virtual void sky_set_material(RID p_sky, RID p_material) = 0;
virtual Ref<Image> sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) = 0;
/* COMPOSITOR EFFECT API */
RID compositor_effect_allocate();
void compositor_effect_initialize(RID p_rid);
void compositor_effect_free(RID p_rid);
bool is_compositor_effect(RID p_compositor) const;
void compositor_effect_set_enabled(RID p_compositor, bool p_enabled);
void compositor_effect_set_callback(RID p_compositor, RS::CompositorEffectCallbackType p_callback_type, const Callable &p_callback);
void compositor_effect_set_flag(RID p_compositor, RS::CompositorEffectFlags p_flag, bool p_set);
/* COMPOSITOR API */
RID compositor_allocate();
void compositor_initialize(RID p_rid);
void compositor_free(RID p_rid);
bool is_compositor(RID p_compositor) const;
void compositor_set_compositor_effects(RID p_compositor, const TypedArray<RID> &p_effects);
/* ENVIRONMENT API */
RID environment_allocate();
@ -289,7 +312,7 @@ public:
void set_multiview_camera(uint32_t p_view_count, const Transform3D *p_transforms, const Projection *p_projections, bool p_is_orthogonal, bool p_vaspect);
};
virtual void render_scene(const Ref<RenderSceneBuffers> &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RenderingMethod::RenderInfo *r_render_info = nullptr) = 0;
virtual void render_scene(const Ref<RenderSceneBuffers> &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_compositor, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RenderingMethod::RenderInfo *r_render_info = nullptr) = 0;
virtual void render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0;
virtual void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<RenderGeometryInstance *> &p_instances) = 0;

View file

@ -134,6 +134,7 @@ protected:
class RDFramebufferPass : public RefCounted {
GDCLASS(RDFramebufferPass, RefCounted)
friend class RenderingDevice;
friend class FramebufferCacheRD;
RD::FramebufferPass base;
@ -443,6 +444,7 @@ protected:
class RDUniform : public RefCounted {
GDCLASS(RDUniform, RefCounted)
friend class RenderingDevice;
friend class UniformSetCacheRD;
RD::Uniform base;
public:

View file

@ -47,6 +47,7 @@ public:
virtual void camera_set_cull_mask(RID p_camera, uint32_t p_layers) = 0;
virtual void camera_set_environment(RID p_camera, RID p_env) = 0;
virtual void camera_set_camera_attributes(RID p_camera, RID p_attributes) = 0;
virtual void camera_set_compositor(RID p_camera, RID p_compositor) = 0;
virtual void camera_set_use_vertical_aspect(RID p_camera, bool p_enable) = 0;
virtual bool is_camera(RID p_camera) const = 0;
@ -60,6 +61,7 @@ public:
virtual void scenario_set_environment(RID p_scenario, RID p_environment) = 0;
virtual void scenario_set_camera_attributes(RID p_scenario, RID p_attributes) = 0;
virtual void scenario_set_fallback_environment(RID p_scenario, RID p_environment) = 0;
virtual void scenario_set_compositor(RID p_scenario, RID p_compositor) = 0;
virtual void scenario_set_reflection_atlas_size(RID p_scenario, int p_reflection_size, int p_reflection_count) = 0;
virtual bool is_scenario(RID p_scenario) const = 0;
virtual RID scenario_get_environment(RID p_scenario) = 0;
@ -117,6 +119,27 @@ public:
virtual void sky_set_material(RID p_sky, RID p_material) = 0;
virtual Ref<Image> sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) = 0;
/* COMPOSITOR EFFECT API */
virtual RID compositor_effect_allocate() = 0;
virtual void compositor_effect_initialize(RID p_rid) = 0;
virtual bool is_compositor_effect(RID p_compositor) const = 0;
virtual void compositor_effect_set_enabled(RID p_compositor, bool p_enabled) = 0;
virtual void compositor_effect_set_callback(RID p_compositor, RS::CompositorEffectCallbackType p_callback_type, const Callable &p_callback) = 0;
virtual void compositor_effect_set_flag(RID p_compositor, RS::CompositorEffectFlags p_flag, bool p_set) = 0;
/* COMPOSITOR API */
virtual RID compositor_allocate() = 0;
virtual void compositor_initialize(RID p_rid) = 0;
virtual bool is_compositor(RID p_compositor) const = 0;
virtual void compositor_set_compositor_effects(RID p_env, const TypedArray<RID> &p_effects) = 0;
/* ENVIRONMENT API */
virtual RID environment_allocate() = 0;

View file

@ -591,6 +591,7 @@ public:
FUNC2(camera_set_cull_mask, RID, uint32_t)
FUNC2(camera_set_environment, RID, RID)
FUNC2(camera_set_camera_attributes, RID, RID)
FUNC2(camera_set_compositor, RID, RID)
FUNC2(camera_set_use_vertical_aspect, RID, bool)
/* OCCLUDER */
@ -676,7 +677,7 @@ public:
FUNC2(viewport_set_vrs_mode, RID, ViewportVRSMode)
FUNC2(viewport_set_vrs_texture, RID, RID)
/* ENVIRONMENT API */
/* COMPOSITOR EFFECT */
#undef server_name
#undef ServerName
@ -684,6 +685,19 @@ public:
#define ServerName RenderingMethod
#define server_name RSG::scene
FUNCRIDSPLIT(compositor_effect)
FUNC2(compositor_effect_set_enabled, RID, bool)
FUNC3(compositor_effect_set_callback, RID, CompositorEffectCallbackType, const Callable &)
FUNC3(compositor_effect_set_flag, RID, CompositorEffectFlags, bool)
/* COMPOSITOR */
FUNC2(compositor_set_compositor_effects, RID, const TypedArray<RID> &)
FUNCRIDSPLIT(compositor)
/* ENVIRONMENT API */
FUNC1(voxel_gi_set_quality, VoxelGIQuality)
/* SKY API */
@ -694,6 +708,8 @@ public:
FUNC2(sky_set_material, RID, RID)
FUNC4R(Ref<Image>, sky_bake_panorama, RID, float, bool, const Size2i &)
/* ENVIRONMENT */
FUNCRIDSPLIT(environment)
FUNC2(environment_set_background, RID, EnvironmentBG)
@ -779,6 +795,7 @@ public:
FUNC2(scenario_set_environment, RID, RID)
FUNC2(scenario_set_camera_attributes, RID, RID)
FUNC2(scenario_set_fallback_environment, RID, RID)
FUNC2(scenario_set_compositor, RID, RID)
/* INSTANCING API */
FUNCRIDSPLIT(instance)

View file

@ -0,0 +1,160 @@
/**************************************************************************/
/* compositor_storage.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#include "compositor_storage.h"
// Storage
RendererCompositorStorage *RendererCompositorStorage::singleton = nullptr;
RendererCompositorStorage::RendererCompositorStorage() {
singleton = this;
}
RendererCompositorStorage::~RendererCompositorStorage() {
singleton = nullptr;
}
// Compositor effect
RID RendererCompositorStorage::compositor_effect_allocate() {
return compositor_effects_owner.allocate_rid();
}
void RendererCompositorStorage::compositor_effect_initialize(RID p_rid) {
compositor_effects_owner.initialize_rid(p_rid, CompositorEffect());
}
void RendererCompositorStorage::compositor_effect_free(RID p_rid) {
// TODO remove this RID from any compositor that uses it.
compositor_effects_owner.free(p_rid);
}
void RendererCompositorStorage::compositor_effect_set_callback(RID p_effect, RS::CompositorEffectCallbackType p_callback_type, const Callable &p_callback) {
CompositorEffect *effect = compositor_effects_owner.get_or_null(p_effect);
ERR_FAIL_NULL(effect);
effect->callback_type = p_callback_type;
effect->callback = p_callback;
}
void RendererCompositorStorage::compositor_effect_set_enabled(RID p_effect, bool p_enabled) {
CompositorEffect *effect = compositor_effects_owner.get_or_null(p_effect);
ERR_FAIL_NULL(effect);
effect->is_enabled = p_enabled;
}
bool RendererCompositorStorage::compositor_effect_get_enabled(RID p_effect) const {
CompositorEffect *effect = compositor_effects_owner.get_or_null(p_effect);
ERR_FAIL_NULL_V(effect, false);
return effect->is_enabled;
}
RS::CompositorEffectCallbackType RendererCompositorStorage::compositor_effect_get_callback_type(RID p_effect) const {
CompositorEffect *effect = compositor_effects_owner.get_or_null(p_effect);
ERR_FAIL_NULL_V(effect, RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_MAX);
return effect->callback_type;
}
Callable RendererCompositorStorage::compositor_effect_get_callback(RID p_effect) const {
CompositorEffect *effect = compositor_effects_owner.get_or_null(p_effect);
ERR_FAIL_NULL_V(effect, Callable());
return effect->callback;
}
void RendererCompositorStorage::compositor_effect_set_flag(RID p_effect, RS::CompositorEffectFlags p_flag, bool p_set) {
CompositorEffect *effect = compositor_effects_owner.get_or_null(p_effect);
ERR_FAIL_NULL(effect);
if (p_set) {
effect->flags.set_flag(p_flag);
} else {
effect->flags.clear_flag(p_flag);
}
}
bool RendererCompositorStorage::compositor_effect_get_flag(RID p_effect, RS::CompositorEffectFlags p_flag) const {
CompositorEffect *effect = compositor_effects_owner.get_or_null(p_effect);
ERR_FAIL_NULL_V(effect, false);
return effect->flags.has_flag(p_flag);
}
// Compositor
RID RendererCompositorStorage::compositor_allocate() {
return compositor_owner.allocate_rid();
}
void RendererCompositorStorage::compositor_initialize(RID p_rid) {
compositor_owner.initialize_rid(p_rid, Compositor());
}
void RendererCompositorStorage::compositor_free(RID p_rid) {
compositor_owner.free(p_rid);
}
// compositor effects
void RendererCompositorStorage::compositor_set_compositor_effects(RID p_compositor, const Vector<RID> &p_effects) {
Compositor *compositor = compositor_owner.get_or_null(p_compositor);
ERR_FAIL_NULL(compositor);
compositor->compositor_effects.clear();
for (const RID &effect : p_effects) {
if (is_compositor_effect(effect)) {
compositor->compositor_effects.push_back(effect);
}
}
}
Vector<RID> RendererCompositorStorage::compositor_get_compositor_effects(RID p_compositor, RS::CompositorEffectCallbackType p_callback_type, bool p_enabled_only) const {
Compositor *compositor = compositor_owner.get_or_null(p_compositor);
ERR_FAIL_NULL_V(compositor, Vector<RID>());
if (p_enabled_only || p_callback_type != RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_ANY) {
Vector<RID> effects;
for (RID rid : compositor->compositor_effects) {
if ((!p_enabled_only || compositor_effect_get_enabled(rid)) && (p_callback_type == RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_ANY || compositor_effect_get_callback_type(rid) == p_callback_type)) {
effects.push_back(rid);
}
}
return effects;
} else {
return compositor->compositor_effects;
}
}

View file

@ -0,0 +1,98 @@
/**************************************************************************/
/* compositor_storage.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef COMPOSITOR_STORAGE_H
#define COMPOSITOR_STORAGE_H
#include "core/templates/rid_owner.h"
#include "servers/rendering_server.h"
class RendererCompositorStorage {
private:
static RendererCompositorStorage *singleton;
// Compositor effect
struct CompositorEffect {
bool is_enabled = true;
RS::CompositorEffectCallbackType callback_type;
Callable callback;
BitField<RS::CompositorEffectFlags> flags;
};
mutable RID_Owner<CompositorEffect, true> compositor_effects_owner;
// Compositor
struct Compositor {
// Compositor effects
Vector<RID> compositor_effects;
};
mutable RID_Owner<Compositor, true> compositor_owner;
public:
static RendererCompositorStorage *get_singleton() { return singleton; }
RendererCompositorStorage();
virtual ~RendererCompositorStorage();
// Compositor effect
RID compositor_effect_allocate();
void compositor_effect_initialize(RID p_rid);
void compositor_effect_free(RID p_rid);
bool is_compositor_effect(RID p_effect) const {
return compositor_effects_owner.owns(p_effect);
}
void compositor_effect_set_enabled(RID p_effect, bool p_enabled);
bool compositor_effect_get_enabled(RID p_effect) const;
void compositor_effect_set_callback(RID p_effect, RS::CompositorEffectCallbackType p_callback_type, const Callable &p_callback);
RS::CompositorEffectCallbackType compositor_effect_get_callback_type(RID p_effect) const;
Callable compositor_effect_get_callback(RID p_effect) const;
void compositor_effect_set_flag(RID p_effect, RS::CompositorEffectFlags p_flag, bool p_set);
bool compositor_effect_get_flag(RID p_effect, RS::CompositorEffectFlags p_flag) const;
// Compositor
RID compositor_allocate();
void compositor_initialize(RID p_rid);
void compositor_free(RID p_rid);
bool is_compositor(RID p_compositor) const {
return compositor_owner.owns(p_compositor);
}
void compositor_set_compositor_effects(RID p_compositor, const Vector<RID> &p_effects);
Vector<RID> compositor_get_compositor_effects(RID p_compositor, RS::CompositorEffectCallbackType p_callback_type = RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_ANY, bool p_enabled_only = true) const;
};
#endif // COMPOSITOR_STORAGE_H

View file

@ -30,6 +30,20 @@
#include "environment_storage.h"
// Storage
RendererEnvironmentStorage *RendererEnvironmentStorage::singleton = nullptr;
RendererEnvironmentStorage::RendererEnvironmentStorage() {
singleton = this;
}
RendererEnvironmentStorage::~RendererEnvironmentStorage() {
singleton = nullptr;
}
// Environment
RID RendererEnvironmentStorage::environment_allocate() {
return environment_owner.allocate_rid();
}

View file

@ -36,6 +36,9 @@
class RendererEnvironmentStorage {
private:
static RendererEnvironmentStorage *singleton;
// Environment
struct Environment {
// Note, we capture and store all environment parameters received from Godot here.
// Not all renderers support all effects and should just ignore the bits they don't support.
@ -155,6 +158,12 @@ private:
mutable RID_Owner<Environment, true> environment_owner;
public:
static RendererEnvironmentStorage *get_singleton() { return singleton; }
RendererEnvironmentStorage();
virtual ~RendererEnvironmentStorage();
// Environment
RID environment_allocate();
void environment_initialize(RID p_rid);
void environment_free(RID p_rid);

View file

@ -0,0 +1,69 @@
/**************************************************************************/
/* render_data.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#include "render_data.h"
void RenderData::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_render_scene_buffers"), &RenderData::get_render_scene_buffers);
ClassDB::bind_method(D_METHOD("get_render_scene_data"), &RenderData::get_render_scene_data);
ClassDB::bind_method(D_METHOD("get_environment"), &RenderData::get_environment);
ClassDB::bind_method(D_METHOD("get_camera_attributes"), &RenderData::get_camera_attributes);
}
void RenderDataExtension::_bind_methods() {
GDVIRTUAL_BIND(_get_render_scene_buffers);
GDVIRTUAL_BIND(_get_render_scene_data)
GDVIRTUAL_BIND(_get_environment)
GDVIRTUAL_BIND(_get_camera_attributes)
}
Ref<RenderSceneBuffers> RenderDataExtension::get_render_scene_buffers() const {
Ref<RenderSceneBuffers> ret;
GDVIRTUAL_CALL(_get_render_scene_buffers, ret);
return ret;
}
RenderSceneData *RenderDataExtension::get_render_scene_data() const {
RenderSceneData *ret = nullptr;
GDVIRTUAL_CALL(_get_render_scene_data, ret);
return ret;
}
RID RenderDataExtension::get_environment() const {
RID ret;
GDVIRTUAL_CALL(_get_environment, ret);
return ret;
}
RID RenderDataExtension::get_camera_attributes() const {
RID ret;
GDVIRTUAL_CALL(_get_camera_attributes, ret);
return ret;
}

View file

@ -0,0 +1,70 @@
/**************************************************************************/
/* render_data.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef RENDER_DATA_H
#define RENDER_DATA_H
#include "core/object/object.h"
#include "render_scene_buffers.h"
#include "render_scene_data.h"
class RenderData : public Object {
GDCLASS(RenderData, Object);
protected:
static void _bind_methods();
public:
virtual Ref<RenderSceneBuffers> get_render_scene_buffers() const = 0;
virtual RenderSceneData *get_render_scene_data() const = 0;
virtual RID get_environment() const = 0;
virtual RID get_camera_attributes() const = 0;
};
class RenderDataExtension : public RenderData {
GDCLASS(RenderDataExtension, RenderData);
protected:
static void _bind_methods();
virtual Ref<RenderSceneBuffers> get_render_scene_buffers() const override;
virtual RenderSceneData *get_render_scene_data() const override;
virtual RID get_environment() const override;
virtual RID get_camera_attributes() const override;
GDVIRTUAL0RC(Ref<RenderSceneBuffers>, _get_render_scene_buffers)
GDVIRTUAL0RC(RenderSceneData *, _get_render_scene_data)
GDVIRTUAL0RC(RID, _get_environment)
GDVIRTUAL0RC(RID, _get_camera_attributes)
};
#endif // RENDER_DATA_H

View file

@ -0,0 +1,88 @@
/**************************************************************************/
/* render_scene_data.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#include "render_scene_data.h"
void RenderSceneData::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_cam_transform"), &RenderSceneData::get_cam_transform);
ClassDB::bind_method(D_METHOD("get_cam_projection"), &RenderSceneData::get_cam_projection);
ClassDB::bind_method(D_METHOD("get_view_count"), &RenderSceneData::get_view_count);
ClassDB::bind_method(D_METHOD("get_view_eye_offset", "view"), &RenderSceneData::get_view_eye_offset);
ClassDB::bind_method(D_METHOD("get_view_projection", "view"), &RenderSceneData::get_view_projection);
ClassDB::bind_method(D_METHOD("get_uniform_buffer"), &RenderSceneData::get_uniform_buffer);
}
void RenderSceneDataExtension::_bind_methods() {
GDVIRTUAL_BIND(_get_cam_transform);
GDVIRTUAL_BIND(_get_cam_projection);
GDVIRTUAL_BIND(_get_view_count);
GDVIRTUAL_BIND(_get_view_eye_offset, "view");
GDVIRTUAL_BIND(_get_view_projection, "view");
GDVIRTUAL_BIND(_get_uniform_buffer);
}
Transform3D RenderSceneDataExtension::get_cam_transform() const {
Transform3D ret;
GDVIRTUAL_CALL(_get_cam_transform, ret);
return ret;
}
Projection RenderSceneDataExtension::get_cam_projection() const {
Projection ret;
GDVIRTUAL_CALL(_get_cam_projection, ret);
return ret;
}
uint32_t RenderSceneDataExtension::get_view_count() const {
uint32_t ret = 0;
GDVIRTUAL_CALL(_get_view_count, ret);
return ret;
}
Vector3 RenderSceneDataExtension::get_view_eye_offset(uint32_t p_view) const {
Vector3 ret;
GDVIRTUAL_CALL(_get_view_eye_offset, p_view, ret);
return ret;
}
Projection RenderSceneDataExtension::get_view_projection(uint32_t p_view) const {
Projection ret;
GDVIRTUAL_CALL(_get_view_projection, p_view, ret);
return ret;
}
RID RenderSceneDataExtension::get_uniform_buffer() const {
RID ret;
GDVIRTUAL_CALL(_get_uniform_buffer, ret);
return ret;
}

View file

@ -0,0 +1,82 @@
/**************************************************************************/
/* render_scene_data.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef RENDER_SCENE_DATA_H
#define RENDER_SCENE_DATA_H
#include "core/object/class_db.h"
#include "core/object/gdvirtual.gen.inc"
#include "core/object/object.h"
#include "core/object/script_language.h"
class RenderSceneData : public Object {
GDCLASS(RenderSceneData, Object);
protected:
static void _bind_methods();
public:
virtual Transform3D get_cam_transform() const = 0;
virtual Projection get_cam_projection() const = 0;
virtual uint32_t get_view_count() const = 0;
virtual Vector3 get_view_eye_offset(uint32_t p_view) const = 0;
virtual Projection get_view_projection(uint32_t p_view) const = 0;
virtual RID get_uniform_buffer() const = 0;
};
class RenderSceneDataExtension : public RenderSceneData {
GDCLASS(RenderSceneDataExtension, RenderSceneData);
protected:
static void _bind_methods();
public:
virtual Transform3D get_cam_transform() const override;
virtual Projection get_cam_projection() const override;
virtual uint32_t get_view_count() const override;
virtual Vector3 get_view_eye_offset(uint32_t p_view) const override;
virtual Projection get_view_projection(uint32_t p_view) const override;
virtual RID get_uniform_buffer() const override;
GDVIRTUAL0RC(Transform3D, _get_cam_transform)
GDVIRTUAL0RC(Projection, _get_cam_projection)
GDVIRTUAL0RC(uint32_t, _get_view_count)
GDVIRTUAL1RC(Vector3, _get_view_eye_offset, uint32_t)
GDVIRTUAL1RC(Projection, _get_view_projection, uint32_t)
GDVIRTUAL0RC(RID, _get_uniform_buffer)
};
#endif // RENDER_SCENE_DATA_H

View file

@ -2762,6 +2762,7 @@ void RenderingServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("camera_set_cull_mask", "camera", "layers"), &RenderingServer::camera_set_cull_mask);
ClassDB::bind_method(D_METHOD("camera_set_environment", "camera", "env"), &RenderingServer::camera_set_environment);
ClassDB::bind_method(D_METHOD("camera_set_camera_attributes", "camera", "effects"), &RenderingServer::camera_set_camera_attributes);
ClassDB::bind_method(D_METHOD("camera_set_compositor", "camera", "compositor"), &RenderingServer::camera_set_compositor);
ClassDB::bind_method(D_METHOD("camera_set_use_vertical_aspect", "camera", "enable"), &RenderingServer::camera_set_use_vertical_aspect);
/* VIEWPORT */
@ -2928,6 +2929,32 @@ void RenderingServer::_bind_methods() {
BIND_ENUM_CONSTANT(SKY_MODE_INCREMENTAL);
BIND_ENUM_CONSTANT(SKY_MODE_REALTIME);
/* COMPOSITOR EFFECT API */
ClassDB::bind_method(D_METHOD("compositor_effect_create"), &RenderingServer::compositor_effect_create);
ClassDB::bind_method(D_METHOD("compositor_effect_set_enabled", "effect", "enabled"), &RenderingServer::compositor_effect_set_enabled);
ClassDB::bind_method(D_METHOD("compositor_effect_set_callback", "effect", "callback_type", "callback"), &RenderingServer::compositor_effect_set_callback);
ClassDB::bind_method(D_METHOD("compositor_effect_set_flag", "effect", "flag", "set"), &RenderingServer::compositor_effect_set_flag);
BIND_ENUM_CONSTANT(COMPOSITOR_EFFECT_FLAG_ACCESS_RESOLVED_COLOR);
BIND_ENUM_CONSTANT(COMPOSITOR_EFFECT_FLAG_ACCESS_RESOLVED_DEPTH);
BIND_ENUM_CONSTANT(COMPOSITOR_EFFECT_FLAG_NEEDS_MOTION_VECTORS);
BIND_ENUM_CONSTANT(COMPOSITOR_EFFECT_FLAG_NEEDS_ROUGHNESS);
BIND_ENUM_CONSTANT(COMPOSITOR_EFFECT_FLAG_NEEDS_SEPARATE_SPECULAR);
BIND_ENUM_CONSTANT(COMPOSITOR_EFFECT_CALLBACK_TYPE_PRE_OPAQUE);
BIND_ENUM_CONSTANT(COMPOSITOR_EFFECT_CALLBACK_TYPE_POST_OPAQUE);
BIND_ENUM_CONSTANT(COMPOSITOR_EFFECT_CALLBACK_TYPE_POST_SKY);
BIND_ENUM_CONSTANT(COMPOSITOR_EFFECT_CALLBACK_TYPE_PRE_TRANSPARENT);
BIND_ENUM_CONSTANT(COMPOSITOR_EFFECT_CALLBACK_TYPE_POST_TRANSPARENT);
BIND_ENUM_CONSTANT(COMPOSITOR_EFFECT_CALLBACK_TYPE_ANY);
/* COMPOSITOR */
ClassDB::bind_method(D_METHOD("compositor_create"), &RenderingServer::compositor_create);
ClassDB::bind_method(D_METHOD("compositor_set_compositor_effects", "compositor", "effects"), &RenderingServer::compositor_set_compositor_effects);
/* ENVIRONMENT */
ClassDB::bind_method(D_METHOD("environment_create"), &RenderingServer::environment_create);
@ -3071,6 +3098,7 @@ void RenderingServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("scenario_set_environment", "scenario", "environment"), &RenderingServer::scenario_set_environment);
ClassDB::bind_method(D_METHOD("scenario_set_fallback_environment", "scenario", "environment"), &RenderingServer::scenario_set_fallback_environment);
ClassDB::bind_method(D_METHOD("scenario_set_camera_attributes", "scenario", "effects"), &RenderingServer::scenario_set_camera_attributes);
ClassDB::bind_method(D_METHOD("scenario_set_compositor", "scenario", "compositor"), &RenderingServer::scenario_set_compositor);
/* INSTANCE */

View file

@ -816,6 +816,7 @@ public:
virtual void camera_set_cull_mask(RID p_camera, uint32_t p_layers) = 0;
virtual void camera_set_environment(RID p_camera, RID p_env) = 0;
virtual void camera_set_camera_attributes(RID p_camera, RID p_camera_attributes) = 0;
virtual void camera_set_compositor(RID p_camera, RID p_compositor) = 0;
virtual void camera_set_use_vertical_aspect(RID p_camera, bool p_enable) = 0;
/* VIEWPORT API */
@ -1046,6 +1047,37 @@ public:
virtual void sky_set_material(RID p_sky, RID p_material) = 0;
virtual Ref<Image> sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) = 0;
/* COMPOSITOR EFFECTS API */
enum CompositorEffectFlags {
COMPOSITOR_EFFECT_FLAG_ACCESS_RESOLVED_COLOR = 1,
COMPOSITOR_EFFECT_FLAG_ACCESS_RESOLVED_DEPTH = 2,
COMPOSITOR_EFFECT_FLAG_NEEDS_MOTION_VECTORS = 4,
COMPOSITOR_EFFECT_FLAG_NEEDS_ROUGHNESS = 8,
COMPOSITOR_EFFECT_FLAG_NEEDS_SEPARATE_SPECULAR = 16,
};
enum CompositorEffectCallbackType {
COMPOSITOR_EFFECT_CALLBACK_TYPE_PRE_OPAQUE,
COMPOSITOR_EFFECT_CALLBACK_TYPE_POST_OPAQUE,
COMPOSITOR_EFFECT_CALLBACK_TYPE_POST_SKY,
COMPOSITOR_EFFECT_CALLBACK_TYPE_PRE_TRANSPARENT,
COMPOSITOR_EFFECT_CALLBACK_TYPE_POST_TRANSPARENT,
COMPOSITOR_EFFECT_CALLBACK_TYPE_MAX,
COMPOSITOR_EFFECT_CALLBACK_TYPE_ANY = -1,
};
virtual RID compositor_effect_create() = 0;
virtual void compositor_effect_set_enabled(RID p_effect, bool p_enabled) = 0;
virtual void compositor_effect_set_callback(RID p_effect, CompositorEffectCallbackType p_callback_type, const Callable &p_callback) = 0;
virtual void compositor_effect_set_flag(RID p_effect, CompositorEffectFlags p_flag, bool p_set) = 0;
/* COMPOSITOR API */
virtual RID compositor_create() = 0;
virtual void compositor_set_compositor_effects(RID p_compositor, const TypedArray<RID> &p_effects) = 0;
/* ENVIRONMENT API */
virtual RID environment_create() = 0;
@ -1241,6 +1273,7 @@ public:
virtual void scenario_set_environment(RID p_scenario, RID p_environment) = 0;
virtual void scenario_set_fallback_environment(RID p_scenario, RID p_environment) = 0;
virtual void scenario_set_camera_attributes(RID p_scenario, RID p_camera_attributes) = 0;
virtual void scenario_set_compositor(RID p_scenario, RID p_compositor) = 0;
/* INSTANCING API */
@ -1737,6 +1770,8 @@ VARIANT_ENUM_CAST(RenderingServer::ViewportSDFOversize);
VARIANT_ENUM_CAST(RenderingServer::ViewportSDFScale);
VARIANT_ENUM_CAST(RenderingServer::ViewportVRSMode);
VARIANT_ENUM_CAST(RenderingServer::SkyMode);
VARIANT_ENUM_CAST(RenderingServer::CompositorEffectCallbackType);
VARIANT_ENUM_CAST(RenderingServer::CompositorEffectFlags);
VARIANT_ENUM_CAST(RenderingServer::EnvironmentBG);
VARIANT_ENUM_CAST(RenderingServer::EnvironmentAmbientSource);
VARIANT_ENUM_CAST(RenderingServer::EnvironmentReflectionSource);