Commit ee1e89f8 by Juan Linietsky

Modified rendering to use cluster instead of foward

parent f8b5c5f0
......@@ -244,6 +244,18 @@ void Basis::scale_local(const Vector3 &p_scale) {
*this = scaled_local(p_scale);
}
float Basis::get_uniform_scale() const {
return (elements[0].length() + elements[1].length() + elements[2].length()) / 3.0;
}
void Basis::make_scale_uniform() {
float l = (elements[0].length() + elements[1].length() + elements[2].length()) / 3.0;
for (int i = 0; i < 3; i++) {
elements[i].normalize();
elements[i] *= l;
}
}
Basis Basis::scaled_local(const Vector3 &p_scale) const {
Basis b;
b.set_diagonal(p_scale);
......
......@@ -108,6 +108,9 @@ public:
void scale_local(const Vector3 &p_scale);
Basis scaled_local(const Vector3 &p_scale) const;
void make_scale_uniform();
float get_uniform_scale() const;
Vector3 get_scale() const;
Vector3 get_scale_abs() const;
Vector3 get_scale_local() const;
......
......@@ -276,6 +276,36 @@ Vector2 CameraMatrix::get_viewport_half_extents() const {
return Vector2(res.x, res.y);
}
void CameraMatrix::get_far_plane_size(real_t &r_width, real_t &r_height) const {
const real_t *matrix = (const real_t *)this->matrix;
///////--- Far Plane ---///////
Plane far_plane = Plane(matrix[3] - matrix[2],
matrix[7] - matrix[6],
matrix[11] - matrix[10],
-matrix[15] + matrix[14]);
far_plane.normalize();
///////--- Right Plane ---///////
Plane right_plane = Plane(matrix[3] - matrix[0],
matrix[7] - matrix[4],
matrix[11] - matrix[8],
-matrix[15] + matrix[12]);
right_plane.normalize();
Plane top_plane = Plane(matrix[3] - matrix[1],
matrix[7] - matrix[5],
matrix[11] - matrix[9],
-matrix[15] + matrix[13]);
top_plane.normalize();
Vector3 res;
far_plane.intersect_3(right_plane, top_plane, &res);
r_width = res.x;
r_height = res.y;
}
bool CameraMatrix::get_endpoints(const Transform &p_transform, Vector3 *p_8points) const {
Vector<Plane> planes = get_projection_planes(Transform());
......
......@@ -75,6 +75,7 @@ struct CameraMatrix {
bool get_endpoints(const Transform &p_transform, Vector3 *p_8points) const;
Vector2 get_viewport_half_extents() const;
void get_far_plane_size(real_t &r_width, real_t &r_height) const;
void invert();
CameraMatrix inverse() const;
......@@ -93,6 +94,21 @@ struct CameraMatrix {
void flip_y();
bool operator==(const CameraMatrix &p_cam) const {
for (uint32_t i = 0; i < 4; i++) {
for (uint32_t j = 0; j < 4; j++) {
if (matrix[i][j] != p_cam.matrix[i][j]) {
return false;
}
}
}
return true;
}
bool operator!=(const CameraMatrix &p_cam) const {
return !(*this == p_cam);
}
CameraMatrix();
CameraMatrix(const Transform &p_transform);
~CameraMatrix();
......
#include "light_cluster_builder.h"
void LightClusterBuilder::begin(const Transform &p_view_transform, const CameraMatrix &p_cam_projection) {
view_xform = p_view_transform;
projection = p_cam_projection;
z_near = -projection.get_z_near();
z_far = -projection.get_z_far();
//reset counts
light_count = 0;
refprobe_count = 0;
item_count = 0;
sort_id_count = 0;
}
void LightClusterBuilder::bake_cluster() {
float slice_depth = (z_near - z_far) / depth;
PoolVector<uint8_t>::Write cluster_dataw = cluster_data.write();
Cell *cluster_data_ptr = (Cell *)cluster_dataw.ptr();
//clear the cluster
zeromem(cluster_data_ptr, (width * height * depth * sizeof(Cell)));
/* Step 1, create cell positions and count them */
for (uint32_t i = 0; i < item_count; i++) {
const Item &item = items[i];
int from_slice = Math::floor((z_near - (item.aabb.position.z + item.aabb.size.z)) / slice_depth);
int to_slice = Math::floor((z_near - item.aabb.position.z) / slice_depth);
if (from_slice >= (int)depth || to_slice < 0) {
continue; //sorry no go
}
from_slice = MAX(0, from_slice);
to_slice = MIN((int)depth - 1, to_slice);
for (int j = from_slice; j <= to_slice; j++) {
Vector3 min = item.aabb.position;
Vector3 max = item.aabb.position + item.aabb.size;
float limit_near = MIN((z_near - slice_depth * j), max.z);
float limit_far = MAX((z_near - slice_depth * (j + 1)), min.z);
max.z = limit_near;
min.z = limit_near;
Vector3 proj_min = projection.xform(min);
Vector3 proj_max = projection.xform(max);
int near_from_x = int(Math::floor((proj_min.x * 0.5 + 0.5) * width));
int near_from_y = int(Math::floor((-proj_max.y * 0.5 + 0.5) * height));
int near_to_x = int(Math::floor((proj_max.x * 0.5 + 0.5) * width));
int near_to_y = int(Math::floor((-proj_min.y * 0.5 + 0.5) * height));
max.z = limit_far;
min.z = limit_far;
proj_min = projection.xform(min);
proj_max = projection.xform(max);
int far_from_x = int(Math::floor((proj_min.x * 0.5 + 0.5) * width));
int far_from_y = int(Math::floor((-proj_max.y * 0.5 + 0.5) * height));
int far_to_x = int(Math::floor((proj_max.x * 0.5 + 0.5) * width));
int far_to_y = int(Math::floor((-proj_min.y * 0.5 + 0.5) * height));
//print_line(itos(j) + " near - " + Vector2i(near_from_x, near_from_y) + " -> " + Vector2i(near_to_x, near_to_y));
//print_line(itos(j) + " far - " + Vector2i(far_from_x, far_from_y) + " -> " + Vector2i(far_to_x, far_to_y));
int from_x = MIN(near_from_x, far_from_x);
int from_y = MIN(near_from_y, far_from_y);
int to_x = MAX(near_to_x, far_to_x);
int to_y = MAX(near_to_y, far_to_y);
if (from_x >= (int)width || to_x < 0 || from_y >= (int)height || to_y < 0) {
continue;
}
int sx = MAX(0, from_x);
int sy = MAX(0, from_y);
int dx = MIN(width - 1, to_x);
int dy = MIN(height - 1, to_y);
//print_line(itos(j) + " - " + Vector2i(sx, sy) + " -> " + Vector2i(dx, dy));
for (int x = sx; x <= dx; x++) {
for (int y = sy; y <= dy; y++) {
uint32_t offset = j * (width * height) + y * width + x;
if (unlikely(sort_id_count == sort_id_max)) {
sort_id_max = nearest_power_of_2_templated(sort_id_max + 1);
sort_ids = (SortID *)memrealloc(sort_ids, sizeof(SortID) * sort_id_max);
if (ids.size()) {
ids.resize(sort_id_max);
RD::get_singleton()->free(items_buffer);
items_buffer = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t) * sort_id_max);
}
}
sort_ids[sort_id_count].cell_index = offset;
sort_ids[sort_id_count].item_index = item.index;
sort_ids[sort_id_count].item_type = item.type;
sort_id_count++;
//for now, only count
cluster_data_ptr[offset].item_pointers[item.type]++;
//print_line("at offset " + itos(offset) + " value: " + itos(cluster_data_ptr[offset].item_pointers[item.type]));
}
}
}
}
/* Step 2, Assign pointers (and reset counters) */
uint32_t offset = 0;
for (uint32_t i = 0; i < (width * height * depth); i++) {
for (int j = 0; j < ITEM_TYPE_MAX; j++) {
uint32_t count = cluster_data_ptr[i].item_pointers[j]; //save count
cluster_data_ptr[i].item_pointers[j] = offset; //replace count by pointer
offset += count; //increase offset by count;
}
}
//print_line("offset: " + itos(offset));
/* Step 3, Place item lists */
PoolVector<uint32_t>::Write idsw = ids.write();
uint32_t *ids_ptr = idsw.ptr();
for (uint32_t i = 0; i < sort_id_count; i++) {
const SortID &id = sort_ids[i];
Cell &cell = cluster_data_ptr[id.cell_index];
uint32_t pointer = cell.item_pointers[id.item_type] & POINTER_MASK;
uint32_t counter = cell.item_pointers[id.item_type] >> COUNTER_SHIFT;
ids_ptr[pointer + counter] = id.item_index;
cell.item_pointers[id.item_type] = pointer | ((counter + 1) << COUNTER_SHIFT);
}
cluster_dataw = PoolVector<uint8_t>::Write();
RD::get_singleton()->texture_update(cluster_texture, 0, cluster_data, true);
RD::get_singleton()->buffer_update(items_buffer, 0, offset * sizeof(uint32_t), ids_ptr, true);
idsw = PoolVector<uint32_t>::Write();
}
void LightClusterBuilder::setup(uint32_t p_width, uint32_t p_height, uint32_t p_depth) {
if (width == p_width && height == p_height && depth == p_depth) {
return;
}
if (cluster_texture.is_valid()) {
RD::get_singleton()->free(cluster_texture);
}
width = p_width;
height = p_height;
depth = p_depth;
cluster_data.resize(width * height * depth * sizeof(Cell));
{
RD::TextureFormat tf;
tf.format = RD::DATA_FORMAT_R32G32B32A32_UINT;
tf.type = RD::TEXTURE_TYPE_3D;
tf.width = width;
tf.height = height;
tf.depth = depth;
tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
cluster_texture = RD::get_singleton()->texture_create(tf, RD::TextureView());
}
}
RID LightClusterBuilder::get_cluster_texture() const {
return cluster_texture;
}
RID LightClusterBuilder::get_cluster_indices_buffer() const {
return items_buffer;
}
LightClusterBuilder::LightClusterBuilder() {
//initialize accumulators to something
lights = (LightData *)memalloc(sizeof(LightData) * 1024);
light_max = 1024;
refprobes = (OrientedBoxData *)memalloc(sizeof(OrientedBoxData) * 1024);
refprobe_max = 1024;
decals = (OrientedBoxData *)memalloc(sizeof(OrientedBoxData) * 1024);
decal_max = 1024;
items = (Item *)memalloc(sizeof(Item) * 1024);
item_max = 1024;
sort_ids = (SortID *)memalloc(sizeof(SortID) * 1024);
ids.resize(2014);
items_buffer = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t) * 1024);
item_max = 1024;
}
LightClusterBuilder::~LightClusterBuilder() {
if (cluster_data.size()) {
RD::get_singleton()->free(cluster_texture);
}
if (lights) {
memfree(lights);
}
if (refprobes) {
memfree(refprobes);
}
if (decals) {
memfree(decals);
}
if (items) {
memfree(items);
}
if (sort_ids) {
memfree(sort_ids);
RD::get_singleton()->free(items_buffer);
}
}
#ifndef LIGHT_CLUSTER_BUILDER_H
#define LIGHT_CLUSTER_BUILDER_H
#include "servers/visual/rasterizer_rd/rasterizer_storage_rd.h"
class LightClusterBuilder {
public:
enum LightType {
LIGHT_TYPE_OMNI,
LIGHT_TYPE_SPOT
};
enum ItemType {
ITEM_TYPE_OMNI_LIGHT,
ITEM_TYPE_SPOT_LIGHT,
ITEM_TYPE_REFLECTION_PROBE,
ITEM_TYPE_DECAL,
ITEM_TYPE_MAX //should always be 4
};
enum {
COUNTER_SHIFT = 20, //one million total ids
POINTER_MASK = (1 << COUNTER_SHIFT) - 1,
COUNTER_MASK = 0xfff // 4096 items per cell
};
private:
struct LightData {
float position[3];
uint32_t type;
float radius;
float spot_aperture;
uint32_t pad[2];
};
uint32_t light_count = 0;
uint32_t light_max = 0;
LightData *lights = nullptr;
struct OrientedBoxData {
float position[3];
uint32_t pad;
float x_axis[3];
uint32_t pad2;
float y_axis[3];
uint32_t pad3;
float z_axis[3];
uint32_t pad4;
};
uint32_t refprobe_count = 0;
uint32_t refprobe_max = 0;
OrientedBoxData *refprobes = nullptr;
uint32_t decal_count = 0;
uint32_t decal_max = 0;
OrientedBoxData *decals = nullptr;
struct Item {
AABB aabb;
ItemType type;
uint32_t index;
};
Item *items = nullptr;
uint32_t item_count = 0;
uint32_t item_max = 0;
uint32_t width = 0;
uint32_t height = 0;
uint32_t depth = 0;
struct Cell {
uint32_t item_pointers[ITEM_TYPE_MAX];
};
PoolVector<uint8_t> cluster_data;
RID cluster_texture;
struct SortID {
uint32_t cell_index;
uint32_t item_index;
ItemType item_type;
};
SortID *sort_ids = nullptr;
PoolVector<uint32_t> ids;
uint32_t sort_id_count = 0;
uint32_t sort_id_max = 0;
RID items_buffer;
Transform view_xform;
CameraMatrix projection;
float z_far = 0;
float z_near = 0;
_FORCE_INLINE_ void _add_item(const AABB &p_aabb, ItemType p_type, uint32_t p_index) {
if (unlikely(item_count == item_max)) {
item_max = nearest_power_of_2_templated(item_max + 1);
items = (Item *)memrealloc(items, sizeof(Item) * item_max);
}
Item &item = items[item_count];
item.aabb = p_aabb;
item.index = p_index;
item.type = p_type;
item_count++;
}
public:
void begin(const Transform &p_view_transform, const CameraMatrix &p_cam_projection);
_FORCE_INLINE_ void add_light(LightType p_type, const Transform &p_transform, float p_radius, float p_spot_aperture) {
if (unlikely(light_count == light_max)) {
light_max = nearest_power_of_2_templated(light_max + 1);
lights = (LightData *)memrealloc(lights, sizeof(LightData) * light_max);
}
LightData &ld = lights[light_count];
ld.type = p_type;
ld.position[0] = p_transform.origin.x;
ld.position[1] = p_transform.origin.y;
ld.position[2] = p_transform.origin.z;
ld.radius = p_radius;
ld.spot_aperture = p_spot_aperture;
Transform xform = view_xform * p_transform;
ld.radius *= xform.basis.get_uniform_scale();
AABB aabb;
switch (p_type) {
case LIGHT_TYPE_OMNI: {
aabb.position = xform.origin;
aabb.size = Vector3(ld.radius, ld.radius, ld.radius);
aabb.position -= aabb.size;
aabb.size *= 2.0;
_add_item(aabb, ITEM_TYPE_OMNI_LIGHT, light_count);
} break;
case LIGHT_TYPE_SPOT: {
Vector3 v(0, 0, -1);
v.rotated(Vector3(0, 1, 0), Math::deg2rad(ld.spot_aperture)); //rotate in x-z
v.normalize();
v *= ld.radius;
v.y = v.x;
aabb.position = xform.origin;
aabb.expand_to(xform.xform(v));
aabb.expand_to(xform.xform(Vector3(-v.x, v.y, v.z)));
aabb.expand_to(xform.xform(Vector3(-v.x, -v.y, v.z)));
aabb.expand_to(xform.xform(Vector3(v.x, -v.y, v.z)));
_add_item(aabb, ITEM_TYPE_SPOT_LIGHT, light_count);
} break;
}
light_count++;
}
_FORCE_INLINE_ void add_reflection_probe(const Transform &p_transform, const Vector3 &p_half_extents) {
if (unlikely(refprobe_count == refprobe_max)) {
refprobe_max = nearest_power_of_2_templated(refprobe_max + 1);
refprobes = (OrientedBoxData *)memrealloc(refprobes, sizeof(OrientedBoxData) * refprobe_max);
}
OrientedBoxData &rp = refprobes[refprobe_count];
Vector3 origin = p_transform.origin;
rp.position[0] = origin.x;
rp.position[1] = origin.y;
rp.position[2] = origin.z;
Vector3 x_axis = p_transform.basis.get_axis(0) * p_half_extents.x;
rp.x_axis[0] = x_axis.x;
rp.x_axis[1] = x_axis.y;
rp.x_axis[2] = x_axis.z;
Vector3 y_axis = p_transform.basis.get_axis(1) * p_half_extents.y;
rp.y_axis[0] = y_axis.x;
rp.y_axis[1] = y_axis.y;
rp.y_axis[2] = y_axis.z;
Vector3 z_axis = p_transform.basis.get_axis(2) * p_half_extents.z;
rp.z_axis[0] = z_axis.x;
rp.z_axis[1] = z_axis.y;
rp.z_axis[2] = z_axis.z;
AABB aabb;
aabb.position = origin + x_axis + y_axis + z_axis;
aabb.expand_to(origin + x_axis + y_axis - z_axis);
aabb.expand_to(origin + x_axis - y_axis + z_axis);
aabb.expand_to(origin + x_axis - y_axis - z_axis);
aabb.expand_to(origin - x_axis + y_axis + z_axis);
aabb.expand_to(origin - x_axis + y_axis - z_axis);
aabb.expand_to(origin - x_axis - y_axis + z_axis);
aabb.expand_to(origin - x_axis - y_axis - z_axis);
_add_item(aabb, ITEM_TYPE_REFLECTION_PROBE, refprobe_count);
refprobe_count++;
}
_FORCE_INLINE_ void add_decal(const Transform &p_transform, const Vector2 &p_half_extents, float p_depth) {
if (unlikely(decal_count == decal_max)) {
decal_max = nearest_power_of_2_templated(decal_max + 1);
decals = (OrientedBoxData *)memrealloc(decals, sizeof(OrientedBoxData) * decal_max);
}
OrientedBoxData &dc = decals[decal_count];
Vector3 z_axis = -p_transform.basis.get_axis(2) * p_depth * 0.5;
dc.z_axis[0] = z_axis.x;
dc.z_axis[1] = z_axis.y;
dc.z_axis[2] = z_axis.z;
Vector3 origin = p_transform.origin - z_axis;
dc.position[0] = origin.x;
dc.position[1] = origin.y;
dc.position[2] = origin.z;
Vector3 x_axis = p_transform.basis.get_axis(0) * p_half_extents.x;
dc.x_axis[0] = x_axis.x;
dc.x_axis[1] = x_axis.y;
dc.x_axis[2] = x_axis.z;
Vector3 y_axis = p_transform.basis.get_axis(1) * p_half_extents.y;
dc.y_axis[0] = y_axis.x;
dc.y_axis[1] = y_axis.y;
dc.y_axis[2] = y_axis.z;
AABB aabb;
aabb.position = origin + x_axis + y_axis + z_axis;
aabb.expand_to(origin + x_axis + y_axis - z_axis);
aabb.expand_to(origin + x_axis - y_axis + z_axis);
aabb.expand_to(origin + x_axis - y_axis - z_axis);
aabb.expand_to(origin - x_axis + y_axis + z_axis);
aabb.expand_to(origin - x_axis + y_axis - z_axis);
aabb.expand_to(origin - x_axis - y_axis + z_axis);
aabb.expand_to(origin - x_axis - y_axis - z_axis);
_add_item(aabb, ITEM_TYPE_DECAL, decal_count);
decal_count++;
}
void bake_cluster();
void setup(uint32_t p_width, uint32_t p_height, uint32_t p_depth);
RID get_cluster_texture() const;
RID get_cluster_indices_buffer() const;
LightClusterBuilder();
~LightClusterBuilder();
};
#endif // LIGHT_CLUSTER_BUILDER_H
......@@ -175,5 +175,5 @@ RasterizerRD::RasterizerRD() {
storage = memnew(RasterizerStorageRD);
canvas = memnew(RasterizerCanvasRD(storage));
scene = memnew(RasterizerSceneForwardRD(storage));
scene = memnew(RasterizerSceneHighEndRD(storage));
}
......@@ -35,14 +35,14 @@
#include "core/thread_work_pool.h"
#include "servers/visual/rasterizer.h"
#include "servers/visual/rasterizer_rd/rasterizer_canvas_rd.h"
#include "servers/visual/rasterizer_rd/rasterizer_scene_forward_rd.h"
#include "servers/visual/rasterizer_rd/rasterizer_scene_high_end_rd.h"
#include "servers/visual/rasterizer_rd/rasterizer_storage_rd.h"
class RasterizerRD : public Rasterizer {
protected:
RasterizerCanvasRD *canvas;
RasterizerStorageRD *storage;
RasterizerSceneForwardRD *scene;
RasterizerSceneHighEndRD *scene;
RID copy_viewports_rd_shader;
RID copy_viewports_rd_pipeline;
......
......@@ -28,15 +28,16 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef RASTERIZER_SCENE_FORWARD_RD_H
#define RASTERIZER_SCENE_FORWARD_RD_H
#ifndef RASTERIZER_SCENE_HIGHEND_RD_H
#define RASTERIZER_SCENE_HIGHEND_RD_H
#include "servers/visual/rasterizer_rd/light_cluster_builder.h"
#include "servers/visual/rasterizer_rd/rasterizer_scene_rd.h"
#include "servers/visual/rasterizer_rd/rasterizer_storage_rd.h"
#include "servers/visual/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h"
#include "servers/visual/rasterizer_rd/shaders/scene_forward.glsl.gen.h"
#include "servers/visual/rasterizer_rd/shaders/scene_high_end.glsl.gen.h"
class RasterizerSceneForwardRD : public RasterizerSceneRD {
class RasterizerSceneHighEndRD : public RasterizerSceneRD {
/* Shader */
......@@ -56,7 +57,7 @@ class RasterizerSceneForwardRD : public RasterizerSceneRD {
};
struct {
SceneForwardShaderRD scene_shader;
SceneHighEndShaderRD scene_shader;
ShaderCompilerRD compiler;
} shader;
......@@ -151,7 +152,7 @@ class RasterizerSceneForwardRD : public RasterizerSceneRD {
RasterizerStorageRD::ShaderData *_create_shader_func();
static RasterizerStorageRD::ShaderData *_create_shader_funcs() {
return static_cast<RasterizerSceneForwardRD *>(singleton)->_create_shader_func();
return static_cast<RasterizerSceneHighEndRD *>(singleton)->_create_shader_func();
}
struct MaterialData : public RasterizerStorageRD::MaterialData {
......@@ -173,7 +174,7 @@ class RasterizerSceneForwardRD : public RasterizerSceneRD {
RasterizerStorageRD::MaterialData *_create_material_func(ShaderData *p_shader);
static RasterizerStorageRD::MaterialData *_create_material_funcs(RasterizerStorageRD::ShaderData *p_shader) {
return static_cast<RasterizerSceneForwardRD *>(singleton)->_create_material_func(static_cast<ShaderData *>(p_shader));
return static_cast<RasterizerSceneHighEndRD *>(singleton)->_create_material_func(static_cast<ShaderData *>(p_shader));
}
/* Push Constant */
......@@ -282,11 +283,6 @@ class RasterizerSceneForwardRD : public RasterizerSceneRD {
uint32_t instance_ofs; //instance_offset in instancing/skeleton buffer
uint32_t gi_offset; //GI information when using lightmapping (VCT or lightmap)
uint32_t mask;
uint16_t reflection_probe_indices[8];
uint16_t omni_light_indices[8];
uint16_t spot_light_indices[8];
uint16_t decal_indices[8];
};
struct SceneState {
......@@ -321,7 +317,7 @@ class RasterizerSceneForwardRD : public RasterizerSceneRD {
uint32_t directional_light_count;
float dual_paraboloid_side;
float z_far;
uint32_t pad[1];
float z_near;
};
UBO ubo;
......@@ -497,7 +493,7 @@ class RasterizerSceneForwardRD : public RasterizerSceneRD {
RenderList render_list;
static RasterizerSceneForwardRD *singleton;
static RasterizerSceneHighEndRD *singleton;
uint64_t render_pass;
double time;
RID default_shader;
......@@ -511,6 +507,8 @@ class RasterizerSceneForwardRD : public RasterizerSceneRD {
RID default_vec4_xform_buffer;
RID default_vec4_xform_uniform_set;
LightClusterBuilder cluster_builder;
enum PassMode {
PASS_MODE_COLOR,
PASS_MODE_COLOR_SPECULAR,
......@@ -523,7 +521,7 @@ class RasterizerSceneForwardRD : public RasterizerSceneRD {
PASS_MODE_DEPTH_MATERIAL,
};
void _setup_environment(RID p_environment, 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);
void _setup_environment(RID p_environment, 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);
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);
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_gi_probes(RID *p_gi_probe_probe_cull_result, int p_gi_probe_probe_cull_count, const Transform &p_camera_transform);
......@@ -547,7 +545,7 @@ public:
virtual bool free(RID p_rid);
RasterizerSceneForwardRD(RasterizerStorageRD *p_storage);
~RasterizerSceneForwardRD();
RasterizerSceneHighEndRD(RasterizerStorageRD *p_storage);
~RasterizerSceneHighEndRD();
};
#endif // RASTERIZER_SCENE_FORWARD_RD_H
#endif // RASTERIZER_SCENE_HIGHEND_RD_H
......@@ -7,7 +7,7 @@ if 'RD_GLSL' in env['BUILDERS']:
env.RD_GLSL('canvas_occlusion.glsl');
env.RD_GLSL('blur.glsl');
env.RD_GLSL('cubemap_roughness.glsl');
env.RD_GLSL('scene_forward.glsl');
env.RD_GLSL('scene_high_end.glsl');
env.RD_GLSL('sky.glsl');
env.RD_GLSL('tonemap.glsl');
env.RD_GLSL('copy.glsl');
......
......@@ -5,7 +5,7 @@
VERSION_DEFINES
#include "scene_forward_inc.glsl"
#include "scene_high_end_inc.glsl"
/* INPUT ATTRIBS */
......@@ -276,7 +276,7 @@ VERTEX_SHADER_CODE
VERSION_DEFINES
#include "scene_forward_inc.glsl"
#include "scene_high_end_inc.glsl"
/* Varyings */
......@@ -1236,9 +1236,7 @@ void main() {
float normaldepth = 1.0;
#if defined(SCREEN_UV_USED)
vec2 screen_uv = gl_FragCoord.xy * scene_data.screen_pixel_size;
#endif
float sss_strength = 0.0;
......@@ -1394,23 +1392,20 @@ FRAGMENT_SHADER_CODE
}
}
#endif
uvec4 cluster_cell = texture(usampler3D(cluster_texture, material_samplers[SAMPLER_NEAREST_CLAMP]),vec3(screen_uv,(abs(vertex.z)-scene_data.z_near)/(scene_data.z_far-scene_data.z_near)));
{ // process reflections
vec4 reflection_accum = vec4(0.0, 0.0, 0.0, 0.0);
vec4 ambient_accum = vec4(0.0, 0.0, 0.0, 0.0);
uint reflection_probe_count = instances.data[instance_index].flags & INSTANCE_FLAGS_FORWARD_MASK;
uint reflection_probe_count = cluster_cell.z >> CLUSTER_COUNTER_SHIFT;
uint reflection_probe_pointer = cluster_cell.z & CLUSTER_POINTER_MASK;
for (uint i = 0; i < reflection_probe_count; i++) {
uint ref_index = instances.data[instance_index].reflection_probe_indices[i >> 1];
if (bool(i & 1)) {
ref_index >>= 16;
} else {
ref_index &= 0xFFFF;
}
uint ref_index = cluster_data.indices[reflection_probe_pointer + i];
reflection_process(ref_index, vertex, normal, roughness, ambient_light, specular_light, ambient_accum, reflection_accum);
}
......@@ -1527,22 +1522,18 @@ FRAGMENT_SHADER_CODE
}
{ //omni lights
uint omni_light_count = (instances.data[instance_index].flags >> INSTANCE_FLAGS_FORWARD_OMNI_LIGHT_SHIFT) & INSTANCE_FLAGS_FORWARD_MASK;
uint omni_light_count = cluster_cell.x >> CLUSTER_COUNTER_SHIFT;
uint omni_light_pointer = cluster_cell.x & CLUSTER_POINTER_MASK;
for (uint i = 0; i < omni_light_count; i++) {
uint light_index = instances.data[instance_index].omni_light_indices[i >> 1];
uint light_index = cluster_data.indices[omni_light_pointer + i];
if (bool(i & 1)) {
light_index >>= 16;
} else {
light_index &= 0xFFFF;
if (!bool(lights.data[light_index].mask&instances.data[instance_index].layer_mask)) {
continue; //not masked
}
//this is done on CPU, so no need to do it here
//if (!bool(lights.data[light_index].mask&instances.data[instance_index].layer_mask)) {
// continue; //not masked
//}
light_process_omni(light_index, vertex, view, normal, albedo, roughness, metallic, specular, specular_blob_intensity,
#ifdef LIGHT_TRANSMISSION_USED
transmission,
......@@ -1565,22 +1556,17 @@ FRAGMENT_SHADER_CODE
}
{ //spot lights
uint spot_light_count = (instances.data[instance_index].flags >> INSTANCE_FLAGS_FORWARD_SPOT_LIGHT_SHIFT) & INSTANCE_FLAGS_FORWARD_MASK;
uint spot_light_count = cluster_cell.y >> CLUSTER_COUNTER_SHIFT;
uint spot_light_pointer = cluster_cell.y & CLUSTER_POINTER_MASK;
for (uint i = 0; i < spot_light_count; i++) {
uint light_index = instances.data[instance_index].spot_light_indices[i >> 1];
uint light_index = cluster_data.indices[spot_light_pointer + i];
if (bool(i & 1)) {
light_index >>= 16;
} else {
light_index &= 0xFFFF;
if (!bool(lights.data[light_index].mask&instances.data[instance_index].layer_mask)) {
continue; //not masked
}
//this is done on CPU, so no need to do it here
//if (!bool(lights.data[light_index].mask&instances.data[instance_index].layer_mask)) {
// continue; //not masked
//}
light_process_spot(light_index, vertex, view, normal, albedo, roughness, metallic, specular, specular_blob_intensity,
#ifdef LIGHT_TRANSMISSION_USED
transmission,
......
......@@ -58,7 +58,7 @@ layout(set = 0, binding = 3, std140) uniform SceneData {
uint directional_light_count;
float dual_paraboloid_side;
float z_far;
uint pad0;
float z_near;
#if 0
vec4 ambient_light_color;
......@@ -118,11 +118,6 @@ struct InstanceData {
uint instance_ofs; //instance_offset in instancing/skeleton buffer
uint gi_offset; //GI information when using lightmapping (VCT or lightmap)
uint layer_mask;
uint reflection_probe_indices[4];
uint omni_light_indices[4];
uint spot_light_indices[4];
uint decal_indices[4];
};
layout(set = 0, binding = 4, std430) buffer Instances {
......@@ -206,6 +201,16 @@ layout(set = 0, binding = 8, std140) uniform GIProbes {
layout(set = 0, binding = 9) uniform texture3D gi_probe_textures[MAX_GI_PROBE_TEXTURES];
#define CLUSTER_COUNTER_SHIFT 20
#define CLUSTER_POINTER_MASK ((1 << CLUSTER_COUNTER_SHIFT) - 1)
#define CLUSTER_COUNTER_MASK 0xfff
layout(set = 0, binding = 10) uniform utexture3D cluster_texture;
layout(set = 0, binding = 11, std430) buffer ClusterData {
uint indices[];
} cluster_data;
/* Set 1, Scene data that changes per render pass */
layout(set = 1, binding = 0) uniform texture2D depth_buffer;
......
......@@ -2302,7 +2302,7 @@ VisualServer::VisualServer() {
GLOBAL_DEF("rendering/quality/gi_probes/anisotropic", false);
GLOBAL_DEF("rendering/quality/gi_probes/quality", 1);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/gi_probes/quality", PropertyInfo(Variant::INT, "rendering/quality/gi_probes/quality", PROPERTY_HINT_ENUM, "Ultra-Low (1 cone, fastest),Medium (4 cones), High (6 cones, slowest)"));
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/gi_probes/quality", PropertyInfo(Variant::INT, "rendering/quality/gi_probes/quality", PROPERTY_HINT_ENUM, "Ultra-Low (1 cone - fastest),Medium (4 cones), High (6 cones - slowest)"));
GLOBAL_DEF("rendering/quality/shading/force_vertex_shading", false);
GLOBAL_DEF("rendering/quality/shading/force_vertex_shading.mobile", true);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment