Update Sky lights in sky setup function
This commit is contained in:
parent
81c28dd706
commit
430d5d64aa
|
@ -1386,7 +1386,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
|
||||||
projection = correction * p_render_data->cam_projection;
|
projection = correction * p_render_data->cam_projection;
|
||||||
}
|
}
|
||||||
|
|
||||||
sky.setup(env, p_render_data->render_buffers, projection, p_render_data->cam_transform, screen_size, this);
|
sky.setup(env, p_render_data->render_buffers, *p_render_data->lights, projection, p_render_data->cam_transform, screen_size, this);
|
||||||
|
|
||||||
RID sky_rid = env->sky;
|
RID sky_rid = env->sky;
|
||||||
if (sky_rid.is_valid()) {
|
if (sky_rid.is_valid()) {
|
||||||
|
|
|
@ -633,7 +633,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
|
||||||
projection = correction * p_render_data->cam_projection;
|
projection = correction * p_render_data->cam_projection;
|
||||||
}
|
}
|
||||||
|
|
||||||
sky.setup(env, p_render_data->render_buffers, projection, p_render_data->cam_transform, screen_size, this);
|
sky.setup(env, p_render_data->render_buffers, *p_render_data->lights, projection, p_render_data->cam_transform, screen_size, this);
|
||||||
|
|
||||||
RID sky_rid = env->sky;
|
RID sky_rid = env->sky;
|
||||||
if (sky_rid.is_valid()) {
|
if (sky_rid.is_valid()) {
|
||||||
|
|
|
@ -3244,7 +3244,6 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
|
||||||
|
|
||||||
r_directional_light_count = 0;
|
r_directional_light_count = 0;
|
||||||
r_positional_light_count = 0;
|
r_positional_light_count = 0;
|
||||||
sky.sky_scene_state.ubo.directional_light_count = 0;
|
|
||||||
|
|
||||||
Plane camera_plane(-p_camera_transform.basis.get_axis(Vector3::AXIS_Z).normalized(), p_camera_transform.origin);
|
Plane camera_plane(-p_camera_transform.basis.get_axis(Vector3::AXIS_Z).normalized(), p_camera_transform.origin);
|
||||||
|
|
||||||
|
@ -3265,43 +3264,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
|
||||||
RS::LightType type = storage->light_get_type(base);
|
RS::LightType type = storage->light_get_type(base);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case RS::LIGHT_DIRECTIONAL: {
|
case RS::LIGHT_DIRECTIONAL: {
|
||||||
// Copy to SkyDirectionalLightData
|
if (r_directional_light_count >= cluster.max_directional_lights) {
|
||||||
if (r_directional_light_count < sky.sky_scene_state.max_directional_lights) {
|
|
||||||
RendererSceneSkyRD::SkyDirectionalLightData &sky_light_data = sky.sky_scene_state.directional_lights[r_directional_light_count];
|
|
||||||
Transform3D light_transform = li->transform;
|
|
||||||
Vector3 world_direction = light_transform.basis.xform(Vector3(0, 0, 1)).normalized();
|
|
||||||
|
|
||||||
sky_light_data.direction[0] = world_direction.x;
|
|
||||||
sky_light_data.direction[1] = world_direction.y;
|
|
||||||
sky_light_data.direction[2] = -world_direction.z;
|
|
||||||
|
|
||||||
float sign = storage->light_is_negative(base) ? -1 : 1;
|
|
||||||
sky_light_data.energy = sign * storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY);
|
|
||||||
|
|
||||||
Color linear_col = storage->light_get_color(base).to_linear();
|
|
||||||
sky_light_data.color[0] = linear_col.r;
|
|
||||||
sky_light_data.color[1] = linear_col.g;
|
|
||||||
sky_light_data.color[2] = linear_col.b;
|
|
||||||
|
|
||||||
sky_light_data.enabled = true;
|
|
||||||
|
|
||||||
float angular_diameter = storage->light_get_param(base, RS::LIGHT_PARAM_SIZE);
|
|
||||||
if (angular_diameter > 0.0) {
|
|
||||||
// I know tan(0) is 0, but let's not risk it with numerical precision.
|
|
||||||
// technically this will keep expanding until reaching the sun, but all we care
|
|
||||||
// is expand until we reach the radius of the near plane (there can't be more occluders than that)
|
|
||||||
angular_diameter = Math::tan(Math::deg2rad(angular_diameter));
|
|
||||||
if (storage->light_has_shadow(base)) {
|
|
||||||
r_directional_light_soft_shadows = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
angular_diameter = 0.0;
|
|
||||||
}
|
|
||||||
sky_light_data.size = angular_diameter;
|
|
||||||
sky.sky_scene_state.ubo.directional_light_count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r_directional_light_count >= cluster.max_directional_lights || storage->light_directional_is_sky_only(base)) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3378,6 +3341,9 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
|
||||||
// technically this will keep expanding until reaching the sun, but all we care
|
// technically this will keep expanding until reaching the sun, but all we care
|
||||||
// is expand until we reach the radius of the near plane (there can't be more occluders than that)
|
// is expand until we reach the radius of the near plane (there can't be more occluders than that)
|
||||||
angular_diameter = Math::tan(Math::deg2rad(angular_diameter));
|
angular_diameter = Math::tan(Math::deg2rad(angular_diameter));
|
||||||
|
if (storage->light_has_shadow(base)) {
|
||||||
|
r_directional_light_soft_shadows = true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
angular_diameter = 0.0;
|
angular_diameter = 0.0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1039,8 +1039,8 @@ RendererSceneSkyRD::~RendererSceneSkyRD() {
|
||||||
RD::get_singleton()->free(index_buffer); //array gets freed as dependency
|
RD::get_singleton()->free(index_buffer); //array gets freed as dependency
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererSceneSkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_buffers, const CameraMatrix &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render) {
|
void RendererSceneSkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const CameraMatrix &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render) {
|
||||||
ERR_FAIL_COND(!p_env); // I guess without an environment we also can't have a sky...
|
ERR_FAIL_COND(!p_env);
|
||||||
|
|
||||||
SkyMaterialData *material = nullptr;
|
SkyMaterialData *material = nullptr;
|
||||||
Sky *sky = get_sky(p_env->sky);
|
Sky *sky = get_sky(p_env->sky);
|
||||||
|
@ -1121,15 +1121,67 @@ void RendererSceneSkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_b
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shader_data->uses_light) {
|
if (shader_data->uses_light) {
|
||||||
// Check whether the directional_light_buffer changes
|
sky_scene_state.ubo.directional_light_count = 0;
|
||||||
bool light_data_dirty = false;
|
// Run through the list of lights in the scene and pick out the Directional Lights.
|
||||||
|
// This can't be done in RenderSceneRenderRD::_setup lights because that needs to be called
|
||||||
|
// after the depth prepass, but this runs before the depth prepass
|
||||||
|
for (int i = 0; i < (int)p_lights.size(); i++) {
|
||||||
|
RendererSceneRenderRD::LightInstance *li = p_scene_render->light_instance_owner.get_or_null(p_lights[i]);
|
||||||
|
if (!li) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
RID base = li->light;
|
||||||
|
|
||||||
|
ERR_CONTINUE(base.is_null());
|
||||||
|
|
||||||
|
RS::LightType type = storage->light_get_type(base);
|
||||||
|
if (type == RS::LIGHT_DIRECTIONAL) {
|
||||||
|
SkyDirectionalLightData &sky_light_data = sky_scene_state.directional_lights[sky_scene_state.ubo.directional_light_count];
|
||||||
|
Transform3D light_transform = li->transform;
|
||||||
|
Vector3 world_direction = light_transform.basis.xform(Vector3(0, 0, 1)).normalized();
|
||||||
|
|
||||||
|
sky_light_data.direction[0] = world_direction.x;
|
||||||
|
sky_light_data.direction[1] = world_direction.y;
|
||||||
|
sky_light_data.direction[2] = -world_direction.z;
|
||||||
|
|
||||||
|
float sign = storage->light_is_negative(base) ? -1 : 1;
|
||||||
|
sky_light_data.energy = sign * storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY);
|
||||||
|
|
||||||
|
Color linear_col = storage->light_get_color(base).to_linear();
|
||||||
|
sky_light_data.color[0] = linear_col.r;
|
||||||
|
sky_light_data.color[1] = linear_col.g;
|
||||||
|
sky_light_data.color[2] = linear_col.b;
|
||||||
|
|
||||||
|
sky_light_data.enabled = true;
|
||||||
|
|
||||||
|
float angular_diameter = storage->light_get_param(base, RS::LIGHT_PARAM_SIZE);
|
||||||
|
if (angular_diameter > 0.0) {
|
||||||
|
// I know tan(0) is 0, but let's not risk it with numerical precision.
|
||||||
|
// technically this will keep expanding until reaching the sun, but all we care
|
||||||
|
// is expand until we reach the radius of the near plane (there can't be more occluders than that)
|
||||||
|
angular_diameter = Math::tan(Math::deg2rad(angular_diameter));
|
||||||
|
} else {
|
||||||
|
angular_diameter = 0.0;
|
||||||
|
}
|
||||||
|
sky_light_data.size = angular_diameter;
|
||||||
|
sky_scene_state.ubo.directional_light_count++;
|
||||||
|
if (sky_scene_state.ubo.directional_light_count >= sky_scene_state.max_directional_lights) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Check whether the directional_light_buffer changes
|
||||||
|
bool light_data_dirty = true;
|
||||||
|
|
||||||
|
// Light buffer is dirty if we have fewer or more lights
|
||||||
|
// If we have fewer lights, make sure that old lights are disabled
|
||||||
if (sky_scene_state.ubo.directional_light_count != sky_scene_state.last_frame_directional_light_count) {
|
if (sky_scene_state.ubo.directional_light_count != sky_scene_state.last_frame_directional_light_count) {
|
||||||
light_data_dirty = true;
|
light_data_dirty = true;
|
||||||
for (uint32_t i = sky_scene_state.ubo.directional_light_count; i < sky_scene_state.max_directional_lights; i++) {
|
for (uint32_t i = sky_scene_state.ubo.directional_light_count; i < sky_scene_state.max_directional_lights; i++) {
|
||||||
sky_scene_state.directional_lights[i].enabled = false;
|
sky_scene_state.directional_lights[i].enabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!light_data_dirty) {
|
if (!light_data_dirty) {
|
||||||
for (uint32_t i = 0; i < sky_scene_state.ubo.directional_light_count; i++) {
|
for (uint32_t i = 0; i < sky_scene_state.ubo.directional_light_count; i++) {
|
||||||
if (sky_scene_state.directional_lights[i].direction[0] != sky_scene_state.last_frame_directional_lights[i].direction[0] ||
|
if (sky_scene_state.directional_lights[i].direction[0] != sky_scene_state.last_frame_directional_lights[i].direction[0] ||
|
||||||
|
|
|
@ -292,7 +292,7 @@ public:
|
||||||
void set_texture_format(RD::DataFormat p_texture_format);
|
void set_texture_format(RD::DataFormat p_texture_format);
|
||||||
~RendererSceneSkyRD();
|
~RendererSceneSkyRD();
|
||||||
|
|
||||||
void setup(RendererSceneEnvironmentRD *p_env, RID p_render_buffers, const CameraMatrix &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render);
|
void setup(RendererSceneEnvironmentRD *p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const CameraMatrix &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render);
|
||||||
void update(RendererSceneEnvironmentRD *p_env, const CameraMatrix &p_projection, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0);
|
void update(RendererSceneEnvironmentRD *p_env, const CameraMatrix &p_projection, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0);
|
||||||
void draw(RendererSceneEnvironmentRD *p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, double p_time); // only called by clustered renderer
|
void draw(RendererSceneEnvironmentRD *p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, double p_time); // only called by clustered renderer
|
||||||
void update_res_buffers(RendererSceneEnvironmentRD *p_env, uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0);
|
void update_res_buffers(RendererSceneEnvironmentRD *p_env, uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0);
|
||||||
|
|
Loading…
Reference in New Issue