mirror of
https://github.com/Relintai/pandemonium_engine_minimal.git
synced 2024-11-17 22:17:19 +01:00
More shadow related code cleanups.
This commit is contained in:
parent
d821a15748
commit
d3ca4c124d
@ -38,18 +38,7 @@
|
||||
|
||||
class RasterizerSceneDummy : public RasterizerScene {
|
||||
public:
|
||||
/* SHADOW ATLAS API */
|
||||
|
||||
RID shadow_atlas_create() { return RID(); }
|
||||
void shadow_atlas_set_size(RID p_atlas, int p_size) {}
|
||||
void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) {}
|
||||
bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) { return false; }
|
||||
|
||||
int get_directional_light_shadow_size(RID p_light_intance) { return 0; }
|
||||
void set_directional_shadow_count(int p_count) {}
|
||||
|
||||
void render_scene(const Transform &p_cam_transform, const Projection &p_cam_projection, const int p_eye, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID p_environment, RID p_shadow_atlas) {}
|
||||
void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count) {}
|
||||
void render_scene(const Transform &p_cam_transform, const Projection &p_cam_projection, const int p_eye, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count) {}
|
||||
|
||||
void set_scene_pass(uint64_t p_pass) {}
|
||||
void set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw) {}
|
||||
|
@ -52,416 +52,9 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
const GLenum RasterizerSceneGLES2::_cube_side_enum[6] = {
|
||||
|
||||
GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_X,
|
||||
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
|
||||
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
|
||||
|
||||
};
|
||||
|
||||
void RasterizerSceneGLES2::directional_shadow_create() {
|
||||
if (directional_shadow.fbo) {
|
||||
// Erase existing directional shadow texture to recreate it.
|
||||
glDeleteTextures(1, &directional_shadow.depth);
|
||||
glDeleteFramebuffers(1, &directional_shadow.fbo);
|
||||
|
||||
directional_shadow.depth = 0;
|
||||
directional_shadow.fbo = 0;
|
||||
}
|
||||
|
||||
directional_shadow.light_count = 0;
|
||||
directional_shadow.size = next_power_of_2(directional_shadow_size);
|
||||
|
||||
if (directional_shadow.size > storage->config.max_viewport_dimensions[0] || directional_shadow.size > storage->config.max_viewport_dimensions[1]) {
|
||||
WARN_PRINT("Cannot set directional shadow size larger than maximum hardware supported size of (" + itos(storage->config.max_viewport_dimensions[0]) + ", " + itos(storage->config.max_viewport_dimensions[1]) + "). Setting size to maximum.");
|
||||
directional_shadow.size = MIN(directional_shadow.size, storage->config.max_viewport_dimensions[0]);
|
||||
directional_shadow.size = MIN(directional_shadow.size, storage->config.max_viewport_dimensions[1]);
|
||||
}
|
||||
|
||||
glGenFramebuffers(1, &directional_shadow.fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, directional_shadow.fbo);
|
||||
|
||||
if (storage->config.use_rgba_3d_shadows) {
|
||||
//maximum compatibility, renderbuffer and RGBA shadow
|
||||
glGenRenderbuffers(1, &directional_shadow.depth);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, directional_shadow.depth);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, storage->config.depth_buffer_internalformat, directional_shadow.size, directional_shadow.size);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, directional_shadow.depth);
|
||||
|
||||
glGenTextures(1, &directional_shadow.color);
|
||||
glBindTexture(GL_TEXTURE_2D, directional_shadow.color);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, directional_shadow.size, directional_shadow.size, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, directional_shadow.color, 0);
|
||||
} else {
|
||||
//just a depth buffer
|
||||
glGenTextures(1, &directional_shadow.depth);
|
||||
glBindTexture(GL_TEXTURE_2D, directional_shadow.depth);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, storage->config.depth_internalformat, directional_shadow.size, directional_shadow.size, 0, GL_DEPTH_COMPONENT, storage->config.depth_type, nullptr);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, directional_shadow.depth, 0);
|
||||
}
|
||||
|
||||
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE) {
|
||||
ERR_PRINT("Directional shadow framebuffer status invalid");
|
||||
}
|
||||
}
|
||||
|
||||
/* SHADOW ATLAS API */
|
||||
|
||||
RID RasterizerSceneGLES2::shadow_atlas_create() {
|
||||
ShadowAtlas *shadow_atlas = memnew(ShadowAtlas);
|
||||
shadow_atlas->fbo = 0;
|
||||
shadow_atlas->depth = 0;
|
||||
shadow_atlas->color = 0;
|
||||
shadow_atlas->size = 0;
|
||||
shadow_atlas->smallest_subdiv = 0;
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
shadow_atlas->size_order[i] = i;
|
||||
}
|
||||
|
||||
return shadow_atlas_owner.make_rid(shadow_atlas);
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES2::shadow_atlas_set_size(RID p_atlas, int p_size) {
|
||||
ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_atlas);
|
||||
ERR_FAIL_COND(!shadow_atlas);
|
||||
ERR_FAIL_COND(p_size < 0);
|
||||
|
||||
p_size = next_power_of_2(p_size);
|
||||
|
||||
if (p_size == shadow_atlas->size) {
|
||||
return;
|
||||
}
|
||||
|
||||
// erase the old atlast
|
||||
if (shadow_atlas->fbo) {
|
||||
if (storage->config.use_rgba_3d_shadows) {
|
||||
glDeleteRenderbuffers(1, &shadow_atlas->depth);
|
||||
} else {
|
||||
glDeleteTextures(1, &shadow_atlas->depth);
|
||||
}
|
||||
glDeleteFramebuffers(1, &shadow_atlas->fbo);
|
||||
if (shadow_atlas->color) {
|
||||
glDeleteTextures(1, &shadow_atlas->color);
|
||||
}
|
||||
|
||||
shadow_atlas->fbo = 0;
|
||||
shadow_atlas->depth = 0;
|
||||
shadow_atlas->color = 0;
|
||||
}
|
||||
|
||||
shadow_atlas->shadow_owners.clear();
|
||||
|
||||
shadow_atlas->size = p_size;
|
||||
|
||||
if (shadow_atlas->size) {
|
||||
glGenFramebuffers(1, &shadow_atlas->fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, shadow_atlas->fbo);
|
||||
|
||||
if (shadow_atlas->size > storage->config.max_viewport_dimensions[0] || shadow_atlas->size > storage->config.max_viewport_dimensions[1]) {
|
||||
WARN_PRINT("Cannot set shadow atlas size larger than maximum hardware supported size of (" + itos(storage->config.max_viewport_dimensions[0]) + ", " + itos(storage->config.max_viewport_dimensions[1]) + "). Setting size to maximum.");
|
||||
shadow_atlas->size = MIN(shadow_atlas->size, storage->config.max_viewport_dimensions[0]);
|
||||
shadow_atlas->size = MIN(shadow_atlas->size, storage->config.max_viewport_dimensions[1]);
|
||||
}
|
||||
|
||||
// create a depth texture
|
||||
WRAPPED_GL_ACTIVE_TEXTURE(GL_TEXTURE0);
|
||||
|
||||
if (storage->config.use_rgba_3d_shadows) {
|
||||
//maximum compatibility, renderbuffer and RGBA shadow
|
||||
glGenRenderbuffers(1, &shadow_atlas->depth);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, shadow_atlas->depth);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, storage->config.depth_buffer_internalformat, shadow_atlas->size, shadow_atlas->size);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, shadow_atlas->depth);
|
||||
|
||||
glGenTextures(1, &shadow_atlas->color);
|
||||
glBindTexture(GL_TEXTURE_2D, shadow_atlas->color);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, shadow_atlas->size, shadow_atlas->size, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, shadow_atlas->color, 0);
|
||||
} else {
|
||||
//just depth texture
|
||||
glGenTextures(1, &shadow_atlas->depth);
|
||||
glBindTexture(GL_TEXTURE_2D, shadow_atlas->depth);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, storage->config.depth_internalformat, shadow_atlas->size, shadow_atlas->size, 0, GL_DEPTH_COMPONENT, storage->config.depth_type, nullptr);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, shadow_atlas->depth, 0);
|
||||
}
|
||||
glViewport(0, 0, shadow_atlas->size, shadow_atlas->size);
|
||||
|
||||
glDepthMask(GL_TRUE);
|
||||
|
||||
glClearDepth(0.0f);
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES2::shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) {
|
||||
ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_atlas);
|
||||
ERR_FAIL_COND(!shadow_atlas);
|
||||
ERR_FAIL_INDEX(p_quadrant, 4);
|
||||
ERR_FAIL_INDEX(p_subdivision, 16384);
|
||||
|
||||
uint32_t subdiv = next_power_of_2(p_subdivision);
|
||||
if (subdiv & 0xaaaaaaaa) { // sqrt(subdiv) must be integer
|
||||
subdiv <<= 1;
|
||||
}
|
||||
|
||||
subdiv = int(Math::sqrt((float)subdiv));
|
||||
|
||||
if (shadow_atlas->quadrants[p_quadrant].shadows.size() == (int)subdiv) {
|
||||
return;
|
||||
}
|
||||
|
||||
shadow_atlas->quadrants[p_quadrant].shadows.resize(0);
|
||||
shadow_atlas->quadrants[p_quadrant].shadows.resize(subdiv);
|
||||
shadow_atlas->quadrants[p_quadrant].subdivision = subdiv;
|
||||
|
||||
// cache the smallest subdivision for faster allocations
|
||||
|
||||
shadow_atlas->smallest_subdiv = 1 << 30;
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (shadow_atlas->quadrants[i].subdivision) {
|
||||
shadow_atlas->smallest_subdiv = MIN(shadow_atlas->smallest_subdiv, shadow_atlas->quadrants[i].subdivision);
|
||||
}
|
||||
}
|
||||
|
||||
if (shadow_atlas->smallest_subdiv == 1 << 30) {
|
||||
shadow_atlas->smallest_subdiv = 0;
|
||||
}
|
||||
|
||||
// re-sort the quadrants
|
||||
|
||||
int swaps = 0;
|
||||
do {
|
||||
swaps = 0;
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (shadow_atlas->quadrants[shadow_atlas->size_order[i]].subdivision < shadow_atlas->quadrants[shadow_atlas->size_order[i + 1]].subdivision) {
|
||||
SWAP(shadow_atlas->size_order[i], shadow_atlas->size_order[i + 1]);
|
||||
swaps++;
|
||||
}
|
||||
}
|
||||
|
||||
} while (swaps > 0);
|
||||
}
|
||||
|
||||
bool RasterizerSceneGLES2::_shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int *p_in_quadrants, int p_quadrant_count, int p_current_subdiv, uint64_t p_tick, int &r_quadrant, int &r_shadow) {
|
||||
for (int i = p_quadrant_count - 1; i >= 0; i--) {
|
||||
int qidx = p_in_quadrants[i];
|
||||
|
||||
if (shadow_atlas->quadrants[qidx].subdivision == (uint32_t)p_current_subdiv) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// look for an empty space
|
||||
|
||||
int sc = shadow_atlas->quadrants[qidx].shadows.size();
|
||||
|
||||
ShadowAtlas::Quadrant::Shadow *sarr = shadow_atlas->quadrants[qidx].shadows.ptrw();
|
||||
|
||||
int found_free_idx = -1; // found a free one
|
||||
int found_used_idx = -1; // found an existing one, must steal it
|
||||
uint64_t min_pass = 0; // pass of the existing one, try to use the least recently
|
||||
|
||||
if (found_free_idx == -1 && found_used_idx == -1) {
|
||||
continue; // nothing found
|
||||
}
|
||||
|
||||
if (found_free_idx == -1 && found_used_idx != -1) {
|
||||
found_free_idx = found_used_idx;
|
||||
}
|
||||
|
||||
r_quadrant = qidx;
|
||||
r_shadow = found_free_idx;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RasterizerSceneGLES2::shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) {
|
||||
ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_atlas);
|
||||
ERR_FAIL_COND_V(!shadow_atlas, false);
|
||||
|
||||
if (shadow_atlas->size == 0 || shadow_atlas->smallest_subdiv == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t quad_size = shadow_atlas->size >> 1;
|
||||
int desired_fit = MIN(quad_size / shadow_atlas->smallest_subdiv, next_power_of_2(quad_size * p_coverage));
|
||||
|
||||
int valid_quadrants[4];
|
||||
int valid_quadrant_count = 0;
|
||||
int best_size = -1;
|
||||
int best_subdiv = -1;
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int q = shadow_atlas->size_order[i];
|
||||
int sd = shadow_atlas->quadrants[q].subdivision;
|
||||
|
||||
if (sd == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int max_fit = quad_size / sd;
|
||||
|
||||
if (best_size != -1 && max_fit > best_size) {
|
||||
break; // what we asked for is bigger than this.
|
||||
}
|
||||
|
||||
valid_quadrants[valid_quadrant_count] = q;
|
||||
valid_quadrant_count++;
|
||||
|
||||
best_subdiv = sd;
|
||||
|
||||
if (max_fit >= desired_fit) {
|
||||
best_size = max_fit;
|
||||
}
|
||||
}
|
||||
|
||||
ERR_FAIL_COND_V(valid_quadrant_count == 0, false); // no suitable block available
|
||||
|
||||
uint64_t tick = OS::get_singleton()->get_ticks_msec();
|
||||
|
||||
if (shadow_atlas->shadow_owners.has(p_light_intance)) {
|
||||
// light was already known!
|
||||
|
||||
uint32_t key = shadow_atlas->shadow_owners[p_light_intance];
|
||||
uint32_t q = (key >> ShadowAtlas::QUADRANT_SHIFT) & 0x3;
|
||||
uint32_t s = key & ShadowAtlas::SHADOW_INDEX_MASK;
|
||||
|
||||
bool should_realloc = shadow_atlas->quadrants[q].subdivision != (uint32_t)best_subdiv && (shadow_atlas->quadrants[q].shadows[s].alloc_tick - tick > shadow_atlas_realloc_tolerance_msec);
|
||||
|
||||
bool should_redraw = shadow_atlas->quadrants[q].shadows[s].version != p_light_version;
|
||||
|
||||
if (!should_realloc) {
|
||||
shadow_atlas->quadrants[q].shadows.write[s].version = p_light_version;
|
||||
return should_redraw;
|
||||
}
|
||||
|
||||
int new_quadrant;
|
||||
int new_shadow;
|
||||
|
||||
// find a better place
|
||||
|
||||
if (_shadow_atlas_find_shadow(shadow_atlas, valid_quadrants, valid_quadrant_count, shadow_atlas->quadrants[q].subdivision, tick, new_quadrant, new_shadow)) {
|
||||
// found a better place
|
||||
|
||||
ShadowAtlas::Quadrant::Shadow *sh = &shadow_atlas->quadrants[new_quadrant].shadows.write[new_shadow];
|
||||
if (sh->owner.is_valid()) {
|
||||
// it is take but invalid, so we can take it
|
||||
|
||||
shadow_atlas->shadow_owners.erase(sh->owner);
|
||||
}
|
||||
|
||||
// erase previous
|
||||
shadow_atlas->quadrants[q].shadows.write[s].version = 0;
|
||||
shadow_atlas->quadrants[q].shadows.write[s].owner = RID();
|
||||
|
||||
sh->owner = p_light_intance;
|
||||
sh->alloc_tick = tick;
|
||||
sh->version = p_light_version;
|
||||
|
||||
// make a new key
|
||||
key = new_quadrant << ShadowAtlas::QUADRANT_SHIFT;
|
||||
key |= new_shadow;
|
||||
|
||||
// update it in the map
|
||||
shadow_atlas->shadow_owners[p_light_intance] = key;
|
||||
|
||||
// make it dirty, so we redraw
|
||||
return true;
|
||||
}
|
||||
|
||||
// no better place found, so we keep the current place
|
||||
|
||||
shadow_atlas->quadrants[q].shadows.write[s].version = p_light_version;
|
||||
|
||||
return should_redraw;
|
||||
}
|
||||
|
||||
int new_quadrant;
|
||||
int new_shadow;
|
||||
|
||||
if (_shadow_atlas_find_shadow(shadow_atlas, valid_quadrants, valid_quadrant_count, -1, tick, new_quadrant, new_shadow)) {
|
||||
// found a better place
|
||||
|
||||
ShadowAtlas::Quadrant::Shadow *sh = &shadow_atlas->quadrants[new_quadrant].shadows.write[new_shadow];
|
||||
if (sh->owner.is_valid()) {
|
||||
// it is take but invalid, so we can take it
|
||||
|
||||
shadow_atlas->shadow_owners.erase(sh->owner);
|
||||
}
|
||||
|
||||
sh->owner = p_light_intance;
|
||||
sh->alloc_tick = tick;
|
||||
sh->version = p_light_version;
|
||||
|
||||
// make a new key
|
||||
uint32_t key = new_quadrant << ShadowAtlas::QUADRANT_SHIFT;
|
||||
key |= new_shadow;
|
||||
|
||||
// update it in the map
|
||||
shadow_atlas->shadow_owners[p_light_intance] = key;
|
||||
|
||||
// make it dirty, so we redraw
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES2::set_directional_shadow_count(int p_count) {
|
||||
directional_shadow.light_count = p_count;
|
||||
directional_shadow.current_light = 0;
|
||||
}
|
||||
|
||||
int RasterizerSceneGLES2::get_directional_light_shadow_size(RID p_light_intance) {
|
||||
ERR_FAIL_COND_V(directional_shadow.light_count == 0, 0);
|
||||
|
||||
int shadow_size;
|
||||
|
||||
if (directional_shadow.light_count == 1) {
|
||||
shadow_size = directional_shadow.size;
|
||||
} else {
|
||||
shadow_size = directional_shadow.size / 2; //more than 4 not supported anyway
|
||||
}
|
||||
|
||||
return shadow_size;
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
|
||||
void RasterizerSceneGLES2::_add_geometry(RasterizerStorageGLES2::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES2::GeometryOwner *p_owner, int p_material, bool p_depth_pass, bool p_shadow_pass) {
|
||||
void RasterizerSceneGLES2::_add_geometry(RasterizerStorageGLES2::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES2::GeometryOwner *p_owner, int p_material, bool p_depth_pass) {
|
||||
RasterizerStorageGLES2::Material *material = nullptr;
|
||||
RID material_src;
|
||||
|
||||
@ -487,7 +80,7 @@ void RasterizerSceneGLES2::_add_geometry(RasterizerStorageGLES2::Geometry *p_geo
|
||||
|
||||
ERR_FAIL_COND(!material);
|
||||
|
||||
_add_geometry_with_material(p_geometry, p_instance, p_owner, material, p_depth_pass, p_shadow_pass);
|
||||
_add_geometry_with_material(p_geometry, p_instance, p_owner, material, p_depth_pass);
|
||||
|
||||
while (material->next_pass.is_valid()) {
|
||||
material = storage->material_owner.getornull(material->next_pass);
|
||||
@ -496,7 +89,7 @@ void RasterizerSceneGLES2::_add_geometry(RasterizerStorageGLES2::Geometry *p_geo
|
||||
break;
|
||||
}
|
||||
|
||||
_add_geometry_with_material(p_geometry, p_instance, p_owner, material, p_depth_pass, p_shadow_pass);
|
||||
_add_geometry_with_material(p_geometry, p_instance, p_owner, material, p_depth_pass);
|
||||
}
|
||||
|
||||
// Repeat the "nested chain" logic also for the overlay
|
||||
@ -507,7 +100,7 @@ void RasterizerSceneGLES2::_add_geometry(RasterizerStorageGLES2::Geometry *p_geo
|
||||
return;
|
||||
}
|
||||
|
||||
_add_geometry_with_material(p_geometry, p_instance, p_owner, material, p_depth_pass, p_shadow_pass);
|
||||
_add_geometry_with_material(p_geometry, p_instance, p_owner, material, p_depth_pass);
|
||||
|
||||
while (material->next_pass.is_valid()) {
|
||||
material = storage->material_owner.getornull(material->next_pass);
|
||||
@ -516,11 +109,11 @@ void RasterizerSceneGLES2::_add_geometry(RasterizerStorageGLES2::Geometry *p_geo
|
||||
break;
|
||||
}
|
||||
|
||||
_add_geometry_with_material(p_geometry, p_instance, p_owner, material, p_depth_pass, p_shadow_pass);
|
||||
_add_geometry_with_material(p_geometry, p_instance, p_owner, material, p_depth_pass);
|
||||
}
|
||||
}
|
||||
}
|
||||
void RasterizerSceneGLES2::_add_geometry_with_material(RasterizerStorageGLES2::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES2::GeometryOwner *p_owner, RasterizerStorageGLES2::Material *p_material, bool p_depth_pass, bool p_shadow_pass) {
|
||||
void RasterizerSceneGLES2::_add_geometry_with_material(RasterizerStorageGLES2::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES2::GeometryOwner *p_owner, RasterizerStorageGLES2::Material *p_material, bool p_depth_pass) {
|
||||
bool has_base_alpha = (p_material->shader->spatial.uses_alpha && !p_material->shader->spatial.uses_alpha_scissor) || p_material->shader->spatial.uses_screen_texture || p_material->shader->spatial.uses_depth_texture;
|
||||
bool has_blend_alpha = p_material->shader->spatial.blend_mode != RasterizerStorageGLES2::Shader::Spatial::BLEND_MODE_MIX;
|
||||
bool has_alpha = has_base_alpha || has_blend_alpha;
|
||||
@ -548,12 +141,7 @@ void RasterizerSceneGLES2::_add_geometry_with_material(RasterizerStorageGLES2::G
|
||||
|
||||
if (!p_material->shader->spatial.uses_alpha_scissor && !p_material->shader->spatial.writes_modelview_or_projection && !p_material->shader->spatial.uses_vertex && !p_material->shader->spatial.uses_discard && p_material->shader->spatial.depth_draw_mode != RasterizerStorageGLES2::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) {
|
||||
//shader does not use discard and does not write a vertex position, use generic material
|
||||
if (p_instance->cast_shadows == RS::SHADOW_CASTING_SETTING_DOUBLE_SIDED) {
|
||||
p_material = storage->material_owner.getptr(!p_shadow_pass && p_material->shader->spatial.uses_world_coordinates ? default_worldcoord_material_twosided : default_material_twosided);
|
||||
mirror = false;
|
||||
} else {
|
||||
p_material = storage->material_owner.getptr(!p_shadow_pass && p_material->shader->spatial.uses_world_coordinates ? default_worldcoord_material : default_material);
|
||||
}
|
||||
p_material = storage->material_owner.getptr(p_material->shader->spatial.uses_world_coordinates ? default_worldcoord_material : default_material);
|
||||
}
|
||||
|
||||
has_alpha = false;
|
||||
@ -613,7 +201,6 @@ void RasterizerSceneGLES2::_add_geometry_with_material(RasterizerStorageGLES2::G
|
||||
//add directional lights
|
||||
|
||||
e->light_mode = LIGHTMODE_UNSHADED;
|
||||
|
||||
}
|
||||
|
||||
// do not add anything here, as lights are duplicated elements..
|
||||
@ -646,12 +233,10 @@ void RasterizerSceneGLES2::_copy_texture_to_buffer(GLuint p_texture, GLuint p_bu
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES2::_fill_render_list(InstanceBase **p_cull_result, int p_cull_count, bool p_depth_pass, bool p_shadow_pass) {
|
||||
void RasterizerSceneGLES2::_fill_render_list(InstanceBase **p_cull_result, int p_cull_count, bool p_depth_pass) {
|
||||
render_pass++;
|
||||
current_material_index = 0;
|
||||
current_geometry_index = 0;
|
||||
current_light_index = 0;
|
||||
current_refprobe_index = 0;
|
||||
current_shader_index = 0;
|
||||
|
||||
for (int i = 0; i < p_cull_count; i++) {
|
||||
@ -669,7 +254,7 @@ void RasterizerSceneGLES2::_fill_render_list(InstanceBase **p_cull_result, int p
|
||||
|
||||
RasterizerStorageGLES2::Surface *surface = mesh->surfaces[j];
|
||||
|
||||
_add_geometry(surface, instance, nullptr, material_index, p_depth_pass, p_shadow_pass);
|
||||
_add_geometry(surface, instance, nullptr, material_index, p_depth_pass);
|
||||
}
|
||||
|
||||
} break;
|
||||
@ -691,7 +276,7 @@ void RasterizerSceneGLES2::_fill_render_list(InstanceBase **p_cull_result, int p
|
||||
|
||||
for (int j = 0; j < ssize; j++) {
|
||||
RasterizerStorageGLES2::Surface *s = mesh->surfaces[j];
|
||||
_add_geometry(s, instance, multi_mesh, -1, p_depth_pass, p_shadow_pass);
|
||||
_add_geometry(s, instance, multi_mesh, -1, p_depth_pass);
|
||||
}
|
||||
} break;
|
||||
|
||||
@ -1033,9 +618,7 @@ void RasterizerSceneGLES2::_render_geometry(RenderList::Element *p_element) {
|
||||
}
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements, int p_element_count, const Transform &p_view_transform, const Projection &p_projection, const int p_eye, RID p_shadow_atlas, float p_shadow_bias, float p_shadow_normal_bias, bool p_reverse_cull, bool p_alpha_pass, bool p_shadow) {
|
||||
ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas);
|
||||
|
||||
void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements, int p_element_count, const Transform &p_view_transform, const Projection &p_projection, const int p_eye, bool p_reverse_cull, bool p_alpha_pass) {
|
||||
Vector2 viewport_size = state.viewport_size;
|
||||
|
||||
Vector2 screen_pixel_size = state.screen_pixel_size;
|
||||
@ -1083,9 +666,8 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
|
||||
bool rebind = false;
|
||||
bool accum_pass = *e->use_accum_ptr;
|
||||
*e->use_accum_ptr = true; //set to accum for next time this is found
|
||||
bool rebind_light = false;
|
||||
|
||||
if (!p_shadow && material->shader) {
|
||||
if (material->shader) {
|
||||
bool unshaded = material->shader->spatial.unshaded;
|
||||
|
||||
if (unshaded != prev_unshaded) {
|
||||
@ -1213,30 +795,17 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
|
||||
_set_cull(e->front_facing, material->shader->spatial.cull_mode == RasterizerStorageGLES2::Shader::Spatial::CULL_MODE_DISABLED, p_reverse_cull);
|
||||
|
||||
if (i == 0 || shader_rebind) { //first time must rebind
|
||||
|
||||
if (p_shadow) {
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::LIGHT_BIAS, p_shadow_bias);
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::LIGHT_NORMAL_BIAS, p_shadow_normal_bias);
|
||||
if (state.shadow_is_dual_parabolloid) {
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::SHADOW_DUAL_PARABOLOID_RENDER_SIDE, state.dual_parbolloid_direction);
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::SHADOW_DUAL_PARABOLOID_RENDER_ZFAR, state.dual_parbolloid_zfar);
|
||||
}
|
||||
} else {
|
||||
if (use_radiance_map) {
|
||||
// would be a bit weird if we don't have this...
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::RADIANCE_INVERSE_XFORM, p_view_transform);
|
||||
}
|
||||
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::BG_ENERGY, 1.0);
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::BG_COLOR, state.default_bg);
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::AMBIENT_SKY_CONTRIBUTION, 1.0);
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::AMBIENT_COLOR, state.default_ambient);
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::AMBIENT_ENERGY, 1.0);
|
||||
|
||||
//rebind all these
|
||||
rebind_light = true;
|
||||
if (use_radiance_map) {
|
||||
// would be a bit weird if we don't have this...
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::RADIANCE_INVERSE_XFORM, p_view_transform);
|
||||
}
|
||||
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::BG_ENERGY, 1.0);
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::BG_COLOR, state.default_bg);
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::AMBIENT_SKY_CONTRIBUTION, 1.0);
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::AMBIENT_COLOR, state.default_ambient);
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::AMBIENT_ENERGY, 1.0);
|
||||
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::CAMERA_MATRIX, p_view_transform);
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::CAMERA_INVERSE_MATRIX, view_transform_inverse);
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::PROJECTION_MATRIX, p_projection);
|
||||
@ -1376,7 +945,7 @@ void RasterizerSceneGLES2::_post_process(const Projection &p_cam_projection) {
|
||||
state.tonemap_shader.set_conditional(TonemapShaderGLES2::DISABLE_ALPHA, false);
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const Projection &p_cam_projection, const int p_eye, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID p_shadow_atlas) {
|
||||
void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const Projection &p_cam_projection, const int p_eye, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count) {
|
||||
Transform cam_transform = p_cam_transform;
|
||||
|
||||
storage->info.render.object_count += p_cull_count;
|
||||
@ -1422,7 +991,7 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
|
||||
// render list stuff
|
||||
|
||||
render_list.clear();
|
||||
_fill_render_list(p_cull_result, p_cull_count, false, false);
|
||||
_fill_render_list(p_cull_result, p_cull_count, false);
|
||||
|
||||
// other stuff
|
||||
|
||||
@ -1478,7 +1047,7 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
|
||||
|
||||
// render opaque things first
|
||||
render_list.sort_by_key(false);
|
||||
_render_render_list(render_list.elements, render_list.element_count, cam_transform, p_cam_projection, p_eye, p_shadow_atlas, 0.0, 0.0, reverse_cull, false, false);
|
||||
_render_render_list(render_list.elements, render_list.element_count, cam_transform, p_cam_projection, p_eye, reverse_cull, false);
|
||||
|
||||
if (storage->frame.current_rt && state.used_screen_texture) {
|
||||
//copy screen texture
|
||||
@ -1524,142 +1093,21 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
|
||||
|
||||
render_list.sort_by_reverse_depth_and_priority(true);
|
||||
|
||||
_render_render_list(&render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, cam_transform, p_cam_projection, p_eye, p_shadow_atlas, 0.0, 0.0, reverse_cull, true, false);
|
||||
_render_render_list(&render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, cam_transform, p_cam_projection, p_eye, reverse_cull, true);
|
||||
|
||||
//post process
|
||||
_post_process(p_cam_projection);
|
||||
|
||||
//#define GLES2_SHADOW_ATLAS_DEBUG_VIEW
|
||||
|
||||
#ifdef GLES2_SHADOW_ATLAS_DEBUG_VIEW
|
||||
ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas);
|
||||
if (shadow_atlas) {
|
||||
WRAPPED_GL_ACTIVE_TEXTURE(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, shadow_atlas->depth);
|
||||
|
||||
glViewport(0, 0, storage->frame.current_rt->width / 4, storage->frame.current_rt->height / 4);
|
||||
storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_CUBEMAP, false);
|
||||
storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_COPY_SECTION, false);
|
||||
storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_CUSTOM_ALPHA, false);
|
||||
storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_MULTIPLIER, false);
|
||||
storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_PANORAMA, false);
|
||||
storage->shaders.copy.bind();
|
||||
|
||||
storage->_copy_screen();
|
||||
}
|
||||
#endif
|
||||
|
||||
//#define GLES2_SHADOW_DIRECTIONAL_DEBUG_VIEW
|
||||
|
||||
#ifdef GLES2_SHADOW_DIRECTIONAL_DEBUG_VIEW
|
||||
if (true) {
|
||||
WRAPPED_GL_ACTIVE_TEXTURE(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, directional_shadow.depth);
|
||||
|
||||
glViewport(0, 0, storage->frame.current_rt->width / 4, storage->frame.current_rt->height / 4);
|
||||
storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_CUBEMAP, false);
|
||||
storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_COPY_SECTION, false);
|
||||
storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_CUSTOM_ALPHA, false);
|
||||
storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_MULTIPLIER, false);
|
||||
storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_PANORAMA, false);
|
||||
storage->shaders.copy.bind();
|
||||
|
||||
storage->_copy_screen();
|
||||
}
|
||||
#endif
|
||||
|
||||
// return to default
|
||||
state.scene_shader.set_conditional(SceneShaderGLES2::OUTPUT_LINEAR, false);
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES2::render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count) {
|
||||
state.render_no_shadows = false;
|
||||
|
||||
uint32_t x;
|
||||
uint32_t y;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
|
||||
float zfar = 0;
|
||||
bool flip_facing = false;
|
||||
int custom_vp_size = 0;
|
||||
GLuint fbo = 0;
|
||||
state.shadow_is_dual_parabolloid = false;
|
||||
state.dual_parbolloid_direction = 0.0;
|
||||
|
||||
int current_cubemap = -1;
|
||||
float bias = 0;
|
||||
float normal_bias = 0;
|
||||
|
||||
Projection light_projection;
|
||||
Transform light_transform;
|
||||
|
||||
render_list.clear();
|
||||
|
||||
_fill_render_list(p_cull_result, p_cull_count, true, true);
|
||||
|
||||
render_list.sort_by_depth(false);
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_DITHER);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
|
||||
glDepthMask(GL_TRUE);
|
||||
if (!storage->config.use_rgba_3d_shadows) {
|
||||
glColorMask(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
if (custom_vp_size) {
|
||||
glViewport(0, 0, custom_vp_size, custom_vp_size);
|
||||
glScissor(0, 0, custom_vp_size, custom_vp_size);
|
||||
} else {
|
||||
glViewport(x, y, width, height);
|
||||
glScissor(x, y, width, height);
|
||||
}
|
||||
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glClearDepth(1.0f);
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
if (storage->config.use_rgba_3d_shadows) {
|
||||
glClearColor(1.0, 1.0, 1.0, 1.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
|
||||
state.scene_shader.set_conditional(SceneShaderGLES2::RENDER_DEPTH, true);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES2::OUTPUT_LINEAR, false); // just in case, should be false already
|
||||
|
||||
_render_render_list(render_list.elements, render_list.element_count, light_transform, light_projection, 0, RID(), bias, normal_bias, flip_facing, false, true);
|
||||
|
||||
state.scene_shader.set_conditional(SceneShaderGLES2::RENDER_DEPTH, false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES2::RENDER_DEPTH_DUAL_PARABOLOID, false);
|
||||
|
||||
if (storage->frame.current_rt) {
|
||||
glViewport(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height);
|
||||
}
|
||||
if (!storage->config.use_rgba_3d_shadows) {
|
||||
glColorMask(1, 1, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES2::set_scene_pass(uint64_t p_pass) {
|
||||
scene_pass = p_pass;
|
||||
}
|
||||
|
||||
bool RasterizerSceneGLES2::free(RID p_rid) {
|
||||
if (shadow_atlas_owner.owns(p_rid)) {
|
||||
ShadowAtlas *shadow_atlas = shadow_atlas_owner.get(p_rid);
|
||||
shadow_atlas_set_size(p_rid, 0);
|
||||
shadow_atlas_owner.free(p_rid);
|
||||
memdelete(shadow_atlas);
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES2::set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw) {
|
||||
@ -1677,8 +1125,6 @@ void RasterizerSceneGLES2::initialize() {
|
||||
|
||||
render_pass = 1;
|
||||
|
||||
shadow_atlas_realloc_tolerance_msec = 500;
|
||||
|
||||
{
|
||||
//default material and shader
|
||||
|
||||
@ -1732,67 +1178,16 @@ void RasterizerSceneGLES2::initialize() {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
// cubemaps for shadows
|
||||
if (storage->config.support_shadow_cubemaps) { //not going to be used
|
||||
int max_shadow_cubemap_sampler_size = MIN(int(GLOBAL_GET("rendering/quality/shadow_atlas/cubemap_size")), storage->config.max_cubemap_texture_size);
|
||||
|
||||
int cube_size = max_shadow_cubemap_sampler_size;
|
||||
|
||||
WRAPPED_GL_ACTIVE_TEXTURE(GL_TEXTURE0);
|
||||
|
||||
while (cube_size >= 32) {
|
||||
ShadowCubeMap cube;
|
||||
|
||||
cube.size = cube_size;
|
||||
|
||||
glGenTextures(1, &cube.cubemap);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, cube.cubemap);
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
glTexImage2D(_cube_side_enum[i], 0, storage->config.depth_internalformat, cube_size, cube_size, 0, GL_DEPTH_COMPONENT, storage->config.depth_type, nullptr);
|
||||
}
|
||||
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
glGenFramebuffers(6, cube.fbo);
|
||||
for (int i = 0; i < 6; i++) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, cube.fbo[i]);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, _cube_side_enum[i], cube.cubemap, 0);
|
||||
}
|
||||
|
||||
shadow_cubemaps.push_back(cube);
|
||||
|
||||
cube_size >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
directional_shadow_create();
|
||||
|
||||
shadow_filter_mode = SHADOW_FILTER_NEAREST;
|
||||
|
||||
glFrontFace(GL_CW);
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES2::iteration() {
|
||||
shadow_filter_mode = ShadowFilterMode(int(GLOBAL_GET("rendering/quality/shadows/filter_mode")));
|
||||
|
||||
const int directional_shadow_size_new = next_power_of_2(int(GLOBAL_GET("rendering/quality/directional_shadow/size")));
|
||||
if (directional_shadow_size != directional_shadow_size_new) {
|
||||
directional_shadow_size = directional_shadow_size_new;
|
||||
directional_shadow_create();
|
||||
}
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES2::finalize() {
|
||||
}
|
||||
|
||||
RasterizerSceneGLES2::RasterizerSceneGLES2() {
|
||||
_light_counter = 0;
|
||||
directional_shadow_size = next_power_of_2(int(GLOBAL_GET("rendering/quality/directional_shadow/size")));
|
||||
}
|
||||
|
||||
RasterizerSceneGLES2::~RasterizerSceneGLES2() {
|
||||
|
@ -53,19 +53,11 @@
|
||||
|
||||
class RasterizerSceneGLES2 : public RasterizerScene {
|
||||
public:
|
||||
enum ShadowFilterMode {
|
||||
SHADOW_FILTER_NEAREST,
|
||||
SHADOW_FILTER_PCF5,
|
||||
SHADOW_FILTER_PCF13,
|
||||
};
|
||||
|
||||
enum {
|
||||
INSTANCE_ATTRIB_BASE = 8,
|
||||
INSTANCE_BONE_BASE = 13,
|
||||
};
|
||||
|
||||
ShadowFilterMode shadow_filter_mode;
|
||||
|
||||
RID default_material;
|
||||
RID default_material_twosided;
|
||||
RID default_shader;
|
||||
@ -84,7 +76,6 @@ public:
|
||||
uint32_t current_material_index;
|
||||
uint32_t current_geometry_index;
|
||||
uint32_t current_light_index;
|
||||
uint32_t current_refprobe_index;
|
||||
uint32_t current_shader_index;
|
||||
|
||||
private:
|
||||
@ -128,83 +119,6 @@ public:
|
||||
Vector2 screen_pixel_size;
|
||||
} state;
|
||||
|
||||
/* SHADOW ATLAS API */
|
||||
|
||||
uint64_t shadow_atlas_realloc_tolerance_msec;
|
||||
|
||||
struct ShadowAtlas : public RID_Data {
|
||||
enum {
|
||||
QUADRANT_SHIFT = 27,
|
||||
SHADOW_INDEX_MASK = (1 << QUADRANT_SHIFT) - 1,
|
||||
SHADOW_INVALID = 0xFFFFFFFF,
|
||||
};
|
||||
|
||||
struct Quadrant {
|
||||
uint32_t subdivision;
|
||||
|
||||
struct Shadow {
|
||||
RID owner;
|
||||
uint64_t version;
|
||||
uint64_t alloc_tick;
|
||||
|
||||
Shadow() {
|
||||
version = 0;
|
||||
alloc_tick = 0;
|
||||
}
|
||||
};
|
||||
|
||||
Vector<Shadow> shadows;
|
||||
|
||||
Quadrant() {
|
||||
subdivision = 0;
|
||||
}
|
||||
} quadrants[4];
|
||||
|
||||
int size_order[4];
|
||||
uint32_t smallest_subdiv;
|
||||
|
||||
int size;
|
||||
|
||||
GLuint fbo;
|
||||
GLuint depth;
|
||||
GLuint color;
|
||||
|
||||
RBMap<RID, uint32_t> shadow_owners;
|
||||
};
|
||||
|
||||
struct ShadowCubeMap {
|
||||
GLuint fbo[6];
|
||||
GLuint cubemap;
|
||||
uint32_t size;
|
||||
};
|
||||
|
||||
Vector<ShadowCubeMap> shadow_cubemaps;
|
||||
|
||||
RID_Owner<ShadowAtlas> shadow_atlas_owner;
|
||||
|
||||
int directional_shadow_size;
|
||||
|
||||
void directional_shadow_create();
|
||||
|
||||
RID shadow_atlas_create();
|
||||
void shadow_atlas_set_size(RID p_atlas, int p_size);
|
||||
void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision);
|
||||
bool _shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int *p_in_quadrants, int p_quadrant_count, int p_current_subdiv, uint64_t p_tick, int &r_quadrant, int &r_shadow);
|
||||
bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version);
|
||||
|
||||
struct DirectionalShadow {
|
||||
GLuint fbo = 0;
|
||||
GLuint depth = 0;
|
||||
GLuint color = 0;
|
||||
|
||||
int light_count = 0;
|
||||
int size = 0;
|
||||
int current_light = 0;
|
||||
} directional_shadow;
|
||||
|
||||
virtual int get_directional_light_shadow_size(RID p_light_intance);
|
||||
virtual void set_directional_shadow_count(int p_count);
|
||||
|
||||
/* RENDER LIST */
|
||||
|
||||
enum LightMode {
|
||||
@ -377,21 +291,17 @@ public:
|
||||
|
||||
RenderList render_list;
|
||||
|
||||
void _add_geometry(RasterizerStorageGLES2::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES2::GeometryOwner *p_owner, int p_material, bool p_depth_pass, bool p_shadow_pass);
|
||||
void _add_geometry_with_material(RasterizerStorageGLES2::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES2::GeometryOwner *p_owner, RasterizerStorageGLES2::Material *p_material, bool p_depth_pass, bool p_shadow_pass);
|
||||
void _add_geometry(RasterizerStorageGLES2::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES2::GeometryOwner *p_owner, int p_material, bool p_depth_pass);
|
||||
void _add_geometry_with_material(RasterizerStorageGLES2::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES2::GeometryOwner *p_owner, RasterizerStorageGLES2::Material *p_material, bool p_depth_pass);
|
||||
|
||||
void _copy_texture_to_buffer(GLuint p_texture, GLuint p_buffer);
|
||||
void _fill_render_list(InstanceBase **p_cull_result, int p_cull_count, bool p_depth_pass, bool p_shadow_pass);
|
||||
void _fill_render_list(InstanceBase **p_cull_result, int p_cull_count, bool p_depth_pass);
|
||||
void _render_render_list(RenderList::Element **p_elements, int p_element_count,
|
||||
const Transform &p_view_transform,
|
||||
const Projection &p_projection,
|
||||
const int p_eye,
|
||||
RID p_shadow_atlas,
|
||||
float p_shadow_bias,
|
||||
float p_shadow_normal_bias,
|
||||
bool p_reverse_cull,
|
||||
bool p_alpha_pass,
|
||||
bool p_shadow);
|
||||
bool p_alpha_pass);
|
||||
|
||||
_FORCE_INLINE_ void _set_cull(bool p_front, bool p_disabled, bool p_reverse_cull);
|
||||
_FORCE_INLINE_ bool _setup_material(RasterizerStorageGLES2::Material *p_material, bool p_alpha_pass, Size2i p_skeleton_tex_size = Size2i(0, 0));
|
||||
@ -400,8 +310,7 @@ public:
|
||||
|
||||
void _post_process(const Projection &p_cam_projection);
|
||||
|
||||
virtual void render_scene(const Transform &p_cam_transform, const Projection &p_cam_projection, const int p_eye, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID p_shadow_atlas);
|
||||
virtual void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count);
|
||||
virtual void render_scene(const Transform &p_cam_transform, const Projection &p_cam_projection, const int p_eye, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count);
|
||||
virtual bool free(RID p_rid);
|
||||
|
||||
virtual void set_scene_pass(uint64_t p_pass);
|
||||
|
@ -2002,17 +2002,6 @@ bool Main::start() {
|
||||
// It can still be overridden by the user in a script.
|
||||
OS::get_singleton()->set_min_window_size(Size2(64, 64));
|
||||
|
||||
int shadow_atlas_size = GLOBAL_GET("rendering/quality/shadow_atlas/size");
|
||||
int shadow_atlas_q0_subdiv = GLOBAL_GET("rendering/quality/shadow_atlas/quadrant_0_subdiv");
|
||||
int shadow_atlas_q1_subdiv = GLOBAL_GET("rendering/quality/shadow_atlas/quadrant_1_subdiv");
|
||||
int shadow_atlas_q2_subdiv = GLOBAL_GET("rendering/quality/shadow_atlas/quadrant_2_subdiv");
|
||||
int shadow_atlas_q3_subdiv = GLOBAL_GET("rendering/quality/shadow_atlas/quadrant_3_subdiv");
|
||||
|
||||
sml->get_root()->set_shadow_atlas_size(shadow_atlas_size);
|
||||
sml->get_root()->set_shadow_atlas_quadrant_subdiv(0, Viewport::ShadowAtlasQuadrantSubdiv(shadow_atlas_q0_subdiv));
|
||||
sml->get_root()->set_shadow_atlas_quadrant_subdiv(1, Viewport::ShadowAtlasQuadrantSubdiv(shadow_atlas_q1_subdiv));
|
||||
sml->get_root()->set_shadow_atlas_quadrant_subdiv(2, Viewport::ShadowAtlasQuadrantSubdiv(shadow_atlas_q2_subdiv));
|
||||
sml->get_root()->set_shadow_atlas_quadrant_subdiv(3, Viewport::ShadowAtlasQuadrantSubdiv(shadow_atlas_q3_subdiv));
|
||||
Viewport::Usage usage = Viewport::Usage(int(GLOBAL_GET("rendering/quality/intended_usage/framebuffer_allocation")));
|
||||
sml->get_root()->set_usage(usage);
|
||||
|
||||
|
@ -892,36 +892,6 @@ Viewport::ClearMode Viewport::get_clear_mode() const {
|
||||
return clear_mode;
|
||||
}
|
||||
|
||||
void Viewport::set_shadow_atlas_size(int p_size) {
|
||||
if (shadow_atlas_size == p_size) {
|
||||
return;
|
||||
}
|
||||
|
||||
shadow_atlas_size = p_size;
|
||||
RS::get_singleton()->viewport_set_shadow_atlas_size(viewport, p_size);
|
||||
}
|
||||
|
||||
int Viewport::get_shadow_atlas_size() const {
|
||||
return shadow_atlas_size;
|
||||
}
|
||||
|
||||
void Viewport::set_shadow_atlas_quadrant_subdiv(int p_quadrant, ShadowAtlasQuadrantSubdiv p_subdiv) {
|
||||
ERR_FAIL_INDEX(p_quadrant, 4);
|
||||
ERR_FAIL_INDEX(p_subdiv, SHADOW_ATLAS_QUADRANT_SUBDIV_MAX);
|
||||
|
||||
if (shadow_atlas_quadrant_subdiv[p_quadrant] == p_subdiv) {
|
||||
return;
|
||||
}
|
||||
|
||||
shadow_atlas_quadrant_subdiv[p_quadrant] = p_subdiv;
|
||||
static const int subdiv[SHADOW_ATLAS_QUADRANT_SUBDIV_MAX] = { 0, 1, 4, 16, 64, 256, 1024 };
|
||||
|
||||
RS::get_singleton()->viewport_set_shadow_atlas_quadrant_subdivision(viewport, p_quadrant, subdiv[p_subdiv]);
|
||||
}
|
||||
Viewport::ShadowAtlasQuadrantSubdiv Viewport::get_shadow_atlas_quadrant_subdiv(int p_quadrant) const {
|
||||
ERR_FAIL_INDEX_V(p_quadrant, 4, SHADOW_ATLAS_QUADRANT_SUBDIV_DISABLED);
|
||||
return shadow_atlas_quadrant_subdiv[p_quadrant];
|
||||
}
|
||||
|
||||
Transform2D Viewport::_get_input_pre_xform() const {
|
||||
Transform2D pre_xf;
|
||||
@ -2821,15 +2791,9 @@ void Viewport::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("_gui_remove_focus"), &Viewport::_gui_remove_focus);
|
||||
ClassDB::bind_method(D_METHOD("_post_gui_grab_click_focus"), &Viewport::_post_gui_grab_click_focus);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_shadow_atlas_size", "size"), &Viewport::set_shadow_atlas_size);
|
||||
ClassDB::bind_method(D_METHOD("get_shadow_atlas_size"), &Viewport::get_shadow_atlas_size);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_snap_controls_to_pixels", "enabled"), &Viewport::set_snap_controls_to_pixels);
|
||||
ClassDB::bind_method(D_METHOD("is_snap_controls_to_pixels_enabled"), &Viewport::is_snap_controls_to_pixels_enabled);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_shadow_atlas_quadrant_subdiv", "quadrant", "subdiv"), &Viewport::set_shadow_atlas_quadrant_subdiv);
|
||||
ClassDB::bind_method(D_METHOD("get_shadow_atlas_quadrant_subdiv", "quadrant"), &Viewport::get_shadow_atlas_quadrant_subdiv);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_input_as_handled"), &Viewport::set_input_as_handled);
|
||||
ClassDB::bind_method(D_METHOD("is_input_handled"), &Viewport::is_input_handled);
|
||||
|
||||
@ -2874,12 +2838,6 @@ void Viewport::_bind_methods() {
|
||||
ADD_GROUP("GUI", "gui_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "gui_disable_input"), "set_disable_input", "is_input_disabled");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "gui_snap_controls_to_pixels"), "set_snap_controls_to_pixels", "is_snap_controls_to_pixels_enabled");
|
||||
ADD_GROUP("Shadow Atlas", "shadow_atlas_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_atlas_size", PROPERTY_HINT_RANGE, "0,16384,256"), "set_shadow_atlas_size", "get_shadow_atlas_size");
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::INT, "shadow_atlas_quad_0", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), "set_shadow_atlas_quadrant_subdiv", "get_shadow_atlas_quadrant_subdiv", 0);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::INT, "shadow_atlas_quad_1", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), "set_shadow_atlas_quadrant_subdiv", "get_shadow_atlas_quadrant_subdiv", 1);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::INT, "shadow_atlas_quad_2", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), "set_shadow_atlas_quadrant_subdiv", "get_shadow_atlas_quadrant_subdiv", 2);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::INT, "shadow_atlas_quad_3", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), "set_shadow_atlas_quadrant_subdiv", "get_shadow_atlas_quadrant_subdiv", 3);
|
||||
|
||||
ADD_SIGNAL(MethodInfo("size_changed"));
|
||||
ADD_SIGNAL(MethodInfo("gui_focus_changed", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Control")));
|
||||
@ -2889,15 +2847,6 @@ void Viewport::_bind_methods() {
|
||||
BIND_ENUM_CONSTANT(UPDATE_WHEN_VISIBLE);
|
||||
BIND_ENUM_CONSTANT(UPDATE_ALWAYS);
|
||||
|
||||
BIND_ENUM_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_DISABLED);
|
||||
BIND_ENUM_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_1);
|
||||
BIND_ENUM_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_4);
|
||||
BIND_ENUM_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_16);
|
||||
BIND_ENUM_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_64);
|
||||
BIND_ENUM_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_256);
|
||||
BIND_ENUM_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_1024);
|
||||
BIND_ENUM_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_MAX);
|
||||
|
||||
BIND_ENUM_CONSTANT(RENDER_INFO_OBJECTS_IN_FRAME);
|
||||
BIND_ENUM_CONSTANT(RENDER_INFO_VERTICES_IN_FRAME);
|
||||
BIND_ENUM_CONSTANT(RENDER_INFO_MATERIAL_CHANGES_IN_FRAME);
|
||||
@ -2999,15 +2948,6 @@ Viewport::Viewport() {
|
||||
physics_has_last_mousepos = false;
|
||||
physics_last_mousepos = Vector2(Math_INF, Math_INF);
|
||||
|
||||
shadow_atlas_size = 0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
shadow_atlas_quadrant_subdiv[i] = SHADOW_ATLAS_QUADRANT_SUBDIV_MAX;
|
||||
}
|
||||
set_shadow_atlas_quadrant_subdiv(0, SHADOW_ATLAS_QUADRANT_SUBDIV_4);
|
||||
set_shadow_atlas_quadrant_subdiv(1, SHADOW_ATLAS_QUADRANT_SUBDIV_4);
|
||||
set_shadow_atlas_quadrant_subdiv(2, SHADOW_ATLAS_QUADRANT_SUBDIV_16);
|
||||
set_shadow_atlas_quadrant_subdiv(3, SHADOW_ATLAS_QUADRANT_SUBDIV_64);
|
||||
|
||||
String id = itos(get_instance_id());
|
||||
input_group = "_vp_input" + id;
|
||||
gui_input_group = "_vp_gui_input" + id;
|
||||
|
@ -97,18 +97,6 @@ public:
|
||||
UPDATE_ALWAYS
|
||||
};
|
||||
|
||||
enum ShadowAtlasQuadrantSubdiv {
|
||||
SHADOW_ATLAS_QUADRANT_SUBDIV_DISABLED,
|
||||
SHADOW_ATLAS_QUADRANT_SUBDIV_1,
|
||||
SHADOW_ATLAS_QUADRANT_SUBDIV_4,
|
||||
SHADOW_ATLAS_QUADRANT_SUBDIV_16,
|
||||
SHADOW_ATLAS_QUADRANT_SUBDIV_64,
|
||||
SHADOW_ATLAS_QUADRANT_SUBDIV_256,
|
||||
SHADOW_ATLAS_QUADRANT_SUBDIV_1024,
|
||||
SHADOW_ATLAS_QUADRANT_SUBDIV_MAX,
|
||||
|
||||
};
|
||||
|
||||
enum MSAA {
|
||||
MSAA_DISABLED,
|
||||
MSAA_2X,
|
||||
@ -202,12 +190,6 @@ public:
|
||||
UpdateMode get_update_mode() const;
|
||||
Ref<ViewportTexture> get_texture() const;
|
||||
|
||||
void set_shadow_atlas_size(int p_size);
|
||||
int get_shadow_atlas_size() const;
|
||||
|
||||
void set_shadow_atlas_quadrant_subdiv(int p_quadrant, ShadowAtlasQuadrantSubdiv p_subdiv);
|
||||
ShadowAtlasQuadrantSubdiv get_shadow_atlas_quadrant_subdiv(int p_quadrant) const;
|
||||
|
||||
void set_msaa(MSAA p_msaa);
|
||||
MSAA get_msaa() const;
|
||||
|
||||
@ -391,9 +373,6 @@ private:
|
||||
|
||||
Usage usage;
|
||||
|
||||
int shadow_atlas_size;
|
||||
ShadowAtlasQuadrantSubdiv shadow_atlas_quadrant_subdiv[4];
|
||||
|
||||
MSAA msaa;
|
||||
bool use_fxaa;
|
||||
bool use_debanding;
|
||||
@ -524,7 +503,6 @@ private:
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(Viewport::UpdateMode);
|
||||
VARIANT_ENUM_CAST(Viewport::ShadowAtlasQuadrantSubdiv);
|
||||
VARIANT_ENUM_CAST(Viewport::MSAA);
|
||||
VARIANT_ENUM_CAST(Viewport::Usage);
|
||||
VARIANT_ENUM_CAST(Viewport::DebugDraw);
|
||||
|
@ -38,16 +38,6 @@
|
||||
|
||||
class RasterizerScene {
|
||||
public:
|
||||
/* SHADOW ATLAS API */
|
||||
|
||||
virtual RID shadow_atlas_create() = 0;
|
||||
virtual void shadow_atlas_set_size(RID p_atlas, int p_size) = 0;
|
||||
virtual void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) = 0;
|
||||
virtual bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) = 0;
|
||||
|
||||
virtual int get_directional_light_shadow_size(RID p_light_intance) = 0;
|
||||
virtual void set_directional_shadow_count(int p_count) = 0;
|
||||
|
||||
struct InstanceBase : RID_Data {
|
||||
RS::InstanceType base_type;
|
||||
RID base;
|
||||
@ -76,8 +66,6 @@ public:
|
||||
|
||||
PoolVector<float> blend_values;
|
||||
|
||||
RS::ShadowCastingSetting cast_shadows;
|
||||
|
||||
//fit in 32 bits
|
||||
bool mirror : 1;
|
||||
bool receive_shadows : 1;
|
||||
@ -103,7 +91,6 @@ public:
|
||||
InstanceBase() :
|
||||
dependency_item(this) {
|
||||
base_type = RS::INSTANCE_NONE;
|
||||
cast_shadows = RS::SHADOW_CASTING_SETTING_ON;
|
||||
receive_shadows = true;
|
||||
visible = true;
|
||||
depth_layer = 0;
|
||||
@ -118,8 +105,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
virtual void render_scene(const Transform &p_cam_transform, const Projection &p_cam_projection, const int p_eye, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID p_shadow_atlas) = 0;
|
||||
virtual void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count) = 0;
|
||||
virtual void render_scene(const Transform &p_cam_transform, const Projection &p_cam_projection, const int p_eye, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count) = 0;
|
||||
|
||||
virtual void set_scene_pass(uint64_t p_pass) = 0;
|
||||
virtual void set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw) = 0;
|
||||
|
@ -339,8 +339,6 @@ public:
|
||||
|
||||
BIND2(viewport_set_global_canvas_transform, RID, const Transform2D &)
|
||||
BIND4(viewport_set_canvas_stacking, RID, RID, int, int)
|
||||
BIND2(viewport_set_shadow_atlas_size, RID, int)
|
||||
BIND3(viewport_set_shadow_atlas_quadrant_subdivision, RID, int, int)
|
||||
BIND2(viewport_set_msaa, RID, ViewportMSAA)
|
||||
BIND2(viewport_set_use_fxaa, RID, bool)
|
||||
BIND2(viewport_set_use_debanding, RID, bool)
|
||||
@ -362,9 +360,6 @@ public:
|
||||
BIND0R(RID, scenario_create)
|
||||
|
||||
BIND2(scenario_set_debug, RID, ScenarioDebugMode)
|
||||
BIND2(scenario_set_environment, RID, RID)
|
||||
BIND3(scenario_set_reflection_atlas_size, RID, int, int)
|
||||
BIND2(scenario_set_fallback_environment, RID, RID)
|
||||
|
||||
/* INSTANCING API */
|
||||
|
||||
@ -398,7 +393,6 @@ public:
|
||||
BIND2RC(Vector<ObjectID>, instances_cull_convex, const Vector<Plane> &, RID)
|
||||
|
||||
BIND3(instance_geometry_set_flag, RID, InstanceFlags, bool)
|
||||
BIND2(instance_geometry_set_cast_shadows_setting, RID, ShadowCastingSetting)
|
||||
BIND2(instance_geometry_set_material_override, RID, RID)
|
||||
BIND2(instance_geometry_set_material_overlay, RID, RID)
|
||||
|
||||
|
@ -328,13 +328,6 @@ RID RenderingServerScene::scenario_create() {
|
||||
scenario->sps->set_pair_callback(_instance_pair, this);
|
||||
scenario->sps->set_unpair_callback(_instance_unpair, this);
|
||||
|
||||
scenario->shadow_atlas = RSG::scene_render->shadow_atlas_create();
|
||||
RSG::scene_render->shadow_atlas_set_size(scenario->shadow_atlas, 1024); //make enough shadows for close distance, don't bother with rest
|
||||
RSG::scene_render->shadow_atlas_set_quadrant_subdivision(scenario->shadow_atlas, 0, 4);
|
||||
RSG::scene_render->shadow_atlas_set_quadrant_subdivision(scenario->shadow_atlas, 1, 4);
|
||||
RSG::scene_render->shadow_atlas_set_quadrant_subdivision(scenario->shadow_atlas, 2, 4);
|
||||
RSG::scene_render->shadow_atlas_set_quadrant_subdivision(scenario->shadow_atlas, 3, 8);
|
||||
|
||||
return scenario_rid;
|
||||
}
|
||||
|
||||
@ -363,21 +356,6 @@ void RenderingServerScene::scenario_set_debug(RID p_scenario, RS::ScenarioDebugM
|
||||
scenario->debug = p_debug_mode;
|
||||
}
|
||||
|
||||
void RenderingServerScene::scenario_set_environment(RID p_scenario, RID p_environment) {
|
||||
Scenario *scenario = scenario_owner.get(p_scenario);
|
||||
ERR_FAIL_COND(!scenario);
|
||||
scenario->environment = p_environment;
|
||||
}
|
||||
|
||||
void RenderingServerScene::scenario_set_fallback_environment(RID p_scenario, RID p_environment) {
|
||||
Scenario *scenario = scenario_owner.get(p_scenario);
|
||||
ERR_FAIL_COND(!scenario);
|
||||
scenario->fallback_environment = p_environment;
|
||||
}
|
||||
|
||||
void RenderingServerScene::scenario_set_reflection_atlas_size(RID p_scenario, int p_size, int p_subdiv) {
|
||||
}
|
||||
|
||||
/* INSTANCING API */
|
||||
|
||||
void RenderingServerScene::_instance_queue_update(Instance *p_instance, bool p_update_aabb, bool p_update_materials) {
|
||||
@ -1019,13 +997,6 @@ void RenderingServerScene::instance_geometry_set_flag(RID p_instance, RS::Instan
|
||||
}
|
||||
}
|
||||
}
|
||||
void RenderingServerScene::instance_geometry_set_cast_shadows_setting(RID p_instance, RS::ShadowCastingSetting p_shadow_casting_setting) {
|
||||
Instance *instance = instance_owner.get(p_instance);
|
||||
ERR_FAIL_COND(!instance);
|
||||
|
||||
instance->cast_shadows = p_shadow_casting_setting;
|
||||
instance->base_changed(false, true); // to actually compute if shadows are visible or not
|
||||
}
|
||||
void RenderingServerScene::instance_geometry_set_material_override(RID p_instance, RID p_material) {
|
||||
Instance *instance = instance_owner.get(p_instance);
|
||||
ERR_FAIL_COND(!instance);
|
||||
@ -1176,80 +1147,47 @@ void RenderingServerScene::_update_dirty_instance(Instance *p_instance) {
|
||||
if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
|
||||
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data);
|
||||
|
||||
bool can_cast_shadows = true;
|
||||
bool is_animated = false;
|
||||
|
||||
if (p_instance->cast_shadows == RS::SHADOW_CASTING_SETTING_OFF) {
|
||||
can_cast_shadows = false;
|
||||
} else if (p_instance->material_override.is_valid()) {
|
||||
can_cast_shadows = RSG::storage->material_casts_shadows(p_instance->material_override);
|
||||
if (p_instance->material_override.is_valid()) {
|
||||
is_animated = RSG::storage->material_is_animated(p_instance->material_override);
|
||||
} else {
|
||||
if (p_instance->base_type == RS::INSTANCE_MESH) {
|
||||
RID mesh = p_instance->base;
|
||||
|
||||
if (mesh.is_valid()) {
|
||||
bool cast_shadows = false;
|
||||
|
||||
for (int i = 0; i < p_instance->materials.size(); i++) {
|
||||
RID mat = p_instance->materials[i].is_valid() ? p_instance->materials[i] : RSG::storage->mesh_surface_get_material(mesh, i);
|
||||
|
||||
if (!mat.is_valid()) {
|
||||
cast_shadows = true;
|
||||
} else {
|
||||
if (RSG::storage->material_casts_shadows(mat)) {
|
||||
cast_shadows = true;
|
||||
}
|
||||
|
||||
if (mat.is_valid()) {
|
||||
if (RSG::storage->material_is_animated(mat)) {
|
||||
is_animated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!cast_shadows) {
|
||||
can_cast_shadows = false;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (p_instance->base_type == RS::INSTANCE_MULTIMESH) {
|
||||
RID mesh = RSG::storage->multimesh_get_mesh(p_instance->base);
|
||||
if (mesh.is_valid()) {
|
||||
bool cast_shadows = false;
|
||||
|
||||
int sc = RSG::storage->mesh_get_surface_count(mesh);
|
||||
for (int i = 0; i < sc; i++) {
|
||||
RID mat = RSG::storage->mesh_surface_get_material(mesh, i);
|
||||
|
||||
if (!mat.is_valid()) {
|
||||
cast_shadows = true;
|
||||
|
||||
} else {
|
||||
if (RSG::storage->material_casts_shadows(mat)) {
|
||||
cast_shadows = true;
|
||||
}
|
||||
if (mat.is_valid()) {
|
||||
if (RSG::storage->material_is_animated(mat)) {
|
||||
is_animated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!cast_shadows) {
|
||||
can_cast_shadows = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (p_instance->material_overlay.is_valid()) {
|
||||
can_cast_shadows = can_cast_shadows || RSG::storage->material_casts_shadows(p_instance->material_overlay);
|
||||
is_animated = is_animated || RSG::storage->material_is_animated(p_instance->material_overlay);
|
||||
}
|
||||
|
||||
if (can_cast_shadows != geom->can_cast_shadows) {
|
||||
geom->can_cast_shadows = can_cast_shadows;
|
||||
}
|
||||
|
||||
geom->material_is_animated = is_animated;
|
||||
}
|
||||
}
|
||||
@ -1262,7 +1200,7 @@ void RenderingServerScene::_update_dirty_instance(Instance *p_instance) {
|
||||
p_instance->update_materials = false;
|
||||
}
|
||||
|
||||
void RenderingServerScene::render_camera(RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas) {
|
||||
void RenderingServerScene::render_camera(RID p_camera, RID p_scenario, Size2 p_viewport_size) {
|
||||
// render to mono camera
|
||||
#ifndef _3D_DISABLED
|
||||
|
||||
@ -1307,18 +1245,16 @@ void RenderingServerScene::render_camera(RID p_camera, RID p_scenario, Size2 p_v
|
||||
|
||||
Transform camera_transform = _interpolation_data.interpolation_enabled ? camera->get_transform_interpolated() : camera->transform;
|
||||
|
||||
_prepare_scene(camera_transform, camera_matrix, ortho, camera->env, camera->visible_layers, p_scenario, p_shadow_atlas, RID(), camera->previous_room_id_hint);
|
||||
_render_scene(camera_transform, camera_matrix, 0, ortho, camera->env, p_scenario, p_shadow_atlas);
|
||||
_prepare_scene(camera_transform, camera_matrix, ortho, camera->env, camera->visible_layers, p_scenario, camera->previous_room_id_hint);
|
||||
_render_scene(camera_transform, camera_matrix, 0, ortho, camera->env, p_scenario);
|
||||
#endif
|
||||
}
|
||||
|
||||
void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, RID p_force_environment, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, int32_t &r_previous_room_id_hint) {
|
||||
void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, RID p_force_environment, uint32_t p_visible_layers, RID p_scenario, int32_t &r_previous_room_id_hint) {
|
||||
// Note, in stereo rendering:
|
||||
// - p_cam_transform will be a transform in the middle of our two eyes
|
||||
// - p_cam_projection is a wider frustrum that encompasses both eyes
|
||||
|
||||
Scenario *scenario = scenario_owner.getornull(p_scenario);
|
||||
|
||||
render_pass++;
|
||||
uint32_t camera_layer_mask = p_visible_layers;
|
||||
|
||||
@ -1333,7 +1269,6 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const
|
||||
|
||||
/* STEP 2 - CULL */
|
||||
instance_cull_count = 0;
|
||||
light_cull_count = 0;
|
||||
|
||||
//light_samplers_culled=0;
|
||||
|
||||
@ -1356,7 +1291,7 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const
|
||||
|
||||
if ((camera_layer_mask & ins->layer_mask) == 0) {
|
||||
//failure
|
||||
} else if (((1 << ins->base_type) & RS::INSTANCE_GEOMETRY_MASK) && ins->visible && ins->cast_shadows != RS::SHADOW_CASTING_SETTING_SHADOWS_ONLY) {
|
||||
} else if (((1 << ins->base_type) & RS::INSTANCE_GEOMETRY_MASK) && ins->visible) {
|
||||
keep = true;
|
||||
|
||||
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(ins->base_data);
|
||||
@ -1366,7 +1301,6 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const
|
||||
}
|
||||
|
||||
if (geom->lighting_dirty) {
|
||||
int l = 0;
|
||||
//only called when lights AABB enter/exit this geometry
|
||||
ins->light_instances.resize(geom->lighting.size());
|
||||
geom->lighting_dirty = false;
|
||||
@ -1387,14 +1321,11 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const
|
||||
|
||||
/* STEP 5 - PROCESS LIGHTS */
|
||||
|
||||
RID *directional_light_ptr = &light_instance_cull_result[light_cull_count];
|
||||
directional_light_count = 0;
|
||||
|
||||
// Calculate instance->depth from the camera, after shadow calculation has stopped overwriting instance->depth
|
||||
for (int i = 0; i < instance_cull_count; i++) {
|
||||
Instance *ins = instance_cull_result[i];
|
||||
|
||||
if (((1 << ins->base_type) & RS::INSTANCE_GEOMETRY_MASK) && ins->visible && ins->cast_shadows != RS::SHADOW_CASTING_SETTING_SHADOWS_ONLY) {
|
||||
if (((1 << ins->base_type) & RS::INSTANCE_GEOMETRY_MASK) && ins->visible) {
|
||||
Vector3 center = ins->transform.origin;
|
||||
if (ins->use_aabb_center) {
|
||||
center = ins->transformed_aabb.position + (ins->transformed_aabb.size * 0.5);
|
||||
@ -1409,37 +1340,15 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const
|
||||
}
|
||||
}
|
||||
|
||||
void RenderingServerScene::_render_scene(const Transform p_cam_transform, const Projection &p_cam_projection, const int p_eye, bool p_cam_orthogonal, RID p_force_environment, RID p_scenario, RID p_shadow_atlas) {
|
||||
Scenario *scenario = scenario_owner.getornull(p_scenario);
|
||||
|
||||
/* ENVIRONMENT */
|
||||
|
||||
RID environment;
|
||||
if (p_force_environment.is_valid()) { //camera has more environment priority
|
||||
environment = p_force_environment;
|
||||
} else if (scenario->environment.is_valid()) {
|
||||
environment = scenario->environment;
|
||||
} else {
|
||||
environment = scenario->fallback_environment;
|
||||
}
|
||||
|
||||
void RenderingServerScene::_render_scene(const Transform p_cam_transform, const Projection &p_cam_projection, const int p_eye, bool p_cam_orthogonal, RID p_force_environment, RID p_scenario) {
|
||||
/* PROCESS GEOMETRY AND DRAW SCENE */
|
||||
|
||||
RSG::scene_render->render_scene(p_cam_transform, p_cam_projection, p_eye, p_cam_orthogonal, (RasterizerScene::InstanceBase **)instance_cull_result, instance_cull_count, light_instance_cull_result, light_cull_count + directional_light_count, p_shadow_atlas);
|
||||
RSG::scene_render->render_scene(p_cam_transform, p_cam_projection, p_eye, p_cam_orthogonal, (RasterizerScene::InstanceBase **)instance_cull_result, instance_cull_count);
|
||||
}
|
||||
|
||||
void RenderingServerScene::render_empty_scene(RID p_scenario, RID p_shadow_atlas) {
|
||||
void RenderingServerScene::render_empty_scene(RID p_scenario) {
|
||||
#ifndef _3D_DISABLED
|
||||
|
||||
Scenario *scenario = scenario_owner.getornull(p_scenario);
|
||||
|
||||
RID environment;
|
||||
if (scenario->environment.is_valid()) {
|
||||
environment = scenario->environment;
|
||||
} else {
|
||||
environment = scenario->fallback_environment;
|
||||
}
|
||||
RSG::scene_render->render_scene(Transform(), Projection(), 0, true, nullptr, 0, nullptr, 0, p_shadow_atlas);
|
||||
RSG::scene_render->render_scene(Transform(), Projection(), 0, true, nullptr, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1475,7 +1384,7 @@ bool RenderingServerScene::free(RID p_rid) {
|
||||
while (scenario->instances.first()) {
|
||||
instance_set_scenario(scenario->instances.first()->self()->self, RID());
|
||||
}
|
||||
RSG::scene_render->free(scenario->shadow_atlas);
|
||||
|
||||
scenario_owner.free(p_rid);
|
||||
memdelete(scenario);
|
||||
|
||||
|
@ -270,11 +270,6 @@ public:
|
||||
|
||||
SpatialPartitioningScene *sps;
|
||||
|
||||
List<Instance *> directional_lights;
|
||||
RID environment;
|
||||
RID fallback_environment;
|
||||
RID shadow_atlas;
|
||||
|
||||
SelfList<Instance>::List instances;
|
||||
|
||||
Scenario();
|
||||
@ -289,9 +284,6 @@ public:
|
||||
virtual RID scenario_create();
|
||||
|
||||
virtual void scenario_set_debug(RID p_scenario, RS::ScenarioDebugMode p_debug_mode);
|
||||
virtual void scenario_set_environment(RID p_scenario, RID p_environment);
|
||||
virtual void scenario_set_fallback_environment(RID p_scenario, RID p_environment);
|
||||
virtual void scenario_set_reflection_atlas_size(RID p_scenario, int p_size, int p_subdiv);
|
||||
|
||||
/* INSTANCING API */
|
||||
|
||||
@ -416,45 +408,16 @@ public:
|
||||
struct InstanceGeometryData : public InstanceBaseData {
|
||||
List<Instance *> lighting;
|
||||
bool lighting_dirty;
|
||||
bool can_cast_shadows;
|
||||
bool material_is_animated;
|
||||
|
||||
InstanceGeometryData() {
|
||||
lighting_dirty = true;
|
||||
can_cast_shadows = true;
|
||||
material_is_animated = true;
|
||||
}
|
||||
};
|
||||
|
||||
struct InstanceReflectionProbeData : public InstanceBaseData {
|
||||
Instance *owner;
|
||||
|
||||
struct PairInfo {
|
||||
List<Instance *>::Element *L; //reflection iterator in geometry
|
||||
Instance *geometry;
|
||||
};
|
||||
List<PairInfo> geometries;
|
||||
|
||||
RID instance;
|
||||
SelfList<InstanceReflectionProbeData> update_list;
|
||||
|
||||
int render_step;
|
||||
int32_t previous_room_id_hint;
|
||||
|
||||
InstanceReflectionProbeData() :
|
||||
update_list(this) {
|
||||
render_step = -1;
|
||||
previous_room_id_hint = -1;
|
||||
}
|
||||
};
|
||||
|
||||
int instance_cull_count;
|
||||
Instance *instance_cull_result[MAX_INSTANCE_CULL];
|
||||
Instance *instance_shadow_cull_result[MAX_INSTANCE_CULL]; //used for generating shadowmaps
|
||||
Instance *light_cull_result[MAX_LIGHTS_CULLED];
|
||||
RID light_instance_cull_result[MAX_LIGHTS_CULLED];
|
||||
int light_cull_count;
|
||||
int directional_light_count;
|
||||
|
||||
RID_Owner<Instance> instance_owner;
|
||||
|
||||
@ -491,7 +454,6 @@ public:
|
||||
virtual Vector<ObjectID> instances_cull_convex(const Vector<Plane> &p_convex, RID p_scenario = RID()) const;
|
||||
|
||||
virtual void instance_geometry_set_flag(RID p_instance, RS::InstanceFlags p_flags, bool p_enabled);
|
||||
virtual void instance_geometry_set_cast_shadows_setting(RID p_instance, RS::ShadowCastingSetting p_shadow_casting_setting);
|
||||
virtual void instance_geometry_set_material_override(RID p_instance, RID p_material);
|
||||
virtual void instance_geometry_set_material_overlay(RID p_instance, RID p_material);
|
||||
|
||||
@ -502,11 +464,11 @@ public:
|
||||
_FORCE_INLINE_ void _update_instance_aabb(Instance *p_instance);
|
||||
_FORCE_INLINE_ void _update_dirty_instance(Instance *p_instance);
|
||||
|
||||
void _prepare_scene(const Transform p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, RID p_force_environment, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, int32_t &r_previous_room_id_hint);
|
||||
void _render_scene(const Transform p_cam_transform, const Projection &p_cam_projection, const int p_eye, bool p_cam_orthogonal, RID p_force_environment, RID p_scenario, RID p_shadow_atlas);
|
||||
void render_empty_scene(RID p_scenario, RID p_shadow_atlas);
|
||||
void _prepare_scene(const Transform p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, RID p_force_environment, uint32_t p_visible_layers, RID p_scenario, int32_t &r_previous_room_id_hint);
|
||||
void _render_scene(const Transform p_cam_transform, const Projection &p_cam_projection, const int p_eye, bool p_cam_orthogonal, RID p_force_environment, RID p_scenario);
|
||||
void render_empty_scene(RID p_scenario);
|
||||
|
||||
void render_camera(RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas);
|
||||
void render_camera(RID p_camera, RID p_scenario, Size2 p_viewport_size);
|
||||
void update_dirty_instances();
|
||||
|
||||
// interpolation
|
||||
|
@ -65,7 +65,7 @@ static Transform2D _canvas_get_transform(RenderingServerViewport::Viewport *p_vi
|
||||
}
|
||||
|
||||
void RenderingServerViewport::_draw_3d(Viewport *p_viewport) {
|
||||
RSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
|
||||
RSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size);
|
||||
}
|
||||
|
||||
void RenderingServerViewport::_draw_viewport(Viewport *p_viewport) {
|
||||
@ -103,7 +103,7 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport) {
|
||||
|
||||
if (scenario_draw_canvas_bg && canvas_map.front() && canvas_map.front()->key().get_layer() > scenario_canvas_max_layer) {
|
||||
if (!can_draw_3d) {
|
||||
RSG::scene->render_empty_scene(p_viewport->scenario, p_viewport->shadow_atlas);
|
||||
RSG::scene->render_empty_scene(p_viewport->scenario);
|
||||
} else {
|
||||
_draw_3d(p_viewport);
|
||||
}
|
||||
@ -121,7 +121,7 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport) {
|
||||
|
||||
if (scenario_draw_canvas_bg && E->key().get_layer() >= scenario_canvas_max_layer) {
|
||||
if (!can_draw_3d) {
|
||||
RSG::scene->render_empty_scene(p_viewport->scenario, p_viewport->shadow_atlas);
|
||||
RSG::scene->render_empty_scene(p_viewport->scenario);
|
||||
} else {
|
||||
_draw_3d(p_viewport);
|
||||
}
|
||||
@ -132,7 +132,7 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport) {
|
||||
|
||||
if (scenario_draw_canvas_bg) {
|
||||
if (!can_draw_3d) {
|
||||
RSG::scene->render_empty_scene(p_viewport->scenario, p_viewport->shadow_atlas);
|
||||
RSG::scene->render_empty_scene(p_viewport->scenario);
|
||||
} else {
|
||||
_draw_3d(p_viewport);
|
||||
}
|
||||
@ -210,7 +210,6 @@ RID RenderingServerViewport::viewport_create() {
|
||||
viewport->hide_scenario = false;
|
||||
viewport->hide_canvas = false;
|
||||
viewport->render_target = RSG::storage->render_target_create();
|
||||
viewport->shadow_atlas = RSG::scene_render->shadow_atlas_create();
|
||||
viewport->viewport_render_direct_to_screen = false;
|
||||
|
||||
return rid;
|
||||
@ -429,22 +428,6 @@ void RenderingServerViewport::viewport_set_canvas_stacking(RID p_viewport, RID p
|
||||
viewport->canvas_map[p_canvas].sublayer = p_sublayer;
|
||||
}
|
||||
|
||||
void RenderingServerViewport::viewport_set_shadow_atlas_size(RID p_viewport, int p_size) {
|
||||
Viewport *viewport = viewport_owner.getornull(p_viewport);
|
||||
ERR_FAIL_COND(!viewport);
|
||||
|
||||
viewport->shadow_atlas_size = p_size;
|
||||
|
||||
RSG::scene_render->shadow_atlas_set_size(viewport->shadow_atlas, viewport->shadow_atlas_size);
|
||||
}
|
||||
|
||||
void RenderingServerViewport::viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv) {
|
||||
Viewport *viewport = viewport_owner.getornull(p_viewport);
|
||||
ERR_FAIL_COND(!viewport);
|
||||
|
||||
RSG::scene_render->shadow_atlas_set_quadrant_subdivision(viewport->shadow_atlas, p_quadrant, p_subdiv);
|
||||
}
|
||||
|
||||
void RenderingServerViewport::viewport_set_msaa(RID p_viewport, RS::ViewportMSAA p_msaa) {
|
||||
Viewport *viewport = viewport_owner.getornull(p_viewport);
|
||||
ERR_FAIL_COND(!viewport);
|
||||
|
@ -175,9 +175,6 @@ public:
|
||||
void viewport_set_global_canvas_transform(RID p_viewport, const Transform2D &p_transform);
|
||||
void viewport_set_canvas_stacking(RID p_viewport, RID p_canvas, int p_layer, int p_sublayer);
|
||||
|
||||
void viewport_set_shadow_atlas_size(RID p_viewport, int p_size);
|
||||
void viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv);
|
||||
|
||||
void viewport_set_msaa(RID p_viewport, RS::ViewportMSAA p_msaa);
|
||||
void viewport_set_use_fxaa(RID p_viewport, bool p_fxaa);
|
||||
void viewport_set_use_debanding(RID p_viewport, bool p_debanding);
|
||||
|
@ -258,8 +258,6 @@ public:
|
||||
|
||||
FUNC2(viewport_set_global_canvas_transform, RID, const Transform2D &)
|
||||
FUNC4(viewport_set_canvas_stacking, RID, RID, int, int)
|
||||
FUNC2(viewport_set_shadow_atlas_size, RID, int)
|
||||
FUNC3(viewport_set_shadow_atlas_quadrant_subdivision, RID, int, int)
|
||||
FUNC2(viewport_set_msaa, RID, ViewportMSAA)
|
||||
FUNC2(viewport_set_use_fxaa, RID, bool)
|
||||
FUNC2(viewport_set_use_debanding, RID, bool)
|
||||
@ -280,9 +278,6 @@ public:
|
||||
FUNCRID(scenario)
|
||||
|
||||
FUNC2(scenario_set_debug, RID, ScenarioDebugMode)
|
||||
FUNC2(scenario_set_environment, RID, RID)
|
||||
FUNC3(scenario_set_reflection_atlas_size, RID, int, int)
|
||||
FUNC2(scenario_set_fallback_environment, RID, RID)
|
||||
|
||||
/* INSTANCING API */
|
||||
FUNCRID(instance)
|
||||
@ -315,7 +310,6 @@ public:
|
||||
FUNC2RC(Vector<ObjectID>, instances_cull_convex, const Vector<Plane> &, RID)
|
||||
|
||||
FUNC3(instance_geometry_set_flag, RID, InstanceFlags, bool)
|
||||
FUNC2(instance_geometry_set_cast_shadows_setting, RID, ShadowCastingSetting)
|
||||
FUNC2(instance_geometry_set_material_override, RID, RID)
|
||||
FUNC2(instance_geometry_set_material_overlay, RID, RID)
|
||||
|
||||
|
@ -1954,8 +1954,6 @@ void RenderingServer::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("viewport_set_transparent_background", "viewport", "enabled"), &RenderingServer::viewport_set_transparent_background);
|
||||
ClassDB::bind_method(D_METHOD("viewport_set_global_canvas_transform", "viewport", "transform"), &RenderingServer::viewport_set_global_canvas_transform);
|
||||
ClassDB::bind_method(D_METHOD("viewport_set_canvas_stacking", "viewport", "canvas", "layer", "sublayer"), &RenderingServer::viewport_set_canvas_stacking);
|
||||
ClassDB::bind_method(D_METHOD("viewport_set_shadow_atlas_size", "viewport", "size"), &RenderingServer::viewport_set_shadow_atlas_size);
|
||||
ClassDB::bind_method(D_METHOD("viewport_set_shadow_atlas_quadrant_subdivision", "viewport", "quadrant", "subdivision"), &RenderingServer::viewport_set_shadow_atlas_quadrant_subdivision);
|
||||
ClassDB::bind_method(D_METHOD("viewport_set_msaa", "viewport", "msaa"), &RenderingServer::viewport_set_msaa);
|
||||
ClassDB::bind_method(D_METHOD("viewport_set_use_fxaa", "viewport", "fxaa"), &RenderingServer::viewport_set_use_fxaa);
|
||||
ClassDB::bind_method(D_METHOD("viewport_set_use_debanding", "viewport", "debanding"), &RenderingServer::viewport_set_use_debanding);
|
||||
@ -1968,9 +1966,6 @@ void RenderingServer::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("scenario_create"), &RenderingServer::scenario_create);
|
||||
ClassDB::bind_method(D_METHOD("scenario_set_debug", "scenario", "debug_mode"), &RenderingServer::scenario_set_debug);
|
||||
ClassDB::bind_method(D_METHOD("scenario_set_environment", "scenario", "environment"), &RenderingServer::scenario_set_environment);
|
||||
ClassDB::bind_method(D_METHOD("scenario_set_reflection_atlas_size", "scenario", "size", "subdiv"), &RenderingServer::scenario_set_reflection_atlas_size);
|
||||
ClassDB::bind_method(D_METHOD("scenario_set_fallback_environment", "scenario", "environment"), &RenderingServer::scenario_set_fallback_environment);
|
||||
|
||||
#ifndef _3D_DISABLED
|
||||
|
||||
@ -1991,7 +1986,6 @@ void RenderingServer::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("instance_set_exterior", "instance", "enabled"), &RenderingServer::instance_set_exterior);
|
||||
ClassDB::bind_method(D_METHOD("instance_set_extra_visibility_margin", "instance", "margin"), &RenderingServer::instance_set_extra_visibility_margin);
|
||||
ClassDB::bind_method(D_METHOD("instance_geometry_set_flag", "instance", "flag", "enabled"), &RenderingServer::instance_geometry_set_flag);
|
||||
ClassDB::bind_method(D_METHOD("instance_geometry_set_cast_shadows_setting", "instance", "shadow_casting_setting"), &RenderingServer::instance_geometry_set_cast_shadows_setting);
|
||||
ClassDB::bind_method(D_METHOD("instance_geometry_set_material_override", "instance", "material"), &RenderingServer::instance_geometry_set_material_override);
|
||||
ClassDB::bind_method(D_METHOD("instance_geometry_set_material_overlay", "instance", "material"), &RenderingServer::instance_geometry_set_material_overlay);
|
||||
ClassDB::bind_method(D_METHOD("instance_geometry_set_draw_range", "instance", "min", "max", "min_margin", "max_margin"), &RenderingServer::instance_geometry_set_draw_range);
|
||||
@ -2208,11 +2202,6 @@ void RenderingServer::_bind_methods() {
|
||||
BIND_ENUM_CONSTANT(INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE);
|
||||
BIND_ENUM_CONSTANT(INSTANCE_FLAG_MAX);
|
||||
|
||||
BIND_ENUM_CONSTANT(SHADOW_CASTING_SETTING_OFF);
|
||||
BIND_ENUM_CONSTANT(SHADOW_CASTING_SETTING_ON);
|
||||
BIND_ENUM_CONSTANT(SHADOW_CASTING_SETTING_DOUBLE_SIDED);
|
||||
BIND_ENUM_CONSTANT(SHADOW_CASTING_SETTING_SHADOWS_ONLY);
|
||||
|
||||
BIND_ENUM_CONSTANT(NINE_PATCH_STRETCH);
|
||||
BIND_ENUM_CONSTANT(NINE_PATCH_TILE);
|
||||
BIND_ENUM_CONSTANT(NINE_PATCH_TILE_FIT);
|
||||
@ -2335,23 +2324,6 @@ RenderingServer::RenderingServer() {
|
||||
GLOBAL_DEF("rendering/limits/time/time_rollover_secs", 3600);
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/time/time_rollover_secs", PropertyInfo(Variant::REAL, "rendering/limits/time/time_rollover_secs", PROPERTY_HINT_RANGE, "0,10000,1,or_greater"));
|
||||
|
||||
GLOBAL_DEF("rendering/quality/directional_shadow/size", 4096);
|
||||
GLOBAL_DEF("rendering/quality/directional_shadow/size.mobile", 2048);
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/directional_shadow/size", PropertyInfo(Variant::INT, "rendering/quality/directional_shadow/size", PROPERTY_HINT_RANGE, "256,16384,256"));
|
||||
GLOBAL_DEF_RST("rendering/quality/shadow_atlas/size", 4096);
|
||||
GLOBAL_DEF("rendering/quality/shadow_atlas/size.mobile", 2048);
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/size", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/size", PROPERTY_HINT_RANGE, "256,16384,256"));
|
||||
GLOBAL_DEF_RST("rendering/quality/shadow_atlas/cubemap_size", 512);
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/cubemap_size", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/cubemap_size", PROPERTY_HINT_RANGE, "64,16384,64"));
|
||||
GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_0_subdiv", 1);
|
||||
GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_1_subdiv", 2);
|
||||
GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_2_subdiv", 3);
|
||||
GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_3_subdiv", 4);
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_0_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_0_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_1_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_1_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_2_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_2_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_3_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_3_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
|
||||
|
||||
GLOBAL_DEF("rendering/quality/shadows/filter_mode", 1);
|
||||
GLOBAL_DEF("rendering/quality/shadows/filter_mode.mobile", 0);
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadows/filter_mode", PropertyInfo(Variant::INT, "rendering/quality/shadows/filter_mode", PROPERTY_HINT_ENUM, "Disabled,PCF5,PCF13"));
|
||||
|
@ -458,9 +458,6 @@ public:
|
||||
virtual void viewport_set_global_canvas_transform(RID p_viewport, const Transform2D &p_transform) = 0;
|
||||
virtual void viewport_set_canvas_stacking(RID p_viewport, RID p_canvas, int p_layer, int p_sublayer) = 0;
|
||||
|
||||
virtual void viewport_set_shadow_atlas_size(RID p_viewport, int p_size) = 0;
|
||||
virtual void viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv) = 0;
|
||||
|
||||
enum ViewportMSAA {
|
||||
VIEWPORT_MSAA_DISABLED,
|
||||
VIEWPORT_MSAA_2X,
|
||||
@ -528,9 +525,6 @@ public:
|
||||
};
|
||||
|
||||
virtual void scenario_set_debug(RID p_scenario, ScenarioDebugMode p_debug_mode) = 0;
|
||||
virtual void scenario_set_environment(RID p_scenario, RID p_environment) = 0;
|
||||
virtual void scenario_set_reflection_atlas_size(RID p_scenario, int p_size, int p_subdiv) = 0;
|
||||
virtual void scenario_set_fallback_environment(RID p_scenario, RID p_environment) = 0;
|
||||
|
||||
/* INSTANCING API */
|
||||
|
||||
@ -584,15 +578,7 @@ public:
|
||||
INSTANCE_FLAG_MAX
|
||||
};
|
||||
|
||||
enum ShadowCastingSetting {
|
||||
SHADOW_CASTING_SETTING_OFF,
|
||||
SHADOW_CASTING_SETTING_ON,
|
||||
SHADOW_CASTING_SETTING_DOUBLE_SIDED,
|
||||
SHADOW_CASTING_SETTING_SHADOWS_ONLY,
|
||||
};
|
||||
|
||||
virtual void instance_geometry_set_flag(RID p_instance, InstanceFlags p_flags, bool p_enabled) = 0;
|
||||
virtual void instance_geometry_set_cast_shadows_setting(RID p_instance, ShadowCastingSetting p_shadow_casting_setting) = 0;
|
||||
virtual void instance_geometry_set_material_override(RID p_instance, RID p_material) = 0;
|
||||
virtual void instance_geometry_set_material_overlay(RID p_instance, RID p_material) = 0;
|
||||
|
||||
@ -795,7 +781,6 @@ VARIANT_ENUM_CAST(RenderingServer::MultimeshColorFormat);
|
||||
VARIANT_ENUM_CAST(RenderingServer::MultimeshCustomDataFormat);
|
||||
VARIANT_ENUM_CAST(RenderingServer::MultimeshPhysicsInterpolationQuality);
|
||||
VARIANT_ENUM_CAST(RenderingServer::InstanceFlags);
|
||||
VARIANT_ENUM_CAST(RenderingServer::ShadowCastingSetting);
|
||||
VARIANT_ENUM_CAST(RenderingServer::TextureType);
|
||||
VARIANT_ENUM_CAST(RenderingServer::ChangedPriority);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user