Fix shadows for billboarded Sprite3D's
This commit is contained in:
parent
9272f7b53d
commit
eab95698cd
18 changed files with 66 additions and 26 deletions
|
@ -125,6 +125,7 @@
|
|||
</member>
|
||||
<member name="billboard_mode" type="int" setter="set_billboard_mode" getter="get_billboard_mode" enum="BaseMaterial3D.BillboardMode" default="0">
|
||||
Controls how the object faces the camera. See [enum BillboardMode].
|
||||
[b]Note:[/b] When billboarding is enabled and the material also casts shadows, billboards will face [b]the[/b] camera in the scene when rendering shadows. In scenes with multiple cameras, the intended shadow cannot be determined and this will result in undefined behavior. See [url=https://github.com/godotengine/godot/pull/72638]GitHub Pull Request #72638[/url] for details.
|
||||
[b]Note:[/b] Billboard mode is not suitable for VR because the left-right vector of the camera is not horizontal when the screen is attached to your head instead of on the table. See [url=https://github.com/godotengine/godot/issues/41567]GitHub issue #41567[/url] for details.
|
||||
</member>
|
||||
<member name="blend_mode" type="int" setter="set_blend_mode" getter="get_blend_mode" enum="BaseMaterial3D.BlendMode" default="0">
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
</member>
|
||||
<member name="billboard" type="int" setter="set_billboard_mode" getter="get_billboard_mode" enum="BaseMaterial3D.BillboardMode" default="0">
|
||||
The billboard mode to use for the sprite. See [enum BaseMaterial3D.BillboardMode] for possible values.
|
||||
[b]Note:[/b] When billboarding is enabled and the material also casts shadows, billboards will face [b]the[/b] camera in the scene when rendering shadows. In scenes with multiple cameras, the intended shadow cannot be determined and this will result in undefined behavior. See [url=https://github.com/godotengine/godot/pull/72638]GitHub Pull Request #72638[/url] for details.
|
||||
</member>
|
||||
<member name="centered" type="bool" setter="set_centered" getter="is_centered" default="true">
|
||||
If [code]true[/code], texture will be centered.
|
||||
|
|
|
@ -1555,6 +1555,7 @@ void RasterizerSceneGLES3::_setup_environment(const RenderDataGLES3 *p_render_da
|
|||
GLES3::MaterialStorage::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix);
|
||||
GLES3::MaterialStorage::store_transform(p_render_data->cam_transform, scene_state.ubo.inv_view_matrix);
|
||||
GLES3::MaterialStorage::store_transform(p_render_data->inv_cam_transform, scene_state.ubo.view_matrix);
|
||||
GLES3::MaterialStorage::store_transform(p_render_data->main_cam_transform, scene_state.ubo.main_cam_inv_view_matrix);
|
||||
scene_state.ubo.camera_visible_layers = p_render_data->camera_visible_layers;
|
||||
|
||||
if (p_render_data->view_count > 1) {
|
||||
|
@ -2095,20 +2096,20 @@ void RasterizerSceneGLES3::_render_shadows(const RenderDataGLES3 *p_render_data,
|
|||
|
||||
// Render cubemap shadows.
|
||||
for (const int &index : cube_shadows) {
|
||||
_render_shadow_pass(p_render_data->render_shadows[index].light, p_render_data->shadow_atlas, p_render_data->render_shadows[index].pass, p_render_data->render_shadows[index].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->render_info, p_viewport_size);
|
||||
_render_shadow_pass(p_render_data->render_shadows[index].light, p_render_data->shadow_atlas, p_render_data->render_shadows[index].pass, p_render_data->render_shadows[index].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->render_info, p_viewport_size, p_render_data->cam_transform);
|
||||
}
|
||||
// Render directional shadows.
|
||||
for (uint32_t i = 0; i < directional_shadows.size(); i++) {
|
||||
_render_shadow_pass(p_render_data->render_shadows[directional_shadows[i]].light, p_render_data->shadow_atlas, p_render_data->render_shadows[directional_shadows[i]].pass, p_render_data->render_shadows[directional_shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->render_info, p_viewport_size);
|
||||
_render_shadow_pass(p_render_data->render_shadows[directional_shadows[i]].light, p_render_data->shadow_atlas, p_render_data->render_shadows[directional_shadows[i]].pass, p_render_data->render_shadows[directional_shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->render_info, p_viewport_size, p_render_data->cam_transform);
|
||||
}
|
||||
// Render positional shadows (Spotlight and Omnilight with dual-paraboloid).
|
||||
for (uint32_t i = 0; i < shadows.size(); i++) {
|
||||
_render_shadow_pass(p_render_data->render_shadows[shadows[i]].light, p_render_data->shadow_atlas, p_render_data->render_shadows[shadows[i]].pass, p_render_data->render_shadows[shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->render_info, p_viewport_size);
|
||||
_render_shadow_pass(p_render_data->render_shadows[shadows[i]].light, p_render_data->shadow_atlas, p_render_data->render_shadows[shadows[i]].pass, p_render_data->render_shadows[shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->render_info, p_viewport_size, p_render_data->cam_transform);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES3::_render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &p_instances, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, RenderingMethod::RenderInfo *p_render_info, const Size2i &p_viewport_size) {
|
||||
void RasterizerSceneGLES3::_render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &p_instances, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, RenderingMethod::RenderInfo *p_render_info, const Size2i &p_viewport_size, const Transform3D &p_main_cam_transform) {
|
||||
GLES3::LightStorage *light_storage = GLES3::LightStorage::get_singleton();
|
||||
|
||||
ERR_FAIL_COND(!light_storage->owns_light_instance(p_light));
|
||||
|
@ -2242,6 +2243,7 @@ void RasterizerSceneGLES3::_render_shadow_pass(RID p_light, RID p_shadow_atlas,
|
|||
render_data.z_far = zfar; // Only used by OmniLights.
|
||||
render_data.z_near = 0.0;
|
||||
render_data.lod_distance_multiplier = p_lod_distance_multiplier;
|
||||
render_data.main_cam_transform = p_main_cam_transform;
|
||||
|
||||
render_data.instances = &p_instances;
|
||||
render_data.render_info = p_render_info;
|
||||
|
@ -2330,6 +2332,7 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_
|
|||
render_data.cam_projection = p_camera_data->main_projection;
|
||||
render_data.cam_orthogonal = p_camera_data->is_orthogonal;
|
||||
render_data.camera_visible_layers = p_camera_data->visible_layers;
|
||||
render_data.main_cam_transform = p_camera_data->main_transform;
|
||||
|
||||
render_data.view_count = p_camera_data->view_count;
|
||||
for (uint32_t v = 0; v < p_camera_data->view_count; v++) {
|
||||
|
@ -3448,6 +3451,7 @@ void RasterizerSceneGLES3::render_particle_collider_heightfield(RID p_collider,
|
|||
render_data.cam_orthogonal = true;
|
||||
render_data.z_near = 0.0;
|
||||
render_data.z_far = cm.get_z_far();
|
||||
render_data.main_cam_transform = cam_xform;
|
||||
|
||||
render_data.instances = &p_instances;
|
||||
|
||||
|
|
|
@ -98,6 +98,9 @@ struct RenderDataGLES3 {
|
|||
bool cam_orthogonal = false;
|
||||
uint32_t camera_visible_layers = 0xFFFFFFFF;
|
||||
|
||||
// For billboards to cast correct shadows.
|
||||
Transform3D main_cam_transform;
|
||||
|
||||
// For stereo rendering
|
||||
uint32_t view_count = 1;
|
||||
Vector3 view_eye_offset[RendererSceneRender::MAX_RENDER_VIEWS];
|
||||
|
@ -370,6 +373,8 @@ private:
|
|||
float inv_view_matrix[16];
|
||||
float view_matrix[16];
|
||||
|
||||
float main_cam_inv_view_matrix[16];
|
||||
|
||||
float viewport_size[2];
|
||||
float screen_pixel_size[2];
|
||||
|
||||
|
@ -538,7 +543,7 @@ private:
|
|||
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, float p_shadow_bias = 0.0);
|
||||
void _fill_render_list(RenderListType p_render_list, const RenderDataGLES3 *p_render_data, PassMode p_pass_mode, bool p_append = false);
|
||||
void _render_shadows(const RenderDataGLES3 *p_render_data, const Size2i &p_viewport_size = Size2i(1, 1));
|
||||
void _render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_mesh_lod_threshold = 0.0, RenderingMethod::RenderInfo *p_render_info = nullptr, const Size2i &p_viewport_size = Size2i(1, 1));
|
||||
void _render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_mesh_lod_threshold = 0.0, RenderingMethod::RenderInfo *p_render_info = nullptr, const Size2i &p_viewport_size = Size2i(1, 1), const Transform3D &p_main_cam_transform = Transform3D());
|
||||
void _render_post_processing(const RenderDataGLES3 *p_render_data);
|
||||
|
||||
template <PassMode p_pass_mode>
|
||||
|
|
|
@ -155,6 +155,9 @@ layout(std140) uniform SceneData { // ubo:2
|
|||
highp mat4 inv_view_matrix;
|
||||
highp mat4 view_matrix;
|
||||
|
||||
// Used for billboards to cast correct shadows.
|
||||
highp mat4 main_cam_inv_view_matrix;
|
||||
|
||||
vec2 viewport_size;
|
||||
vec2 screen_pixel_size;
|
||||
|
||||
|
@ -637,6 +640,9 @@ layout(std140) uniform SceneData { // ubo:2
|
|||
highp mat4 inv_view_matrix;
|
||||
highp mat4 view_matrix;
|
||||
|
||||
// Used for billboards to cast correct shadows.
|
||||
highp mat4 main_cam_inv_view_matrix;
|
||||
|
||||
vec2 viewport_size;
|
||||
vec2 screen_pixel_size;
|
||||
|
||||
|
|
|
@ -1209,6 +1209,7 @@ MaterialStorage::MaterialStorage() {
|
|||
actions.renames["INV_PROJECTION_MATRIX"] = "inv_projection_matrix";
|
||||
actions.renames["MODELVIEW_MATRIX"] = "modelview";
|
||||
actions.renames["MODELVIEW_NORMAL_MATRIX"] = "modelview_normal";
|
||||
actions.renames["MAIN_CAM_INV_VIEW_MATRIX"] = "scene_data.main_cam_inv_view_matrix";
|
||||
|
||||
actions.renames["VERTEX"] = "vertex";
|
||||
actions.renames["NORMAL"] = "normal";
|
||||
|
|
|
@ -991,7 +991,8 @@ void BaseMaterial3D::_update_shader() {
|
|||
case BILLBOARD_DISABLED: {
|
||||
} break;
|
||||
case BILLBOARD_ENABLED: {
|
||||
code += " MODELVIEW_MATRIX = VIEW_MATRIX * mat4(INV_VIEW_MATRIX[0], INV_VIEW_MATRIX[1], INV_VIEW_MATRIX[2], MODEL_MATRIX[3]);\n";
|
||||
// MAIN_CAM_INV_VIEW_MATRIX is inverse of the camera, even on shadow passes: this ensures the billboard faces the camera when casting shadows.
|
||||
code += " MODELVIEW_MATRIX = VIEW_MATRIX * mat4(MAIN_CAM_INV_VIEW_MATRIX[0], MAIN_CAM_INV_VIEW_MATRIX[1], MAIN_CAM_INV_VIEW_MATRIX[2], MODEL_MATRIX[3]);\n";
|
||||
|
||||
if (flags[FLAG_BILLBOARD_KEEP_SCALE]) {
|
||||
code += " MODELVIEW_MATRIX = MODELVIEW_MATRIX * mat4(vec4(length(MODEL_MATRIX[0].xyz), 0.0, 0.0, 0.0), vec4(0.0, length(MODEL_MATRIX[1].xyz), 0.0, 0.0), vec4(0.0, 0.0, length(MODEL_MATRIX[2].xyz), 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n";
|
||||
|
@ -999,10 +1000,11 @@ void BaseMaterial3D::_update_shader() {
|
|||
code += " MODELVIEW_NORMAL_MATRIX = mat3(MODELVIEW_MATRIX);\n";
|
||||
} break;
|
||||
case BILLBOARD_FIXED_Y: {
|
||||
code += " MODELVIEW_MATRIX = VIEW_MATRIX * mat4(vec4(normalize(cross(vec3(0.0, 1.0, 0.0), INV_VIEW_MATRIX[2].xyz)), 0.0), vec4(0.0, 1.0, 0.0, 0.0), vec4(normalize(cross(INV_VIEW_MATRIX[0].xyz, vec3(0.0, 1.0, 0.0))), 0.0), MODEL_MATRIX[3]);\n";
|
||||
// MAIN_CAM_INV_VIEW_MATRIX is inverse of the camera, even on shadow passes: this ensures the billboard faces the camera when casting shadows.
|
||||
code += " MODELVIEW_MATRIX = VIEW_MATRIX * mat4(vec4(normalize(cross(vec3(0.0, 1.0, 0.0), MAIN_CAM_INV_VIEW_MATRIX[2].xyz)), 0.0), vec4(0.0, 1.0, 0.0, 0.0), vec4(normalize(cross(MAIN_CAM_INV_VIEW_MATRIX[0].xyz, vec3(0.0, 1.0, 0.0))), 0.0), MODEL_MATRIX[3]);\n";
|
||||
|
||||
if (flags[FLAG_BILLBOARD_KEEP_SCALE]) {
|
||||
code += " MODELVIEW_MATRIX = MODELVIEW_MATRIX * mat4(vec4(length(MODEL_MATRIX[0].xyz), 0.0, 0.0, 0.0),vec4(0.0, length(MODEL_MATRIX[1].xyz), 0.0, 0.0), vec4(0.0, 0.0, length(MODEL_MATRIX[2].xyz), 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n";
|
||||
code += " MODELVIEW_MATRIX = MODELVIEW_MATRIX * mat4(vec4(length(MODEL_MATRIX[0].xyz), 0.0, 0.0, 0.0), vec4(0.0, length(MODEL_MATRIX[1].xyz), 0.0, 0.0), vec4(0.0, 0.0, length(MODEL_MATRIX[2].xyz), 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n";
|
||||
}
|
||||
code += " MODELVIEW_NORMAL_MATRIX = mat3(MODELVIEW_MATRIX);\n";
|
||||
} break;
|
||||
|
|
|
@ -1403,7 +1403,7 @@ void RenderForwardClustered::_pre_opaque_render(RenderDataRD *p_render_data, boo
|
|||
|
||||
//cube shadows are rendered in their own way
|
||||
for (const int &index : p_render_data->cube_shadows) {
|
||||
_render_shadow_pass(p_render_data->render_shadows[index].light, p_render_data->shadow_atlas, p_render_data->render_shadows[index].pass, p_render_data->render_shadows[index].instances, camera_plane, lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, true, true, true, p_render_data->render_info, viewport_size);
|
||||
_render_shadow_pass(p_render_data->render_shadows[index].light, p_render_data->shadow_atlas, p_render_data->render_shadows[index].pass, p_render_data->render_shadows[index].instances, camera_plane, lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, true, true, true, p_render_data->render_info, viewport_size, p_render_data->scene_data->cam_transform);
|
||||
}
|
||||
|
||||
if (p_render_data->directional_shadows.size()) {
|
||||
|
@ -1433,11 +1433,11 @@ void RenderForwardClustered::_pre_opaque_render(RenderDataRD *p_render_data, boo
|
|||
|
||||
//render directional shadows
|
||||
for (uint32_t i = 0; i < p_render_data->directional_shadows.size(); i++) {
|
||||
_render_shadow_pass(p_render_data->render_shadows[p_render_data->directional_shadows[i]].light, p_render_data->shadow_atlas, p_render_data->render_shadows[p_render_data->directional_shadows[i]].pass, p_render_data->render_shadows[p_render_data->directional_shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, false, i == p_render_data->directional_shadows.size() - 1, false, p_render_data->render_info, viewport_size);
|
||||
_render_shadow_pass(p_render_data->render_shadows[p_render_data->directional_shadows[i]].light, p_render_data->shadow_atlas, p_render_data->render_shadows[p_render_data->directional_shadows[i]].pass, p_render_data->render_shadows[p_render_data->directional_shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, false, i == p_render_data->directional_shadows.size() - 1, false, p_render_data->render_info, viewport_size, p_render_data->scene_data->cam_transform);
|
||||
}
|
||||
//render positional shadows
|
||||
for (uint32_t i = 0; i < p_render_data->shadows.size(); i++) {
|
||||
_render_shadow_pass(p_render_data->render_shadows[p_render_data->shadows[i]].light, p_render_data->shadow_atlas, p_render_data->render_shadows[p_render_data->shadows[i]].pass, p_render_data->render_shadows[p_render_data->shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, i == 0, i == p_render_data->shadows.size() - 1, true, p_render_data->render_info, viewport_size);
|
||||
_render_shadow_pass(p_render_data->render_shadows[p_render_data->shadows[i]].light, p_render_data->shadow_atlas, p_render_data->render_shadows[p_render_data->shadows[i]].pass, p_render_data->render_shadows[p_render_data->shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, i == 0, i == p_render_data->shadows.size() - 1, true, p_render_data->render_info, viewport_size, p_render_data->scene_data->cam_transform);
|
||||
}
|
||||
|
||||
_render_shadow_process();
|
||||
|
@ -2268,7 +2268,7 @@ void RenderForwardClustered::_render_buffers_debug_draw(const RenderDataRD *p_re
|
|||
}
|
||||
}
|
||||
|
||||
void RenderForwardClustered::_render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &p_instances, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, bool p_open_pass, bool p_close_pass, bool p_clear_region, RenderingMethod::RenderInfo *p_render_info, const Size2i &p_viewport_size) {
|
||||
void RenderForwardClustered::_render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &p_instances, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, bool p_open_pass, bool p_close_pass, bool p_clear_region, RenderingMethod::RenderInfo *p_render_info, const Size2i &p_viewport_size, const Transform3D &p_main_cam_transform) {
|
||||
RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();
|
||||
|
||||
ERR_FAIL_COND(!light_storage->owns_light_instance(p_light));
|
||||
|
@ -2423,7 +2423,7 @@ void RenderForwardClustered::_render_shadow_pass(RID p_light, RID p_shadow_atlas
|
|||
|
||||
if (render_cubemap) {
|
||||
//rendering to cubemap
|
||||
_render_shadow_append(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, reverse_cull_face, false, false, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_mesh_lod_threshold, Rect2(), false, true, true, true, p_render_info, p_viewport_size);
|
||||
_render_shadow_append(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, reverse_cull_face, false, false, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_mesh_lod_threshold, Rect2(), false, true, true, true, p_render_info, p_viewport_size, p_main_cam_transform);
|
||||
if (finalize_cubemap) {
|
||||
_render_shadow_process();
|
||||
_render_shadow_end();
|
||||
|
@ -2441,7 +2441,7 @@ void RenderForwardClustered::_render_shadow_pass(RID p_light, RID p_shadow_atlas
|
|||
|
||||
} else {
|
||||
//render shadow
|
||||
_render_shadow_append(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, reverse_cull_face, using_dual_paraboloid, using_dual_paraboloid_flip, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_mesh_lod_threshold, atlas_rect, flip_y, p_clear_region, p_open_pass, p_close_pass, p_render_info, p_viewport_size);
|
||||
_render_shadow_append(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, reverse_cull_face, using_dual_paraboloid, using_dual_paraboloid_flip, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_mesh_lod_threshold, atlas_rect, flip_y, p_clear_region, p_open_pass, p_close_pass, p_render_info, p_viewport_size, p_main_cam_transform);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2454,7 +2454,7 @@ void RenderForwardClustered::_render_shadow_begin() {
|
|||
scene_state.instance_data[RENDER_LIST_SECONDARY].clear();
|
||||
}
|
||||
|
||||
void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_reverse_cull_face, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end, RenderingMethod::RenderInfo *p_render_info, const Size2i &p_viewport_size) {
|
||||
void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_reverse_cull_face, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end, RenderingMethod::RenderInfo *p_render_info, const Size2i &p_viewport_size, const Transform3D &p_main_cam_transform) {
|
||||
uint32_t shadow_pass_index = scene_state.shadow_passes.size();
|
||||
|
||||
SceneState::ShadowPass shadow_pass;
|
||||
|
@ -2470,6 +2470,7 @@ void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const Page
|
|||
scene_data.opaque_prepass_threshold = 0.1f;
|
||||
scene_data.time = time;
|
||||
scene_data.time_step = time_step;
|
||||
scene_data.main_cam_transform = p_main_cam_transform;
|
||||
|
||||
RenderDataRD render_data;
|
||||
render_data.scene_data = &scene_data;
|
||||
|
@ -2561,6 +2562,7 @@ void RenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, con
|
|||
scene_data.opaque_prepass_threshold = 0.0;
|
||||
scene_data.time = time;
|
||||
scene_data.time_step = time_step;
|
||||
scene_data.main_cam_transform = p_cam_transform;
|
||||
|
||||
RenderDataRD render_data;
|
||||
render_data.scene_data = &scene_data;
|
||||
|
@ -2605,6 +2607,7 @@ void RenderForwardClustered::_render_material(const Transform3D &p_cam_transform
|
|||
scene_data.emissive_exposure_normalization = p_exposure_normalization;
|
||||
scene_data.time = time;
|
||||
scene_data.time_step = time_step;
|
||||
scene_data.main_cam_transform = p_cam_transform;
|
||||
|
||||
RenderDataRD render_data;
|
||||
render_data.scene_data = &scene_data;
|
||||
|
|
|
@ -591,9 +591,9 @@ class RenderForwardClustered : public RendererSceneRenderRD {
|
|||
|
||||
/* Render shadows */
|
||||
|
||||
void _render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_mesh_lod_threshold = 0.0, bool p_open_pass = true, bool p_close_pass = true, bool p_clear_region = true, RenderingMethod::RenderInfo *p_render_info = nullptr, const Size2i &p_viewport_size = Size2i(1, 1));
|
||||
void _render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_mesh_lod_threshold = 0.0, bool p_open_pass = true, bool p_close_pass = true, bool p_clear_region = true, RenderingMethod::RenderInfo *p_render_info = nullptr, const Size2i &p_viewport_size = Size2i(1, 1), const Transform3D &p_main_cam_transform = Transform3D());
|
||||
void _render_shadow_begin();
|
||||
void _render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_reverse_cull_face, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RenderingMethod::RenderInfo *p_render_info = nullptr, const Size2i &p_viewport_size = Size2i(1, 1));
|
||||
void _render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_reverse_cull_face, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RenderingMethod::RenderInfo *p_render_info = nullptr, const Size2i &p_viewport_size = Size2i(1, 1), const Transform3D &p_main_cam_transform = Transform3D());
|
||||
void _render_shadow_process();
|
||||
void _render_shadow_end();
|
||||
|
||||
|
|
|
@ -559,6 +559,7 @@ void SceneShaderForwardClustered::init(const String p_defines) {
|
|||
actions.renames["INV_PROJECTION_MATRIX"] = "inv_projection_matrix";
|
||||
actions.renames["MODELVIEW_MATRIX"] = "modelview";
|
||||
actions.renames["MODELVIEW_NORMAL_MATRIX"] = "modelview_normal";
|
||||
actions.renames["MAIN_CAM_INV_VIEW_MATRIX"] = "scene_data.main_cam_inv_view_matrix";
|
||||
|
||||
actions.renames["VERTEX"] = "vertex";
|
||||
actions.renames["NORMAL"] = "normal";
|
||||
|
|
|
@ -608,7 +608,7 @@ void RenderForwardMobile::_pre_opaque_render(RenderDataRD *p_render_data) {
|
|||
|
||||
//cube shadows are rendered in their own way
|
||||
for (const int &index : p_render_data->cube_shadows) {
|
||||
_render_shadow_pass(p_render_data->render_shadows[index].light, p_render_data->shadow_atlas, p_render_data->render_shadows[index].pass, p_render_data->render_shadows[index].instances, camera_plane, lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, true, true, true, p_render_data->render_info);
|
||||
_render_shadow_pass(p_render_data->render_shadows[index].light, p_render_data->shadow_atlas, p_render_data->render_shadows[index].pass, p_render_data->render_shadows[index].instances, camera_plane, lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, true, true, true, p_render_data->render_info, p_render_data->scene_data->cam_transform);
|
||||
}
|
||||
|
||||
if (p_render_data->directional_shadows.size()) {
|
||||
|
@ -629,11 +629,11 @@ void RenderForwardMobile::_pre_opaque_render(RenderDataRD *p_render_data) {
|
|||
|
||||
//render directional shadows
|
||||
for (uint32_t i = 0; i < p_render_data->directional_shadows.size(); i++) {
|
||||
_render_shadow_pass(p_render_data->render_shadows[p_render_data->directional_shadows[i]].light, p_render_data->shadow_atlas, p_render_data->render_shadows[p_render_data->directional_shadows[i]].pass, p_render_data->render_shadows[p_render_data->directional_shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, false, i == p_render_data->directional_shadows.size() - 1, false, p_render_data->render_info);
|
||||
_render_shadow_pass(p_render_data->render_shadows[p_render_data->directional_shadows[i]].light, p_render_data->shadow_atlas, p_render_data->render_shadows[p_render_data->directional_shadows[i]].pass, p_render_data->render_shadows[p_render_data->directional_shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, false, i == p_render_data->directional_shadows.size() - 1, false, p_render_data->render_info, p_render_data->scene_data->cam_transform);
|
||||
}
|
||||
//render positional shadows
|
||||
for (uint32_t i = 0; i < p_render_data->shadows.size(); i++) {
|
||||
_render_shadow_pass(p_render_data->render_shadows[p_render_data->shadows[i]].light, p_render_data->shadow_atlas, p_render_data->render_shadows[p_render_data->shadows[i]].pass, p_render_data->render_shadows[p_render_data->shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, i == 0, i == p_render_data->shadows.size() - 1, true, p_render_data->render_info);
|
||||
_render_shadow_pass(p_render_data->render_shadows[p_render_data->shadows[i]].light, p_render_data->shadow_atlas, p_render_data->render_shadows[p_render_data->shadows[i]].pass, p_render_data->render_shadows[p_render_data->shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, i == 0, i == p_render_data->shadows.size() - 1, true, p_render_data->render_info, p_render_data->scene_data->cam_transform);
|
||||
}
|
||||
|
||||
_render_shadow_process();
|
||||
|
@ -1068,7 +1068,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
|
|||
|
||||
/* these are being called from RendererSceneRenderRD::_pre_opaque_render */
|
||||
|
||||
void RenderForwardMobile::_render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &p_instances, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, bool p_open_pass, bool p_close_pass, bool p_clear_region, RenderingMethod::RenderInfo *p_render_info) {
|
||||
void RenderForwardMobile::_render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &p_instances, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, bool p_open_pass, bool p_close_pass, bool p_clear_region, RenderingMethod::RenderInfo *p_render_info, const Transform3D &p_main_cam_transform) {
|
||||
RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();
|
||||
|
||||
ERR_FAIL_COND(!light_storage->owns_light_instance(p_light));
|
||||
|
@ -1222,7 +1222,7 @@ void RenderForwardMobile::_render_shadow_pass(RID p_light, RID p_shadow_atlas, i
|
|||
|
||||
if (render_cubemap) {
|
||||
//rendering to cubemap
|
||||
_render_shadow_append(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, false, false, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_mesh_lod_threshold, Rect2(), false, true, true, true, p_render_info);
|
||||
_render_shadow_append(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, false, false, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_mesh_lod_threshold, Rect2(), false, true, true, true, p_render_info, p_main_cam_transform);
|
||||
if (finalize_cubemap) {
|
||||
_render_shadow_process();
|
||||
_render_shadow_end();
|
||||
|
@ -1241,7 +1241,7 @@ void RenderForwardMobile::_render_shadow_pass(RID p_light, RID p_shadow_atlas, i
|
|||
|
||||
} else {
|
||||
//render shadow
|
||||
_render_shadow_append(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, using_dual_paraboloid, using_dual_paraboloid_flip, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_mesh_lod_threshold, atlas_rect, flip_y, p_clear_region, p_open_pass, p_close_pass, p_render_info);
|
||||
_render_shadow_append(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, using_dual_paraboloid, using_dual_paraboloid_flip, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_mesh_lod_threshold, atlas_rect, flip_y, p_clear_region, p_open_pass, p_close_pass, p_render_info, p_main_cam_transform);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1253,7 +1253,7 @@ void RenderForwardMobile::_render_shadow_begin() {
|
|||
render_list[RENDER_LIST_SECONDARY].clear();
|
||||
}
|
||||
|
||||
void RenderForwardMobile::_render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end, RenderingMethod::RenderInfo *p_render_info) {
|
||||
void RenderForwardMobile::_render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end, RenderingMethod::RenderInfo *p_render_info, const Transform3D &p_main_cam_transform) {
|
||||
uint32_t shadow_pass_index = scene_state.shadow_passes.size();
|
||||
|
||||
SceneState::ShadowPass shadow_pass;
|
||||
|
@ -1274,6 +1274,7 @@ void RenderForwardMobile::_render_shadow_append(RID p_framebuffer, const PagedAr
|
|||
scene_data.opaque_prepass_threshold = 0.1;
|
||||
scene_data.time = time;
|
||||
scene_data.time_step = time_step;
|
||||
scene_data.main_cam_transform = p_main_cam_transform;
|
||||
|
||||
RenderDataRD render_data;
|
||||
render_data.scene_data = &scene_data;
|
||||
|
@ -1363,6 +1364,7 @@ void RenderForwardMobile::_render_material(const Transform3D &p_cam_transform, c
|
|||
scene_data.emissive_exposure_normalization = p_exposure_normalization;
|
||||
scene_data.time = time;
|
||||
scene_data.time_step = time_step;
|
||||
scene_data.main_cam_transform = p_cam_transform;
|
||||
|
||||
RenderDataRD render_data;
|
||||
render_data.scene_data = &scene_data;
|
||||
|
@ -1488,6 +1490,7 @@ void RenderForwardMobile::_render_particle_collider_heightfield(RID p_fb, const
|
|||
scene_data.opaque_prepass_threshold = 0.0;
|
||||
scene_data.time = time;
|
||||
scene_data.time_step = time_step;
|
||||
scene_data.main_cam_transform = p_cam_transform;
|
||||
|
||||
RenderDataRD render_data;
|
||||
render_data.scene_data = &scene_data;
|
||||
|
|
|
@ -177,9 +177,9 @@ private:
|
|||
|
||||
/* Render shadows */
|
||||
|
||||
void _render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_mesh_lod_threshold = 0.0, bool p_open_pass = true, bool p_close_pass = true, bool p_clear_region = true, RenderingMethod::RenderInfo *p_render_info = nullptr);
|
||||
void _render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_mesh_lod_threshold = 0.0, bool p_open_pass = true, bool p_close_pass = true, bool p_clear_region = true, RenderingMethod::RenderInfo *p_render_info = nullptr, const Transform3D &p_main_cam_transform = Transform3D());
|
||||
void _render_shadow_begin();
|
||||
void _render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RenderingMethod::RenderInfo *p_render_info = nullptr);
|
||||
void _render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RenderingMethod::RenderInfo *p_render_info = nullptr, const Transform3D &p_main_cam_transform = Transform3D());
|
||||
void _render_shadow_process();
|
||||
void _render_shadow_end();
|
||||
|
||||
|
|
|
@ -463,6 +463,7 @@ void SceneShaderForwardMobile::init(const String p_defines) {
|
|||
actions.renames["INV_PROJECTION_MATRIX"] = "inv_projection_matrix";
|
||||
actions.renames["MODELVIEW_MATRIX"] = "modelview";
|
||||
actions.renames["MODELVIEW_NORMAL_MATRIX"] = "modelview_normal";
|
||||
actions.renames["MAIN_CAM_INV_VIEW_MATRIX"] = "scene_data.main_cam_inv_view_matrix";
|
||||
|
||||
actions.renames["VERTEX"] = "vertex";
|
||||
actions.renames["NORMAL"] = "normal";
|
||||
|
|
|
@ -1005,6 +1005,7 @@ void RendererSceneRenderRD::render_scene(const Ref<RenderSceneBuffers> &p_render
|
|||
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.main_cam_transform = p_camera_data->main_transform;
|
||||
|
||||
scene_data.view_count = p_camera_data->view_count;
|
||||
for (uint32_t v = 0; v < p_camera_data->view_count; v++) {
|
||||
|
|
|
@ -14,6 +14,9 @@ struct SceneData {
|
|||
highp mat4 inv_projection_matrix_view[MAX_VIEWS];
|
||||
highp vec4 eye_offset[MAX_VIEWS];
|
||||
|
||||
// Used for billboards to cast correct shadows.
|
||||
highp mat4 main_cam_inv_view_matrix;
|
||||
|
||||
highp vec2 viewport_size;
|
||||
highp vec2 screen_pixel_size;
|
||||
|
||||
|
|
|
@ -76,6 +76,8 @@ void RenderSceneDataRD::update_ubo(RID p_uniform_buffer, RS::ViewportDebugDraw p
|
|||
ubo.eye_offset[v][3] = 0.0;
|
||||
}
|
||||
|
||||
RendererRD::MaterialStorage::store_transform(main_cam_transform, ubo.main_cam_inv_view_matrix);
|
||||
|
||||
ubo.taa_jitter[0] = taa_jitter.x;
|
||||
ubo.taa_jitter[1] = taa_jitter.y;
|
||||
|
||||
|
|
|
@ -48,6 +48,9 @@ public:
|
|||
uint32_t camera_visible_layers;
|
||||
bool cam_orthogonal = false;
|
||||
|
||||
// For billboards to cast correct shadows.
|
||||
Transform3D main_cam_transform;
|
||||
|
||||
// For stereo rendering
|
||||
uint32_t view_count = 1;
|
||||
Vector3 view_eye_offset[RendererSceneRender::MAX_RENDER_VIEWS];
|
||||
|
@ -94,6 +97,8 @@ private:
|
|||
float inv_projection_matrix_view[RendererSceneRender::MAX_RENDER_VIEWS][16];
|
||||
float eye_offset[RendererSceneRender::MAX_RENDER_VIEWS][4];
|
||||
|
||||
float main_cam_inv_view_matrix[16];
|
||||
|
||||
float viewport_size[2];
|
||||
float screen_pixel_size[2];
|
||||
|
||||
|
|
|
@ -97,6 +97,7 @@ ShaderTypes::ShaderTypes() {
|
|||
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["MODELVIEW_NORMAL_MATRIX"] = ShaderLanguage::TYPE_MAT3;
|
||||
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["VIEWPORT_SIZE"] = constt(ShaderLanguage::TYPE_VEC2);
|
||||
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["OUTPUT_IS_SRGB"] = constt(ShaderLanguage::TYPE_BOOL);
|
||||
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["MAIN_CAM_INV_VIEW_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4);
|
||||
|
||||
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;
|
||||
|
|
Loading…
Reference in a new issue