summaryrefslogtreecommitdiff
path: root/servers/rendering
diff options
context:
space:
mode:
Diffstat (limited to 'servers/rendering')
-rw-r--r--servers/rendering/renderer_canvas_cull.cpp42
-rw-r--r--servers/rendering/renderer_rd/effects/copy_effects.cpp3
-rw-r--r--servers/rendering/renderer_rd/environment/sky.cpp4
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp1
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp1
-rw-r--r--servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp17
-rw-r--r--servers/rendering/renderer_rd/renderer_canvas_render_rd.h4
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.cpp6
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/cubemap_roughness_inc.glsl11
-rw-r--r--servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl9
-rw-r--r--servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl8
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_data_inc.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl2
-rw-r--r--servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp9
-rw-r--r--servers/rendering/renderer_rd/storage_rd/mesh_storage.h1
-rw-r--r--servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp1
-rw-r--r--servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h3
-rw-r--r--servers/rendering/renderer_scene_cull.cpp6
-rw-r--r--servers/rendering/renderer_scene_render.cpp4
-rw-r--r--servers/rendering/renderer_scene_render.h3
-rw-r--r--servers/rendering/rendering_device.cpp20
-rw-r--r--servers/rendering/rendering_device.h4
-rw-r--r--servers/rendering/rendering_device_binds.h2
-rw-r--r--servers/rendering/shader_language.cpp6
-rw-r--r--servers/rendering/shader_types.cpp2
25 files changed, 101 insertions, 70 deletions
diff --git a/servers/rendering/renderer_canvas_cull.cpp b/servers/rendering/renderer_canvas_cull.cpp
index 16d382a5f3..33f1f38bf5 100644
--- a/servers/rendering/renderer_canvas_cull.cpp
+++ b/servers/rendering/renderer_canvas_cull.cpp
@@ -275,12 +275,12 @@ void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2
if (ci->clip) {
if (p_canvas_clip != nullptr) {
ci->final_clip_rect = p_canvas_clip->final_clip_rect.intersection(global_rect);
- if (ci->final_clip_rect == Rect2()) {
- // Clip rects do not intersect, so don't draw this item.
- return;
- }
} else {
- ci->final_clip_rect = global_rect;
+ ci->final_clip_rect = p_clip_rect.intersection(global_rect);
+ }
+ if (ci->final_clip_rect.size.width < 0.5 || ci->final_clip_rect.size.height < 0.5) {
+ // The clip rect area is 0, so don't draw the item.
+ return;
}
ci->final_clip_rect.position = ci->final_clip_rect.position.round();
ci->final_clip_rect.size = ci->final_clip_rect.size.round();
@@ -1075,18 +1075,36 @@ void RendererCanvasCull::canvas_item_add_polyline(RID p_item, const Vector<Point
void RendererCanvasCull::canvas_item_add_multiline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width) {
ERR_FAIL_COND(p_points.size() < 2);
- Item *canvas_item = canvas_item_owner.get_or_null(p_item);
- ERR_FAIL_COND(!canvas_item);
-
- Item::CommandPolygon *pline = canvas_item->alloc_command<Item::CommandPolygon>();
- ERR_FAIL_COND(!pline);
- if (true || p_width <= 1) {
-#define TODO make thick lines possible
+ // TODO: `canvas_item_add_line`(`multiline`, `polyline`) share logic, should factor out.
+ if (p_width <= 1) {
+ Item *canvas_item = canvas_item_owner.get_or_null(p_item);
+ ERR_FAIL_COND(!canvas_item);
+ Item::CommandPolygon *pline = canvas_item->alloc_command<Item::CommandPolygon>();
+ ERR_FAIL_COND(!pline);
pline->primitive = RS::PRIMITIVE_LINES;
pline->polygon.create(Vector<int>(), p_points, p_colors);
} else {
+ if (p_colors.size() == 1) {
+ Color color = p_colors[0];
+ for (int i = 0; i < p_points.size() >> 1; i++) {
+ Vector2 from = p_points[i * 2 + 0];
+ Vector2 to = p_points[i * 2 + 1];
+
+ canvas_item_add_line(p_item, from, to, color, p_width);
+ }
+ } else if (p_colors.size() == p_points.size() >> 1) {
+ for (int i = 0; i < p_points.size() >> 1; i++) {
+ Color color = p_colors[i];
+ Vector2 from = p_points[i * 2 + 0];
+ Vector2 to = p_points[i * 2 + 1];
+
+ canvas_item_add_line(p_item, from, to, color, p_width);
+ }
+ } else {
+ ERR_FAIL_MSG("Length of p_colors is invalid.");
+ }
}
}
diff --git a/servers/rendering/renderer_rd/effects/copy_effects.cpp b/servers/rendering/renderer_rd/effects/copy_effects.cpp
index a05db8c563..f94abd66d7 100644
--- a/servers/rendering/renderer_rd/effects/copy_effects.cpp
+++ b/servers/rendering/renderer_rd/effects/copy_effects.cpp
@@ -1153,7 +1153,8 @@ void CopyEffects::cubemap_roughness(RID p_source_rd_texture, RID p_dest_texture,
memset(&roughness.push_constant, 0, sizeof(CubemapRoughnessPushConstant));
roughness.push_constant.face_id = p_face_id > 9 ? 0 : p_face_id;
- roughness.push_constant.roughness = p_roughness * p_roughness; // Shader expects roughness, not perceptual roughness, so multiply before passing in.
+ // Remap to perceptual-roughness^2 to create more detail in lower mips and match the mapping of cubemap_filter.
+ roughness.push_constant.roughness = p_roughness * p_roughness;
roughness.push_constant.sample_count = p_sample_count;
roughness.push_constant.use_direct_write = p_roughness == 0.0;
roughness.push_constant.face_size = p_size;
diff --git a/servers/rendering/renderer_rd/environment/sky.cpp b/servers/rendering/renderer_rd/environment/sky.cpp
index 0acd48c22a..36d26ad783 100644
--- a/servers/rendering/renderer_rd/environment/sky.cpp
+++ b/servers/rendering/renderer_rd/environment/sky.cpp
@@ -1661,7 +1661,7 @@ void SkyRD::update_res_buffers(RID p_env, uint32_t p_view_count, const Projectio
projections = &camera;
}
- sky_transform = p_transform.basis * sky_transform;
+ sky_transform = sky_transform * p_transform.basis;
if (shader_data->uses_quarter_res) {
PipelineCacheRD *pipeline = &shader_data->pipelines[view_count > 1 ? SKY_VERSION_QUARTER_RES_MULTIVIEW : SKY_VERSION_QUARTER_RES];
@@ -1754,7 +1754,7 @@ void SkyRD::draw(RD::DrawListID p_draw_list, RID p_env, RID p_fb, uint32_t p_vie
projections = &camera;
}
- sky_transform = p_transform.basis * sky_transform;
+ sky_transform = sky_transform * p_transform.basis;
PipelineCacheRD *pipeline = &shader_data->pipelines[view_count > 1 ? SKY_VERSION_BACKGROUND_MULTIVIEW : SKY_VERSION_BACKGROUND];
diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
index 6c8ce5265e..b5d4098e65 100644
--- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
@@ -709,6 +709,7 @@ void SceneShaderForwardClustered::init(const String p_defines) {
actions.renames["NODE_POSITION_WORLD"] = "read_model_matrix[3].xyz";
actions.renames["CAMERA_POSITION_WORLD"] = "scene_data.inv_view_matrix[3].xyz";
actions.renames["CAMERA_DIRECTION_WORLD"] = "scene_data.view_matrix[3].xyz";
+ actions.renames["CAMERA_VISIBLE_LAYERS"] = "scene_data.camera_visible_layers";
actions.renames["NODE_POSITION_VIEW"] = "(read_model_matrix * scene_data.view_matrix)[3].xyz";
actions.renames["VIEW_INDEX"] = "ViewIndex";
diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
index ee82fa7c7d..2d80cffdad 100644
--- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
+++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
@@ -609,6 +609,7 @@ void SceneShaderForwardMobile::init(const String p_defines) {
actions.renames["NODE_POSITION_WORLD"] = "read_model_matrix[3].xyz";
actions.renames["CAMERA_POSITION_WORLD"] = "scene_data.inv_view_matrix[3].xyz";
actions.renames["CAMERA_DIRECTION_WORLD"] = "scene_data.view_matrix[3].xyz";
+ actions.renames["CAMERA_VISIBLE_LAYERS"] = "scene_data.camera_visible_layers";
actions.renames["NODE_POSITION_VIEW"] = "(read_model_matrix * scene_data.view_matrix)[3].xyz";
actions.renames["VIEW_INDEX"] = "ViewIndex";
diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
index cc8238a8dd..d41daa18b4 100644
--- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
@@ -398,7 +398,7 @@ void RendererCanvasRenderRD::_bind_canvas_texture(RD::DrawListID p_draw_list, RI
r_last_texture = p_texture;
}
-void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_render_target, const Item *p_item, RD::FramebufferFormatID p_framebuffer_format, const Transform2D &p_canvas_transform_inverse, Item *&current_clip, Light *p_lights, PipelineVariants *p_pipeline_variants) {
+void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_render_target, const Item *p_item, RD::FramebufferFormatID p_framebuffer_format, const Transform2D &p_canvas_transform_inverse, Item *&current_clip, Light *p_lights, PipelineVariants *p_pipeline_variants, bool &r_sdf_used) {
//create an empty push constant
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
RendererRD::MeshStorage *mesh_storage = RendererRD::MeshStorage::get_singleton();
@@ -833,6 +833,9 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend
} else {
particles_storage->particles_set_canvas_sdf_collision(pt->particles, false, Transform2D(), Rect2(), RID());
}
+
+ // Signal that SDF texture needs to be updated.
+ r_sdf_used |= particles_storage->particles_has_collision(pt->particles);
}
if (mesh.is_null()) {
@@ -1045,7 +1048,7 @@ RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, boo
return uniform_set;
}
-void RendererCanvasRenderRD::_render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool p_to_backbuffer) {
+void RendererCanvasRenderRD::_render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool &r_sdf_used, bool p_to_backbuffer) {
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
@@ -1142,7 +1145,7 @@ void RendererCanvasRenderRD::_render_items(RID p_to_render_target, int p_item_co
}
}
- _render_item(draw_list, p_to_render_target, ci, fb_format, canvas_transform_inverse, current_clip, p_lights, pipeline_variants);
+ _render_item(draw_list, p_to_render_target, ci, fb_format, canvas_transform_inverse, current_clip, p_lights, pipeline_variants, r_sdf_used);
prev_material = material;
}
@@ -1440,7 +1443,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p
update_skeletons = false;
}
- _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list);
+ _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, r_sdf_used);
item_count = 0;
if (ci->canvas_group_owner->canvas_group->mode != RS::CANVAS_GROUP_MODE_TRANSPARENT) {
@@ -1472,7 +1475,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p
update_skeletons = false;
}
- _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, true);
+ _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, r_sdf_used, true);
item_count = 0;
if (ci->canvas_group->blur_mipmaps) {
@@ -1491,7 +1494,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p
update_skeletons = false;
}
- _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list);
+ _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, r_sdf_used);
item_count = 0;
texture_storage->render_target_copy_to_back_buffer(p_to_render_target, back_buffer_rect, backbuffer_gen_mipmaps);
@@ -1517,7 +1520,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p
update_skeletons = false;
}
- _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list);
+ _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, r_sdf_used, false);
//then reset
item_count = 0;
}
diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h
index 3fff574098..6e876b1297 100644
--- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h
+++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h
@@ -421,8 +421,8 @@ class RendererCanvasRenderRD : public RendererCanvasRender {
RID _create_base_uniform_set(RID p_to_render_target, bool p_backbuffer);
inline void _bind_canvas_texture(RD::DrawListID p_draw_list, RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, RID &r_last_texture, PushConstant &push_constant, Size2 &r_texpixel_size); //recursive, so regular inline used instead.
- void _render_item(RenderingDevice::DrawListID p_draw_list, RID p_render_target, const Item *p_item, RenderingDevice::FramebufferFormatID p_framebuffer_format, const Transform2D &p_canvas_transform_inverse, Item *&current_clip, Light *p_lights, PipelineVariants *p_pipeline_variants);
- void _render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool p_to_backbuffer = false);
+ void _render_item(RenderingDevice::DrawListID p_draw_list, RID p_render_target, const Item *p_item, RenderingDevice::FramebufferFormatID p_framebuffer_format, const Transform2D &p_canvas_transform_inverse, Item *&current_clip, Light *p_lights, PipelineVariants *p_pipeline_variants, bool &r_sdf_used);
+ void _render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool &r_sdf_used, bool p_to_backbuffer = false);
_FORCE_INLINE_ void _update_transform_2d_to_mat2x4(const Transform2D &p_transform, float *p_mat2x4);
_FORCE_INLINE_ void _update_transform_2d_to_mat2x3(const Transform2D &p_transform, float *p_mat2x3);
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
index 75fe84f46b..1b5665855f 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
@@ -1078,6 +1078,7 @@ void RendererSceneRenderRD::render_scene(const Ref<RenderSceneBuffers> &p_render
scene_data.cam_transform = p_camera_data->main_transform;
scene_data.cam_projection = p_camera_data->main_projection;
scene_data.cam_orthogonal = p_camera_data->is_orthogonal;
+ scene_data.camera_visible_layers = p_camera_data->visible_layers;
scene_data.taa_jitter = p_camera_data->taa_jitter;
scene_data.view_count = p_camera_data->view_count;
@@ -1418,10 +1419,13 @@ void RendererSceneRenderRD::init() {
cull_argument.set_page_pool(&cull_argument_pool);
bool can_use_storage = _render_buffers_can_be_storage();
+ bool can_use_vrs = is_vrs_supported();
bokeh_dof = memnew(RendererRD::BokehDOF(!can_use_storage));
copy_effects = memnew(RendererRD::CopyEffects(!can_use_storage));
tone_mapper = memnew(RendererRD::ToneMapper);
- vrs = memnew(RendererRD::VRS);
+ if (can_use_vrs) {
+ vrs = memnew(RendererRD::VRS);
+ }
if (can_use_storage) {
fsr = memnew(RendererRD::FSR);
}
diff --git a/servers/rendering/renderer_rd/shaders/effects/cubemap_roughness_inc.glsl b/servers/rendering/renderer_rd/shaders/effects/cubemap_roughness_inc.glsl
index 1bee428a6f..c0597fe3f3 100644
--- a/servers/rendering/renderer_rd/shaders/effects/cubemap_roughness_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/cubemap_roughness_inc.glsl
@@ -70,17 +70,6 @@ float DistributionGGX(float NdotH, float roughness4) {
return roughness4 / denom;
}
-// https://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html
-float GGX(float NdotV, float a) {
- float k = a / 2.0;
- return NdotV / (NdotV * (1.0 - k) + k);
-}
-
-// https://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html
-float G_Smith(float a, float nDotV, float nDotL) {
- return GGX(nDotL, a * a) * GGX(nDotV, a * a);
-}
-
float radicalInverse_VdC(uint bits) {
bits = (bits << 16u) | (bits >> 16u);
bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
diff --git a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl
index 896f51ca01..be53a7ae49 100644
--- a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl
+++ b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl
@@ -1084,12 +1084,13 @@ void fragment_shader(in SceneData scene_data) {
#ifdef USE_RADIANCE_CUBEMAP_ARRAY
float lod, blend;
- blend = modf(roughness * MAX_ROUGHNESS_LOD, lod);
+
+ blend = modf(sqrt(roughness) * MAX_ROUGHNESS_LOD, lod);
specular_light = texture(samplerCubeArray(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(ref_vec, lod)).rgb;
specular_light = mix(specular_light, texture(samplerCubeArray(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(ref_vec, lod + 1)).rgb, blend);
#else
- specular_light = textureLod(samplerCube(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), ref_vec, roughness * MAX_ROUGHNESS_LOD).rgb;
+ specular_light = textureLod(samplerCube(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), ref_vec, sqrt(roughness) * MAX_ROUGHNESS_LOD).rgb;
#endif //USE_RADIANCE_CUBEMAP_ARRAY
specular_light *= scene_data.IBL_exposure_normalization;
@@ -1137,7 +1138,7 @@ void fragment_shader(in SceneData scene_data) {
ref_vec = mix(ref_vec, n, clearcoat_roughness * clearcoat_roughness);
float horizon = min(1.0 + dot(ref_vec, normal), 1.0);
ref_vec = scene_data.radiance_inverse_xform * ref_vec;
- float roughness_lod = mix(0.001, 0.1, clearcoat_roughness) * MAX_ROUGHNESS_LOD;
+ float roughness_lod = mix(0.001, 0.1, sqrt(clearcoat_roughness)) * MAX_ROUGHNESS_LOD;
#ifdef USE_RADIANCE_CUBEMAP_ARRAY
float lod, blend;
@@ -1484,7 +1485,7 @@ void fragment_shader(in SceneData scene_data) {
float a004 = min(r.x * r.x, exp2(-9.28 * ndotv)) * r.x + r.y;
vec2 env = vec2(-1.04, 1.04) * a004 + r.zw;
- specular_light *= env.x * f0 + env.y * clamp(50.0 * f0.g, 0.0, 1.0);
+ specular_light *= env.x * f0 + env.y * clamp(50.0 * f0.g, metallic, 1.0);
#endif
}
diff --git a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl
index d50749306e..b45c68db5a 100644
--- a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl
+++ b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl
@@ -987,12 +987,12 @@ void main() {
#ifdef USE_RADIANCE_CUBEMAP_ARRAY
float lod, blend;
- blend = modf(roughness * MAX_ROUGHNESS_LOD, lod);
+ blend = modf(sqrt(roughness) * MAX_ROUGHNESS_LOD, lod);
specular_light = texture(samplerCubeArray(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(ref_vec, lod)).rgb;
specular_light = mix(specular_light, texture(samplerCubeArray(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(ref_vec, lod + 1)).rgb, blend);
#else // USE_RADIANCE_CUBEMAP_ARRAY
- specular_light = textureLod(samplerCube(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), ref_vec, roughness * MAX_ROUGHNESS_LOD).rgb;
+ specular_light = textureLod(samplerCube(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), ref_vec, sqrt(roughness) * MAX_ROUGHNESS_LOD).rgb;
#endif //USE_RADIANCE_CUBEMAP_ARRAY
specular_light *= sc_luminance_multiplier;
@@ -1042,7 +1042,7 @@ void main() {
float horizon = min(1.0 + dot(ref_vec, normal), 1.0);
ref_vec = scene_data.radiance_inverse_xform * ref_vec;
- float roughness_lod = mix(0.001, 0.1, clearcoat_roughness) * MAX_ROUGHNESS_LOD;
+ float roughness_lod = mix(0.001, 0.1, sqrt(clearcoat_roughness)) * MAX_ROUGHNESS_LOD;
#ifdef USE_RADIANCE_CUBEMAP_ARRAY
float lod, blend;
@@ -1205,7 +1205,7 @@ void main() {
float a004 = min(r.x * r.x, exp2(-9.28 * ndotv)) * r.x + r.y;
vec2 env = vec2(-1.04, 1.04) * a004 + r.zw;
- specular_light *= env.x * f0 + env.y;
+ specular_light *= env.x * f0 + env.y * clamp(50.0 * f0.g, metallic, 1.0);
#endif
}
diff --git a/servers/rendering/renderer_rd/shaders/scene_data_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_data_inc.glsl
index 048257e9ef..b57ee18521 100644
--- a/servers/rendering/renderer_rd/shaders/scene_data_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_data_inc.glsl
@@ -63,7 +63,7 @@ struct SceneData {
float IBL_exposure_normalization;
bool pancake_shadows;
- uint pad1;
+ uint camera_visible_layers;
uint pad2;
uint pad3;
};
diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl
index 2fba1351f7..ba31b9c6dd 100644
--- a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl
@@ -202,7 +202,7 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte
float cLdotH5 = SchlickFresnel(cLdotH);
// Calculate Fresnel using specular occlusion term from Filament:
// https://google.github.io/filament/Filament.html#lighting/occlusion/specularocclusion
- float f90 = clamp(dot(f0, vec3(50.0 * 0.33)), 0.0, 1.0);
+ float f90 = clamp(dot(f0, vec3(50.0 * 0.33)), metallic, 1.0);
vec3 F = f0 + (f90 - f0) * cLdotH5;
vec3 specular_brdf_NL = cNdotL * D * F * G;
diff --git a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp
index 71f4f3ad11..503a25184e 100644
--- a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp
@@ -445,7 +445,14 @@ void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface)
for (int i = 0; i < p_surface.bone_aabbs.size(); i++) {
const AABB &bone = p_surface.bone_aabbs[i];
if (bone.has_volume()) {
- mesh->bone_aabbs.write[i].merge_with(bone);
+ AABB &mesh_bone = mesh->bone_aabbs.write[i];
+ if (mesh_bone != AABB()) {
+ // Already initialized, merge AABBs.
+ mesh_bone.merge_with(bone);
+ } else {
+ // Not yet initialized, copy the bone AABB.
+ mesh_bone = bone;
+ }
}
}
mesh->aabb.merge_with(p_surface.aabb);
diff --git a/servers/rendering/renderer_rd/storage_rd/mesh_storage.h b/servers/rendering/renderer_rd/storage_rd/mesh_storage.h
index 4765475804..27c82213e4 100644
--- a/servers/rendering/renderer_rd/storage_rd/mesh_storage.h
+++ b/servers/rendering/renderer_rd/storage_rd/mesh_storage.h
@@ -665,7 +665,6 @@ public:
virtual void skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_skeleton = false) override;
virtual void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) override;
- void skeleton_set_world_transform(RID p_skeleton, bool p_enable, const Transform3D &p_world_transform);
virtual int skeleton_get_bone_count(RID p_skeleton) const override;
virtual void skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform3D &p_transform) override;
virtual Transform3D skeleton_bone_get_transform(RID p_skeleton, int p_bone) const override;
diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp b/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp
index 7dd790d1da..9b3d5a2d29 100644
--- a/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp
@@ -88,6 +88,7 @@ void RenderSceneDataRD::update_ubo(RID p_uniform_buffer, RS::ViewportDebugDraw p
RendererRD::MaterialStorage::store_soft_shadow_kernel(render_scene_render->directional_soft_shadow_kernel_get(), ubo.directional_soft_shadow_kernel);
RendererRD::MaterialStorage::store_soft_shadow_kernel(render_scene_render->penumbra_shadow_kernel_get(), ubo.penumbra_shadow_kernel);
RendererRD::MaterialStorage::store_soft_shadow_kernel(render_scene_render->soft_shadow_kernel_get(), ubo.soft_shadow_kernel);
+ ubo.camera_visible_layers = camera_visible_layers;
ubo.viewport_size[0] = p_screen_size.x;
ubo.viewport_size[1] = p_screen_size.y;
diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h b/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h
index 9c031acc1e..5ea4991e8e 100644
--- a/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h
+++ b/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h
@@ -45,6 +45,7 @@ public:
Transform3D cam_transform;
Projection cam_projection;
Vector2 taa_jitter;
+ uint32_t camera_visible_layers;
bool cam_orthogonal = false;
// For stereo rendering
@@ -142,7 +143,7 @@ private:
float IBL_exposure_normalization; // Adjusts for baked exposure.
uint32_t pancake_shadows;
- uint32_t pad1;
+ uint32_t camera_visible_layers;
uint32_t pad2;
uint32_t pad3;
};
diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp
index 4ee355ee9f..cfc25fc577 100644
--- a/servers/rendering/renderer_scene_cull.cpp
+++ b/servers/rendering/renderer_scene_cull.cpp
@@ -2512,7 +2512,7 @@ void RendererSceneCull::render_camera(const Ref<RenderSceneBuffers> &p_render_bu
} break;
}
- camera_data.set_camera(transform, projection, is_orthogonal, vaspect, jitter);
+ camera_data.set_camera(transform, projection, is_orthogonal, vaspect, jitter, camera->visible_layers);
} else {
// Setup our camera for our XR interface.
// We can support multiple views here each with their own camera
@@ -2520,7 +2520,7 @@ void RendererSceneCull::render_camera(const Ref<RenderSceneBuffers> &p_render_bu
Projection projections[RendererSceneRender::MAX_RENDER_VIEWS];
uint32_t view_count = p_xr_interface->get_view_count();
- ERR_FAIL_COND_MSG(view_count > RendererSceneRender::MAX_RENDER_VIEWS, "Requested view count is not supported");
+ ERR_FAIL_COND_MSG(view_count == 0 || view_count > RendererSceneRender::MAX_RENDER_VIEWS, "Requested view count is not supported");
float aspect = p_viewport_size.width / (float)p_viewport_size.height;
@@ -2534,7 +2534,7 @@ void RendererSceneCull::render_camera(const Ref<RenderSceneBuffers> &p_render_bu
}
if (view_count == 1) {
- camera_data.set_camera(transforms[0], projections[0], false, camera->vaspect, jitter);
+ camera_data.set_camera(transforms[0], projections[0], false, camera->vaspect, jitter, camera->visible_layers);
} else if (view_count == 2) {
camera_data.set_multiview_camera(view_count, transforms, projections, false, camera->vaspect);
} else {
diff --git a/servers/rendering/renderer_scene_render.cpp b/servers/rendering/renderer_scene_render.cpp
index f085168df3..3c069f6e2e 100644
--- a/servers/rendering/renderer_scene_render.cpp
+++ b/servers/rendering/renderer_scene_render.cpp
@@ -33,7 +33,7 @@
/////////////////////////////////////////////////////////////////////////////
// CameraData
-void RendererSceneRender::CameraData::set_camera(const Transform3D p_transform, const Projection p_projection, bool p_is_orthogonal, bool p_vaspect, const Vector2 &p_taa_jitter) {
+void RendererSceneRender::CameraData::set_camera(const Transform3D p_transform, const Projection p_projection, bool p_is_orthogonal, bool p_vaspect, const Vector2 &p_taa_jitter, const uint32_t p_visible_layers) {
view_count = 1;
is_orthogonal = p_is_orthogonal;
vaspect = p_vaspect;
@@ -41,6 +41,7 @@ void RendererSceneRender::CameraData::set_camera(const Transform3D p_transform,
main_transform = p_transform;
main_projection = p_projection;
+ visible_layers = p_visible_layers;
view_offset[0] = Transform3D();
view_projection[0] = p_projection;
taa_jitter = p_taa_jitter;
@@ -49,6 +50,7 @@ void RendererSceneRender::CameraData::set_camera(const Transform3D p_transform,
void RendererSceneRender::CameraData::set_multiview_camera(uint32_t p_view_count, const Transform3D *p_transforms, const Projection *p_projections, bool p_is_orthogonal, bool p_vaspect) {
ERR_FAIL_COND_MSG(p_view_count != 2, "Incorrect view count for stereoscopic view");
+ visible_layers = 0xFFFFFFFF;
view_count = p_view_count;
is_orthogonal = p_is_orthogonal;
vaspect = p_vaspect;
diff --git a/servers/rendering/renderer_scene_render.h b/servers/rendering/renderer_scene_render.h
index a8df897077..2c2d5a5a9e 100644
--- a/servers/rendering/renderer_scene_render.h
+++ b/servers/rendering/renderer_scene_render.h
@@ -268,6 +268,7 @@ public:
// flags
uint32_t view_count;
bool is_orthogonal;
+ uint32_t visible_layers;
bool vaspect;
// Main/center projection
@@ -278,7 +279,7 @@ public:
Projection view_projection[RendererSceneRender::MAX_RENDER_VIEWS];
Vector2 taa_jitter;
- void set_camera(const Transform3D p_transform, const Projection p_projection, bool p_is_orthogonal, bool p_vaspect, const Vector2 &p_taa_jitter = Vector2());
+ void set_camera(const Transform3D p_transform, const Projection p_projection, bool p_is_orthogonal, bool p_vaspect, const Vector2 &p_taa_jitter = Vector2(), uint32_t p_visible_layers = 0xFFFFFFFF);
void set_multiview_camera(uint32_t p_view_count, const Transform3D *p_transforms, const Projection *p_projections, bool p_is_orthogonal, bool p_vaspect);
};
diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp
index c09b185137..23070fb7c0 100644
--- a/servers/rendering/rendering_device.cpp
+++ b/servers/rendering/rendering_device.cpp
@@ -759,16 +759,16 @@ void RenderingDevice::_bind_methods() {
BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_64);
BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_MAX);
- BIND_ENUM_CONSTANT(TEXTURE_USAGE_SAMPLING_BIT);
- BIND_ENUM_CONSTANT(TEXTURE_USAGE_COLOR_ATTACHMENT_BIT);
- BIND_ENUM_CONSTANT(TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
- BIND_ENUM_CONSTANT(TEXTURE_USAGE_STORAGE_BIT);
- BIND_ENUM_CONSTANT(TEXTURE_USAGE_STORAGE_ATOMIC_BIT);
- BIND_ENUM_CONSTANT(TEXTURE_USAGE_CPU_READ_BIT);
- BIND_ENUM_CONSTANT(TEXTURE_USAGE_CAN_UPDATE_BIT);
- BIND_ENUM_CONSTANT(TEXTURE_USAGE_CAN_COPY_FROM_BIT);
- BIND_ENUM_CONSTANT(TEXTURE_USAGE_CAN_COPY_TO_BIT);
- BIND_ENUM_CONSTANT(TEXTURE_USAGE_INPUT_ATTACHMENT_BIT);
+ BIND_BITFIELD_FLAG(TEXTURE_USAGE_SAMPLING_BIT);
+ BIND_BITFIELD_FLAG(TEXTURE_USAGE_COLOR_ATTACHMENT_BIT);
+ BIND_BITFIELD_FLAG(TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
+ BIND_BITFIELD_FLAG(TEXTURE_USAGE_STORAGE_BIT);
+ BIND_BITFIELD_FLAG(TEXTURE_USAGE_STORAGE_ATOMIC_BIT);
+ BIND_BITFIELD_FLAG(TEXTURE_USAGE_CPU_READ_BIT);
+ BIND_BITFIELD_FLAG(TEXTURE_USAGE_CAN_UPDATE_BIT);
+ BIND_BITFIELD_FLAG(TEXTURE_USAGE_CAN_COPY_FROM_BIT);
+ BIND_BITFIELD_FLAG(TEXTURE_USAGE_CAN_COPY_TO_BIT);
+ BIND_BITFIELD_FLAG(TEXTURE_USAGE_INPUT_ATTACHMENT_BIT);
BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_IDENTITY);
BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_ZERO);
diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h
index abdd07844a..0b43b73042 100644
--- a/servers/rendering/rendering_device.h
+++ b/servers/rendering/rendering_device.h
@@ -535,7 +535,7 @@ public:
virtual Error texture_update(RID p_texture, uint32_t p_layer, const Vector<uint8_t> &p_data, BitField<BarrierMask> p_post_barrier = BARRIER_MASK_ALL_BARRIERS) = 0;
virtual Vector<uint8_t> texture_get_data(RID p_texture, uint32_t p_layer) = 0; // CPU textures will return immediately, while GPU textures will most likely force a flush
- virtual bool texture_is_format_supported_for_usage(DataFormat p_format, uint32_t p_usage) const = 0;
+ virtual bool texture_is_format_supported_for_usage(DataFormat p_format, BitField<RenderingDevice::TextureUsageBits> p_usage) const = 0;
virtual bool texture_is_shared(RID p_texture) = 0;
virtual bool texture_is_valid(RID p_texture) = 0;
virtual Size2i texture_size(RID p_texture) = 0;
@@ -1340,7 +1340,7 @@ VARIANT_ENUM_CAST(RenderingDevice::DataFormat)
VARIANT_BITFIELD_CAST(RenderingDevice::BarrierMask);
VARIANT_ENUM_CAST(RenderingDevice::TextureType)
VARIANT_ENUM_CAST(RenderingDevice::TextureSamples)
-VARIANT_ENUM_CAST(RenderingDevice::TextureUsageBits)
+VARIANT_BITFIELD_CAST(RenderingDevice::TextureUsageBits)
VARIANT_ENUM_CAST(RenderingDevice::TextureSwizzle)
VARIANT_ENUM_CAST(RenderingDevice::TextureSliceType)
VARIANT_ENUM_CAST(RenderingDevice::SamplerFilter)
diff --git a/servers/rendering/rendering_device_binds.h b/servers/rendering/rendering_device_binds.h
index c710bd0a10..dbff305794 100644
--- a/servers/rendering/rendering_device_binds.h
+++ b/servers/rendering/rendering_device_binds.h
@@ -66,7 +66,7 @@ public:
RD_SETGET(uint32_t, mipmaps)
RD_SETGET(RD::TextureType, texture_type)
RD_SETGET(RD::TextureSamples, samples)
- RD_SETGET(uint32_t, usage_bits)
+ RD_SETGET(BitField<RenderingDevice::TextureUsageBits>, usage_bits)
void add_shareable_format(RD::DataFormat p_format) { base.shareable_formats.push_back(p_format); }
void remove_shareable_format(RD::DataFormat p_format) { base.shareable_formats.erase(p_format); }
diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp
index 92b8d7350e..e451fb35c2 100644
--- a/servers/rendering/shader_language.cpp
+++ b/servers/rendering/shader_language.cpp
@@ -4111,7 +4111,7 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform
if (p_uniform.array_size > 0) {
pi.type = Variant::ARRAY;
pi.hint = PROPERTY_HINT_ARRAY_TYPE;
- pi.hint_string = vformat("%s/%s:%s", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "Texture2D");
+ pi.hint_string = MAKE_RESOURCE_TYPE_HINT("Texture2D");
} else {
pi.type = Variant::OBJECT;
pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
@@ -4126,7 +4126,7 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform
if (p_uniform.array_size > 0) {
pi.type = Variant::ARRAY;
pi.hint = PROPERTY_HINT_ARRAY_TYPE;
- pi.hint_string = vformat("%s/%s:%s", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "TextureLayered");
+ pi.hint_string = MAKE_RESOURCE_TYPE_HINT("TextureLayered");
} else {
pi.type = Variant::OBJECT;
pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
@@ -4139,7 +4139,7 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform
if (p_uniform.array_size > 0) {
pi.type = Variant::ARRAY;
pi.hint = PROPERTY_HINT_ARRAY_TYPE;
- pi.hint_string = vformat("%s/%s:%s", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "Texture3D");
+ pi.hint_string = MAKE_RESOURCE_TYPE_HINT("Texture3D");
} else {
pi.type = Variant::OBJECT;
pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
diff --git a/servers/rendering/shader_types.cpp b/servers/rendering/shader_types.cpp
index 5e1da7c15d..86dd6a8b7e 100644
--- a/servers/rendering/shader_types.cpp
+++ b/servers/rendering/shader_types.cpp
@@ -100,6 +100,7 @@ ShaderTypes::ShaderTypes() {
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["NODE_POSITION_WORLD"] = ShaderLanguage::TYPE_VEC3;
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["CAMERA_POSITION_WORLD"] = ShaderLanguage::TYPE_VEC3;
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["CAMERA_DIRECTION_WORLD"] = ShaderLanguage::TYPE_VEC3;
+ shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["CAMERA_VISIBLE_LAYERS"] = ShaderLanguage::TYPE_UINT;
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["NODE_POSITION_VIEW"] = ShaderLanguage::TYPE_VEC3;
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["VIEW_INDEX"] = constt(ShaderLanguage::TYPE_INT);
@@ -147,6 +148,7 @@ ShaderTypes::ShaderTypes() {
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["NODE_POSITION_WORLD"] = ShaderLanguage::TYPE_VEC3;
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["CAMERA_POSITION_WORLD"] = ShaderLanguage::TYPE_VEC3;
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["CAMERA_DIRECTION_WORLD"] = ShaderLanguage::TYPE_VEC3;
+ shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["CAMERA_VISIBLE_LAYERS"] = ShaderLanguage::TYPE_UINT;
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["NODE_POSITION_VIEW"] = ShaderLanguage::TYPE_VEC3;
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["VIEW_INDEX"] = constt(ShaderLanguage::TYPE_INT);