Basic 3D rendering
This commit is contained in:
parent
2bf8831dd6
commit
652adcd5bf
|
@ -82,11 +82,6 @@ public:
|
||||||
RENDER_SEPARATE_THREAD
|
RENDER_SEPARATE_THREAD
|
||||||
};
|
};
|
||||||
|
|
||||||
enum RenderMainThreadMode {
|
|
||||||
RENDER_MAIN_THREAD_ONLY,
|
|
||||||
RENDER_ANY_THREAD,
|
|
||||||
};
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class Main;
|
friend class Main;
|
||||||
// Needed by tests to setup command-line args.
|
// Needed by tests to setup command-line args.
|
||||||
|
@ -94,7 +89,6 @@ protected:
|
||||||
|
|
||||||
HasServerFeatureCallback has_server_feature_callback = nullptr;
|
HasServerFeatureCallback has_server_feature_callback = nullptr;
|
||||||
RenderThreadMode _render_thread_mode = RENDER_THREAD_SAFE;
|
RenderThreadMode _render_thread_mode = RENDER_THREAD_SAFE;
|
||||||
RenderMainThreadMode _render_main_thread_mode = RENDER_ANY_THREAD;
|
|
||||||
|
|
||||||
// Functions used by Main to initialize/deinitialize the OS.
|
// Functions used by Main to initialize/deinitialize the OS.
|
||||||
void add_logger(Logger *p_logger);
|
void add_logger(Logger *p_logger);
|
||||||
|
@ -258,8 +252,6 @@ public:
|
||||||
virtual uint64_t get_free_static_memory() const;
|
virtual uint64_t get_free_static_memory() const;
|
||||||
|
|
||||||
RenderThreadMode get_render_thread_mode() const { return _render_thread_mode; }
|
RenderThreadMode get_render_thread_mode() const { return _render_thread_mode; }
|
||||||
RenderMainThreadMode get_render_main_thread_mode() const { return _render_main_thread_mode; }
|
|
||||||
void set_render_main_thread_mode(RenderMainThreadMode p_thread_mode) { _render_main_thread_mode = p_thread_mode; }
|
|
||||||
|
|
||||||
virtual String get_locale() const;
|
virtual String get_locale() const;
|
||||||
String get_locale_language() const;
|
String get_locale_language() const;
|
||||||
|
|
|
@ -1557,18 +1557,6 @@
|
||||||
[b]Note:[/b] This property is only read when the project starts. To change the physics FPS at runtime, set [member Engine.physics_ticks_per_second] instead.
|
[b]Note:[/b] This property is only read when the project starts. To change the physics FPS at runtime, set [member Engine.physics_ticks_per_second] instead.
|
||||||
[b]Note:[/b] Only 8 physics ticks may be simulated per rendered frame at most. If more than 8 physics ticks have to be simulated per rendered frame to keep up with rendering, the game will appear to slow down (even if [code]delta[/code] is used consistently in physics calculations). Therefore, it is recommended not to increase [member physics/common/physics_ticks_per_second] above 240. Otherwise, the game will slow down when the rendering framerate goes below 30 FPS.
|
[b]Note:[/b] Only 8 physics ticks may be simulated per rendered frame at most. If more than 8 physics ticks have to be simulated per rendered frame to keep up with rendering, the game will appear to slow down (even if [code]delta[/code] is used consistently in physics calculations). Therefore, it is recommended not to increase [member physics/common/physics_ticks_per_second] above 240. Otherwise, the game will slow down when the rendering framerate goes below 30 FPS.
|
||||||
</member>
|
</member>
|
||||||
<member name="rendering/2d/opengl/batching_send_null" type="int" setter="" getter="" default="0">
|
|
||||||
</member>
|
|
||||||
<member name="rendering/2d/opengl/batching_stream" type="int" setter="" getter="" default="0">
|
|
||||||
</member>
|
|
||||||
<member name="rendering/2d/opengl/legacy_orphan_buffers" type="int" setter="" getter="" default="0">
|
|
||||||
</member>
|
|
||||||
<member name="rendering/2d/opengl/legacy_stream" type="int" setter="" getter="" default="0">
|
|
||||||
</member>
|
|
||||||
<member name="rendering/2d/options/ninepatch_mode" type="int" setter="" getter="" default="1">
|
|
||||||
</member>
|
|
||||||
<member name="rendering/2d/options/use_software_skinning" type="bool" setter="" getter="" default="true">
|
|
||||||
</member>
|
|
||||||
<member name="rendering/2d/sdf/oversize" type="int" setter="" getter="" default="1">
|
<member name="rendering/2d/sdf/oversize" type="int" setter="" getter="" default="1">
|
||||||
</member>
|
</member>
|
||||||
<member name="rendering/2d/sdf/scale" type="int" setter="" getter="" default="1">
|
<member name="rendering/2d/sdf/scale" type="int" setter="" getter="" default="1">
|
||||||
|
@ -1594,32 +1582,6 @@
|
||||||
</member>
|
</member>
|
||||||
<member name="rendering/anti_aliasing/screen_space_roughness_limiter/limit" type="float" setter="" getter="" default="0.18">
|
<member name="rendering/anti_aliasing/screen_space_roughness_limiter/limit" type="float" setter="" getter="" default="0.18">
|
||||||
</member>
|
</member>
|
||||||
<member name="rendering/batching/debug/diagnose_frame" type="bool" setter="" getter="" default="false">
|
|
||||||
</member>
|
|
||||||
<member name="rendering/batching/debug/flash_batching" type="bool" setter="" getter="" default="false">
|
|
||||||
</member>
|
|
||||||
<member name="rendering/batching/lights/max_join_items" type="int" setter="" getter="" default="32">
|
|
||||||
</member>
|
|
||||||
<member name="rendering/batching/lights/scissor_area_threshold" type="float" setter="" getter="" default="1.0">
|
|
||||||
</member>
|
|
||||||
<member name="rendering/batching/options/single_rect_fallback" type="bool" setter="" getter="" default="false">
|
|
||||||
</member>
|
|
||||||
<member name="rendering/batching/options/use_batching" type="bool" setter="" getter="" default="false">
|
|
||||||
</member>
|
|
||||||
<member name="rendering/batching/options/use_batching_in_editor" type="bool" setter="" getter="" default="false">
|
|
||||||
</member>
|
|
||||||
<member name="rendering/batching/parameters/batch_buffer_size" type="int" setter="" getter="" default="16384">
|
|
||||||
</member>
|
|
||||||
<member name="rendering/batching/parameters/colored_vertex_format_threshold" type="float" setter="" getter="" default="0.25">
|
|
||||||
</member>
|
|
||||||
<member name="rendering/batching/parameters/item_reordering_lookahead" type="int" setter="" getter="" default="4">
|
|
||||||
</member>
|
|
||||||
<member name="rendering/batching/parameters/max_join_item_commands" type="int" setter="" getter="" default="16">
|
|
||||||
</member>
|
|
||||||
<member name="rendering/batching/precision/uv_contract" type="bool" setter="" getter="" default="false">
|
|
||||||
</member>
|
|
||||||
<member name="rendering/batching/precision/uv_contract_amount" type="int" setter="" getter="" default="100">
|
|
||||||
</member>
|
|
||||||
<member name="rendering/camera/depth_of_field/depth_of_field_bokeh_quality" type="int" setter="" getter="" default="1">
|
<member name="rendering/camera/depth_of_field/depth_of_field_bokeh_quality" type="int" setter="" getter="" default="1">
|
||||||
Sets the quality of the depth of field effect. Higher quality takes more samples, which is slower but looks smoother.
|
Sets the quality of the depth of field effect. Higher quality takes more samples, which is slower but looks smoother.
|
||||||
</member>
|
</member>
|
||||||
|
@ -1629,13 +1591,16 @@
|
||||||
<member name="rendering/camera/depth_of_field/depth_of_field_use_jitter" type="bool" setter="" getter="" default="false">
|
<member name="rendering/camera/depth_of_field/depth_of_field_use_jitter" type="bool" setter="" getter="" default="false">
|
||||||
If [code]true[/code], jitters DOF samples to make effect slightly blurrier and hide lines created from low sample rates. This can result in a slightly grainy appearance when used with a low number of samples.
|
If [code]true[/code], jitters DOF samples to make effect slightly blurrier and hide lines created from low sample rates. This can result in a slightly grainy appearance when used with a low number of samples.
|
||||||
</member>
|
</member>
|
||||||
|
<member name="rendering/driver/depth_prepass/disable_for_vendors" type="String" setter="" getter="" default=""PowerVR,Mali,Adreno,Apple"">
|
||||||
|
Disables [member rendering/driver/depth_prepass/enable] conditionally for certain venders. By default, disables the depth prepass for mobile devices as mobile devices do not benefit from the depth prepass due to their unique architecture.
|
||||||
|
</member>
|
||||||
<member name="rendering/driver/depth_prepass/enable" type="bool" setter="" getter="" default="true">
|
<member name="rendering/driver/depth_prepass/enable" type="bool" setter="" getter="" default="true">
|
||||||
If [code]true[/code], performs a previous depth pass before rendering 3D materials. This increases performance significantly in scenes with high overdraw, when complex materials and lighting are used. However, in scenes with few occluded surfaces, the depth prepass may reduce performance. If your game is viewed from a fixed angle that makes it easy to avoid overdraw (such as top-down or side-scrolling perspective), consider disabling the depth prepass to improve performance. This setting can be changed at run-time to optimize performance depending on the scene currently being viewed.
|
If [code]true[/code], performs a previous depth pass before rendering 3D materials. This increases performance significantly in scenes with high overdraw, when complex materials and lighting are used. However, in scenes with few occluded surfaces, the depth prepass may reduce performance. If your game is viewed from a fixed angle that makes it easy to avoid overdraw (such as top-down or side-scrolling perspective), consider disabling the depth prepass to improve performance. This setting can be changed at run-time to optimize performance depending on the scene currently being viewed.
|
||||||
[b]Note:[/b] Only supported when using the Vulkan Clustered backend (not Vulkan Mobile or OpenGL). When using Vulkan Mobile or OpenGL, there is no depth prepass performed.
|
[b]Note:[/b] Only supported when using the Vulkan Clustered backend or the OpenGL backend. When using Vulkan Mobile there is no depth prepass performed.
|
||||||
</member>
|
</member>
|
||||||
<member name="rendering/driver/driver_name" type="String" setter="" getter="" default=""vulkan"">
|
<member name="rendering/driver/driver_name" type="String" setter="" getter="" default=""vulkan"">
|
||||||
The video driver to use.
|
The video driver to use.
|
||||||
[b]Note:[/b] OpenGL support is currently incomplete. Only basic 2D rendering is supported, and single-window mode is required for correct operation.
|
[b]Note:[/b] OpenGL support is currently incomplete. Only basic rendering is supported.
|
||||||
[b]Note:[/b] The backend in use can be overridden at runtime via the [code]--rendering-driver[/code] command line argument.
|
[b]Note:[/b] The backend in use can be overridden at runtime via the [code]--rendering-driver[/code] command line argument.
|
||||||
[b]FIXME:[/b] No longer valid after DisplayServer split:
|
[b]FIXME:[/b] No longer valid after DisplayServer split:
|
||||||
In such cases, this property is not updated, so use [code]OS.get_current_video_driver[/code] to query it at run-time.
|
In such cases, this property is not updated, so use [code]OS.get_current_video_driver[/code] to query it at run-time.
|
||||||
|
@ -1715,10 +1680,6 @@
|
||||||
<member name="rendering/environment/volumetric_fog/volume_size" type="int" setter="" getter="" default="64">
|
<member name="rendering/environment/volumetric_fog/volume_size" type="int" setter="" getter="" default="64">
|
||||||
Base size used to determine size of froxel buffer in the camera X-axis and Y-axis. The final size is scaled by the aspect ratio of the screen, so actual values may differ from what is set. Set a larger size for more detailed fog, set a smaller size for better performance.
|
Base size used to determine size of froxel buffer in the camera X-axis and Y-axis. The final size is scaled by the aspect ratio of the screen, so actual values may differ from what is set. Set a larger size for more detailed fog, set a smaller size for better performance.
|
||||||
</member>
|
</member>
|
||||||
<member name="rendering/gles2/compatibility/disable_half_float" type="bool" setter="" getter="" default="false">
|
|
||||||
</member>
|
|
||||||
<member name="rendering/gles2/compatibility/enable_high_float.Android" type="bool" setter="" getter="" default="false">
|
|
||||||
</member>
|
|
||||||
<member name="rendering/global_illumination/gi/use_half_resolution" type="bool" setter="" getter="" default="false">
|
<member name="rendering/global_illumination/gi/use_half_resolution" type="bool" setter="" getter="" default="false">
|
||||||
If [code]true[/code], renders [VoxelGI] and SDFGI ([member Environment.sdfgi_enabled]) buffers at halved resolution (e.g. 960×540 when the viewport size is 1920×1080). This improves performance significantly when VoxelGI or SDFGI is enabled, at the cost of artifacts that may be visible on polygon edges. The loss in quality becomes less noticeable as the viewport resolution increases. [LightmapGI] rendering is not affected by this setting.
|
If [code]true[/code], renders [VoxelGI] and SDFGI ([member Environment.sdfgi_enabled]) buffers at halved resolution (e.g. 960×540 when the viewport size is 1920×1080). This improves performance significantly when VoxelGI or SDFGI is enabled, at the cost of artifacts that may be visible on polygon edges. The loss in quality becomes less noticeable as the viewport resolution increases. [LightmapGI] rendering is not affected by this setting.
|
||||||
[b]Note:[/b] This property is only read when the project starts. To set half-resolution GI at run-time, call [method RenderingServer.gi_set_use_half_resolution] instead.
|
[b]Note:[/b] This property is only read when the project starts. To set half-resolution GI at run-time, call [method RenderingServer.gi_set_use_half_resolution] instead.
|
||||||
|
@ -1761,6 +1722,15 @@
|
||||||
</member>
|
</member>
|
||||||
<member name="rendering/limits/global_shader_variables/buffer_size" type="int" setter="" getter="" default="65536">
|
<member name="rendering/limits/global_shader_variables/buffer_size" type="int" setter="" getter="" default="65536">
|
||||||
</member>
|
</member>
|
||||||
|
<member name="rendering/limits/opengl/max_lights_per_object" type="int" setter="" getter="" default="8">
|
||||||
|
Max number of lights renderable per object. This is further limited by hardware support. Setting this low will slightly reduce memory usage, may decrease shader compile times, and may result in faster rendering on low-end, mobile, or web devices.
|
||||||
|
</member>
|
||||||
|
<member name="rendering/limits/opengl/max_renderable_elements" type="int" setter="" getter="" default="65536">
|
||||||
|
Max amount of elements renderable in a frame. If more elements than this are visible per frame, they will not be drawn. Keep in mind elements refer to mesh surfaces and not meshes themselves. Setting this low will slightly reduce memory usage and may decrease shader compile times, particularly on web. For most uses, the default value is suitable, but consider lowering as much as possible on web export.
|
||||||
|
</member>
|
||||||
|
<member name="rendering/limits/opengl/max_renderable_lights" type="int" setter="" getter="" default="256">
|
||||||
|
Max number of lights renderable in a frame. If more lights than this number are used, they will be ignored. Setting this low will slightly reduce memory usage and may decrease shader compile times, particularly on web. For most uses, the default value is suitable, but consider lowering as much as possible on web export.
|
||||||
|
</member>
|
||||||
<member name="rendering/limits/spatial_indexer/threaded_cull_minimum_instances" type="int" setter="" getter="" default="1000">
|
<member name="rendering/limits/spatial_indexer/threaded_cull_minimum_instances" type="int" setter="" getter="" default="1000">
|
||||||
</member>
|
</member>
|
||||||
<member name="rendering/limits/spatial_indexer/update_iterations_per_frame" type="int" setter="" getter="" default="10">
|
<member name="rendering/limits/spatial_indexer/update_iterations_per_frame" type="int" setter="" getter="" default="10">
|
||||||
|
|
|
@ -179,12 +179,12 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_
|
||||||
|
|
||||||
//print_line("w: " + itos(ssize.width) + " s: " + rtos(canvas_scale));
|
//print_line("w: " + itos(ssize.width) + " s: " + rtos(canvas_scale));
|
||||||
state_buffer.tex_to_sdf = 1.0 / ((canvas_scale.x + canvas_scale.y) * 0.5);
|
state_buffer.tex_to_sdf = 1.0 / ((canvas_scale.x + canvas_scale.y) * 0.5);
|
||||||
glBindBufferBase(GL_UNIFORM_BUFFER, BASE_UNIFORM_BUFFER_OBJECT, state.canvas_state_buffer);
|
glBindBufferBase(GL_UNIFORM_BUFFER, BASE_UNIFORM_LOCATION, state.canvas_state_buffer);
|
||||||
glBufferData(GL_UNIFORM_BUFFER, sizeof(StateBuffer), &state_buffer, GL_STREAM_DRAW);
|
glBufferData(GL_UNIFORM_BUFFER, sizeof(StateBuffer), &state_buffer, GL_STREAM_DRAW);
|
||||||
|
|
||||||
GLuint global_buffer = material_storage->global_variables_get_uniform_buffer();
|
GLuint global_buffer = material_storage->global_variables_get_uniform_buffer();
|
||||||
|
|
||||||
glBindBufferBase(GL_UNIFORM_BUFFER, GLOBAL_UNIFORM_BUFFER_OBJECT, global_buffer);
|
glBindBufferBase(GL_UNIFORM_BUFFER, GLOBAL_UNIFORM_LOCATION, global_buffer);
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -522,7 +522,7 @@ void RasterizerCanvasGLES3::_render_item(RID p_render_target, const Item *p_item
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glBindBufferBase(GL_UNIFORM_BUFFER, INSTANCE_UNIFORM_BUFFER_OBJECT, state.canvas_instance_data_buffers[state.current_buffer]);
|
glBindBufferBase(GL_UNIFORM_BUFFER, INSTANCE_UNIFORM_LOCATION, state.canvas_instance_data_buffers[state.current_buffer]);
|
||||||
#ifdef JAVASCRIPT_ENABLED
|
#ifdef JAVASCRIPT_ENABLED
|
||||||
//WebGL 2.0 does not support mapping buffers, so use slow glBufferData instead
|
//WebGL 2.0 does not support mapping buffers, so use slow glBufferData instead
|
||||||
glBufferData(GL_UNIFORM_BUFFER, sizeof(InstanceData), &state.instance_data_array[0], GL_DYNAMIC_DRAW);
|
glBufferData(GL_UNIFORM_BUFFER, sizeof(InstanceData), &state.instance_data_array[0], GL_DYNAMIC_DRAW);
|
||||||
|
@ -728,7 +728,7 @@ void RasterizerCanvasGLES3::_render_batch(uint32_t &r_index) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glBindBufferBase(GL_UNIFORM_BUFFER, INSTANCE_UNIFORM_BUFFER_OBJECT, state.canvas_instance_data_buffers[state.current_buffer]);
|
glBindBufferBase(GL_UNIFORM_BUFFER, INSTANCE_UNIFORM_LOCATION, state.canvas_instance_data_buffers[state.current_buffer]);
|
||||||
#ifdef JAVASCRIPT_ENABLED
|
#ifdef JAVASCRIPT_ENABLED
|
||||||
//WebGL 2.0 does not support mapping buffers, so use slow glBufferData instead
|
//WebGL 2.0 does not support mapping buffers, so use slow glBufferData instead
|
||||||
glBufferData(GL_UNIFORM_BUFFER, sizeof(InstanceData) * r_index, state.instance_data_array, GL_DYNAMIC_DRAW);
|
glBufferData(GL_UNIFORM_BUFFER, sizeof(InstanceData) * r_index, state.instance_data_array, GL_DYNAMIC_DRAW);
|
||||||
|
|
|
@ -97,13 +97,12 @@ class RasterizerCanvasGLES3 : public RendererCanvasRender {
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//TODO move to Material storage
|
|
||||||
enum {
|
enum {
|
||||||
BASE_UNIFORM_BUFFER_OBJECT = 0,
|
BASE_UNIFORM_LOCATION = 0,
|
||||||
GLOBAL_UNIFORM_BUFFER_OBJECT = 1,
|
GLOBAL_UNIFORM_LOCATION = 1,
|
||||||
LIGHT_UNIFORM_BUFFER_OBJECT = 2,
|
LIGHT_UNIFORM_LOCATION = 2,
|
||||||
INSTANCE_UNIFORM_BUFFER_OBJECT = 3,
|
INSTANCE_UNIFORM_LOCATION = 3,
|
||||||
MATERIAL_UNIFORM_BUFFER_OBJECT = 4,
|
MATERIAL_UNIFORM_LOCATION = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct StateBuffer {
|
struct StateBuffer {
|
||||||
|
|
|
@ -268,10 +268,6 @@ RasterizerGLES3::RasterizerGLES3() {
|
||||||
storage = memnew(RasterizerStorageGLES3);
|
storage = memnew(RasterizerStorageGLES3);
|
||||||
canvas = memnew(RasterizerCanvasGLES3(storage));
|
canvas = memnew(RasterizerCanvasGLES3(storage));
|
||||||
scene = memnew(RasterizerSceneGLES3(storage));
|
scene = memnew(RasterizerSceneGLES3(storage));
|
||||||
|
|
||||||
texture_storage->set_main_thread_id(Thread::get_caller_id());
|
|
||||||
// make sure the OS knows to only access the renderer from the main thread
|
|
||||||
OS::get_singleton()->set_render_main_thread_mode(OS::RENDER_MAIN_THREAD_ONLY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RasterizerGLES3::~RasterizerGLES3() {
|
RasterizerGLES3::~RasterizerGLES3() {
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -34,6 +34,7 @@
|
||||||
#ifdef GLES3_ENABLED
|
#ifdef GLES3_ENABLED
|
||||||
|
|
||||||
#include "core/math/camera_matrix.h"
|
#include "core/math/camera_matrix.h"
|
||||||
|
#include "core/templates/paged_allocator.h"
|
||||||
#include "core/templates/rid_owner.h"
|
#include "core/templates/rid_owner.h"
|
||||||
#include "core/templates/self_list.h"
|
#include "core/templates/self_list.h"
|
||||||
#include "rasterizer_storage_gles3.h"
|
#include "rasterizer_storage_gles3.h"
|
||||||
|
@ -44,13 +45,47 @@
|
||||||
#include "shader_gles3.h"
|
#include "shader_gles3.h"
|
||||||
#include "shaders/sky.glsl.gen.h"
|
#include "shaders/sky.glsl.gen.h"
|
||||||
|
|
||||||
// Copied from renderer_scene_render_rd
|
enum RenderListType {
|
||||||
|
RENDER_LIST_OPAQUE, //used for opaque objects
|
||||||
|
RENDER_LIST_ALPHA, //used for transparent objects
|
||||||
|
RENDER_LIST_SECONDARY, //used for shadows and other objects
|
||||||
|
RENDER_LIST_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
enum PassMode {
|
||||||
|
PASS_MODE_COLOR,
|
||||||
|
PASS_MODE_COLOR_TRANSPARENT,
|
||||||
|
PASS_MODE_COLOR_ADDITIVE,
|
||||||
|
PASS_MODE_SHADOW,
|
||||||
|
PASS_MODE_DEPTH,
|
||||||
|
};
|
||||||
|
|
||||||
|
// These should share as much as possible with SkyUniform Location
|
||||||
|
enum SceneUniformLocation {
|
||||||
|
SCENE_TONEMAP_UNIFORM_LOCATION,
|
||||||
|
SCENE_GLOBALS_UNIFORM_LOCATION,
|
||||||
|
SCENE_DATA_UNIFORM_LOCATION,
|
||||||
|
SCENE_MATERIAL_UNIFORM_LOCATION,
|
||||||
|
SCENE_RADIANCE_UNIFORM_LOCATION,
|
||||||
|
SCENE_OMNILIGHT_UNIFORM_LOCATION,
|
||||||
|
SCENE_SPOTLIGHT_UNIFORM_LOCATION,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SkyUniformLocation {
|
||||||
|
SKY_TONEMAP_UNIFORM_LOCATION,
|
||||||
|
SKY_GLOBALS_UNIFORM_LOCATION,
|
||||||
|
SKY_SCENE_DATA_UNIFORM_LOCATION,
|
||||||
|
SKY_DIRECTIONAL_LIGHT_UNIFORM_LOCATION,
|
||||||
|
SKY_MATERIAL_UNIFORM_LOCATION,
|
||||||
|
};
|
||||||
|
|
||||||
struct RenderDataGLES3 {
|
struct RenderDataGLES3 {
|
||||||
RID render_buffers = RID();
|
RID render_buffers = RID();
|
||||||
|
bool transparent_bg = false;
|
||||||
|
|
||||||
Transform3D cam_transform = Transform3D();
|
Transform3D cam_transform = Transform3D();
|
||||||
CameraMatrix cam_projection = CameraMatrix();
|
CameraMatrix cam_projection = CameraMatrix();
|
||||||
bool cam_ortogonal = false;
|
bool cam_orthogonal = false;
|
||||||
|
|
||||||
// For stereo rendering
|
// For stereo rendering
|
||||||
uint32_t view_count = 1;
|
uint32_t view_count = 1;
|
||||||
|
@ -110,6 +145,305 @@ private:
|
||||||
RID default_shader;
|
RID default_shader;
|
||||||
} scene_globals;
|
} scene_globals;
|
||||||
|
|
||||||
|
struct SceneState {
|
||||||
|
struct UBO {
|
||||||
|
float projection_matrix[16];
|
||||||
|
float inv_projection_matrix[16];
|
||||||
|
float inv_view_matrix[16];
|
||||||
|
float view_matrix[16];
|
||||||
|
|
||||||
|
float viewport_size[2];
|
||||||
|
float screen_pixel_size[2];
|
||||||
|
|
||||||
|
float ambient_light_color_energy[4];
|
||||||
|
|
||||||
|
float ambient_color_sky_mix;
|
||||||
|
uint32_t ambient_flags;
|
||||||
|
uint32_t material_uv2_mode;
|
||||||
|
float opaque_prepass_threshold;
|
||||||
|
//bool use_ambient_light;
|
||||||
|
//bool use_ambient_cubemap;
|
||||||
|
//bool use_reflection_cubemap;
|
||||||
|
|
||||||
|
float radiance_inverse_xform[12];
|
||||||
|
|
||||||
|
uint32_t directional_light_count;
|
||||||
|
float z_far;
|
||||||
|
float z_near;
|
||||||
|
uint32_t pancake_shadows;
|
||||||
|
|
||||||
|
uint32_t fog_enabled;
|
||||||
|
float fog_density;
|
||||||
|
float fog_height;
|
||||||
|
float fog_height_density;
|
||||||
|
|
||||||
|
float fog_light_color[3];
|
||||||
|
float fog_sun_scatter;
|
||||||
|
|
||||||
|
float fog_aerial_perspective;
|
||||||
|
float time;
|
||||||
|
uint32_t pad[2];
|
||||||
|
};
|
||||||
|
static_assert(sizeof(UBO) % 16 == 0, "Scene UBO size must be a multiple of 16 bytes");
|
||||||
|
|
||||||
|
struct TonemapUBO {
|
||||||
|
float exposure = 1.0;
|
||||||
|
float white = 1.0;
|
||||||
|
int32_t tonemapper = 0;
|
||||||
|
int32_t pad = 0;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(TonemapUBO) % 16 == 0, "Tonemap UBO size must be a multiple of 16 bytes");
|
||||||
|
|
||||||
|
UBO ubo;
|
||||||
|
GLuint ubo_buffer = 0;
|
||||||
|
GLuint tonemap_buffer = 0;
|
||||||
|
|
||||||
|
bool used_depth_prepass = false;
|
||||||
|
|
||||||
|
GLES3::SceneShaderData::BlendMode current_blend_mode = GLES3::SceneShaderData::BLEND_MODE_MIX;
|
||||||
|
GLES3::SceneShaderData::DepthDraw current_depth_draw = GLES3::SceneShaderData::DEPTH_DRAW_OPAQUE;
|
||||||
|
GLES3::SceneShaderData::DepthTest current_depth_test = GLES3::SceneShaderData::DEPTH_TEST_DISABLED;
|
||||||
|
GLES3::SceneShaderData::Cull cull_mode = GLES3::SceneShaderData::CULL_BACK;
|
||||||
|
|
||||||
|
bool texscreen_copied = false;
|
||||||
|
bool used_screen_texture = false;
|
||||||
|
bool used_normal_texture = false;
|
||||||
|
bool used_depth_texture = false;
|
||||||
|
} scene_state;
|
||||||
|
|
||||||
|
struct GeometryInstanceGLES3;
|
||||||
|
|
||||||
|
// Cached data for drawing surfaces
|
||||||
|
struct GeometryInstanceSurface {
|
||||||
|
enum {
|
||||||
|
FLAG_PASS_DEPTH = 1,
|
||||||
|
FLAG_PASS_OPAQUE = 2,
|
||||||
|
FLAG_PASS_ALPHA = 4,
|
||||||
|
FLAG_PASS_SHADOW = 8,
|
||||||
|
FLAG_USES_SHARED_SHADOW_MATERIAL = 128,
|
||||||
|
FLAG_USES_SCREEN_TEXTURE = 2048,
|
||||||
|
FLAG_USES_DEPTH_TEXTURE = 4096,
|
||||||
|
FLAG_USES_NORMAL_TEXTURE = 8192,
|
||||||
|
FLAG_USES_DOUBLE_SIDED_SHADOWS = 16384,
|
||||||
|
};
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
uint64_t lod_index : 8;
|
||||||
|
uint64_t surface_index : 8;
|
||||||
|
uint64_t geometry_id : 32;
|
||||||
|
uint64_t material_id_low : 16;
|
||||||
|
|
||||||
|
uint64_t material_id_hi : 16;
|
||||||
|
uint64_t shader_id : 32;
|
||||||
|
uint64_t uses_softshadow : 1;
|
||||||
|
uint64_t uses_projector : 1;
|
||||||
|
uint64_t uses_forward_gi : 1;
|
||||||
|
uint64_t uses_lightmap : 1;
|
||||||
|
uint64_t depth_layer : 4;
|
||||||
|
uint64_t priority : 8;
|
||||||
|
};
|
||||||
|
struct {
|
||||||
|
uint64_t sort_key1;
|
||||||
|
uint64_t sort_key2;
|
||||||
|
};
|
||||||
|
} sort;
|
||||||
|
|
||||||
|
RS::PrimitiveType primitive = RS::PRIMITIVE_MAX;
|
||||||
|
uint32_t flags = 0;
|
||||||
|
uint32_t surface_index = 0;
|
||||||
|
uint32_t lod_index = 0;
|
||||||
|
|
||||||
|
void *surface = nullptr;
|
||||||
|
GLES3::SceneShaderData *shader = nullptr;
|
||||||
|
GLES3::SceneMaterialData *material = nullptr;
|
||||||
|
|
||||||
|
void *surface_shadow = nullptr;
|
||||||
|
GLES3::SceneShaderData *shader_shadow = nullptr;
|
||||||
|
GLES3::SceneMaterialData *material_shadow = nullptr;
|
||||||
|
|
||||||
|
GeometryInstanceSurface *next = nullptr;
|
||||||
|
GeometryInstanceGLES3 *owner = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GeometryInstanceGLES3 : public GeometryInstance {
|
||||||
|
//used during rendering
|
||||||
|
bool mirror = false;
|
||||||
|
bool non_uniform_scale = false;
|
||||||
|
float lod_bias = 0.0;
|
||||||
|
float lod_model_scale = 1.0;
|
||||||
|
AABB transformed_aabb; //needed for LOD
|
||||||
|
float depth = 0;
|
||||||
|
uint32_t flags_cache = 0;
|
||||||
|
bool store_transform_cache = true;
|
||||||
|
int32_t shader_parameters_offset = -1;
|
||||||
|
|
||||||
|
uint32_t layer_mask = 1;
|
||||||
|
uint32_t instance_count = 0;
|
||||||
|
|
||||||
|
RID mesh_instance;
|
||||||
|
bool can_sdfgi = false;
|
||||||
|
bool using_projectors = false;
|
||||||
|
bool using_softshadows = false;
|
||||||
|
bool fade_near = false;
|
||||||
|
float fade_near_begin = 0;
|
||||||
|
float fade_near_end = 0;
|
||||||
|
bool fade_far = false;
|
||||||
|
float fade_far_begin = 0;
|
||||||
|
float fade_far_end = 0;
|
||||||
|
float force_alpha = 1.0;
|
||||||
|
float parent_fade_alpha = 1.0;
|
||||||
|
|
||||||
|
uint32_t omni_light_count = 0;
|
||||||
|
uint32_t omni_lights[8];
|
||||||
|
uint32_t spot_light_count = 0;
|
||||||
|
uint32_t spot_lights[8];
|
||||||
|
|
||||||
|
//used during setup
|
||||||
|
uint32_t base_flags = 0;
|
||||||
|
Transform3D transform;
|
||||||
|
GeometryInstanceSurface *surface_caches = nullptr;
|
||||||
|
SelfList<GeometryInstanceGLES3> dirty_list_element;
|
||||||
|
|
||||||
|
struct Data {
|
||||||
|
//data used less often goes into regular heap
|
||||||
|
RID base;
|
||||||
|
RS::InstanceType base_type;
|
||||||
|
|
||||||
|
RID skeleton;
|
||||||
|
Vector<RID> surface_materials;
|
||||||
|
RID material_override;
|
||||||
|
RID material_overlay;
|
||||||
|
AABB aabb;
|
||||||
|
|
||||||
|
bool use_dynamic_gi = false;
|
||||||
|
bool use_baked_light = false;
|
||||||
|
bool cast_double_sided_shadows = false;
|
||||||
|
bool mirror = false;
|
||||||
|
bool dirty_dependencies = false;
|
||||||
|
|
||||||
|
RendererStorage::DependencyTracker dependency_tracker;
|
||||||
|
};
|
||||||
|
|
||||||
|
Data *data = nullptr;
|
||||||
|
|
||||||
|
GeometryInstanceGLES3() :
|
||||||
|
dirty_list_element(this) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
INSTANCE_DATA_FLAGS_NON_UNIFORM_SCALE = 1 << 5,
|
||||||
|
INSTANCE_DATA_FLAG_USE_GI_BUFFERS = 1 << 6,
|
||||||
|
INSTANCE_DATA_FLAG_USE_LIGHTMAP_CAPTURE = 1 << 8,
|
||||||
|
INSTANCE_DATA_FLAG_USE_LIGHTMAP = 1 << 9,
|
||||||
|
INSTANCE_DATA_FLAG_USE_SH_LIGHTMAP = 1 << 10,
|
||||||
|
INSTANCE_DATA_FLAG_USE_VOXEL_GI = 1 << 11,
|
||||||
|
INSTANCE_DATA_FLAG_MULTIMESH = 1 << 12,
|
||||||
|
INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D = 1 << 13,
|
||||||
|
INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR = 1 << 14,
|
||||||
|
INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA = 1 << 15,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void _geometry_instance_dependency_changed(RendererStorage::DependencyChangedNotification p_notification, RendererStorage::DependencyTracker *p_tracker);
|
||||||
|
static void _geometry_instance_dependency_deleted(const RID &p_dependency, RendererStorage::DependencyTracker *p_tracker);
|
||||||
|
|
||||||
|
SelfList<GeometryInstanceGLES3>::List geometry_instance_dirty_list;
|
||||||
|
|
||||||
|
// Use PagedAllocator instead of RID to maximize performance
|
||||||
|
PagedAllocator<GeometryInstanceGLES3> geometry_instance_alloc;
|
||||||
|
PagedAllocator<GeometryInstanceSurface> geometry_instance_surface_alloc;
|
||||||
|
|
||||||
|
void _geometry_instance_add_surface_with_material(GeometryInstanceGLES3 *ginstance, uint32_t p_surface, GLES3::SceneMaterialData *p_material, uint32_t p_material_id, uint32_t p_shader_id, RID p_mesh);
|
||||||
|
void _geometry_instance_add_surface_with_material_chain(GeometryInstanceGLES3 *ginstance, uint32_t p_surface, GLES3::SceneMaterialData *p_material, RID p_mat_src, RID p_mesh);
|
||||||
|
void _geometry_instance_add_surface(GeometryInstanceGLES3 *ginstance, uint32_t p_surface, RID p_material, RID p_mesh);
|
||||||
|
void _geometry_instance_mark_dirty(GeometryInstance *p_geometry_instance);
|
||||||
|
void _geometry_instance_update(GeometryInstance *p_geometry_instance);
|
||||||
|
void _update_dirty_geometry_instances();
|
||||||
|
|
||||||
|
struct RenderListParameters {
|
||||||
|
GeometryInstanceSurface **elements = nullptr;
|
||||||
|
int element_count = 0;
|
||||||
|
bool reverse_cull = false;
|
||||||
|
uint32_t spec_constant_base_flags = 0;
|
||||||
|
bool force_wireframe = false;
|
||||||
|
Plane lod_plane;
|
||||||
|
float lod_distance_multiplier = 0.0;
|
||||||
|
float screen_mesh_lod_threshold = 0.0;
|
||||||
|
|
||||||
|
RenderListParameters(GeometryInstanceSurface **p_elements, int p_element_count, bool p_reverse_cull, uint32_t p_spec_constant_base_flags, bool p_force_wireframe = false, const Plane &p_lod_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0) {
|
||||||
|
elements = p_elements;
|
||||||
|
element_count = p_element_count;
|
||||||
|
reverse_cull = p_reverse_cull;
|
||||||
|
spec_constant_base_flags = p_spec_constant_base_flags;
|
||||||
|
force_wireframe = p_force_wireframe;
|
||||||
|
lod_plane = p_lod_plane;
|
||||||
|
lod_distance_multiplier = p_lod_distance_multiplier;
|
||||||
|
screen_mesh_lod_threshold = p_screen_mesh_lod_threshold;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RenderList {
|
||||||
|
LocalVector<GeometryInstanceSurface *> elements;
|
||||||
|
|
||||||
|
void clear() {
|
||||||
|
elements.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
//should eventually be replaced by radix
|
||||||
|
|
||||||
|
struct SortByKey {
|
||||||
|
_FORCE_INLINE_ bool operator()(const GeometryInstanceSurface *A, const GeometryInstanceSurface *B) const {
|
||||||
|
return (A->sort.sort_key2 == B->sort.sort_key2) ? (A->sort.sort_key1 < B->sort.sort_key1) : (A->sort.sort_key2 < B->sort.sort_key2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void sort_by_key() {
|
||||||
|
SortArray<GeometryInstanceSurface *, SortByKey> sorter;
|
||||||
|
sorter.sort(elements.ptr(), elements.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void sort_by_key_range(uint32_t p_from, uint32_t p_size) {
|
||||||
|
SortArray<GeometryInstanceSurface *, SortByKey> sorter;
|
||||||
|
sorter.sort(elements.ptr() + p_from, p_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SortByDepth {
|
||||||
|
_FORCE_INLINE_ bool operator()(const GeometryInstanceSurface *A, const GeometryInstanceSurface *B) const {
|
||||||
|
return (A->owner->depth < B->owner->depth);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void sort_by_depth() { //used for shadows
|
||||||
|
|
||||||
|
SortArray<GeometryInstanceSurface *, SortByDepth> sorter;
|
||||||
|
sorter.sort(elements.ptr(), elements.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SortByReverseDepthAndPriority {
|
||||||
|
_FORCE_INLINE_ bool operator()(const GeometryInstanceSurface *A, const GeometryInstanceSurface *B) const {
|
||||||
|
return (A->sort.priority == B->sort.priority) ? (A->owner->depth > B->owner->depth) : (A->sort.priority < B->sort.priority);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void sort_by_reverse_depth_and_priority() { //used for alpha
|
||||||
|
|
||||||
|
SortArray<GeometryInstanceSurface *, SortByReverseDepthAndPriority> sorter;
|
||||||
|
sorter.sort(elements.ptr(), elements.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
_FORCE_INLINE_ void add_element(GeometryInstanceSurface *p_element) {
|
||||||
|
elements.push_back(p_element);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
RenderList render_list[RENDER_LIST_MAX];
|
||||||
|
|
||||||
|
void _setup_environment(const RenderDataGLES3 *p_render_data, bool p_no_fog, const Size2i &p_screen_size, bool p_flip_y, const Color &p_default_bg_color, bool p_pancake_shadows);
|
||||||
|
void _fill_render_list(RenderListType p_render_list, const RenderDataGLES3 *p_render_data, PassMode p_pass_mode, bool p_append = false);
|
||||||
|
|
||||||
|
template <PassMode p_pass_mode>
|
||||||
|
_FORCE_INLINE_ void _render_list_template(RenderListParameters *p_params, const RenderDataGLES3 *p_render_data, uint32_t p_from_element, uint32_t p_to_element, bool p_alpha_pass = false);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
double time;
|
double time;
|
||||||
double time_step = 0;
|
double time_step = 0;
|
||||||
|
@ -125,6 +459,8 @@ protected:
|
||||||
//bool use_debanding = false;
|
//bool use_debanding = false;
|
||||||
//uint32_t view_count = 1;
|
//uint32_t view_count = 1;
|
||||||
|
|
||||||
|
bool is_transparent = false;
|
||||||
|
|
||||||
RID render_target;
|
RID render_target;
|
||||||
GLuint internal_texture = 0; // Used for rendering when post effects are enabled
|
GLuint internal_texture = 0; // Used for rendering when post effects are enabled
|
||||||
GLuint depth_texture = 0; // Main depth texture
|
GLuint depth_texture = 0; // Main depth texture
|
||||||
|
@ -391,9 +727,15 @@ public:
|
||||||
/* SDFGI UPDATE */
|
/* SDFGI UPDATE */
|
||||||
|
|
||||||
void sdfgi_update(RID p_render_buffers, RID p_environment, const Vector3 &p_world_position) override {}
|
void sdfgi_update(RID p_render_buffers, RID p_environment, const Vector3 &p_world_position) override {}
|
||||||
int sdfgi_get_pending_region_count(RID p_render_buffers) const override { return 0; }
|
int sdfgi_get_pending_region_count(RID p_render_buffers) const override {
|
||||||
AABB sdfgi_get_pending_region_bounds(RID p_render_buffers, int p_region) const override { return AABB(); }
|
return 0;
|
||||||
uint32_t sdfgi_get_pending_region_cascade(RID p_render_buffers, int p_region) const override { return 0; }
|
}
|
||||||
|
AABB sdfgi_get_pending_region_bounds(RID p_render_buffers, int p_region) const override {
|
||||||
|
return AABB();
|
||||||
|
}
|
||||||
|
uint32_t sdfgi_get_pending_region_cascade(RID p_render_buffers, int p_region) const override {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* SKY API */
|
/* SKY API */
|
||||||
|
|
||||||
|
|
|
@ -344,9 +344,10 @@ void RasterizerStorageGLES3::canvas_light_occluder_set_polylines(RID p_occluder,
|
||||||
RS::InstanceType RasterizerStorageGLES3::get_base_type(RID p_rid) const {
|
RS::InstanceType RasterizerStorageGLES3::get_base_type(RID p_rid) const {
|
||||||
if (GLES3::MeshStorage::get_singleton()->owns_mesh(p_rid)) {
|
if (GLES3::MeshStorage::get_singleton()->owns_mesh(p_rid)) {
|
||||||
return RS::INSTANCE_MESH;
|
return RS::INSTANCE_MESH;
|
||||||
}
|
} else if (GLES3::MeshStorage::get_singleton()->owns_multimesh(p_rid)) {
|
||||||
if (GLES3::MeshStorage::get_singleton()->owns_multimesh(p_rid)) {
|
|
||||||
return RS::INSTANCE_MULTIMESH;
|
return RS::INSTANCE_MULTIMESH;
|
||||||
|
} else if (GLES3::LightStorage::get_singleton()->owns_light(p_rid)) {
|
||||||
|
return RS::INSTANCE_LIGHT;
|
||||||
}
|
}
|
||||||
return RS::INSTANCE_NONE;
|
return RS::INSTANCE_NONE;
|
||||||
}
|
}
|
||||||
|
@ -376,19 +377,14 @@ bool RasterizerStorageGLES3::free(RID p_rid) {
|
||||||
} else if (GLES3::MeshStorage::get_singleton()->owns_mesh_instance(p_rid)) {
|
} else if (GLES3::MeshStorage::get_singleton()->owns_mesh_instance(p_rid)) {
|
||||||
GLES3::MeshStorage::get_singleton()->mesh_instance_free(p_rid);
|
GLES3::MeshStorage::get_singleton()->mesh_instance_free(p_rid);
|
||||||
return true;
|
return true;
|
||||||
|
} else if (GLES3::LightStorage::get_singleton()->owns_light(p_rid)) {
|
||||||
|
GLES3::LightStorage::get_singleton()->light_free(p_rid);
|
||||||
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
} else if (light_owner.owns(p_rid)) {
|
else if (reflection_probe_owner.owns(p_rid)) {
|
||||||
Light *light = light_owner.get_or_null(p_rid);
|
|
||||||
light->instance_remove_deps();
|
|
||||||
|
|
||||||
light_owner.free(p_rid);
|
|
||||||
memdelete(light);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
} else if (reflection_probe_owner.owns(p_rid)) {
|
|
||||||
// delete the texture
|
// delete the texture
|
||||||
ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_rid);
|
ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_rid);
|
||||||
reflection_probe->instance_remove_deps();
|
reflection_probe->instance_remove_deps();
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include "servers/rendering/shader_compiler.h"
|
#include "servers/rendering/shader_compiler.h"
|
||||||
#include "servers/rendering/shader_language.h"
|
#include "servers/rendering/shader_language.h"
|
||||||
#include "storage/config.h"
|
#include "storage/config.h"
|
||||||
|
#include "storage/light_storage.h"
|
||||||
#include "storage/material_storage.h"
|
#include "storage/material_storage.h"
|
||||||
#include "storage/mesh_storage.h"
|
#include "storage/mesh_storage.h"
|
||||||
#include "storage/texture_storage.h"
|
#include "storage/texture_storage.h"
|
||||||
|
@ -55,6 +56,48 @@ public:
|
||||||
|
|
||||||
GLES3::Config *config = nullptr;
|
GLES3::Config *config = nullptr;
|
||||||
|
|
||||||
|
static _FORCE_INLINE_ void store_transform(const Transform3D &p_mtx, float *p_array) {
|
||||||
|
p_array[0] = p_mtx.basis.rows[0][0];
|
||||||
|
p_array[1] = p_mtx.basis.rows[1][0];
|
||||||
|
p_array[2] = p_mtx.basis.rows[2][0];
|
||||||
|
p_array[3] = 0;
|
||||||
|
p_array[4] = p_mtx.basis.rows[0][1];
|
||||||
|
p_array[5] = p_mtx.basis.rows[1][1];
|
||||||
|
p_array[6] = p_mtx.basis.rows[2][1];
|
||||||
|
p_array[7] = 0;
|
||||||
|
p_array[8] = p_mtx.basis.rows[0][2];
|
||||||
|
p_array[9] = p_mtx.basis.rows[1][2];
|
||||||
|
p_array[10] = p_mtx.basis.rows[2][2];
|
||||||
|
p_array[11] = 0;
|
||||||
|
p_array[12] = p_mtx.origin.x;
|
||||||
|
p_array[13] = p_mtx.origin.y;
|
||||||
|
p_array[14] = p_mtx.origin.z;
|
||||||
|
p_array[15] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static _FORCE_INLINE_ void store_transform_3x3(const Basis &p_mtx, float *p_array) {
|
||||||
|
p_array[0] = p_mtx.rows[0][0];
|
||||||
|
p_array[1] = p_mtx.rows[1][0];
|
||||||
|
p_array[2] = p_mtx.rows[2][0];
|
||||||
|
p_array[3] = 0;
|
||||||
|
p_array[4] = p_mtx.rows[0][1];
|
||||||
|
p_array[5] = p_mtx.rows[1][1];
|
||||||
|
p_array[6] = p_mtx.rows[2][1];
|
||||||
|
p_array[7] = 0;
|
||||||
|
p_array[8] = p_mtx.rows[0][2];
|
||||||
|
p_array[9] = p_mtx.rows[1][2];
|
||||||
|
p_array[10] = p_mtx.rows[2][2];
|
||||||
|
p_array[11] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static _FORCE_INLINE_ void store_camera(const CameraMatrix &p_mtx, float *p_array) {
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
for (int j = 0; j < 4; j++) {
|
||||||
|
p_array[i * 4 + j] = p_mtx.matrix[i][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct Resources {
|
struct Resources {
|
||||||
GLuint mipmap_blur_fbo;
|
GLuint mipmap_blur_fbo;
|
||||||
GLuint mipmap_blur_color;
|
GLuint mipmap_blur_color;
|
||||||
|
|
|
@ -171,6 +171,15 @@ void ShaderGLES3::_build_variant_code(StringBuilder &builder, uint32_t p_variant
|
||||||
}
|
}
|
||||||
builder.append("\n"); //make sure defines begin at newline
|
builder.append("\n"); //make sure defines begin at newline
|
||||||
|
|
||||||
|
// Default to highp precision unless specified otherwise.
|
||||||
|
builder.append("precision highp float;\n");
|
||||||
|
builder.append("precision highp int;\n");
|
||||||
|
#ifndef GLES_OVER_GL
|
||||||
|
builder.append("precision highp sampler2D;\n");
|
||||||
|
builder.append("precision highp samplerCube;\n");
|
||||||
|
builder.append("precision highp sampler2DArray;\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
for (uint32_t i = 0; i < p_template.chunks.size(); i++) {
|
for (uint32_t i = 0; i < p_template.chunks.size(); i++) {
|
||||||
const StageTemplate::Chunk &chunk = p_template.chunks[i];
|
const StageTemplate::Chunk &chunk = p_template.chunks[i];
|
||||||
switch (chunk.type) {
|
switch (chunk.type) {
|
||||||
|
|
|
@ -218,6 +218,7 @@ protected:
|
||||||
ERR_FAIL_INDEX_V(p_which, uniform_count, -1);
|
ERR_FAIL_INDEX_V(p_which, uniform_count, -1);
|
||||||
Version *version = version_owner.get_or_null(p_version);
|
Version *version = version_owner.get_or_null(p_version);
|
||||||
ERR_FAIL_COND_V(!version, -1);
|
ERR_FAIL_COND_V(!version, -1);
|
||||||
|
ERR_FAIL_INDEX_V(p_variant, int(version->variants.size()), -1);
|
||||||
return version->variants[p_variant].lookup_ptr(p_specialization)->uniform_location[p_which];
|
return version->variants[p_variant].lookup_ptr(p_specialization)->uniform_location[p_which];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -518,8 +518,8 @@ void main() {
|
||||||
float px_size = max(0.5 * dot((vec2(px_range) / msdf_size), dest_size), 1.0);
|
float px_size = max(0.5 * dot((vec2(px_range) / msdf_size), dest_size), 1.0);
|
||||||
float d = msdf_median(msdf_sample.r, msdf_sample.g, msdf_sample.b, msdf_sample.a) - 0.5;
|
float d = msdf_median(msdf_sample.r, msdf_sample.g, msdf_sample.b, msdf_sample.a) - 0.5;
|
||||||
|
|
||||||
if (outline_thickness > 0) {
|
if (outline_thickness > 0.0) {
|
||||||
float cr = clamp(outline_thickness, 0.0, px_range / 2) / px_range;
|
float cr = clamp(outline_thickness, 0.0, px_range / 2.0) / px_range;
|
||||||
float a = clamp((d + cr) * px_size, 0.0, 1.0);
|
float a = clamp((d + cr) * px_size, 0.0, 1.0);
|
||||||
color.a = a * color.a;
|
color.a = a * color.a;
|
||||||
} else {
|
} else {
|
||||||
|
@ -710,8 +710,8 @@ void main() {
|
||||||
vec2 pos_rot = pos_norm * mat2(vec2(0.7071067811865476, -0.7071067811865476), vec2(0.7071067811865476, 0.7071067811865476)); //is there a faster way to 45 degrees rot?
|
vec2 pos_rot = pos_norm * mat2(vec2(0.7071067811865476, -0.7071067811865476), vec2(0.7071067811865476, 0.7071067811865476)); //is there a faster way to 45 degrees rot?
|
||||||
float tex_ofs;
|
float tex_ofs;
|
||||||
float distance;
|
float distance;
|
||||||
if (pos_rot.y > 0) {
|
if (pos_rot.y > 0.0) {
|
||||||
if (pos_rot.x > 0) {
|
if (pos_rot.x > 0.0) {
|
||||||
tex_ofs = pos_box.y * 0.125 + 0.125;
|
tex_ofs = pos_box.y * 0.125 + 0.125;
|
||||||
distance = shadow_pos.x;
|
distance = shadow_pos.x;
|
||||||
} else {
|
} else {
|
||||||
|
@ -719,7 +719,7 @@ void main() {
|
||||||
distance = shadow_pos.y;
|
distance = shadow_pos.y;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (pos_rot.x < 0) {
|
if (pos_rot.x < 0.0) {
|
||||||
tex_ofs = pos_box.y * -0.125 + (0.5 + 0.125);
|
tex_ofs = pos_box.y * -0.125 + (0.5 + 0.125);
|
||||||
distance = -shadow_pos.x;
|
distance = -shadow_pos.x;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -20,13 +20,19 @@ USE_LIGHT_POSITIONAL = false
|
||||||
|
|
||||||
#include "stdlib_inc.glsl"
|
#include "stdlib_inc.glsl"
|
||||||
|
|
||||||
|
#if !defined(MODE_RENDER_DEPTH) || defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED) ||defined(LIGHT_CLEARCOAT_USED)
|
||||||
|
#ifndef NORMAL_USED
|
||||||
|
#define NORMAL_USED
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
from RenderingServer:
|
from RenderingServer:
|
||||||
ARRAY_VERTEX = 0, // RG32F or RGB32F (depending on 2D bit)
|
ARRAY_VERTEX = 0, // RG32F or RGB32F (depending on 2D bit)
|
||||||
|
ARRAY_NORMAL = 1, // A2B10G10R10, A is ignored.
|
||||||
|
ARRAY_TANGENT = 2, // A2B10G10R10, A flips sign of binormal.
|
||||||
ARRAY_COLOR = 3, // RGBA8
|
ARRAY_COLOR = 3, // RGBA8
|
||||||
ARRAY_TEX_UV = 4, // RG32F
|
ARRAY_TEX_UV = 4, // RG32F
|
||||||
ARRAY_TANGENT = 2, // A2B10G10R10, A flips sign of binormal.
|
|
||||||
ARRAY_NORMAL = 1, // A2B10G10R10, A is ignored.
|
|
||||||
ARRAY_TEX_UV2 = 5, // RG32F
|
ARRAY_TEX_UV2 = 5, // RG32F
|
||||||
ARRAY_CUSTOM0 = 6, // Depends on ArrayCustomFormat.
|
ARRAY_CUSTOM0 = 6, // Depends on ArrayCustomFormat.
|
||||||
ARRAY_CUSTOM1 = 7,
|
ARRAY_CUSTOM1 = 7,
|
||||||
|
@ -40,7 +46,7 @@ ARRAY_MAX = 13
|
||||||
|
|
||||||
/* INPUT ATTRIBS */
|
/* INPUT ATTRIBS */
|
||||||
|
|
||||||
layout(location = 0) in vec3 vertex_attrib;
|
layout(location = 0) in highp vec3 vertex_attrib;
|
||||||
/* clang-format on */
|
/* clang-format on */
|
||||||
|
|
||||||
#ifdef NORMAL_USED
|
#ifdef NORMAL_USED
|
||||||
|
@ -79,19 +85,23 @@ layout(location = 8) in vec4 custom2_attrib;
|
||||||
layout(location = 9) in vec4 custom3_attrib;
|
layout(location = 9) in vec4 custom3_attrib;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(BONES_USED) || defined(USE_PARTICLE_TRAILS)
|
#if defined(BONES_USED)
|
||||||
layout(location = 10) in uvec4 bone_attrib;
|
layout(location = 10) in uvec4 bone_attrib;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(WEIGHTS_USED) || defined(USE_PARTICLE_TRAILS)
|
#if defined(WEIGHTS_USED)
|
||||||
layout(location = 11) in vec4 weight_attrib;
|
layout(location = 11) in vec4 weight_attrib;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
layout(std140) uniform SceneData { // ubo:3
|
layout(std140) uniform GlobalVariableData { //ubo:1
|
||||||
mat4 projection_matrix;
|
vec4 global_variables[MAX_GLOBAL_VARIABLES];
|
||||||
mat4 inv_projection_matrix;
|
};
|
||||||
mat4 inv_view_matrix;
|
|
||||||
mat4 view_matrix;
|
layout(std140) uniform SceneData { // ubo:2
|
||||||
|
highp mat4 projection_matrix;
|
||||||
|
highp mat4 inv_projection_matrix;
|
||||||
|
highp mat4 inv_view_matrix;
|
||||||
|
highp mat4 view_matrix;
|
||||||
|
|
||||||
vec2 viewport_size;
|
vec2 viewport_size;
|
||||||
vec2 screen_pixel_size;
|
vec2 screen_pixel_size;
|
||||||
|
@ -143,15 +153,15 @@ out highp vec3 vertex_interp;
|
||||||
out vec3 normal_interp;
|
out vec3 normal_interp;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(ENABLE_COLOR_INTERP)
|
#if defined(COLOR_USED)
|
||||||
out vec4 color_interp;
|
out vec4 color_interp;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(ENABLE_UV_INTERP)
|
#if defined(UV_USED)
|
||||||
out vec2 uv_interp;
|
out vec2 uv_interp;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(ENABLE_UV2_INTERP)
|
#if defined(UV2_USED)
|
||||||
out vec2 uv2_interp;
|
out vec2 uv2_interp;
|
||||||
#else
|
#else
|
||||||
#ifdef USE_LIGHTMAP
|
#ifdef USE_LIGHTMAP
|
||||||
|
@ -159,15 +169,15 @@ out vec2 uv2_interp;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY)
|
#if defined(TANGENT_USED) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY)
|
||||||
out vec3 tangent_interp;
|
out vec3 tangent_interp;
|
||||||
out vec3 binormal_interp;
|
out vec3 binormal_interp;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(USE_MATERIAL)
|
#if defined(MATERIAL_UNIFORMS_USED)
|
||||||
|
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
layout(std140) uniform UniformData { // ubo:1
|
layout(std140) uniform MaterialUniforms { // ubo:3
|
||||||
|
|
||||||
#MATERIAL_UNIFORMS
|
#MATERIAL_UNIFORMS
|
||||||
|
|
||||||
|
@ -194,31 +204,31 @@ void main() {
|
||||||
#ifdef NORMAL_USED
|
#ifdef NORMAL_USED
|
||||||
vec3 normal = normal_attrib * 2.0 - 1.0;
|
vec3 normal = normal_attrib * 2.0 - 1.0;
|
||||||
#endif
|
#endif
|
||||||
mat3 model_normal_matrix = mat3(model_matrix);
|
highp mat3 model_normal_matrix = mat3(model_matrix);
|
||||||
|
|
||||||
#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY)
|
#if defined(TANGENT_USED) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY)
|
||||||
vec3 tangent;
|
vec3 tangent;
|
||||||
float binormalf;
|
float binormalf;
|
||||||
tangent = normal_tangent_attrib.xyz;
|
tangent = normal_tangent_attrib.xyz;
|
||||||
binormalf = normal_tangent_attrib.a;
|
binormalf = normal_tangent_attrib.a;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(ENABLE_COLOR_INTERP)
|
#if defined(COLOR_USED)
|
||||||
color_interp = color_attrib;
|
color_interp = color_attrib;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY)
|
#if defined(TANGENT_USED) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY)
|
||||||
vec3 binormal = normalize(cross(normal, tangent) * binormalf);
|
vec3 binormal = normalize(cross(normal, tangent) * binormalf);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(ENABLE_UV_INTERP)
|
#if defined(UV_USED)
|
||||||
uv_interp = uv_attrib;
|
uv_interp = uv_attrib;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_LIGHTMAP
|
#ifdef USE_LIGHTMAP
|
||||||
uv2_interp = lightmap_uv_rect.zw * uv2_attrib + lightmap_uv_rect.xy;
|
uv2_interp = lightmap_uv_rect.zw * uv2_attrib + lightmap_uv_rect.xy;
|
||||||
#else
|
#else
|
||||||
#if defined(ENABLE_UV2_INTERP)
|
#if defined(UV2_USED)
|
||||||
uv2_interp = uv2_attrib;
|
uv2_interp = uv2_attrib;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
@ -226,8 +236,8 @@ void main() {
|
||||||
#if defined(OVERRIDE_POSITION)
|
#if defined(OVERRIDE_POSITION)
|
||||||
highp vec4 position;
|
highp vec4 position;
|
||||||
#endif
|
#endif
|
||||||
mat4 projection_matrix = scene_data.projection_matrix;
|
highp mat4 projection_matrix = scene_data.projection_matrix;
|
||||||
mat4 inv_projection_matrix = scene_data.inv_projection_matrix;
|
highp mat4 inv_projection_matrix = scene_data.inv_projection_matrix;
|
||||||
|
|
||||||
vec4 instance_custom = vec4(0.0);
|
vec4 instance_custom = vec4(0.0);
|
||||||
|
|
||||||
|
@ -250,8 +260,8 @@ void main() {
|
||||||
|
|
||||||
float roughness = 1.0;
|
float roughness = 1.0;
|
||||||
|
|
||||||
mat4 modelview = scene_data.view_matrix * model_matrix;
|
highp mat4 modelview = scene_data.view_matrix * model_matrix;
|
||||||
mat3 modelview_normal = mat3(scene_data.view_matrix) * model_normal_matrix;
|
highp mat3 modelview_normal = mat3(scene_data.view_matrix) * model_normal_matrix;
|
||||||
|
|
||||||
float point_size = 1.0;
|
float point_size = 1.0;
|
||||||
|
|
||||||
|
@ -296,7 +306,7 @@ void main() {
|
||||||
normal_interp = normal;
|
normal_interp = normal;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY)
|
#if defined(TANGENT_USED) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY)
|
||||||
tangent_interp = tangent;
|
tangent_interp = tangent;
|
||||||
binormal_interp = binormal;
|
binormal_interp = binormal;
|
||||||
#endif
|
#endif
|
||||||
|
@ -327,7 +337,7 @@ void main() {
|
||||||
#define SPECULAR_SCHLICK_GGX
|
#define SPECULAR_SCHLICK_GGX
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(MODE_RENDER_DEPTH) || defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED)
|
#if !defined(MODE_RENDER_DEPTH) || defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED) ||defined(LIGHT_CLEARCOAT_USED)
|
||||||
#ifndef NORMAL_USED
|
#ifndef NORMAL_USED
|
||||||
#define NORMAL_USED
|
#define NORMAL_USED
|
||||||
#endif
|
#endif
|
||||||
|
@ -351,19 +361,19 @@ uniform highp mat4 world_transform;
|
||||||
/* clang-format on */
|
/* clang-format on */
|
||||||
|
|
||||||
#define M_PI 3.14159265359
|
#define M_PI 3.14159265359
|
||||||
#define SHADER_IS_SRGB false
|
#define SHADER_IS_SRGB true
|
||||||
|
|
||||||
/* Varyings */
|
/* Varyings */
|
||||||
|
|
||||||
#if defined(ENABLE_COLOR_INTERP)
|
#if defined(COLOR_USED)
|
||||||
in vec4 color_interp;
|
in vec4 color_interp;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(ENABLE_UV_INTERP)
|
#if defined(UV_USED)
|
||||||
in vec2 uv_interp;
|
in vec2 uv_interp;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(ENABLE_UV2_INTERP)
|
#if defined(UV2_USED)
|
||||||
in vec2 uv2_interp;
|
in vec2 uv2_interp;
|
||||||
#else
|
#else
|
||||||
#ifdef USE_LIGHTMAP
|
#ifdef USE_LIGHTMAP
|
||||||
|
@ -371,19 +381,22 @@ in vec2 uv2_interp;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY)
|
#if defined(TANGENT_USED) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY)
|
||||||
in vec3 tangent_interp;
|
in vec3 tangent_interp;
|
||||||
in vec3 binormal_interp;
|
in vec3 binormal_interp;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
in highp vec3 vertex_interp;
|
#ifdef NORMAL_USED
|
||||||
in vec3 normal_interp;
|
in vec3 normal_interp;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
in highp vec3 vertex_interp;
|
||||||
|
|
||||||
/* PBR CHANNELS */
|
/* PBR CHANNELS */
|
||||||
|
|
||||||
#ifdef USE_RADIANCE_MAP
|
#ifdef USE_RADIANCE_MAP
|
||||||
|
|
||||||
layout(std140) uniform Radiance { // ubo:2
|
layout(std140) uniform Radiance { // ubo:4
|
||||||
|
|
||||||
mat4 radiance_inverse_xform;
|
mat4 radiance_inverse_xform;
|
||||||
float radiance_ambient_contribution;
|
float radiance_ambient_contribution;
|
||||||
|
@ -405,12 +418,16 @@ vec3 textureDualParaboloid(sampler2D p_tex, vec3 p_vec, float p_roughness) {
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Material Uniforms */
|
layout(std140) uniform GlobalVariableData { //ubo:1
|
||||||
|
vec4 global_variables[MAX_GLOBAL_VARIABLES];
|
||||||
|
};
|
||||||
|
|
||||||
#if defined(USE_MATERIAL)
|
/* Material Uniforms */
|
||||||
|
|
||||||
|
#if defined(MATERIAL_UNIFORMS_USED)
|
||||||
|
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
layout(std140) uniform UniformData {
|
layout(std140) uniform MaterialUniforms { // ubo:3
|
||||||
|
|
||||||
#MATERIAL_UNIFORMS
|
#MATERIAL_UNIFORMS
|
||||||
|
|
||||||
|
@ -419,11 +436,11 @@ layout(std140) uniform UniformData {
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
layout(std140) uniform SceneData { // ubo:3
|
layout(std140) uniform SceneData { // ubo:2
|
||||||
mat4 projection_matrix;
|
highp mat4 projection_matrix;
|
||||||
mat4 inv_projection_matrix;
|
highp mat4 inv_projection_matrix;
|
||||||
mat4 inv_view_matrix;
|
highp mat4 inv_view_matrix;
|
||||||
mat4 view_matrix;
|
highp mat4 view_matrix;
|
||||||
|
|
||||||
vec2 viewport_size;
|
vec2 viewport_size;
|
||||||
vec2 screen_pixel_size;
|
vec2 screen_pixel_size;
|
||||||
|
@ -501,12 +518,12 @@ struct LightData { //this structure needs to be as packed as possible
|
||||||
bool shadow_enabled;
|
bool shadow_enabled;
|
||||||
};
|
};
|
||||||
|
|
||||||
layout(std140) uniform OmniLightData { // ubo:4
|
layout(std140) uniform OmniLightData { // ubo:5
|
||||||
|
|
||||||
LightData omni_lights[MAX_LIGHT_DATA_STRUCTS];
|
LightData omni_lights[MAX_LIGHT_DATA_STRUCTS];
|
||||||
};
|
};
|
||||||
|
|
||||||
layout(std140) uniform SpotLightData { // ubo:5
|
layout(std140) uniform SpotLightData { // ubo:6
|
||||||
|
|
||||||
LightData spot_lights[MAX_LIGHT_DATA_STRUCTS];
|
LightData spot_lights[MAX_LIGHT_DATA_STRUCTS];
|
||||||
};
|
};
|
||||||
|
|
|
@ -12,23 +12,14 @@ mode_cubemap_quarter_res = #define USE_CUBEMAP_PASS \n#define USE_QUARTER_RES_PA
|
||||||
|
|
||||||
#[vertex]
|
#[vertex]
|
||||||
|
|
||||||
#ifdef USE_GLES_OVER_GL
|
|
||||||
#define lowp
|
|
||||||
#define mediump
|
|
||||||
#define highp
|
|
||||||
#else
|
|
||||||
precision highp float;
|
|
||||||
precision highp int;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
out vec2 uv_interp;
|
out vec2 uv_interp;
|
||||||
/* clang-format on */
|
/* clang-format on */
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
// One big triangle to cover the whole screen
|
// One big triangle to cover the whole screen
|
||||||
vec2 base_arr[3] = vec2[](vec2(-1.0, -1.0), vec2(-1.0, 3.0), vec2(3.0, -1.0));
|
vec2 base_arr[3] = vec2[](vec2(-1.0, -1.0), vec2(3.0, -1.0), vec2(-1.0, 3.0));
|
||||||
uv_interp = base_arr[gl_VertexID];
|
uv_interp = base_arr[gl_VertexID];
|
||||||
gl_Position = vec4(uv_interp, 0.0, 1.0);
|
gl_Position = vec4(uv_interp, 1.0, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
|
@ -36,20 +27,6 @@ void main() {
|
||||||
|
|
||||||
#define M_PI 3.14159265359
|
#define M_PI 3.14159265359
|
||||||
|
|
||||||
#ifdef USE_GLES_OVER_GL
|
|
||||||
#define lowp
|
|
||||||
#define mediump
|
|
||||||
#define highp
|
|
||||||
#else
|
|
||||||
#if defined(USE_HIGHP_PRECISION)
|
|
||||||
precision highp float;
|
|
||||||
precision highp int;
|
|
||||||
#else
|
|
||||||
precision mediump float;
|
|
||||||
precision mediump int;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "tonemap_inc.glsl"
|
#include "tonemap_inc.glsl"
|
||||||
|
|
||||||
in vec2 uv_interp;
|
in vec2 uv_interp;
|
||||||
|
@ -65,22 +42,22 @@ uniform sampler2D half_res; //texunit:-2
|
||||||
uniform sampler2D quarter_res; //texunit:-3
|
uniform sampler2D quarter_res; //texunit:-3
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
layout(std140) uniform SceneData { //ubo:0
|
|
||||||
float pad1;
|
|
||||||
float pad2;
|
|
||||||
};
|
|
||||||
|
|
||||||
layout(std140) uniform GlobalVariableData { //ubo:1
|
layout(std140) uniform GlobalVariableData { //ubo:1
|
||||||
vec4 global_variables[MAX_GLOBAL_VARIABLES];
|
vec4 global_variables[MAX_GLOBAL_VARIABLES];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
layout(std140) uniform SceneData { //ubo:2
|
||||||
|
float pad1;
|
||||||
|
float pad2;
|
||||||
|
};
|
||||||
|
|
||||||
struct DirectionalLightData {
|
struct DirectionalLightData {
|
||||||
vec4 direction_energy;
|
vec4 direction_energy;
|
||||||
vec4 color_size;
|
vec4 color_size;
|
||||||
bool enabled;
|
bool enabled;
|
||||||
};
|
};
|
||||||
|
|
||||||
layout(std140) uniform DirectionalLights { //ubo:2
|
layout(std140) uniform DirectionalLights { //ubo:3
|
||||||
DirectionalLightData data[MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS];
|
DirectionalLightData data[MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS];
|
||||||
}
|
}
|
||||||
directional_lights;
|
directional_lights;
|
||||||
|
@ -88,7 +65,7 @@ directional_lights;
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
|
|
||||||
#ifdef MATERIAL_UNIFORMS_USED
|
#ifdef MATERIAL_UNIFORMS_USED
|
||||||
layout(std140) uniform MaterialUniforms{ //ubo:3
|
layout(std140) uniform MaterialUniforms{ //ubo:4
|
||||||
|
|
||||||
#MATERIAL_UNIFORMS
|
#MATERIAL_UNIFORMS
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
|
||||||
#ifdef USE_GLES_OVER_GL
|
#ifdef USE_GLES_OVER_GL
|
||||||
|
// Floating point pack/unpack functions are part of the GLSL ES 300 specification used by web and mobile.
|
||||||
uint float2half(uint f) {
|
uint float2half(uint f) {
|
||||||
return ((f >> uint(16)) & uint(0x8000)) |
|
return ((f >> uint(16)) & uint(0x8000)) |
|
||||||
((((f & uint(0x7f800000)) - uint(0x38000000)) >> uint(13)) & uint(0x7c00)) |
|
((((f & uint(0x7f800000)) - uint(0x38000000)) >> uint(13)) & uint(0x7c00)) |
|
||||||
|
@ -37,6 +38,7 @@ vec2 unpackSnorm2x16(uint p) {
|
||||||
vec2 v = vec2(float(p & uint(0xffff)), float(p >> uint(16)));
|
vec2 v = vec2(float(p & uint(0xffff)), float(p >> uint(16)));
|
||||||
return clamp((v - 32767.0) * vec2(0.00003051851), vec2(-1.0), vec2(1.0));
|
return clamp((v - 32767.0) * vec2(0.00003051851), vec2(-1.0), vec2(1.0));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
uint packUnorm4x8(vec4 v) {
|
uint packUnorm4x8(vec4 v) {
|
||||||
uvec4 uv = uvec4(round(clamp(v, vec4(0.0), vec4(1.0)) * 255.0));
|
uvec4 uv = uvec4(round(clamp(v, vec4(0.0), vec4(1.0)) * 255.0));
|
||||||
|
@ -56,4 +58,3 @@ vec4 unpackSnorm4x8(uint p) {
|
||||||
vec4 v = vec4(float(p & uint(0xffff)), float((p >> uint(8)) & uint(0xffff)), float((p >> uint(16)) & uint(0xffff)), float(p >> uint(24)));
|
vec4 v = vec4(float(p & uint(0xffff)), float((p >> uint(8)) & uint(0xffff)), float((p >> uint(16)) & uint(0xffff)), float(p >> uint(24)));
|
||||||
return clamp((v - vec4(127.0)) * vec4(0.00787401574), vec4(-1.0), vec4(1.0));
|
return clamp((v - vec4(127.0)) * vec4(0.00787401574), vec4(-1.0), vec4(1.0));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
|
@ -10,10 +10,12 @@ uniform sampler3D source_color_correction; //texunit:-1
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// These could be grouped into some form of SceneData UBO along with time, will have to test performance though
|
layout(std140) uniform TonemapData { //ubo:0
|
||||||
uniform int tonemapper;
|
float exposure;
|
||||||
uniform float exposure;
|
float white;
|
||||||
uniform float white;
|
int tonemapper;
|
||||||
|
int pad;
|
||||||
|
};
|
||||||
|
|
||||||
vec3 apply_bcs(vec3 color, vec3 bcs) {
|
vec3 apply_bcs(vec3 color, vec3 bcs) {
|
||||||
color = mix(vec3(0.0), color, bcs.x);
|
color = mix(vec3(0.0), color, bcs.x);
|
||||||
|
|
|
@ -120,16 +120,6 @@ Config::Config() {
|
||||||
support_write_depth = extensions.has("GL_EXT_frag_depth");
|
support_write_depth = extensions.has("GL_EXT_frag_depth");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
support_half_float_vertices = true;
|
|
||||||
//every platform should support this except web, iOS has issues with their support, so add option to disable
|
|
||||||
#ifdef JAVASCRIPT_ENABLED
|
|
||||||
support_half_float_vertices = false;
|
|
||||||
#endif
|
|
||||||
bool disable_half_float = false; //GLOBAL_GET("rendering/opengl/compatibility/disable_half_float");
|
|
||||||
if (disable_half_float) {
|
|
||||||
support_half_float_vertices = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//picky requirements for these
|
//picky requirements for these
|
||||||
support_shadow_cubemaps = support_write_depth && support_depth_cubemaps;
|
support_shadow_cubemaps = support_write_depth && support_depth_cubemaps;
|
||||||
// the use skeleton software path should be used if either float texture is not supported,
|
// the use skeleton software path should be used if either float texture is not supported,
|
||||||
|
@ -149,6 +139,27 @@ Config::Config() {
|
||||||
|
|
||||||
force_vertex_shading = false; //GLOBAL_GET("rendering/quality/shading/force_vertex_shading");
|
force_vertex_shading = false; //GLOBAL_GET("rendering/quality/shading/force_vertex_shading");
|
||||||
use_nearest_mip_filter = GLOBAL_GET("rendering/textures/default_filters/use_nearest_mipmap_filter");
|
use_nearest_mip_filter = GLOBAL_GET("rendering/textures/default_filters/use_nearest_mipmap_filter");
|
||||||
|
|
||||||
|
use_depth_prepass = bool(GLOBAL_GET("rendering/driver/depth_prepass/enable"));
|
||||||
|
if (use_depth_prepass) {
|
||||||
|
String vendors = GLOBAL_GET("rendering/driver/depth_prepass/disable_for_vendors");
|
||||||
|
Vector<String> vendor_match = vendors.split(",");
|
||||||
|
String renderer = (const char *)glGetString(GL_RENDERER);
|
||||||
|
for (int i = 0; i < vendor_match.size(); i++) {
|
||||||
|
String v = vendor_match[i].strip_edges();
|
||||||
|
if (v == String()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (renderer.findn(v) != -1) {
|
||||||
|
use_depth_prepass = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
max_renderable_elements = GLOBAL_GET("rendering/limits/opengl/max_renderable_elements");
|
||||||
|
max_renderable_lights = GLOBAL_GET("rendering/limits/opengl/max_renderable_lights");
|
||||||
|
max_lights_per_object = GLOBAL_GET("rendering/limits/opengl/max_lights_per_object");
|
||||||
}
|
}
|
||||||
|
|
||||||
Config::~Config() {
|
Config::~Config() {
|
||||||
|
|
|
@ -58,6 +58,9 @@ public:
|
||||||
int max_texture_image_units = 0;
|
int max_texture_image_units = 0;
|
||||||
int max_texture_size = 0;
|
int max_texture_size = 0;
|
||||||
int max_uniform_buffer_size = 0;
|
int max_uniform_buffer_size = 0;
|
||||||
|
int max_renderable_elements = 0;
|
||||||
|
int max_renderable_lights = 0;
|
||||||
|
int max_lights_per_object = 0;
|
||||||
|
|
||||||
// TODO implement wireframe in OpenGL
|
// TODO implement wireframe in OpenGL
|
||||||
// bool generate_wireframes;
|
// bool generate_wireframes;
|
||||||
|
@ -82,7 +85,6 @@ public:
|
||||||
|
|
||||||
bool support_32_bits_indices = false;
|
bool support_32_bits_indices = false;
|
||||||
bool support_write_depth = false;
|
bool support_write_depth = false;
|
||||||
bool support_half_float_vertices = false;
|
|
||||||
bool support_npot_repeat_mipmap = false;
|
bool support_npot_repeat_mipmap = false;
|
||||||
bool support_depth_cubemaps = false;
|
bool support_depth_cubemaps = false;
|
||||||
bool support_shadow_cubemaps = false;
|
bool support_shadow_cubemaps = false;
|
||||||
|
@ -97,6 +99,8 @@ public:
|
||||||
// so the user can switch orphaning off for them.
|
// so the user can switch orphaning off for them.
|
||||||
bool should_orphan = true;
|
bool should_orphan = true;
|
||||||
|
|
||||||
|
bool use_depth_prepass = true;
|
||||||
|
|
||||||
static Config *get_singleton() { return singleton; };
|
static Config *get_singleton() { return singleton; };
|
||||||
|
|
||||||
Config();
|
Config();
|
||||||
|
|
|
@ -43,7 +43,7 @@ using namespace GLES3;
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// UBI helper functions
|
// UBI helper functions
|
||||||
|
|
||||||
_FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataType type, int p_array_size, const Variant &value, uint8_t *data, bool p_linear_color) {
|
_FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataType type, int p_array_size, const Variant &value, uint8_t *data) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ShaderLanguage::TYPE_BOOL: {
|
case ShaderLanguage::TYPE_BOOL: {
|
||||||
uint32_t *gui = (uint32_t *)data;
|
uint32_t *gui = (uint32_t *)data;
|
||||||
|
@ -399,9 +399,6 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
|
||||||
for (int i = 0, j = 0; i < p_array_size; i++, j += 4) {
|
for (int i = 0, j = 0; i < p_array_size; i++, j += 4) {
|
||||||
if (i < s) {
|
if (i < s) {
|
||||||
Color color = a[i];
|
Color color = a[i];
|
||||||
if (p_linear_color) {
|
|
||||||
color = color.srgb_to_linear();
|
|
||||||
}
|
|
||||||
gui[j] = color.r;
|
gui[j] = color.r;
|
||||||
gui[j + 1] = color.g;
|
gui[j + 1] = color.g;
|
||||||
gui[j + 2] = color.b;
|
gui[j + 2] = color.b;
|
||||||
|
@ -433,10 +430,6 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
|
||||||
if (value.get_type() == Variant::COLOR) {
|
if (value.get_type() == Variant::COLOR) {
|
||||||
Color v = value;
|
Color v = value;
|
||||||
|
|
||||||
if (p_linear_color) {
|
|
||||||
v = v.srgb_to_linear();
|
|
||||||
}
|
|
||||||
|
|
||||||
gui[0] = v.r;
|
gui[0] = v.r;
|
||||||
gui[1] = v.g;
|
gui[1] = v.g;
|
||||||
gui[2] = v.b;
|
gui[2] = v.b;
|
||||||
|
@ -459,9 +452,6 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
|
||||||
for (int i = 0, j = 0; i < p_array_size; i++, j += 4) {
|
for (int i = 0, j = 0; i < p_array_size; i++, j += 4) {
|
||||||
if (i < s) {
|
if (i < s) {
|
||||||
Color color = a[i];
|
Color color = a[i];
|
||||||
if (p_linear_color) {
|
|
||||||
color = color.srgb_to_linear();
|
|
||||||
}
|
|
||||||
gui[j] = color.r;
|
gui[j] = color.r;
|
||||||
gui[j + 1] = color.g;
|
gui[j + 1] = color.g;
|
||||||
gui[j + 2] = color.b;
|
gui[j + 2] = color.b;
|
||||||
|
@ -496,10 +486,6 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
|
||||||
if (value.get_type() == Variant::COLOR) {
|
if (value.get_type() == Variant::COLOR) {
|
||||||
Color v = value;
|
Color v = value;
|
||||||
|
|
||||||
if (p_linear_color) {
|
|
||||||
v = v.srgb_to_linear();
|
|
||||||
}
|
|
||||||
|
|
||||||
gui[0] = v.r;
|
gui[0] = v.r;
|
||||||
gui[1] = v.g;
|
gui[1] = v.g;
|
||||||
gui[2] = v.b;
|
gui[2] = v.b;
|
||||||
|
@ -987,7 +973,7 @@ void MaterialData::update_uniform_buffer(const Map<StringName, ShaderLanguage::S
|
||||||
|
|
||||||
if (V) {
|
if (V) {
|
||||||
//user provided
|
//user provided
|
||||||
_fill_std140_variant_ubo_value(E.value.type, E.value.array_size, V->get(), data, p_use_linear_color);
|
_fill_std140_variant_ubo_value(E.value.type, E.value.array_size, V->get(), data);
|
||||||
|
|
||||||
} else if (E.value.default_value.size()) {
|
} else if (E.value.default_value.size()) {
|
||||||
//default value
|
//default value
|
||||||
|
@ -997,7 +983,7 @@ void MaterialData::update_uniform_buffer(const Map<StringName, ShaderLanguage::S
|
||||||
//zero because it was not provided
|
//zero because it was not provided
|
||||||
if ((E.value.type == ShaderLanguage::TYPE_VEC3 || E.value.type == ShaderLanguage::TYPE_VEC4) && E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) {
|
if ((E.value.type == ShaderLanguage::TYPE_VEC3 || E.value.type == ShaderLanguage::TYPE_VEC4) && E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) {
|
||||||
//colors must be set as black, with alpha as 1.0
|
//colors must be set as black, with alpha as 1.0
|
||||||
_fill_std140_variant_ubo_value(E.value.type, E.value.array_size, Color(0, 0, 0, 1), data, p_use_linear_color);
|
_fill_std140_variant_ubo_value(E.value.type, E.value.array_size, Color(0, 0, 0, 1), data);
|
||||||
} else {
|
} else {
|
||||||
//else just zero it out
|
//else just zero it out
|
||||||
_fill_std140_ubo_empty(E.value.type, E.value.array_size, data);
|
_fill_std140_ubo_empty(E.value.type, E.value.array_size, data);
|
||||||
|
@ -1883,7 +1869,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob
|
||||||
bv.w = v.a;
|
bv.w = v.a;
|
||||||
|
|
||||||
GlobalVariables::Value &bv_linear = global_variables.buffer_values[p_index + 1];
|
GlobalVariables::Value &bv_linear = global_variables.buffer_values[p_index + 1];
|
||||||
v = v.srgb_to_linear();
|
//v = v.srgb_to_linear();
|
||||||
bv_linear.x = v.r;
|
bv_linear.x = v.r;
|
||||||
bv_linear.y = v.g;
|
bv_linear.y = v.g;
|
||||||
bv_linear.z = v.b;
|
bv_linear.z = v.b;
|
||||||
|
@ -2322,7 +2308,7 @@ void MaterialStorage::global_variables_instance_update(RID p_instance, int p_ind
|
||||||
|
|
||||||
pos += p_index;
|
pos += p_index;
|
||||||
|
|
||||||
_fill_std140_variant_ubo_value(datatype, 0, p_value, (uint8_t *)&global_variables.buffer_values[pos], true); //instances always use linear color in this renderer
|
_fill_std140_variant_ubo_value(datatype, 0, p_value, (uint8_t *)&global_variables.buffer_values[pos]);
|
||||||
_global_variable_mark_buffer_dirty(pos, 1);
|
_global_variable_mark_buffer_dirty(pos, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2929,7 +2915,7 @@ void CanvasMaterialData::update_parameters(const Map<StringName, Variant> &p_par
|
||||||
|
|
||||||
void CanvasMaterialData::bind_uniforms() {
|
void CanvasMaterialData::bind_uniforms() {
|
||||||
// Bind Material Uniforms
|
// Bind Material Uniforms
|
||||||
glBindBufferBase(GL_UNIFORM_BUFFER, RasterizerCanvasGLES3::MATERIAL_UNIFORM_BUFFER_OBJECT, uniform_buffer);
|
glBindBufferBase(GL_UNIFORM_BUFFER, RasterizerCanvasGLES3::MATERIAL_UNIFORM_LOCATION, uniform_buffer);
|
||||||
|
|
||||||
RID *textures = texture_cache.ptrw();
|
RID *textures = texture_cache.ptrw();
|
||||||
ShaderCompiler::GeneratedCode::Texture *texture_uniforms = shader_data->texture_uniforms.ptrw();
|
ShaderCompiler::GeneratedCode::Texture *texture_uniforms = shader_data->texture_uniforms.ptrw();
|
||||||
|
@ -3162,7 +3148,7 @@ GLES3::MaterialData *GLES3::_create_sky_material_func(ShaderData *p_shader) {
|
||||||
|
|
||||||
void SkyMaterialData::bind_uniforms() {
|
void SkyMaterialData::bind_uniforms() {
|
||||||
// Bind Material Uniforms
|
// Bind Material Uniforms
|
||||||
glBindBufferBase(GL_UNIFORM_BUFFER, 3, uniform_buffer);
|
glBindBufferBase(GL_UNIFORM_BUFFER, SKY_MATERIAL_UNIFORM_LOCATION, uniform_buffer);
|
||||||
|
|
||||||
RID *textures = texture_cache.ptrw();
|
RID *textures = texture_cache.ptrw();
|
||||||
ShaderCompiler::GeneratedCode::Texture *texture_uniforms = shader_data->texture_uniforms.ptrw();
|
ShaderCompiler::GeneratedCode::Texture *texture_uniforms = shader_data->texture_uniforms.ptrw();
|
||||||
|
@ -3278,6 +3264,18 @@ void SceneShaderData::set_code(const String &p_code) {
|
||||||
actions.write_flag_pointers["VERTEX"] = &uses_vertex;
|
actions.write_flag_pointers["VERTEX"] = &uses_vertex;
|
||||||
actions.write_flag_pointers["POSITION"] = &uses_position;
|
actions.write_flag_pointers["POSITION"] = &uses_position;
|
||||||
|
|
||||||
|
actions.usage_flag_pointers["TANGENT"] = &uses_tangent;
|
||||||
|
actions.usage_flag_pointers["BINORMAL"] = &uses_tangent;
|
||||||
|
actions.usage_flag_pointers["COLOR"] = &uses_color;
|
||||||
|
actions.usage_flag_pointers["UV"] = &uses_uv;
|
||||||
|
actions.usage_flag_pointers["UV2"] = &uses_uv2;
|
||||||
|
actions.usage_flag_pointers["CUSTOM0"] = &uses_custom0;
|
||||||
|
actions.usage_flag_pointers["CUSTOM1"] = &uses_custom1;
|
||||||
|
actions.usage_flag_pointers["CUSTOM2"] = &uses_custom2;
|
||||||
|
actions.usage_flag_pointers["CUSTOM3"] = &uses_custom3;
|
||||||
|
actions.usage_flag_pointers["BONE_INDICES"] = &uses_bones;
|
||||||
|
actions.usage_flag_pointers["BONE_WEIGHTS"] = &uses_weights;
|
||||||
|
|
||||||
actions.uniforms = &uniforms;
|
actions.uniforms = &uniforms;
|
||||||
|
|
||||||
Error err = MaterialStorage::get_singleton()->shaders.compiler_scene.compile(RS::SHADER_SPATIAL, code, &actions, path, gen_code);
|
Error err = MaterialStorage::get_singleton()->shaders.compiler_scene.compile(RS::SHADER_SPATIAL, code, &actions, path, gen_code);
|
||||||
|
@ -3292,6 +3290,17 @@ void SceneShaderData::set_code(const String &p_code) {
|
||||||
cull_mode = Cull(cull_modei);
|
cull_mode = Cull(cull_modei);
|
||||||
blend_mode = BlendMode(blend_modei);
|
blend_mode = BlendMode(blend_modei);
|
||||||
alpha_antialiasing_mode = AlphaAntiAliasing(alpha_antialiasing_modei);
|
alpha_antialiasing_mode = AlphaAntiAliasing(alpha_antialiasing_modei);
|
||||||
|
vertex_input_mask = uint32_t(uses_normal);
|
||||||
|
vertex_input_mask |= uses_tangent << 1;
|
||||||
|
vertex_input_mask |= uses_color << 2;
|
||||||
|
vertex_input_mask |= uses_uv << 3;
|
||||||
|
vertex_input_mask |= uses_uv2 << 4;
|
||||||
|
vertex_input_mask |= uses_custom0 << 5;
|
||||||
|
vertex_input_mask |= uses_custom1 << 6;
|
||||||
|
vertex_input_mask |= uses_custom2 << 7;
|
||||||
|
vertex_input_mask |= uses_custom3 << 8;
|
||||||
|
vertex_input_mask |= uses_bones << 9;
|
||||||
|
vertex_input_mask |= uses_weights << 10;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
print_line("**compiling shader:");
|
print_line("**compiling shader:");
|
||||||
|
@ -3455,7 +3464,7 @@ GLES3::MaterialData *GLES3::_create_scene_material_func(ShaderData *p_shader) {
|
||||||
|
|
||||||
void SceneMaterialData::bind_uniforms() {
|
void SceneMaterialData::bind_uniforms() {
|
||||||
// Bind Material Uniforms
|
// Bind Material Uniforms
|
||||||
glBindBufferBase(GL_UNIFORM_BUFFER, 3, uniform_buffer);
|
glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_MATERIAL_UNIFORM_LOCATION, uniform_buffer);
|
||||||
|
|
||||||
RID *textures = texture_cache.ptrw();
|
RID *textures = texture_cache.ptrw();
|
||||||
ShaderCompiler::GeneratedCode::Texture *texture_uniforms = shader_data->texture_uniforms.ptrw();
|
ShaderCompiler::GeneratedCode::Texture *texture_uniforms = shader_data->texture_uniforms.ptrw();
|
||||||
|
|
|
@ -279,14 +279,6 @@ struct SceneShaderData : public ShaderData {
|
||||||
CULL_BACK
|
CULL_BACK
|
||||||
};
|
};
|
||||||
|
|
||||||
enum CullVariant {
|
|
||||||
CULL_VARIANT_NORMAL,
|
|
||||||
CULL_VARIANT_REVERSED,
|
|
||||||
CULL_VARIANT_DOUBLE_SIDED,
|
|
||||||
CULL_VARIANT_MAX
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
enum AlphaAntiAliasing {
|
enum AlphaAntiAliasing {
|
||||||
ALPHA_ANTIALIASING_OFF,
|
ALPHA_ANTIALIASING_OFF,
|
||||||
ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE,
|
ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE,
|
||||||
|
@ -335,6 +327,18 @@ struct SceneShaderData : public ShaderData {
|
||||||
bool uses_time;
|
bool uses_time;
|
||||||
bool writes_modelview_or_projection;
|
bool writes_modelview_or_projection;
|
||||||
bool uses_world_coordinates;
|
bool uses_world_coordinates;
|
||||||
|
bool uses_tangent;
|
||||||
|
bool uses_color;
|
||||||
|
bool uses_uv;
|
||||||
|
bool uses_uv2;
|
||||||
|
bool uses_custom0;
|
||||||
|
bool uses_custom1;
|
||||||
|
bool uses_custom2;
|
||||||
|
bool uses_custom3;
|
||||||
|
bool uses_bones;
|
||||||
|
bool uses_weights;
|
||||||
|
|
||||||
|
uint32_t vertex_input_mask = 0;
|
||||||
|
|
||||||
uint64_t last_pass = 0;
|
uint64_t last_pass = 0;
|
||||||
uint32_t index = 0;
|
uint32_t index = 0;
|
||||||
|
|
|
@ -194,6 +194,7 @@ void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface)
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, s->attribute_buffer);
|
glBindBuffer(GL_ARRAY_BUFFER, s->attribute_buffer);
|
||||||
glBufferData(GL_ARRAY_BUFFER, p_surface.attribute_data.size(), p_surface.attribute_data.ptr(), (s->format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
|
glBufferData(GL_ARRAY_BUFFER, p_surface.attribute_data.size(), p_surface.attribute_data.ptr(), (s->format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
|
glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
|
||||||
|
s->attribute_buffer_size = p_surface.attribute_data.size();
|
||||||
}
|
}
|
||||||
if (p_surface.skin_data.size()) {
|
if (p_surface.skin_data.size()) {
|
||||||
glGenBuffers(1, &s->skin_buffer);
|
glGenBuffers(1, &s->skin_buffer);
|
||||||
|
@ -216,6 +217,7 @@ void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface)
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, p_surface.index_data.size(), p_surface.index_data.ptr(), GL_STATIC_DRAW);
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, p_surface.index_data.size(), p_surface.index_data.ptr(), GL_STATIC_DRAW);
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //unbind
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //unbind
|
||||||
s->index_count = p_surface.index_count;
|
s->index_count = p_surface.index_count;
|
||||||
|
s->index_buffer_size = p_surface.index_data.size();
|
||||||
|
|
||||||
if (p_surface.lods.size()) {
|
if (p_surface.lods.size()) {
|
||||||
s->lods = memnew_arr(Mesh::Surface::LOD, p_surface.lods.size());
|
s->lods = memnew_arr(Mesh::Surface::LOD, p_surface.lods.size());
|
||||||
|
@ -323,7 +325,97 @@ RID MeshStorage::mesh_surface_get_material(RID p_mesh, int p_surface) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
RS::SurfaceData MeshStorage::mesh_get_surface(RID p_mesh, int p_surface) const {
|
RS::SurfaceData MeshStorage::mesh_get_surface(RID p_mesh, int p_surface) const {
|
||||||
return RS::SurfaceData();
|
Mesh *mesh = mesh_owner.get_or_null(p_mesh);
|
||||||
|
ERR_FAIL_COND_V(!mesh, RS::SurfaceData());
|
||||||
|
ERR_FAIL_UNSIGNED_INDEX_V((uint32_t)p_surface, mesh->surface_count, RS::SurfaceData());
|
||||||
|
|
||||||
|
Mesh::Surface &s = *mesh->surfaces[p_surface];
|
||||||
|
|
||||||
|
RS::SurfaceData sd;
|
||||||
|
sd.format = s.format;
|
||||||
|
{
|
||||||
|
Vector<uint8_t> ret;
|
||||||
|
ret.resize(s.vertex_buffer_size);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, s.vertex_buffer);
|
||||||
|
|
||||||
|
#if defined(__EMSCRIPTEN__)
|
||||||
|
{
|
||||||
|
uint8_t *w = ret.ptrw();
|
||||||
|
glGetBufferSubData(GL_ARRAY_BUFFER, 0, s.vertex_buffer_size, w);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void *data = glMapBufferRange(GL_ARRAY_BUFFER, 0, s.vertex_buffer_size, GL_MAP_READ_BIT);
|
||||||
|
ERR_FAIL_NULL_V(data, RS::SurfaceData());
|
||||||
|
{
|
||||||
|
uint8_t *w = ret.ptrw();
|
||||||
|
memcpy(w, data, s.vertex_buffer_size);
|
||||||
|
}
|
||||||
|
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||||
|
#endif
|
||||||
|
sd.vertex_data = ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s.attribute_buffer != 0) {
|
||||||
|
Vector<uint8_t> ret;
|
||||||
|
ret.resize(s.attribute_buffer_size);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, s.attribute_buffer);
|
||||||
|
|
||||||
|
#if defined(__EMSCRIPTEN__)
|
||||||
|
{
|
||||||
|
uint8_t *w = ret.ptrw();
|
||||||
|
glGetBufferSubData(GL_ARRAY_BUFFER, 0, s.attribute_buffer_size, w);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void *data = glMapBufferRange(GL_ARRAY_BUFFER, 0, s.attribute_buffer_size, GL_MAP_READ_BIT);
|
||||||
|
ERR_FAIL_NULL_V(data, RS::SurfaceData());
|
||||||
|
{
|
||||||
|
uint8_t *w = ret.ptrw();
|
||||||
|
memcpy(w, data, s.attribute_buffer_size);
|
||||||
|
}
|
||||||
|
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||||
|
#endif
|
||||||
|
sd.attribute_data = ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
sd.vertex_count = s.vertex_count;
|
||||||
|
sd.index_count = s.index_count;
|
||||||
|
sd.primitive = s.primitive;
|
||||||
|
|
||||||
|
if (sd.index_count) {
|
||||||
|
Vector<uint8_t> ret;
|
||||||
|
ret.resize(s.index_buffer_size);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s.index_buffer);
|
||||||
|
|
||||||
|
#if defined(__EMSCRIPTEN__)
|
||||||
|
{
|
||||||
|
uint8_t *w = ret.ptrw();
|
||||||
|
glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, s.index_buffer_size, w);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void *data = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, s.index_buffer_size, GL_MAP_READ_BIT);
|
||||||
|
ERR_FAIL_NULL_V(data, RS::SurfaceData());
|
||||||
|
{
|
||||||
|
uint8_t *w = ret.ptrw();
|
||||||
|
memcpy(w, data, s.index_buffer_size);
|
||||||
|
}
|
||||||
|
glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
|
||||||
|
#endif
|
||||||
|
sd.index_data = ret;
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
sd.aabb = s.aabb;
|
||||||
|
for (uint32_t i = 0; i < s.lod_count; i++) {
|
||||||
|
RS::SurfaceData::LOD lod;
|
||||||
|
lod.edge_length = s.lods[i].edge_length;
|
||||||
|
//lod.index_data = RD::get_singleton()->buffer_get_data(s.lods[i].index_buffer);
|
||||||
|
sd.lods.push_back(lod);
|
||||||
|
}
|
||||||
|
|
||||||
|
sd.bone_aabbs = s.bone_aabbs;
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
|
return sd;
|
||||||
}
|
}
|
||||||
|
|
||||||
int MeshStorage::mesh_get_surface_count(RID p_mesh) const {
|
int MeshStorage::mesh_get_surface_count(RID p_mesh) const {
|
||||||
|
@ -496,7 +588,6 @@ void MeshStorage::mesh_clear(RID p_mesh) {
|
||||||
|
|
||||||
if (s.index_buffer != 0) {
|
if (s.index_buffer != 0) {
|
||||||
glDeleteBuffers(1, &s.index_buffer);
|
glDeleteBuffers(1, &s.index_buffer);
|
||||||
glDeleteVertexArrays(1, &s.index_array);
|
|
||||||
}
|
}
|
||||||
memdelete(mesh->surfaces[i]);
|
memdelete(mesh->surfaces[i]);
|
||||||
}
|
}
|
||||||
|
@ -553,14 +644,14 @@ void MeshStorage::_mesh_surface_generate_version_for_input_mask(Mesh::Surface::V
|
||||||
case RS::ARRAY_NORMAL: {
|
case RS::ARRAY_NORMAL: {
|
||||||
attribs[i].offset = vertex_stride;
|
attribs[i].offset = vertex_stride;
|
||||||
// Will need to change to accommodate octahedral compression
|
// Will need to change to accommodate octahedral compression
|
||||||
attribs[i].size = 1;
|
attribs[i].size = 4;
|
||||||
attribs[i].type = GL_UNSIGNED_INT_2_10_10_10_REV;
|
attribs[i].type = GL_UNSIGNED_INT_2_10_10_10_REV;
|
||||||
vertex_stride += sizeof(float);
|
vertex_stride += sizeof(float);
|
||||||
attribs[i].normalized = GL_TRUE;
|
attribs[i].normalized = GL_TRUE;
|
||||||
} break;
|
} break;
|
||||||
case RS::ARRAY_TANGENT: {
|
case RS::ARRAY_TANGENT: {
|
||||||
attribs[i].offset = vertex_stride;
|
attribs[i].offset = vertex_stride;
|
||||||
attribs[i].size = 1;
|
attribs[i].size = 4;
|
||||||
attribs[i].type = GL_UNSIGNED_INT_2_10_10_10_REV;
|
attribs[i].type = GL_UNSIGNED_INT_2_10_10_10_REV;
|
||||||
vertex_stride += sizeof(float);
|
vertex_stride += sizeof(float);
|
||||||
attribs[i].normalized = GL_TRUE;
|
attribs[i].normalized = GL_TRUE;
|
||||||
|
@ -629,14 +720,17 @@ void MeshStorage::_mesh_surface_generate_version_for_input_mask(Mesh::Surface::V
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (i <= RS::ARRAY_TANGENT) {
|
if (i <= RS::ARRAY_TANGENT) {
|
||||||
|
attribs[i].stride = vertex_stride;
|
||||||
if (mis) {
|
if (mis) {
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, mis->vertex_buffer);
|
glBindBuffer(GL_ARRAY_BUFFER, mis->vertex_buffer);
|
||||||
} else {
|
} else {
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, s->vertex_buffer);
|
glBindBuffer(GL_ARRAY_BUFFER, s->vertex_buffer);
|
||||||
}
|
}
|
||||||
} else if (i <= RS::ARRAY_CUSTOM3) {
|
} else if (i <= RS::ARRAY_CUSTOM3) {
|
||||||
|
attribs[i].stride = attributes_stride;
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, s->attribute_buffer);
|
glBindBuffer(GL_ARRAY_BUFFER, s->attribute_buffer);
|
||||||
} else {
|
} else {
|
||||||
|
attribs[i].stride = skin_stride;
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, s->skin_buffer);
|
glBindBuffer(GL_ARRAY_BUFFER, s->skin_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -645,7 +739,7 @@ void MeshStorage::_mesh_surface_generate_version_for_input_mask(Mesh::Surface::V
|
||||||
} else {
|
} else {
|
||||||
glVertexAttribPointer(i, attribs[i].size, attribs[i].type, attribs[i].normalized, attribs[i].stride, CAST_INT_TO_UCHAR_PTR(attribs[i].offset));
|
glVertexAttribPointer(i, attribs[i].size, attribs[i].type, attribs[i].normalized, attribs[i].stride, CAST_INT_TO_UCHAR_PTR(attribs[i].offset));
|
||||||
}
|
}
|
||||||
glEnableVertexAttribArray(attribs[i].index);
|
glEnableVertexAttribArray(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do not bind index here as we want to switch between index buffers for LOD
|
// Do not bind index here as we want to switch between index buffers for LOD
|
||||||
|
|
|
@ -54,7 +54,6 @@ struct Mesh {
|
||||||
struct Attrib {
|
struct Attrib {
|
||||||
bool enabled;
|
bool enabled;
|
||||||
bool integer;
|
bool integer;
|
||||||
GLuint index;
|
|
||||||
GLint size;
|
GLint size;
|
||||||
GLenum type;
|
GLenum type;
|
||||||
GLboolean normalized;
|
GLboolean normalized;
|
||||||
|
@ -69,6 +68,7 @@ struct Mesh {
|
||||||
GLuint skin_buffer = 0;
|
GLuint skin_buffer = 0;
|
||||||
uint32_t vertex_count = 0;
|
uint32_t vertex_count = 0;
|
||||||
uint32_t vertex_buffer_size = 0;
|
uint32_t vertex_buffer_size = 0;
|
||||||
|
uint32_t attribute_buffer_size = 0;
|
||||||
uint32_t skin_buffer_size = 0;
|
uint32_t skin_buffer_size = 0;
|
||||||
|
|
||||||
// Cache vertex arrays so they can be created
|
// Cache vertex arrays so they can be created
|
||||||
|
@ -84,8 +84,8 @@ struct Mesh {
|
||||||
uint32_t version_count = 0;
|
uint32_t version_count = 0;
|
||||||
|
|
||||||
GLuint index_buffer = 0;
|
GLuint index_buffer = 0;
|
||||||
GLuint index_array = 0;
|
|
||||||
uint32_t index_count = 0;
|
uint32_t index_count = 0;
|
||||||
|
uint32_t index_buffer_size = 0;
|
||||||
|
|
||||||
struct LOD {
|
struct LOD {
|
||||||
float edge_length = 0.0;
|
float edge_length = 0.0;
|
||||||
|
@ -357,6 +357,12 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_FORCE_INLINE_ GLenum mesh_surface_get_index_type(void *p_surface) const {
|
||||||
|
Mesh::Surface *s = reinterpret_cast<Mesh::Surface *>(p_surface);
|
||||||
|
|
||||||
|
return s->vertex_count <= 65536 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT;
|
||||||
|
}
|
||||||
|
|
||||||
// Use this to cache Vertex Array Objects so they are only generated once
|
// Use this to cache Vertex Array Objects so they are only generated once
|
||||||
_FORCE_INLINE_ void mesh_surface_get_vertex_arrays_and_format(void *p_surface, uint32_t p_input_mask, GLuint &r_vertex_array_gl) {
|
_FORCE_INLINE_ void mesh_surface_get_vertex_arrays_and_format(void *p_surface, uint32_t p_input_mask, GLuint &r_vertex_array_gl) {
|
||||||
Mesh::Surface *s = reinterpret_cast<Mesh::Surface *>(p_surface);
|
Mesh::Surface *s = reinterpret_cast<Mesh::Surface *>(p_surface);
|
||||||
|
|
|
@ -62,8 +62,9 @@ TextureStorage::TextureStorage() {
|
||||||
|
|
||||||
Ref<Image> image;
|
Ref<Image> image;
|
||||||
image.instantiate();
|
image.instantiate();
|
||||||
image->create(4, 4, false, Image::FORMAT_RGBA8);
|
image->create(4, 4, true, Image::FORMAT_RGBA8);
|
||||||
image->fill(Color(1, 1, 1, 1));
|
image->fill(Color(1, 1, 1, 1));
|
||||||
|
image->generate_mipmaps();
|
||||||
|
|
||||||
default_gl_textures[DEFAULT_GL_TEXTURE_WHITE] = texture_allocate();
|
default_gl_textures[DEFAULT_GL_TEXTURE_WHITE] = texture_allocate();
|
||||||
texture_2d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_WHITE], image);
|
texture_2d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_WHITE], image);
|
||||||
|
@ -92,8 +93,9 @@ TextureStorage::TextureStorage() {
|
||||||
{ // black
|
{ // black
|
||||||
Ref<Image> image;
|
Ref<Image> image;
|
||||||
image.instantiate();
|
image.instantiate();
|
||||||
image->create(4, 4, false, Image::FORMAT_RGBA8);
|
image->create(4, 4, true, Image::FORMAT_RGBA8);
|
||||||
image->fill(Color(0, 0, 0, 1));
|
image->fill(Color(0, 0, 0, 1));
|
||||||
|
image->generate_mipmaps();
|
||||||
|
|
||||||
default_gl_textures[DEFAULT_GL_TEXTURE_BLACK] = texture_allocate();
|
default_gl_textures[DEFAULT_GL_TEXTURE_BLACK] = texture_allocate();
|
||||||
texture_2d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_BLACK], image);
|
texture_2d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_BLACK], image);
|
||||||
|
@ -117,8 +119,9 @@ TextureStorage::TextureStorage() {
|
||||||
{
|
{
|
||||||
Ref<Image> image;
|
Ref<Image> image;
|
||||||
image.instantiate();
|
image.instantiate();
|
||||||
image->create(4, 4, false, Image::FORMAT_RGBA8);
|
image->create(4, 4, true, Image::FORMAT_RGBA8);
|
||||||
image->fill(Color(0.5, 0.5, 1, 1));
|
image->fill(Color(0.5, 0.5, 1, 1));
|
||||||
|
image->generate_mipmaps();
|
||||||
|
|
||||||
default_gl_textures[DEFAULT_GL_TEXTURE_NORMAL] = texture_allocate();
|
default_gl_textures[DEFAULT_GL_TEXTURE_NORMAL] = texture_allocate();
|
||||||
texture_2d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_NORMAL], image);
|
texture_2d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_NORMAL], image);
|
||||||
|
@ -127,8 +130,9 @@ TextureStorage::TextureStorage() {
|
||||||
{
|
{
|
||||||
Ref<Image> image;
|
Ref<Image> image;
|
||||||
image.instantiate();
|
image.instantiate();
|
||||||
image->create(4, 4, false, Image::FORMAT_RGBA8);
|
image->create(4, 4, true, Image::FORMAT_RGBA8);
|
||||||
image->fill(Color(1.0, 0.5, 1, 1));
|
image->fill(Color(1.0, 0.5, 1, 1));
|
||||||
|
image->generate_mipmaps();
|
||||||
|
|
||||||
default_gl_textures[DEFAULT_GL_TEXTURE_ANISO] = texture_allocate();
|
default_gl_textures[DEFAULT_GL_TEXTURE_ANISO] = texture_allocate();
|
||||||
texture_2d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_ANISO], image);
|
texture_2d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_ANISO], image);
|
||||||
|
@ -189,18 +193,7 @@ TextureStorage::~TextureStorage() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureStorage::set_main_thread_id(Thread::ID p_id) {
|
//TODO, move back to storage
|
||||||
_main_thread_id = p_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TextureStorage::_is_main_thread() {
|
|
||||||
//#if defined DEBUG_ENABLED && defined TOOLS_ENABLED
|
|
||||||
// must be called from main thread in OpenGL
|
|
||||||
bool is_main_thread = _main_thread_id == Thread::get_caller_id();
|
|
||||||
//#endif
|
|
||||||
return is_main_thread;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TextureStorage::can_create_resources_async() const {
|
bool TextureStorage::can_create_resources_async() const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -644,10 +637,14 @@ void TextureStorage::texture_2d_initialize(RID p_texture, const Ref<Image> &p_im
|
||||||
Texture texture;
|
Texture texture;
|
||||||
texture.width = p_image->get_width();
|
texture.width = p_image->get_width();
|
||||||
texture.height = p_image->get_height();
|
texture.height = p_image->get_height();
|
||||||
|
texture.alloc_width = texture.width;
|
||||||
|
texture.alloc_height = texture.height;
|
||||||
|
texture.mipmaps = p_image->get_mipmap_count();
|
||||||
texture.format = p_image->get_format();
|
texture.format = p_image->get_format();
|
||||||
texture.type = Texture::TYPE_2D;
|
texture.type = Texture::TYPE_2D;
|
||||||
texture.target = GL_TEXTURE_2D;
|
texture.target = GL_TEXTURE_2D;
|
||||||
texture.image_cache_2d = p_image; //TODO, remove this once texture_2d_get is implemented
|
_get_gl_image_and_format(Ref<Image>(), texture.format, 0, texture.real_format, texture.gl_format_cache, texture.gl_internal_format_cache, texture.gl_type_cache, texture.compressed, false);
|
||||||
|
//texture.total_data_size = p_image->get_image_data_size(); // verify that this returns size in bytes
|
||||||
texture.active = true;
|
texture.active = true;
|
||||||
glGenTextures(1, &texture.tex_id);
|
glGenTextures(1, &texture.tex_id);
|
||||||
texture_owner.initialize_rid(p_texture, texture);
|
texture_owner.initialize_rid(p_texture, texture);
|
||||||
|
@ -740,49 +737,66 @@ void TextureStorage::texture_3d_placeholder_initialize(RID p_texture) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<Image> TextureStorage::texture_2d_get(RID p_texture) const {
|
Ref<Image> TextureStorage::texture_2d_get(RID p_texture) const {
|
||||||
Texture *tex = texture_owner.get_or_null(p_texture);
|
Texture *texture = texture_owner.get_or_null(p_texture);
|
||||||
ERR_FAIL_COND_V(!tex, Ref<Image>());
|
ERR_FAIL_COND_V(!texture, Ref<Image>());
|
||||||
|
|
||||||
#ifdef TOOLS_ENABLED
|
#ifdef TOOLS_ENABLED
|
||||||
if (tex->image_cache_2d.is_valid() && !tex->is_render_target) {
|
if (texture->image_cache_2d.is_valid() && !texture->is_render_target) {
|
||||||
return tex->image_cache_2d;
|
return texture->image_cache_2d;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
#ifdef GLES_OVER_GL
|
||||||
#ifdef TOOLS_ENABLED
|
// OpenGL 3.3 supports glGetTexImage which is faster and simpler than glReadPixels.
|
||||||
if (tex->image_cache_2d.is_valid()) {
|
Vector<uint8_t> data;
|
||||||
return tex->image_cache_2d;
|
|
||||||
|
int data_size = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, texture->real_format, texture->mipmaps > 1);
|
||||||
|
|
||||||
|
data.resize(data_size * 2); //add some memory at the end, just in case for buggy drivers
|
||||||
|
uint8_t *w = data.ptrw();
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
|
||||||
|
glBindTexture(texture->target, texture->tex_id);
|
||||||
|
|
||||||
|
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
||||||
|
|
||||||
|
for (int i = 0; i < texture->mipmaps; i++) {
|
||||||
|
int ofs = Image::get_image_mipmap_offset(texture->alloc_width, texture->alloc_height, texture->real_format, i);
|
||||||
|
|
||||||
|
if (texture->compressed) {
|
||||||
|
glPixelStorei(GL_PACK_ALIGNMENT, 4);
|
||||||
|
glGetCompressedTexImage(texture->target, i, &w[ofs]);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||||
|
|
||||||
|
glGetTexImage(texture->target, i, texture->gl_format_cache, texture->gl_type_cache, &w[ofs]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
Vector<uint8_t> data = RD::get_singleton()->texture_get_data(tex->rd_texture, 0);
|
data.resize(data_size);
|
||||||
|
|
||||||
ERR_FAIL_COND_V(data.size() == 0, Ref<Image>());
|
ERR_FAIL_COND_V(data.size() == 0, Ref<Image>());
|
||||||
Ref<Image> image;
|
Ref<Image> image;
|
||||||
image.instance();
|
image.instantiate();
|
||||||
image->create(tex->width, tex->height, tex->mipmaps > 1, tex->validated_format, data);
|
image->create(texture->width, texture->height, texture->mipmaps > 1, texture->real_format, data);
|
||||||
ERR_FAIL_COND_V(image->empty(), Ref<Image>());
|
ERR_FAIL_COND_V(image->is_empty(), Ref<Image>());
|
||||||
if (tex->format != tex->validated_format) {
|
if (texture->format != texture->real_format) {
|
||||||
image->convert(tex->format);
|
image->convert(texture->format);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
// Support for Web and Mobile will come later.
|
||||||
|
Ref<Image> image;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef TOOLS_ENABLED
|
#ifdef TOOLS_ENABLED
|
||||||
if (Engine::get_singleton()->is_editor_hint()) {
|
if (Engine::get_singleton()->is_editor_hint() && !texture->is_render_target) {
|
||||||
tex->image_cache_2d = image;
|
texture->image_cache_2d = image;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
return image;
|
||||||
#ifdef TOOLS_ENABLED
|
|
||||||
if (Engine::get_singleton()->is_editor_hint() && !tex->is_render_target) {
|
|
||||||
tex->image_cache_2d = image;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
*/
|
|
||||||
|
|
||||||
// return image;
|
|
||||||
|
|
||||||
return Ref<Image>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureStorage::texture_replace(RID p_texture, RID p_by_texture) {
|
void TextureStorage::texture_replace(RID p_texture, RID p_by_texture) {
|
||||||
|
@ -1357,6 +1371,9 @@ void TextureStorage::_update_render_target(RenderTarget *rt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
texture->format = rt->image_format;
|
texture->format = rt->image_format;
|
||||||
|
texture->real_format = rt->image_format;
|
||||||
|
texture->type = Texture::TYPE_2D;
|
||||||
|
texture->target = GL_TEXTURE_2D;
|
||||||
texture->gl_format_cache = rt->color_format;
|
texture->gl_format_cache = rt->color_format;
|
||||||
texture->gl_type_cache = GL_UNSIGNED_BYTE;
|
texture->gl_type_cache = GL_UNSIGNED_BYTE;
|
||||||
texture->gl_internal_format_cache = rt->color_internal_format;
|
texture->gl_internal_format_cache = rt->color_internal_format;
|
||||||
|
|
|
@ -141,6 +141,7 @@ struct Texture {
|
||||||
int alloc_width = 0;
|
int alloc_width = 0;
|
||||||
int alloc_height = 0;
|
int alloc_height = 0;
|
||||||
Image::Format format = Image::FORMAT_R8;
|
Image::Format format = Image::FORMAT_R8;
|
||||||
|
Image::Format real_format = Image::FORMAT_R8;
|
||||||
|
|
||||||
enum Type {
|
enum Type {
|
||||||
TYPE_2D,
|
TYPE_2D,
|
||||||
|
@ -370,9 +371,6 @@ private:
|
||||||
|
|
||||||
RID default_gl_textures[DEFAULT_GL_TEXTURE_MAX];
|
RID default_gl_textures[DEFAULT_GL_TEXTURE_MAX];
|
||||||
|
|
||||||
Thread::ID _main_thread_id = 0;
|
|
||||||
bool _is_main_thread();
|
|
||||||
|
|
||||||
/* Canvas Texture API */
|
/* Canvas Texture API */
|
||||||
|
|
||||||
RID_Owner<CanvasTexture, true> canvas_texture_owner;
|
RID_Owner<CanvasTexture, true> canvas_texture_owner;
|
||||||
|
@ -440,8 +438,6 @@ public:
|
||||||
};
|
};
|
||||||
bool owns_texture(RID p_rid) { return texture_owner.owns(p_rid); };
|
bool owns_texture(RID p_rid) { return texture_owner.owns(p_rid); };
|
||||||
|
|
||||||
void set_main_thread_id(Thread::ID p_id);
|
|
||||||
|
|
||||||
virtual bool can_create_resources_async() const override;
|
virtual bool can_create_resources_async() const override;
|
||||||
|
|
||||||
RID texture_create();
|
RID texture_create();
|
||||||
|
|
|
@ -623,8 +623,6 @@ void EditorNode::_notification(int p_what) {
|
||||||
|
|
||||||
ResourceImporterTexture::get_singleton()->update_imports();
|
ResourceImporterTexture::get_singleton()->update_imports();
|
||||||
|
|
||||||
// if using a main thread only renderer, we need to update the resource previews
|
|
||||||
EditorResourcePreview::get_singleton()->update();
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case NOTIFICATION_ENTER_TREE: {
|
case NOTIFICATION_ENTER_TREE: {
|
||||||
|
|
|
@ -430,12 +430,8 @@ void EditorResourcePreview::check_for_invalidation(const String &p_path) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorResourcePreview::start() {
|
void EditorResourcePreview::start() {
|
||||||
if (OS::get_singleton()->get_render_main_thread_mode() == OS::RENDER_ANY_THREAD) {
|
ERR_FAIL_COND_MSG(thread.is_started(), "Thread already started.");
|
||||||
ERR_FAIL_COND_MSG(thread.is_started(), "Thread already started.");
|
thread.start(_thread_func, this);
|
||||||
thread.start(_thread_func, this);
|
|
||||||
} else {
|
|
||||||
_mainthread_only = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorResourcePreview::stop() {
|
void EditorResourcePreview::stop() {
|
||||||
|
@ -458,18 +454,3 @@ EditorResourcePreview::EditorResourcePreview() {
|
||||||
EditorResourcePreview::~EditorResourcePreview() {
|
EditorResourcePreview::~EditorResourcePreview() {
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorResourcePreview::update() {
|
|
||||||
if (!_mainthread_only) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!exit.is_set()) {
|
|
||||||
// no need to even lock the mutex if the size is zero
|
|
||||||
// there is no problem if queue.size() is wrong, even if
|
|
||||||
// there was a race condition.
|
|
||||||
if (queue.size()) {
|
|
||||||
_iterate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -81,11 +81,6 @@ class EditorResourcePreview : public Node {
|
||||||
SafeFlag exit;
|
SafeFlag exit;
|
||||||
SafeFlag exited;
|
SafeFlag exited;
|
||||||
|
|
||||||
// when running from GLES, we want to run the previews
|
|
||||||
// in the main thread using an update, rather than create
|
|
||||||
// a separate thread
|
|
||||||
bool _mainthread_only = false;
|
|
||||||
|
|
||||||
struct Item {
|
struct Item {
|
||||||
Ref<Texture2D> preview;
|
Ref<Texture2D> preview;
|
||||||
Ref<Texture2D> small_preview;
|
Ref<Texture2D> small_preview;
|
||||||
|
@ -125,9 +120,6 @@ public:
|
||||||
void start();
|
void start();
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
// for single threaded mode
|
|
||||||
void update();
|
|
||||||
|
|
||||||
EditorResourcePreview();
|
EditorResourcePreview();
|
||||||
~EditorResourcePreview();
|
~EditorResourcePreview();
|
||||||
};
|
};
|
||||||
|
|
|
@ -4112,13 +4112,13 @@ void DisplayServerX11::process_events() {
|
||||||
|
|
||||||
void DisplayServerX11::release_rendering_thread() {
|
void DisplayServerX11::release_rendering_thread() {
|
||||||
#if defined(GLES3_ENABLED)
|
#if defined(GLES3_ENABLED)
|
||||||
// gl_manager->release_current();
|
gl_manager->release_current();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayServerX11::make_rendering_thread() {
|
void DisplayServerX11::make_rendering_thread() {
|
||||||
#if defined(GLES3_ENABLED)
|
#if defined(GLES3_ENABLED)
|
||||||
// gl_manager->make_current();
|
gl_manager->make_current();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1096,7 +1096,6 @@ void Environment::_validate_property(PropertyInfo &property) const {
|
||||||
|
|
||||||
static const char *high_end_prefixes[] = {
|
static const char *high_end_prefixes[] = {
|
||||||
"auto_exposure_",
|
"auto_exposure_",
|
||||||
"tonemap_",
|
|
||||||
"ssr_",
|
"ssr_",
|
||||||
"ssao_",
|
"ssao_",
|
||||||
nullptr
|
nullptr
|
||||||
|
|
|
@ -50,4 +50,34 @@ struct ReflectionData {
|
||||||
// notes: for ambientblend, use distance to edge to blend between already existing global environment
|
// notes: for ambientblend, use distance to edge to blend between already existing global environment
|
||||||
};
|
};
|
||||||
|
|
||||||
uv_scale1
|
struct DirectionalLightData {
|
||||||
|
mediump vec3 direction;
|
||||||
|
mediump float energy;
|
||||||
|
mediump vec3 color;
|
||||||
|
mediump float size;
|
||||||
|
mediump float specular;
|
||||||
|
uint mask;
|
||||||
|
highp float softshadow_angle;
|
||||||
|
highp float soft_shadow_scale;
|
||||||
|
bool blend_splits;
|
||||||
|
bool shadow_enabled;
|
||||||
|
highp float fade_from;
|
||||||
|
highp float fade_to;
|
||||||
|
uvec2 pad;
|
||||||
|
uint bake_mode;
|
||||||
|
mediump float shadow_volumetric_fog_fade;
|
||||||
|
highp vec4 shadow_bias;
|
||||||
|
highp vec4 shadow_normal_bias;
|
||||||
|
highp vec4 shadow_transmittance_bias;
|
||||||
|
highp vec4 shadow_z_range;
|
||||||
|
highp vec4 shadow_range_begin;
|
||||||
|
highp vec4 shadow_split_offsets;
|
||||||
|
highp mat4 shadow_matrix1;
|
||||||
|
highp mat4 shadow_matrix2;
|
||||||
|
highp mat4 shadow_matrix3;
|
||||||
|
highp mat4 shadow_matrix4;
|
||||||
|
highp vec2 uv_scale1;
|
||||||
|
highp vec2 uv_scale2;
|
||||||
|
highp vec2 uv_scale3;
|
||||||
|
highp vec2 uv_scale4;
|
||||||
|
};
|
||||||
|
|
|
@ -2885,6 +2885,7 @@ RenderingServer::RenderingServer() {
|
||||||
GLOBAL_DEF("rendering/shading/overrides/force_lambert_over_burley.mobile", true);
|
GLOBAL_DEF("rendering/shading/overrides/force_lambert_over_burley.mobile", true);
|
||||||
|
|
||||||
GLOBAL_DEF("rendering/driver/depth_prepass/enable", true);
|
GLOBAL_DEF("rendering/driver/depth_prepass/enable", true);
|
||||||
|
GLOBAL_DEF("rendering/driver/depth_prepass/disable_for_vendors", "PowerVR,Mali,Adreno,Apple");
|
||||||
|
|
||||||
GLOBAL_DEF_RST("rendering/textures/default_filters/use_nearest_mipmap_filter", false);
|
GLOBAL_DEF_RST("rendering/textures/default_filters/use_nearest_mipmap_filter", false);
|
||||||
GLOBAL_DEF_RST("rendering/textures/default_filters/anisotropic_filtering_level", 2);
|
GLOBAL_DEF_RST("rendering/textures/default_filters/anisotropic_filtering_level", 2);
|
||||||
|
@ -3002,44 +3003,15 @@ RenderingServer::RenderingServer() {
|
||||||
GLOBAL_DEF("rendering/limits/cluster_builder/max_clustered_elements", 512);
|
GLOBAL_DEF("rendering/limits/cluster_builder/max_clustered_elements", 512);
|
||||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/cluster_builder/max_clustered_elements", PropertyInfo(Variant::FLOAT, "rendering/limits/cluster_builder/max_clustered_elements", PROPERTY_HINT_RANGE, "32,8192,1"));
|
ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/cluster_builder/max_clustered_elements", PropertyInfo(Variant::FLOAT, "rendering/limits/cluster_builder/max_clustered_elements", PROPERTY_HINT_RANGE, "32,8192,1"));
|
||||||
|
|
||||||
|
// OpenGL limits
|
||||||
|
GLOBAL_DEF_RST("rendering/limits/opengl/max_renderable_elements", 65536);
|
||||||
|
ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/opengl/max_renderable_elements", PropertyInfo(Variant::INT, "rendering/limits/opengl/max_renderable_elements", PROPERTY_HINT_RANGE, "1024,65536,1"));
|
||||||
|
GLOBAL_DEF_RST("rendering/limits/opengl/max_renderable_lights", 256);
|
||||||
|
ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/opengl/max_renderable_lights", PropertyInfo(Variant::INT, "rendering/limits/opengl/max_renderable_lights", PROPERTY_HINT_RANGE, "16,4096,1"));
|
||||||
|
GLOBAL_DEF_RST("rendering/limits/opengl/max_lights_per_object", 8);
|
||||||
|
ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/opengl/max_lights_per_object", PropertyInfo(Variant::INT, "rendering/limits/opengl/max_lights_per_object", PROPERTY_HINT_RANGE, "2,1024,1"));
|
||||||
|
|
||||||
GLOBAL_DEF_RST_BASIC("xr/shaders/enabled", false);
|
GLOBAL_DEF_RST_BASIC("xr/shaders/enabled", false);
|
||||||
|
|
||||||
GLOBAL_DEF_RST("rendering/2d/options/use_software_skinning", true);
|
|
||||||
GLOBAL_DEF_RST("rendering/2d/options/ninepatch_mode", 1);
|
|
||||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/2d/options/ninepatch_mode", PropertyInfo(Variant::INT, "rendering/2d/options/ninepatch_mode", PROPERTY_HINT_ENUM, "Fixed,Scaling"));
|
|
||||||
|
|
||||||
GLOBAL_DEF_RST("rendering/2d/opengl/batching_send_null", 0);
|
|
||||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/2d/opengl/batching_send_null", PropertyInfo(Variant::INT, "rendering/2d/opengl/batching_send_null", PROPERTY_HINT_ENUM, "Default (On),Off,On"));
|
|
||||||
GLOBAL_DEF_RST("rendering/2d/opengl/batching_stream", 0);
|
|
||||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/2d/opengl/batching_stream", PropertyInfo(Variant::INT, "rendering/2d/opengl/batching_stream", PROPERTY_HINT_ENUM, "Default (Off),Off,On"));
|
|
||||||
GLOBAL_DEF_RST("rendering/2d/opengl/legacy_orphan_buffers", 0);
|
|
||||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/2d/opengl/legacy_orphan_buffers", PropertyInfo(Variant::INT, "rendering/2d/opengl/legacy_orphan_buffers", PROPERTY_HINT_ENUM, "Default (On),Off,On"));
|
|
||||||
GLOBAL_DEF_RST("rendering/2d/opengl/legacy_stream", 0);
|
|
||||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/2d/opengl/legacy_stream", PropertyInfo(Variant::INT, "rendering/2d/opengl/legacy_stream", PROPERTY_HINT_ENUM, "Default (On),Off,On"));
|
|
||||||
|
|
||||||
GLOBAL_DEF("rendering/batching/options/use_batching", false);
|
|
||||||
GLOBAL_DEF_RST("rendering/batching/options/use_batching_in_editor", false);
|
|
||||||
GLOBAL_DEF("rendering/batching/options/single_rect_fallback", false);
|
|
||||||
GLOBAL_DEF("rendering/batching/parameters/max_join_item_commands", 16);
|
|
||||||
GLOBAL_DEF("rendering/batching/parameters/colored_vertex_format_threshold", 0.25f);
|
|
||||||
GLOBAL_DEF("rendering/batching/lights/scissor_area_threshold", 1.0f);
|
|
||||||
GLOBAL_DEF("rendering/batching/lights/max_join_items", 32);
|
|
||||||
GLOBAL_DEF("rendering/batching/parameters/batch_buffer_size", 16384);
|
|
||||||
GLOBAL_DEF("rendering/batching/parameters/item_reordering_lookahead", 4);
|
|
||||||
GLOBAL_DEF("rendering/batching/debug/flash_batching", false);
|
|
||||||
GLOBAL_DEF("rendering/batching/debug/diagnose_frame", false);
|
|
||||||
GLOBAL_DEF("rendering/gles2/compatibility/disable_half_float", false);
|
|
||||||
GLOBAL_DEF("rendering/gles2/compatibility/enable_high_float.Android", false);
|
|
||||||
GLOBAL_DEF("rendering/batching/precision/uv_contract", false);
|
|
||||||
GLOBAL_DEF("rendering/batching/precision/uv_contract_amount", 100);
|
|
||||||
|
|
||||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/batching/parameters/max_join_item_commands", PropertyInfo(Variant::INT, "rendering/batching/parameters/max_join_item_commands", PROPERTY_HINT_RANGE, "0,65535"));
|
|
||||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/batching/parameters/colored_vertex_format_threshold", PropertyInfo(Variant::FLOAT, "rendering/batching/parameters/colored_vertex_format_threshold", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"));
|
|
||||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/batching/parameters/batch_buffer_size", PropertyInfo(Variant::INT, "rendering/batching/parameters/batch_buffer_size", PROPERTY_HINT_RANGE, "1024,65535,1024"));
|
|
||||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/batching/lights/scissor_area_threshold", PropertyInfo(Variant::FLOAT, "rendering/batching/lights/scissor_area_threshold", PROPERTY_HINT_RANGE, "0.0,1.0"));
|
|
||||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/batching/lights/max_join_items", PropertyInfo(Variant::INT, "rendering/batching/lights/max_join_items", PROPERTY_HINT_RANGE, "0,512"));
|
|
||||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/batching/parameters/item_reordering_lookahead", PropertyInfo(Variant::INT, "rendering/batching/parameters/item_reordering_lookahead", PROPERTY_HINT_RANGE, "0,256"));
|
|
||||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/batching/precision/uv_contract_amount", PropertyInfo(Variant::INT, "rendering/batching/precision/uv_contract_amount", PROPERTY_HINT_RANGE, "0,10000"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderingServer::~RenderingServer() {
|
RenderingServer::~RenderingServer() {
|
||||||
|
|
Loading…
Reference in New Issue