1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-28 16:07:14 +00:00

Implement signed distance fields for 2D shaders

This commit is contained in:
reduz
2020-11-26 09:50:21 -03:00
parent 4e5625ce30
commit 1bcf3c305b
26 changed files with 1028 additions and 89 deletions

View File

@@ -146,6 +146,36 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface::
RasterizerCanvas::Light *directional_lights = nullptr;
RasterizerCanvas::Light *directional_lights_with_shadow = nullptr;
if (p_viewport->sdf_active) {
//process SDF
Rect2 sdf_rect = RSG::storage->render_target_get_sdf_rect(p_viewport->render_target);
RasterizerCanvas::LightOccluderInstance *occluders = nullptr;
//make list of occluders
for (Map<RID, Viewport::CanvasData>::Element *E = p_viewport->canvas_map.front(); E; E = E->next()) {
RenderingServerCanvas::Canvas *canvas = static_cast<RenderingServerCanvas::Canvas *>(E->get().canvas);
Transform2D xf = _canvas_get_transform(p_viewport, canvas, &E->get(), clip_rect.size);
for (Set<RasterizerCanvas::LightOccluderInstance *>::Element *F = canvas->occluders.front(); F; F = F->next()) {
if (!F->get()->enabled) {
continue;
}
F->get()->xform_cache = xf * F->get()->xform;
if (sdf_rect.intersects_transformed(F->get()->xform_cache, F->get()->aabb_cache)) {
F->get()->next = occluders;
occluders = F->get();
}
}
}
RSG::canvas_render->render_sdf(p_viewport->render_target, occluders);
p_viewport->sdf_active = false; // if used, gets set active again
}
Rect2 shadow_rect;
int light_count = 0;
@@ -195,7 +225,6 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface::
}
//guess this is not needed, but keeping because it may be
//RSG::canvas_render->light_internal_update(cl->light_internal, cl);
}
}
@@ -256,7 +285,6 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface::
light = light->shadows_next_ptr;
}
//RSG::canvas_render->reset_canvas();
RENDER_TIMESTAMP("<End rendering 2D Shadows");
}
@@ -340,7 +368,6 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface::
light = light->shadows_next_ptr;
}
//RSG::canvas_render->reset_canvas();
RENDER_TIMESTAMP("<Render Directional 2D Shadows");
}
@@ -380,6 +407,9 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface::
}
RSG::canvas->render_canvas(p_viewport->render_target, canvas, xform, canvas_lights, canvas_directional_lights, clip_rect, p_viewport->texture_filter, p_viewport->texture_repeat, p_viewport->snap_2d_transforms_to_pixel, p_viewport->snap_2d_vertices_to_pixel);
if (RSG::canvas->was_sdf_used()) {
p_viewport->sdf_active = true;
}
i++;
if (scenario_draw_canvas_bg && E->key().get_layer() >= scenario_canvas_max_layer) {
@@ -400,8 +430,6 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface::
_draw_3d(p_viewport, p_eye);
}
}
//RSG::canvas_render->canvas_debug_viewport_shadows(lights_with_shadow);
}
if (RSG::storage->render_target_is_clear_requested(p_viewport->render_target)) {
@@ -925,6 +953,13 @@ void RenderingServerViewport::viewport_set_default_canvas_item_texture_repeat(RI
viewport->texture_repeat = p_repeat;
}
void RenderingServerViewport::viewport_set_sdf_oversize_and_scale(RID p_viewport, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
RSG::storage->render_target_set_sdf_size_and_scale(viewport->render_target, p_size, p_scale);
}
bool RenderingServerViewport::free(RID p_rid) {
if (viewport_owner.owns(p_rid)) {
Viewport *viewport = viewport_owner.getornull(p_rid);