mirror of
https://github.com/godotengine/godot
synced 2024-09-04 22:58:28 +00:00
Rewrote large part of rendering, omni and spot shadows now work.
This commit is contained in:
parent
1d871f6226
commit
920db604d2
|
@ -512,6 +512,28 @@ CameraMatrix CameraMatrix::operator*(const CameraMatrix &p_matrix) const {
|
|||
return new_matrix;
|
||||
}
|
||||
|
||||
void CameraMatrix::set_depth_correction() {
|
||||
|
||||
real_t *m = &matrix[0][0];
|
||||
|
||||
m[0] = 1;
|
||||
m[1] = 0.0;
|
||||
m[2] = 0.0;
|
||||
m[3] = 0.0;
|
||||
m[4] = 0.0;
|
||||
m[5] = -1;
|
||||
m[6] = 0.0;
|
||||
m[7] = 0.0;
|
||||
m[8] = 0.0;
|
||||
m[9] = 0.0;
|
||||
m[10] = 0.5;
|
||||
m[11] = 0.0;
|
||||
m[12] = 0.0;
|
||||
m[13] = 0.0;
|
||||
m[14] = 0.5;
|
||||
m[15] = 1.0;
|
||||
}
|
||||
|
||||
void CameraMatrix::set_light_bias() {
|
||||
|
||||
real_t *m = &matrix[0][0];
|
||||
|
|
|
@ -50,6 +50,7 @@ struct CameraMatrix {
|
|||
void set_identity();
|
||||
void set_zero();
|
||||
void set_light_bias();
|
||||
void set_depth_correction();
|
||||
void set_light_atlas_rect(const Rect2 &p_rect);
|
||||
void set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_t p_z_near, real_t p_z_far, bool p_flip_fov = false);
|
||||
void set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_t p_z_near, real_t p_z_far, bool p_flip_fov, int p_eye, real_t p_intraocular_dist, real_t p_convergence_dist);
|
||||
|
|
|
@ -216,7 +216,7 @@ public:
|
|||
|
||||
/* SHADOW ATLAS API */
|
||||
|
||||
struct ShadowAtlas {
|
||||
struct ShadowAtlas {
|
||||
|
||||
enum {
|
||||
QUADRANT_SHIFT = 27,
|
||||
|
@ -288,7 +288,7 @@ public:
|
|||
|
||||
/* REFLECTION PROBE ATLAS API */
|
||||
|
||||
struct ReflectionAtlas {
|
||||
struct ReflectionAtlas {
|
||||
|
||||
int subdiv;
|
||||
int size;
|
||||
|
@ -307,8 +307,7 @@ public:
|
|||
mutable RID_PtrOwner<ReflectionAtlas> reflection_atlas_owner;
|
||||
|
||||
virtual RID reflection_atlas_create();
|
||||
virtual void reflection_atlas_set_size(RID p_ref_atlas, int p_size);
|
||||
virtual void reflection_atlas_set_subdivision(RID p_ref_atlas, int p_subdiv);
|
||||
virtual void reflection_atlas_configure(RID p_ref_atlas, int p_size, int p_count);
|
||||
|
||||
/* REFLECTION CUBEMAPS */
|
||||
|
||||
|
@ -324,7 +323,7 @@ public:
|
|||
|
||||
/* REFLECTION PROBE INSTANCE */
|
||||
|
||||
struct ReflectionProbeInstance {
|
||||
struct ReflectionProbeInstance {
|
||||
|
||||
RasterizerStorageGLES3::ReflectionProbe *probe_ptr;
|
||||
RID probe;
|
||||
|
@ -364,7 +363,7 @@ public:
|
|||
|
||||
/* ENVIRONMENT API */
|
||||
|
||||
struct Environment {
|
||||
struct Environment {
|
||||
|
||||
VS::EnvironmentBG bg_mode;
|
||||
|
||||
|
@ -590,7 +589,7 @@ public:
|
|||
float shadow_split_offsets[4];
|
||||
};
|
||||
|
||||
struct LightInstance {
|
||||
struct LightInstance {
|
||||
|
||||
struct ShadowTransform {
|
||||
|
||||
|
@ -639,7 +638,7 @@ public:
|
|||
|
||||
/* REFLECTION INSTANCE */
|
||||
|
||||
struct GIProbeInstance {
|
||||
struct GIProbeInstance {
|
||||
RID data;
|
||||
RasterizerStorageGLES3::GIProbe *probe;
|
||||
GLuint tex_cache;
|
||||
|
|
|
@ -1497,6 +1497,23 @@ void RenderingDeviceVulkan::_memory_barrier(VkPipelineStageFlags p_src_stage_mas
|
|||
|
||||
vkCmdPipelineBarrier(p_sync_with_draw ? frames[frame].draw_command_buffer : frames[frame].setup_command_buffer, p_src_stage_mask, p_dst_stage_mask, 0, 1, &mem_barrier, 0, NULL, 0, NULL);
|
||||
}
|
||||
|
||||
void RenderingDeviceVulkan::_buffer_memory_barrier(VkBuffer buffer, uint64_t p_from, uint64_t p_size, VkPipelineStageFlags p_src_stage_mask, VkPipelineStageFlags p_dst_stage_mask, VkAccessFlags p_src_access, VkAccessFlags p_dst_sccess, bool p_sync_with_draw) {
|
||||
|
||||
VkBufferMemoryBarrier buffer_mem_barrier;
|
||||
buffer_mem_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
|
||||
buffer_mem_barrier.pNext = NULL;
|
||||
buffer_mem_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
buffer_mem_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
buffer_mem_barrier.srcAccessMask = p_src_access;
|
||||
buffer_mem_barrier.dstAccessMask = p_dst_sccess;
|
||||
buffer_mem_barrier.buffer = buffer;
|
||||
buffer_mem_barrier.offset = p_from;
|
||||
buffer_mem_barrier.size = p_size;
|
||||
|
||||
vkCmdPipelineBarrier(p_sync_with_draw ? frames[frame].draw_command_buffer : frames[frame].setup_command_buffer, p_src_stage_mask, p_dst_stage_mask, 0, 0, NULL, 1, &buffer_mem_barrier, 0, NULL);
|
||||
}
|
||||
|
||||
/*****************/
|
||||
/**** TEXTURE ****/
|
||||
/*****************/
|
||||
|
@ -1715,7 +1732,7 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T
|
|||
}
|
||||
|
||||
if (p_format.usage_bits & TEXTURE_USAGE_SAMPLING_BIT) {
|
||||
texture.unbound_layout = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
texture.unbound_layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
} else {
|
||||
texture.unbound_layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
}
|
||||
|
@ -2526,6 +2543,9 @@ Error RenderingDeviceVulkan::texture_copy(RID p_from_texture, RID p_to_texture,
|
|||
ERR_FAIL_COND_V(p_dst_mipmap >= dst_tex->mipmaps, ERR_INVALID_PARAMETER);
|
||||
ERR_FAIL_COND_V(p_dst_layer >= dst_layer_count, ERR_INVALID_PARAMETER);
|
||||
|
||||
ERR_FAIL_COND_V_MSG(src_tex->read_aspect_mask != dst_tex->read_aspect_mask, ERR_INVALID_PARAMETER,
|
||||
"Source and destination texture must be of the same type (color or depth).");
|
||||
|
||||
VkCommandBuffer command_buffer = p_sync_with_draw ? frames[frame].draw_command_buffer : frames[frame].setup_command_buffer;
|
||||
|
||||
{
|
||||
|
@ -2586,7 +2606,7 @@ Error RenderingDeviceVulkan::texture_copy(RID p_from_texture, RID p_to_texture,
|
|||
image_copy_region.srcOffset.y = p_from.y;
|
||||
image_copy_region.srcOffset.z = p_from.z;
|
||||
|
||||
image_copy_region.dstSubresource.aspectMask = src_tex->barrier_aspect_mask;
|
||||
image_copy_region.dstSubresource.aspectMask = dst_tex->read_aspect_mask;
|
||||
image_copy_region.dstSubresource.baseArrayLayer = p_dst_layer;
|
||||
image_copy_region.dstSubresource.layerCount = 1;
|
||||
image_copy_region.dstSubresource.mipLevel = p_dst_mipmap;
|
||||
|
@ -2712,6 +2732,8 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
|
|||
ERR_FAIL_COND_V_MSG(!(p_format[i].usage_flags & (TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | TEXTURE_USAGE_RESOLVE_ATTACHMENT_BIT)), VK_NULL_HANDLE,
|
||||
"Texture format for index (" + itos(i) + ") requires an attachment (depth, stencil or resolve) bit set.");
|
||||
|
||||
bool can_be_sampled = p_format[i].usage_flags & TEXTURE_USAGE_SAMPLING_BIT;
|
||||
|
||||
switch (p_initial_action) {
|
||||
|
||||
case INITIAL_ACTION_CLEAR: {
|
||||
|
@ -2722,7 +2744,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
|
|||
case INITIAL_ACTION_KEEP_COLOR: {
|
||||
if (p_format[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
|
||||
description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
description.initialLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
description.initialLayout = can_be_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
} else if (p_format[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
|
||||
description.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
|
@ -2738,10 +2760,10 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
|
|||
|
||||
if (p_format[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
|
||||
description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
description.initialLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
description.initialLayout = can_be_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
} else if (p_format[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
|
||||
description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
description.initialLayout = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL; //don't care what is there
|
||||
description.initialLayout = can_be_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; //don't care what is there
|
||||
description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
} else {
|
||||
description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
|
@ -2772,15 +2794,16 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
|
|||
|
||||
switch (p_final_action) {
|
||||
case FINAL_ACTION_READ_COLOR_AND_DEPTH: {
|
||||
|
||||
if (p_format[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
|
||||
description.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
description.finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
description.finalLayout = can_be_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
} else if (p_format[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
|
||||
|
||||
description.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
description.finalLayout = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
description.finalLayout = can_be_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
} else {
|
||||
description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
|
@ -2791,12 +2814,12 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
|
|||
if (p_format[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
|
||||
description.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
description.finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
description.finalLayout = can_be_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
} else if (p_format[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
|
||||
|
||||
description.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
description.finalLayout = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
description.finalLayout = can_be_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
} else {
|
||||
description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
|
@ -2807,12 +2830,12 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
|
|||
if (p_format[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
|
||||
description.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
description.finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
description.finalLayout = can_be_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
} else if (p_format[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
|
||||
|
||||
description.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
description.finalLayout = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
description.finalLayout = can_be_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
} else {
|
||||
description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
|
@ -3062,7 +3085,7 @@ RID RenderingDeviceVulkan::vertex_buffer_create(uint32_t p_size_bytes, const Poo
|
|||
uint64_t data_size = p_data.size();
|
||||
PoolVector<uint8_t>::Read r = p_data.read();
|
||||
_buffer_update(&buffer, 0, r.ptr(), data_size);
|
||||
_memory_barrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, false);
|
||||
_buffer_memory_barrier(buffer.buffer, 0, data_size, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, false);
|
||||
}
|
||||
|
||||
return vertex_buffer_owner.make_rid(buffer);
|
||||
|
@ -3223,7 +3246,7 @@ RID RenderingDeviceVulkan::index_buffer_create(uint32_t p_index_count, IndexBuff
|
|||
uint64_t data_size = p_data.size();
|
||||
PoolVector<uint8_t>::Read r = p_data.read();
|
||||
_buffer_update(&index_buffer, 0, r.ptr(), data_size);
|
||||
_memory_barrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_INDEX_READ_BIT, false);
|
||||
_buffer_memory_barrier(index_buffer.buffer, 0, data_size, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_INDEX_READ_BIT, false);
|
||||
}
|
||||
return index_buffer_owner.make_rid(index_buffer);
|
||||
}
|
||||
|
@ -3934,7 +3957,7 @@ RID RenderingDeviceVulkan::uniform_buffer_create(uint32_t p_size_bytes, const Po
|
|||
uint64_t data_size = p_data.size();
|
||||
PoolVector<uint8_t>::Read r = p_data.read();
|
||||
_buffer_update(&buffer, 0, r.ptr(), data_size);
|
||||
_memory_barrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_UNIFORM_READ_BIT, false);
|
||||
_buffer_memory_barrier(buffer.buffer, 0, data_size, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_UNIFORM_READ_BIT, false);
|
||||
}
|
||||
return uniform_buffer_owner.make_rid(buffer);
|
||||
}
|
||||
|
@ -3953,7 +3976,7 @@ RID RenderingDeviceVulkan::storage_buffer_create(uint32_t p_size_bytes, const Po
|
|||
uint64_t data_size = p_data.size();
|
||||
PoolVector<uint8_t>::Read r = p_data.read();
|
||||
_buffer_update(&buffer, 0, r.ptr(), data_size);
|
||||
_memory_barrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, false);
|
||||
_buffer_memory_barrier(buffer.buffer, 0, data_size, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, false);
|
||||
}
|
||||
return storage_buffer_owner.make_rid(buffer);
|
||||
}
|
||||
|
@ -3976,7 +3999,7 @@ RID RenderingDeviceVulkan::texture_buffer_create(uint32_t p_size_elements, DataF
|
|||
uint64_t data_size = p_data.size();
|
||||
PoolVector<uint8_t>::Read r = p_data.read();
|
||||
_buffer_update(&texture_buffer.buffer, 0, r.ptr(), data_size);
|
||||
_memory_barrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, false);
|
||||
_buffer_memory_barrier(texture_buffer.buffer.buffer, 0, data_size, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, false);
|
||||
}
|
||||
|
||||
VkBufferViewCreateInfo view_create_info;
|
||||
|
@ -4400,7 +4423,8 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms,
|
|||
Buffer *buffer = storage_buffer_owner.getornull(uniform.ids[0]);
|
||||
ERR_FAIL_COND_V_MSG(!buffer, RID(), "Storage buffer supplied (binding: " + itos(uniform.binding) + ") is invalid.");
|
||||
|
||||
ERR_FAIL_COND_V_MSG(buffer->size != (uint32_t)set_uniform.length, RID(),
|
||||
//if 0, then its sized on link time
|
||||
ERR_FAIL_COND_V_MSG(set_uniform.length > 0 && buffer->size != (uint32_t)set_uniform.length, RID(),
|
||||
"Storage buffer supplied (binding: " + itos(uniform.binding) + ") size (" + itos(buffer->size) + " does not match size of shader uniform: (" + itos(set_uniform.length) + ").");
|
||||
|
||||
write.dstArrayElement = 0;
|
||||
|
@ -4523,8 +4547,47 @@ Error RenderingDeviceVulkan::buffer_update(RID p_buffer, uint32_t p_offset, uint
|
|||
return err;
|
||||
}
|
||||
|
||||
_memory_barrier(VK_PIPELINE_STAGE_TRANSFER_BIT, dst_stage_mask, VK_ACCESS_TRANSFER_WRITE_BIT, dst_access, p_sync_with_draw);
|
||||
_buffer_memory_barrier(buffer->buffer, p_offset, p_size, VK_PIPELINE_STAGE_TRANSFER_BIT, dst_stage_mask, VK_ACCESS_TRANSFER_WRITE_BIT, dst_access, p_sync_with_draw);
|
||||
#if 0
|
||||
if (p_sync_with_draw) {
|
||||
VkMemoryBarrier memoryBarrier;
|
||||
|
||||
memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
|
||||
memoryBarrier.pNext = NULL;
|
||||
memoryBarrier.srcAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT |
|
||||
VK_ACCESS_INDEX_READ_BIT |
|
||||
VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT |
|
||||
VK_ACCESS_UNIFORM_READ_BIT |
|
||||
VK_ACCESS_INPUT_ATTACHMENT_READ_BIT |
|
||||
VK_ACCESS_SHADER_READ_BIT |
|
||||
VK_ACCESS_SHADER_WRITE_BIT |
|
||||
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
|
||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
|
||||
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
|
||||
VK_ACCESS_TRANSFER_READ_BIT |
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT |
|
||||
VK_ACCESS_HOST_READ_BIT |
|
||||
VK_ACCESS_HOST_WRITE_BIT;
|
||||
memoryBarrier.dstAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT |
|
||||
VK_ACCESS_INDEX_READ_BIT |
|
||||
VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT |
|
||||
VK_ACCESS_UNIFORM_READ_BIT |
|
||||
VK_ACCESS_INPUT_ATTACHMENT_READ_BIT |
|
||||
VK_ACCESS_SHADER_READ_BIT |
|
||||
VK_ACCESS_SHADER_WRITE_BIT |
|
||||
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
|
||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
|
||||
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
|
||||
VK_ACCESS_TRANSFER_READ_BIT |
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT |
|
||||
VK_ACCESS_HOST_READ_BIT |
|
||||
VK_ACCESS_HOST_WRITE_BIT;
|
||||
|
||||
vkCmdPipelineBarrier(p_sync_with_draw ? frames[frame].draw_command_buffer : frames[frame].setup_command_buffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 1, &memoryBarrier, 0, NULL, 0, NULL);
|
||||
}
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -5145,6 +5208,47 @@ Error RenderingDeviceVulkan::_draw_list_render_pass_begin(Framebuffer *framebuff
|
|||
return OK;
|
||||
}
|
||||
|
||||
void RenderingDeviceVulkan::_draw_list_insert_clear_region(DrawList *draw_list, Framebuffer *framebuffer, Point2i viewport_offset, Point2i viewport_size, const Vector<Color> &p_clear_colors) {
|
||||
Vector<VkClearAttachment> clear_attachments;
|
||||
int color_index = 0;
|
||||
for (int i = 0; i < framebuffer->texture_ids.size(); i++) {
|
||||
Texture *texture = texture_owner.getornull(framebuffer->texture_ids[i]);
|
||||
VkClearAttachment clear_at;
|
||||
if (texture->usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
|
||||
ERR_FAIL_INDEX(color_index, p_clear_colors.size()); //a bug
|
||||
Color clear_color = p_clear_colors[color_index];
|
||||
clear_at.clearValue.color.float32[0] = clear_color.r;
|
||||
clear_at.clearValue.color.float32[1] = clear_color.g;
|
||||
clear_at.clearValue.color.float32[2] = clear_color.b;
|
||||
clear_at.clearValue.color.float32[3] = clear_color.a;
|
||||
clear_at.colorAttachment = color_index++;
|
||||
clear_at.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
} else if (texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
|
||||
|
||||
clear_at.clearValue.depthStencil.depth = 1.0;
|
||||
clear_at.clearValue.depthStencil.stencil = 0;
|
||||
clear_at.colorAttachment = 0;
|
||||
clear_at.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
if (format_has_stencil(texture->format)) {
|
||||
clear_at.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
}
|
||||
} else {
|
||||
ERR_CONTINUE(true);
|
||||
}
|
||||
clear_attachments.push_back(clear_at);
|
||||
}
|
||||
|
||||
VkClearRect cr;
|
||||
cr.baseArrayLayer = 0;
|
||||
cr.layerCount = 1;
|
||||
cr.rect.offset.x = viewport_offset.x;
|
||||
cr.rect.offset.y = viewport_offset.y;
|
||||
cr.rect.extent.width = viewport_size.width;
|
||||
cr.rect.extent.height = viewport_size.height;
|
||||
|
||||
vkCmdClearAttachments(draw_list->command_buffer, clear_attachments.size(), clear_attachments.ptr(), 1, &cr);
|
||||
}
|
||||
|
||||
RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebuffer, InitialAction p_initial_action, FinalAction p_final_action, const Vector<Color> &p_clear_colors, const Rect2 &p_region) {
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
@ -5154,8 +5258,9 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebu
|
|||
|
||||
Point2i viewport_offset;
|
||||
Point2i viewport_size = framebuffer->size;
|
||||
bool needs_clear_region = false;
|
||||
|
||||
if (p_region != Rect2()) { //check custom region
|
||||
if (p_region != Rect2() && p_region != Rect2(Vector2(), viewport_size)) { //check custom region
|
||||
Rect2i viewport(viewport_offset, viewport_size);
|
||||
Rect2i regioni = p_region;
|
||||
if (!(regioni.position.x >= viewport.position.x) && (regioni.position.y >= viewport.position.y) &&
|
||||
|
@ -5166,6 +5271,11 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebu
|
|||
|
||||
viewport_offset = regioni.position;
|
||||
viewport_size = regioni.size;
|
||||
|
||||
if (p_initial_action == INITIAL_ACTION_CLEAR) {
|
||||
p_initial_action = INITIAL_ACTION_KEEP_COLOR_AND_DEPTH;
|
||||
needs_clear_region = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (p_initial_action == INITIAL_ACTION_CLEAR) { //check clear values
|
||||
|
@ -5196,6 +5306,10 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebu
|
|||
draw_list_count = 0;
|
||||
draw_list_split = false;
|
||||
|
||||
if (needs_clear_region) {
|
||||
_draw_list_insert_clear_region(draw_list, framebuffer, viewport_offset, viewport_size, p_clear_colors);
|
||||
}
|
||||
|
||||
VkViewport viewport;
|
||||
viewport.x = viewport_offset.x;
|
||||
viewport.y = viewport_offset.y;
|
||||
|
@ -5230,7 +5344,9 @@ Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p
|
|||
Point2i viewport_offset;
|
||||
Point2i viewport_size = framebuffer->size;
|
||||
|
||||
if (p_region != Rect2()) { //check custom region
|
||||
bool needs_clear_region = false;
|
||||
|
||||
if (p_region != Rect2() && p_region != Rect2(Vector2(), viewport_size)) { //check custom region
|
||||
Rect2i viewport(viewport_offset, viewport_size);
|
||||
Rect2i regioni = p_region;
|
||||
if (!(regioni.position.x >= viewport.position.x) && (regioni.position.y >= viewport.position.y) &&
|
||||
|
@ -5241,6 +5357,11 @@ Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p
|
|||
|
||||
viewport_offset = regioni.position;
|
||||
viewport_size = regioni.size;
|
||||
|
||||
if (p_initial_action == INITIAL_ACTION_CLEAR) {
|
||||
p_initial_action = INITIAL_ACTION_KEEP_COLOR_AND_DEPTH;
|
||||
needs_clear_region = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (p_initial_action == INITIAL_ACTION_CLEAR) { //check clear values
|
||||
|
@ -5340,6 +5461,9 @@ Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p
|
|||
#ifdef DEBUG_ENABLED
|
||||
draw_list[i].validation.framebuffer_format = framebuffer->format_id;
|
||||
#endif
|
||||
if (i == 0 && needs_clear_region) {
|
||||
_draw_list_insert_clear_region(&draw_list[i], framebuffer, viewport_offset, viewport_size, p_clear_colors);
|
||||
}
|
||||
|
||||
VkViewport viewport;
|
||||
viewport.x = viewport_offset.x;
|
||||
|
@ -5754,6 +5878,11 @@ void RenderingDeviceVulkan::draw_list_end() {
|
|||
}
|
||||
}
|
||||
draw_list_bound_textures.clear();
|
||||
|
||||
// To ensure proper synchronization, we must make sure rendering is done before:
|
||||
// * Some buffer is copied
|
||||
// * Another render pass happens (since we may be done
|
||||
_memory_barrier(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_INDEX_READ_BIT | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | VK_ACCESS_TRANSFER_READ_BIT, true);
|
||||
}
|
||||
#if 0
|
||||
void RenderingDeviceVulkan::draw_list_render_secondary_to_framebuffer(ID p_framebuffer, ID *p_draw_lists, uint32_t p_draw_list_count, InitialAction p_initial_action, FinalAction p_final_action, const Vector<Variant> &p_clear_colors) {
|
||||
|
|
|
@ -216,6 +216,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
|
|||
Error _buffer_update(Buffer *p_buffer, size_t p_offset, const uint8_t *p_data, size_t p_data_size, bool p_use_draw_command_buffer = false, uint32_t p_required_align = 32);
|
||||
|
||||
void _memory_barrier(VkPipelineStageFlags p_src_stage_mask, VkPipelineStageFlags p_dst_stage_mask, VkAccessFlags p_src_access, VkAccessFlags p_dst_sccess, bool p_sync_with_draw);
|
||||
void _buffer_memory_barrier(VkBuffer buffer, uint64_t p_from, uint64_t p_size, VkPipelineStageFlags p_src_stage_mask, VkPipelineStageFlags p_dst_stage_mask, VkAccessFlags p_src_access, VkAccessFlags p_dst_sccess, bool p_sync_with_draw);
|
||||
|
||||
/*********************/
|
||||
/**** FRAMEBUFFER ****/
|
||||
|
@ -790,6 +791,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
|
|||
Vector<RID> draw_list_bound_textures;
|
||||
bool draw_list_unbind_textures;
|
||||
|
||||
void _draw_list_insert_clear_region(DrawList *draw_list, Framebuffer *framebuffer, Point2i viewport_offset, Point2i viewport_size, const Vector<Color> &p_clear_colors);
|
||||
Error _draw_list_setup_framebuffer(Framebuffer *p_framebuffer, InitialAction p_initial_action, FinalAction p_final_action, VkFramebuffer *r_framebuffer, VkRenderPass *r_render_pass);
|
||||
Error _draw_list_render_pass_begin(Framebuffer *framebuffer, InitialAction p_initial_action, FinalAction p_final_action, const Vector<Color> &p_clear_colors, Point2i viewport_offset, Point2i viewport_size, VkFramebuffer vkframebuffer, VkRenderPass render_pass, VkCommandBuffer command_buffer, VkSubpassContents subpass_contents);
|
||||
_FORCE_INLINE_ DrawList *_get_draw_list_ptr(DrawListID p_id);
|
||||
|
|
|
@ -1753,6 +1753,12 @@ bool Main::start() {
|
|||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
|
||||
int directional_atlas_size = GLOBAL_GET("rendering/quality/directional_shadow/size");
|
||||
VisualServer::get_singleton()->directional_shadow_atlas_set_size(directional_atlas_size);
|
||||
}
|
||||
|
||||
if (!editor && !project_manager) {
|
||||
//standard helpers that can be changed from main config
|
||||
|
||||
|
|
|
@ -431,42 +431,24 @@ OmniLight::ShadowMode OmniLight::get_shadow_mode() const {
|
|||
return shadow_mode;
|
||||
}
|
||||
|
||||
void OmniLight::set_shadow_detail(ShadowDetail p_detail) {
|
||||
|
||||
shadow_detail = p_detail;
|
||||
VS::get_singleton()->light_omni_set_shadow_detail(light, VS::LightOmniShadowDetail(p_detail));
|
||||
}
|
||||
OmniLight::ShadowDetail OmniLight::get_shadow_detail() const {
|
||||
|
||||
return shadow_detail;
|
||||
}
|
||||
|
||||
void OmniLight::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_shadow_mode", "mode"), &OmniLight::set_shadow_mode);
|
||||
ClassDB::bind_method(D_METHOD("get_shadow_mode"), &OmniLight::get_shadow_mode);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_shadow_detail", "detail"), &OmniLight::set_shadow_detail);
|
||||
ClassDB::bind_method(D_METHOD("get_shadow_detail"), &OmniLight::get_shadow_detail);
|
||||
|
||||
ADD_GROUP("Omni", "omni_");
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "omni_range", PROPERTY_HINT_EXP_RANGE, "0,4096,0.1,or_greater"), "set_param", "get_param", PARAM_RANGE);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "omni_attenuation", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_param", "get_param", PARAM_ATTENUATION);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "omni_shadow_mode", PROPERTY_HINT_ENUM, "Dual Paraboloid,Cube"), "set_shadow_mode", "get_shadow_mode");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "omni_shadow_detail", PROPERTY_HINT_ENUM, "Vertical,Horizontal"), "set_shadow_detail", "get_shadow_detail");
|
||||
|
||||
BIND_ENUM_CONSTANT(SHADOW_DUAL_PARABOLOID);
|
||||
BIND_ENUM_CONSTANT(SHADOW_CUBE);
|
||||
|
||||
BIND_ENUM_CONSTANT(SHADOW_DETAIL_VERTICAL);
|
||||
BIND_ENUM_CONSTANT(SHADOW_DETAIL_HORIZONTAL);
|
||||
}
|
||||
|
||||
OmniLight::OmniLight() :
|
||||
Light(VisualServer::LIGHT_OMNI) {
|
||||
|
||||
set_shadow_mode(SHADOW_CUBE);
|
||||
set_shadow_detail(SHADOW_DETAIL_HORIZONTAL);
|
||||
}
|
||||
|
||||
String SpotLight::get_configuration_warning() const {
|
||||
|
|
|
@ -183,15 +183,8 @@ public:
|
|||
SHADOW_CUBE,
|
||||
};
|
||||
|
||||
// omni light
|
||||
enum ShadowDetail {
|
||||
SHADOW_DETAIL_VERTICAL,
|
||||
SHADOW_DETAIL_HORIZONTAL
|
||||
};
|
||||
|
||||
private:
|
||||
ShadowMode shadow_mode;
|
||||
ShadowDetail shadow_detail;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
@ -200,14 +193,10 @@ public:
|
|||
void set_shadow_mode(ShadowMode p_mode);
|
||||
ShadowMode get_shadow_mode() const;
|
||||
|
||||
void set_shadow_detail(ShadowDetail p_detail);
|
||||
ShadowDetail get_shadow_detail() const;
|
||||
|
||||
OmniLight();
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(OmniLight::ShadowMode)
|
||||
VARIANT_ENUM_CAST(OmniLight::ShadowDetail)
|
||||
|
||||
class SpotLight : public Light {
|
||||
|
||||
|
|
|
@ -2075,14 +2075,10 @@ SceneTree::SceneTree() {
|
|||
|
||||
int ref_atlas_size = GLOBAL_DEF("rendering/quality/reflections/atlas_size", 2048);
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/reflections/atlas_size", PropertyInfo(Variant::INT, "rendering/quality/reflections/atlas_size", PROPERTY_HINT_RANGE, "0,8192,or_greater")); //next_power_of_2 will return a 0 as min value
|
||||
int ref_atlas_subdiv = GLOBAL_DEF("rendering/quality/reflections/atlas_subdiv", 8);
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/reflections/atlas_subdiv", PropertyInfo(Variant::INT, "rendering/quality/reflections/atlas_subdiv", PROPERTY_HINT_RANGE, "0,32,or_greater")); //next_power_of_2 will return a 0 as min value
|
||||
int msaa_mode = GLOBAL_DEF("rendering/quality/filters/msaa", 0);
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/filters/msaa", PropertyInfo(Variant::INT, "rendering/quality/filters/msaa", PROPERTY_HINT_ENUM, "Disabled,2x,4x,8x,16x,AndroidVR 2x,AndroidVR 4x"));
|
||||
root->set_msaa(Viewport::MSAA(msaa_mode));
|
||||
|
||||
VS::get_singleton()->scenario_set_reflection_atlas_size(root->get_world()->get_scenario(), ref_atlas_size, ref_atlas_subdiv);
|
||||
|
||||
{ //load default fallback environment
|
||||
//get possible extensions
|
||||
List<String> exts;
|
||||
|
|
|
@ -47,6 +47,8 @@ void RasterizerScene::InstanceDependency::instance_notify_deleted(RID p_deleted)
|
|||
for (Map<InstanceBase *, uint32_t>::Element *E = instances.front(); E; E = E->next()) {
|
||||
E->key()->dependencies.erase(this);
|
||||
}
|
||||
|
||||
instances.clear();
|
||||
}
|
||||
|
||||
RasterizerScene::InstanceDependency::~InstanceDependency() {
|
||||
|
|
|
@ -46,6 +46,7 @@ public:
|
|||
virtual void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) = 0;
|
||||
virtual bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) = 0;
|
||||
|
||||
virtual void directional_shadow_atlas_set_size(int p_size) = 0;
|
||||
virtual int get_directional_light_shadow_size(RID p_light_intance) = 0;
|
||||
virtual void set_directional_shadow_count(int p_count) = 0;
|
||||
|
||||
|
@ -107,18 +108,11 @@ public:
|
|||
Map<InstanceBase *, uint32_t> instances;
|
||||
};
|
||||
|
||||
struct InstanceCustomData {
|
||||
|
||||
virtual ~InstanceCustomData() {}
|
||||
};
|
||||
|
||||
struct InstanceBase {
|
||||
|
||||
VS::InstanceType base_type;
|
||||
RID base;
|
||||
|
||||
InstanceCustomData *custom_data;
|
||||
|
||||
RID skeleton;
|
||||
RID material_override;
|
||||
|
||||
|
@ -201,7 +195,6 @@ public:
|
|||
InstanceBase() :
|
||||
dependency_item(this) {
|
||||
|
||||
custom_data = nullptr;
|
||||
base_type = VS::INSTANCE_NONE;
|
||||
cast_shadows = VS::SHADOW_CASTING_SETTING_ON;
|
||||
receive_shadows = true;
|
||||
|
@ -215,9 +208,6 @@ public:
|
|||
}
|
||||
|
||||
virtual ~InstanceBase() {
|
||||
if (custom_data) {
|
||||
memdelete(custom_data);
|
||||
}
|
||||
clear_dependencies();
|
||||
}
|
||||
};
|
||||
|
@ -228,16 +218,10 @@ public:
|
|||
virtual void light_instance_mark_visible(RID p_light_instance) = 0;
|
||||
virtual bool light_instances_can_render_shadow_cube() const { return true; }
|
||||
|
||||
virtual RID reflection_atlas_create() = 0;
|
||||
virtual void reflection_atlas_set_size(RID p_ref_atlas, int p_size) = 0;
|
||||
virtual void reflection_atlas_set_subdivision(RID p_ref_atlas, int p_subdiv) = 0;
|
||||
|
||||
virtual RID reflection_probe_instance_create(RID p_probe) = 0;
|
||||
virtual void reflection_probe_instance_set_transform(RID p_instance, const Transform &p_transform) = 0;
|
||||
virtual void reflection_probe_release_atlas_index(RID p_instance) = 0;
|
||||
virtual bool reflection_probe_instance_needs_redraw(RID p_instance) = 0;
|
||||
virtual bool reflection_probe_instance_has_reflection(RID p_instance) = 0;
|
||||
virtual bool reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) = 0;
|
||||
virtual void reflection_probe_instance_begin_render(RID p_instance) = 0;
|
||||
virtual bool reflection_probe_instance_postprocess_step(RID p_instance) = 0;
|
||||
|
||||
virtual RID gi_probe_instance_create() = 0;
|
||||
|
@ -245,21 +229,13 @@ public:
|
|||
virtual void gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform) = 0;
|
||||
virtual void gi_probe_instance_set_bounds(RID p_probe, const Vector3 &p_bounds) = 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_environment, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) = 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_environment, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass) = 0;
|
||||
virtual void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count) = 0;
|
||||
|
||||
virtual void set_scene_pass(uint64_t p_pass) = 0;
|
||||
virtual void set_time(double p_time) = 0;
|
||||
virtual void set_debug_draw_mode(VS::ViewportDebugDraw p_debug_draw) = 0;
|
||||
|
||||
virtual void instance_create_custom_data(InstanceBase *p_instance) = 0;
|
||||
virtual void instance_free_custom_data(InstanceBase *p_instance) = 0;
|
||||
virtual void instance_custom_data_update_lights(InstanceBase *p_instance) = 0;
|
||||
virtual void instance_custom_data_update_reflection_probes(InstanceBase *p_instance) = 0;
|
||||
virtual void instance_custom_data_update_gi_probes(InstanceBase *p_instance) = 0;
|
||||
virtual void instance_custom_data_update_lightmap(InstanceBase *p_instance) = 0;
|
||||
virtual void instance_custom_data_update_transform(InstanceBase *p_instance) = 0;
|
||||
|
||||
virtual RID render_buffers_create() = 0;
|
||||
virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, VS::ViewportMSAA p_msaa) = 0;
|
||||
|
||||
|
@ -442,7 +418,6 @@ public:
|
|||
virtual void light_set_use_gi(RID p_light, bool p_enable) = 0;
|
||||
|
||||
virtual void light_omni_set_shadow_mode(RID p_light, VS::LightOmniShadowMode p_mode) = 0;
|
||||
virtual void light_omni_set_shadow_detail(RID p_light, VS::LightOmniShadowDetail p_detail) = 0;
|
||||
|
||||
virtual void light_directional_set_shadow_mode(RID p_light, VS::LightDirectionalShadowMode p_mode) = 0;
|
||||
virtual void light_directional_set_blend_splits(RID p_light, bool p_enable) = 0;
|
||||
|
|
|
@ -2375,7 +2375,7 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
|
|||
attachments.push_back(af_color);
|
||||
|
||||
RD::AttachmentFormat af_depth;
|
||||
af_depth.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_X8_D24_UNORM_PACK32, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ? RD::DATA_FORMAT_X8_D24_UNORM_PACK32 : RD::DATA_FORMAT_D32_SFLOAT;
|
||||
af_depth.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D32_SFLOAT, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ? RD::DATA_FORMAT_D32_SFLOAT : RD::DATA_FORMAT_X8_D24_UNORM_PACK32;
|
||||
af_depth.usage_flags = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
||||
|
||||
attachments.push_back(af_depth);
|
||||
|
|
|
@ -39,7 +39,23 @@ RID RasterizerEffectsRD::_get_uniform_set_from_texture(RID p_texture) {
|
|||
return uniform_set;
|
||||
}
|
||||
|
||||
void RasterizerEffectsRD::copy(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_region) {
|
||||
void RasterizerEffectsRD::copy_to_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_rect, bool p_flip_y) {
|
||||
|
||||
zeromem(&blur.push_constant, sizeof(BlurPushConstant));
|
||||
if (p_flip_y) {
|
||||
blur.push_constant.flags |= BLUR_FLAG_FLIP_Y;
|
||||
}
|
||||
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP_COLOR, RD::FINAL_ACTION_READ_COLOR_DISCARD_DEPTH, Vector<Color>(), p_rect);
|
||||
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur.pipelines[BLUR_MODE_SIMPLY_COPY].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
|
||||
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0);
|
||||
RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
|
||||
RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur.push_constant, sizeof(BlurPushConstant));
|
||||
RD::get_singleton()->draw_list_draw(draw_list, true);
|
||||
RD::get_singleton()->draw_list_end();
|
||||
}
|
||||
|
||||
void RasterizerEffectsRD::region_copy(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_region) {
|
||||
|
||||
zeromem(&blur.push_constant, sizeof(BlurPushConstant));
|
||||
|
||||
|
@ -164,6 +180,23 @@ void RasterizerEffectsRD::make_mipmap(RID p_source_rd_texture, RID p_dest_frameb
|
|||
RD::get_singleton()->draw_list_end();
|
||||
}
|
||||
|
||||
void RasterizerEffectsRD::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_rect, float p_z_near, float p_z_far, float p_bias, bool p_dp_flip) {
|
||||
|
||||
CopyToDPPushConstant push_constant;
|
||||
push_constant.bias = p_bias;
|
||||
push_constant.z_far = p_z_far;
|
||||
push_constant.z_near = p_z_near;
|
||||
push_constant.z_flip = p_dp_flip;
|
||||
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP_COLOR, RD::FINAL_ACTION_READ_COLOR_DISCARD_DEPTH, Vector<Color>(), p_rect);
|
||||
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, copy.pipelines[COPY_MODE_CUBE_TO_DP].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
|
||||
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0);
|
||||
RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
|
||||
RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(CopyToDPPushConstant));
|
||||
RD::get_singleton()->draw_list_draw(draw_list, true);
|
||||
RD::get_singleton()->draw_list_end();
|
||||
}
|
||||
|
||||
void RasterizerEffectsRD::tonemapper(RID p_source_color, RID p_dst_framebuffer, const TonemapSettings &p_settings) {
|
||||
|
||||
zeromem(&tonemap.push_constant, sizeof(TonemapPushConstant));
|
||||
|
@ -277,6 +310,20 @@ RasterizerEffectsRD::RasterizerEffectsRD() {
|
|||
}
|
||||
}
|
||||
|
||||
{
|
||||
// Initialize copier
|
||||
Vector<String> copy_modes;
|
||||
copy_modes.push_back("\n#define MODE_CUBE_TO_DP\n");
|
||||
|
||||
copy.shader.initialize(copy_modes);
|
||||
|
||||
copy.shader_version = copy.shader.version_create();
|
||||
|
||||
for (int i = 0; i < COPY_MODE_MAX; i++) {
|
||||
copy.pipelines[i].setup(copy.shader.version_get_shader(copy.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
RD::SamplerState sampler;
|
||||
sampler.mag_filter = RD::SAMPLER_FILTER_LINEAR;
|
||||
sampler.min_filter = RD::SAMPLER_FILTER_LINEAR;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "core/math/camera_matrix.h"
|
||||
#include "render_pipeline_vertex_format_cache_rd.h"
|
||||
#include "servers/visual/rasterizer_rd/shaders/blur.glsl.gen.h"
|
||||
#include "servers/visual/rasterizer_rd/shaders/copy.glsl.gen.h"
|
||||
#include "servers/visual/rasterizer_rd/shaders/cubemap_roughness.glsl.gen.h"
|
||||
#include "servers/visual/rasterizer_rd/shaders/sky.glsl.gen.h"
|
||||
#include "servers/visual/rasterizer_rd/shaders/tonemap.glsl.gen.h"
|
||||
|
@ -36,7 +37,8 @@ class RasterizerEffectsRD {
|
|||
BLUR_FLAG_USE_BLUR_SECTION = (1 << 1),
|
||||
BLUR_FLAG_USE_ORTHOGONAL_PROJECTION = (1 << 2),
|
||||
BLUR_FLAG_DOF_NEAR_FIRST_TAP = (1 << 3),
|
||||
BLUR_FLAG_GLOW_FIRST_PASS = (1 << 4)
|
||||
BLUR_FLAG_GLOW_FIRST_PASS = (1 << 4),
|
||||
BLUR_FLAG_FLIP_Y = (1 << 5)
|
||||
};
|
||||
|
||||
struct BlurPushConstant {
|
||||
|
@ -146,6 +148,25 @@ class RasterizerEffectsRD {
|
|||
RenderPipelineVertexFormatCacheRD pipelines[TONEMAP_MODE_MAX];
|
||||
} tonemap;
|
||||
|
||||
struct CopyToDPPushConstant {
|
||||
float bias;
|
||||
float z_far;
|
||||
float z_near;
|
||||
uint32_t z_flip;
|
||||
};
|
||||
|
||||
enum CopyMode {
|
||||
COPY_MODE_CUBE_TO_DP,
|
||||
COPY_MODE_MAX
|
||||
};
|
||||
|
||||
struct Copy {
|
||||
|
||||
CopyShaderRD shader;
|
||||
RID shader_version;
|
||||
RenderPipelineVertexFormatCacheRD pipelines[COPY_MODE_MAX];
|
||||
} copy;
|
||||
|
||||
RID default_sampler;
|
||||
RID index_buffer;
|
||||
RID index_array;
|
||||
|
@ -155,11 +176,13 @@ class RasterizerEffectsRD {
|
|||
RID _get_uniform_set_from_texture(RID p_texture);
|
||||
|
||||
public:
|
||||
void copy(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_region);
|
||||
void region_copy(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_region);
|
||||
void copy_to_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_rect, bool p_flip_y = false);
|
||||
void gaussian_blur(RID p_source_rd_texture, RID p_framebuffer_half, RID p_rd_texture_half, RID p_dest_framebuffer, const Vector2 &p_pixel_size, const Rect2 &p_region);
|
||||
void cubemap_roughness(RID p_source_rd_texture, bool p_source_is_panorama, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness);
|
||||
void render_panorama(RD::DrawListID p_list, RenderingDevice::FramebufferFormatID p_fb_format, RID p_panorama, const CameraMatrix &p_camera, const Basis &p_orientation, float p_alpha, float p_multipler);
|
||||
void make_mipmap(RID p_source_rd_texture, RID p_framebuffer_half, const Vector2 &p_pixel_size);
|
||||
void copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_rect, float p_z_near, float p_z_far, float p_bias, bool p_dp_flip);
|
||||
|
||||
struct TonemapSettings {
|
||||
|
||||
|
|
|
@ -67,6 +67,18 @@ static _FORCE_INLINE_ void store_transform_3x3(const Transform &p_mtx, float *p_
|
|||
p_array[11] = 0;
|
||||
}
|
||||
|
||||
static _FORCE_INLINE_ void store_transform_3x3_430(const Transform &p_mtx, float *p_array) {
|
||||
p_array[0] = p_mtx.basis.elements[0][0];
|
||||
p_array[1] = p_mtx.basis.elements[1][0];
|
||||
p_array[2] = p_mtx.basis.elements[2][0];
|
||||
p_array[3] = p_mtx.basis.elements[0][1];
|
||||
p_array[4] = p_mtx.basis.elements[1][1];
|
||||
p_array[5] = p_mtx.basis.elements[2][1];
|
||||
p_array[6] = p_mtx.basis.elements[0][2];
|
||||
p_array[7] = p_mtx.basis.elements[1][2];
|
||||
p_array[8] = p_mtx.basis.elements[2][2];
|
||||
}
|
||||
|
||||
static _FORCE_INLINE_ void store_camera(const CameraMatrix &p_mtx, float *p_array) {
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
|
@ -296,8 +308,8 @@ void RasterizerSceneForwardRD::ShaderData::set_code(const String &p_code) {
|
|||
if (depth_draw == DEPTH_DRAW_OPAQUE) {
|
||||
depth_stencil.enable_depth_write = false; //alpha does not draw depth
|
||||
}
|
||||
} else if (uses_depth_pre_pass && (k == SHADER_VERSION_DEPTH_PASS || k == SHADER_VERSION_DEPTH_PASS_WITH_NORMAL || k == SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS)) {
|
||||
if (k == SHADER_VERSION_DEPTH_PASS) {
|
||||
} else if (uses_depth_pre_pass && (k == SHADER_VERSION_DEPTH_PASS || k == SHADER_VERSION_DEPTH_PASS_DP || k == SHADER_VERSION_DEPTH_PASS_WITH_NORMAL || k == SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS)) {
|
||||
if (k == SHADER_VERSION_DEPTH_PASS || k == k == SHADER_VERSION_DEPTH_PASS_DP) {
|
||||
//none, blend state contains nothing
|
||||
} else {
|
||||
blend_state = blend_state_opaque; //writes to normal and roughness in opaque way
|
||||
|
@ -310,7 +322,7 @@ void RasterizerSceneForwardRD::ShaderData::set_code(const String &p_code) {
|
|||
|
||||
if (k == SHADER_VERSION_COLOR_PASS || k == SHADER_VERSION_VCT_COLOR_PASS || k == SHADER_VERSION_LIGHTMAP_COLOR_PASS) {
|
||||
blend_state = blend_state_opaque;
|
||||
} else if (k == SHADER_VERSION_DEPTH_PASS) {
|
||||
} else if (k == SHADER_VERSION_DEPTH_PASS || k == SHADER_VERSION_DEPTH_PASS_DP) {
|
||||
//none, leave empty
|
||||
} else if (k == SHADER_VERSION_DEPTH_PASS_WITH_NORMAL || k == SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS) {
|
||||
blend_state = blend_state_opaque; //writes to normal and roughness in opaque way
|
||||
|
@ -583,60 +595,62 @@ bool RasterizerSceneForwardRD::free(RID p_rid) {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
/// INSTANCE DATA ///
|
||||
|
||||
void RasterizerSceneForwardRD::instance_create_custom_data(InstanceBase *p_instance) {
|
||||
InstanceGeometryData *geom_data = memnew(InstanceGeometryData);
|
||||
geom_data->ubo = RD::get_singleton()->uniform_buffer_create(sizeof(InstanceGeometryData::UBO));
|
||||
geom_data->using_lightmap_gi = p_instance->lightmap.is_valid();
|
||||
p_instance->custom_data = geom_data;
|
||||
}
|
||||
void RasterizerSceneForwardRD::_fill_instances(RenderList::Element **p_elements, int p_element_count) {
|
||||
|
||||
void RasterizerSceneForwardRD::instance_free_custom_data(InstanceBase *p_instance) {
|
||||
InstanceGeometryData *geom_data = (InstanceGeometryData *)p_instance->custom_data;
|
||||
ERR_FAIL_COND(!geom_data);
|
||||
RD::get_singleton()->free(geom_data->ubo);
|
||||
//uniform sets are freed as dependencies
|
||||
memdelete(geom_data);
|
||||
p_instance->custom_data = nullptr;
|
||||
}
|
||||
for (int i = 0; i < p_element_count; i++) {
|
||||
|
||||
void RasterizerSceneForwardRD::instance_custom_data_update_lights(InstanceBase *p_instance) {
|
||||
//unused
|
||||
}
|
||||
const RenderList::Element *e = p_elements[i];
|
||||
InstanceData &id = scene_state.instances[i];
|
||||
store_transform(e->instance->transform, id.transform);
|
||||
store_transform(Transform(e->instance->transform.basis.inverse().transposed()), id.normal_transform);
|
||||
id.flags = 0;
|
||||
id.mask = e->instance->layer_mask;
|
||||
|
||||
void RasterizerSceneForwardRD::instance_custom_data_update_reflection_probes(InstanceBase *p_instance) {
|
||||
//unused
|
||||
}
|
||||
void RasterizerSceneForwardRD::instance_custom_data_update_lightmap(InstanceBase *p_instance) {
|
||||
InstanceGeometryData *geom_data = (InstanceGeometryData *)p_instance->custom_data;
|
||||
ERR_FAIL_COND(!geom_data);
|
||||
//forward
|
||||
|
||||
geom_data->using_lightmap_gi = p_instance->lightmap.is_valid();
|
||||
uint32_t reflection_count = 0;
|
||||
uint32_t omni_count = 0;
|
||||
uint32_t spot_count = 0;
|
||||
uint32_t decal_count = 0;
|
||||
|
||||
if (geom_data->uniform_set_gi.is_valid() && RD::get_singleton()->uniform_set_is_valid(geom_data->uniform_set_gi)) {
|
||||
RD::get_singleton()->free(geom_data->uniform_set_gi);
|
||||
if (!e->instance->light_instances.empty()) {
|
||||
uint32_t light_count = e->instance->light_instances.size();
|
||||
const RID *light_ptrs = e->instance->light_instances.ptr();
|
||||
|
||||
for (uint32_t j = 0; j < light_count; j++) {
|
||||
if (render_pass != light_instance_get_render_pass(light_ptrs[j])) {
|
||||
continue; //not rendered this frame
|
||||
}
|
||||
|
||||
RID base = light_instance_get_base_light(light_ptrs[j]);
|
||||
|
||||
uint32_t mask = storage->light_get_cull_mask(base);
|
||||
if (!(mask & id.mask)) {
|
||||
continue; //masked
|
||||
}
|
||||
|
||||
if (storage->light_get_type(base) == VS::LIGHT_OMNI) {
|
||||
if (omni_count < 8) {
|
||||
id.omni_light_indices[omni_count] = light_instance_get_index(light_ptrs[j]);
|
||||
omni_count++;
|
||||
}
|
||||
} else {
|
||||
if (spot_count < 8) {
|
||||
id.omni_light_indices[spot_count] = light_instance_get_index(light_ptrs[j]);
|
||||
spot_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
id.flags |= reflection_count;
|
||||
id.flags |= omni_count << 3;
|
||||
id.flags |= spot_count << 6;
|
||||
id.flags |= decal_count << 9;
|
||||
}
|
||||
geom_data->uniform_set_gi = RID();
|
||||
}
|
||||
|
||||
void RasterizerSceneForwardRD::instance_custom_data_update_gi_probes(InstanceBase *p_instance) {
|
||||
InstanceGeometryData *geom_data = (InstanceGeometryData *)p_instance->custom_data;
|
||||
ERR_FAIL_COND(!geom_data);
|
||||
|
||||
geom_data->using_vct_gi = p_instance->gi_probe_instances.size();
|
||||
|
||||
if (geom_data->uniform_set_gi.is_valid() && RD::get_singleton()->uniform_set_is_valid(geom_data->uniform_set_gi)) {
|
||||
RD::get_singleton()->free(geom_data->uniform_set_gi);
|
||||
}
|
||||
geom_data->uniform_set_gi = RID();
|
||||
}
|
||||
|
||||
void RasterizerSceneForwardRD::instance_custom_data_update_transform(InstanceBase *p_instance) {
|
||||
InstanceGeometryData *geom_data = (InstanceGeometryData *)p_instance->custom_data;
|
||||
ERR_FAIL_COND(!geom_data);
|
||||
|
||||
geom_data->ubo_dirty = true;
|
||||
RD::get_singleton()->buffer_update(scene_state.instance_buffer, 0, sizeof(InstanceData) * p_element_count, scene_state.instances, true);
|
||||
}
|
||||
|
||||
/// RENDERING ///
|
||||
|
@ -669,7 +683,7 @@ void RasterizerSceneForwardRD::_render_list(RenderingDevice::DrawListID p_draw_l
|
|||
//find cull variant
|
||||
ShaderData::CullVariant cull_variant;
|
||||
|
||||
if (p_pass_mode == PASS_MODE_SHADOW && e->instance->cast_shadows == VS::SHADOW_CASTING_SETTING_DOUBLE_SIDED) {
|
||||
if ((p_pass_mode == PASS_MODE_SHADOW || p_pass_mode == PASS_MODE_SHADOW_DP) && e->instance->cast_shadows == VS::SHADOW_CASTING_SETTING_DOUBLE_SIDED) {
|
||||
cull_variant = ShaderData::CULL_VARIANT_DOUBLE_SIDED;
|
||||
} else {
|
||||
bool mirror = e->instance->mirror;
|
||||
|
@ -700,59 +714,42 @@ void RasterizerSceneForwardRD::_render_list(RenderingDevice::DrawListID p_draw_l
|
|||
}
|
||||
}
|
||||
|
||||
InstanceGeometryData *geom_data = (InstanceGeometryData *)e->instance->custom_data;
|
||||
|
||||
ShaderVersion shader_version;
|
||||
RID instance_uniform_set;
|
||||
|
||||
switch (p_pass_mode) {
|
||||
case PASS_MODE_COLOR:
|
||||
case PASS_MODE_COLOR_TRANSPARENT: {
|
||||
|
||||
if (p_no_gi) {
|
||||
instance_uniform_set = geom_data->uniform_set_base;
|
||||
shader_version = SHADER_VERSION_COLOR_PASS;
|
||||
} else if (geom_data->using_lightmap_gi) {
|
||||
instance_uniform_set = geom_data->uniform_set_gi;
|
||||
if (e->uses_lightmap) {
|
||||
shader_version = SHADER_VERSION_LIGHTMAP_COLOR_PASS;
|
||||
} else if (geom_data->using_vct_gi) {
|
||||
instance_uniform_set = geom_data->uniform_set_gi;
|
||||
} else if (e->uses_vct) {
|
||||
shader_version = SHADER_VERSION_VCT_COLOR_PASS;
|
||||
} else {
|
||||
instance_uniform_set = geom_data->uniform_set_gi;
|
||||
shader_version = SHADER_VERSION_COLOR_PASS;
|
||||
}
|
||||
|
||||
} break;
|
||||
case PASS_MODE_COLOR_SPECULAR: {
|
||||
if (p_no_gi) {
|
||||
instance_uniform_set = geom_data->uniform_set_base;
|
||||
shader_version = SHADER_VERSION_COLOR_PASS_WITH_SEPARATE_SPECULAR;
|
||||
} else if (geom_data->using_lightmap_gi) {
|
||||
instance_uniform_set = geom_data->uniform_set_gi;
|
||||
if (e->uses_lightmap) {
|
||||
shader_version = SHADER_VERSION_LIGHTMAP_COLOR_PASS_WITH_SEPARATE_SPECULAR;
|
||||
} else if (geom_data->using_vct_gi) {
|
||||
instance_uniform_set = geom_data->uniform_set_gi;
|
||||
} else if (e->uses_vct) {
|
||||
shader_version = SHADER_VERSION_VCT_COLOR_PASS_WITH_SEPARATE_SPECULAR;
|
||||
} else {
|
||||
instance_uniform_set = geom_data->uniform_set_gi;
|
||||
shader_version = SHADER_VERSION_COLOR_PASS_WITH_SEPARATE_SPECULAR;
|
||||
}
|
||||
} break;
|
||||
case PASS_MODE_SHADOW: {
|
||||
shader_version = SHADER_VERSION_DEPTH_PASS;
|
||||
instance_uniform_set = geom_data->uniform_set_base;
|
||||
} break;
|
||||
case PASS_MODE_SHADOW:
|
||||
case PASS_MODE_DEPTH: {
|
||||
shader_version = SHADER_VERSION_DEPTH_PASS;
|
||||
instance_uniform_set = geom_data->uniform_set_base;
|
||||
} break;
|
||||
case PASS_MODE_SHADOW_DP: {
|
||||
shader_version = SHADER_VERSION_DEPTH_PASS_DP;
|
||||
} break;
|
||||
case PASS_MODE_DEPTH_NORMAL: {
|
||||
shader_version = SHADER_VERSION_DEPTH_PASS_WITH_NORMAL;
|
||||
instance_uniform_set = geom_data->uniform_set_base;
|
||||
} break;
|
||||
case PASS_MODE_DEPTH_NORMAL_ROUGHNESS: {
|
||||
shader_version = SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS;
|
||||
instance_uniform_set = geom_data->uniform_set_base;
|
||||
} break;
|
||||
}
|
||||
|
||||
|
@ -812,8 +809,7 @@ void RasterizerSceneForwardRD::_render_list(RenderingDevice::DrawListID p_draw_l
|
|||
prev_material = material;
|
||||
}
|
||||
|
||||
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, instance_uniform_set, 3);
|
||||
|
||||
push_constant.index = i;
|
||||
RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(PushConstant));
|
||||
|
||||
switch (e->instance->base_type) {
|
||||
|
@ -836,10 +832,13 @@ void RasterizerSceneForwardRD::_render_list(RenderingDevice::DrawListID p_draw_l
|
|||
}
|
||||
}
|
||||
|
||||
void RasterizerSceneForwardRD::_setup_environment(RID p_render_target, RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, bool p_no_fog) {
|
||||
void RasterizerSceneForwardRD::_setup_environment(RID p_render_target, RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, bool p_no_fog, const Size2 &p_screen_pixel_size, RID p_shadow_atlas) {
|
||||
|
||||
CameraMatrix projection = p_cam_projection;
|
||||
projection.flip_y(); // Vulkan and modern APIs use Y-Down
|
||||
//CameraMatrix projection = p_cam_projection;
|
||||
//projection.flip_y(); // Vulkan and modern APIs use Y-Down
|
||||
CameraMatrix correction;
|
||||
correction.set_depth_correction();
|
||||
CameraMatrix projection = correction * p_cam_projection;
|
||||
|
||||
//store camera into ubo
|
||||
store_camera(projection, scene_state.ubo.projection_matrix);
|
||||
|
@ -847,6 +846,19 @@ void RasterizerSceneForwardRD::_setup_environment(RID p_render_target, RID p_env
|
|||
store_transform(p_cam_transform, scene_state.ubo.camera_matrix);
|
||||
store_transform(p_cam_transform.affine_inverse(), scene_state.ubo.inv_camera_matrix);
|
||||
|
||||
scene_state.ubo.screen_pixel_size[0] = p_screen_pixel_size.x;
|
||||
scene_state.ubo.screen_pixel_size[1] = p_screen_pixel_size.y;
|
||||
|
||||
if (p_shadow_atlas.is_valid()) {
|
||||
Vector2 sas = shadow_atlas_get_size(p_shadow_atlas);
|
||||
scene_state.ubo.shadow_atlas_pixel_size[0] = 1.0 / sas.x;
|
||||
scene_state.ubo.shadow_atlas_pixel_size[1] = 1.0 / sas.y;
|
||||
}
|
||||
{
|
||||
Vector2 dss = directional_shadow_get_size();
|
||||
scene_state.ubo.directional_shadow_pixel_size[0] = 1.0 / dss.x;
|
||||
scene_state.ubo.directional_shadow_pixel_size[1] = 1.0 / dss.y;
|
||||
}
|
||||
//time global variables
|
||||
scene_state.ubo.time = time;
|
||||
|
||||
|
@ -863,7 +875,7 @@ void RasterizerSceneForwardRD::_setup_environment(RID p_render_target, RID p_env
|
|||
//ambient
|
||||
if (ambient_src == VS::ENV_AMBIENT_SOURCE_BG && (env_bg == VS::ENV_BG_CLEAR_COLOR || env_bg == VS::ENV_BG_COLOR)) {
|
||||
|
||||
Color color = (p_render_target.is_valid() && env_bg == VS::ENV_BG_CLEAR_COLOR) ? storage->render_target_get_clear_request_color(p_render_target) : environment_get_bg_color(p_environment);
|
||||
Color color = (p_render_target.is_valid() && env_bg == VS::ENV_BG_CLEAR_COLOR) ? (p_render_target.is_valid() ? storage->render_target_get_clear_request_color(p_render_target) : Color(0, 0, 0)) : environment_get_bg_color(p_environment);
|
||||
color = color.to_linear();
|
||||
|
||||
scene_state.ubo.ambient_light_color_energy[0] = color.r * bg_energy;
|
||||
|
@ -1024,7 +1036,7 @@ void RasterizerSceneForwardRD::_setup_environment(RID p_render_target, RID p_env
|
|||
RD::get_singleton()->buffer_update(scene_state.uniform_buffer, 0, sizeof(SceneState::UBO), &scene_state.ubo, true);
|
||||
}
|
||||
|
||||
void RasterizerSceneForwardRD::_add_geometry(InstanceBase *p_instance, uint32_t p_surface, RID p_material, PassMode p_pass_mode) {
|
||||
void RasterizerSceneForwardRD::_add_geometry(InstanceBase *p_instance, uint32_t p_surface, RID p_material, PassMode p_pass_mode, uint32_t p_geometry_index) {
|
||||
|
||||
RID m_src = p_instance->material_override.is_valid() ? p_instance->material_override : p_material;
|
||||
|
||||
|
@ -1047,18 +1059,18 @@ void RasterizerSceneForwardRD::_add_geometry(InstanceBase *p_instance, uint32_t
|
|||
|
||||
ERR_FAIL_COND(!material);
|
||||
|
||||
_add_geometry_with_material(p_instance, p_surface, material, p_pass_mode);
|
||||
_add_geometry_with_material(p_instance, p_surface, material, p_pass_mode, p_geometry_index);
|
||||
|
||||
while (material->next_pass.is_valid()) {
|
||||
|
||||
material = (MaterialData *)storage->material_get_data(material->next_pass, RasterizerStorageRD::SHADER_TYPE_3D);
|
||||
if (!material || !material->shader_data->valid)
|
||||
break;
|
||||
_add_geometry_with_material(p_instance, p_surface, material, p_pass_mode);
|
||||
_add_geometry_with_material(p_instance, p_surface, material, p_pass_mode, p_geometry_index);
|
||||
}
|
||||
}
|
||||
|
||||
void RasterizerSceneForwardRD::_add_geometry_with_material(InstanceBase *p_instance, uint32_t p_surface, MaterialData *p_material, PassMode p_pass_mode) {
|
||||
void RasterizerSceneForwardRD::_add_geometry_with_material(InstanceBase *p_instance, uint32_t p_surface, MaterialData *p_material, PassMode p_pass_mode, uint32_t p_geometry_index) {
|
||||
|
||||
bool has_read_screen_alpha = p_material->shader_data->uses_screen_texture || p_material->shader_data->uses_depth_texture || p_material->shader_data->uses_normal_texture;
|
||||
bool has_base_alpha = (p_material->shader_data->uses_alpha || has_read_screen_alpha);
|
||||
|
@ -1120,8 +1132,11 @@ void RasterizerSceneForwardRD::_add_geometry_with_material(InstanceBase *p_insta
|
|||
e->material->shader_data->index = scene_state.current_shader_index++;
|
||||
}
|
||||
}
|
||||
|
||||
e->geometry_index = p_geometry_index;
|
||||
e->material_index = e->material->index;
|
||||
e->uses_instancing = e->instance->base_type == VS::INSTANCE_MULTIMESH;
|
||||
e->uses_lightmap = e->instance->lightmap.is_valid();
|
||||
e->uses_vct = e->instance->gi_probe_instances.size();
|
||||
e->shader_index = e->shader_index;
|
||||
e->depth_layer = e->instance->depth_layer;
|
||||
e->priority = p_material->priority;
|
||||
|
@ -1140,89 +1155,14 @@ void RasterizerSceneForwardRD::_fill_render_list(InstanceBase **p_cull_result, i
|
|||
scene_state.used_normal_texture = false;
|
||||
scene_state.used_depth_texture = false;
|
||||
|
||||
uint32_t geometry_index = 0;
|
||||
|
||||
//fill list
|
||||
|
||||
for (int i = 0; i < p_cull_count; i++) {
|
||||
|
||||
InstanceBase *inst = p_cull_result[i];
|
||||
|
||||
InstanceGeometryData *geom_data = (InstanceGeometryData *)inst->custom_data;
|
||||
|
||||
ERR_CONTINUE(!geom_data);
|
||||
|
||||
if (geom_data->ubo_dirty) {
|
||||
//ubo marked dirty, must be updated
|
||||
InstanceGeometryData::UBO ubo;
|
||||
store_transform(inst->transform, ubo.transform);
|
||||
store_transform_3x3(inst->transform.basis.inverse().transposed(), ubo.normal_transform);
|
||||
ubo.flags = 0;
|
||||
ubo.pad[0] = 0;
|
||||
ubo.pad[1] = 0;
|
||||
ubo.pad[2] = 0;
|
||||
RD::get_singleton()->buffer_update(geom_data->ubo, 0, sizeof(InstanceGeometryData::UBO), &ubo, true);
|
||||
}
|
||||
|
||||
if (p_no_gi) {
|
||||
if (geom_data->uniform_set_base.is_null() || !RD::get_singleton()->uniform_set_is_valid(geom_data->uniform_set_base)) {
|
||||
|
||||
Vector<RD::Uniform> uniforms;
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
|
||||
u.binding = 0;
|
||||
u.ids.push_back(geom_data->ubo);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.type = RD::UNIFORM_TYPE_TEXTURE_BUFFER;
|
||||
u.binding = 1;
|
||||
u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_MULTIMESH_BUFFER));
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
|
||||
geom_data->uniform_set_base = RD::get_singleton()->uniform_set_create(uniforms, default_shader_rd, 3);
|
||||
}
|
||||
} else {
|
||||
if (geom_data->uniform_set_gi.is_null() || !RD::get_singleton()->uniform_set_is_valid(geom_data->uniform_set_gi)) {
|
||||
|
||||
Vector<RD::Uniform> uniforms;
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
|
||||
u.binding = 0;
|
||||
u.ids.push_back(geom_data->ubo);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.type = RD::UNIFORM_TYPE_TEXTURE_BUFFER;
|
||||
u.binding = 1;
|
||||
u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_MULTIMESH_BUFFER));
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
|
||||
if (geom_data->using_lightmap_gi) {
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
u.binding = 2;
|
||||
#ifndef _MSC_VER
|
||||
#warning Need to put actual lightmap or lightmap capture texture if exists
|
||||
#endif
|
||||
u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE));
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
} else if (geom_data->using_vct_gi) {
|
||||
#ifndef _MSC_VER
|
||||
#warning Need to put actual vct textures here
|
||||
#endif
|
||||
}
|
||||
|
||||
geom_data->uniform_set_gi = RD::get_singleton()->uniform_set_create(uniforms, default_shader_rd, 3);
|
||||
}
|
||||
}
|
||||
|
||||
//add geometry for drawing
|
||||
switch (inst->base_type) {
|
||||
|
||||
|
@ -1242,7 +1182,8 @@ void RasterizerSceneForwardRD::_fill_render_list(InstanceBase **p_cull_result, i
|
|||
|
||||
RID material = inst_materials[j].is_valid() ? inst_materials[j] : materials[j];
|
||||
|
||||
_add_geometry(inst, j, material, p_pass_mode);
|
||||
uint32_t surface_index = storage->mesh_surface_get_render_pass_index(inst->base, j, render_pass, &geometry_index);
|
||||
_add_geometry(inst, j, material, p_pass_mode, surface_index);
|
||||
}
|
||||
|
||||
//mesh->last_pass=frame;
|
||||
|
@ -1341,12 +1282,208 @@ void RasterizerSceneForwardRD::_draw_sky(RD::DrawListID p_draw_list, RD::Framebu
|
|||
storage->get_effects()->render_panorama(p_draw_list, p_fb_format, panorama, camera, sky_transform, 1.0, multiplier);
|
||||
}
|
||||
|
||||
void RasterizerSceneForwardRD::_render_scene(RenderBufferData *p_buffer_data, 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_environment, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) {
|
||||
void RasterizerSceneForwardRD::_setup_reflections(RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, const Transform &p_camera_inverse_transform, RID p_environment) {
|
||||
|
||||
for (uint32_t i = 0; i < p_reflection_probe_cull_count; i++) {
|
||||
|
||||
RID rpi = p_reflection_probe_cull_result[i];
|
||||
|
||||
if (i >= scene_state.max_reflections) {
|
||||
reflection_probe_instance_set_render_index(rpi, 0); //invalid, but something needs to be set
|
||||
continue;
|
||||
}
|
||||
|
||||
reflection_probe_instance_set_render_index(rpi, i);
|
||||
|
||||
RID base_probe = reflection_probe_instance_get_probe(rpi);
|
||||
|
||||
ReflectionData &reflection_ubo = scene_state.reflections[i];
|
||||
|
||||
Vector3 extents = storage->reflection_probe_get_extents(base_probe);
|
||||
|
||||
reflection_ubo.box_extents[0] = extents.x;
|
||||
reflection_ubo.box_extents[1] = extents.y;
|
||||
reflection_ubo.box_extents[2] = extents.z;
|
||||
reflection_ubo.box_extents[3] = 0;
|
||||
|
||||
Vector3 origin_offset = storage->reflection_probe_get_origin_offset(base_probe);
|
||||
|
||||
reflection_ubo.box_offset[0] = origin_offset.x;
|
||||
reflection_ubo.box_offset[1] = origin_offset.y;
|
||||
reflection_ubo.box_offset[2] = origin_offset.z;
|
||||
reflection_ubo.box_offset[3] = 0;
|
||||
|
||||
float intensity = storage->reflection_probe_get_intensity(base_probe);
|
||||
bool interior = storage->reflection_probe_is_interior(base_probe);
|
||||
bool box_projection = storage->reflection_probe_is_box_projection(base_probe);
|
||||
|
||||
reflection_ubo.params[0] = intensity;
|
||||
reflection_ubo.params[1] = 0;
|
||||
reflection_ubo.params[2] = interior ? 1.0 : 0.0;
|
||||
reflection_ubo.params[3] = box_projection ? 1.0 : 0.0;
|
||||
|
||||
if (interior) {
|
||||
Color ambient_linear = storage->reflection_probe_get_interior_ambient(base_probe).to_linear();
|
||||
float interior_ambient_energy = storage->reflection_probe_get_interior_ambient_energy(base_probe);
|
||||
float interior_ambient_probe_contrib = storage->reflection_probe_get_interior_ambient_probe_contribution(base_probe);
|
||||
reflection_ubo.ambient[0] = ambient_linear.r * interior_ambient_energy;
|
||||
reflection_ubo.ambient[1] = ambient_linear.g * interior_ambient_energy;
|
||||
reflection_ubo.ambient[2] = ambient_linear.b * interior_ambient_energy;
|
||||
reflection_ubo.ambient[3] = interior_ambient_probe_contrib;
|
||||
} else {
|
||||
Color ambient_linear = storage->reflection_probe_get_interior_ambient(base_probe).to_linear();
|
||||
if (is_environment(p_environment)) {
|
||||
Color env_ambient_color = environment_get_ambient_light_color(p_environment).to_linear();
|
||||
float env_ambient_energy = environment_get_ambient_light_ambient_energy(p_environment);
|
||||
ambient_linear = env_ambient_color;
|
||||
ambient_linear.r *= env_ambient_energy;
|
||||
ambient_linear.g *= env_ambient_energy;
|
||||
ambient_linear.b *= env_ambient_energy;
|
||||
}
|
||||
|
||||
reflection_ubo.ambient[0] = ambient_linear.r;
|
||||
reflection_ubo.ambient[1] = ambient_linear.g;
|
||||
reflection_ubo.ambient[2] = ambient_linear.b;
|
||||
reflection_ubo.ambient[3] = 0; //not used in exterior mode, since it just blends with regular ambient light
|
||||
}
|
||||
|
||||
Transform transform = reflection_probe_instance_get_transform(rpi);
|
||||
Transform proj = (p_camera_inverse_transform * transform).inverse();
|
||||
store_transform(proj, reflection_ubo.local_matrix);
|
||||
}
|
||||
|
||||
if (p_reflection_probe_cull_count) {
|
||||
RD::get_singleton()->buffer_update(scene_state.reflection_buffer, 0, MIN(scene_state.max_reflections, p_reflection_probe_cull_count) * sizeof(ReflectionData), scene_state.reflections, true);
|
||||
}
|
||||
}
|
||||
|
||||
void RasterizerSceneForwardRD::_setup_lights(RID *p_light_cull_result, int p_light_cull_count, const Transform &p_camera_inverse_transform, RID p_shadow_atlas) {
|
||||
|
||||
uint32_t light_count = 0;
|
||||
scene_state.ubo.directional_light_count = 0;
|
||||
|
||||
for (int i = 0; i < p_light_cull_count; i++) {
|
||||
|
||||
RID li = p_light_cull_result[i];
|
||||
RID base = light_instance_get_base_light(li);
|
||||
|
||||
ERR_CONTINUE(base.is_null());
|
||||
|
||||
VS::LightType type = storage->light_get_type(base);
|
||||
switch (type) {
|
||||
|
||||
case VS::LIGHT_DIRECTIONAL: {
|
||||
|
||||
if (scene_state.ubo.directional_light_count >= scene_state.max_directional_lights) {
|
||||
continue;
|
||||
}
|
||||
} break;
|
||||
case VS::LIGHT_SPOT:
|
||||
case VS::LIGHT_OMNI: {
|
||||
|
||||
if (light_count >= scene_state.max_lights) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Transform light_transform = light_instance_get_base_transform(li);
|
||||
|
||||
LightData &light_data = scene_state.lights[light_count];
|
||||
|
||||
float sign = storage->light_is_negative(base) ? -1 : 1;
|
||||
Color linear_col = storage->light_get_color(base).to_linear();
|
||||
|
||||
light_data.attenuation_energy[0] = Math::make_half_float(storage->light_get_param(base, VS::LIGHT_PARAM_ATTENUATION));
|
||||
light_data.attenuation_energy[1] = Math::make_half_float(sign * storage->light_get_param(base, VS::LIGHT_PARAM_ENERGY) * Math_PI);
|
||||
|
||||
light_data.color_specular[0] = CLAMP(uint32_t(linear_col.r * 255), 0, 255);
|
||||
light_data.color_specular[1] = CLAMP(uint32_t(linear_col.g * 255), 0, 255);
|
||||
light_data.color_specular[2] = CLAMP(uint32_t(linear_col.b * 255), 0, 255);
|
||||
light_data.color_specular[3] = CLAMP(uint32_t(storage->light_get_param(base, VS::LIGHT_PARAM_SPECULAR) * 255), 0, 255);
|
||||
|
||||
light_data.inv_radius = 1.0 / MAX(0.001, storage->light_get_param(base, VS::LIGHT_PARAM_RANGE));
|
||||
|
||||
Vector3 pos = p_camera_inverse_transform.xform(light_transform.origin);
|
||||
|
||||
light_data.position[0] = pos.x;
|
||||
light_data.position[1] = pos.y;
|
||||
light_data.position[2] = pos.z;
|
||||
|
||||
Vector3 direction = p_camera_inverse_transform.basis.xform(light_transform.basis.xform(Vector3(0, 0, -1))).normalized();
|
||||
|
||||
light_data.direction[0] = direction.x;
|
||||
light_data.direction[1] = direction.y;
|
||||
light_data.direction[2] = direction.z;
|
||||
|
||||
light_data.cone_attenuation_angle[0] = Math::make_half_float(storage->light_get_param(base, VS::LIGHT_PARAM_SPOT_ATTENUATION));
|
||||
light_data.cone_attenuation_angle[1] = Math::make_half_float(Math::cos(Math::deg2rad(storage->light_get_param(base, VS::LIGHT_PARAM_SPOT_ANGLE))));
|
||||
|
||||
light_data.mask = storage->light_get_cull_mask(base);
|
||||
|
||||
Color shadow_color = storage->light_get_shadow_color(base);
|
||||
|
||||
bool has_shadow = storage->light_has_shadow(base);
|
||||
light_data.shadow_color_enabled[0] = CLAMP(uint32_t(shadow_color.r * 255), 0, 255);
|
||||
light_data.shadow_color_enabled[1] = CLAMP(uint32_t(shadow_color.g * 255), 0, 255);
|
||||
light_data.shadow_color_enabled[2] = CLAMP(uint32_t(shadow_color.b * 255), 0, 255);
|
||||
light_data.shadow_color_enabled[3] = has_shadow ? 255 : 0;
|
||||
|
||||
light_data.atlas_rect[0] = 0;
|
||||
light_data.atlas_rect[1] = 0;
|
||||
light_data.atlas_rect[2] = 0;
|
||||
light_data.atlas_rect[3] = 0;
|
||||
|
||||
if (storage->light_has_shadow(base) && p_shadow_atlas.is_valid() && shadow_atlas_owns_light_instance(p_shadow_atlas, li)) {
|
||||
// fill in the shadow information
|
||||
|
||||
Rect2 rect = light_instance_get_shadow_atlas_rect(li, p_shadow_atlas);
|
||||
|
||||
if (type == VS::LIGHT_OMNI) {
|
||||
|
||||
light_data.atlas_rect[0] = rect.position.x;
|
||||
light_data.atlas_rect[1] = rect.position.y;
|
||||
light_data.atlas_rect[2] = rect.size.width;
|
||||
light_data.atlas_rect[3] = rect.size.height * 0.5;
|
||||
|
||||
Transform proj = (p_camera_inverse_transform * light_transform).inverse();
|
||||
|
||||
store_transform(proj, light_data.shadow_matrix);
|
||||
} else if (type == VS::LIGHT_SPOT) {
|
||||
|
||||
Transform modelview = (p_camera_inverse_transform * light_transform).inverse();
|
||||
CameraMatrix bias;
|
||||
bias.set_light_bias();
|
||||
CameraMatrix rectm;
|
||||
rectm.set_light_atlas_rect(rect);
|
||||
|
||||
CameraMatrix shadow_mtx = rectm * bias * light_instance_get_shadow_camera(li, 0) * modelview;
|
||||
store_camera(shadow_mtx, light_data.shadow_matrix);
|
||||
}
|
||||
}
|
||||
|
||||
light_instance_set_index(li, light_count);
|
||||
|
||||
light_count++;
|
||||
} break;
|
||||
}
|
||||
|
||||
light_instance_set_render_pass(li, render_pass);
|
||||
|
||||
//update UBO for forward rendering, blit to texture for clustered
|
||||
}
|
||||
|
||||
if (light_count) {
|
||||
RD::get_singleton()->buffer_update(scene_state.light_buffer, 0, sizeof(LightData) * light_count, scene_state.lights, true);
|
||||
}
|
||||
|
||||
if (scene_state.ubo.directional_light_count) {
|
||||
RD::get_singleton()->buffer_update(scene_state.directional_light_buffer, 0, sizeof(DirectionalLightData) * light_count, scene_state.directional_lights, true);
|
||||
}
|
||||
}
|
||||
|
||||
void RasterizerSceneForwardRD::_render_scene(RenderBufferData *p_buffer_data, 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_environment, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass) {
|
||||
|
||||
RenderBufferDataForward *render_buffer = (RenderBufferDataForward *)p_buffer_data;
|
||||
|
||||
ERR_FAIL_COND(!render_buffer); //bug out for now
|
||||
|
||||
//first of all, make a new render pass
|
||||
render_pass++;
|
||||
|
||||
|
@ -1388,14 +1525,34 @@ void RasterizerSceneForwardRD::_render_scene(RenderBufferData *p_buffer_data, co
|
|||
scene_state.ubo.viewport_size[1] = vp_he.y;
|
||||
|
||||
RID render_target;
|
||||
Size2 screen_pixel_size;
|
||||
RID opaque_framebuffer;
|
||||
RID alpha_framebuffer;
|
||||
|
||||
if (render_buffer) {
|
||||
scene_state.ubo.screen_pixel_size[0] = 1.0 / render_buffer->width;
|
||||
scene_state.ubo.screen_pixel_size[1] = 1.0 / render_buffer->height;
|
||||
screen_pixel_size.width = 1.0 / render_buffer->width;
|
||||
screen_pixel_size.height = 1.0 / render_buffer->height;
|
||||
render_target = render_buffer->render_target;
|
||||
|
||||
opaque_framebuffer = render_buffer->color_fb;
|
||||
alpha_framebuffer = opaque_framebuffer;
|
||||
|
||||
} else if (p_reflection_probe.is_valid()) {
|
||||
uint32_t resolution = reflection_probe_instance_get_resolution(p_reflection_probe);
|
||||
screen_pixel_size.width = 1.0 / resolution;
|
||||
screen_pixel_size.height = 1.0 / resolution;
|
||||
|
||||
opaque_framebuffer = reflection_probe_instance_get_framebuffer(p_reflection_probe, p_reflection_probe_pass);
|
||||
alpha_framebuffer = opaque_framebuffer;
|
||||
|
||||
} else {
|
||||
ERR_FAIL(); //bug?
|
||||
}
|
||||
|
||||
_setup_environment(render_target, p_environment, p_cam_projection, p_cam_transform, p_reflection_probe.is_valid());
|
||||
_setup_lights(p_light_cull_result, p_light_cull_count, p_cam_transform.affine_inverse(), p_shadow_atlas);
|
||||
_setup_reflections(p_reflection_probe_cull_result, p_reflection_probe_cull_count, p_cam_transform.affine_inverse(), p_environment);
|
||||
_setup_environment(render_target, p_environment, p_cam_projection, p_cam_transform, p_reflection_probe.is_valid(), screen_pixel_size, p_shadow_atlas);
|
||||
|
||||
#if 0
|
||||
for (int i = 0; i < p_light_cull_count; i++) {
|
||||
|
||||
|
@ -1771,10 +1928,12 @@ void RasterizerSceneForwardRD::_render_scene(RenderBufferData *p_buffer_data, co
|
|||
}
|
||||
}
|
||||
|
||||
_setup_render_base_uniform_set(RID(), RID(), RID(), RID(), radiance_cubemap);
|
||||
_setup_render_base_uniform_set(RID(), RID(), RID(), RID(), radiance_cubemap, p_shadow_atlas, RID());
|
||||
|
||||
render_list.sort_by_key(false);
|
||||
|
||||
_fill_instances(render_list.elements, render_list.element_count);
|
||||
|
||||
bool can_continue = true; //unless the middle buffers are needed
|
||||
bool using_separate_specular = false;
|
||||
|
||||
|
@ -1782,14 +1941,14 @@ void RasterizerSceneForwardRD::_render_scene(RenderBufferData *p_buffer_data, co
|
|||
//regular forward for now
|
||||
Vector<Color> c;
|
||||
c.push_back(clear_color.to_linear());
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(render_buffer->color_fb, keep_color ? RD::INITIAL_ACTION_KEEP_COLOR : RD::INITIAL_ACTION_CLEAR, (can_continue || draw_sky) ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ_COLOR_AND_DEPTH, c);
|
||||
_render_list(draw_list, RD::get_singleton()->framebuffer_get_format(render_buffer->color_fb), render_list.elements, render_list.element_count, false, PASS_MODE_COLOR, render_buffer == nullptr);
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(opaque_framebuffer, keep_color ? RD::INITIAL_ACTION_KEEP_COLOR : RD::INITIAL_ACTION_CLEAR, (can_continue || draw_sky) ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ_COLOR_AND_DEPTH, c);
|
||||
_render_list(draw_list, RD::get_singleton()->framebuffer_get_format(opaque_framebuffer), render_list.elements, render_list.element_count, false, PASS_MODE_COLOR, render_buffer == nullptr);
|
||||
RD::get_singleton()->draw_list_end();
|
||||
}
|
||||
|
||||
if (draw_sky) {
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(render_buffer->color_fb, RD::INITIAL_ACTION_CONTINUE, can_continue ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ_COLOR_AND_DEPTH);
|
||||
_draw_sky(draw_list, RD::get_singleton()->framebuffer_get_format(render_buffer->color_fb), p_environment, p_cam_projection, p_cam_transform, 1.0);
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(opaque_framebuffer, RD::INITIAL_ACTION_CONTINUE, can_continue ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ_COLOR_AND_DEPTH);
|
||||
_draw_sky(draw_list, RD::get_singleton()->framebuffer_get_format(opaque_framebuffer), p_environment, p_cam_projection, p_cam_transform, 1.0);
|
||||
RD::get_singleton()->draw_list_end();
|
||||
|
||||
if (using_separate_specular && !can_continue) {
|
||||
|
@ -1887,9 +2046,11 @@ void RasterizerSceneForwardRD::_render_scene(RenderBufferData *p_buffer_data, co
|
|||
#endif
|
||||
render_list.sort_by_reverse_depth_and_priority(true);
|
||||
|
||||
_fill_instances(&render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count);
|
||||
|
||||
{
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(render_buffer->color_fb, can_continue ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP_COLOR_AND_DEPTH, RD::FINAL_ACTION_READ_COLOR_AND_DEPTH);
|
||||
_render_list(draw_list, RD::get_singleton()->framebuffer_get_format(render_buffer->color_fb), &render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, false, PASS_MODE_COLOR, render_buffer == nullptr);
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(alpha_framebuffer, can_continue ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP_COLOR_AND_DEPTH, RD::FINAL_ACTION_READ_COLOR_AND_DEPTH);
|
||||
_render_list(draw_list, RD::get_singleton()->framebuffer_get_format(alpha_framebuffer), &render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, false, PASS_MODE_COLOR, render_buffer == nullptr);
|
||||
RD::get_singleton()->draw_list_end();
|
||||
}
|
||||
|
||||
|
@ -1907,7 +2068,7 @@ void RasterizerSceneForwardRD::_render_scene(RenderBufferData *p_buffer_data, co
|
|||
}
|
||||
#endif
|
||||
if (p_reflection_probe.is_valid()) {
|
||||
//rendering a probe, do no more!
|
||||
//was rendering a probe, so do no more
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1931,6 +2092,15 @@ void RasterizerSceneForwardRD::_render_scene(RenderBufferData *p_buffer_data, co
|
|||
|
||||
storage->render_target_disable_clear_request(render_buffer->render_target);
|
||||
|
||||
if (true) {
|
||||
if (p_shadow_atlas.is_valid()) {
|
||||
RID shadow_atlas_texture = shadow_atlas_get_texture(p_shadow_atlas);
|
||||
Size2 rtsize = storage->render_target_get_size(render_buffer->render_target);
|
||||
|
||||
effects->copy_to_rect(shadow_atlas_texture, storage->render_target_get_rd_framebuffer(render_buffer->render_target), Rect2(Vector2(), rtsize / 2));
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
_post_process(env, p_cam_projection);
|
||||
// Needed only for debugging
|
||||
|
@ -1988,8 +2158,38 @@ void RasterizerSceneForwardRD::_render_scene(RenderBufferData *p_buffer_data, co
|
|||
//disable all stuff
|
||||
#endif
|
||||
}
|
||||
void RasterizerSceneForwardRD::_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) {
|
||||
|
||||
void RasterizerSceneForwardRD::_setup_render_base_uniform_set(RID p_depth_buffer, RID p_color_buffer, RID p_normal_buffer, RID p_roughness_limit_buffer, RID p_radiance_cubemap) {
|
||||
render_pass++;
|
||||
|
||||
scene_state.ubo.shadow_z_offset = p_bias;
|
||||
scene_state.ubo.shadow_z_slope_scale = p_normal_bias;
|
||||
scene_state.ubo.z_far = p_zfar;
|
||||
scene_state.ubo.dual_paraboloid_side = p_use_dp_flip ? -1 : 1;
|
||||
|
||||
_setup_environment(RID(), RID(), p_projection, p_transform, true, Vector2(1, 1), RID());
|
||||
|
||||
render_list.clear();
|
||||
|
||||
PassMode pass_mode = p_use_dp ? PASS_MODE_SHADOW_DP : PASS_MODE_SHADOW;
|
||||
|
||||
_fill_render_list(p_cull_result, p_cull_count, pass_mode, true);
|
||||
|
||||
_setup_render_base_uniform_set(RID(), RID(), RID(), RID(), RID(), RID(), RID());
|
||||
|
||||
render_list.sort_by_key(false);
|
||||
|
||||
_fill_instances(render_list.elements, render_list.element_count);
|
||||
|
||||
{
|
||||
//regular forward for now
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ_COLOR_AND_DEPTH);
|
||||
_render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), render_list.elements, render_list.element_count, p_use_dp_flip, pass_mode, true);
|
||||
RD::get_singleton()->draw_list_end();
|
||||
}
|
||||
}
|
||||
|
||||
void RasterizerSceneForwardRD::_setup_render_base_uniform_set(RID p_depth_buffer, RID p_color_buffer, RID p_normal_buffer, RID p_roughness_limit_buffer, RID p_radiance_cubemap, RID p_shadow_atlas, RID p_reflection_atlas) {
|
||||
|
||||
if (render_base_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set)) {
|
||||
RD::get_singleton()->free(render_base_uniform_set);
|
||||
|
@ -2065,20 +2265,79 @@ void RasterizerSceneForwardRD::_setup_render_base_uniform_set(RID p_depth_buffer
|
|||
{
|
||||
RD::Uniform u;
|
||||
u.binding = 7;
|
||||
u.type = RD::UNIFORM_TYPE_SAMPLER;
|
||||
u.ids.push_back(shadow_sampler);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.binding = 8;
|
||||
u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
|
||||
u.ids.push_back(scene_state.uniform_buffer);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.binding = 9;
|
||||
u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
|
||||
u.ids.push_back(scene_state.instance_buffer);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.binding = 10;
|
||||
u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
|
||||
u.ids.push_back(scene_state.reflection_buffer);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.binding = 11;
|
||||
u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
|
||||
u.ids.push_back(scene_state.light_buffer);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.binding = 12;
|
||||
u.type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
if (p_shadow_atlas.is_valid()) {
|
||||
u.ids.push_back(shadow_atlas_get_texture(p_shadow_atlas));
|
||||
} else {
|
||||
u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE));
|
||||
}
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.binding = 13;
|
||||
u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
|
||||
u.ids.push_back(scene_state.directional_light_buffer);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.binding = 14;
|
||||
u.type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
if (directional_shadow_get_texture().is_valid()) {
|
||||
u.ids.push_back(directional_shadow_get_texture());
|
||||
} else {
|
||||
u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE));
|
||||
}
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
|
||||
render_base_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, default_shader_rd, 0);
|
||||
}
|
||||
|
||||
RasterizerSceneForwardRD *RasterizerSceneForwardRD::singleton = NULL;
|
||||
|
||||
void RasterizerSceneForwardRD::set_scene_pass(uint64_t p_pass) {
|
||||
scene_pass = p_pass;
|
||||
}
|
||||
|
||||
void RasterizerSceneForwardRD::set_time(double p_time) {
|
||||
time = p_time;
|
||||
}
|
||||
|
@ -2097,8 +2356,53 @@ RasterizerSceneForwardRD::RasterizerSceneForwardRD(RasterizerStorageRD *p_storag
|
|||
defines += "\n#define USE_RADIANCE_CUBEMAP_ARRAY \n";
|
||||
}
|
||||
|
||||
uint32_t textures_per_stage = RD::get_singleton()->limit_get(RD::LIMIT_MAX_TEXTURES_PER_SHADER_STAGE);
|
||||
|
||||
if (textures_per_stage <= 16) {
|
||||
//ARM pretty much, and very old Intel GPUs under Linux
|
||||
scene_state.max_reflection_probes_per_instance = 4; //sad
|
||||
} else {
|
||||
//maximum 8
|
||||
scene_state.max_reflection_probes_per_instance = 8;
|
||||
}
|
||||
|
||||
defines += "\n#define MAX_REFLECTION_PROBES " + itos(scene_state.max_reflection_probes_per_instance) + "\n";
|
||||
|
||||
uint32_t uniform_max_size = RD::get_singleton()->limit_get(RD::LIMIT_MAX_UNIFORM_BUFFER_SIZE);
|
||||
|
||||
{ //reflections
|
||||
uint32_t reflection_buffer_size;
|
||||
if (uniform_max_size < 65536) {
|
||||
//Yes, you guessed right, ARM again
|
||||
reflection_buffer_size = uniform_max_size;
|
||||
} else {
|
||||
reflection_buffer_size = 65536;
|
||||
}
|
||||
|
||||
scene_state.max_reflections = reflection_buffer_size / sizeof(ReflectionData);
|
||||
scene_state.reflections = memnew_arr(ReflectionData, scene_state.max_reflections);
|
||||
scene_state.reflection_buffer = RD::get_singleton()->uniform_buffer_create(reflection_buffer_size);
|
||||
defines += "\n#define MAX_REFLECTION_DATA_STRUCTS " + itos(scene_state.max_reflections) + "\n";
|
||||
}
|
||||
|
||||
{ //lights
|
||||
scene_state.max_lights = MIN(65536, uniform_max_size) / sizeof(LightData);
|
||||
uint32_t light_buffer_size = scene_state.max_lights * sizeof(LightData);
|
||||
print_line("ID: " + itos(sizeof(InstanceData)));
|
||||
scene_state.lights = memnew_arr(LightData, scene_state.max_lights);
|
||||
scene_state.light_buffer = RD::get_singleton()->uniform_buffer_create(light_buffer_size);
|
||||
defines += "\n#define MAX_LIGHT_DATA_STRUCTS " + itos(scene_state.max_lights) + "\n";
|
||||
|
||||
scene_state.max_directional_lights = 4;
|
||||
uint32_t directional_light_buffer_size = scene_state.max_directional_lights * sizeof(DirectionalLightData);
|
||||
scene_state.directional_lights = memnew_arr(DirectionalLightData, scene_state.max_directional_lights);
|
||||
scene_state.directional_light_buffer = RD::get_singleton()->uniform_buffer_create(directional_light_buffer_size);
|
||||
defines += "\n#define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS " + itos(scene_state.max_directional_lights) + "\n";
|
||||
}
|
||||
|
||||
Vector<String> shader_versions;
|
||||
shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n");
|
||||
shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_DUAL_PARABOLOID\n");
|
||||
shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define ENABLE_WRITE_NORMAL_BUFFER\n");
|
||||
shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define ENABLE_WRITE_NORMAL_ROUGHNESS_BUFFER\n");
|
||||
shader_versions.push_back("");
|
||||
|
@ -2198,7 +2502,7 @@ RasterizerSceneForwardRD::RasterizerSceneForwardRD(RasterizerStorageRD *p_storag
|
|||
actions.usage_defines["POSITION"] = "#define OVERRIDE_POSITION\n";
|
||||
|
||||
actions.usage_defines["SSS_STRENGTH"] = "#define ENABLE_SSS\n";
|
||||
actions.usage_defines["TRANSMISSION"] = "#define TRANSMISSION_USED\n";
|
||||
actions.usage_defines["TRANSMISSION"] = "#define LIGHT_TRANSMISSION_USED\n";
|
||||
actions.usage_defines["SCREEN_TEXTURE"] = "#define SCREEN_TEXTURE_USED\n";
|
||||
actions.usage_defines["SCREEN_UV"] = "#define SCREEN_UV_USED\n";
|
||||
|
||||
|
@ -2249,11 +2553,17 @@ RasterizerSceneForwardRD::RasterizerSceneForwardRD(RasterizerStorageRD *p_storag
|
|||
}
|
||||
|
||||
//render list
|
||||
render_list.max_elements = GLOBAL_DEF_RST("rendering/limits/rendering/max_renderable_elements", (int)256000);
|
||||
render_list.max_elements = GLOBAL_DEF_RST("rendering/limits/rendering/max_renderable_elements", (int)128000);
|
||||
render_list.init();
|
||||
scene_pass = 0;
|
||||
render_pass = 0;
|
||||
|
||||
{
|
||||
|
||||
scene_state.max_instances = render_list.max_elements;
|
||||
scene_state.instances = memnew_arr(InstanceData, scene_state.max_instances);
|
||||
scene_state.instance_buffer = RD::get_singleton()->storage_buffer_create(sizeof(InstanceData) * scene_state.max_instances);
|
||||
}
|
||||
|
||||
scene_state.uniform_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(SceneState::UBO));
|
||||
|
||||
{
|
||||
|
@ -2266,6 +2576,16 @@ RasterizerSceneForwardRD::RasterizerSceneForwardRD(RasterizerStorageRD *p_storag
|
|||
MaterialData *md = (MaterialData *)storage->material_get_data(default_material, RasterizerStorageRD::SHADER_TYPE_3D);
|
||||
default_shader_rd = shader.scene_shader.version_get_shader(md->shader_data->version, SHADER_VERSION_COLOR_PASS);
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
RD::SamplerState sampler;
|
||||
sampler.mag_filter = RD::SAMPLER_FILTER_LINEAR;
|
||||
sampler.min_filter = RD::SAMPLER_FILTER_LINEAR;
|
||||
sampler.enable_compare = true;
|
||||
sampler.compare_op = RD::COMPARE_OP_LESS;
|
||||
shadow_sampler = RD::get_singleton()->sampler_create(sampler);
|
||||
}
|
||||
}
|
||||
|
||||
RasterizerSceneForwardRD::~RasterizerSceneForwardRD() {
|
||||
|
@ -2273,4 +2593,9 @@ RasterizerSceneForwardRD::~RasterizerSceneForwardRD() {
|
|||
if (render_base_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set)) {
|
||||
RD::get_singleton()->free(render_base_uniform_set);
|
||||
}
|
||||
|
||||
{
|
||||
RD::get_singleton()->free(scene_state.reflection_buffer);
|
||||
memdelete_arr(scene_state.reflections);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ class RasterizerSceneForwardRD : public RasterizerSceneRD {
|
|||
|
||||
enum ShaderVersion {
|
||||
SHADER_VERSION_DEPTH_PASS,
|
||||
SHADER_VERSION_DEPTH_PASS_DP,
|
||||
SHADER_VERSION_DEPTH_PASS_WITH_NORMAL,
|
||||
SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS,
|
||||
SHADER_VERSION_COLOR_PASS,
|
||||
|
@ -174,37 +175,11 @@ class RasterizerSceneForwardRD : public RasterizerSceneRD {
|
|||
return static_cast<RasterizerSceneForwardRD *>(singleton)->_create_material_func(static_cast<ShaderData *>(p_shader));
|
||||
}
|
||||
|
||||
/* Instance Custom Data */
|
||||
|
||||
struct InstanceGeometryData : public InstanceCustomData {
|
||||
|
||||
struct UBO {
|
||||
float transform[16];
|
||||
float normal_transform[12];
|
||||
uint32_t flags;
|
||||
uint32_t pad[3];
|
||||
};
|
||||
|
||||
RID ubo;
|
||||
RID uniform_set_base;
|
||||
RID uniform_set_gi;
|
||||
|
||||
bool ubo_dirty = true;
|
||||
bool using_lightmap_gi = false;
|
||||
bool using_vct_gi = false;
|
||||
};
|
||||
|
||||
/* Push Constant */
|
||||
|
||||
struct PushConstant {
|
||||
uint32_t reflection_probe_count;
|
||||
uint32_t omni_light_count;
|
||||
uint32_t spot_light_count;
|
||||
uint32_t decal_count;
|
||||
float reflection_probe_indices[4];
|
||||
float omni_light_indices[4];
|
||||
float spot_light_indices[4];
|
||||
float decal_indices[4];
|
||||
uint32_t index;
|
||||
uint32_t pad[3];
|
||||
};
|
||||
|
||||
/* Framebuffer */
|
||||
|
@ -227,11 +202,65 @@ class RasterizerSceneForwardRD : public RasterizerSceneRD {
|
|||
|
||||
virtual RenderBufferData *_create_render_buffer_data();
|
||||
|
||||
RID shadow_sampler;
|
||||
RID render_base_uniform_set;
|
||||
void _setup_render_base_uniform_set(RID p_depth_buffer, RID p_color_buffer, RID p_normal_buffer, RID p_roughness_limit_buffer, RID p_radiance_cubemap);
|
||||
void _setup_render_base_uniform_set(RID p_depth_buffer, RID p_color_buffer, RID p_normal_buffer, RID p_roughness_limit_buffer, RID p_radiance_cubemap, RID p_shadow_atlas, RID p_reflection_atlas);
|
||||
|
||||
/* Scene State UBO */
|
||||
|
||||
struct ReflectionData { //should always be 128 bytes
|
||||
float box_extents[4];
|
||||
float box_offset[4];
|
||||
float params[4]; // intensity, 0, interior , boxproject
|
||||
float ambient[4]; // ambient color, energy
|
||||
float local_matrix[16]; // up to here for spot and omni, rest is for directional
|
||||
};
|
||||
|
||||
struct LightData {
|
||||
float position[3];
|
||||
float inv_radius;
|
||||
float direction[3];
|
||||
uint16_t attenuation_energy[2]; //16 bits attenuation, then energy
|
||||
uint8_t color_specular[4]; //rgb color, a specular (8 bit unorm)
|
||||
uint16_t cone_attenuation_angle[2]; // attenuation and angle, (16bit float)
|
||||
uint32_t mask;
|
||||
uint8_t shadow_color_enabled[4]; //shadow rgb color, a>0.5 enabled (8bit unorm)
|
||||
float atlas_rect[4]; // in omni, used for atlas uv, in spot, used for projector uv
|
||||
float shadow_matrix[16];
|
||||
};
|
||||
|
||||
struct DirectionalLightData {
|
||||
|
||||
float direction[3];
|
||||
float energy;
|
||||
float color[3];
|
||||
float specular;
|
||||
uint32_t mask;
|
||||
uint32_t pad[3];
|
||||
float shadow_color[3];
|
||||
uint32_t shadow_enabled;
|
||||
float shadow_atlas_rect[4];
|
||||
float shadow_split_offsets[4];
|
||||
float shadow_matrix1[16];
|
||||
float shadow_matrix2[16];
|
||||
float shadow_matrix3[16];
|
||||
float shadow_matrix4[16];
|
||||
};
|
||||
|
||||
struct InstanceData {
|
||||
float transform[16];
|
||||
float normal_transform[16];
|
||||
uint32_t flags;
|
||||
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 {
|
||||
struct UBO {
|
||||
float projection_matrix[16];
|
||||
|
@ -257,12 +286,37 @@ class RasterizerSceneForwardRD : public RasterizerSceneRD {
|
|||
uint32_t use_reflection_cubemap;
|
||||
|
||||
float radiance_inverse_xform[12];
|
||||
|
||||
float shadow_atlas_pixel_size[2];
|
||||
float directional_shadow_pixel_size[2];
|
||||
|
||||
uint32_t directional_light_count;
|
||||
float dual_paraboloid_side;
|
||||
float z_far;
|
||||
uint32_t pad[1];
|
||||
};
|
||||
|
||||
UBO ubo;
|
||||
|
||||
RID uniform_buffer;
|
||||
|
||||
ReflectionData *reflections;
|
||||
uint32_t max_reflections;
|
||||
RID reflection_buffer;
|
||||
uint32_t max_reflection_probes_per_instance;
|
||||
|
||||
LightData *lights;
|
||||
uint32_t max_lights;
|
||||
RID light_buffer;
|
||||
|
||||
DirectionalLightData *directional_lights;
|
||||
uint32_t max_directional_lights;
|
||||
RID directional_light_buffer;
|
||||
|
||||
RID instance_buffer;
|
||||
InstanceData *instances;
|
||||
uint32_t max_instances;
|
||||
|
||||
bool used_screen_texture = false;
|
||||
bool used_normal_texture = false;
|
||||
bool used_depth_texture = false;
|
||||
|
@ -283,10 +337,14 @@ class RasterizerSceneForwardRD : public RasterizerSceneRD {
|
|||
union {
|
||||
struct {
|
||||
//from least significant to most significant in sort, TODO: should be endian swapped on big endian
|
||||
uint64_t material_index : 20;
|
||||
uint64_t shader_index : 20;
|
||||
uint64_t priority : 16;
|
||||
uint64_t depth_layer : 8;
|
||||
uint64_t geometry_index : 20;
|
||||
uint64_t material_index : 15;
|
||||
uint64_t shader_index : 12;
|
||||
uint64_t uses_instancing : 1;
|
||||
uint64_t uses_vct : 1;
|
||||
uint64_t uses_lightmap : 1;
|
||||
uint64_t depth_layer : 4;
|
||||
uint64_t priority : 8;
|
||||
};
|
||||
|
||||
uint64_t sort_key;
|
||||
|
@ -407,7 +465,6 @@ class RasterizerSceneForwardRD : public RasterizerSceneRD {
|
|||
RenderList render_list;
|
||||
|
||||
static RasterizerSceneForwardRD *singleton;
|
||||
uint64_t scene_pass;
|
||||
uint64_t render_pass;
|
||||
double time;
|
||||
RID default_shader;
|
||||
|
@ -419,39 +476,33 @@ class RasterizerSceneForwardRD : public RasterizerSceneRD {
|
|||
PASS_MODE_COLOR_SPECULAR,
|
||||
PASS_MODE_COLOR_TRANSPARENT,
|
||||
PASS_MODE_SHADOW,
|
||||
PASS_MODE_SHADOW_DP,
|
||||
PASS_MODE_DEPTH,
|
||||
PASS_MODE_DEPTH_NORMAL,
|
||||
PASS_MODE_DEPTH_NORMAL_ROUGHNESS,
|
||||
};
|
||||
|
||||
void _setup_environment(RID p_render_target, RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, bool p_no_fog);
|
||||
void _setup_environment(RID p_render_target, RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, bool p_no_fog, const Size2 &p_screen_pixel_size, RID p_shadow_atlas);
|
||||
void _setup_lights(RID *p_light_cull_result, int p_light_cull_count, const Transform &p_camera_inverse_transform, RID p_shadow_atlas);
|
||||
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 _fill_instances(RenderList::Element **p_elements, int p_element_count);
|
||||
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);
|
||||
_FORCE_INLINE_ void _add_geometry(InstanceBase *p_instance, uint32_t p_surface, RID p_material, PassMode p_pass_mode);
|
||||
_FORCE_INLINE_ void _add_geometry_with_material(InstanceBase *p_instance, uint32_t p_surface, MaterialData *p_material, PassMode p_pass_mode);
|
||||
_FORCE_INLINE_ void _add_geometry(InstanceBase *p_instance, uint32_t p_surface, RID p_material, PassMode p_pass_mode, uint32_t p_geometry_index);
|
||||
_FORCE_INLINE_ void _add_geometry_with_material(InstanceBase *p_instance, uint32_t p_surface, MaterialData *p_material, PassMode p_pass_mode, uint32_t p_geometry_index);
|
||||
|
||||
void _fill_render_list(InstanceBase **p_cull_result, int p_cull_count, PassMode p_pass_mode, bool p_no_gi);
|
||||
|
||||
void _draw_sky(RD::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_fb_format, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform, float p_alpha);
|
||||
|
||||
protected:
|
||||
virtual void _render_scene(RenderBufferData *p_buffer_data, 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_environment, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass);
|
||||
virtual void _render_scene(RenderBufferData *p_buffer_data, 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_environment, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass);
|
||||
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);
|
||||
|
||||
public:
|
||||
virtual void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count) {}
|
||||
|
||||
virtual void set_scene_pass(uint64_t p_pass);
|
||||
virtual void set_time(double p_time);
|
||||
virtual void set_debug_draw_mode(VS::ViewportDebugDraw p_debug_draw) {}
|
||||
|
||||
virtual void instance_create_custom_data(InstanceBase *p_instance);
|
||||
virtual void instance_free_custom_data(InstanceBase *p_instance);
|
||||
virtual void instance_custom_data_update_lights(InstanceBase *p_instance);
|
||||
virtual void instance_custom_data_update_reflection_probes(InstanceBase *p_instance);
|
||||
virtual void instance_custom_data_update_gi_probes(InstanceBase *p_instance);
|
||||
virtual void instance_custom_data_update_lightmap(InstanceBase *p_instance);
|
||||
virtual void instance_custom_data_update_transform(InstanceBase *p_instance);
|
||||
|
||||
virtual bool free(RID p_rid);
|
||||
|
||||
RasterizerSceneForwardRD(RasterizerStorageRD *p_storage);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -15,20 +15,17 @@ protected:
|
|||
};
|
||||
virtual RenderBufferData *_create_render_buffer_data() = 0;
|
||||
|
||||
virtual void _render_scene(RenderBufferData *p_buffer_data, 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_environment, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) = 0;
|
||||
virtual void _render_scene(RenderBufferData *p_buffer_data, 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_environment, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass) = 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) = 0;
|
||||
|
||||
private:
|
||||
int roughness_layers;
|
||||
|
||||
RasterizerStorageRD *storage;
|
||||
|
||||
struct Sky {
|
||||
int radiance_size = 256;
|
||||
VS::SkyMode mode = VS::SKY_MODE_QUALITY;
|
||||
RID panorama;
|
||||
struct ReflectionData {
|
||||
RID radiance;
|
||||
bool dirty = false;
|
||||
Sky *dirty_list = nullptr;
|
||||
|
||||
struct Layer {
|
||||
struct Mipmap {
|
||||
RID framebuffers[6];
|
||||
|
@ -38,9 +35,26 @@ private:
|
|||
Vector<Mipmap> mipmaps;
|
||||
};
|
||||
RID radiance_base_cubemap; //cubemap for first layer, first cubemap
|
||||
|
||||
Vector<Layer> layers;
|
||||
};
|
||||
|
||||
void _clear_reflection_data(ReflectionData &rd);
|
||||
void _update_reflection_data(ReflectionData &rd, int p_size, bool p_quality);
|
||||
void _create_reflection_from_panorama(ReflectionData &rd, RID p_panorama, bool p_quality);
|
||||
void _create_reflection_from_base_mipmap(ReflectionData &rd, bool p_quality, int p_cube_side);
|
||||
void _update_reflection_mipmaps(ReflectionData &rd, bool p_quality);
|
||||
|
||||
/* SKY */
|
||||
struct Sky {
|
||||
int radiance_size = 256;
|
||||
VS::SkyMode mode = VS::SKY_MODE_QUALITY;
|
||||
RID panorama;
|
||||
ReflectionData reflection;
|
||||
bool dirty = false;
|
||||
Sky *dirty_list = nullptr;
|
||||
};
|
||||
|
||||
Sky *dirty_sky_list = nullptr;
|
||||
|
||||
void _sky_invalidate(Sky *p_sky);
|
||||
|
@ -52,6 +66,156 @@ private:
|
|||
|
||||
mutable RID_Owner<Sky> sky_owner;
|
||||
|
||||
/* REFLECTION PROBE INSTANCE */
|
||||
|
||||
struct ReflectionProbeInstance {
|
||||
|
||||
RID probe;
|
||||
|
||||
ReflectionData reflection;
|
||||
RID depth_buffer;
|
||||
RID render_fb[6];
|
||||
|
||||
int current_resolution = 0;
|
||||
|
||||
bool dirty = true;
|
||||
bool rendering = false;
|
||||
int processing_side = 0;
|
||||
|
||||
uint32_t render_index = 0;
|
||||
|
||||
Transform transform;
|
||||
};
|
||||
|
||||
mutable RID_Owner<ReflectionProbeInstance> reflection_probe_instance_owner;
|
||||
|
||||
/* SHADOW ATLAS */
|
||||
|
||||
struct ShadowAtlas {
|
||||
|
||||
enum {
|
||||
QUADRANT_SHIFT = 27,
|
||||
SHADOW_INDEX_MASK = (1 << QUADRANT_SHIFT) - 1,
|
||||
SHADOW_INVALID = 0xFFFFFFFF
|
||||
};
|
||||
|
||||
struct Quadrant {
|
||||
|
||||
uint32_t subdivision;
|
||||
|
||||
struct Shadow {
|
||||
RID owner;
|
||||
uint64_t version;
|
||||
uint64_t alloc_tick;
|
||||
|
||||
Shadow() {
|
||||
version = 0;
|
||||
alloc_tick = 0;
|
||||
}
|
||||
};
|
||||
|
||||
Vector<Shadow> shadows;
|
||||
|
||||
Quadrant() {
|
||||
subdivision = 0; //not in use
|
||||
}
|
||||
|
||||
} quadrants[4];
|
||||
|
||||
int size_order[4] = { 0, 1, 2, 3 };
|
||||
uint32_t smallest_subdiv = 0;
|
||||
|
||||
int size = 0;
|
||||
|
||||
RID depth;
|
||||
RID fb; //for copying
|
||||
|
||||
Map<RID, uint32_t> shadow_owners;
|
||||
};
|
||||
|
||||
RID_Owner<ShadowAtlas> shadow_atlas_owner;
|
||||
|
||||
bool _shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int *p_in_quadrants, int p_quadrant_count, int p_current_subdiv, uint64_t p_tick, int &r_quadrant, int &r_shadow);
|
||||
|
||||
/* DIRECTIONAL SHADOW */
|
||||
|
||||
struct DirectionalShadow {
|
||||
RID depth;
|
||||
RID fb; //for copying
|
||||
|
||||
int light_count = 0;
|
||||
int size = 0;
|
||||
int current_light = 0;
|
||||
} directional_shadow;
|
||||
|
||||
/* SHADOW CUBEMAPS */
|
||||
|
||||
struct ShadowCubemap {
|
||||
|
||||
RID cubemap;
|
||||
RID side_fb[6];
|
||||
};
|
||||
|
||||
Map<int, ShadowCubemap> shadow_cubemaps;
|
||||
ShadowCubemap *_get_shadow_cubemap(int p_size);
|
||||
|
||||
struct ShadowMap {
|
||||
RID depth;
|
||||
RID fb;
|
||||
};
|
||||
|
||||
Map<Vector2i, ShadowMap> shadow_maps;
|
||||
ShadowMap *_get_shadow_map(const Size2i &p_size);
|
||||
|
||||
void _create_shadow_cubemaps();
|
||||
|
||||
/* LIGHT INSTANCE */
|
||||
|
||||
struct LightInstance {
|
||||
|
||||
struct ShadowTransform {
|
||||
|
||||
CameraMatrix camera;
|
||||
Transform transform;
|
||||
float farplane;
|
||||
float split;
|
||||
float bias_scale;
|
||||
};
|
||||
|
||||
VS::LightType light_type;
|
||||
|
||||
ShadowTransform shadow_transform[4];
|
||||
|
||||
RID self;
|
||||
RID light;
|
||||
Transform transform;
|
||||
|
||||
Vector3 light_vector;
|
||||
Vector3 spot_vector;
|
||||
float linear_att;
|
||||
|
||||
uint64_t shadow_pass = 0;
|
||||
uint64_t last_scene_pass = 0;
|
||||
uint64_t last_scene_shadow_pass = 0;
|
||||
uint64_t last_pass = 0;
|
||||
uint32_t light_index = 0;
|
||||
uint32_t light_directional_index = 0;
|
||||
|
||||
uint32_t current_shadow_atlas_key;
|
||||
|
||||
Vector2 dp;
|
||||
|
||||
Rect2 directional_rect;
|
||||
|
||||
Set<RID> shadow_atlases; //shadow atlases where this light is registered
|
||||
|
||||
LightInstance() {}
|
||||
};
|
||||
|
||||
mutable RID_Owner<LightInstance> light_instance_owner;
|
||||
|
||||
/* ENVIRONMENT */
|
||||
|
||||
struct Environent {
|
||||
|
||||
// BG
|
||||
|
@ -82,6 +246,8 @@ private:
|
|||
|
||||
mutable RID_Owner<Environent> environment_owner;
|
||||
|
||||
/* RENDER BUFFERS */
|
||||
|
||||
struct RenderBuffers {
|
||||
|
||||
RenderBufferData *data = nullptr;
|
||||
|
@ -92,16 +258,45 @@ private:
|
|||
|
||||
mutable RID_Owner<RenderBuffers> render_buffers_owner;
|
||||
|
||||
uint64_t scene_pass = 0;
|
||||
uint64_t shadow_atlas_realloc_tolerance_msec = 500;
|
||||
|
||||
public:
|
||||
/* SHADOW ATLAS API */
|
||||
|
||||
RID shadow_atlas_create() { return RID(); }
|
||||
void shadow_atlas_set_size(RID p_atlas, int p_size) {}
|
||||
void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) {}
|
||||
bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) { return false; }
|
||||
RID shadow_atlas_create();
|
||||
void shadow_atlas_set_size(RID p_atlas, int p_size);
|
||||
void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision);
|
||||
bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version);
|
||||
_FORCE_INLINE_ bool shadow_atlas_owns_light_instance(RID p_atlas, RID p_light_intance) {
|
||||
ShadowAtlas *atlas = shadow_atlas_owner.getornull(p_atlas);
|
||||
ERR_FAIL_COND_V(!atlas, false);
|
||||
return atlas->shadow_owners.has(p_light_intance);
|
||||
}
|
||||
|
||||
int get_directional_light_shadow_size(RID p_light_intance) { return 0; }
|
||||
void set_directional_shadow_count(int p_count) {}
|
||||
_FORCE_INLINE_ RID shadow_atlas_get_texture(RID p_atlas) {
|
||||
ShadowAtlas *atlas = shadow_atlas_owner.getornull(p_atlas);
|
||||
ERR_FAIL_COND_V(!atlas, RID());
|
||||
return atlas->depth;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Size2i shadow_atlas_get_size(RID p_atlas) {
|
||||
ShadowAtlas *atlas = shadow_atlas_owner.getornull(p_atlas);
|
||||
ERR_FAIL_COND_V(!atlas, Size2i());
|
||||
return Size2(atlas->size, atlas->size);
|
||||
}
|
||||
|
||||
void directional_shadow_atlas_set_size(int p_size);
|
||||
int get_directional_light_shadow_size(RID p_light_intance);
|
||||
void set_directional_shadow_count(int p_count);
|
||||
|
||||
_FORCE_INLINE_ RID directional_shadow_get_texture() {
|
||||
return directional_shadow.depth;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Size2i directional_shadow_get_size() {
|
||||
return Size2i(directional_shadow.size, directional_shadow.size);
|
||||
}
|
||||
|
||||
/* SKY API */
|
||||
|
||||
|
@ -166,22 +361,121 @@ public:
|
|||
void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_end, float p_depth_curve, bool p_transmit, float p_transmit_curve) {}
|
||||
void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve) {}
|
||||
|
||||
RID light_instance_create(RID p_light) { return RID(); }
|
||||
void light_instance_set_transform(RID p_light_instance, const Transform &p_transform) {}
|
||||
void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_bias_scale = 1.0) {}
|
||||
void light_instance_mark_visible(RID p_light_instance) {}
|
||||
RID light_instance_create(RID p_light);
|
||||
void light_instance_set_transform(RID p_light_instance, const Transform &p_transform);
|
||||
void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_bias_scale = 1.0);
|
||||
void light_instance_mark_visible(RID p_light_instance);
|
||||
|
||||
RID reflection_atlas_create() { return RID(); }
|
||||
void reflection_atlas_set_size(RID p_ref_atlas, int p_size) {}
|
||||
void reflection_atlas_set_subdivision(RID p_ref_atlas, int p_subdiv) {}
|
||||
_FORCE_INLINE_ RID light_instance_get_base_light(RID p_light_instance) {
|
||||
LightInstance *li = light_instance_owner.getornull(p_light_instance);
|
||||
return li->light;
|
||||
}
|
||||
|
||||
RID reflection_probe_instance_create(RID p_probe) { return RID(); }
|
||||
void reflection_probe_instance_set_transform(RID p_instance, const Transform &p_transform) {}
|
||||
void reflection_probe_release_atlas_index(RID p_instance) {}
|
||||
bool reflection_probe_instance_needs_redraw(RID p_instance) { return false; }
|
||||
bool reflection_probe_instance_has_reflection(RID p_instance) { return false; }
|
||||
bool reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) { return false; }
|
||||
bool reflection_probe_instance_postprocess_step(RID p_instance) { return true; }
|
||||
_FORCE_INLINE_ Transform light_instance_get_base_transform(RID p_light_instance) {
|
||||
LightInstance *li = light_instance_owner.getornull(p_light_instance);
|
||||
return li->transform;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Rect2 light_instance_get_shadow_atlas_rect(RID p_light_instance, RID p_shadow_atlas) {
|
||||
|
||||
ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas);
|
||||
LightInstance *li = light_instance_owner.getornull(p_light_instance);
|
||||
uint32_t key = shadow_atlas->shadow_owners[li->self];
|
||||
|
||||
uint32_t quadrant = (key >> ShadowAtlas::QUADRANT_SHIFT) & 0x3;
|
||||
uint32_t shadow = key & ShadowAtlas::SHADOW_INDEX_MASK;
|
||||
|
||||
ERR_FAIL_COND_V(shadow >= (uint32_t)shadow_atlas->quadrants[quadrant].shadows.size(), Rect2());
|
||||
|
||||
uint32_t atlas_size = shadow_atlas->size;
|
||||
uint32_t quadrant_size = atlas_size >> 1;
|
||||
|
||||
uint32_t x = (quadrant & 1) * quadrant_size;
|
||||
uint32_t y = (quadrant >> 1) * quadrant_size;
|
||||
|
||||
uint32_t shadow_size = (quadrant_size / shadow_atlas->quadrants[quadrant].subdivision);
|
||||
x += (shadow % shadow_atlas->quadrants[quadrant].subdivision) * shadow_size;
|
||||
y += (shadow / shadow_atlas->quadrants[quadrant].subdivision) * shadow_size;
|
||||
|
||||
uint32_t width = shadow_size;
|
||||
uint32_t height = shadow_size;
|
||||
|
||||
return Rect2(x / float(shadow_atlas->size), y / float(shadow_atlas->size), width / float(shadow_atlas->size), height / float(shadow_atlas->size));
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ CameraMatrix light_instance_get_shadow_camera(RID p_light_instance, int p_index) {
|
||||
|
||||
LightInstance *li = light_instance_owner.getornull(p_light_instance);
|
||||
return li->shadow_transform[p_index].camera;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void light_instance_set_render_pass(RID p_light_instance, uint64_t p_pass) {
|
||||
LightInstance *li = light_instance_owner.getornull(p_light_instance);
|
||||
li->last_pass = p_pass;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ uint64_t light_instance_get_render_pass(RID p_light_instance) {
|
||||
LightInstance *li = light_instance_owner.getornull(p_light_instance);
|
||||
return li->last_pass;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void light_instance_set_index(RID p_light_instance, uint32_t p_index) {
|
||||
LightInstance *li = light_instance_owner.getornull(p_light_instance);
|
||||
li->light_index = p_index;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ uint32_t light_instance_get_index(RID p_light_instance) {
|
||||
LightInstance *li = light_instance_owner.getornull(p_light_instance);
|
||||
return li->light_index;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ VS::LightType light_instance_get_type(RID p_light_instance) {
|
||||
LightInstance *li = light_instance_owner.getornull(p_light_instance);
|
||||
return li->light_type;
|
||||
}
|
||||
|
||||
virtual RID reflection_probe_instance_create(RID p_probe);
|
||||
virtual void reflection_probe_instance_set_transform(RID p_instance, const Transform &p_transform);
|
||||
virtual bool reflection_probe_instance_needs_redraw(RID p_instance);
|
||||
virtual void reflection_probe_instance_begin_render(RID p_instance);
|
||||
virtual bool reflection_probe_instance_postprocess_step(RID p_instance);
|
||||
|
||||
uint32_t reflection_probe_instance_get_resolution(RID p_instance);
|
||||
RID reflection_probe_instance_get_framebuffer(RID p_instance, int p_index);
|
||||
|
||||
_FORCE_INLINE_ RID reflection_probe_instance_get_probe(RID p_instance) {
|
||||
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance);
|
||||
ERR_FAIL_COND_V(!rpi, RID());
|
||||
|
||||
return rpi->probe;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void reflection_probe_instance_set_render_index(RID p_instance, uint32_t p_render_index) {
|
||||
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance);
|
||||
ERR_FAIL_COND(!rpi);
|
||||
rpi->render_index = p_render_index;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ uint32_t reflection_probe_instance_get_render_index(RID p_instance) {
|
||||
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance);
|
||||
ERR_FAIL_COND_V(!rpi, 0);
|
||||
|
||||
return rpi->render_index;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Transform reflection_probe_instance_get_transform(RID p_instance) {
|
||||
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance);
|
||||
ERR_FAIL_COND_V(!rpi, Transform());
|
||||
|
||||
return rpi->transform;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ RID reflection_probe_instance_get_texture(RID p_instance) {
|
||||
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance);
|
||||
ERR_FAIL_COND_V(!rpi, RID());
|
||||
|
||||
return rpi->reflection.radiance;
|
||||
}
|
||||
|
||||
RID gi_probe_instance_create() { return RID(); }
|
||||
void gi_probe_instance_set_light_data(RID p_probe, RID p_base, RID p_data) {}
|
||||
|
@ -191,7 +485,12 @@ public:
|
|||
RID render_buffers_create();
|
||||
void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, VS::ViewportMSAA p_msaa);
|
||||
|
||||
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_environment, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass);
|
||||
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_environment, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass);
|
||||
|
||||
void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count);
|
||||
|
||||
virtual void set_scene_pass(uint64_t p_pass) { scene_pass = p_pass; }
|
||||
_FORCE_INLINE_ uint64_t get_scene_pass() { return scene_pass; }
|
||||
|
||||
int get_roughness_layers() const;
|
||||
bool is_using_radiance_cubemap_array() const;
|
||||
|
@ -201,6 +500,7 @@ public:
|
|||
virtual void update();
|
||||
|
||||
RasterizerSceneRD(RasterizerStorageRD *p_storage);
|
||||
~RasterizerSceneRD();
|
||||
};
|
||||
|
||||
#endif // RASTERIZER_SCENE_RD_H
|
||||
|
|
|
@ -2087,6 +2087,462 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su
|
|||
v.vertex_array = RD::get_singleton()->vertex_array_create(s->vertex_count, v.vertex_format, buffers);
|
||||
}
|
||||
|
||||
/* LIGHT */
|
||||
|
||||
RID RasterizerStorageRD::light_create(VS::LightType p_type) {
|
||||
|
||||
Light light;
|
||||
light.type = p_type;
|
||||
|
||||
light.param[VS::LIGHT_PARAM_ENERGY] = 1.0;
|
||||
light.param[VS::LIGHT_PARAM_INDIRECT_ENERGY] = 1.0;
|
||||
light.param[VS::LIGHT_PARAM_SPECULAR] = 0.5;
|
||||
light.param[VS::LIGHT_PARAM_RANGE] = 1.0;
|
||||
light.param[VS::LIGHT_PARAM_SPOT_ANGLE] = 45;
|
||||
light.param[VS::LIGHT_PARAM_CONTACT_SHADOW_SIZE] = 45;
|
||||
light.param[VS::LIGHT_PARAM_SHADOW_MAX_DISTANCE] = 0;
|
||||
light.param[VS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET] = 0.1;
|
||||
light.param[VS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET] = 0.3;
|
||||
light.param[VS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET] = 0.6;
|
||||
light.param[VS::LIGHT_PARAM_SHADOW_NORMAL_BIAS] = 0.1;
|
||||
light.param[VS::LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE] = 0.1;
|
||||
|
||||
return light_owner.make_rid(light);
|
||||
}
|
||||
|
||||
void RasterizerStorageRD::light_set_color(RID p_light, const Color &p_color) {
|
||||
|
||||
Light *light = light_owner.getornull(p_light);
|
||||
ERR_FAIL_COND(!light);
|
||||
|
||||
light->color = p_color;
|
||||
}
|
||||
void RasterizerStorageRD::light_set_param(RID p_light, VS::LightParam p_param, float p_value) {
|
||||
|
||||
Light *light = light_owner.getornull(p_light);
|
||||
ERR_FAIL_COND(!light);
|
||||
ERR_FAIL_INDEX(p_param, VS::LIGHT_PARAM_MAX);
|
||||
|
||||
switch (p_param) {
|
||||
case VS::LIGHT_PARAM_RANGE:
|
||||
case VS::LIGHT_PARAM_SPOT_ANGLE:
|
||||
case VS::LIGHT_PARAM_SHADOW_MAX_DISTANCE:
|
||||
case VS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET:
|
||||
case VS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET:
|
||||
case VS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET:
|
||||
case VS::LIGHT_PARAM_SHADOW_NORMAL_BIAS:
|
||||
case VS::LIGHT_PARAM_SHADOW_BIAS: {
|
||||
|
||||
light->version++;
|
||||
light->instance_dependency.instance_notify_changed(true, false);
|
||||
} break;
|
||||
default: {
|
||||
}
|
||||
}
|
||||
|
||||
light->param[p_param] = p_value;
|
||||
}
|
||||
void RasterizerStorageRD::light_set_shadow(RID p_light, bool p_enabled) {
|
||||
|
||||
Light *light = light_owner.getornull(p_light);
|
||||
ERR_FAIL_COND(!light);
|
||||
light->shadow = p_enabled;
|
||||
|
||||
light->version++;
|
||||
light->instance_dependency.instance_notify_changed(true, false);
|
||||
}
|
||||
|
||||
void RasterizerStorageRD::light_set_shadow_color(RID p_light, const Color &p_color) {
|
||||
|
||||
Light *light = light_owner.getornull(p_light);
|
||||
ERR_FAIL_COND(!light);
|
||||
light->shadow_color = p_color;
|
||||
}
|
||||
|
||||
void RasterizerStorageRD::light_set_projector(RID p_light, RID p_texture) {
|
||||
|
||||
Light *light = light_owner.getornull(p_light);
|
||||
ERR_FAIL_COND(!light);
|
||||
|
||||
light->projector = p_texture;
|
||||
}
|
||||
|
||||
void RasterizerStorageRD::light_set_negative(RID p_light, bool p_enable) {
|
||||
|
||||
Light *light = light_owner.getornull(p_light);
|
||||
ERR_FAIL_COND(!light);
|
||||
|
||||
light->negative = p_enable;
|
||||
}
|
||||
void RasterizerStorageRD::light_set_cull_mask(RID p_light, uint32_t p_mask) {
|
||||
|
||||
Light *light = light_owner.getornull(p_light);
|
||||
ERR_FAIL_COND(!light);
|
||||
|
||||
light->cull_mask = p_mask;
|
||||
|
||||
light->version++;
|
||||
light->instance_dependency.instance_notify_changed(true, false);
|
||||
}
|
||||
|
||||
void RasterizerStorageRD::light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) {
|
||||
|
||||
Light *light = light_owner.getornull(p_light);
|
||||
ERR_FAIL_COND(!light);
|
||||
|
||||
light->reverse_cull = p_enabled;
|
||||
|
||||
light->version++;
|
||||
light->instance_dependency.instance_notify_changed(true, false);
|
||||
}
|
||||
|
||||
void RasterizerStorageRD::light_set_use_gi(RID p_light, bool p_enabled) {
|
||||
Light *light = light_owner.getornull(p_light);
|
||||
ERR_FAIL_COND(!light);
|
||||
|
||||
light->use_gi = p_enabled;
|
||||
|
||||
light->version++;
|
||||
light->instance_dependency.instance_notify_changed(true, false);
|
||||
}
|
||||
void RasterizerStorageRD::light_omni_set_shadow_mode(RID p_light, VS::LightOmniShadowMode p_mode) {
|
||||
|
||||
Light *light = light_owner.getornull(p_light);
|
||||
ERR_FAIL_COND(!light);
|
||||
|
||||
light->omni_shadow_mode = p_mode;
|
||||
|
||||
light->version++;
|
||||
light->instance_dependency.instance_notify_changed(true, false);
|
||||
}
|
||||
|
||||
VS::LightOmniShadowMode RasterizerStorageRD::light_omni_get_shadow_mode(RID p_light) {
|
||||
|
||||
const Light *light = light_owner.getornull(p_light);
|
||||
ERR_FAIL_COND_V(!light, VS::LIGHT_OMNI_SHADOW_CUBE);
|
||||
|
||||
return light->omni_shadow_mode;
|
||||
}
|
||||
|
||||
void RasterizerStorageRD::light_directional_set_shadow_mode(RID p_light, VS::LightDirectionalShadowMode p_mode) {
|
||||
|
||||
Light *light = light_owner.getornull(p_light);
|
||||
ERR_FAIL_COND(!light);
|
||||
|
||||
light->directional_shadow_mode = p_mode;
|
||||
light->version++;
|
||||
light->instance_dependency.instance_notify_changed(true, false);
|
||||
}
|
||||
|
||||
void RasterizerStorageRD::light_directional_set_blend_splits(RID p_light, bool p_enable) {
|
||||
|
||||
Light *light = light_owner.getornull(p_light);
|
||||
ERR_FAIL_COND(!light);
|
||||
|
||||
light->directional_blend_splits = p_enable;
|
||||
light->version++;
|
||||
light->instance_dependency.instance_notify_changed(true, false);
|
||||
}
|
||||
|
||||
bool RasterizerStorageRD::light_directional_get_blend_splits(RID p_light) const {
|
||||
|
||||
const Light *light = light_owner.getornull(p_light);
|
||||
ERR_FAIL_COND_V(!light, false);
|
||||
|
||||
return light->directional_blend_splits;
|
||||
}
|
||||
|
||||
VS::LightDirectionalShadowMode RasterizerStorageRD::light_directional_get_shadow_mode(RID p_light) {
|
||||
|
||||
const Light *light = light_owner.getornull(p_light);
|
||||
ERR_FAIL_COND_V(!light, VS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL);
|
||||
|
||||
return light->directional_shadow_mode;
|
||||
}
|
||||
|
||||
void RasterizerStorageRD::light_directional_set_shadow_depth_range_mode(RID p_light, VS::LightDirectionalShadowDepthRangeMode p_range_mode) {
|
||||
|
||||
Light *light = light_owner.getornull(p_light);
|
||||
ERR_FAIL_COND(!light);
|
||||
|
||||
light->directional_range_mode = p_range_mode;
|
||||
}
|
||||
|
||||
VS::LightDirectionalShadowDepthRangeMode RasterizerStorageRD::light_directional_get_shadow_depth_range_mode(RID p_light) const {
|
||||
|
||||
const Light *light = light_owner.getornull(p_light);
|
||||
ERR_FAIL_COND_V(!light, VS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE);
|
||||
|
||||
return light->directional_range_mode;
|
||||
}
|
||||
|
||||
bool RasterizerStorageRD::light_get_use_gi(RID p_light) {
|
||||
Light *light = light_owner.getornull(p_light);
|
||||
ERR_FAIL_COND_V(!light, false);
|
||||
|
||||
return light->use_gi;
|
||||
}
|
||||
|
||||
uint64_t RasterizerStorageRD::light_get_version(RID p_light) const {
|
||||
|
||||
const Light *light = light_owner.getornull(p_light);
|
||||
ERR_FAIL_COND_V(!light, 0);
|
||||
|
||||
return light->version;
|
||||
}
|
||||
|
||||
AABB RasterizerStorageRD::light_get_aabb(RID p_light) const {
|
||||
|
||||
const Light *light = light_owner.getornull(p_light);
|
||||
ERR_FAIL_COND_V(!light, AABB());
|
||||
|
||||
switch (light->type) {
|
||||
|
||||
case VS::LIGHT_SPOT: {
|
||||
|
||||
float len = light->param[VS::LIGHT_PARAM_RANGE];
|
||||
float size = Math::tan(Math::deg2rad(light->param[VS::LIGHT_PARAM_SPOT_ANGLE])) * len;
|
||||
return AABB(Vector3(-size, -size, -len), Vector3(size * 2, size * 2, len));
|
||||
};
|
||||
case VS::LIGHT_OMNI: {
|
||||
|
||||
float r = light->param[VS::LIGHT_PARAM_RANGE];
|
||||
return AABB(-Vector3(r, r, r), Vector3(r, r, r) * 2);
|
||||
};
|
||||
case VS::LIGHT_DIRECTIONAL: {
|
||||
|
||||
return AABB();
|
||||
};
|
||||
}
|
||||
|
||||
ERR_FAIL_V(AABB());
|
||||
}
|
||||
|
||||
/* REFLECTION PROBE */
|
||||
|
||||
RID RasterizerStorageRD::reflection_probe_create() {
|
||||
|
||||
return reflection_probe_owner.make_rid(ReflectionProbe());
|
||||
}
|
||||
|
||||
void RasterizerStorageRD::reflection_probe_set_update_mode(RID p_probe, VS::ReflectionProbeUpdateMode p_mode) {
|
||||
|
||||
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
|
||||
ERR_FAIL_COND(!reflection_probe);
|
||||
|
||||
reflection_probe->update_mode = p_mode;
|
||||
reflection_probe->instance_dependency.instance_notify_changed(true, false);
|
||||
}
|
||||
|
||||
void RasterizerStorageRD::reflection_probe_set_intensity(RID p_probe, float p_intensity) {
|
||||
|
||||
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
|
||||
ERR_FAIL_COND(!reflection_probe);
|
||||
|
||||
reflection_probe->intensity = p_intensity;
|
||||
}
|
||||
|
||||
void RasterizerStorageRD::reflection_probe_set_interior_ambient(RID p_probe, const Color &p_ambient) {
|
||||
|
||||
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
|
||||
ERR_FAIL_COND(!reflection_probe);
|
||||
|
||||
reflection_probe->interior_ambient = p_ambient;
|
||||
}
|
||||
|
||||
void RasterizerStorageRD::reflection_probe_set_interior_ambient_energy(RID p_probe, float p_energy) {
|
||||
|
||||
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
|
||||
ERR_FAIL_COND(!reflection_probe);
|
||||
|
||||
reflection_probe->interior_ambient_energy = p_energy;
|
||||
}
|
||||
|
||||
void RasterizerStorageRD::reflection_probe_set_interior_ambient_probe_contribution(RID p_probe, float p_contrib) {
|
||||
|
||||
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
|
||||
ERR_FAIL_COND(!reflection_probe);
|
||||
|
||||
reflection_probe->interior_ambient_probe_contrib = p_contrib;
|
||||
}
|
||||
|
||||
void RasterizerStorageRD::reflection_probe_set_max_distance(RID p_probe, float p_distance) {
|
||||
|
||||
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
|
||||
ERR_FAIL_COND(!reflection_probe);
|
||||
|
||||
reflection_probe->max_distance = p_distance;
|
||||
|
||||
reflection_probe->instance_dependency.instance_notify_changed(true, false);
|
||||
}
|
||||
void RasterizerStorageRD::reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) {
|
||||
|
||||
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
|
||||
ERR_FAIL_COND(!reflection_probe);
|
||||
|
||||
reflection_probe->extents = p_extents;
|
||||
reflection_probe->instance_dependency.instance_notify_changed(true, false);
|
||||
}
|
||||
void RasterizerStorageRD::reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) {
|
||||
|
||||
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
|
||||
ERR_FAIL_COND(!reflection_probe);
|
||||
|
||||
reflection_probe->origin_offset = p_offset;
|
||||
reflection_probe->instance_dependency.instance_notify_changed(true, false);
|
||||
}
|
||||
|
||||
void RasterizerStorageRD::reflection_probe_set_as_interior(RID p_probe, bool p_enable) {
|
||||
|
||||
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
|
||||
ERR_FAIL_COND(!reflection_probe);
|
||||
|
||||
reflection_probe->interior = p_enable;
|
||||
reflection_probe->instance_dependency.instance_notify_changed(true, false);
|
||||
}
|
||||
void RasterizerStorageRD::reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) {
|
||||
|
||||
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
|
||||
ERR_FAIL_COND(!reflection_probe);
|
||||
|
||||
reflection_probe->box_projection = p_enable;
|
||||
}
|
||||
|
||||
void RasterizerStorageRD::reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) {
|
||||
|
||||
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
|
||||
ERR_FAIL_COND(!reflection_probe);
|
||||
|
||||
reflection_probe->enable_shadows = p_enable;
|
||||
reflection_probe->instance_dependency.instance_notify_changed(true, false);
|
||||
}
|
||||
void RasterizerStorageRD::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) {
|
||||
|
||||
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
|
||||
ERR_FAIL_COND(!reflection_probe);
|
||||
|
||||
reflection_probe->cull_mask = p_layers;
|
||||
reflection_probe->instance_dependency.instance_notify_changed(true, false);
|
||||
}
|
||||
|
||||
void RasterizerStorageRD::reflection_probe_set_resolution(RID p_probe, int p_resolution) {
|
||||
|
||||
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
|
||||
ERR_FAIL_COND(!reflection_probe);
|
||||
ERR_FAIL_COND(p_resolution < 32);
|
||||
|
||||
reflection_probe->resolution = p_resolution;
|
||||
}
|
||||
|
||||
AABB RasterizerStorageRD::reflection_probe_get_aabb(RID p_probe) const {
|
||||
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
|
||||
ERR_FAIL_COND_V(!reflection_probe, AABB());
|
||||
|
||||
AABB aabb;
|
||||
aabb.position = -reflection_probe->extents;
|
||||
aabb.size = reflection_probe->extents * 2.0;
|
||||
|
||||
return aabb;
|
||||
}
|
||||
VS::ReflectionProbeUpdateMode RasterizerStorageRD::reflection_probe_get_update_mode(RID p_probe) const {
|
||||
|
||||
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
|
||||
ERR_FAIL_COND_V(!reflection_probe, VS::REFLECTION_PROBE_UPDATE_ALWAYS);
|
||||
|
||||
return reflection_probe->update_mode;
|
||||
}
|
||||
|
||||
uint32_t RasterizerStorageRD::reflection_probe_get_cull_mask(RID p_probe) const {
|
||||
|
||||
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
|
||||
ERR_FAIL_COND_V(!reflection_probe, 0);
|
||||
|
||||
return reflection_probe->cull_mask;
|
||||
}
|
||||
|
||||
Vector3 RasterizerStorageRD::reflection_probe_get_extents(RID p_probe) const {
|
||||
|
||||
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
|
||||
ERR_FAIL_COND_V(!reflection_probe, Vector3());
|
||||
|
||||
return reflection_probe->extents;
|
||||
}
|
||||
Vector3 RasterizerStorageRD::reflection_probe_get_origin_offset(RID p_probe) const {
|
||||
|
||||
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
|
||||
ERR_FAIL_COND_V(!reflection_probe, Vector3());
|
||||
|
||||
return reflection_probe->origin_offset;
|
||||
}
|
||||
|
||||
bool RasterizerStorageRD::reflection_probe_renders_shadows(RID p_probe) const {
|
||||
|
||||
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
|
||||
ERR_FAIL_COND_V(!reflection_probe, false);
|
||||
|
||||
return reflection_probe->enable_shadows;
|
||||
}
|
||||
|
||||
float RasterizerStorageRD::reflection_probe_get_origin_max_distance(RID p_probe) const {
|
||||
|
||||
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
|
||||
ERR_FAIL_COND_V(!reflection_probe, 0);
|
||||
|
||||
return reflection_probe->max_distance;
|
||||
}
|
||||
|
||||
int RasterizerStorageRD::reflection_probe_get_resolution(RID p_probe) const {
|
||||
|
||||
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
|
||||
ERR_FAIL_COND_V(!reflection_probe, 0);
|
||||
|
||||
return reflection_probe->resolution;
|
||||
}
|
||||
|
||||
float RasterizerStorageRD::reflection_probe_get_intensity(RID p_probe) const {
|
||||
|
||||
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
|
||||
ERR_FAIL_COND_V(!reflection_probe, 0);
|
||||
|
||||
return reflection_probe->intensity;
|
||||
}
|
||||
bool RasterizerStorageRD::reflection_probe_is_interior(RID p_probe) const {
|
||||
|
||||
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
|
||||
ERR_FAIL_COND_V(!reflection_probe, false);
|
||||
|
||||
return reflection_probe->interior;
|
||||
}
|
||||
bool RasterizerStorageRD::reflection_probe_is_box_projection(RID p_probe) const {
|
||||
|
||||
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
|
||||
ERR_FAIL_COND_V(!reflection_probe, false);
|
||||
|
||||
return reflection_probe->box_projection;
|
||||
}
|
||||
|
||||
Color RasterizerStorageRD::reflection_probe_get_interior_ambient(RID p_probe) const {
|
||||
|
||||
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
|
||||
ERR_FAIL_COND_V(!reflection_probe, Color());
|
||||
|
||||
return reflection_probe->interior_ambient;
|
||||
}
|
||||
float RasterizerStorageRD::reflection_probe_get_interior_ambient_energy(RID p_probe) const {
|
||||
|
||||
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
|
||||
ERR_FAIL_COND_V(!reflection_probe, 0);
|
||||
|
||||
return reflection_probe->interior_ambient_energy;
|
||||
}
|
||||
float RasterizerStorageRD::reflection_probe_get_interior_ambient_probe_contribution(RID p_probe) const {
|
||||
|
||||
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
|
||||
ERR_FAIL_COND_V(!reflection_probe, 0);
|
||||
|
||||
return reflection_probe->interior_ambient_probe_contrib;
|
||||
}
|
||||
|
||||
/* RENDER TARGET API */
|
||||
|
||||
void RasterizerStorageRD::_clear_render_target(RenderTarget *rt) {
|
||||
|
@ -2432,6 +2888,12 @@ void RasterizerStorageRD::base_update_dependency(RID p_base, RasterizerScene::In
|
|||
if (mesh_owner.owns(p_base)) {
|
||||
Mesh *mesh = mesh_owner.getornull(p_base);
|
||||
p_instance->update_dependency(&mesh->instance_dependency);
|
||||
} else if (reflection_probe_owner.owns(p_base)) {
|
||||
ReflectionProbe *rp = reflection_probe_owner.getornull(p_base);
|
||||
p_instance->update_dependency(&rp->instance_dependency);
|
||||
} else if (light_owner.owns(p_base)) {
|
||||
Light *l = light_owner.getornull(p_base);
|
||||
p_instance->update_dependency(&l->instance_dependency);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2440,6 +2902,13 @@ VS::InstanceType RasterizerStorageRD::get_base_type(RID p_rid) const {
|
|||
if (mesh_owner.owns(p_rid)) {
|
||||
return VS::INSTANCE_MESH;
|
||||
}
|
||||
if (reflection_probe_owner.owns(p_rid)) {
|
||||
return VS::INSTANCE_REFLECTION_PROBE;
|
||||
}
|
||||
if (light_owner.owns(p_rid)) {
|
||||
return VS::INSTANCE_LIGHT;
|
||||
}
|
||||
|
||||
return VS::INSTANCE_NONE;
|
||||
}
|
||||
void RasterizerStorageRD::update_dirty_resources() {
|
||||
|
@ -2461,6 +2930,13 @@ bool RasterizerStorageRD::free(RID p_rid) {
|
|||
RD::get_singleton()->free(t->rd_texture);
|
||||
}
|
||||
|
||||
if (t->is_proxy && t->proxy_to.is_valid()) {
|
||||
Texture *proxy_to = texture_owner.getornull(t->proxy_to);
|
||||
if (proxy_to) {
|
||||
proxy_to->proxies.erase(p_rid);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < t->proxies.size(); i++) {
|
||||
Texture *p = texture_owner.getornull(t->proxies[i]);
|
||||
ERR_CONTINUE(!p);
|
||||
|
@ -2495,6 +2971,18 @@ bool RasterizerStorageRD::free(RID p_rid) {
|
|||
Mesh *mesh = mesh_owner.getornull(p_rid);
|
||||
mesh->instance_dependency.instance_notify_deleted(p_rid);
|
||||
mesh_owner.free(p_rid);
|
||||
} else if (reflection_probe_owner.owns(p_rid)) {
|
||||
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_rid);
|
||||
reflection_probe->instance_dependency.instance_notify_deleted(p_rid);
|
||||
reflection_probe_owner.free(p_rid);
|
||||
|
||||
} else if (light_owner.owns(p_rid)) {
|
||||
|
||||
// delete the texture
|
||||
Light *light = light_owner.getornull(p_rid);
|
||||
light->instance_dependency.instance_notify_deleted(p_rid);
|
||||
light_owner.free(p_rid);
|
||||
|
||||
} else if (render_target_owner.owns(p_rid)) {
|
||||
RenderTarget *rt = render_target_owner.getornull(p_rid);
|
||||
|
||||
|
@ -2606,7 +3094,7 @@ RasterizerStorageRD::RasterizerStorageRD() {
|
|||
tformat.height = 4;
|
||||
tformat.array_layers = 6;
|
||||
tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
|
||||
tformat.type = RD::TEXTURE_TYPE_CUBE;
|
||||
tformat.type = RD::TEXTURE_TYPE_CUBE_ARRAY;
|
||||
|
||||
PoolVector<uint8_t> pv;
|
||||
pv.resize(16 * 4);
|
||||
|
@ -2634,7 +3122,7 @@ RasterizerStorageRD::RasterizerStorageRD() {
|
|||
tformat.height = 4;
|
||||
tformat.array_layers = 6;
|
||||
tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
|
||||
tformat.type = RD::TEXTURE_TYPE_CUBE_ARRAY;
|
||||
tformat.type = RD::TEXTURE_TYPE_CUBE;
|
||||
|
||||
PoolVector<uint8_t> pv;
|
||||
pv.resize(16 * 4);
|
||||
|
@ -2680,34 +3168,6 @@ RasterizerStorageRD::RasterizerStorageRD() {
|
|||
}
|
||||
}
|
||||
|
||||
{ //create default cubemap array
|
||||
|
||||
RD::TextureFormat tformat;
|
||||
tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
|
||||
tformat.width = 4;
|
||||
tformat.height = 4;
|
||||
tformat.array_layers = 6;
|
||||
tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
|
||||
tformat.type = RD::TEXTURE_TYPE_CUBE_ARRAY;
|
||||
|
||||
PoolVector<uint8_t> pv;
|
||||
pv.resize(16 * 4);
|
||||
for (int i = 0; i < 16; i++) {
|
||||
pv.set(i * 4 + 0, 0);
|
||||
pv.set(i * 4 + 1, 0);
|
||||
pv.set(i * 4 + 2, 0);
|
||||
pv.set(i * 4 + 3, 0);
|
||||
}
|
||||
|
||||
{
|
||||
Vector<PoolVector<uint8_t> > vpv;
|
||||
for (int i = 0; i < 6; i++) {
|
||||
vpv.push_back(pv);
|
||||
}
|
||||
default_rd_textures[DEFAULT_RD_TEXTURE_CUBEMAP_BLACK] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv);
|
||||
}
|
||||
}
|
||||
|
||||
//default samplers
|
||||
for (int i = 1; i < VS::CANVAS_ITEM_TEXTURE_FILTER_MAX; i++) {
|
||||
for (int j = 1; j < VS::CANVAS_ITEM_TEXTURE_REPEAT_MAX; j++) {
|
||||
|
|
|
@ -251,6 +251,12 @@ private:
|
|||
RID blend_shape_base_buffer; //source buffer goes here when using blend shapes, and main one is uncompressed
|
||||
|
||||
RID material;
|
||||
|
||||
uint32_t render_index = 0;
|
||||
uint64_t render_pass = 0;
|
||||
|
||||
uint32_t multimesh_render_index = 0;
|
||||
uint64_t multimesh_render_pass = 0;
|
||||
};
|
||||
|
||||
uint32_t blend_shape_count = 0;
|
||||
|
@ -275,6 +281,54 @@ private:
|
|||
|
||||
RID mesh_default_rd_buffers[DEFAULT_RD_BUFFER_MAX];
|
||||
|
||||
/* LIGHT */
|
||||
|
||||
struct Light {
|
||||
|
||||
VS::LightType type;
|
||||
float param[VS::LIGHT_PARAM_MAX];
|
||||
Color color = Color(1, 1, 1, 1);
|
||||
Color shadow_color;
|
||||
RID projector;
|
||||
bool shadow = false;
|
||||
bool negative = false;
|
||||
bool reverse_cull = false;
|
||||
bool use_gi = true;
|
||||
uint32_t cull_mask = 0xFFFFFFFF;
|
||||
VS::LightOmniShadowMode omni_shadow_mode = VS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID;
|
||||
VS::LightDirectionalShadowMode directional_shadow_mode = VS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL;
|
||||
VS::LightDirectionalShadowDepthRangeMode directional_range_mode = VS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE;
|
||||
bool directional_blend_splits = false;
|
||||
uint64_t version = 0;
|
||||
|
||||
RasterizerScene::InstanceDependency instance_dependency;
|
||||
};
|
||||
|
||||
mutable RID_Owner<Light> light_owner;
|
||||
|
||||
/* REFLECTION PROBE */
|
||||
|
||||
struct ReflectionProbe {
|
||||
|
||||
VS::ReflectionProbeUpdateMode update_mode = VS::REFLECTION_PROBE_UPDATE_ONCE;
|
||||
int resolution = 256;
|
||||
float intensity = 1.0;
|
||||
Color interior_ambient;
|
||||
float interior_ambient_energy = 1.0;
|
||||
float interior_ambient_probe_contrib = 0.0;
|
||||
float max_distance = 0;
|
||||
Vector3 extents = Vector3(1, 1, 1);
|
||||
Vector3 origin_offset;
|
||||
bool interior = false;
|
||||
bool box_projection = false;
|
||||
bool enable_shadows = false;
|
||||
uint32_t cull_mask = (1 << 20) - 1;
|
||||
|
||||
RasterizerScene::InstanceDependency instance_dependency;
|
||||
};
|
||||
|
||||
mutable RID_Owner<ReflectionProbe> reflection_probe_owner;
|
||||
|
||||
/* RENDER TARGET */
|
||||
|
||||
struct RenderTarget {
|
||||
|
@ -530,6 +584,32 @@ public:
|
|||
return mesh_default_rd_buffers[p_buffer];
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ uint32_t mesh_surface_get_render_pass_index(RID p_mesh, uint32_t p_surface_index, uint64_t p_render_pass, uint32_t *r_index) {
|
||||
Mesh *mesh = mesh_owner.getornull(p_mesh);
|
||||
Mesh::Surface *s = mesh->surfaces[p_surface_index];
|
||||
|
||||
if (s->render_pass != p_render_pass) {
|
||||
(*r_index)++;
|
||||
s->render_pass = p_render_pass;
|
||||
s->render_index = *r_index;
|
||||
}
|
||||
|
||||
return s->render_index;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ uint32_t mesh_surface_get_multimesh_render_pass_index(RID p_mesh, uint32_t p_surface_index, uint64_t p_render_pass, uint32_t *r_index) {
|
||||
Mesh *mesh = mesh_owner.getornull(p_mesh);
|
||||
Mesh::Surface *s = mesh->surfaces[p_surface_index];
|
||||
|
||||
if (s->multimesh_render_pass != p_render_pass) {
|
||||
(*r_index)++;
|
||||
s->multimesh_render_pass = p_render_pass;
|
||||
s->multimesh_render_index = *r_index;
|
||||
}
|
||||
|
||||
return s->multimesh_render_index;
|
||||
}
|
||||
|
||||
/* MULTIMESH API */
|
||||
|
||||
virtual RID multimesh_create() { return RID(); }
|
||||
|
@ -587,68 +667,125 @@ public:
|
|||
|
||||
/* Light API */
|
||||
|
||||
RID light_create(VS::LightType p_type) { return RID(); }
|
||||
RID light_create(VS::LightType p_type);
|
||||
|
||||
RID directional_light_create() { return light_create(VS::LIGHT_DIRECTIONAL); }
|
||||
RID omni_light_create() { return light_create(VS::LIGHT_OMNI); }
|
||||
RID spot_light_create() { return light_create(VS::LIGHT_SPOT); }
|
||||
|
||||
void light_set_color(RID p_light, const Color &p_color) {}
|
||||
void light_set_param(RID p_light, VS::LightParam p_param, float p_value) {}
|
||||
void light_set_shadow(RID p_light, bool p_enabled) {}
|
||||
void light_set_shadow_color(RID p_light, const Color &p_color) {}
|
||||
void light_set_projector(RID p_light, RID p_texture) {}
|
||||
void light_set_negative(RID p_light, bool p_enable) {}
|
||||
void light_set_cull_mask(RID p_light, uint32_t p_mask) {}
|
||||
void light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) {}
|
||||
void light_set_use_gi(RID p_light, bool p_enabled) {}
|
||||
void light_set_color(RID p_light, const Color &p_color);
|
||||
void light_set_param(RID p_light, VS::LightParam p_param, float p_value);
|
||||
void light_set_shadow(RID p_light, bool p_enabled);
|
||||
void light_set_shadow_color(RID p_light, const Color &p_color);
|
||||
void light_set_projector(RID p_light, RID p_texture);
|
||||
void light_set_negative(RID p_light, bool p_enable);
|
||||
void light_set_cull_mask(RID p_light, uint32_t p_mask);
|
||||
void light_set_reverse_cull_face_mode(RID p_light, bool p_enabled);
|
||||
void light_set_use_gi(RID p_light, bool p_enabled);
|
||||
|
||||
void light_omni_set_shadow_mode(RID p_light, VS::LightOmniShadowMode p_mode) {}
|
||||
void light_omni_set_shadow_detail(RID p_light, VS::LightOmniShadowDetail p_detail) {}
|
||||
void light_omni_set_shadow_mode(RID p_light, VS::LightOmniShadowMode p_mode);
|
||||
|
||||
void light_directional_set_shadow_mode(RID p_light, VS::LightDirectionalShadowMode p_mode) {}
|
||||
void light_directional_set_blend_splits(RID p_light, bool p_enable) {}
|
||||
bool light_directional_get_blend_splits(RID p_light) const { return false; }
|
||||
void light_directional_set_shadow_depth_range_mode(RID p_light, VS::LightDirectionalShadowDepthRangeMode p_range_mode) {}
|
||||
VS::LightDirectionalShadowDepthRangeMode light_directional_get_shadow_depth_range_mode(RID p_light) const { return VS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE; }
|
||||
void light_directional_set_shadow_mode(RID p_light, VS::LightDirectionalShadowMode p_mode);
|
||||
void light_directional_set_blend_splits(RID p_light, bool p_enable);
|
||||
bool light_directional_get_blend_splits(RID p_light) const;
|
||||
void light_directional_set_shadow_depth_range_mode(RID p_light, VS::LightDirectionalShadowDepthRangeMode p_range_mode);
|
||||
VS::LightDirectionalShadowDepthRangeMode light_directional_get_shadow_depth_range_mode(RID p_light) const;
|
||||
|
||||
VS::LightDirectionalShadowMode light_directional_get_shadow_mode(RID p_light) { return VS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL; }
|
||||
VS::LightOmniShadowMode light_omni_get_shadow_mode(RID p_light) { return VS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID; }
|
||||
VS::LightDirectionalShadowMode light_directional_get_shadow_mode(RID p_light);
|
||||
VS::LightOmniShadowMode light_omni_get_shadow_mode(RID p_light);
|
||||
|
||||
bool light_has_shadow(RID p_light) const { return false; }
|
||||
_FORCE_INLINE_ VS::LightType light_get_type(RID p_light) const {
|
||||
const Light *light = light_owner.getornull(p_light);
|
||||
ERR_FAIL_COND_V(!light, VS::LIGHT_DIRECTIONAL);
|
||||
|
||||
VS::LightType light_get_type(RID p_light) const { return VS::LIGHT_OMNI; }
|
||||
AABB light_get_aabb(RID p_light) const { return AABB(); }
|
||||
float light_get_param(RID p_light, VS::LightParam p_param) { return 0.0; }
|
||||
Color light_get_color(RID p_light) { return Color(); }
|
||||
bool light_get_use_gi(RID p_light) { return false; }
|
||||
uint64_t light_get_version(RID p_light) const { return 0; }
|
||||
return light->type;
|
||||
}
|
||||
AABB light_get_aabb(RID p_light) const;
|
||||
|
||||
_FORCE_INLINE_ float light_get_param(RID p_light, VS::LightParam p_param) {
|
||||
|
||||
const Light *light = light_owner.getornull(p_light);
|
||||
ERR_FAIL_COND_V(!light, 0);
|
||||
|
||||
return light->param[p_param];
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Color light_get_color(RID p_light) {
|
||||
|
||||
const Light *light = light_owner.getornull(p_light);
|
||||
ERR_FAIL_COND_V(!light, Color());
|
||||
|
||||
return light->color;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Color light_get_shadow_color(RID p_light) {
|
||||
|
||||
const Light *light = light_owner.getornull(p_light);
|
||||
ERR_FAIL_COND_V(!light, Color());
|
||||
|
||||
return light->shadow_color;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ uint32_t light_get_cull_mask(RID p_light) {
|
||||
|
||||
const Light *light = light_owner.getornull(p_light);
|
||||
ERR_FAIL_COND_V(!light, 0);
|
||||
|
||||
return light->cull_mask;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ bool light_has_shadow(RID p_light) const {
|
||||
|
||||
const Light *light = light_owner.getornull(p_light);
|
||||
ERR_FAIL_COND_V(!light, VS::LIGHT_DIRECTIONAL);
|
||||
|
||||
return light->shadow;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ bool light_is_negative(RID p_light) const {
|
||||
|
||||
const Light *light = light_owner.getornull(p_light);
|
||||
ERR_FAIL_COND_V(!light, VS::LIGHT_DIRECTIONAL);
|
||||
|
||||
return light->negative;
|
||||
}
|
||||
|
||||
bool light_get_use_gi(RID p_light);
|
||||
uint64_t light_get_version(RID p_light) const;
|
||||
|
||||
/* PROBE API */
|
||||
|
||||
RID reflection_probe_create() { return RID(); }
|
||||
RID reflection_probe_create();
|
||||
|
||||
void reflection_probe_set_update_mode(RID p_probe, VS::ReflectionProbeUpdateMode p_mode) {}
|
||||
void reflection_probe_set_intensity(RID p_probe, float p_intensity) {}
|
||||
void reflection_probe_set_interior_ambient(RID p_probe, const Color &p_ambient) {}
|
||||
void reflection_probe_set_interior_ambient_energy(RID p_probe, float p_energy) {}
|
||||
void reflection_probe_set_interior_ambient_probe_contribution(RID p_probe, float p_contrib) {}
|
||||
void reflection_probe_set_max_distance(RID p_probe, float p_distance) {}
|
||||
void reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) {}
|
||||
void reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) {}
|
||||
void reflection_probe_set_as_interior(RID p_probe, bool p_enable) {}
|
||||
void reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) {}
|
||||
void reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) {}
|
||||
void reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) {}
|
||||
void reflection_probe_set_resolution(RID p_probe, int p_resolution) {}
|
||||
void reflection_probe_set_update_mode(RID p_probe, VS::ReflectionProbeUpdateMode p_mode);
|
||||
void reflection_probe_set_intensity(RID p_probe, float p_intensity);
|
||||
void reflection_probe_set_interior_ambient(RID p_probe, const Color &p_ambient);
|
||||
void reflection_probe_set_interior_ambient_energy(RID p_probe, float p_energy);
|
||||
void reflection_probe_set_interior_ambient_probe_contribution(RID p_probe, float p_contrib);
|
||||
void reflection_probe_set_max_distance(RID p_probe, float p_distance);
|
||||
void reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents);
|
||||
void reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset);
|
||||
void reflection_probe_set_as_interior(RID p_probe, bool p_enable);
|
||||
void reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable);
|
||||
void reflection_probe_set_enable_shadows(RID p_probe, bool p_enable);
|
||||
void reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers);
|
||||
void reflection_probe_set_resolution(RID p_probe, int p_resolution);
|
||||
|
||||
AABB reflection_probe_get_aabb(RID p_probe) const { return AABB(); }
|
||||
VS::ReflectionProbeUpdateMode reflection_probe_get_update_mode(RID p_probe) const { return VisualServer::REFLECTION_PROBE_UPDATE_ONCE; }
|
||||
uint32_t reflection_probe_get_cull_mask(RID p_probe) const { return 0; }
|
||||
Vector3 reflection_probe_get_extents(RID p_probe) const { return Vector3(); }
|
||||
Vector3 reflection_probe_get_origin_offset(RID p_probe) const { return Vector3(); }
|
||||
float reflection_probe_get_origin_max_distance(RID p_probe) const { return 0.0; }
|
||||
bool reflection_probe_renders_shadows(RID p_probe) const { return false; }
|
||||
AABB reflection_probe_get_aabb(RID p_probe) const;
|
||||
VS::ReflectionProbeUpdateMode reflection_probe_get_update_mode(RID p_probe) const;
|
||||
uint32_t reflection_probe_get_cull_mask(RID p_probe) const;
|
||||
Vector3 reflection_probe_get_extents(RID p_probe) const;
|
||||
Vector3 reflection_probe_get_origin_offset(RID p_probe) const;
|
||||
float reflection_probe_get_origin_max_distance(RID p_probe) const;
|
||||
int reflection_probe_get_resolution(RID p_probe) const;
|
||||
bool reflection_probe_renders_shadows(RID p_probe) const;
|
||||
|
||||
float reflection_probe_get_intensity(RID p_probe) const;
|
||||
bool reflection_probe_is_interior(RID p_probe) const;
|
||||
bool reflection_probe_is_box_projection(RID p_probe) const;
|
||||
Color reflection_probe_get_interior_ambient(RID p_probe) const;
|
||||
float reflection_probe_get_interior_ambient_energy(RID p_probe) const;
|
||||
float reflection_probe_get_interior_ambient_probe_contribution(RID p_probe) const;
|
||||
|
||||
void base_update_dependency(RID p_base, RasterizerScene::InstanceBase *p_instance);
|
||||
void skeleton_update_dependency(RID p_skeleton, RasterizerScene::InstanceBase *p_instance) {}
|
||||
|
|
|
@ -31,10 +31,13 @@
|
|||
#ifndef RENDER_PIPELINE_CACHE_RD_H
|
||||
#define RENDER_PIPELINE_CACHE_RD_H
|
||||
|
||||
#include "core/spin_lock.h"
|
||||
#include "servers/visual/rendering_device.h"
|
||||
|
||||
class RenderPipelineVertexFormatCacheRD {
|
||||
|
||||
SpinLock spin_lock;
|
||||
|
||||
RID shader;
|
||||
uint32_t input_mask;
|
||||
|
||||
|
@ -68,12 +71,19 @@ public:
|
|||
ERR_FAIL_COND_V_MSG(shader.is_null(), RID(),
|
||||
"Attempted to use an unused shader variant (shader is null),");
|
||||
#endif
|
||||
|
||||
spin_lock.lock();
|
||||
RID result;
|
||||
for (uint32_t i = 0; i < version_count; i++) {
|
||||
if (versions[i].vertex_id == p_vertex_format_id && versions[i].framebuffer_id == p_framebuffer_format_id) {
|
||||
return versions[i].pipeline;
|
||||
result = versions[i].pipeline;
|
||||
spin_lock.unlock();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return _generate_version(p_vertex_format_id, p_framebuffer_format_id);
|
||||
result = _generate_version(p_vertex_format_id, p_framebuffer_format_id);
|
||||
spin_lock.unlock();
|
||||
return result;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ uint32_t get_vertex_input_mask() const {
|
||||
|
|
|
@ -10,4 +10,5 @@ if 'RD_GLSL' in env['BUILDERS']:
|
|||
env.RD_GLSL('scene_forward.glsl');
|
||||
env.RD_GLSL('sky.glsl');
|
||||
env.RD_GLSL('tonemap.glsl');
|
||||
env.RD_GLSL('copy.glsl');
|
||||
|
||||
|
|
|
@ -23,6 +23,10 @@ void main() {
|
|||
|
||||
gl_Position = vec4( uv_interp *2.0 - 1.0, 0.0, 1.0);
|
||||
|
||||
if (bool(blur.flags&FLAG_FLIP_Y)) {
|
||||
uv_interp.y = 1.0 - uv_interp.y;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* clang-format off */
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#define FLAG_USE_ORTHOGONAL_PROJECTION (1<<2)
|
||||
#define FLAG_DOF_NEAR_FIRST_TAP (1<<3)
|
||||
#define FLAG_GLOW_FIRST_PASS (1<<4)
|
||||
#define FLAG_FLIP_Y (1<<5)
|
||||
|
||||
layout(push_constant, binding = 1, std430) uniform Blur {
|
||||
vec4 section;
|
||||
|
|
93
servers/visual/rasterizer_rd/shaders/copy.glsl
Normal file
93
servers/visual/rasterizer_rd/shaders/copy.glsl
Normal file
|
@ -0,0 +1,93 @@
|
|||
/* clang-format off */
|
||||
[vertex]
|
||||
/* clang-format on */
|
||||
|
||||
#version 450
|
||||
|
||||
/* clang-format off */
|
||||
VERSION_DEFINES
|
||||
/* clang-format on */
|
||||
|
||||
layout(location =0) out vec2 uv_interp;
|
||||
|
||||
void main() {
|
||||
|
||||
vec2 base_arr[4] = vec2[](vec2(0.0,0.0),vec2(0.0,1.0),vec2(1.0,1.0),vec2(1.0,0.0));
|
||||
uv_interp = base_arr[gl_VertexIndex];
|
||||
|
||||
gl_Position = vec4( uv_interp *2.0 - 1.0, 0.0, 1.0);
|
||||
|
||||
}
|
||||
|
||||
/* clang-format off */
|
||||
[fragment]
|
||||
/* clang-format on */
|
||||
|
||||
#version 450
|
||||
|
||||
/* clang-format off */
|
||||
VERSION_DEFINES
|
||||
/* clang-format on */
|
||||
|
||||
layout(location =0) in vec2 uv_interp;
|
||||
|
||||
#ifdef MODE_CUBE_TO_DP
|
||||
|
||||
layout( set=0, binding=0 ) uniform samplerCube source_cube;
|
||||
|
||||
layout(push_constant, binding = 0, std430) uniform Params {
|
||||
float bias;
|
||||
float z_far;
|
||||
float z_near;
|
||||
bool z_flip;
|
||||
|
||||
} params;
|
||||
|
||||
layout(location=0) out float depth_buffer;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
void main() {
|
||||
|
||||
#ifdef MODE_CUBE_TO_DP
|
||||
|
||||
vec3 normal = vec3(uv_interp * 2.0 - 1.0, 0.0);
|
||||
|
||||
normal.z = 0.5 - 0.5 * ((normal.x * normal.x) + (normal.y * normal.y));
|
||||
normal = normalize(normal);
|
||||
|
||||
|
||||
normal.y = -normal.y; //needs to be flipped to match projection matrix
|
||||
if (!params.z_flip) {
|
||||
normal.z = -normal.z;
|
||||
}
|
||||
|
||||
float depth = texture(source_cube, normal).r;
|
||||
|
||||
// absolute values for direction cosines, bigger value equals closer to basis axis
|
||||
vec3 unorm = abs(normal);
|
||||
|
||||
if ((unorm.x >= unorm.y) && (unorm.x >= unorm.z)) {
|
||||
// x code
|
||||
unorm = normal.x > 0.0 ? vec3(1.0, 0.0, 0.0) : vec3(-1.0, 0.0, 0.0);
|
||||
} else if ((unorm.y > unorm.x) && (unorm.y >= unorm.z)) {
|
||||
// y code
|
||||
unorm = normal.y > 0.0 ? vec3(0.0, 1.0, 0.0) : vec3(0.0, -1.0, 0.0);
|
||||
} else if ((unorm.z > unorm.x) && (unorm.z > unorm.y)) {
|
||||
// z code
|
||||
unorm = normal.z > 0.0 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 0.0, -1.0);
|
||||
} else {
|
||||
// oh-no we messed up code
|
||||
// has to be
|
||||
unorm = vec3(1.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
float depth_fix = 1.0 / dot(normal, unorm);
|
||||
|
||||
depth = 2.0 * depth - 1.0;
|
||||
float linear_depth = 2.0 * params.z_near * params.z_far / (params.z_far + params.z_near - depth * (params.z_far - params.z_near));
|
||||
depth_buffer = (linear_depth * depth_fix + params.bias) / params.z_far;
|
||||
|
||||
#endif
|
||||
}
|
|
@ -75,12 +75,26 @@ VERTEX_SHADER_GLOBALS
|
|||
// See GH-13450 and https://bugs.freedesktop.org/show_bug.cgi?id=100316
|
||||
//invariant gl_Position;
|
||||
|
||||
layout(location =7) flat out uint instance_index;
|
||||
|
||||
#ifdef MODE_DUAL_PARABOLOID
|
||||
|
||||
layout(location =8) out float dp_clip;
|
||||
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
|
||||
instance_index = draw_call.instance_index;
|
||||
|
||||
/*if (draw_call.instance_increment) {
|
||||
instance_index += gl_InstanceIndex;
|
||||
}*/
|
||||
|
||||
vec3 vertex = vertex_attrib;
|
||||
|
||||
mat4 world_matrix = instance_data.transform;
|
||||
mat3 world_normal_matrix= instance_data.normal_transform;
|
||||
mat4 world_matrix = instances.data[instance_index].transform;
|
||||
mat3 world_normal_matrix= mat3(instances.data[instance_index].normal_transform);
|
||||
|
||||
vec3 normal = normal_attrib;
|
||||
|
||||
|
@ -131,8 +145,8 @@ void main() {
|
|||
|
||||
float roughness = 1.0;
|
||||
|
||||
mat4 modelview = scene_data.inv_camera_matrix * instance_data.transform;
|
||||
mat3 modelview_normal = mat3(scene_data.inv_camera_matrix) * instance_data.normal_transform;
|
||||
mat4 modelview = scene_data.inv_camera_matrix * world_matrix;
|
||||
mat3 modelview_normal = mat3(scene_data.inv_camera_matrix) * world_normal_matrix;
|
||||
|
||||
{
|
||||
/* clang-format off */
|
||||
|
@ -179,14 +193,35 @@ VERTEX_SHADER_CODE
|
|||
|
||||
#ifdef MODE_RENDER_DEPTH
|
||||
|
||||
#ifdef MODE_DUAL_PARABOLOID
|
||||
|
||||
vertex_interp.z *= scene_data.dual_paraboloid_side;
|
||||
normal_interp.z *= scene_data.dual_paraboloid_side;
|
||||
|
||||
dp_clip = vertex_interp.z; //this attempts to avoid noise caused by objects sent to the other parabolloid side due to bias
|
||||
|
||||
//for dual paraboloid shadow mapping, this is the fastest but least correct way, as it curves straight edges
|
||||
|
||||
vec3 vtx = vertex_interp + normalize(vertex_interp) * scene_data.z_offset;
|
||||
float distance = length(vtx);
|
||||
vtx = normalize(vtx);
|
||||
vtx.xy /= 1.0 - vtx.z;
|
||||
vtx.z = (distance / scene_data.z_far);
|
||||
vtx.z = vtx.z * 2.0 - 1.0;
|
||||
|
||||
vertex_interp = vtx;
|
||||
#else
|
||||
|
||||
float z_ofs = scene_data.z_offset;
|
||||
z_ofs += (1.0 - abs(normal_interp.z)) * scene_data.z_slope_scale;
|
||||
vertex_interp.z -= z_ofs;
|
||||
|
||||
#endif
|
||||
|
||||
#endif //MODE_RENDER_DEPTH
|
||||
|
||||
#ifdef USE_OVERRIDE_POSITION
|
||||
gl_Position = position;
|
||||
gl_Position = position;;
|
||||
#else
|
||||
gl_Position = projection_matrix * vec4(vertex_interp, 1.0);
|
||||
#endif
|
||||
|
@ -227,10 +262,19 @@ layout(location = 5) in vec3 tangent_interp;
|
|||
layout(location = 6) in vec3 binormal_interp;
|
||||
#endif
|
||||
|
||||
layout(location =7) flat in uint instance_index;
|
||||
|
||||
#ifdef MODE_DUAL_PARABOLOID
|
||||
|
||||
layout(location =8) in float dp_clip;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
//defines to keep compatibility with vertex
|
||||
|
||||
#define world_matrix instance_data.transform;
|
||||
#define world_normal_matrix instance_data.normal_transform;
|
||||
#define world_matrix instances.data[instance_index].transform;
|
||||
#define world_normal_matrix instances.data[instance_index].normal_transform;
|
||||
#define projection_matrix scene_data.projection_matrix;
|
||||
|
||||
#ifdef USE_MATERIAL_UNIFORMS
|
||||
|
@ -253,10 +297,14 @@ layout(location = 0) out vec4 diffuse_buffer; //diffuse (rgb) and roughness
|
|||
layout(location = 1) out vec4 specular_buffer; //specular and SSS (subsurface scatter)
|
||||
#else
|
||||
|
||||
#ifndef MODE_RENDER_DEPTH
|
||||
layout(location = 0) out vec4 frag_color;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// This returns the G_GGX function divided by 2 cos_theta_m, where in practice cos_theta_m is either N.L or N.V.
|
||||
// We're dividing this factor off because the overall term we'll end up looks like
|
||||
// (see, for example, the first unnumbered equation in B. Burley, "Physically Based Shading at Disney", SIGGRAPH 2012):
|
||||
|
@ -329,7 +377,24 @@ vec3 F0(float metallic, float specular, vec3 albedo) {
|
|||
return mix(vec3(dielectric), albedo, vec3(metallic));
|
||||
}
|
||||
|
||||
void light_compute(vec3 N, vec3 L, vec3 V, vec3 B, vec3 T, vec3 light_color, vec3 attenuation, vec3 diffuse_color, vec3 transmission, float specular_blob_intensity, float roughness, float metallic, float specular, float rim, float rim_tint, float clearcoat, float clearcoat_gloss, float anisotropy, inout vec3 diffuse_light, inout vec3 specular_light, inout float alpha) {
|
||||
void light_compute(vec3 N, vec3 L, vec3 V, vec3 light_color, vec3 attenuation, vec3 diffuse_color,float roughness, float metallic, float specular,float specular_blob_intensity,
|
||||
#ifdef LIGHT_TRANSMISSION_USED
|
||||
vec3 transmission,
|
||||
#endif
|
||||
#ifdef LIGHT_RIM_USED
|
||||
float rim, float rim_tint,
|
||||
#endif
|
||||
#ifdef LIGHT_CLEARCOAT_USED
|
||||
float clearcoat, float clearcoat_gloss,
|
||||
#endif
|
||||
#ifdef LIGHT_ANISOTROPY_USED
|
||||
vec3 B, vec3 T,float anisotropy,
|
||||
#endif
|
||||
#ifdef USE_SHADOW_TO_OPACITY
|
||||
inout float alpha,
|
||||
#endif
|
||||
inout vec3 diffuse_light, inout vec3 specular_light
|
||||
) {
|
||||
|
||||
#if defined(USE_LIGHT_SHADER_CODE)
|
||||
// light is written by the light shader
|
||||
|
@ -419,11 +484,11 @@ LIGHT_SHADER_CODE
|
|||
|
||||
diffuse_light += light_color * diffuse_color * diffuse_brdf_NL * attenuation;
|
||||
|
||||
#if defined(TRANSMISSION_USED)
|
||||
#if defined(LIGHT_TRANSMISSION_USED)
|
||||
diffuse_light += light_color * diffuse_color * (vec3(1.0 / M_PI) - diffuse_brdf_NL) * transmission * attenuation;
|
||||
#endif
|
||||
|
||||
#if defined(RIM_LIGHT_USED)
|
||||
#if defined(LIGHT_RIM_USED)
|
||||
float rim_light = pow(max(0.0, 1.0 - cNdotV), max(0.0, (1.0 - roughness) * 16.0));
|
||||
diffuse_light += rim_light * rim * mix(vec3(1.0), diffuse_color, rim_tint) * light_color;
|
||||
#endif
|
||||
|
@ -517,9 +582,209 @@ LIGHT_SHADER_CODE
|
|||
#endif //defined(USE_LIGHT_SHADER_CODE)
|
||||
}
|
||||
|
||||
#ifndef USE_NO_SHADOWS
|
||||
|
||||
float sample_shadow(texture2D shadow, vec2 shadow_pixel_size, vec2 pos, float depth) {
|
||||
|
||||
#ifdef SHADOW_MODE_PCF_13
|
||||
|
||||
float avg = textureProj(shadow, vec4(pos, depth, 1.0));
|
||||
avg += textureProj(sampler2DShadow(shadow,shadow_sampler), vec4(pos + vec2(shadow_pixel_size.x, 0.0), depth, 1.0));
|
||||
avg += textureProj(sampler2DShadow(shadow,shadow_sampler), vec4(pos + vec2(-shadow_pixel_size.x, 0.0), depth, 1.0));
|
||||
avg += textureProj(sampler2DShadow(shadow,shadow_sampler), vec4(pos + vec2(0.0, shadow_pixel_size.y), depth, 1.0));
|
||||
avg += textureProj(sampler2DShadow(shadow,shadow_sampler), vec4(pos + vec2(0.0, -shadow_pixel_size.y), depth, 1.0));
|
||||
avg += textureProj(sampler2DShadow(shadow,shadow_sampler), vec4(pos + vec2(shadow_pixel_size.x, shadow_pixel_size.y), depth, 1.0));
|
||||
avg += textureProj(sampler2DShadow(shadow,shadow_sampler), vec4(pos + vec2(-shadow_pixel_size.x, shadow_pixel_size.y), depth, 1.0));
|
||||
avg += textureProj(sampler2DShadow(shadow,shadow_sampler), vec4(pos + vec2(shadow_pixel_size.x, -shadow_pixel_size.y), depth, 1.0));
|
||||
avg += textureProj(sampler2DShadow(shadow,shadow_sampler), vec4(pos + vec2(-shadow_pixel_size.x, -shadow_pixel_size.y), depth, 1.0));
|
||||
avg += textureProj(sampler2DShadow(shadow,shadow_sampler), vec4(pos + vec2(shadow_pixel_size.x * 2.0, 0.0), depth, 1.0));
|
||||
avg += textureProj(sampler2DShadow(shadow,shadow_sampler), vec4(pos + vec2(-shadow_pixel_size.x * 2.0, 0.0), depth, 1.0));
|
||||
avg += textureProj(sampler2DShadow(shadow,shadow_sampler), vec4(pos + vec2(0.0, shadow_pixel_size.y * 2.0), depth, 1.0));
|
||||
avg += textureProj(sampler2DShadow(shadow,shadow_sampler), vec4(pos + vec2(0.0, -shadow_pixel_size.y * 2.0), depth, 1.0));
|
||||
return avg * (1.0 / 13.0);
|
||||
#endif
|
||||
|
||||
#ifdef SHADOW_MODE_PCF_5
|
||||
|
||||
float avg = textureProj(sampler2DShadow(shadow,shadow_sampler), vec4(pos, depth, 1.0));
|
||||
avg += textureProj(sampler2DShadow(shadow,shadow_sampler), vec4(pos + vec2(shadow_pixel_size.x, 0.0), depth, 1.0));
|
||||
avg += textureProj(sampler2DShadow(shadow,shadow_sampler), vec4(pos + vec2(-shadow_pixel_size.x, 0.0), depth, 1.0));
|
||||
avg += textureProj(sampler2DShadow(shadow,shadow_sampler), vec4(pos + vec2(0.0, shadow_pixel_size.y), depth, 1.0));
|
||||
avg += textureProj(sampler2DShadow(shadow,shadow_sampler), vec4(pos + vec2(0.0, -shadow_pixel_size.y), depth, 1.0));
|
||||
return avg * (1.0 / 5.0);
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(SHADOW_MODE_PCF_5) || !defined(SHADOW_MODE_PCF_13)
|
||||
|
||||
return textureProj(sampler2DShadow(shadow,shadow_sampler), vec4(pos, depth, 1.0));
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif //USE_NO_SHADOWS
|
||||
|
||||
|
||||
void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 albedo,float roughness, float metallic, float specular,float p_blob_intensity,
|
||||
#ifdef LIGHT_TRANSMISSION_USED
|
||||
vec3 transmission,
|
||||
#endif
|
||||
#ifdef LIGHT_RIM_USED
|
||||
float rim, float rim_tint,
|
||||
#endif
|
||||
#ifdef LIGHT_CLEARCOAT_USED
|
||||
float clearcoat, float clearcoat_gloss,
|
||||
#endif
|
||||
#ifdef LIGHT_ANISOTROPY_USED
|
||||
vec3 binormal, vec3 tangent, float anisotropy,
|
||||
#endif
|
||||
#ifdef USE_SHADOW_TO_OPACITY
|
||||
inout float alpha,
|
||||
#endif
|
||||
inout vec3 diffuse_light, inout vec3 specular_light) {
|
||||
|
||||
vec3 light_rel_vec = lights.data[idx].position - vertex;
|
||||
float light_length = length(light_rel_vec);
|
||||
float normalized_distance = light_length * lights.data[idx].inv_radius;
|
||||
vec2 attenuation_energy = unpackHalf2x16(lights.data[idx].attenuation_energy);
|
||||
float omni_attenuation = pow(max(1.0 - normalized_distance, 0.0), attenuation_energy.x);
|
||||
vec3 light_attenuation = vec3(omni_attenuation);
|
||||
vec4 color_specular = unpackUnorm4x8(lights.data[idx].color_specular);
|
||||
color_specular.rgb*=attenuation_energy.y;
|
||||
|
||||
#ifndef USE_NO_SHADOWS
|
||||
vec4 shadow_color_enabled = unpackUnorm4x8(lights.data[idx].shadow_color_enabled);
|
||||
if (shadow_color_enabled.w > 0.5) {
|
||||
// there is a shadowmap
|
||||
|
||||
vec3 splane = (lights.data[idx].shadow_matrix * vec4(vertex, 1.0)).xyz;
|
||||
float shadow_len = length(splane);
|
||||
splane = normalize(splane);
|
||||
vec4 clamp_rect = lights.data[idx].atlas_rect;
|
||||
|
||||
if (splane.z >= 0.0) {
|
||||
|
||||
splane.z += 1.0;
|
||||
|
||||
clamp_rect.y += clamp_rect.w;
|
||||
|
||||
} else {
|
||||
|
||||
splane.z = 1.0 - splane.z;
|
||||
|
||||
}
|
||||
|
||||
splane.xy /= splane.z;
|
||||
splane.xy = splane.xy * 0.5 + 0.5;
|
||||
splane.z = shadow_len * lights.data[idx].inv_radius;
|
||||
|
||||
splane.xy = clamp_rect.xy + splane.xy * clamp_rect.zw;
|
||||
float shadow = sample_shadow(shadow_atlas, scene_data.shadow_atlas_pixel_size, splane.xy, splane.z);
|
||||
|
||||
light_attenuation *= mix(shadow_color_enabled.rgb, vec3(1.0), shadow);
|
||||
}
|
||||
#endif //USE_NO_SHADOWS
|
||||
|
||||
light_compute(normal, normalize(light_rel_vec), eye_vec, color_specular.rgb, light_attenuation, albedo, roughness, metallic, specular,color_specular.a * p_blob_intensity,
|
||||
#ifdef LIGHT_TRANSMISSION_USED
|
||||
transmission,
|
||||
#endif
|
||||
#ifdef LIGHT_RIM_USED
|
||||
rim * omni_attenuation, rim_tint,
|
||||
#endif
|
||||
#ifdef LIGHT_CLEARCOAT_USED
|
||||
clearcoat, clearcoat_gloss,
|
||||
#endif
|
||||
#ifdef LIGHT_ANISOTROPY_USED
|
||||
binormal, tangent, anisotropy,
|
||||
#endif
|
||||
#ifdef USE_SHADOW_TO_OPACITY
|
||||
alpha
|
||||
#endif
|
||||
diffuse_light, specular_light);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 albedo,float roughness, float metallic, float specular,float p_blob_intensity,
|
||||
#ifdef LIGHT_TRANSMISSION_USED
|
||||
vec3 transmission,
|
||||
#endif
|
||||
#ifdef LIGHT_RIM_USED
|
||||
float rim, float rim_tint,
|
||||
#endif
|
||||
#ifdef LIGHT_CLEARCOAT_USED
|
||||
float clearcoat, float clearcoat_gloss,
|
||||
#endif
|
||||
#ifdef LIGHT_ANISOTROPY_USED
|
||||
vec3 binormal, vec3 tangent, float anisotropy,
|
||||
#endif
|
||||
#ifdef USE_SHADOW_TO_OPACITY
|
||||
inout float alpha
|
||||
#endif
|
||||
inout vec3 diffuse_light, inout vec3 specular_light) {
|
||||
|
||||
vec3 light_rel_vec = lights.data[idx].position - vertex;
|
||||
float light_length = length(light_rel_vec);
|
||||
float normalized_distance = light_length * lights.data[idx].inv_radius;
|
||||
vec2 attenuation_energy = unpackHalf2x16(lights.data[idx].attenuation_energy);
|
||||
float spot_attenuation = pow(max(1.0 - normalized_distance, 0.001), attenuation_energy.x);
|
||||
vec3 spot_dir = lights.data[idx].direction;
|
||||
vec2 spot_att_angle = unpackHalf2x16(lights.data[idx].cone_attenuation_angle);
|
||||
float scos = max(dot(-normalize(light_rel_vec), spot_dir), spot_att_angle.y);
|
||||
float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - spot_att_angle.y));
|
||||
spot_attenuation *= 1.0 - pow(spot_rim, spot_att_angle.x);
|
||||
vec3 light_attenuation = vec3(spot_attenuation);
|
||||
vec4 color_specular = unpackUnorm4x8(lights.data[idx].color_specular);
|
||||
color_specular.rgb*=attenuation_energy.y;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
if (lights.data[idx].atlas_rect!=vec4(0.0)) {
|
||||
//use projector texture
|
||||
}
|
||||
*/
|
||||
#ifndef USE_NO_SHADOWS
|
||||
vec4 shadow_color_enabled = unpackUnorm4x8(lights.data[idx].shadow_color_enabled);
|
||||
if (shadow_color_enabled.w > 0.5) {
|
||||
//there is a shadowmap
|
||||
vec4 splane = (lights.data[idx].shadow_matrix * vec4(vertex, 1.0));
|
||||
splane.xyz /= splane.w;
|
||||
|
||||
float shadow = sample_shadow(shadow_atlas, scene_data.shadow_atlas_pixel_size, splane.xy, splane.z);
|
||||
|
||||
light_attenuation *= mix(shadow_color_enabled.rgb, vec3(1.0), shadow);
|
||||
}
|
||||
|
||||
#endif //USE_NO_SHADOWS
|
||||
|
||||
light_compute(normal, normalize(light_rel_vec), eye_vec, color_specular.rgb, light_attenuation, albedo, roughness, metallic, specular,color_specular.a * p_blob_intensity,
|
||||
#ifdef LIGHT_TRANSMISSION_USED
|
||||
transmission,
|
||||
#endif
|
||||
#ifdef LIGHT_RIM_USED
|
||||
rim * omni_attenuation, rim_tint,
|
||||
#endif
|
||||
#ifdef LIGHT_CLEARCOAT_USED
|
||||
clearcoat, clearcoat_gloss,
|
||||
#endif
|
||||
#ifdef LIGHT_ANISOTROPY_USED
|
||||
binormal, tangent, anisotropy,
|
||||
#endif
|
||||
#ifdef USE_SHADOW_TO_OPACITY
|
||||
alpha,
|
||||
#endif
|
||||
diffuse_light, specular_light);
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
||||
#ifdef MODE_DUAL_PARABOLOID
|
||||
|
||||
if (dp_clip > 0.0)
|
||||
discard;
|
||||
#endif
|
||||
|
||||
//lay out everything, whathever is unused is optimized away anyway
|
||||
vec3 vertex = vertex_interp;
|
||||
|
@ -701,14 +966,149 @@ FRAGMENT_SHADER_CODE
|
|||
specular_blob_intensity *= specular * 2.0;
|
||||
#endif
|
||||
|
||||
#ifndef MODE_RENDER_DEPTH
|
||||
//gi probes
|
||||
|
||||
//lightmap
|
||||
|
||||
//lightmap capture
|
||||
|
||||
//process reflections
|
||||
#if 0
|
||||
{ // 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);
|
||||
|
||||
for (uint i = 0; i < MAX_REFLECTION_PROBES; i++) {
|
||||
if (i >= draw_data.reflection_probe_count) {
|
||||
break;
|
||||
}
|
||||
|
||||
uint ref_index;
|
||||
if (i<4) {
|
||||
if (i<2) {
|
||||
ref_index=draw_data.reflection_probe_indices[0];
|
||||
} else {
|
||||
ref_index=draw_data.reflection_probe_indices[1];
|
||||
}
|
||||
} else {
|
||||
if (i<6) {
|
||||
ref_index=draw_data.reflection_probe_indices[2];
|
||||
} else {
|
||||
ref_index=draw_data.reflection_probe_indices[3];
|
||||
}
|
||||
}
|
||||
ref_index>>=(i&1)*16;
|
||||
ref_index&=0xFFFF;
|
||||
|
||||
vec3 box_extents = reflections.data[ref_index].box_extents.xyz;
|
||||
vec3 local_pos = (reflections.data[ref_index].local_matrix * vec4(vertex, 1.0)).xyz;
|
||||
|
||||
if (any(greaterThan(abs(local_pos), box_extents))) { //out of the reflection box
|
||||
continue;
|
||||
}
|
||||
|
||||
vec3 ref_vec = normalize(reflect(vertex, normal));
|
||||
|
||||
vec3 inner_pos = abs(local_pos / box_extents);
|
||||
float blend = max(inner_pos.x, max(inner_pos.y, inner_pos.z));
|
||||
//make blend more rounded
|
||||
blend = mix(length(inner_pos), blend, blend);
|
||||
blend *= blend;
|
||||
blend = max(0.0, 1.0 - blend);
|
||||
|
||||
if (reflections.data[ref_index].params.x > 0.0) { // compute reflection
|
||||
|
||||
vec3 local_ref_vec = (reflections.data[ref_index].local_matrix * vec4(ref_vec, 0.0)).xyz;
|
||||
|
||||
if (reflections.data[ref_index].params.w > 0.5) { //box project
|
||||
|
||||
vec3 nrdir = normalize(local_ref_vec);
|
||||
vec3 rbmax = (box_extents - local_pos) / nrdir;
|
||||
vec3 rbmin = (-box_extents - local_pos) / nrdir;
|
||||
|
||||
vec3 rbminmax = mix(rbmin, rbmax, greaterThan(nrdir, vec3(0.0, 0.0, 0.0)));
|
||||
|
||||
float fa = min(min(rbminmax.x, rbminmax.y), rbminmax.z);
|
||||
vec3 posonbox = local_pos + nrdir * fa;
|
||||
local_ref_vec = posonbox - reflections.data[ref_index].box_offset.xyz;
|
||||
}
|
||||
|
||||
vec4 reflection;
|
||||
|
||||
#ifdef USE_RADIANCE_CUBEMAP_ARRAY
|
||||
|
||||
float lod,layer_blend;
|
||||
layer_blend = modf(roughness * MAX_ROUGHNESS_LOD, lod);
|
||||
reflection.rgb = texture(samplerCubeArray(reflection_probes[i],material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(local_ref_vec, lod)).rgb;
|
||||
reflection.rgb = mix(reflection.rgb,texture(samplerCubeArray(reflection_probes[i],material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(local_ref_vec, lod+1)).rgb,layer_blend);
|
||||
|
||||
#else
|
||||
reflection.rgb = textureLod(samplerCube(reflection_probes[i],material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), local_ref_vec, roughness * MAX_ROUGHNESS_LOD).rgb;
|
||||
|
||||
#endif
|
||||
|
||||
if (reflections.data[ref_index].params.z < 0.5) {
|
||||
reflection.rgb = mix(specular_light, reflection.rgb, blend);
|
||||
}
|
||||
|
||||
reflection.rgb *= reflections.data[ref_index].params.x;
|
||||
reflection.a = blend;
|
||||
reflection.rgb *= reflection.a;
|
||||
|
||||
reflection_accum += reflection;
|
||||
}
|
||||
|
||||
#ifndef USE_LIGHTMAP
|
||||
if (reflections.data[ref_index].ambient.a > 0.0) { //compute ambient using skybox
|
||||
|
||||
vec3 local_amb_vec = (reflections.data[ref_index].local_matrix * vec4(normal, 0.0)).xyz;
|
||||
|
||||
vec4 ambient_out;
|
||||
|
||||
#ifdef USE_RADIANCE_CUBEMAP_ARRAY
|
||||
ambient_out.rgb = texture(samplerCubeArray(reflection_probes[i],material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(local_amb_vec, MAX_ROUGHNESS_LOD)).rgb;
|
||||
#else
|
||||
ambient_out.rgb = textureLod(samplerCube(reflection_probes[i],material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), local_amb_vec, MAX_ROUGHNESS_LOD).rgb;
|
||||
#endif //USE_RADIANCE_CUBEMAP_ARRAY
|
||||
|
||||
ambient_out.a = blend;
|
||||
ambient_out.rgb = mix(reflections.data[ref_index].ambient.rgb, ambient_out.rgb, reflections.data[ref_index].ambient.a);
|
||||
if (reflections.data[ref_index].params.z < 0.5) {
|
||||
ambient_out.rgb = mix(ambient_light, ambient_out.rgb, blend);
|
||||
}
|
||||
|
||||
ambient_out.rgb *= ambient_out.a;
|
||||
ambient_accum += ambient_out;
|
||||
} else {
|
||||
|
||||
vec4 ambient_out;
|
||||
ambient_out.a = blend;
|
||||
ambient_out.rgb = reflections.data[ref_index].ambient.rgb;
|
||||
if (reflections.data[ref_index].params.z < 0.5) {
|
||||
ambient_out.rgb = mix(ambient_light, ambient_out.rgb, blend);
|
||||
}
|
||||
ambient_out.rgb *= ambient_out.a;
|
||||
ambient_accum += ambient_out;
|
||||
}
|
||||
#endif //USE_LIGHTMAP
|
||||
|
||||
}
|
||||
|
||||
if (reflection_accum.a > 0.0) {
|
||||
specular_light = reflection_accum.rgb / reflection_accum.a;
|
||||
}
|
||||
|
||||
#if !defined(USE_LIGHTMAP)
|
||||
if (ambient_accum.a > 0.0) {
|
||||
ambient_light = ambient_accum.rgb / ambient_accum.a;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
#endif //0
|
||||
{
|
||||
|
||||
#if defined(DIFFUSE_TOON)
|
||||
|
@ -734,8 +1134,86 @@ FRAGMENT_SHADER_CODE
|
|||
|
||||
//directional light
|
||||
|
||||
{ //omni lights
|
||||
uint omni_light_count = (instances.data[instance_index].flags >> INSTANCE_FLAGS_FORWARD_OMNI_LIGHT_SHIFT) & INSTANCE_FLAGS_FORWARD_MASK;
|
||||
for (uint i = 0; i < omni_light_count; i++) {
|
||||
|
||||
//process omni and spots
|
||||
uint light_index = instances.data[instance_index].omni_light_indices[i>>1];
|
||||
|
||||
if (bool(i&1)) {
|
||||
light_index>>=16;
|
||||
} else {
|
||||
light_index&=0xFFFF;
|
||||
}
|
||||
|
||||
//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,
|
||||
#endif
|
||||
#ifdef LIGHT_RIM_USED
|
||||
rim,
|
||||
rim_tint,
|
||||
#endif
|
||||
#ifdef LIGHT_CLEARCOAT_USED
|
||||
clearcoat, clearcoat_gloss,
|
||||
#endif
|
||||
#ifdef LIGHT_ANISOTROPY_USED
|
||||
tangent, binormal, anisotropy,
|
||||
#endif
|
||||
#ifdef USE_SHADOW_TO_OPACITY
|
||||
alpha,
|
||||
#endif
|
||||
diffuse_light, specular_light);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
{ //spot lights
|
||||
uint spot_light_count = (instances.data[instance_index].flags >> INSTANCE_FLAGS_FORWARD_SPOT_LIGHT_SHIFT) & INSTANCE_FLAGS_FORWARD_MASK;
|
||||
for (uint i = 0; i < spot_light_count; i++) {
|
||||
|
||||
uint light_index = instances.data[instance_index].spot_light_indices[i>>1];
|
||||
|
||||
if (bool(i&1)) {
|
||||
light_index>>=16;
|
||||
} else {
|
||||
light_index&=0xFFFF;
|
||||
}
|
||||
|
||||
//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,
|
||||
#endif
|
||||
#ifdef LIGHT_RIM_USED
|
||||
rim,
|
||||
rim_tint,
|
||||
#endif
|
||||
#ifdef LIGHT_CLEARCOAT_USED
|
||||
clearcoat, clearcoat_gloss,
|
||||
#endif
|
||||
#ifdef LIGHT_ANISOTROPY_USED
|
||||
tangent, binormal, anisotropy,
|
||||
#endif
|
||||
#ifdef USE_SHADOW_TO_OPACITY
|
||||
alpha,
|
||||
#endif
|
||||
diffuse_light, specular_light);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif //!MODE_RENDER_DEPTH
|
||||
|
||||
#ifdef USE_SHADOW_TO_OPACITY
|
||||
alpha = min(alpha, clamp(length(ambient_light), 0.0, 1.0));
|
||||
|
@ -757,6 +1235,7 @@ FRAGMENT_SHADER_CODE
|
|||
#endif // USE_SHADOW_TO_OPACITY
|
||||
|
||||
|
||||
|
||||
#ifdef MODE_RENDER_DEPTH
|
||||
//nothing happens, so a tree-ssa optimizer will result in no fragment shader :)
|
||||
#else
|
||||
|
|
|
@ -2,6 +2,13 @@
|
|||
#define M_PI 3.14159265359
|
||||
#define ROUGHNESS_MAX_LOD 5
|
||||
|
||||
layout(push_constant, binding = 0, std430) uniform DrawCall {
|
||||
uint instance_index;
|
||||
uint pad[3]; //16 bits minimum size
|
||||
} draw_call;
|
||||
|
||||
|
||||
|
||||
/* Set 0 Scene data, screen and sources (changes the least) */
|
||||
|
||||
layout(set=0,binding=1) uniform texture2D depth_buffer;
|
||||
|
@ -35,7 +42,9 @@ layout(set = 0, binding = 5) uniform textureCube radiance_cubemap;
|
|||
|
||||
layout(set = 0, binding = 6) uniform sampler material_samplers[12];
|
||||
|
||||
layout(set=0,binding=7,std140) uniform SceneData {
|
||||
layout(set = 0, binding = 7) uniform sampler shadow_sampler;
|
||||
|
||||
layout(set=0,binding=8,std140) uniform SceneData {
|
||||
|
||||
mat4 projection_matrix;
|
||||
mat4 inv_projection_matrix;
|
||||
|
@ -63,6 +72,14 @@ layout(set=0,binding=7,std140) uniform SceneData {
|
|||
|
||||
mat3 radiance_inverse_xform;
|
||||
|
||||
vec2 shadow_atlas_pixel_size;
|
||||
vec2 directional_shadow_pixel_size;
|
||||
|
||||
uint directional_light_count;
|
||||
float dual_paraboloid_side;
|
||||
float z_far;
|
||||
uint pad0;
|
||||
|
||||
#if 0
|
||||
vec4 ambient_light_color;
|
||||
vec4 bg_color;
|
||||
|
@ -101,80 +118,125 @@ layout(set=0,binding=7,std140) uniform SceneData {
|
|||
#endif
|
||||
} scene_data;
|
||||
|
||||
#define INSTANCE_FLAGS_FORWARD_MASK 3
|
||||
#define INSTANCE_FLAGS_FORWARD_OMNI_LIGHT_SHIFT 3
|
||||
#define INSTANCE_FLAGS_FORWARD_SPOT_LIGHT_SHIFT 6
|
||||
#define INSTANCE_FLAGS_FORWARD_DECAL_SHIFT 9
|
||||
|
||||
|
||||
struct InstanceData {
|
||||
mat4 transform;
|
||||
mat4 normal_transform;
|
||||
uint flags;
|
||||
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=9,std430) buffer Instances {
|
||||
InstanceData data[];
|
||||
} instances;
|
||||
|
||||
struct ReflectionData {
|
||||
|
||||
vec4 box_extents;
|
||||
vec4 box_offset;
|
||||
vec4 params; // intensity, 0, interior , boxproject
|
||||
vec4 ambient; // ambient color, energy
|
||||
mat4 local_matrix; // up to here for spot and omni, rest is for directional
|
||||
// notes: for ambientblend, use distance to edge to blend between already existing global environment
|
||||
};
|
||||
|
||||
layout(set=0,binding=10,std140) uniform ReflectionProbeData {
|
||||
ReflectionData data[MAX_REFLECTION_DATA_STRUCTS];
|
||||
} reflections;
|
||||
|
||||
|
||||
struct LightData { //this structure needs to be 128 bits
|
||||
|
||||
vec3 position;
|
||||
float inv_radius;
|
||||
vec3 direction;
|
||||
uint attenuation_energy; //attenuation
|
||||
uint color_specular; //rgb color, a specular (8 bit unorm)
|
||||
uint cone_attenuation_angle; // attenuation and angle, (16bit float)
|
||||
uint mask;
|
||||
uint shadow_color_enabled; //shadow rgb color, a>0.5 enabled (8bit unorm)
|
||||
vec4 atlas_rect; //used for shadow atlas uv on omni, and for projection atlas on spot
|
||||
mat4 shadow_matrix;
|
||||
};
|
||||
|
||||
layout(set=0,binding=11,std140) uniform Lights {
|
||||
LightData data[MAX_LIGHT_DATA_STRUCTS];
|
||||
} lights;
|
||||
|
||||
layout(set=0,binding=12) uniform texture2D shadow_atlas;
|
||||
|
||||
#if 0
|
||||
struct DirectionalLightData {
|
||||
|
||||
vec4 light_pos_inv_radius;
|
||||
vec4 light_direction_attenuation;
|
||||
vec4 light_color_energy;
|
||||
vec4 light_params; // cone attenuation, angle, specular, shadow enabled,
|
||||
vec4 light_clamp;
|
||||
vec4 shadow_color_contact;
|
||||
vec3 direction;
|
||||
float energy;
|
||||
vec3 color;
|
||||
float specular;
|
||||
uint mask;
|
||||
uint pad0,pad1,pad2;
|
||||
vec3 shadow_color;
|
||||
bool shadow_enabled;
|
||||
vec4 shadow_atlas_rect;
|
||||
vec4 shadow_split_offsets;
|
||||
mat4 shadow_matrix1;
|
||||
mat4 shadow_matrix2;
|
||||
mat4 shadow_matrix3;
|
||||
mat4 shadow_matrix4;
|
||||
vec4 shadow_split_offsets;
|
||||
};
|
||||
#endif
|
||||
|
||||
/* Set 1 Skeleton Data (most objects lack it, so it changes little */
|
||||
};
|
||||
|
||||
layout(set=0,binding=13,std140) uniform DirectionalLights {
|
||||
DirectionalLightData data[MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS];
|
||||
} directional_lights;
|
||||
|
||||
layout(set=0,binding=14) uniform texture2D directional_shadow_atlas;
|
||||
|
||||
/*
|
||||
layout(set=0,binding=15,std430) buffer Skeletons {
|
||||
vec4 data[];
|
||||
} skeletons;
|
||||
*/
|
||||
|
||||
/* Set 1 Instancing (Multimesh) */
|
||||
|
||||
//layout(set = 1, binding = 0) uniform textureBuffer multimesh_transforms;
|
||||
|
||||
/* Set 2 Instancing (Multimesh) data */
|
||||
|
||||
#if 0
|
||||
layout(set = 1 binding = 0, std140) uniform SkeletonData {
|
||||
mat4 transform;
|
||||
bool use_skeleton;
|
||||
bool use_world_coords;
|
||||
bool pad1;
|
||||
bool pad2;
|
||||
} skeleton;
|
||||
|
||||
layout(set = 1, binding = 1) uniform textureBuffer skeleton_bones;
|
||||
#endif
|
||||
#ifdef USE_RADIANCE_CUBEMAP_ARRAY
|
||||
|
||||
/* Set 2 Custom Material Data (changess less than instance) */
|
||||
layout(set = 3, binding = 2) uniform textureCubeArray reflection_probes[MAX_REFLECTION_PROBES];
|
||||
|
||||
#else
|
||||
|
||||
/* Set 3 Instance Data (Set on every draw call) */
|
||||
|
||||
layout(push_constant, binding = 0, std430) uniform DrawData {
|
||||
//used in forward rendering, 16 bits indices, max 8
|
||||
uint reflection_probe_count;
|
||||
uint omni_light_count;
|
||||
uint spot_light_count;
|
||||
uint decal_count;
|
||||
uvec4 reflection_probe_indices;
|
||||
uvec4 omni_light_indices;
|
||||
uvec4 spot_light_indices;
|
||||
uvec4 decal_indices;
|
||||
} draw_data;
|
||||
|
||||
layout(set = 3, binding = 0, std140) uniform InstanceData {
|
||||
mat4 transform;
|
||||
mat3 normal_transform;
|
||||
uint flags;
|
||||
uint pad0;
|
||||
uint pad1;
|
||||
uint pad2;
|
||||
} instance_data;
|
||||
|
||||
layout(set = 3, binding = 1) uniform textureBuffer multimesh_transforms;
|
||||
|
||||
#ifdef USE_LIGHTMAP
|
||||
|
||||
layout(set = 3, binding = 2) uniform texture2D lightmap;
|
||||
layout(set = 3, binding = 2) uniform textureCube reflection_probes[MAX_REFLECTION_PROBES];
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef USE_VOXEL_CONE_TRACING
|
||||
|
||||
layout(set = 3, binding = 3) uniform texture3D gi_probe[2];
|
||||
layout(set = 3, binding = 4) uniform texture3D gi_probe[2];
|
||||
|
||||
#ifdef USE_ANISOTROPIC_VOXEL_CONE_TRACING
|
||||
layout(set = 3, binding = 4) uniform texture3D gi_probe_aniso_pos[2];
|
||||
layout(set = 3, binding = 5) uniform texture3D gi_probe_aniso_neg[2];
|
||||
layout(set = 3, binding = 5) uniform texture3D gi_probe_aniso_pos[2];
|
||||
layout(set = 3, binding = 6) uniform texture3D gi_probe_aniso_neg[2];
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -166,7 +166,9 @@ vec3 tonemap_reinhard(vec3 color, float white) {
|
|||
return (white * color + color) / (color * white + white);
|
||||
}
|
||||
|
||||
vec3 linear_to_srgb(vec3 color) { // convert linear rgb to srgb, assumes clamped input in range [0;1]
|
||||
vec3 linear_to_srgb(vec3 color) {
|
||||
//if going to srgb, clamp from 0 to 1.
|
||||
color = clamp(color,vec3(0.0),vec3(1.0));
|
||||
const vec3 a = vec3(0.055f);
|
||||
return mix((vec3(1.0f) + a) * pow(color.rgb, vec3(1.0f / 2.4f)) - a, 12.92f * color.rgb, lessThan(color.rgb, vec3(0.0031308f)));
|
||||
}
|
||||
|
@ -233,15 +235,9 @@ vec3 apply_glow(vec3 color, vec3 glow) { // apply glow using the selected blendi
|
|||
return color + glow;
|
||||
} else if (params.glow_mode==GLOW_MODE_SCREEN) {
|
||||
//need color clamping
|
||||
color = clamp(color,0.0,1.0);
|
||||
glow = clamp(glow,0.0,1.0);
|
||||
|
||||
return max((color + glow) - (color * glow), vec3(0.0));
|
||||
} else if ( params.glow_mode==GLOW_MODE_SOFTLIGHT) {
|
||||
//need color clamping
|
||||
color = clamp(color,0.0,1.0);
|
||||
glow = clamp(glow,0.0,1.0);
|
||||
|
||||
glow = glow * vec3(0.5f) + vec3(0.5f);
|
||||
|
||||
color.r = (glow.r <= 0.5f) ? (color.r - (1.0f - 2.0f * glow.r) * color.r * (1.0f - color.r)) : (((glow.r > 0.5f) && (color.r <= 0.25f)) ? (color.r + (2.0f * glow.r - 1.0f) * (4.0f * color.r * (4.0f * color.r + 1.0f) * (color.r - 1.0f) + 7.0f * color.r)) : (color.r + (2.0f * glow.r - 1.0f) * (sqrt(color.r) - color.r)));
|
||||
|
|
|
@ -103,9 +103,9 @@ void VisualServerRaster::draw(bool p_swap_buffers, double frame_step) {
|
|||
|
||||
VSG::rasterizer->begin_frame(frame_step);
|
||||
|
||||
VSG::scene->update_dirty_instances(); //update scene stuff
|
||||
VSG::scene_render->update(); //update scenes stuff before updating instances
|
||||
|
||||
VSG::scene_render->update();
|
||||
VSG::scene->update_dirty_instances(); //update scene stuff
|
||||
|
||||
VSG::viewport->draw_viewports();
|
||||
VSG::scene->render_probes();
|
||||
|
|
|
@ -313,7 +313,6 @@ public:
|
|||
BIND2(light_set_use_gi, RID, bool)
|
||||
|
||||
BIND2(light_omni_set_shadow_mode, RID, LightOmniShadowMode)
|
||||
BIND2(light_omni_set_shadow_detail, RID, LightOmniShadowDetail)
|
||||
|
||||
BIND2(light_directional_set_shadow_mode, RID, LightDirectionalShadowMode)
|
||||
BIND2(light_directional_set_blend_splits, RID, bool)
|
||||
|
@ -489,6 +488,8 @@ public:
|
|||
//from now on, calls forwarded to this singleton
|
||||
#define BINDBASE VSG::scene_render
|
||||
|
||||
BIND1(directional_shadow_atlas_set_size, int)
|
||||
|
||||
/* SKY API */
|
||||
|
||||
BIND0R(RID, sky_create)
|
||||
|
@ -535,7 +536,6 @@ public:
|
|||
|
||||
BIND2(scenario_set_debug, RID, ScenarioDebugMode)
|
||||
BIND2(scenario_set_environment, RID, RID)
|
||||
BIND3(scenario_set_reflection_atlas_size, RID, int, int)
|
||||
BIND2(scenario_set_fallback_environment, RID, RID)
|
||||
|
||||
/* INSTANCING API */
|
||||
|
|
|
@ -268,7 +268,6 @@ RID VisualServerScene::scenario_create() {
|
|||
VSG::scene_render->shadow_atlas_set_quadrant_subdivision(scenario->reflection_probe_shadow_atlas, 1, 4);
|
||||
VSG::scene_render->shadow_atlas_set_quadrant_subdivision(scenario->reflection_probe_shadow_atlas, 2, 4);
|
||||
VSG::scene_render->shadow_atlas_set_quadrant_subdivision(scenario->reflection_probe_shadow_atlas, 3, 8);
|
||||
scenario->reflection_atlas = VSG::scene_render->reflection_atlas_create();
|
||||
|
||||
return scenario_rid;
|
||||
}
|
||||
|
@ -294,14 +293,6 @@ void VisualServerScene::scenario_set_fallback_environment(RID p_scenario, RID p_
|
|||
scenario->fallback_environment = p_environment;
|
||||
}
|
||||
|
||||
void VisualServerScene::scenario_set_reflection_atlas_size(RID p_scenario, int p_size, int p_subdiv) {
|
||||
|
||||
Scenario *scenario = scenario_owner.getornull(p_scenario);
|
||||
ERR_FAIL_COND(!scenario);
|
||||
VSG::scene_render->reflection_atlas_set_size(scenario->reflection_atlas, p_size);
|
||||
VSG::scene_render->reflection_atlas_set_subdivision(scenario->reflection_atlas, p_subdiv);
|
||||
}
|
||||
|
||||
/* INSTANCING API */
|
||||
|
||||
void VisualServerScene::_instance_queue_update(Instance *p_instance, bool p_update_aabb, bool p_update_dependencies) {
|
||||
|
@ -360,11 +351,6 @@ void VisualServerScene::instance_set_base(RID p_instance, RID p_base) {
|
|||
instance->octree_id = 0;
|
||||
}
|
||||
|
||||
if (instance->custom_data) {
|
||||
VSG::scene_render->instance_free_custom_data(instance);
|
||||
instance->custom_data = nullptr;
|
||||
}
|
||||
|
||||
switch (instance->base_type) {
|
||||
case VS::INSTANCE_LIGHT: {
|
||||
|
||||
|
@ -494,8 +480,6 @@ void VisualServerScene::instance_set_base(RID p_instance, RID p_base) {
|
|||
|
||||
//forcefully update the dependency now, so if for some reason it gets removed, we can immediately clear it
|
||||
VSG::storage->base_update_dependency(p_base, instance);
|
||||
|
||||
VSG::scene_render->instance_create_custom_data(instance);
|
||||
}
|
||||
|
||||
_instance_queue_update(instance, true, true);
|
||||
|
@ -527,8 +511,6 @@ void VisualServerScene::instance_set_scenario(RID p_instance, RID p_scenario) {
|
|||
} break;
|
||||
case VS::INSTANCE_REFLECTION_PROBE: {
|
||||
|
||||
InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(instance->base_data);
|
||||
VSG::scene_render->reflection_probe_release_atlas_index(reflection_probe->instance);
|
||||
} break;
|
||||
case VS::INSTANCE_GI_PROBE: {
|
||||
|
||||
|
@ -710,10 +692,6 @@ void VisualServerScene::instance_set_use_lightmap(RID p_instance, RID p_lightmap
|
|||
lightmap_capture->users.insert(instance);
|
||||
instance->lightmap = p_lightmap;
|
||||
}
|
||||
|
||||
if (instance->custom_data) {
|
||||
VSG::scene_render->instance_custom_data_update_lightmap(instance);
|
||||
}
|
||||
}
|
||||
|
||||
void VisualServerScene::instance_set_custom_aabb(RID p_instance, AABB p_aabb) {
|
||||
|
@ -943,10 +921,6 @@ void VisualServerScene::_update_instance(Instance *p_instance) {
|
|||
|
||||
p_instance->transformed_aabb = new_aabb;
|
||||
|
||||
if (p_instance->custom_data) {
|
||||
VSG::scene_render->instance_custom_data_update_transform(p_instance);
|
||||
}
|
||||
|
||||
if (!p_instance->scenario) {
|
||||
|
||||
return;
|
||||
|
@ -1614,12 +1588,12 @@ bool VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
|
|||
//using this one ensures that raster deferred will have it
|
||||
|
||||
static const Vector3 view_normals[6] = {
|
||||
Vector3(-1, 0, 0),
|
||||
Vector3(+1, 0, 0),
|
||||
Vector3(-1, 0, 0),
|
||||
Vector3(0, -1, 0),
|
||||
Vector3(0, +1, 0),
|
||||
Vector3(0, 0, -1),
|
||||
Vector3(0, 0, +1)
|
||||
Vector3(0, 0, +1),
|
||||
Vector3(0, 0, -1)
|
||||
};
|
||||
static const Vector3 view_up[6] = {
|
||||
Vector3(0, -1, 0),
|
||||
|
@ -1920,10 +1894,8 @@ void VisualServerScene::_prepare_scene(const Transform p_cam_transform, const Ca
|
|||
reflection_probe->reflection_dirty = false;
|
||||
}
|
||||
|
||||
if (VSG::scene_render->reflection_probe_instance_has_reflection(reflection_probe->instance)) {
|
||||
reflection_probe_instance_cull_result[reflection_probe_cull_count] = reflection_probe->instance;
|
||||
reflection_probe_cull_count++;
|
||||
}
|
||||
reflection_probe_instance_cull_result[reflection_probe_cull_count] = reflection_probe->instance;
|
||||
reflection_probe_cull_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1970,10 +1942,6 @@ void VisualServerScene::_prepare_scene(const Transform p_cam_transform, const Ca
|
|||
}
|
||||
|
||||
geom->lighting_dirty = false;
|
||||
|
||||
if (ins->custom_data) {
|
||||
VSG::scene_render->instance_custom_data_update_lights(ins);
|
||||
}
|
||||
}
|
||||
|
||||
if (geom->reflection_dirty) {
|
||||
|
@ -1989,10 +1957,6 @@ void VisualServerScene::_prepare_scene(const Transform p_cam_transform, const Ca
|
|||
}
|
||||
|
||||
geom->reflection_dirty = false;
|
||||
|
||||
if (ins->custom_data) {
|
||||
VSG::scene_render->instance_custom_data_update_reflection_probes(ins);
|
||||
}
|
||||
}
|
||||
|
||||
if (geom->gi_probes_dirty) {
|
||||
|
@ -2008,10 +1972,6 @@ void VisualServerScene::_prepare_scene(const Transform p_cam_transform, const Ca
|
|||
}
|
||||
|
||||
geom->gi_probes_dirty = false;
|
||||
|
||||
if (ins->custom_data) {
|
||||
VSG::scene_render->instance_custom_data_update_gi_probes(ins);
|
||||
}
|
||||
}
|
||||
|
||||
ins->depth = near_plane.distance_to(ins->transform.origin);
|
||||
|
@ -2188,7 +2148,7 @@ void VisualServerScene::_render_scene(RID p_render_buffers, const Transform p_ca
|
|||
|
||||
/* PROCESS GEOMETRY AND DRAW SCENE */
|
||||
|
||||
VSG::scene_render->render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_orthogonal, (RasterizerScene::InstanceBase **)instance_cull_result, instance_cull_count, light_instance_cull_result, light_cull_count + directional_light_count, reflection_probe_instance_cull_result, reflection_probe_cull_count, environment, p_shadow_atlas, scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass);
|
||||
VSG::scene_render->render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_orthogonal, (RasterizerScene::InstanceBase **)instance_cull_result, instance_cull_count, light_instance_cull_result, light_cull_count + directional_light_count, reflection_probe_instance_cull_result, reflection_probe_cull_count, environment, p_shadow_atlas, p_reflection_probe, p_reflection_probe_pass);
|
||||
}
|
||||
|
||||
void VisualServerScene::render_empty_scene(RID p_render_buffers, RID p_scenario, RID p_shadow_atlas) {
|
||||
|
@ -2202,7 +2162,7 @@ void VisualServerScene::render_empty_scene(RID p_render_buffers, RID p_scenario,
|
|||
environment = scenario->environment;
|
||||
else
|
||||
environment = scenario->fallback_environment;
|
||||
VSG::scene_render->render_scene(p_render_buffers, Transform(), CameraMatrix(), true, NULL, 0, NULL, 0, NULL, 0, environment, p_shadow_atlas, scenario->reflection_atlas, RID(), 0);
|
||||
VSG::scene_render->render_scene(p_render_buffers, Transform(), CameraMatrix(), true, NULL, 0, NULL, 0, NULL, 0, environment, p_shadow_atlas, RID(), 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -2216,9 +2176,7 @@ bool VisualServerScene::_render_reflection_probe_step(Instance *p_instance, int
|
|||
|
||||
if (p_step == 0) {
|
||||
|
||||
if (!VSG::scene_render->reflection_probe_instance_begin_render(reflection_probe->instance, scenario->reflection_atlas)) {
|
||||
return true; //sorry, all full :(
|
||||
}
|
||||
VSG::scene_render->reflection_probe_instance_begin_render(reflection_probe->instance);
|
||||
}
|
||||
|
||||
if (p_step >= 0 && p_step < 6) {
|
||||
|
@ -3507,7 +3465,6 @@ bool VisualServerScene::free(RID p_rid) {
|
|||
instance_set_scenario(scenario->instances.first()->self()->self, RID());
|
||||
}
|
||||
VSG::scene_render->free(scenario->reflection_probe_shadow_atlas);
|
||||
VSG::scene_render->free(scenario->reflection_atlas);
|
||||
scenario_owner.free(p_rid);
|
||||
memdelete(scenario);
|
||||
|
||||
|
|
|
@ -115,7 +115,6 @@ public:
|
|||
RID environment;
|
||||
RID fallback_environment;
|
||||
RID reflection_probe_shadow_atlas;
|
||||
RID reflection_atlas;
|
||||
|
||||
SelfList<Instance>::List instances;
|
||||
|
||||
|
@ -132,7 +131,6 @@ public:
|
|||
virtual void scenario_set_debug(RID p_scenario, VS::ScenarioDebugMode p_debug_mode);
|
||||
virtual void scenario_set_environment(RID p_scenario, RID p_environment);
|
||||
virtual void scenario_set_fallback_environment(RID p_scenario, RID p_environment);
|
||||
virtual void scenario_set_reflection_atlas_size(RID p_scenario, int p_size, int p_subdiv);
|
||||
|
||||
/* INSTANCING API */
|
||||
|
||||
|
|
|
@ -240,7 +240,6 @@ public:
|
|||
FUNC2(light_set_use_gi, RID, bool)
|
||||
|
||||
FUNC2(light_omni_set_shadow_mode, RID, LightOmniShadowMode)
|
||||
FUNC2(light_omni_set_shadow_detail, RID, LightOmniShadowDetail)
|
||||
|
||||
FUNC2(light_directional_set_shadow_mode, RID, LightDirectionalShadowMode)
|
||||
FUNC2(light_directional_set_blend_splits, RID, bool)
|
||||
|
@ -404,6 +403,8 @@ public:
|
|||
|
||||
FUNC2(viewport_set_debug_draw, RID, ViewportDebugDraw)
|
||||
|
||||
FUNC1(directional_shadow_atlas_set_size, int)
|
||||
|
||||
/* SKY API */
|
||||
|
||||
FUNCRID(sky)
|
||||
|
@ -447,7 +448,6 @@ public:
|
|||
|
||||
FUNC2(scenario_set_debug, RID, ScenarioDebugMode)
|
||||
FUNC2(scenario_set_environment, RID, RID)
|
||||
FUNC3(scenario_set_reflection_atlas_size, RID, int, int)
|
||||
FUNC2(scenario_set_fallback_environment, RID, RID)
|
||||
|
||||
/* INSTANCING API */
|
||||
|
|
|
@ -1694,7 +1694,6 @@ void VisualServer::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("light_set_use_gi", "light", "enabled"), &VisualServer::light_set_use_gi);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("light_omni_set_shadow_mode", "light", "mode"), &VisualServer::light_omni_set_shadow_mode);
|
||||
ClassDB::bind_method(D_METHOD("light_omni_set_shadow_detail", "light", "detail"), &VisualServer::light_omni_set_shadow_detail);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("light_directional_set_shadow_mode", "light", "mode"), &VisualServer::light_directional_set_shadow_mode);
|
||||
ClassDB::bind_method(D_METHOD("light_directional_set_blend_splits", "light", "enable"), &VisualServer::light_directional_set_blend_splits);
|
||||
|
@ -1836,7 +1835,6 @@ void VisualServer::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("scenario_create"), &VisualServer::scenario_create);
|
||||
ClassDB::bind_method(D_METHOD("scenario_set_debug", "scenario", "debug_mode"), &VisualServer::scenario_set_debug);
|
||||
ClassDB::bind_method(D_METHOD("scenario_set_environment", "scenario", "environment"), &VisualServer::scenario_set_environment);
|
||||
ClassDB::bind_method(D_METHOD("scenario_set_reflection_atlas_size", "scenario", "size", "subdiv"), &VisualServer::scenario_set_reflection_atlas_size);
|
||||
ClassDB::bind_method(D_METHOD("scenario_set_fallback_environment", "scenario", "environment"), &VisualServer::scenario_set_fallback_environment);
|
||||
|
||||
#ifndef _3D_DISABLED
|
||||
|
@ -2056,8 +2054,6 @@ void VisualServer::_bind_methods() {
|
|||
|
||||
BIND_ENUM_CONSTANT(LIGHT_OMNI_SHADOW_DUAL_PARABOLOID);
|
||||
BIND_ENUM_CONSTANT(LIGHT_OMNI_SHADOW_CUBE);
|
||||
BIND_ENUM_CONSTANT(LIGHT_OMNI_SHADOW_DETAIL_VERTICAL);
|
||||
BIND_ENUM_CONSTANT(LIGHT_OMNI_SHADOW_DETAIL_HORIZONTAL);
|
||||
|
||||
BIND_ENUM_CONSTANT(LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL);
|
||||
BIND_ENUM_CONSTANT(LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS);
|
||||
|
|
|
@ -432,14 +432,6 @@ public:
|
|||
|
||||
virtual void light_omni_set_shadow_mode(RID p_light, LightOmniShadowMode p_mode) = 0;
|
||||
|
||||
// omni light
|
||||
enum LightOmniShadowDetail {
|
||||
LIGHT_OMNI_SHADOW_DETAIL_VERTICAL,
|
||||
LIGHT_OMNI_SHADOW_DETAIL_HORIZONTAL
|
||||
};
|
||||
|
||||
virtual void light_omni_set_shadow_detail(RID p_light, LightOmniShadowDetail p_detail) = 0;
|
||||
|
||||
// directional light
|
||||
enum LightDirectionalShadowMode {
|
||||
LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL,
|
||||
|
@ -667,12 +659,17 @@ public:
|
|||
enum ViewportDebugDraw {
|
||||
VIEWPORT_DEBUG_DRAW_DISABLED,
|
||||
VIEWPORT_DEBUG_DRAW_UNSHADED,
|
||||
VIEWPORT_DEBUG_DRAW_LIGHTING,
|
||||
VIEWPORT_DEBUG_DRAW_OVERDRAW,
|
||||
VIEWPORT_DEBUG_DRAW_WIREFRAME,
|
||||
VIEWPORT_DEBUG_DRAW_SHADOW_ATLAS
|
||||
|
||||
};
|
||||
|
||||
virtual void viewport_set_debug_draw(RID p_viewport, ViewportDebugDraw p_draw) = 0;
|
||||
|
||||
virtual void directional_shadow_atlas_set_size(int p_size) = 0;
|
||||
|
||||
/* SKY API */
|
||||
|
||||
enum SkyMode {
|
||||
|
@ -792,7 +789,6 @@ public:
|
|||
|
||||
virtual void scenario_set_debug(RID p_scenario, ScenarioDebugMode p_debug_mode) = 0;
|
||||
virtual void scenario_set_environment(RID p_scenario, RID p_environment) = 0;
|
||||
virtual void scenario_set_reflection_atlas_size(RID p_scenario, int p_size, int p_subdiv) = 0;
|
||||
virtual void scenario_set_fallback_environment(RID p_scenario, RID p_environment) = 0;
|
||||
|
||||
/* INSTANCING API */
|
||||
|
@ -1106,7 +1102,6 @@ VARIANT_ENUM_CAST(VisualServer::MultimeshTransformFormat);
|
|||
VARIANT_ENUM_CAST(VisualServer::MultimeshColorFormat);
|
||||
VARIANT_ENUM_CAST(VisualServer::MultimeshCustomDataFormat);
|
||||
VARIANT_ENUM_CAST(VisualServer::LightOmniShadowMode);
|
||||
VARIANT_ENUM_CAST(VisualServer::LightOmniShadowDetail);
|
||||
VARIANT_ENUM_CAST(VisualServer::LightDirectionalShadowMode);
|
||||
VARIANT_ENUM_CAST(VisualServer::LightDirectionalShadowDepthRangeMode);
|
||||
VARIANT_ENUM_CAST(VisualServer::ReflectionProbeUpdateMode);
|
||||
|
|
Loading…
Reference in a new issue