You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-12 13:20:55 +00:00
Implement Physical Light Units as an optional setting.
This allows light sources to be specified in physical light units in addition to the regular energy multiplier. In order to avoid loss of precision at high values, brightness values are premultiplied by an exposure normalization value. In support of Physical Light Units this PR also renames CameraEffects to CameraAttributes.
This commit is contained in:
@@ -292,7 +292,7 @@ static _FORCE_INLINE_ void store_transform_3x3(const Basis &p_basis, float *p_ar
|
||||
p_array[11] = 0;
|
||||
}
|
||||
|
||||
void SkyRD::_render_sky(RD::DrawListID p_list, float p_time, RID p_fb, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, uint32_t p_view_count, const Projection *p_projections, const Basis &p_orientation, float p_multiplier, const Vector3 &p_position, float p_luminance_multiplier) {
|
||||
void SkyRD::_render_sky(RD::DrawListID p_list, float p_time, RID p_fb, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, uint32_t p_view_count, const Projection *p_projections, const Basis &p_orientation, const Vector3 &p_position, float p_luminance_multiplier) {
|
||||
SkyPushConstant sky_push_constant;
|
||||
|
||||
memset(&sky_push_constant, 0, sizeof(SkyPushConstant));
|
||||
@@ -307,7 +307,6 @@ void SkyRD::_render_sky(RD::DrawListID p_list, float p_time, RID p_fb, PipelineC
|
||||
sky_push_constant.position[0] = p_position.x;
|
||||
sky_push_constant.position[1] = p_position.y;
|
||||
sky_push_constant.position[2] = p_position.z;
|
||||
sky_push_constant.multiplier = p_multiplier;
|
||||
sky_push_constant.time = p_time;
|
||||
sky_push_constant.luminance_multiplier = p_luminance_multiplier;
|
||||
store_transform_3x3(p_orientation, sky_push_constant.orientation);
|
||||
@@ -762,7 +761,7 @@ Ref<Image> SkyRD::Sky::bake_panorama(float p_energy, int p_roughness_layers, con
|
||||
RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton();
|
||||
|
||||
RD::TextureFormat tf;
|
||||
tf.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
|
||||
tf.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT; // Could be RGBA16
|
||||
tf.width = p_size.width;
|
||||
tf.height = p_size.height;
|
||||
tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
|
||||
@@ -868,7 +867,7 @@ void SkyRD::init() {
|
||||
actions.renames["COLOR"] = "color";
|
||||
actions.renames["ALPHA"] = "alpha";
|
||||
actions.renames["EYEDIR"] = "cube_normal";
|
||||
actions.renames["POSITION"] = "params.position_multiplier.xyz";
|
||||
actions.renames["POSITION"] = "params.position";
|
||||
actions.renames["SKY_COORDS"] = "panorama_coords";
|
||||
actions.renames["SCREEN_UV"] = "uv";
|
||||
actions.renames["FRAGCOORD"] = "gl_FragCoord";
|
||||
@@ -1110,7 +1109,7 @@ SkyRD::~SkyRD() {
|
||||
RD::get_singleton()->free(index_buffer); //array gets freed as dependency
|
||||
}
|
||||
|
||||
void SkyRD::setup(RID p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const Projection &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render) {
|
||||
void SkyRD::setup(RID p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, RID p_camera_attributes, const Projection &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render) {
|
||||
RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();
|
||||
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
|
||||
ERR_FAIL_COND(p_env.is_null());
|
||||
@@ -1220,6 +1219,14 @@ void SkyRD::setup(RID p_env, RID p_render_buffers, const PagedArray<RID> &p_ligh
|
||||
float sign = light_storage->light_is_negative(base) ? -1 : 1;
|
||||
sky_light_data.energy = sign * light_storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY);
|
||||
|
||||
if (p_scene_render->is_using_physical_light_units()) {
|
||||
sky_light_data.energy *= light_storage->light_get_param(base, RS::LIGHT_PARAM_INTENSITY);
|
||||
}
|
||||
|
||||
if (p_camera_attributes.is_valid()) {
|
||||
sky_light_data.energy *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_camera_attributes);
|
||||
}
|
||||
|
||||
Color linear_col = light_storage->light_get_color(base).srgb_to_linear();
|
||||
sky_light_data.color[0] = linear_col.r;
|
||||
sky_light_data.color[1] = linear_col.g;
|
||||
@@ -1351,8 +1358,6 @@ void SkyRD::update(RID p_env, const Projection &p_projection, const Transform3D
|
||||
|
||||
ERR_FAIL_COND(!shader_data);
|
||||
|
||||
float multiplier = RendererSceneRenderRD::get_singleton()->environment_get_bg_energy(p_env);
|
||||
|
||||
bool update_single_frame = sky->mode == RS::SKY_MODE_REALTIME || sky->mode == RS::SKY_MODE_QUALITY;
|
||||
RS::SkyMode sky_mode = sky->mode;
|
||||
|
||||
@@ -1415,7 +1420,7 @@ void SkyRD::update(RID p_env, const Projection &p_projection, const Transform3D
|
||||
RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES, sky_shader.default_shader_rd);
|
||||
|
||||
cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[2].framebuffers[i], RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
|
||||
_render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[2].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, 1, &cm, local_view, multiplier, p_transform.origin, p_luminance_multiplier);
|
||||
_render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[2].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, 1, &cm, local_view, p_transform.origin, p_luminance_multiplier);
|
||||
RD::get_singleton()->draw_list_end();
|
||||
}
|
||||
RD::get_singleton()->draw_command_end_label();
|
||||
@@ -1434,7 +1439,7 @@ void SkyRD::update(RID p_env, const Projection &p_projection, const Transform3D
|
||||
RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_CUBEMAP_HALF_RES, sky_shader.default_shader_rd);
|
||||
|
||||
cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[1].framebuffers[i], RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
|
||||
_render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[1].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, 1, &cm, local_view, multiplier, p_transform.origin, p_luminance_multiplier);
|
||||
_render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[1].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, 1, &cm, local_view, p_transform.origin, p_luminance_multiplier);
|
||||
RD::get_singleton()->draw_list_end();
|
||||
}
|
||||
RD::get_singleton()->draw_command_end_label();
|
||||
@@ -1449,7 +1454,7 @@ void SkyRD::update(RID p_env, const Projection &p_projection, const Transform3D
|
||||
RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_CUBEMAP, sky_shader.default_shader_rd);
|
||||
|
||||
cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[0].framebuffers[i], RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
|
||||
_render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[0].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, 1, &cm, local_view, multiplier, p_transform.origin, p_luminance_multiplier);
|
||||
_render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[0].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, 1, &cm, local_view, p_transform.origin, p_luminance_multiplier);
|
||||
RD::get_singleton()->draw_list_end();
|
||||
}
|
||||
RD::get_singleton()->draw_command_end_label();
|
||||
@@ -1475,7 +1480,7 @@ void SkyRD::update(RID p_env, const Projection &p_projection, const Transform3D
|
||||
}
|
||||
sky->processing_layer = 1;
|
||||
}
|
||||
|
||||
sky->baked_exposure = p_luminance_multiplier;
|
||||
sky->reflection.dirty = false;
|
||||
|
||||
} else {
|
||||
@@ -1491,7 +1496,7 @@ void SkyRD::update(RID p_env, const Projection &p_projection, const Transform3D
|
||||
}
|
||||
}
|
||||
|
||||
void SkyRD::draw(RID p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time) {
|
||||
void SkyRD::draw(RID p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) {
|
||||
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
|
||||
ERR_FAIL_COND(p_env.is_null());
|
||||
|
||||
@@ -1536,7 +1541,6 @@ void SkyRD::draw(RID p_env, bool p_can_continue_color, bool p_can_continue_depth
|
||||
Basis sky_transform = RendererSceneRenderRD::get_singleton()->environment_get_sky_orientation(p_env);
|
||||
sky_transform.invert();
|
||||
|
||||
float multiplier = RendererSceneRenderRD::get_singleton()->environment_get_bg_energy(p_env);
|
||||
float custom_fov = RendererSceneRenderRD::get_singleton()->environment_get_sky_custom_fov(p_env);
|
||||
|
||||
// Camera
|
||||
@@ -1567,7 +1571,7 @@ void SkyRD::draw(RID p_env, bool p_can_continue_color, bool p_can_continue_depth
|
||||
clear_colors.push_back(Color(0.0, 0.0, 0.0));
|
||||
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(sky->quarter_res_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors);
|
||||
_render_sky(draw_list, p_time, sky->quarter_res_framebuffer, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, multiplier, p_transform.origin, 1.0);
|
||||
_render_sky(draw_list, p_time, sky->quarter_res_framebuffer, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, p_transform.origin, p_luminance_multiplier);
|
||||
RD::get_singleton()->draw_list_end();
|
||||
}
|
||||
|
||||
@@ -1580,7 +1584,7 @@ void SkyRD::draw(RID p_env, bool p_can_continue_color, bool p_can_continue_depth
|
||||
clear_colors.push_back(Color(0.0, 0.0, 0.0));
|
||||
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(sky->half_res_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors);
|
||||
_render_sky(draw_list, p_time, sky->half_res_framebuffer, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, multiplier, p_transform.origin, 1.0);
|
||||
_render_sky(draw_list, p_time, sky->half_res_framebuffer, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, p_transform.origin, p_luminance_multiplier);
|
||||
RD::get_singleton()->draw_list_end();
|
||||
}
|
||||
|
||||
@@ -1594,7 +1598,7 @@ void SkyRD::draw(RID p_env, bool p_can_continue_color, bool p_can_continue_depth
|
||||
}
|
||||
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_fb, RD::INITIAL_ACTION_CONTINUE, p_can_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, p_can_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ);
|
||||
_render_sky(draw_list, p_time, p_fb, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, multiplier, p_transform.origin, 1.0);
|
||||
_render_sky(draw_list, p_time, p_fb, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, p_transform.origin, p_luminance_multiplier);
|
||||
RD::get_singleton()->draw_list_end();
|
||||
}
|
||||
|
||||
@@ -1634,7 +1638,6 @@ void SkyRD::update_res_buffers(RID p_env, uint32_t p_view_count, const Projectio
|
||||
Basis sky_transform = RendererSceneRenderRD::get_singleton()->environment_get_sky_orientation(p_env);
|
||||
sky_transform.invert();
|
||||
|
||||
float multiplier = RendererSceneRenderRD::get_singleton()->environment_get_bg_energy(p_env);
|
||||
float custom_fov = RendererSceneRenderRD::get_singleton()->environment_get_sky_custom_fov(p_env);
|
||||
|
||||
// Camera
|
||||
@@ -1665,7 +1668,7 @@ void SkyRD::update_res_buffers(RID p_env, uint32_t p_view_count, const Projectio
|
||||
clear_colors.push_back(Color(0.0, 0.0, 0.0));
|
||||
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(sky->quarter_res_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors);
|
||||
_render_sky(draw_list, p_time, sky->quarter_res_framebuffer, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, multiplier, p_transform.origin, p_luminance_multiplier);
|
||||
_render_sky(draw_list, p_time, sky->quarter_res_framebuffer, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, p_transform.origin, p_luminance_multiplier);
|
||||
RD::get_singleton()->draw_list_end();
|
||||
}
|
||||
|
||||
@@ -1678,7 +1681,7 @@ void SkyRD::update_res_buffers(RID p_env, uint32_t p_view_count, const Projectio
|
||||
clear_colors.push_back(Color(0.0, 0.0, 0.0));
|
||||
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(sky->half_res_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors);
|
||||
_render_sky(draw_list, p_time, sky->half_res_framebuffer, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, multiplier, p_transform.origin, p_luminance_multiplier);
|
||||
_render_sky(draw_list, p_time, sky->half_res_framebuffer, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, p_transform.origin, p_luminance_multiplier);
|
||||
RD::get_singleton()->draw_list_end();
|
||||
}
|
||||
}
|
||||
@@ -1728,7 +1731,6 @@ void SkyRD::draw(RD::DrawListID p_draw_list, RID p_env, RID p_fb, uint32_t p_vie
|
||||
Basis sky_transform = RendererSceneRenderRD::get_singleton()->environment_get_sky_orientation(p_env);
|
||||
sky_transform.invert();
|
||||
|
||||
float multiplier = RendererSceneRenderRD::get_singleton()->environment_get_bg_energy(p_env);
|
||||
float custom_fov = RendererSceneRenderRD::get_singleton()->environment_get_sky_custom_fov(p_env);
|
||||
|
||||
// Camera
|
||||
@@ -1759,7 +1761,7 @@ void SkyRD::draw(RD::DrawListID p_draw_list, RID p_env, RID p_fb, uint32_t p_vie
|
||||
texture_uniform_set = sky_scene_state.fog_only_texture_uniform_set;
|
||||
}
|
||||
|
||||
_render_sky(p_draw_list, p_time, p_fb, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, multiplier, p_transform.origin, p_luminance_multiplier);
|
||||
_render_sky(p_draw_list, p_time, p_fb, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, p_transform.origin, p_luminance_multiplier);
|
||||
}
|
||||
|
||||
void SkyRD::invalidate_sky(Sky *p_sky) {
|
||||
@@ -1881,6 +1883,13 @@ RID SkyRD::sky_get_material(RID p_sky) const {
|
||||
return sky->material;
|
||||
}
|
||||
|
||||
float SkyRD::sky_get_baked_exposure(RID p_sky) const {
|
||||
Sky *sky = get_sky(p_sky);
|
||||
ERR_FAIL_COND_V(!sky, 1.0);
|
||||
|
||||
return sky->baked_exposure;
|
||||
}
|
||||
|
||||
RID SkyRD::allocate_sky_rid() {
|
||||
return sky_owner.allocate_rid();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user