Replace Octree by DynamicBVH in cull code
-Much greater pairing/unpairing performance -For now, using it for culling too, but this will change in a couple of days. -Added a paged allocator, to efficiently alloc/free some types of objects.
This commit is contained in:
parent
c4c211c3b7
commit
83058597cf
|
@ -49,7 +49,6 @@ DynamicBVH::Node *DynamicBVH::_create_node(Node *p_parent, void *p_data) {
|
||||||
Node *node = memnew(Node);
|
Node *node = memnew(Node);
|
||||||
node->parent = p_parent;
|
node->parent = p_parent;
|
||||||
node->data = p_data;
|
node->data = p_data;
|
||||||
node->childs[1] = 0;
|
|
||||||
return (node);
|
return (node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -335,6 +334,7 @@ DynamicBVH::ID DynamicBVH::insert(const AABB &p_box, void *p_userdata) {
|
||||||
|
|
||||||
ID id;
|
ID id;
|
||||||
id.node = leaf;
|
id.node = leaf;
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -389,12 +389,35 @@ void DynamicBVH::_extract_leaves(Node *p_node, List<ID> *r_elements) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DynamicBVH::set_index(uint32_t p_index) {
|
||||||
|
ERR_FAIL_COND(bvh_root != nullptr);
|
||||||
|
index = p_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t DynamicBVH::get_index() const {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
void DynamicBVH::get_elements(List<ID> *r_elements) {
|
void DynamicBVH::get_elements(List<ID> *r_elements) {
|
||||||
if (bvh_root) {
|
if (bvh_root) {
|
||||||
_extract_leaves(bvh_root, r_elements);
|
_extract_leaves(bvh_root, r_elements);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int DynamicBVH::get_leaf_count() const {
|
||||||
|
return total_leaves;
|
||||||
|
}
|
||||||
|
int DynamicBVH::get_max_depth() const {
|
||||||
|
if (bvh_root) {
|
||||||
|
int depth = 1;
|
||||||
|
int max_depth = 0;
|
||||||
|
bvh_root->get_max_depth(depth, max_depth);
|
||||||
|
return max_depth;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DynamicBVH::~DynamicBVH() {
|
DynamicBVH::~DynamicBVH() {
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,13 +61,10 @@ class DynamicBVH {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
struct ID {
|
struct ID {
|
||||||
Node *node;
|
Node *node = nullptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
_FORCE_INLINE_ bool is_valid() const { return node != nullptr; }
|
_FORCE_INLINE_ bool is_valid() const { return node != nullptr; }
|
||||||
_FORCE_INLINE_ ID() {
|
|
||||||
node = nullptr;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -134,6 +131,48 @@ private:
|
||||||
(min.z <= b.max.z) &&
|
(min.z <= b.max.z) &&
|
||||||
(max.z >= b.min.z));
|
(max.z >= b.min.z));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_FORCE_INLINE_ bool intersects_convex(const Plane *p_planes, int p_plane_count, const Vector3 *p_points, int p_point_count) const {
|
||||||
|
Vector3 half_extents = (max - min) * 0.5;
|
||||||
|
Vector3 ofs = min + half_extents;
|
||||||
|
|
||||||
|
for (int i = 0; i < p_plane_count; i++) {
|
||||||
|
const Plane &p = p_planes[i];
|
||||||
|
Vector3 point(
|
||||||
|
(p.normal.x > 0) ? -half_extents.x : half_extents.x,
|
||||||
|
(p.normal.y > 0) ? -half_extents.y : half_extents.y,
|
||||||
|
(p.normal.z > 0) ? -half_extents.z : half_extents.z);
|
||||||
|
point += ofs;
|
||||||
|
if (p.is_point_over(point)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure all points in the shape aren't fully separated from the AABB on
|
||||||
|
// each axis.
|
||||||
|
int bad_point_counts_positive[3] = { 0 };
|
||||||
|
int bad_point_counts_negative[3] = { 0 };
|
||||||
|
|
||||||
|
for (int k = 0; k < 3; k++) {
|
||||||
|
for (int i = 0; i < p_point_count; i++) {
|
||||||
|
if (p_points[i].coord[k] > ofs.coord[k] + half_extents.coord[k]) {
|
||||||
|
bad_point_counts_positive[k]++;
|
||||||
|
}
|
||||||
|
if (p_points[i].coord[k] < ofs.coord[k] - half_extents.coord[k]) {
|
||||||
|
bad_point_counts_negative[k]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bad_point_counts_negative[k] == p_point_count) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (bad_point_counts_positive[k] == p_point_count) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Node {
|
struct Node {
|
||||||
|
@ -144,14 +183,14 @@ private:
|
||||||
void *data;
|
void *data;
|
||||||
};
|
};
|
||||||
|
|
||||||
_FORCE_INLINE_ bool is_leaf() const { return data != nullptr; }
|
_FORCE_INLINE_ bool is_leaf() const { return childs[1] == nullptr; }
|
||||||
_FORCE_INLINE_ bool is_internal() const { return (!is_leaf()); }
|
_FORCE_INLINE_ bool is_internal() const { return (!is_leaf()); }
|
||||||
|
|
||||||
_FORCE_INLINE_ int get_index_in_parent() const {
|
_FORCE_INLINE_ int get_index_in_parent() const {
|
||||||
ERR_FAIL_COND_V(!parent, 0);
|
ERR_FAIL_COND_V(!parent, 0);
|
||||||
return (parent->childs[1] == this) ? 1 : 0;
|
return (parent->childs[1] == this) ? 1 : 0;
|
||||||
}
|
}
|
||||||
_FORCE_INLINE_ void get_max_depth(int depth, int &maxdepth) {
|
void get_max_depth(int depth, int &maxdepth) {
|
||||||
if (is_internal()) {
|
if (is_internal()) {
|
||||||
childs[0]->get_max_depth(depth + 1, maxdepth);
|
childs[0]->get_max_depth(depth + 1, maxdepth);
|
||||||
childs[1]->get_max_depth(depth + 1, maxdepth);
|
childs[1]->get_max_depth(depth + 1, maxdepth);
|
||||||
|
@ -183,6 +222,7 @@ private:
|
||||||
int lkhd = -1;
|
int lkhd = -1;
|
||||||
int total_leaves = 0;
|
int total_leaves = 0;
|
||||||
uint32_t opath = 0;
|
uint32_t opath = 0;
|
||||||
|
uint32_t index = 0;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
ALLOCA_STACK_SIZE = 128
|
ALLOCA_STACK_SIZE = 128
|
||||||
|
@ -245,6 +285,9 @@ public:
|
||||||
void remove(const ID &p_id);
|
void remove(const ID &p_id);
|
||||||
void get_elements(List<ID> *r_elements);
|
void get_elements(List<ID> *r_elements);
|
||||||
|
|
||||||
|
int get_leaf_count() const;
|
||||||
|
int get_max_depth() const;
|
||||||
|
|
||||||
/* Discouraged, but works as a reference on how it must be used */
|
/* Discouraged, but works as a reference on how it must be used */
|
||||||
struct DefaultQueryResult {
|
struct DefaultQueryResult {
|
||||||
virtual bool operator()(void *p_data) = 0; //return true whether you want to continue the query
|
virtual bool operator()(void *p_data) = 0; //return true whether you want to continue the query
|
||||||
|
@ -254,9 +297,13 @@ public:
|
||||||
template <class QueryResult>
|
template <class QueryResult>
|
||||||
_FORCE_INLINE_ void aabb_query(const AABB &p_aabb, QueryResult &r_result);
|
_FORCE_INLINE_ void aabb_query(const AABB &p_aabb, QueryResult &r_result);
|
||||||
template <class QueryResult>
|
template <class QueryResult>
|
||||||
|
_FORCE_INLINE_ void convex_query(const Plane *p_planes, int p_plane_count, const Vector3 *p_points, int p_point_count, QueryResult &r_result);
|
||||||
|
template <class QueryResult>
|
||||||
_FORCE_INLINE_ void ray_query(const Vector3 &p_from, const Vector3 &p_to, QueryResult &r_result);
|
_FORCE_INLINE_ void ray_query(const Vector3 &p_from, const Vector3 &p_to, QueryResult &r_result);
|
||||||
|
|
||||||
DynamicBVH();
|
void set_index(uint32_t p_index);
|
||||||
|
uint32_t get_index() const;
|
||||||
|
|
||||||
~DynamicBVH();
|
~DynamicBVH();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -278,8 +325,8 @@ void DynamicBVH::aabb_query(const AABB &p_box, QueryResult &r_result) {
|
||||||
LocalVector<const Node *> aux_stack; //only used in rare occasions when you run out of alloca memory because tree is too unbalanced. Should correct itself over time.
|
LocalVector<const Node *> aux_stack; //only used in rare occasions when you run out of alloca memory because tree is too unbalanced. Should correct itself over time.
|
||||||
|
|
||||||
do {
|
do {
|
||||||
const Node *n = stack[depth - 1];
|
|
||||||
depth--;
|
depth--;
|
||||||
|
const Node *n = stack[depth];
|
||||||
if (n->volume.intersects(volume)) {
|
if (n->volume.intersects(volume)) {
|
||||||
if (n->is_internal()) {
|
if (n->is_internal()) {
|
||||||
if (depth > threshold) {
|
if (depth > threshold) {
|
||||||
|
@ -303,8 +350,67 @@ void DynamicBVH::aabb_query(const AABB &p_box, QueryResult &r_result) {
|
||||||
} while (depth > 0);
|
} while (depth > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class QueryResult>
|
||||||
|
void DynamicBVH::convex_query(const Plane *p_planes, int p_plane_count, const Vector3 *p_points, int p_point_count, QueryResult &r_result) {
|
||||||
|
if (!bvh_root) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//generate a volume anyway to improve pre-testing
|
||||||
|
Volume volume;
|
||||||
|
for (int i = 0; i < p_point_count; i++) {
|
||||||
|
if (i == 0) {
|
||||||
|
volume.min = p_points[0];
|
||||||
|
volume.max = p_points[0];
|
||||||
|
} else {
|
||||||
|
volume.min.x = MIN(volume.min.x, p_points[i].x);
|
||||||
|
volume.min.y = MIN(volume.min.y, p_points[i].y);
|
||||||
|
volume.min.z = MIN(volume.min.z, p_points[i].z);
|
||||||
|
|
||||||
|
volume.max.x = MAX(volume.max.x, p_points[i].x);
|
||||||
|
volume.max.y = MAX(volume.max.y, p_points[i].y);
|
||||||
|
volume.max.z = MAX(volume.max.z, p_points[i].z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const Node **stack = (const Node **)alloca(ALLOCA_STACK_SIZE * sizeof(const Node *));
|
||||||
|
stack[0] = bvh_root;
|
||||||
|
int32_t depth = 1;
|
||||||
|
int32_t threshold = ALLOCA_STACK_SIZE - 2;
|
||||||
|
|
||||||
|
LocalVector<const Node *> aux_stack; //only used in rare occasions when you run out of alloca memory because tree is too unbalanced. Should correct itself over time.
|
||||||
|
|
||||||
|
do {
|
||||||
|
depth--;
|
||||||
|
const Node *n = stack[depth];
|
||||||
|
if (n->volume.intersects(volume) && n->volume.intersects_convex(p_planes, p_plane_count, p_points, p_point_count)) {
|
||||||
|
if (n->is_internal()) {
|
||||||
|
if (depth > threshold) {
|
||||||
|
if (aux_stack.empty()) {
|
||||||
|
aux_stack.resize(ALLOCA_STACK_SIZE * 2);
|
||||||
|
copymem(aux_stack.ptr(), stack, ALLOCA_STACK_SIZE * sizeof(const Node *));
|
||||||
|
} else {
|
||||||
|
aux_stack.resize(aux_stack.size() * 2);
|
||||||
|
}
|
||||||
|
stack = aux_stack.ptr();
|
||||||
|
threshold = aux_stack.size() - 2;
|
||||||
|
}
|
||||||
|
stack[depth++] = n->childs[0];
|
||||||
|
stack[depth++] = n->childs[1];
|
||||||
|
} else {
|
||||||
|
if (r_result(n->data)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (depth > 0);
|
||||||
|
}
|
||||||
template <class QueryResult>
|
template <class QueryResult>
|
||||||
void DynamicBVH::ray_query(const Vector3 &p_from, const Vector3 &p_to, QueryResult &r_result) {
|
void DynamicBVH::ray_query(const Vector3 &p_from, const Vector3 &p_to, QueryResult &r_result) {
|
||||||
|
if (!bvh_root) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Vector3 ray_dir = (p_to - p_from);
|
Vector3 ray_dir = (p_to - p_from);
|
||||||
ray_dir.normalize();
|
ray_dir.normalize();
|
||||||
|
|
||||||
|
@ -327,7 +433,8 @@ void DynamicBVH::ray_query(const Vector3 &p_from, const Vector3 &p_to, QueryResu
|
||||||
LocalVector<const Node *> aux_stack; //only used in rare occasions when you run out of alloca memory because tree is too unbalanced. Should correct itself over time.
|
LocalVector<const Node *> aux_stack; //only used in rare occasions when you run out of alloca memory because tree is too unbalanced. Should correct itself over time.
|
||||||
|
|
||||||
do {
|
do {
|
||||||
const Node *node = stack[--depth];
|
depth--;
|
||||||
|
const Node *node = stack[depth];
|
||||||
bounds[0] = node->volume.min;
|
bounds[0] = node->volume.min;
|
||||||
bounds[1] = node->volume.max;
|
bounds[1] = node->volume.max;
|
||||||
real_t tmin = 1.f, lambda_min = 0.f;
|
real_t tmin = 1.f, lambda_min = 0.f;
|
||||||
|
|
|
@ -0,0 +1,129 @@
|
||||||
|
/*************************************************************************/
|
||||||
|
/* paged_allocator.h */
|
||||||
|
/*************************************************************************/
|
||||||
|
/* This file is part of: */
|
||||||
|
/* GODOT ENGINE */
|
||||||
|
/* https://godotengine.org */
|
||||||
|
/*************************************************************************/
|
||||||
|
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
||||||
|
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
||||||
|
/* */
|
||||||
|
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||||
|
/* a copy of this software and associated documentation files (the */
|
||||||
|
/* "Software"), to deal in the Software without restriction, including */
|
||||||
|
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||||
|
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||||
|
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||||
|
/* the following conditions: */
|
||||||
|
/* */
|
||||||
|
/* The above copyright notice and this permission notice shall be */
|
||||||
|
/* included in all copies or substantial portions of the Software. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||||
|
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||||
|
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||||
|
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||||
|
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||||
|
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||||
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
#ifndef PAGED_ALLOCATOR_H
|
||||||
|
#define PAGED_ALLOCATOR_H
|
||||||
|
|
||||||
|
#include "core/os/memory.h"
|
||||||
|
#include "core/os/spin_lock.h"
|
||||||
|
#include "core/typedefs.h"
|
||||||
|
|
||||||
|
template <class T, bool thread_safe = false>
|
||||||
|
class PagedAllocator {
|
||||||
|
T **page_pool = nullptr;
|
||||||
|
T ***available_pool = nullptr;
|
||||||
|
uint32_t pages_allocated = 0;
|
||||||
|
uint32_t allocs_available = 0;
|
||||||
|
|
||||||
|
uint32_t page_shift = 0;
|
||||||
|
uint32_t page_mask = 0;
|
||||||
|
uint32_t page_size = 0;
|
||||||
|
SpinLock spin_lock;
|
||||||
|
|
||||||
|
public:
|
||||||
|
T *alloc() {
|
||||||
|
if (thread_safe) {
|
||||||
|
spin_lock.lock();
|
||||||
|
}
|
||||||
|
if (unlikely(allocs_available == 0)) {
|
||||||
|
uint32_t pages_used = pages_allocated;
|
||||||
|
|
||||||
|
pages_allocated++;
|
||||||
|
page_pool = (T **)memrealloc(page_pool, sizeof(T *) * pages_allocated);
|
||||||
|
available_pool = (T ***)memrealloc(available_pool, sizeof(T **) * pages_allocated);
|
||||||
|
|
||||||
|
page_pool[pages_used] = (T *)memalloc(sizeof(T) * page_size);
|
||||||
|
available_pool[pages_used] = (T **)memalloc(sizeof(T *) * page_size);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < page_size; i++) {
|
||||||
|
available_pool[0][i] = &page_pool[pages_used][i];
|
||||||
|
}
|
||||||
|
allocs_available += page_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
allocs_available--;
|
||||||
|
T *alloc = available_pool[allocs_available >> page_shift][allocs_available & page_mask];
|
||||||
|
if (thread_safe) {
|
||||||
|
spin_lock.unlock();
|
||||||
|
}
|
||||||
|
memnew_placement(alloc, T);
|
||||||
|
return alloc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void free(T *p_mem) {
|
||||||
|
if (thread_safe) {
|
||||||
|
spin_lock.lock();
|
||||||
|
}
|
||||||
|
p_mem->~T();
|
||||||
|
available_pool[allocs_available >> page_shift][allocs_available & page_mask] = p_mem;
|
||||||
|
if (thread_safe) {
|
||||||
|
spin_lock.unlock();
|
||||||
|
}
|
||||||
|
allocs_available++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset() {
|
||||||
|
ERR_FAIL_COND(allocs_available < pages_allocated * page_size);
|
||||||
|
if (pages_allocated) {
|
||||||
|
for (uint32_t i = 0; i < pages_allocated; i++) {
|
||||||
|
memfree(page_pool[i]);
|
||||||
|
memfree(available_pool[i]);
|
||||||
|
}
|
||||||
|
memfree(page_pool);
|
||||||
|
memfree(available_pool);
|
||||||
|
page_pool = nullptr;
|
||||||
|
available_pool = nullptr;
|
||||||
|
pages_allocated = 0;
|
||||||
|
allocs_available = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool is_configured() const {
|
||||||
|
return page_size > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void configure(uint32_t p_page_size, bool p_thread_safe) {
|
||||||
|
ERR_FAIL_COND(page_pool != nullptr); //sanity check
|
||||||
|
ERR_FAIL_COND(p_page_size == 0);
|
||||||
|
page_size = nearest_power_of_2_templated(p_page_size);
|
||||||
|
page_mask = page_size - 1;
|
||||||
|
page_shift = get_shift_from_power_of_2(page_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
PagedAllocator(uint32_t p_page_size = 4096, bool p_thread_safe = false) { // power of 2 recommended because of alignment with OS page sizes. Even if element is bigger, its still a multiple and get rounded amount of pages
|
||||||
|
configure(p_page_size, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
~PagedAllocator() {
|
||||||
|
ERR_FAIL_COND_MSG(allocs_available < pages_allocated * page_size, "Pages in use exist at exit in PagedAllocator");
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PAGED_ALLOCATOR_H
|
|
@ -329,7 +329,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t size() const {
|
_FORCE_INLINE_ uint64_t size() const {
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -346,6 +346,18 @@ public:
|
||||||
alloc.free(p_rid);
|
alloc.free(p_rid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_FORCE_INLINE_ uint32_t get_rid_count() const {
|
||||||
|
return alloc.get_rid_count();
|
||||||
|
}
|
||||||
|
|
||||||
|
_FORCE_INLINE_ RID get_rid_by_index(uint32_t p_index) {
|
||||||
|
return alloc.get_rid_by_index(p_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
_FORCE_INLINE_ T *get_ptr_by_index(uint32_t p_index) {
|
||||||
|
return *alloc.get_ptr_by_index(p_index);
|
||||||
|
}
|
||||||
|
|
||||||
_FORCE_INLINE_ void get_owned_list(List<RID> *p_owned) {
|
_FORCE_INLINE_ void get_owned_list(List<RID> *p_owned) {
|
||||||
return alloc.get_owned_list(p_owned);
|
return alloc.get_owned_list(p_owned);
|
||||||
}
|
}
|
||||||
|
@ -353,6 +365,7 @@ public:
|
||||||
void set_description(const char *p_descrption) {
|
void set_description(const char *p_descrption) {
|
||||||
alloc.set_description(p_descrption);
|
alloc.set_description(p_descrption);
|
||||||
}
|
}
|
||||||
|
|
||||||
RID_PtrOwner(uint32_t p_target_chunk_byte_size = 4096) :
|
RID_PtrOwner(uint32_t p_target_chunk_byte_size = 4096) :
|
||||||
alloc(p_target_chunk_byte_size) {}
|
alloc(p_target_chunk_byte_size) {}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1532,7 +1532,7 @@ void RendererSceneRenderForward::_add_geometry_with_material(InstanceBase *p_ins
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererSceneRenderForward::_fill_render_list(InstanceBase **p_cull_result, int p_cull_count, PassMode p_pass_mode, bool p_using_sdfgi) {
|
void RendererSceneRenderForward::_fill_render_list(const PagedArray<InstanceBase *> &p_instances, PassMode p_pass_mode, bool p_using_sdfgi) {
|
||||||
scene_state.current_shader_index = 0;
|
scene_state.current_shader_index = 0;
|
||||||
scene_state.current_material_index = 0;
|
scene_state.current_material_index = 0;
|
||||||
scene_state.used_sss = false;
|
scene_state.used_sss = false;
|
||||||
|
@ -1544,8 +1544,8 @@ void RendererSceneRenderForward::_fill_render_list(InstanceBase **p_cull_result,
|
||||||
|
|
||||||
//fill list
|
//fill list
|
||||||
|
|
||||||
for (int i = 0; i < p_cull_count; i++) {
|
for (int i = 0; i < (int)p_instances.size(); i++) {
|
||||||
InstanceBase *inst = p_cull_result[i];
|
InstanceBase *inst = p_instances[i];
|
||||||
|
|
||||||
//add geometry for drawing
|
//add geometry for drawing
|
||||||
switch (inst->base_type) {
|
switch (inst->base_type) {
|
||||||
|
@ -1635,14 +1635,14 @@ void RendererSceneRenderForward::_fill_render_list(InstanceBase **p_cull_result,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererSceneRenderForward::_setup_lightmaps(InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, const Transform &p_cam_transform) {
|
void RendererSceneRenderForward::_setup_lightmaps(const PagedArray<InstanceBase *> &p_lightmaps, const Transform &p_cam_transform) {
|
||||||
uint32_t lightmaps_used = 0;
|
uint32_t lightmaps_used = 0;
|
||||||
for (int i = 0; i < p_lightmap_cull_count; i++) {
|
for (int i = 0; i < (int)p_lightmaps.size(); i++) {
|
||||||
if (i >= (int)scene_state.max_lightmaps) {
|
if (i >= (int)scene_state.max_lightmaps) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
InstanceBase *lm = p_lightmap_cull_result[i];
|
InstanceBase *lm = p_lightmaps[i];
|
||||||
Basis to_lm = lm->transform.basis.inverse() * p_cam_transform.basis;
|
Basis to_lm = lm->transform.basis.inverse() * p_cam_transform.basis;
|
||||||
to_lm = to_lm.inverse().transposed(); //will transform normals
|
to_lm = to_lm.inverse().transposed(); //will transform normals
|
||||||
RendererStorageRD::store_transform_3x3(to_lm, scene_state.lightmaps[i].normal_xform);
|
RendererStorageRD::store_transform_3x3(to_lm, scene_state.lightmaps[i].normal_xform);
|
||||||
|
@ -1654,7 +1654,7 @@ void RendererSceneRenderForward::_setup_lightmaps(InstanceBase **p_lightmap_cull
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, int p_directional_light_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color, float p_screen_lod_threshold) {
|
void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, int p_directional_light_count, const PagedArray<RID> &p_gi_probes, const PagedArray<InstanceBase *> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color, float p_screen_lod_threshold) {
|
||||||
RenderBufferDataForward *render_buffer = nullptr;
|
RenderBufferDataForward *render_buffer = nullptr;
|
||||||
if (p_render_buffer.is_valid()) {
|
if (p_render_buffer.is_valid()) {
|
||||||
render_buffer = (RenderBufferDataForward *)render_buffers_get_data(p_render_buffer);
|
render_buffer = (RenderBufferDataForward *)render_buffers_get_data(p_render_buffer);
|
||||||
|
@ -1709,7 +1709,7 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf
|
||||||
|
|
||||||
opaque_framebuffer = render_buffer->color_fb;
|
opaque_framebuffer = render_buffer->color_fb;
|
||||||
|
|
||||||
if (!low_end && p_gi_probe_cull_count > 0) {
|
if (!low_end && p_gi_probes.size() > 0) {
|
||||||
using_giprobe = true;
|
using_giprobe = true;
|
||||||
render_buffer->ensure_gi();
|
render_buffer->ensure_gi();
|
||||||
}
|
}
|
||||||
|
@ -1776,13 +1776,13 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf
|
||||||
ERR_FAIL(); //bug?
|
ERR_FAIL(); //bug?
|
||||||
}
|
}
|
||||||
|
|
||||||
_setup_lightmaps(p_lightmap_cull_result, p_lightmap_cull_count, p_cam_transform);
|
_setup_lightmaps(p_lightmaps, p_cam_transform);
|
||||||
_setup_environment(p_environment, p_render_buffer, p_cam_projection, p_cam_transform, p_reflection_probe, p_reflection_probe.is_valid(), screen_pixel_size, p_shadow_atlas, !p_reflection_probe.is_valid(), p_default_bg_color, p_cam_projection.get_z_near(), p_cam_projection.get_z_far(), false);
|
_setup_environment(p_environment, p_render_buffer, p_cam_projection, p_cam_transform, p_reflection_probe, p_reflection_probe.is_valid(), screen_pixel_size, p_shadow_atlas, !p_reflection_probe.is_valid(), p_default_bg_color, p_cam_projection.get_z_near(), p_cam_projection.get_z_far(), false);
|
||||||
|
|
||||||
_update_render_base_uniform_set(); //may have changed due to the above (light buffer enlarged, as an example)
|
_update_render_base_uniform_set(); //may have changed due to the above (light buffer enlarged, as an example)
|
||||||
|
|
||||||
render_list.clear();
|
render_list.clear();
|
||||||
_fill_render_list(p_cull_result, p_cull_count, PASS_MODE_COLOR, using_sdfgi);
|
_fill_render_list(p_instances, PASS_MODE_COLOR, using_sdfgi);
|
||||||
|
|
||||||
bool using_sss = !low_end && render_buffer && scene_state.used_sss && sub_surface_scattering_get_quality() != RS::SUB_SURFACE_SCATTERING_QUALITY_DISABLED;
|
bool using_sss = !low_end && render_buffer && scene_state.used_sss && sub_surface_scattering_get_quality() != RS::SUB_SURFACE_SCATTERING_QUALITY_DISABLED;
|
||||||
|
|
||||||
|
@ -1864,7 +1864,7 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf
|
||||||
clear_color = p_default_bg_color;
|
clear_color = p_default_bg_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
RID rp_uniform_set = _setup_render_pass_uniform_set(p_render_buffer, radiance_texture, p_shadow_atlas, p_reflection_atlas, p_gi_probe_cull_result, p_gi_probe_cull_count);
|
RID rp_uniform_set = _setup_render_pass_uniform_set(p_render_buffer, radiance_texture, p_shadow_atlas, p_reflection_atlas, p_gi_probes);
|
||||||
|
|
||||||
render_list.sort_by_key(false);
|
render_list.sort_by_key(false);
|
||||||
|
|
||||||
|
@ -1903,7 +1903,7 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf
|
||||||
}
|
}
|
||||||
|
|
||||||
if (using_sdfgi || using_giprobe) {
|
if (using_sdfgi || using_giprobe) {
|
||||||
_process_gi(p_render_buffer, render_buffer->normal_roughness_buffer, render_buffer->ambient_buffer, render_buffer->reflection_buffer, render_buffer->giprobe_buffer, p_environment, p_cam_projection, p_cam_transform, p_gi_probe_cull_result, p_gi_probe_cull_count);
|
_process_gi(p_render_buffer, render_buffer->normal_roughness_buffer, render_buffer->ambient_buffer, render_buffer->reflection_buffer, render_buffer->giprobe_buffer, p_environment, p_cam_projection, p_cam_transform, p_gi_probes);
|
||||||
}
|
}
|
||||||
|
|
||||||
_setup_environment(p_environment, p_render_buffer, p_cam_projection, p_cam_transform, p_reflection_probe, p_reflection_probe.is_valid(), screen_pixel_size, p_shadow_atlas, !p_reflection_probe.is_valid(), p_default_bg_color, p_cam_projection.get_z_near(), p_cam_projection.get_z_far(), p_render_buffer.is_valid());
|
_setup_environment(p_environment, p_render_buffer, p_cam_projection, p_cam_transform, p_reflection_probe, p_reflection_probe.is_valid(), screen_pixel_size, p_shadow_atlas, !p_reflection_probe.is_valid(), p_default_bg_color, p_cam_projection.get_z_near(), p_cam_projection.get_z_far(), p_render_buffer.is_valid());
|
||||||
|
@ -1949,8 +1949,8 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf
|
||||||
dc.set_depth_correction(true);
|
dc.set_depth_correction(true);
|
||||||
CameraMatrix cm = (dc * p_cam_projection) * CameraMatrix(p_cam_transform.affine_inverse());
|
CameraMatrix cm = (dc * p_cam_projection) * CameraMatrix(p_cam_transform.affine_inverse());
|
||||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(opaque_framebuffer, RD::INITIAL_ACTION_CONTINUE, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ);
|
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(opaque_framebuffer, RD::INITIAL_ACTION_CONTINUE, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ);
|
||||||
for (int i = 0; i < p_gi_probe_cull_count; i++) {
|
for (int i = 0; i < (int)p_gi_probes.size(); i++) {
|
||||||
_debug_giprobe(p_gi_probe_cull_result[i], draw_list, opaque_framebuffer, cm, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_LIGHTING, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_EMISSION, 1.0);
|
_debug_giprobe(p_gi_probes[i], draw_list, opaque_framebuffer, cm, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_LIGHTING, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_EMISSION, 1.0);
|
||||||
}
|
}
|
||||||
RD::get_singleton()->draw_list_end();
|
RD::get_singleton()->draw_list_end();
|
||||||
}
|
}
|
||||||
|
@ -2027,7 +2027,7 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererSceneRenderForward::_render_shadow(RID p_framebuffer, InstanceBase **p_cull_result, int p_cull_count, const CameraMatrix &p_projection, const Transform &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_lod_threshold) {
|
void RendererSceneRenderForward::_render_shadow(RID p_framebuffer, const PagedArray<InstanceBase *> &p_instances, const CameraMatrix &p_projection, const Transform &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_lod_threshold) {
|
||||||
RENDER_TIMESTAMP("Setup Rendering Shadow");
|
RENDER_TIMESTAMP("Setup Rendering Shadow");
|
||||||
|
|
||||||
_update_render_base_uniform_set();
|
_update_render_base_uniform_set();
|
||||||
|
@ -2046,9 +2046,9 @@ void RendererSceneRenderForward::_render_shadow(RID p_framebuffer, InstanceBase
|
||||||
|
|
||||||
PassMode pass_mode = p_use_dp ? PASS_MODE_SHADOW_DP : PASS_MODE_SHADOW;
|
PassMode pass_mode = p_use_dp ? PASS_MODE_SHADOW_DP : PASS_MODE_SHADOW;
|
||||||
|
|
||||||
_fill_render_list(p_cull_result, p_cull_count, pass_mode);
|
_fill_render_list(p_instances, pass_mode);
|
||||||
|
|
||||||
RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), nullptr, 0);
|
RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), PagedArray<RID>());
|
||||||
|
|
||||||
RENDER_TIMESTAMP("Render Shadow");
|
RENDER_TIMESTAMP("Render Shadow");
|
||||||
|
|
||||||
|
@ -2064,7 +2064,7 @@ void RendererSceneRenderForward::_render_shadow(RID p_framebuffer, InstanceBase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererSceneRenderForward::_render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, InstanceBase **p_cull_result, int p_cull_count) {
|
void RendererSceneRenderForward::_render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<InstanceBase *> &p_instances) {
|
||||||
RENDER_TIMESTAMP("Setup Render Collider Heightfield");
|
RENDER_TIMESTAMP("Setup Render Collider Heightfield");
|
||||||
|
|
||||||
_update_render_base_uniform_set();
|
_update_render_base_uniform_set();
|
||||||
|
@ -2079,9 +2079,9 @@ void RendererSceneRenderForward::_render_particle_collider_heightfield(RID p_fb,
|
||||||
|
|
||||||
PassMode pass_mode = PASS_MODE_SHADOW;
|
PassMode pass_mode = PASS_MODE_SHADOW;
|
||||||
|
|
||||||
_fill_render_list(p_cull_result, p_cull_count, pass_mode);
|
_fill_render_list(p_instances, pass_mode);
|
||||||
|
|
||||||
RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), nullptr, 0);
|
RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), PagedArray<RID>());
|
||||||
|
|
||||||
RENDER_TIMESTAMP("Render Collider Heightield");
|
RENDER_TIMESTAMP("Render Collider Heightield");
|
||||||
|
|
||||||
|
@ -2097,7 +2097,7 @@ void RendererSceneRenderForward::_render_particle_collider_heightfield(RID p_fb,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererSceneRenderForward::_render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) {
|
void RendererSceneRenderForward::_render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, RID p_framebuffer, const Rect2i &p_region) {
|
||||||
RENDER_TIMESTAMP("Setup Rendering Material");
|
RENDER_TIMESTAMP("Setup Rendering Material");
|
||||||
|
|
||||||
_update_render_base_uniform_set();
|
_update_render_base_uniform_set();
|
||||||
|
@ -2112,9 +2112,9 @@ void RendererSceneRenderForward::_render_material(const Transform &p_cam_transfo
|
||||||
render_list.clear();
|
render_list.clear();
|
||||||
|
|
||||||
PassMode pass_mode = PASS_MODE_DEPTH_MATERIAL;
|
PassMode pass_mode = PASS_MODE_DEPTH_MATERIAL;
|
||||||
_fill_render_list(p_cull_result, p_cull_count, pass_mode);
|
_fill_render_list(p_instances, pass_mode);
|
||||||
|
|
||||||
RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), nullptr, 0);
|
RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), PagedArray<RID>());
|
||||||
|
|
||||||
RENDER_TIMESTAMP("Render Material");
|
RENDER_TIMESTAMP("Render Material");
|
||||||
|
|
||||||
|
@ -2136,7 +2136,7 @@ void RendererSceneRenderForward::_render_material(const Transform &p_cam_transfo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererSceneRenderForward::_render_uv2(InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) {
|
void RendererSceneRenderForward::_render_uv2(const PagedArray<InstanceBase *> &p_instances, RID p_framebuffer, const Rect2i &p_region) {
|
||||||
RENDER_TIMESTAMP("Setup Rendering UV2");
|
RENDER_TIMESTAMP("Setup Rendering UV2");
|
||||||
|
|
||||||
_update_render_base_uniform_set();
|
_update_render_base_uniform_set();
|
||||||
|
@ -2151,9 +2151,9 @@ void RendererSceneRenderForward::_render_uv2(InstanceBase **p_cull_result, int p
|
||||||
render_list.clear();
|
render_list.clear();
|
||||||
|
|
||||||
PassMode pass_mode = PASS_MODE_DEPTH_MATERIAL;
|
PassMode pass_mode = PASS_MODE_DEPTH_MATERIAL;
|
||||||
_fill_render_list(p_cull_result, p_cull_count, pass_mode);
|
_fill_render_list(p_instances, pass_mode);
|
||||||
|
|
||||||
RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), nullptr, 0);
|
RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), PagedArray<RID>());
|
||||||
|
|
||||||
RENDER_TIMESTAMP("Render Material");
|
RENDER_TIMESTAMP("Render Material");
|
||||||
|
|
||||||
|
@ -2197,7 +2197,7 @@ void RendererSceneRenderForward::_render_uv2(InstanceBase **p_cull_result, int p
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererSceneRenderForward::_render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, InstanceBase **p_cull_result, int p_cull_count, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) {
|
void RendererSceneRenderForward::_render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<InstanceBase *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) {
|
||||||
RENDER_TIMESTAMP("Render SDFGI");
|
RENDER_TIMESTAMP("Render SDFGI");
|
||||||
|
|
||||||
_update_render_base_uniform_set();
|
_update_render_base_uniform_set();
|
||||||
|
@ -2209,7 +2209,7 @@ void RendererSceneRenderForward::_render_sdfgi(RID p_render_buffers, const Vecto
|
||||||
render_list.clear();
|
render_list.clear();
|
||||||
|
|
||||||
PassMode pass_mode = PASS_MODE_SDF;
|
PassMode pass_mode = PASS_MODE_SDF;
|
||||||
_fill_render_list(p_cull_result, p_cull_count, pass_mode);
|
_fill_render_list(p_instances, pass_mode);
|
||||||
render_list.sort_by_key(false);
|
render_list.sort_by_key(false);
|
||||||
_fill_instances(render_list.elements, render_list.element_count, true);
|
_fill_instances(render_list.elements, render_list.element_count, true);
|
||||||
|
|
||||||
|
@ -2453,7 +2453,7 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count) {
|
RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, const PagedArray<RID> &p_gi_probes) {
|
||||||
if (render_pass_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(render_pass_uniform_set)) {
|
if (render_pass_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(render_pass_uniform_set)) {
|
||||||
RD::get_singleton()->free(render_pass_uniform_set);
|
RD::get_singleton()->free(render_pass_uniform_set);
|
||||||
}
|
}
|
||||||
|
@ -2516,8 +2516,8 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
|
||||||
u.ids.resize(MAX_GI_PROBES);
|
u.ids.resize(MAX_GI_PROBES);
|
||||||
RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE);
|
RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE);
|
||||||
for (int i = 0; i < MAX_GI_PROBES; i++) {
|
for (int i = 0; i < MAX_GI_PROBES; i++) {
|
||||||
if (i < p_gi_probe_cull_count) {
|
if (i < (int)p_gi_probes.size()) {
|
||||||
RID tex = gi_probe_instance_get_texture(p_gi_probe_cull_result[i]);
|
RID tex = gi_probe_instance_get_texture(p_gi_probes[i]);
|
||||||
if (!tex.is_valid()) {
|
if (!tex.is_valid()) {
|
||||||
tex = default_tex;
|
tex = default_tex;
|
||||||
}
|
}
|
||||||
|
|
|
@ -266,7 +266,7 @@ class RendererSceneRenderForward : public RendererSceneRenderRD {
|
||||||
|
|
||||||
void _update_render_base_uniform_set();
|
void _update_render_base_uniform_set();
|
||||||
RID _setup_sdfgi_render_pass_uniform_set(RID p_albedo_texture, RID p_emission_texture, RID p_emission_aniso_texture, RID p_geom_facing_texture);
|
RID _setup_sdfgi_render_pass_uniform_set(RID p_albedo_texture, RID p_emission_texture, RID p_emission_aniso_texture, RID p_geom_facing_texture);
|
||||||
RID _setup_render_pass_uniform_set(RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count);
|
RID _setup_render_pass_uniform_set(RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, const PagedArray<RID> &p_gi_probes);
|
||||||
|
|
||||||
struct LightmapData {
|
struct LightmapData {
|
||||||
float normal_xform[12];
|
float normal_xform[12];
|
||||||
|
@ -567,26 +567,26 @@ class RendererSceneRenderForward : public RendererSceneRenderRD {
|
||||||
};
|
};
|
||||||
|
|
||||||
void _setup_environment(RID p_environment, RID p_render_buffers, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2 &p_screen_pixel_size, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers = false, bool p_pancake_shadows = false);
|
void _setup_environment(RID p_environment, RID p_render_buffers, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2 &p_screen_pixel_size, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers = false, bool p_pancake_shadows = false);
|
||||||
void _setup_lightmaps(InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, const Transform &p_cam_transform);
|
void _setup_lightmaps(const PagedArray<InstanceBase *> &p_lightmaps, const Transform &p_cam_transform);
|
||||||
|
|
||||||
void _fill_instances(RenderList::Element **p_elements, int p_element_count, bool p_for_depth, bool p_has_sdfgi = false, bool p_has_opaque_gi = false);
|
void _fill_instances(RenderList::Element **p_elements, int p_element_count, bool p_for_depth, bool p_has_sdfgi = false, bool p_has_opaque_gi = false);
|
||||||
void _render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderList::Element **p_elements, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, bool p_no_gi, RID p_render_pass_uniform_set, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), const Plane &p_lod_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0);
|
void _render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderList::Element **p_elements, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, bool p_no_gi, RID p_render_pass_uniform_set, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), const Plane &p_lod_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0);
|
||||||
_FORCE_INLINE_ void _add_geometry(InstanceBase *p_instance, uint32_t p_surface, RID p_material, PassMode p_pass_mode, uint32_t p_geometry_index, bool p_using_sdfgi = false);
|
_FORCE_INLINE_ void _add_geometry(InstanceBase *p_instance, uint32_t p_surface, RID p_material, PassMode p_pass_mode, uint32_t p_geometry_index, bool p_using_sdfgi = false);
|
||||||
_FORCE_INLINE_ void _add_geometry_with_material(InstanceBase *p_instance, uint32_t p_surface, MaterialData *p_material, RID p_material_rid, PassMode p_pass_mode, uint32_t p_geometry_index, bool p_using_sdfgi = false);
|
_FORCE_INLINE_ void _add_geometry_with_material(InstanceBase *p_instance, uint32_t p_surface, MaterialData *p_material, RID p_material_rid, PassMode p_pass_mode, uint32_t p_geometry_index, bool p_using_sdfgi = false);
|
||||||
|
|
||||||
void _fill_render_list(InstanceBase **p_cull_result, int p_cull_count, PassMode p_pass_mode, bool p_using_sdfgi = false);
|
void _fill_render_list(const PagedArray<InstanceBase *> &p_instances, PassMode p_pass_mode, bool p_using_sdfgi = false);
|
||||||
|
|
||||||
Map<Size2i, RID> sdfgi_framebuffer_size_cache;
|
Map<Size2i, RID> sdfgi_framebuffer_size_cache;
|
||||||
|
|
||||||
bool low_end = false;
|
bool low_end = false;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, int p_directional_light_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color, float p_lod_threshold);
|
virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, int p_directional_light_count, const PagedArray<RID> &p_gi_probes, const PagedArray<InstanceBase *> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color, float p_lod_threshold);
|
||||||
virtual void _render_shadow(RID p_framebuffer, InstanceBase **p_cull_result, int p_cull_count, const CameraMatrix &p_projection, const Transform &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_lod_threshold = 0.0);
|
virtual void _render_shadow(RID p_framebuffer, const PagedArray<InstanceBase *> &p_instances, const CameraMatrix &p_projection, const Transform &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_lod_threshold = 0.0);
|
||||||
virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region);
|
virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, RID p_framebuffer, const Rect2i &p_region);
|
||||||
virtual void _render_uv2(InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region);
|
virtual void _render_uv2(const PagedArray<InstanceBase *> &p_instances, RID p_framebuffer, const Rect2i &p_region);
|
||||||
virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, InstanceBase **p_cull_result, int p_cull_count, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture);
|
virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<InstanceBase *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture);
|
||||||
virtual void _render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, InstanceBase **p_cull_result, int p_cull_count);
|
virtual void _render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<InstanceBase *> &p_instances);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void set_time(double p_time, double p_step);
|
virtual void set_time(double p_time, double p_step);
|
||||||
|
|
|
@ -1153,7 +1153,7 @@ void RendererSceneRenderRD::_sdfgi_update_cascades(RID p_render_buffers) {
|
||||||
RD::get_singleton()->buffer_update(rb->sdfgi->cascades_ubo, 0, sizeof(SDFGI::Cascade::UBO) * SDFGI::MAX_CASCADES, cascade_data, true);
|
RD::get_singleton()->buffer_update(rb->sdfgi->cascades_ubo, 0, sizeof(SDFGI::Cascade::UBO) * SDFGI::MAX_CASCADES, cascade_data, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererSceneRenderRD::sdfgi_update_probes(RID p_render_buffers, RID p_environment, const RID *p_directional_light_instances, uint32_t p_directional_light_count, const RID *p_positional_light_instances, uint32_t p_positional_light_count) {
|
void RendererSceneRenderRD::sdfgi_update_probes(RID p_render_buffers, RID p_environment, const PagedArray<RID> &p_directional_light_instances, const RID *p_positional_light_instances, uint32_t p_positional_light_count) {
|
||||||
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
|
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
|
||||||
ERR_FAIL_COND(rb == nullptr);
|
ERR_FAIL_COND(rb == nullptr);
|
||||||
if (rb->sdfgi == nullptr) {
|
if (rb->sdfgi == nullptr) {
|
||||||
|
@ -1179,7 +1179,7 @@ void RendererSceneRenderRD::sdfgi_update_probes(RID p_render_buffers, RID p_envi
|
||||||
|
|
||||||
SDGIShader::Light lights[SDFGI::MAX_DYNAMIC_LIGHTS];
|
SDGIShader::Light lights[SDFGI::MAX_DYNAMIC_LIGHTS];
|
||||||
uint32_t idx = 0;
|
uint32_t idx = 0;
|
||||||
for (uint32_t j = 0; j < p_directional_light_count; j++) {
|
for (uint32_t j = 0; j < (uint32_t)p_directional_light_instances.size(); j++) {
|
||||||
if (idx == SDFGI::MAX_DYNAMIC_LIGHTS) {
|
if (idx == SDFGI::MAX_DYNAMIC_LIGHTS) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1402,7 +1402,7 @@ void RendererSceneRenderRD::sdfgi_update_probes(RID p_render_buffers, RID p_envi
|
||||||
RENDER_TIMESTAMP("<SDFGI Update Probes");
|
RENDER_TIMESTAMP("<SDFGI Update Probes");
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererSceneRenderRD::_setup_giprobes(RID p_render_buffers, const Transform &p_transform, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, uint32_t &r_gi_probes_used) {
|
void RendererSceneRenderRD::_setup_giprobes(RID p_render_buffers, const Transform &p_transform, const PagedArray<RID> &p_gi_probes, uint32_t &r_gi_probes_used) {
|
||||||
r_gi_probes_used = 0;
|
r_gi_probes_used = 0;
|
||||||
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
|
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
|
||||||
ERR_FAIL_COND(rb == nullptr);
|
ERR_FAIL_COND(rb == nullptr);
|
||||||
|
@ -1417,8 +1417,8 @@ void RendererSceneRenderRD::_setup_giprobes(RID p_render_buffers, const Transfor
|
||||||
|
|
||||||
for (int i = 0; i < RenderBuffers::MAX_GIPROBES; i++) {
|
for (int i = 0; i < RenderBuffers::MAX_GIPROBES; i++) {
|
||||||
RID texture;
|
RID texture;
|
||||||
if (i < p_gi_probe_cull_count) {
|
if (i < (int)p_gi_probes.size()) {
|
||||||
GIProbeInstance *gipi = gi_probe_instance_owner.getornull(p_gi_probe_cull_result[i]);
|
GIProbeInstance *gipi = gi_probe_instance_owner.getornull(p_gi_probes[i]);
|
||||||
|
|
||||||
if (gipi) {
|
if (gipi) {
|
||||||
texture = gipi->texture;
|
texture = gipi->texture;
|
||||||
|
@ -1489,12 +1489,12 @@ void RendererSceneRenderRD::_setup_giprobes(RID p_render_buffers, const Transfor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_gi_probe_cull_count > 0) {
|
if (p_gi_probes.size() > 0) {
|
||||||
RD::get_singleton()->buffer_update(gi_probe_buffer, 0, sizeof(GI::GIProbeData) * MIN(RenderBuffers::MAX_GIPROBES, p_gi_probe_cull_count), gi_probe_data, true);
|
RD::get_singleton()->buffer_update(gi_probe_buffer, 0, sizeof(GI::GIProbeData) * MIN((uint64_t)RenderBuffers::MAX_GIPROBES, p_gi_probes.size()), gi_probe_data, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererSceneRenderRD::_process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_ambient_buffer, RID p_reflection_buffer, RID p_gi_probe_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count) {
|
void RendererSceneRenderRD::_process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_ambient_buffer, RID p_reflection_buffer, RID p_gi_probe_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform, const PagedArray<RID> &p_gi_probes) {
|
||||||
RENDER_TIMESTAMP("Render GI");
|
RENDER_TIMESTAMP("Render GI");
|
||||||
|
|
||||||
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
|
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
|
||||||
|
@ -1512,7 +1512,7 @@ void RendererSceneRenderRD::_process_gi(RID p_render_buffers, RID p_normal_rough
|
||||||
push_constant.proj_info[1] = -2.0f / (rb->height * p_projection.matrix[1][1]);
|
push_constant.proj_info[1] = -2.0f / (rb->height * p_projection.matrix[1][1]);
|
||||||
push_constant.proj_info[2] = (1.0f - p_projection.matrix[0][2]) / p_projection.matrix[0][0];
|
push_constant.proj_info[2] = (1.0f - p_projection.matrix[0][2]) / p_projection.matrix[0][0];
|
||||||
push_constant.proj_info[3] = (1.0f + p_projection.matrix[1][2]) / p_projection.matrix[1][1];
|
push_constant.proj_info[3] = (1.0f + p_projection.matrix[1][2]) / p_projection.matrix[1][1];
|
||||||
push_constant.max_giprobes = MIN(RenderBuffers::MAX_GIPROBES, p_gi_probe_cull_count);
|
push_constant.max_giprobes = MIN((uint64_t)RenderBuffers::MAX_GIPROBES, p_gi_probes.size());
|
||||||
push_constant.high_quality_vct = gi_probe_quality == RS::GI_PROBE_QUALITY_HIGH;
|
push_constant.high_quality_vct = gi_probe_quality == RS::GI_PROBE_QUALITY_HIGH;
|
||||||
push_constant.use_sdfgi = rb->sdfgi != nullptr;
|
push_constant.use_sdfgi = rb->sdfgi != nullptr;
|
||||||
|
|
||||||
|
@ -4061,7 +4061,7 @@ bool RendererSceneRenderRD::gi_probe_needs_update(RID p_probe) const {
|
||||||
return gi_probe->last_probe_version != storage->gi_probe_get_version(gi_probe->probe);
|
return gi_probe->last_probe_version != storage->gi_probe_get_version(gi_probe->probe);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererSceneRenderRD::gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, int p_dynamic_object_count, InstanceBase **p_dynamic_objects) {
|
void RendererSceneRenderRD::gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<InstanceBase *> &p_dynamic_objects) {
|
||||||
GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_probe);
|
GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_probe);
|
||||||
ERR_FAIL_COND(!gi_probe);
|
ERR_FAIL_COND(!gi_probe);
|
||||||
|
|
||||||
|
@ -4420,7 +4420,7 @@ void RendererSceneRenderRD::gi_probe_update(RID p_probe, bool p_update_light_ins
|
||||||
|
|
||||||
uint32_t light_count = 0;
|
uint32_t light_count = 0;
|
||||||
|
|
||||||
if (p_update_light_instances || p_dynamic_object_count > 0) {
|
if (p_update_light_instances || p_dynamic_objects.size() > 0) {
|
||||||
light_count = MIN(gi_probe_max_lights, (uint32_t)p_light_instances.size());
|
light_count = MIN(gi_probe_max_lights, (uint32_t)p_light_instances.size());
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -4470,7 +4470,7 @@ void RendererSceneRenderRD::gi_probe_update(RID p_probe, bool p_update_light_ins
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gi_probe->has_dynamic_object_data || p_update_light_instances || p_dynamic_object_count) {
|
if (gi_probe->has_dynamic_object_data || p_update_light_instances || p_dynamic_objects.size()) {
|
||||||
// PROCESS MIPMAPS
|
// PROCESS MIPMAPS
|
||||||
if (gi_probe->mipmaps.size()) {
|
if (gi_probe->mipmaps.size()) {
|
||||||
//can update mipmaps
|
//can update mipmaps
|
||||||
|
@ -4563,7 +4563,7 @@ void RendererSceneRenderRD::gi_probe_update(RID p_probe, bool p_update_light_ins
|
||||||
|
|
||||||
gi_probe->has_dynamic_object_data = false; //clear until dynamic object data is used again
|
gi_probe->has_dynamic_object_data = false; //clear until dynamic object data is used again
|
||||||
|
|
||||||
if (p_dynamic_object_count && gi_probe->dynamic_maps.size()) {
|
if (p_dynamic_objects.size() && gi_probe->dynamic_maps.size()) {
|
||||||
Vector3i octree_size = storage->gi_probe_get_octree_size(gi_probe->probe);
|
Vector3i octree_size = storage->gi_probe_get_octree_size(gi_probe->probe);
|
||||||
int multiplier = gi_probe->dynamic_maps[0].size / MAX(MAX(octree_size.x, octree_size.y), octree_size.z);
|
int multiplier = gi_probe->dynamic_maps[0].size / MAX(MAX(octree_size.x, octree_size.y), octree_size.z);
|
||||||
|
|
||||||
|
@ -4577,7 +4577,7 @@ void RendererSceneRenderRD::gi_probe_update(RID p_probe, bool p_update_light_ins
|
||||||
AABB probe_aabb(Vector3(), octree_size);
|
AABB probe_aabb(Vector3(), octree_size);
|
||||||
|
|
||||||
//this could probably be better parallelized in compute..
|
//this could probably be better parallelized in compute..
|
||||||
for (int i = 0; i < p_dynamic_object_count; i++) {
|
for (int i = 0; i < (int)p_dynamic_objects.size(); i++) {
|
||||||
InstanceBase *instance = p_dynamic_objects[i];
|
InstanceBase *instance = p_dynamic_objects[i];
|
||||||
//not used, so clear
|
//not used, so clear
|
||||||
instance->depth_layer = 0;
|
instance->depth_layer = 0;
|
||||||
|
@ -4648,7 +4648,12 @@ void RendererSceneRenderRD::gi_probe_update(RID p_probe, bool p_update_light_ins
|
||||||
CameraMatrix cm;
|
CameraMatrix cm;
|
||||||
cm.set_orthogonal(-rect.size.width / 2, rect.size.width / 2, -rect.size.height / 2, rect.size.height / 2, 0.0001, aabb.size[z_axis]);
|
cm.set_orthogonal(-rect.size.width / 2, rect.size.width / 2, -rect.size.height / 2, rect.size.height / 2, 0.0001, aabb.size[z_axis]);
|
||||||
|
|
||||||
_render_material(to_world_xform * xform, cm, true, &instance, 1, gi_probe->dynamic_maps[0].fb, Rect2i(Vector2i(), rect.size));
|
if (cull_argument.size() == 0) {
|
||||||
|
cull_argument.push_back(nullptr);
|
||||||
|
}
|
||||||
|
cull_argument[0] = instance;
|
||||||
|
|
||||||
|
_render_material(to_world_xform * xform, cm, true, cull_argument, gi_probe->dynamic_maps[0].fb, Rect2i(Vector2i(), rect.size));
|
||||||
|
|
||||||
GIProbeDynamicPushConstant push_constant;
|
GIProbeDynamicPushConstant push_constant;
|
||||||
zeromem(&push_constant, sizeof(GIProbeDynamicPushConstant));
|
zeromem(&push_constant, sizeof(GIProbeDynamicPushConstant));
|
||||||
|
@ -6001,11 +6006,11 @@ RendererSceneRenderRD::RenderBufferData *RendererSceneRenderRD::render_buffers_g
|
||||||
return rb->data;
|
return rb->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererSceneRenderRD::_setup_reflections(RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, const Transform &p_camera_inverse_transform, RID p_environment) {
|
void RendererSceneRenderRD::_setup_reflections(const PagedArray<RID> &p_reflections, const Transform &p_camera_inverse_transform, RID p_environment) {
|
||||||
for (int i = 0; i < p_reflection_probe_cull_count; i++) {
|
for (uint32_t i = 0; i < (uint32_t)p_reflections.size(); i++) {
|
||||||
RID rpi = p_reflection_probe_cull_result[i];
|
RID rpi = p_reflections[i];
|
||||||
|
|
||||||
if (i >= (int)cluster.max_reflections) {
|
if (i >= cluster.max_reflections) {
|
||||||
reflection_probe_instance_set_render_index(rpi, 0); //invalid, but something needs to be set
|
reflection_probe_instance_set_render_index(rpi, 0); //invalid, but something needs to be set
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -6056,19 +6061,19 @@ void RendererSceneRenderRD::_setup_reflections(RID *p_reflection_probe_cull_resu
|
||||||
reflection_probe_instance_set_render_pass(rpi, RSG::rasterizer->get_frame_number());
|
reflection_probe_instance_set_render_pass(rpi, RSG::rasterizer->get_frame_number());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_reflection_probe_cull_count) {
|
if (p_reflections.size()) {
|
||||||
RD::get_singleton()->buffer_update(cluster.reflection_buffer, 0, MIN(cluster.max_reflections, (unsigned int)p_reflection_probe_cull_count) * sizeof(ReflectionData), cluster.reflections, true);
|
RD::get_singleton()->buffer_update(cluster.reflection_buffer, 0, MIN(cluster.max_reflections, (unsigned int)p_reflections.size()) * sizeof(ReflectionData), cluster.reflections, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererSceneRenderRD::_setup_lights(RID *p_light_cull_result, int p_light_cull_count, const Transform &p_camera_inverse_transform, RID p_shadow_atlas, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_positional_light_count) {
|
void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const Transform &p_camera_inverse_transform, RID p_shadow_atlas, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_positional_light_count) {
|
||||||
uint32_t light_count = 0;
|
uint32_t light_count = 0;
|
||||||
r_directional_light_count = 0;
|
r_directional_light_count = 0;
|
||||||
r_positional_light_count = 0;
|
r_positional_light_count = 0;
|
||||||
sky_scene_state.ubo.directional_light_count = 0;
|
sky_scene_state.ubo.directional_light_count = 0;
|
||||||
|
|
||||||
for (int i = 0; i < p_light_cull_count; i++) {
|
for (int i = 0; i < (int)p_lights.size(); i++) {
|
||||||
RID li = p_light_cull_result[i];
|
RID li = p_lights[i];
|
||||||
RID base = light_instance_get_base_light(li);
|
RID base = light_instance_get_base_light(li);
|
||||||
|
|
||||||
ERR_CONTINUE(base.is_null());
|
ERR_CONTINUE(base.is_null());
|
||||||
|
@ -6421,15 +6426,15 @@ void RendererSceneRenderRD::_setup_lights(RID *p_light_cull_result, int p_light_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererSceneRenderRD::_setup_decals(const RID *p_decal_instances, int p_decal_count, const Transform &p_camera_inverse_xform) {
|
void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const Transform &p_camera_inverse_xform) {
|
||||||
Transform uv_xform;
|
Transform uv_xform;
|
||||||
uv_xform.basis.scale(Vector3(2.0, 1.0, 2.0));
|
uv_xform.basis.scale(Vector3(2.0, 1.0, 2.0));
|
||||||
uv_xform.origin = Vector3(-1.0, 0.0, -1.0);
|
uv_xform.origin = Vector3(-1.0, 0.0, -1.0);
|
||||||
|
|
||||||
p_decal_count = MIN((uint32_t)p_decal_count, cluster.max_decals);
|
uint32_t decal_count = MIN((uint32_t)p_decals.size(), cluster.max_decals);
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
for (int i = 0; i < p_decal_count; i++) {
|
for (uint32_t i = 0; i < decal_count; i++) {
|
||||||
RID di = p_decal_instances[i];
|
RID di = p_decals[i];
|
||||||
RID decal = decal_instance_get_base(di);
|
RID decal = decal_instance_get_base(di);
|
||||||
|
|
||||||
Transform xform = decal_instance_get_transform(di);
|
Transform xform = decal_instance_get_transform(di);
|
||||||
|
@ -7097,7 +7102,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
|
||||||
RD::get_singleton()->compute_list_end();
|
RD::get_singleton()->compute_list_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold) {
|
void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<InstanceBase *> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold) {
|
||||||
Color clear_color;
|
Color clear_color;
|
||||||
if (p_render_buffers.is_valid()) {
|
if (p_render_buffers.is_valid()) {
|
||||||
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
|
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
|
||||||
|
@ -7108,17 +7113,23 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform &
|
||||||
}
|
}
|
||||||
|
|
||||||
//assign render indices to giprobes
|
//assign render indices to giprobes
|
||||||
for (int i = 0; i < p_gi_probe_cull_count; i++) {
|
for (uint32_t i = 0; i < (uint32_t)p_gi_probes.size(); i++) {
|
||||||
GIProbeInstance *giprobe_inst = gi_probe_instance_owner.getornull(p_gi_probe_cull_result[i]);
|
GIProbeInstance *giprobe_inst = gi_probe_instance_owner.getornull(p_gi_probes[i]);
|
||||||
if (giprobe_inst) {
|
if (giprobe_inst) {
|
||||||
giprobe_inst->render_index = i;
|
giprobe_inst->render_index = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PagedArray<RID> *lights = &p_lights;
|
||||||
|
const PagedArray<RID> *reflections = &p_reflection_probes;
|
||||||
|
const PagedArray<RID> *gi_probes = &p_gi_probes;
|
||||||
|
|
||||||
|
PagedArray<RID> empty;
|
||||||
|
|
||||||
if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_UNSHADED) {
|
if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_UNSHADED) {
|
||||||
p_light_cull_count = 0;
|
lights = ∅
|
||||||
p_reflection_probe_cull_count = 0;
|
reflections = ∅
|
||||||
p_gi_probe_cull_count = 0;
|
gi_probes = ∅
|
||||||
}
|
}
|
||||||
|
|
||||||
cluster.builder.begin(p_cam_transform.affine_inverse(), p_cam_projection); //prepare cluster
|
cluster.builder.begin(p_cam_transform.affine_inverse(), p_cam_projection); //prepare cluster
|
||||||
|
@ -7131,17 +7142,17 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform &
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//do not render reflections when rendering a reflection probe
|
//do not render reflections when rendering a reflection probe
|
||||||
_setup_reflections(p_reflection_probe_cull_result, p_reflection_probe_cull_count, p_cam_transform.affine_inverse(), p_environment);
|
_setup_reflections(*reflections, p_cam_transform.affine_inverse(), p_environment);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t directional_light_count = 0;
|
uint32_t directional_light_count = 0;
|
||||||
uint32_t positional_light_count = 0;
|
uint32_t positional_light_count = 0;
|
||||||
_setup_lights(p_light_cull_result, p_light_cull_count, p_cam_transform.affine_inverse(), p_shadow_atlas, using_shadows, directional_light_count, positional_light_count);
|
_setup_lights(*lights, p_cam_transform.affine_inverse(), p_shadow_atlas, using_shadows, directional_light_count, positional_light_count);
|
||||||
_setup_decals(p_decal_cull_result, p_decal_cull_count, p_cam_transform.affine_inverse());
|
_setup_decals(p_decals, p_cam_transform.affine_inverse());
|
||||||
cluster.builder.bake_cluster(); //bake to cluster
|
cluster.builder.bake_cluster(); //bake to cluster
|
||||||
|
|
||||||
uint32_t gi_probe_count = 0;
|
uint32_t gi_probe_count = 0;
|
||||||
_setup_giprobes(p_render_buffers, p_cam_transform, p_gi_probe_cull_result, p_gi_probe_cull_count, gi_probe_count);
|
_setup_giprobes(p_render_buffers, p_cam_transform, *gi_probes, gi_probe_count);
|
||||||
|
|
||||||
if (p_render_buffers.is_valid()) {
|
if (p_render_buffers.is_valid()) {
|
||||||
bool directional_shadows = false;
|
bool directional_shadows = false;
|
||||||
|
@ -7154,7 +7165,7 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform &
|
||||||
_update_volumetric_fog(p_render_buffers, p_environment, p_cam_projection, p_cam_transform, p_shadow_atlas, directional_light_count, directional_shadows, positional_light_count, gi_probe_count);
|
_update_volumetric_fog(p_render_buffers, p_environment, p_cam_projection, p_cam_transform, p_shadow_atlas, directional_light_count, directional_shadows, positional_light_count, gi_probe_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
_render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_ortogonal, p_cull_result, p_cull_count, directional_light_count, p_gi_probe_cull_result, p_gi_probe_cull_count, p_lightmap_cull_result, p_lightmap_cull_count, p_environment, p_camera_effects, p_shadow_atlas, p_reflection_atlas, p_reflection_probe, p_reflection_probe_pass, clear_color, p_screen_lod_threshold);
|
_render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_ortogonal, p_instances, directional_light_count, *gi_probes, p_lightmaps, p_environment, p_camera_effects, p_shadow_atlas, p_reflection_atlas, p_reflection_probe, p_reflection_probe_pass, clear_color, p_screen_lod_threshold);
|
||||||
|
|
||||||
if (p_render_buffers.is_valid()) {
|
if (p_render_buffers.is_valid()) {
|
||||||
RENDER_TIMESTAMP("Tonemap");
|
RENDER_TIMESTAMP("Tonemap");
|
||||||
|
@ -7167,7 +7178,7 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform &
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold) {
|
void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<InstanceBase *> &p_instances, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold) {
|
||||||
LightInstance *light_instance = light_instance_owner.getornull(p_light);
|
LightInstance *light_instance = light_instance_owner.getornull(p_light);
|
||||||
ERR_FAIL_COND(!light_instance);
|
ERR_FAIL_COND(!light_instance);
|
||||||
|
|
||||||
|
@ -7318,7 +7329,7 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p
|
||||||
|
|
||||||
if (render_cubemap) {
|
if (render_cubemap) {
|
||||||
//rendering to cubemap
|
//rendering to cubemap
|
||||||
_render_shadow(render_fb, p_cull_result, p_cull_count, light_projection, light_transform, zfar, 0, 0, false, false, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold);
|
_render_shadow(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, false, false, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold);
|
||||||
if (finalize_cubemap) {
|
if (finalize_cubemap) {
|
||||||
//reblit
|
//reblit
|
||||||
atlas_rect.size.height /= 2;
|
atlas_rect.size.height /= 2;
|
||||||
|
@ -7329,7 +7340,7 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p
|
||||||
} else {
|
} else {
|
||||||
//render shadow
|
//render shadow
|
||||||
|
|
||||||
_render_shadow(render_fb, p_cull_result, p_cull_count, light_projection, light_transform, zfar, bias, normal_bias, using_dual_paraboloid, using_dual_paraboloid_flip, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold);
|
_render_shadow(render_fb, p_instances, light_projection, light_transform, zfar, bias, normal_bias, using_dual_paraboloid, using_dual_paraboloid_flip, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold);
|
||||||
|
|
||||||
//copy to atlas
|
//copy to atlas
|
||||||
if (use_linear_depth) {
|
if (use_linear_depth) {
|
||||||
|
@ -7343,11 +7354,11 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererSceneRenderRD::render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) {
|
void RendererSceneRenderRD::render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, RID p_framebuffer, const Rect2i &p_region) {
|
||||||
_render_material(p_cam_transform, p_cam_projection, p_cam_ortogonal, p_cull_result, p_cull_count, p_framebuffer, p_region);
|
_render_material(p_cam_transform, p_cam_projection, p_cam_ortogonal, p_instances, p_framebuffer, p_region);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, InstanceBase **p_cull_result, int p_cull_count) {
|
void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, const PagedArray<InstanceBase *> &p_instances) {
|
||||||
//print_line("rendering region " + itos(p_region));
|
//print_line("rendering region " + itos(p_region));
|
||||||
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
|
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
|
||||||
ERR_FAIL_COND(!rb);
|
ERR_FAIL_COND(!rb);
|
||||||
|
@ -7370,7 +7381,7 @@ void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, Ins
|
||||||
}
|
}
|
||||||
|
|
||||||
//print_line("rendering cascade " + itos(p_region) + " objects: " + itos(p_cull_count) + " bounds: " + bounds + " from: " + from + " size: " + size + " cell size: " + rtos(rb->sdfgi->cascades[cascade].cell_size));
|
//print_line("rendering cascade " + itos(p_region) + " objects: " + itos(p_cull_count) + " bounds: " + bounds + " from: " + from + " size: " + size + " cell size: " + rtos(rb->sdfgi->cascades[cascade].cell_size));
|
||||||
_render_sdfgi(p_render_buffers, from, size, bounds, p_cull_result, p_cull_count, rb->sdfgi->render_albedo, rb->sdfgi->render_emission, rb->sdfgi->render_emission_aniso, rb->sdfgi->render_geom_facing);
|
_render_sdfgi(p_render_buffers, from, size, bounds, p_instances, rb->sdfgi->render_albedo, rb->sdfgi->render_emission, rb->sdfgi->render_emission_aniso, rb->sdfgi->render_geom_facing);
|
||||||
|
|
||||||
if (cascade_next != cascade) {
|
if (cascade_next != cascade) {
|
||||||
RENDER_TIMESTAMP(">SDFGI Update SDF");
|
RENDER_TIMESTAMP(">SDFGI Update SDF");
|
||||||
|
@ -7684,7 +7695,7 @@ void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, Ins
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererSceneRenderRD::render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, InstanceBase **p_cull_result, int p_cull_count) {
|
void RendererSceneRenderRD::render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, const PagedArray<InstanceBase *> &p_instances) {
|
||||||
ERR_FAIL_COND(!storage->particles_collision_is_heightfield(p_collider));
|
ERR_FAIL_COND(!storage->particles_collision_is_heightfield(p_collider));
|
||||||
Vector3 extents = storage->particles_collision_get_extents(p_collider) * p_transform.basis.get_scale();
|
Vector3 extents = storage->particles_collision_get_extents(p_collider) * p_transform.basis.get_scale();
|
||||||
CameraMatrix cm;
|
CameraMatrix cm;
|
||||||
|
@ -7698,16 +7709,14 @@ void RendererSceneRenderRD::render_particle_collider_heightfield(RID p_collider,
|
||||||
|
|
||||||
RID fb = storage->particles_collision_get_heightfield_framebuffer(p_collider);
|
RID fb = storage->particles_collision_get_heightfield_framebuffer(p_collider);
|
||||||
|
|
||||||
_render_particle_collider_heightfield(fb, cam_xform, cm, p_cull_result, p_cull_count);
|
_render_particle_collider_heightfield(fb, cam_xform, cm, p_instances);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererSceneRenderRD::render_sdfgi_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const RID **p_positional_light_cull_result, const uint32_t *p_positional_light_cull_count) {
|
void RendererSceneRenderRD::render_sdfgi_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result) {
|
||||||
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
|
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
|
||||||
ERR_FAIL_COND(!rb);
|
ERR_FAIL_COND(!rb);
|
||||||
ERR_FAIL_COND(!rb->sdfgi);
|
ERR_FAIL_COND(!rb->sdfgi);
|
||||||
|
|
||||||
ERR_FAIL_COND(p_positional_light_cull_count == 0);
|
|
||||||
|
|
||||||
_sdfgi_update_cascades(p_render_buffers); //need cascades updated for this
|
_sdfgi_update_cascades(p_render_buffers); //need cascades updated for this
|
||||||
|
|
||||||
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
|
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
|
||||||
|
@ -7743,7 +7752,7 @@ void RendererSceneRenderRD::render_sdfgi_static_lights(RID p_render_buffers, uin
|
||||||
|
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
|
|
||||||
for (uint32_t j = 0; j < p_positional_light_cull_count[i]; j++) {
|
for (uint32_t j = 0; j < (uint32_t)p_positional_light_cull_result[i].size(); j++) {
|
||||||
if (idx == SDFGI::MAX_STATIC_LIGHTS) {
|
if (idx == SDFGI::MAX_STATIC_LIGHTS) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -7982,8 +7991,11 @@ TypedArray<Image> RendererSceneRenderRD::bake_render_uv2(RID p_base, const Vecto
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
InstanceBase *cull = &ins;
|
if (cull_argument.size() == 0) {
|
||||||
_render_uv2(&cull, 1, fb, Rect2i(0, 0, p_image_size.width, p_image_size.height));
|
cull_argument.push_back(nullptr);
|
||||||
|
}
|
||||||
|
cull_argument[0] = &ins;
|
||||||
|
_render_uv2(cull_argument, fb, Rect2i(0, 0, p_image_size.width, p_image_size.height));
|
||||||
|
|
||||||
TypedArray<Image> ret;
|
TypedArray<Image> ret;
|
||||||
|
|
||||||
|
@ -8534,6 +8546,8 @@ RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) {
|
||||||
environment_set_volumetric_fog_filter_active(GLOBAL_GET("rendering/volumetric_fog/use_filter"));
|
environment_set_volumetric_fog_filter_active(GLOBAL_GET("rendering/volumetric_fog/use_filter"));
|
||||||
environment_set_volumetric_fog_directional_shadow_shrink_size(GLOBAL_GET("rendering/volumetric_fog/directional_shadow_shrink"));
|
environment_set_volumetric_fog_directional_shadow_shrink_size(GLOBAL_GET("rendering/volumetric_fog/directional_shadow_shrink"));
|
||||||
environment_set_volumetric_fog_positional_shadow_shrink_size(GLOBAL_GET("rendering/volumetric_fog/positional_shadow_shrink"));
|
environment_set_volumetric_fog_positional_shadow_shrink_size(GLOBAL_GET("rendering/volumetric_fog/positional_shadow_shrink"));
|
||||||
|
|
||||||
|
cull_argument.set_page_pool(&cull_argument_pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
RendererSceneRenderRD::~RendererSceneRenderRD() {
|
RendererSceneRenderRD::~RendererSceneRenderRD() {
|
||||||
|
@ -8598,4 +8612,5 @@ RendererSceneRenderRD::~RendererSceneRenderRD() {
|
||||||
RD::get_singleton()->free(shadow_sampler);
|
RD::get_singleton()->free(shadow_sampler);
|
||||||
|
|
||||||
directional_shadow_atlas_set_size(0);
|
directional_shadow_atlas_set_size(0);
|
||||||
|
cull_argument.reset(); //avoid exit error
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,17 +104,17 @@ protected:
|
||||||
};
|
};
|
||||||
virtual RenderBufferData *_create_render_buffer_data() = 0;
|
virtual RenderBufferData *_create_render_buffer_data() = 0;
|
||||||
|
|
||||||
void _setup_lights(RID *p_light_cull_result, int p_light_cull_count, const Transform &p_camera_inverse_transform, RID p_shadow_atlas, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_positional_light_count);
|
void _setup_lights(const PagedArray<RID> &p_lights, const Transform &p_camera_inverse_transform, RID p_shadow_atlas, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_positional_light_count);
|
||||||
void _setup_decals(const RID *p_decal_instances, int p_decal_count, const Transform &p_camera_inverse_xform);
|
void _setup_decals(const PagedArray<RID> &p_decals, const Transform &p_camera_inverse_xform);
|
||||||
void _setup_reflections(RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, const Transform &p_camera_inverse_transform, RID p_environment);
|
void _setup_reflections(const PagedArray<RID> &p_reflections, const Transform &p_camera_inverse_transform, RID p_environment);
|
||||||
void _setup_giprobes(RID p_render_buffers, const Transform &p_transform, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, uint32_t &r_gi_probes_used);
|
void _setup_giprobes(RID p_render_buffers, const Transform &p_transform, const PagedArray<RID> &p_gi_probes, uint32_t &r_gi_probes_used);
|
||||||
|
|
||||||
virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, int p_directional_light_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_color, float p_screen_lod_threshold) = 0;
|
virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, int p_directional_light_count, const PagedArray<RID> &p_gi_probes, const PagedArray<InstanceBase *> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_color, float p_screen_lod_threshold) = 0;
|
||||||
virtual void _render_shadow(RID p_framebuffer, InstanceBase **p_cull_result, int p_cull_count, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0) = 0;
|
virtual void _render_shadow(RID p_framebuffer, const PagedArray<InstanceBase *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0) = 0;
|
||||||
virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) = 0;
|
virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0;
|
||||||
virtual void _render_uv2(InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) = 0;
|
virtual void _render_uv2(const PagedArray<InstanceBase *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0;
|
||||||
virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, InstanceBase **p_cull_result, int p_cull_count, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) = 0;
|
virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<InstanceBase *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) = 0;
|
||||||
virtual void _render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, InstanceBase **p_cull_result, int p_cull_count) = 0;
|
virtual void _render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<InstanceBase *> &p_instances) = 0;
|
||||||
|
|
||||||
virtual void _debug_giprobe(RID p_gi_probe, RenderingDevice::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha);
|
virtual void _debug_giprobe(RID p_gi_probe, RenderingDevice::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha);
|
||||||
void _debug_sdfgi_probes(RID p_render_buffers, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform);
|
void _debug_sdfgi_probes(RID p_render_buffers, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform);
|
||||||
|
@ -134,8 +134,11 @@ protected:
|
||||||
void _setup_sky(RID p_environment, RID p_render_buffers, const CameraMatrix &p_projection, const Transform &p_transform, const Size2i p_screen_size);
|
void _setup_sky(RID p_environment, RID p_render_buffers, const CameraMatrix &p_projection, const Transform &p_transform, const Size2i p_screen_size);
|
||||||
void _update_sky(RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform);
|
void _update_sky(RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform);
|
||||||
void _draw_sky(bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform);
|
void _draw_sky(bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform);
|
||||||
void _process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_ambient_buffer, RID p_reflection_buffer, RID p_gi_probe_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count);
|
void _process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_ambient_buffer, RID p_reflection_buffer, RID p_gi_probe_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform, const PagedArray<RID> &p_gi_probes);
|
||||||
|
|
||||||
|
// needed for a single argument calls (material and uv2)
|
||||||
|
PagedArrayPool<InstanceBase *> cull_argument_pool;
|
||||||
|
PagedArray<InstanceBase *> cull_argument; //need this to exist
|
||||||
private:
|
private:
|
||||||
RS::ViewportDebugDraw debug_draw = RS::VIEWPORT_DEBUG_DRAW_DISABLED;
|
RS::ViewportDebugDraw debug_draw = RS::VIEWPORT_DEBUG_DRAW_DISABLED;
|
||||||
double time_step = 0;
|
double time_step = 0;
|
||||||
|
@ -1513,7 +1516,7 @@ public:
|
||||||
virtual int sdfgi_get_pending_region_count(RID p_render_buffers) const;
|
virtual int sdfgi_get_pending_region_count(RID p_render_buffers) const;
|
||||||
virtual AABB sdfgi_get_pending_region_bounds(RID p_render_buffers, int p_region) const;
|
virtual AABB sdfgi_get_pending_region_bounds(RID p_render_buffers, int p_region) const;
|
||||||
virtual uint32_t sdfgi_get_pending_region_cascade(RID p_render_buffers, int p_region) const;
|
virtual uint32_t sdfgi_get_pending_region_cascade(RID p_render_buffers, int p_region) const;
|
||||||
virtual void sdfgi_update_probes(RID p_render_buffers, RID p_environment, const RID *p_directional_light_instances, uint32_t p_directional_light_count, const RID *p_positional_light_instances, uint32_t p_positional_light_count);
|
virtual void sdfgi_update_probes(RID p_render_buffers, RID p_environment, const PagedArray<RID> &p_directional_light_instances, const RID *p_positional_light_instances, uint32_t p_positional_light_count);
|
||||||
RID sdfgi_get_ubo() const { return gi.sdfgi_ubo; }
|
RID sdfgi_get_ubo() const { return gi.sdfgi_ubo; }
|
||||||
/* SKY API */
|
/* SKY API */
|
||||||
|
|
||||||
|
@ -1822,7 +1825,7 @@ public:
|
||||||
RID gi_probe_instance_create(RID p_base);
|
RID gi_probe_instance_create(RID p_base);
|
||||||
void gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform);
|
void gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform);
|
||||||
bool gi_probe_needs_update(RID p_probe) const;
|
bool gi_probe_needs_update(RID p_probe) const;
|
||||||
void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, int p_dynamic_object_count, InstanceBase **p_dynamic_objects);
|
void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::InstanceBase *> &p_dynamic_objects);
|
||||||
|
|
||||||
void gi_probe_set_quality(RS::GIProbeQuality p_quality) { gi_probe_quality = p_quality; }
|
void gi_probe_set_quality(RS::GIProbeQuality p_quality) { gi_probe_quality = p_quality; }
|
||||||
|
|
||||||
|
@ -1897,16 +1900,16 @@ public:
|
||||||
float render_buffers_get_volumetric_fog_end(RID p_render_buffers);
|
float render_buffers_get_volumetric_fog_end(RID p_render_buffers);
|
||||||
float render_buffers_get_volumetric_fog_detail_spread(RID p_render_buffers);
|
float render_buffers_get_volumetric_fog_detail_spread(RID p_render_buffers);
|
||||||
|
|
||||||
void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, RID p_environment, RID p_shadow_atlas, RID p_camera_effects, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold);
|
void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<InstanceBase *> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold);
|
||||||
|
|
||||||
void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_lod_threshold = 0.0);
|
void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<InstanceBase *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_lod_threshold = 0.0);
|
||||||
|
|
||||||
void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region);
|
void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, RID p_framebuffer, const Rect2i &p_region);
|
||||||
|
|
||||||
void render_sdfgi(RID p_render_buffers, int p_region, InstanceBase **p_cull_result, int p_cull_count);
|
void render_sdfgi(RID p_render_buffers, int p_region, const PagedArray<InstanceBase *> &p_instances);
|
||||||
void render_sdfgi_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const RID **p_positional_light_cull_result, const uint32_t *p_positional_light_cull_count);
|
void render_sdfgi_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result);
|
||||||
|
|
||||||
void render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, InstanceBase **p_cull_result, int p_cull_count);
|
void render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, const PagedArray<InstanceBase *> &p_instances);
|
||||||
|
|
||||||
virtual void set_scene_pass(uint64_t p_pass) {
|
virtual void set_scene_pass(uint64_t p_pass) {
|
||||||
scene_pass = p_pass;
|
scene_pass = p_pass;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -34,30 +34,25 @@
|
||||||
#include "core/templates/pass_func.h"
|
#include "core/templates/pass_func.h"
|
||||||
#include "servers/rendering/renderer_compositor.h"
|
#include "servers/rendering/renderer_compositor.h"
|
||||||
|
|
||||||
|
#include "core/math/dynamic_bvh.h"
|
||||||
#include "core/math/geometry_3d.h"
|
#include "core/math/geometry_3d.h"
|
||||||
#include "core/math/octree.h"
|
#include "core/math/octree.h"
|
||||||
#include "core/os/semaphore.h"
|
#include "core/os/semaphore.h"
|
||||||
#include "core/os/thread.h"
|
#include "core/os/thread.h"
|
||||||
#include "core/templates/local_vector.h"
|
#include "core/templates/local_vector.h"
|
||||||
|
#include "core/templates/paged_allocator.h"
|
||||||
|
#include "core/templates/paged_array.h"
|
||||||
#include "core/templates/rid_owner.h"
|
#include "core/templates/rid_owner.h"
|
||||||
#include "core/templates/self_list.h"
|
#include "core/templates/self_list.h"
|
||||||
#include "servers/rendering/renderer_scene.h"
|
#include "servers/rendering/renderer_scene.h"
|
||||||
#include "servers/rendering/renderer_scene_render.h"
|
#include "servers/rendering/renderer_scene_render.h"
|
||||||
#include "servers/xr/xr_interface.h"
|
#include "servers/xr/xr_interface.h"
|
||||||
|
|
||||||
class RendererSceneCull : public RendererScene {
|
class RendererSceneCull : public RendererScene {
|
||||||
public:
|
public:
|
||||||
RendererSceneRender *scene_render;
|
RendererSceneRender *scene_render;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
MAX_INSTANCE_CULL = 65536,
|
SDFGI_MAX_CASCADES = 8
|
||||||
MAX_LIGHTS_CULLED = 4096,
|
|
||||||
MAX_REFLECTION_PROBES_CULLED = 4096,
|
|
||||||
MAX_DECALS_CULLED = 4096,
|
|
||||||
MAX_GI_PROBES_CULLED = 4096,
|
|
||||||
MAX_ROOM_CULL = 32,
|
|
||||||
MAX_LIGHTMAPS_CULLED = 4096,
|
|
||||||
MAX_EXTERIOR_PORTALS = 128,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
uint64_t render_pass;
|
uint64_t render_pass;
|
||||||
|
@ -114,11 +109,17 @@ public:
|
||||||
struct Instance;
|
struct Instance;
|
||||||
|
|
||||||
struct Scenario {
|
struct Scenario {
|
||||||
|
enum IndexerType {
|
||||||
|
INDEXER_GEOMETRY, //for geometry
|
||||||
|
INDEXER_VOLUMES, //for everything else
|
||||||
|
INDEXER_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
DynamicBVH indexers[INDEXER_MAX];
|
||||||
|
|
||||||
RS::ScenarioDebugMode debug;
|
RS::ScenarioDebugMode debug;
|
||||||
RID self;
|
RID self;
|
||||||
|
|
||||||
Octree<Instance, true> octree;
|
|
||||||
|
|
||||||
List<Instance *> directional_lights;
|
List<Instance *> directional_lights;
|
||||||
RID environment;
|
RID environment;
|
||||||
RID fallback_environment;
|
RID fallback_environment;
|
||||||
|
@ -130,13 +131,19 @@ public:
|
||||||
|
|
||||||
LocalVector<RID> dynamic_lights;
|
LocalVector<RID> dynamic_lights;
|
||||||
|
|
||||||
Scenario() { debug = RS::SCENARIO_DEBUG_DISABLED; }
|
Scenario() {
|
||||||
|
indexers[INDEXER_GEOMETRY].set_index(INDEXER_GEOMETRY);
|
||||||
|
indexers[INDEXER_VOLUMES].set_index(INDEXER_VOLUMES);
|
||||||
|
debug = RS::SCENARIO_DEBUG_DISABLED;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int indexer_update_iterations = 0;
|
||||||
|
|
||||||
mutable RID_PtrOwner<Scenario> scenario_owner;
|
mutable RID_PtrOwner<Scenario> scenario_owner;
|
||||||
|
|
||||||
static void *_instance_pair(void *p_self, OctreeElementID, Instance *p_A, int, OctreeElementID, Instance *p_B, int);
|
static void _instance_pair(Instance *p_A, Instance *p_B);
|
||||||
static void _instance_unpair(void *p_self, OctreeElementID, Instance *p_A, int, OctreeElementID, Instance *p_B, int, void *);
|
static void _instance_unpair(Instance *p_A, Instance *p_B);
|
||||||
|
|
||||||
static void _instance_update_mesh_instance(Instance *p_instance);
|
static void _instance_update_mesh_instance(Instance *p_instance);
|
||||||
|
|
||||||
|
@ -152,6 +159,17 @@ public:
|
||||||
|
|
||||||
/* INSTANCING API */
|
/* INSTANCING API */
|
||||||
|
|
||||||
|
struct InstancePair {
|
||||||
|
Instance *a;
|
||||||
|
Instance *b;
|
||||||
|
SelfList<InstancePair> list_a;
|
||||||
|
SelfList<InstancePair> list_b;
|
||||||
|
InstancePair() :
|
||||||
|
list_a(this), list_b(this) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
PagedAllocator<InstancePair> pair_allocator;
|
||||||
|
|
||||||
struct InstanceBaseData {
|
struct InstanceBaseData {
|
||||||
virtual ~InstanceBaseData() {}
|
virtual ~InstanceBaseData() {}
|
||||||
};
|
};
|
||||||
|
@ -159,7 +177,7 @@ public:
|
||||||
struct Instance : RendererSceneRender::InstanceBase {
|
struct Instance : RendererSceneRender::InstanceBase {
|
||||||
RID self;
|
RID self;
|
||||||
//scenario stuff
|
//scenario stuff
|
||||||
OctreeElementID octree_id;
|
DynamicBVH::ID indexer_id;
|
||||||
Scenario *scenario;
|
Scenario *scenario;
|
||||||
SelfList<Instance> scenario_item;
|
SelfList<Instance> scenario_item;
|
||||||
|
|
||||||
|
@ -188,6 +206,9 @@ public:
|
||||||
|
|
||||||
InstanceBaseData *base_data;
|
InstanceBaseData *base_data;
|
||||||
|
|
||||||
|
SelfList<InstancePair>::List pairs;
|
||||||
|
uint64_t pair_check;
|
||||||
|
|
||||||
virtual void dependency_deleted(RID p_dependency) {
|
virtual void dependency_deleted(RID p_dependency) {
|
||||||
if (p_dependency == base) {
|
if (p_dependency == base) {
|
||||||
singleton->instance_set_base(self, RID());
|
singleton->instance_set_base(self, RID());
|
||||||
|
@ -205,7 +226,6 @@ public:
|
||||||
Instance() :
|
Instance() :
|
||||||
scenario_item(this),
|
scenario_item(this),
|
||||||
update_item(this) {
|
update_item(this) {
|
||||||
octree_id = 0;
|
|
||||||
scenario = nullptr;
|
scenario = nullptr;
|
||||||
|
|
||||||
update_aabb = false;
|
update_aabb = false;
|
||||||
|
@ -226,6 +246,8 @@ public:
|
||||||
base_data = nullptr;
|
base_data = nullptr;
|
||||||
|
|
||||||
custom_aabb = nullptr;
|
custom_aabb = nullptr;
|
||||||
|
|
||||||
|
pair_check = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
~Instance() {
|
~Instance() {
|
||||||
|
@ -242,21 +264,21 @@ public:
|
||||||
void _instance_queue_update(Instance *p_instance, bool p_update_aabb, bool p_update_dependencies = false);
|
void _instance_queue_update(Instance *p_instance, bool p_update_aabb, bool p_update_dependencies = false);
|
||||||
|
|
||||||
struct InstanceGeometryData : public InstanceBaseData {
|
struct InstanceGeometryData : public InstanceBaseData {
|
||||||
List<Instance *> lighting;
|
Set<Instance *> lights;
|
||||||
bool lighting_dirty;
|
bool lighting_dirty;
|
||||||
bool can_cast_shadows;
|
bool can_cast_shadows;
|
||||||
bool material_is_animated;
|
bool material_is_animated;
|
||||||
|
|
||||||
List<Instance *> decals;
|
Set<Instance *> decals;
|
||||||
bool decal_dirty;
|
bool decal_dirty;
|
||||||
|
|
||||||
List<Instance *> reflection_probes;
|
Set<Instance *> reflection_probes;
|
||||||
bool reflection_dirty;
|
bool reflection_dirty;
|
||||||
|
|
||||||
List<Instance *> gi_probes;
|
Set<Instance *> gi_probes;
|
||||||
bool gi_probes_dirty;
|
bool gi_probes_dirty;
|
||||||
|
|
||||||
List<Instance *> lightmap_captures;
|
Set<Instance *> lightmap_captures;
|
||||||
|
|
||||||
InstanceGeometryData() {
|
InstanceGeometryData() {
|
||||||
lighting_dirty = false;
|
lighting_dirty = false;
|
||||||
|
@ -271,11 +293,7 @@ public:
|
||||||
struct InstanceReflectionProbeData : public InstanceBaseData {
|
struct InstanceReflectionProbeData : public InstanceBaseData {
|
||||||
Instance *owner;
|
Instance *owner;
|
||||||
|
|
||||||
struct PairInfo {
|
Set<Instance *> geometries;
|
||||||
List<Instance *>::Element *L; //reflection iterator in geometry
|
|
||||||
Instance *geometry;
|
|
||||||
};
|
|
||||||
List<PairInfo> geometries;
|
|
||||||
|
|
||||||
RID instance;
|
RID instance;
|
||||||
bool reflection_dirty;
|
bool reflection_dirty;
|
||||||
|
@ -294,11 +312,7 @@ public:
|
||||||
Instance *owner;
|
Instance *owner;
|
||||||
RID instance;
|
RID instance;
|
||||||
|
|
||||||
struct PairInfo {
|
Set<Instance *> geometries;
|
||||||
List<Instance *>::Element *L; //reflection iterator in geometry
|
|
||||||
Instance *geometry;
|
|
||||||
};
|
|
||||||
List<PairInfo> geometries;
|
|
||||||
|
|
||||||
InstanceDecalData() {
|
InstanceDecalData() {
|
||||||
}
|
}
|
||||||
|
@ -307,18 +321,13 @@ public:
|
||||||
SelfList<InstanceReflectionProbeData>::List reflection_probe_render_list;
|
SelfList<InstanceReflectionProbeData>::List reflection_probe_render_list;
|
||||||
|
|
||||||
struct InstanceLightData : public InstanceBaseData {
|
struct InstanceLightData : public InstanceBaseData {
|
||||||
struct PairInfo {
|
|
||||||
List<Instance *>::Element *L; //light iterator in geometry
|
|
||||||
Instance *geometry;
|
|
||||||
};
|
|
||||||
|
|
||||||
RID instance;
|
RID instance;
|
||||||
uint64_t last_version;
|
uint64_t last_version;
|
||||||
List<Instance *>::Element *D; // directional light in scenario
|
List<Instance *>::Element *D; // directional light in scenario
|
||||||
|
|
||||||
bool shadow_dirty;
|
bool shadow_dirty;
|
||||||
|
|
||||||
List<PairInfo> geometries;
|
Set<Instance *> geometries;
|
||||||
|
|
||||||
Instance *baked_light;
|
Instance *baked_light;
|
||||||
|
|
||||||
|
@ -339,13 +348,8 @@ public:
|
||||||
struct InstanceGIProbeData : public InstanceBaseData {
|
struct InstanceGIProbeData : public InstanceBaseData {
|
||||||
Instance *owner;
|
Instance *owner;
|
||||||
|
|
||||||
struct PairInfo {
|
Set<Instance *> geometries;
|
||||||
List<Instance *>::Element *L; //gi probe iterator in geometry
|
Set<Instance *> dynamic_geometries;
|
||||||
Instance *geometry;
|
|
||||||
};
|
|
||||||
|
|
||||||
List<PairInfo> geometries;
|
|
||||||
List<PairInfo> dynamic_geometries;
|
|
||||||
|
|
||||||
Set<Instance *> lights;
|
Set<Instance *> lights;
|
||||||
|
|
||||||
|
@ -383,40 +387,110 @@ public:
|
||||||
SelfList<InstanceGIProbeData>::List gi_probe_update_list;
|
SelfList<InstanceGIProbeData>::List gi_probe_update_list;
|
||||||
|
|
||||||
struct InstanceLightmapData : public InstanceBaseData {
|
struct InstanceLightmapData : public InstanceBaseData {
|
||||||
struct PairInfo {
|
Set<Instance *> geometries;
|
||||||
List<Instance *>::Element *L; //iterator in geometry
|
|
||||||
Instance *geometry;
|
|
||||||
};
|
|
||||||
List<PairInfo> geometries;
|
|
||||||
|
|
||||||
Set<Instance *> users;
|
Set<Instance *> users;
|
||||||
|
|
||||||
InstanceLightmapData() {
|
InstanceLightmapData() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
uint64_t pair_pass = 1;
|
||||||
|
|
||||||
|
struct PairInstances {
|
||||||
|
Instance *instance = nullptr;
|
||||||
|
PagedAllocator<InstancePair> *pair_allocator = nullptr;
|
||||||
|
SelfList<InstancePair>::List pairs_found;
|
||||||
|
DynamicBVH *bvh = nullptr;
|
||||||
|
DynamicBVH *bvh2 = nullptr; //some may need to cull in two
|
||||||
|
uint32_t pair_mask;
|
||||||
|
uint64_t pair_pass;
|
||||||
|
|
||||||
|
_FORCE_INLINE_ bool operator()(void *p_data) {
|
||||||
|
Instance *p_instance = (Instance *)p_data;
|
||||||
|
if (instance != p_instance && instance->transformed_aabb.intersects(p_instance->transformed_aabb) && (pair_mask & (1 << p_instance->base_type))) {
|
||||||
|
//test is more coarse in indexer
|
||||||
|
p_instance->pair_check = pair_pass;
|
||||||
|
InstancePair *pair = pair_allocator->alloc();
|
||||||
|
pair->a = instance;
|
||||||
|
pair->b = p_instance;
|
||||||
|
pairs_found.add(&pair->list_a);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pair() {
|
||||||
|
if (bvh) {
|
||||||
|
bvh->aabb_query(instance->transformed_aabb, *this);
|
||||||
|
}
|
||||||
|
if (bvh2) {
|
||||||
|
bvh2->aabb_query(instance->transformed_aabb, *this);
|
||||||
|
}
|
||||||
|
while (instance->pairs.first()) {
|
||||||
|
InstancePair *pair = instance->pairs.first()->self();
|
||||||
|
Instance *other_instance = instance == pair->a ? pair->b : pair->a;
|
||||||
|
if (other_instance->pair_check != pair_pass) {
|
||||||
|
//unpaired
|
||||||
|
_instance_unpair(instance, other_instance);
|
||||||
|
} else {
|
||||||
|
//kept
|
||||||
|
other_instance->pair_check = 0; // if kept, then put pair check to zero, so we can distinguish with the newly added ones
|
||||||
|
}
|
||||||
|
|
||||||
|
pair_allocator->free(pair);
|
||||||
|
}
|
||||||
|
while (pairs_found.first()) {
|
||||||
|
InstancePair *pair = pairs_found.first()->self();
|
||||||
|
pairs_found.remove(pairs_found.first());
|
||||||
|
|
||||||
|
if (pair->b->pair_check == pair_pass) {
|
||||||
|
//paired
|
||||||
|
_instance_pair(instance, pair->b);
|
||||||
|
}
|
||||||
|
pair->a->pairs.add(&pair->list_a);
|
||||||
|
pair->b->pairs.add(&pair->list_b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CullResult {
|
||||||
|
PagedArray<Instance *> *result;
|
||||||
|
_FORCE_INLINE_ bool operator()(void *p_data) {
|
||||||
|
Instance *p_instance = (Instance *)p_data;
|
||||||
|
result->push_back(p_instance);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Set<Instance *> heightfield_particle_colliders_update_list;
|
Set<Instance *> heightfield_particle_colliders_update_list;
|
||||||
|
|
||||||
int instance_cull_count;
|
PagedArrayPool<Instance *> instance_cull_page_pool;
|
||||||
Instance *instance_cull_result[MAX_INSTANCE_CULL];
|
PagedArrayPool<RendererSceneRender::InstanceBase *> base_instance_cull_page_pool;
|
||||||
Instance *instance_shadow_cull_result[MAX_INSTANCE_CULL]; //used for generating shadowmaps
|
PagedArrayPool<RID> rid_cull_page_pool;
|
||||||
Instance *light_cull_result[MAX_LIGHTS_CULLED];
|
|
||||||
RID sdfgi_light_cull_result[MAX_LIGHTS_CULLED];
|
PagedArray<Instance *> instance_cull_result;
|
||||||
RID light_instance_cull_result[MAX_LIGHTS_CULLED];
|
PagedArray<RendererSceneRender::InstanceBase *> geometry_instances_to_render;
|
||||||
|
PagedArray<Instance *> instance_shadow_cull_result;
|
||||||
|
PagedArray<RendererSceneRender::InstanceBase *> geometry_instances_to_shadow_render;
|
||||||
|
PagedArray<Instance *> instance_sdfgi_cull_result;
|
||||||
|
PagedArray<RendererSceneRender::InstanceBase *> geometry_instances_to_sdfgi_render;
|
||||||
|
PagedArray<Instance *> light_cull_result;
|
||||||
|
PagedArray<RendererSceneRender::InstanceBase *> lightmap_cull_result;
|
||||||
|
PagedArray<Instance *> directional_shadow_cull_result;
|
||||||
|
PagedArray<RID> reflection_probe_instance_cull_result;
|
||||||
|
PagedArray<RID> light_instance_cull_result;
|
||||||
|
PagedArray<RID> directional_light_cull_result;
|
||||||
|
PagedArray<RID> gi_probe_instance_cull_result;
|
||||||
|
PagedArray<RID> decal_instance_cull_result;
|
||||||
|
|
||||||
|
PagedArray<RID> sdfgi_cascade_lights[SDFGI_MAX_CASCADES];
|
||||||
|
|
||||||
uint64_t sdfgi_light_cull_pass = 0;
|
uint64_t sdfgi_light_cull_pass = 0;
|
||||||
int light_cull_count;
|
|
||||||
int directional_light_count;
|
int directional_light_count;
|
||||||
RID reflection_probe_instance_cull_result[MAX_REFLECTION_PROBES_CULLED];
|
|
||||||
RID decal_instance_cull_result[MAX_DECALS_CULLED];
|
|
||||||
int reflection_probe_cull_count;
|
|
||||||
int decal_cull_count;
|
|
||||||
RID gi_probe_instance_cull_result[MAX_GI_PROBES_CULLED];
|
|
||||||
int gi_probe_cull_count;
|
|
||||||
Instance *lightmap_cull_result[MAX_LIGHTS_CULLED];
|
|
||||||
int lightmap_cull_count;
|
|
||||||
|
|
||||||
RID_PtrOwner<Instance> instance_owner;
|
RID_PtrOwner<Instance> instance_owner;
|
||||||
|
|
||||||
|
bool pair_volumes_to_mesh; // used in traditional forward, unnecesary on clustered
|
||||||
|
|
||||||
virtual RID instance_create();
|
virtual RID instance_create();
|
||||||
|
|
||||||
virtual void instance_set_base(RID p_instance, RID p_base);
|
virtual void instance_set_base(RID p_instance, RID p_base);
|
||||||
|
@ -460,6 +534,7 @@ public:
|
||||||
_FORCE_INLINE_ void _update_instance_aabb(Instance *p_instance);
|
_FORCE_INLINE_ void _update_instance_aabb(Instance *p_instance);
|
||||||
_FORCE_INLINE_ void _update_dirty_instance(Instance *p_instance);
|
_FORCE_INLINE_ void _update_dirty_instance(Instance *p_instance);
|
||||||
_FORCE_INLINE_ void _update_instance_lightmap_captures(Instance *p_instance);
|
_FORCE_INLINE_ void _update_instance_lightmap_captures(Instance *p_instance);
|
||||||
|
void _unpair_instance(Instance *p_instance);
|
||||||
|
|
||||||
_FORCE_INLINE_ bool _light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario, float p_scren_lod_threshold);
|
_FORCE_INLINE_ bool _light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario, float p_scren_lod_threshold);
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#define RENDERINGSERVERSCENERENDER_H
|
#define RENDERINGSERVERSCENERENDER_H
|
||||||
|
|
||||||
#include "core/math/camera_matrix.h"
|
#include "core/math/camera_matrix.h"
|
||||||
|
#include "core/templates/paged_array.h"
|
||||||
#include "servers/rendering/renderer_storage.h"
|
#include "servers/rendering/renderer_storage.h"
|
||||||
|
|
||||||
class RendererSceneRender {
|
class RendererSceneRender {
|
||||||
|
@ -55,7 +56,7 @@ public:
|
||||||
virtual int sdfgi_get_pending_region_count(RID p_render_buffers) const = 0;
|
virtual int sdfgi_get_pending_region_count(RID p_render_buffers) const = 0;
|
||||||
virtual AABB sdfgi_get_pending_region_bounds(RID p_render_buffers, int p_region) const = 0;
|
virtual AABB sdfgi_get_pending_region_bounds(RID p_render_buffers, int p_region) const = 0;
|
||||||
virtual uint32_t sdfgi_get_pending_region_cascade(RID p_render_buffers, int p_region) const = 0;
|
virtual uint32_t sdfgi_get_pending_region_cascade(RID p_render_buffers, int p_region) const = 0;
|
||||||
virtual void sdfgi_update_probes(RID p_render_buffers, RID p_environment, const RID *p_directional_light_instances, uint32_t p_directional_light_count, const RID *p_positional_light_instances, uint32_t p_positional_light_count) = 0;
|
virtual void sdfgi_update_probes(RID p_render_buffers, RID p_environment, const PagedArray<RID> &p_directionals, const RID *p_positional_light_instances, uint32_t p_positional_light_count) = 0;
|
||||||
|
|
||||||
/* SKY API */
|
/* SKY API */
|
||||||
|
|
||||||
|
@ -231,17 +232,17 @@ public:
|
||||||
virtual RID gi_probe_instance_create(RID p_gi_probe) = 0;
|
virtual RID gi_probe_instance_create(RID p_gi_probe) = 0;
|
||||||
virtual void gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform) = 0;
|
virtual void gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform) = 0;
|
||||||
virtual bool gi_probe_needs_update(RID p_probe) const = 0;
|
virtual bool gi_probe_needs_update(RID p_probe) const = 0;
|
||||||
virtual void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, int p_dynamic_object_count, InstanceBase **p_dynamic_objects) = 0;
|
virtual void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::InstanceBase *> &p_dynamic_objects) = 0;
|
||||||
|
|
||||||
virtual void gi_probe_set_quality(RS::GIProbeQuality) = 0;
|
virtual void gi_probe_set_quality(RS::GIProbeQuality) = 0;
|
||||||
|
|
||||||
virtual void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold) = 0;
|
virtual void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<InstanceBase *> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold) = 0;
|
||||||
|
|
||||||
virtual void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_lod_threshold = 0.0) = 0;
|
virtual void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<InstanceBase *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_lod_threshold = 0.0) = 0;
|
||||||
virtual void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) = 0;
|
virtual void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0;
|
||||||
virtual void render_sdfgi(RID p_render_buffers, int p_region, InstanceBase **p_cull_result, int p_cull_count) = 0;
|
virtual void render_sdfgi(RID p_render_buffers, int p_region, const PagedArray<InstanceBase *> &p_instances) = 0;
|
||||||
virtual void render_sdfgi_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const RID **p_positional_light_cull_result, const uint32_t *p_positional_light_cull_count) = 0;
|
virtual void render_sdfgi_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_lights) = 0;
|
||||||
virtual void render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, InstanceBase **p_cull_result, int p_cull_count) = 0;
|
virtual void render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, const PagedArray<InstanceBase *> &p_instances) = 0;
|
||||||
|
|
||||||
virtual void set_scene_pass(uint64_t p_pass) = 0;
|
virtual void set_scene_pass(uint64_t p_pass) = 0;
|
||||||
virtual void set_time(double p_time, double p_step) = 0;
|
virtual void set_time(double p_time, double p_step) = 0;
|
||||||
|
|
|
@ -2359,6 +2359,9 @@ RenderingServer::RenderingServer() {
|
||||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/volumetric_fog/directional_shadow_shrink", PropertyInfo(Variant::INT, "rendering/volumetric_fog/directional_shadow_shrink", PROPERTY_HINT_RANGE, "32,2048,1"));
|
ProjectSettings::get_singleton()->set_custom_property_info("rendering/volumetric_fog/directional_shadow_shrink", PropertyInfo(Variant::INT, "rendering/volumetric_fog/directional_shadow_shrink", PROPERTY_HINT_RANGE, "32,2048,1"));
|
||||||
GLOBAL_DEF("rendering/volumetric_fog/positional_shadow_shrink", 512);
|
GLOBAL_DEF("rendering/volumetric_fog/positional_shadow_shrink", 512);
|
||||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/volumetric_fog/positional_shadow_shrink", PropertyInfo(Variant::INT, "rendering/volumetric_fog/positional_shadow_shrink", PROPERTY_HINT_RANGE, "32,2048,1"));
|
ProjectSettings::get_singleton()->set_custom_property_info("rendering/volumetric_fog/positional_shadow_shrink", PropertyInfo(Variant::INT, "rendering/volumetric_fog/positional_shadow_shrink", PROPERTY_HINT_RANGE, "32,2048,1"));
|
||||||
|
|
||||||
|
GLOBAL_DEF("rendering/spatial_indexer/update_iterations_per_frame", 10);
|
||||||
|
ProjectSettings::get_singleton()->set_custom_property_info("rendering/spatial_indexer/update_iterations_per_frame", PropertyInfo(Variant::INT, "rendering/spatial_indexer/update_iterations_per_frame", PROPERTY_HINT_RANGE, "0,1024,1"));
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderingServer::~RenderingServer() {
|
RenderingServer::~RenderingServer() {
|
||||||
|
|
Loading…
Reference in New Issue