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:
clayjohn
2022-07-31 16:20:24 -07:00
parent 736632ee7e
commit 385ee5c70b
131 changed files with 2692 additions and 1283 deletions

View File

@@ -93,10 +93,10 @@ void RendererSceneCull::camera_set_environment(RID p_camera, RID p_env) {
camera->env = p_env;
}
void RendererSceneCull::camera_set_camera_effects(RID p_camera, RID p_fx) {
void RendererSceneCull::camera_set_camera_attributes(RID p_camera, RID p_attributes) {
Camera *camera = camera_owner.get_or_null(p_camera);
ERR_FAIL_COND(!camera);
camera->effects = p_fx;
camera->attributes = p_attributes;
}
void RendererSceneCull::camera_set_use_vertical_aspect(RID p_camera, bool p_enable) {
@@ -378,10 +378,10 @@ void RendererSceneCull::scenario_set_environment(RID p_scenario, RID p_environme
scenario->environment = p_environment;
}
void RendererSceneCull::scenario_set_camera_effects(RID p_scenario, RID p_camera_effects) {
void RendererSceneCull::scenario_set_camera_attributes(RID p_scenario, RID p_camera_attributes) {
Scenario *scenario = scenario_owner.get_or_null(p_scenario);
ERR_FAIL_COND(!scenario);
scenario->camera_effects = p_camera_effects;
scenario->camera_attributes = p_camera_attributes;
}
void RendererSceneCull::scenario_set_fallback_environment(RID p_scenario, RID p_environment) {
@@ -2537,7 +2537,7 @@ void RendererSceneCull::render_camera(RID p_render_buffers, RID p_camera, RID p_
// For now just cull on the first camera
RendererSceneOcclusionCull::get_singleton()->buffer_update(p_viewport, camera_data.main_transform, camera_data.main_projection, camera_data.is_orthogonal);
_render_scene(&camera_data, p_render_buffers, environment, camera->effects, camera->visible_layers, p_scenario, p_viewport, p_shadow_atlas, RID(), -1, p_screen_mesh_lod_threshold, true, r_render_info);
_render_scene(&camera_data, p_render_buffers, environment, camera->attributes, camera->visible_layers, p_scenario, p_viewport, p_shadow_atlas, RID(), -1, p_screen_mesh_lod_threshold, true, r_render_info);
#endif
}
@@ -2910,7 +2910,7 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul
}
}
void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_camera_data, RID p_render_buffers, RID p_environment, RID p_force_camera_effects, uint32_t p_visible_layers, RID p_scenario, RID p_viewport, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, bool p_using_shadows, RendererScene::RenderInfo *r_render_info) {
void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_camera_data, RID p_render_buffers, RID p_environment, RID p_force_camera_attributes, uint32_t p_visible_layers, RID p_scenario, RID p_viewport, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, bool p_using_shadows, RendererScene::RenderInfo *r_render_info) {
Instance *render_reflection_probe = instance_owner.get_or_null(p_reflection_probe); //if null, not rendering to it
Scenario *scenario = scenario_owner.get_or_null(p_scenario);
@@ -3240,11 +3240,11 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c
scene_cull_result.light_instances.push_back(directional_lights[i]);
}
RID camera_effects;
if (p_force_camera_effects.is_valid()) {
camera_effects = p_force_camera_effects;
RID camera_attributes;
if (p_force_camera_attributes.is_valid()) {
camera_attributes = p_force_camera_attributes;
} else {
camera_effects = scenario->camera_effects;
camera_attributes = scenario->camera_attributes;
}
/* PROCESS GEOMETRY AND DRAW SCENE */
@@ -3256,7 +3256,7 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c
}
RENDER_TIMESTAMP("Render 3D Scene");
scene_render->render_scene(p_render_buffers, p_camera_data, prev_camera_data, scene_cull_result.geometry_instances, scene_cull_result.light_instances, scene_cull_result.reflections, scene_cull_result.voxel_gi_instances, scene_cull_result.decals, scene_cull_result.lightmaps, scene_cull_result.fog_volumes, p_environment, camera_effects, p_shadow_atlas, occluders_tex, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass, p_screen_mesh_lod_threshold, render_shadow_data, max_shadows_used, render_sdfgi_data, cull.sdfgi.region_count, &sdfgi_update_data, r_render_info);
scene_render->render_scene(p_render_buffers, p_camera_data, prev_camera_data, scene_cull_result.geometry_instances, scene_cull_result.light_instances, scene_cull_result.reflections, scene_cull_result.voxel_gi_instances, scene_cull_result.decals, scene_cull_result.lightmaps, scene_cull_result.fog_volumes, p_environment, camera_attributes, p_shadow_atlas, occluders_tex, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass, p_screen_mesh_lod_threshold, render_shadow_data, max_shadows_used, render_sdfgi_data, cull.sdfgi.region_count, &sdfgi_update_data, r_render_info);
if (p_viewport.is_valid()) {
RSG::viewport->viewport_set_prev_camera_data(p_viewport, p_camera_data);
@@ -3271,7 +3271,7 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c
render_sdfgi_data[i].instances.clear();
}
// virtual void render_scene(RID p_render_buffers, const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold,const RenderShadowData *p_render_shadows,int p_render_shadow_count,const RenderSDFGIData *p_render_sdfgi_regions,int p_render_sdfgi_region_count,const RenderSDFGIStaticLightData *p_render_sdfgi_static_lights=nullptr) = 0;
// virtual void render_scene(RID p_render_buffers, const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_attributes, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold,const RenderShadowData *p_render_shadows,int p_render_shadow_count,const RenderSDFGIData *p_render_sdfgi_regions,int p_render_sdfgi_region_count,const RenderSDFGIStaticLightData *p_render_sdfgi_static_lights=nullptr) = 0;
}
RID RendererSceneCull::_render_get_environment(RID p_camera, RID p_scenario) {
@@ -3479,6 +3479,7 @@ void RendererSceneCull::render_probes() {
cache->transform != instance->transform ||
cache->color != RSG::light_storage->light_get_color(instance->base) ||
cache->energy != RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_ENERGY) ||
cache->intensity != RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_INTENSITY) ||
cache->bake_energy != RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_INDIRECT_ENERGY) ||
cache->radius != RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_RANGE) ||
cache->attenuation != RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_ATTENUATION) ||
@@ -3510,6 +3511,7 @@ void RendererSceneCull::render_probes() {
cache->transform != instance->transform ||
cache->color != RSG::light_storage->light_get_color(instance->base) ||
cache->energy != RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_ENERGY) ||
cache->intensity != RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_INTENSITY) ||
cache->bake_energy != RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_INDIRECT_ENERGY) ||
cache->radius != RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_RANGE) ||
cache->attenuation != RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_ATTENUATION) ||
@@ -3556,6 +3558,7 @@ void RendererSceneCull::render_probes() {
cache->transform = instance->transform;
cache->color = RSG::light_storage->light_get_color(instance->base);
cache->energy = RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_ENERGY);
cache->intensity = RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_INTENSITY);
cache->bake_energy = RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_INDIRECT_ENERGY);
cache->radius = RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_RANGE);
cache->attenuation = RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_ATTENUATION);
@@ -3578,6 +3581,7 @@ void RendererSceneCull::render_probes() {
cache->transform = instance->transform;
cache->color = RSG::light_storage->light_get_color(instance->base);
cache->energy = RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_ENERGY);
cache->intensity = RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_INTENSITY);
cache->bake_energy = RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_INDIRECT_ENERGY);
cache->radius = RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_RANGE);
cache->attenuation = RSG::light_storage->light_get_param(instance->base, RS::LIGHT_PARAM_ATTENUATION);