Environment sky more or less working.

This commit is contained in:
Juan Linietsky 2019-08-26 17:43:58 -03:00
parent f7aa7927e7
commit 2d6a916835
35 changed files with 1747 additions and 416 deletions

View file

@ -1775,8 +1775,9 @@ void RasterizerStorageGLES3::sky_set_texture(RID p_sky, RID p_panorama, int p_ra
}
sky->panorama = p_panorama;
if (!sky->panorama.is_valid())
if (!sky->panorama.is_valid()) {
return; //cleared
}
Texture *texture = texture_owner.getornull(sky->panorama);
if (!texture) {

View file

@ -1044,6 +1044,8 @@ bool RenderingDeviceVulkan::format_has_stencil(DataFormat p_format) {
case DATA_FORMAT_D32_SFLOAT_S8_UINT: {
return true;
}
default: {
}
}
return false;
}
@ -1219,7 +1221,7 @@ const VkImageType RenderingDeviceVulkan::vulkan_image_type[RenderingDevice::TEXT
VK_IMAGE_TYPE_2D,
VK_IMAGE_TYPE_1D,
VK_IMAGE_TYPE_2D,
VK_IMAGE_TYPE_3D
VK_IMAGE_TYPE_2D
};
/***************************/
@ -1364,7 +1366,7 @@ Error RenderingDeviceVulkan::_staging_buffer_allocate(uint32_t p_amount, uint32_
} else {
//flush EVERYTHING including setup commands. IF not immediate, also need to flush the draw commands
_flush(true, p_on_draw_command_buffer);
_flush(true);
//clear the whole staging buffer
for (int i = 0; i < staging_buffer_blocks.size(); i++) {
@ -1408,7 +1410,7 @@ Error RenderingDeviceVulkan::_staging_buffer_allocate(uint32_t p_amount, uint32_
continue; //and try again
} else {
_flush(false, false);
_flush(false);
for (int i = 0; i < staging_buffer_blocks.size(); i++) {
//clear all blocks but the ones from this frame
@ -1562,10 +1564,6 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T
image_create_info.mipLevels = p_format.mipmaps;
uint32_t array_layer_multiplier = 1;
if (p_format.type == TEXTURE_TYPE_CUBE_ARRAY || p_format.type == TEXTURE_TYPE_CUBE) {
array_layer_multiplier = 6;
}
if (p_format.type == TEXTURE_TYPE_1D_ARRAY || p_format.type == TEXTURE_TYPE_2D_ARRAY || p_format.type == TEXTURE_TYPE_CUBE_ARRAY || p_format.type == TEXTURE_TYPE_CUBE) {
ERR_FAIL_COND_V_MSG(p_format.array_layers < 1, RID(),
"Amount of layers must be equal or greater than 1 for arrays and cubemaps.");
@ -1576,8 +1574,6 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T
image_create_info.arrayLayers = 1;
}
image_create_info.arrayLayers = p_format.array_layers;
ERR_FAIL_INDEX_V(p_format.samples, TEXTURE_SAMPLES_MAX, RID());
image_create_info.samples = rasterization_sample_count[p_format.samples];
@ -1624,11 +1620,11 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T
ERR_FAIL_COND_V_MSG(!(p_format.usage_bits & TEXTURE_USAGE_CAN_UPDATE_BIT), RID(),
"Texture needs the TEXTURE_USAGE_CAN_UPDATE_BIT usage flag in order to be updated at initialization or later");
int expected_images = image_create_info.arrayLayers * array_layer_multiplier;
int expected_images = image_create_info.arrayLayers;
ERR_FAIL_COND_V_MSG(p_data.size() != expected_images, RID(),
"Default supplied data for image format is of invalid length (" + itos(p_data.size()) + "), should be (" + itos(expected_images) + ").");
for (uint32_t i = 0; i < image_create_info.arrayLayers * array_layer_multiplier; i++) {
for (uint32_t i = 0; i < image_create_info.arrayLayers; i++) {
uint32_t required_size = get_image_format_required_size(p_format.format, image_create_info.extent.width, image_create_info.extent.height, image_create_info.extent.depth, image_create_info.mipLevels);
ERR_FAIL_COND_V_MSG((uint32_t)p_data[i].size() != required_size, RID(),
"Data for slice index " + itos(i) + " (mapped to layer " + itos(i) + ") differs in size (supplied: " + itos(p_data[i].size()) + ") than what is required by the format (" + itos(required_size) + ").");
@ -1789,7 +1785,7 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T
image_view_create_info.subresourceRange.baseMipLevel = 0;
image_view_create_info.subresourceRange.levelCount = image_create_info.mipLevels;
image_view_create_info.subresourceRange.baseArrayLayer = 0;
image_view_create_info.subresourceRange.layerCount = array_layer_multiplier * image_create_info.arrayLayers;
image_view_create_info.subresourceRange.layerCount = image_create_info.arrayLayers;
if (p_format.usage_bits & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
} else {
@ -1819,7 +1815,7 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T
image_memory_barrier.subresourceRange.baseMipLevel = 0;
image_memory_barrier.subresourceRange.levelCount = image_create_info.mipLevels;
image_memory_barrier.subresourceRange.baseArrayLayer = 0;
image_memory_barrier.subresourceRange.layerCount = image_create_info.arrayLayers * array_layer_multiplier;
image_memory_barrier.subresourceRange.layerCount = image_create_info.arrayLayers;
vkCmdPipelineBarrier(frames[frame].setup_command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, NULL, 0, NULL, 1, &image_memory_barrier);
}
@ -1850,11 +1846,6 @@ RID RenderingDeviceVulkan::texture_create_shared(const TextureView &p_view, RID
Texture texture = *src_texture;
uint32_t array_layer_multiplier = 1;
if (texture.type == TEXTURE_TYPE_CUBE_ARRAY || texture.type == TEXTURE_TYPE_CUBE) {
array_layer_multiplier = 6;
}
VkImageViewCreateInfo image_view_create_info;
image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
image_view_create_info.pNext = NULL;
@ -1899,7 +1890,7 @@ RID RenderingDeviceVulkan::texture_create_shared(const TextureView &p_view, RID
image_view_create_info.subresourceRange.baseMipLevel = 0;
image_view_create_info.subresourceRange.levelCount = texture.mipmaps;
image_view_create_info.subresourceRange.layerCount = array_layer_multiplier * texture.layers;
image_view_create_info.subresourceRange.layerCount = texture.layers;
image_view_create_info.subresourceRange.baseArrayLayer = 0;
if (texture.usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
@ -1921,7 +1912,7 @@ RID RenderingDeviceVulkan::texture_create_shared(const TextureView &p_view, RID
return id;
}
RID RenderingDeviceVulkan::texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap) {
RID RenderingDeviceVulkan::texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, TextureSliceType p_slice_type) {
Texture *src_texture = texture_owner.getornull(p_with_texture);
ERR_FAIL_COND_V(!src_texture, RID());
@ -1932,20 +1923,18 @@ RID RenderingDeviceVulkan::texture_create_shared_from_slice(const TextureView &p
ERR_FAIL_COND_V(!src_texture, RID()); //this is a bug
}
ERR_FAIL_COND_V_MSG(p_slice_type == TEXTURE_SLICE_CUBEMAP && (src_texture->type != TEXTURE_TYPE_CUBE && src_texture->type != TEXTURE_TYPE_CUBE_ARRAY), RID(),
"Can only create a cubemap slice from a cubemap or cubemap array mipmap");
//create view
ERR_FAIL_INDEX_V(p_mipmap, src_texture->mipmaps, RID());
uint32_t array_layer_multiplier = 1;
if (src_texture->type == TEXTURE_TYPE_CUBE_ARRAY || src_texture->type == TEXTURE_TYPE_CUBE) {
array_layer_multiplier = 6;
}
ERR_FAIL_INDEX_V(p_layer, src_texture->layers * array_layer_multiplier, RID());
ERR_FAIL_INDEX_V(p_layer, src_texture->layers, RID());
Texture texture = *src_texture;
get_image_format_required_size(texture.format, texture.width, texture.height, texture.depth, p_mipmap + 1, &texture.width, &texture.height);
texture.mipmaps = 1;
texture.layers = 1;
texture.layers = p_slice_type == TEXTURE_SLICE_CUBEMAP ? 6 : 1;
VkImageViewCreateInfo image_view_create_info;
image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
@ -1963,7 +1952,7 @@ RID RenderingDeviceVulkan::texture_create_shared_from_slice(const TextureView &p
VK_IMAGE_VIEW_TYPE_2D,
};
image_view_create_info.viewType = view_types[texture.type];
image_view_create_info.viewType = p_slice_type == TEXTURE_SLICE_CUBEMAP ? VK_IMAGE_VIEW_TYPE_CUBE : view_types[texture.type];
if (p_view.format_override == DATA_FORMAT_MAX || p_view.format_override == texture.format) {
image_view_create_info.format = vulkan_formats[texture.format];
} else {
@ -1989,9 +1978,15 @@ RID RenderingDeviceVulkan::texture_create_shared_from_slice(const TextureView &p
image_view_create_info.components.b = component_swizzles[p_view.swizzle_b];
image_view_create_info.components.a = component_swizzles[p_view.swizzle_a];
if (p_slice_type == TEXTURE_SLICE_CUBEMAP) {
ERR_FAIL_COND_V_MSG(p_layer >= src_texture->layers, RID(),
"Specified layer is invalid for cubemap");
ERR_FAIL_COND_V_MSG((p_layer % 6) != 0, RID(),
"Specified layer must be a multiple of 6.");
}
image_view_create_info.subresourceRange.baseMipLevel = p_mipmap;
image_view_create_info.subresourceRange.levelCount = 1;
image_view_create_info.subresourceRange.layerCount = 1;
image_view_create_info.subresourceRange.layerCount = p_slice_type == TEXTURE_SLICE_CUBEMAP ? 6 : 1;
image_view_create_info.subresourceRange.baseArrayLayer = p_layer;
if (texture.usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
@ -2469,7 +2464,7 @@ PoolVector<uint8_t> RenderingDeviceVulkan::texture_get_data(RID p_texture, uint3
}
//flush everything so memory can be safely mapped
_flush(true, false);
_flush(true);
PoolVector<uint8_t> ret = _texture_get_data_from_image(tex, image, allocation, p_layer);
vmaDestroyImage(allocator, image, allocation);
@ -4555,7 +4550,7 @@ PoolVector<uint8_t> RenderingDeviceVulkan::buffer_get_data(RID p_buffer) {
region.size = buffer->size;
vkCmdCopyBuffer(command_buffer, buffer->buffer, tmp_buffer.buffer, 1, &region); //dst buffer is in CPU, but I wonder if src buffer needs a barrier for this..
//flush everything so memory can be safely mapped
_flush(true, false);
_flush(true);
void *buffer_mem;
VkResult vkerr = vmaMapMemory(allocator, tmp_buffer.allocation, &buffer_mem);
@ -4571,6 +4566,8 @@ PoolVector<uint8_t> RenderingDeviceVulkan::buffer_get_data(RID p_buffer) {
copymem(w.ptr(), buffer_mem, buffer->size);
}
vmaUnmapMemory(allocator, tmp_buffer.allocation);
_buffer_free(&tmp_buffer);
return buffer_data;
@ -6041,18 +6038,16 @@ void RenderingDeviceVulkan::advance_frame() {
}
}
void RenderingDeviceVulkan::_flush(bool p_setup, bool p_draw) {
void RenderingDeviceVulkan::_flush(bool p_current_frame) {
//not doing this crashes RADV (undefined behavior)
if (p_setup) {
if (p_current_frame) {
vkEndCommandBuffer(frames[frame].setup_command_buffer);
}
if (p_draw) {
vkEndCommandBuffer(frames[frame].draw_command_buffer);
}
context->flush(p_setup, p_draw);
context->flush(p_current_frame, p_current_frame);
//re-create the setup command
if (p_setup) {
if (p_current_frame) {
VkCommandBufferBeginInfo cmdbuf_begin;
cmdbuf_begin.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
cmdbuf_begin.pNext = NULL;
@ -6064,7 +6059,7 @@ void RenderingDeviceVulkan::_flush(bool p_setup, bool p_draw) {
context->set_setup_buffer(frames[frame].setup_command_buffer); //append now so it's added before everything else
}
if (p_draw) {
if (p_current_frame) {
VkCommandBufferBeginInfo cmdbuf_begin;
cmdbuf_begin.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
cmdbuf_begin.pNext = NULL;
@ -6232,7 +6227,7 @@ void RenderingDeviceVulkan::finalize() {
//free all resources
_flush(false, false);
_flush(false);
_free_rids(pipeline_owner, "Pipeline");
_free_rids(uniform_set_owner, "UniformSet");

View file

@ -840,7 +840,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
VulkanContext *context;
void _free_internal(RID p_id);
void _flush(bool p_setup, bool p_draw);
void _flush(bool p_current_frame);
bool screen_prepared;
@ -850,7 +850,8 @@ class RenderingDeviceVulkan : public RenderingDevice {
public:
virtual RID texture_create(const TextureFormat &p_format, const TextureView &p_view, const Vector<PoolVector<uint8_t> > &p_data = Vector<PoolVector<uint8_t> >());
virtual RID texture_create_shared(const TextureView &p_view, RID p_with_texture);
virtual RID texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap);
virtual RID texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, TextureSliceType p_slice_type = TEXTURE_SLICE_2D);
virtual Error texture_update(RID p_texture, uint32_t p_layer, const PoolVector<uint8_t> &p_data, bool p_sync_with_draw = false);
virtual PoolVector<uint8_t> texture_get_data(RID p_texture, uint32_t p_layer);

View file

@ -923,13 +923,11 @@ Error VulkanContext::_update_swap_chain(Window *window) {
/*b*/ VK_COMPONENT_SWIZZLE_B,
/*a*/ VK_COMPONENT_SWIZZLE_A,
},
/*subresourceRange*/ {
/*aspectMask*/ VK_IMAGE_ASPECT_COLOR_BIT,
/*baseMipLevel*/ 0,
/*levelCount*/ 1,
/*baseArrayLayer*/ 0,
/*layerCount*/ 1
},
/*subresourceRange*/ { /*aspectMask*/ VK_IMAGE_ASPECT_COLOR_BIT,
/*baseMipLevel*/ 0,
/*levelCount*/ 1,
/*baseArrayLayer*/ 0,
/*layerCount*/ 1 },
};
window->swapchain_image_resources[i].image = swapchainImages[i];

View file

@ -225,7 +225,9 @@ EditorInspectorPluginMaterial::EditorInspectorPluginMaterial() {
env.instance();
Ref<ProceduralSky> proc_sky = memnew(ProceduralSky(true));
env->set_sky(proc_sky);
env->set_background(Environment::BG_COLOR_SKY);
env->set_background(Environment::BG_COLOR);
env->set_ambient_source(Environment::AMBIENT_SOURCE_SKY);
env->set_reflection_source(Environment::REFLECTION_SOURCE_SKY);
}
MaterialEditorPlugin::MaterialEditorPlugin(EditorNode *p_node) {

View file

@ -61,25 +61,6 @@ void Environment::set_sky_custom_fov(float p_scale) {
bg_sky_custom_fov = p_scale;
VS::get_singleton()->environment_set_sky_custom_fov(environment, p_scale);
}
void Environment::set_sky_orientation(const Basis &p_orientation) {
bg_sky_orientation = p_orientation;
_change_notify("background_sky_rotation");
_change_notify("background_sky_rotation_degrees");
VS::get_singleton()->environment_set_sky_orientation(environment, bg_sky_orientation);
}
void Environment::set_sky_rotation(const Vector3 &p_euler_rad) {
bg_sky_orientation.set_euler(p_euler_rad);
_change_notify("background_sky_orientation");
_change_notify("background_sky_rotation_degrees");
VS::get_singleton()->environment_set_sky_orientation(environment, bg_sky_orientation);
}
void Environment::set_sky_rotation_degrees(const Vector3 &p_euler_deg) {
set_sky_rotation(p_euler_deg * Math_PI / 180.0);
_change_notify("background_sky_rotation");
}
void Environment::set_bg_color(const Color &p_color) {
bg_color = p_color;
@ -98,17 +79,17 @@ void Environment::set_canvas_max_layer(int p_max_layer) {
void Environment::set_ambient_light_color(const Color &p_color) {
ambient_color = p_color;
VS::get_singleton()->environment_set_ambient_light(environment, ambient_color, ambient_energy, ambient_sky_contribution);
VS::get_singleton()->environment_set_ambient_light(environment, ambient_color, VS::EnvironmentAmbientSource(ambient_source), ambient_energy, ambient_sky_contribution, VS::EnvironmentReflectionSource(reflection_source));
}
void Environment::set_ambient_light_energy(float p_energy) {
ambient_energy = p_energy;
VS::get_singleton()->environment_set_ambient_light(environment, ambient_color, ambient_energy, ambient_sky_contribution);
VS::get_singleton()->environment_set_ambient_light(environment, ambient_color, VS::EnvironmentAmbientSource(ambient_source), ambient_energy, ambient_sky_contribution, VS::EnvironmentReflectionSource(reflection_source));
}
void Environment::set_ambient_light_sky_contribution(float p_energy) {
ambient_sky_contribution = p_energy;
VS::get_singleton()->environment_set_ambient_light(environment, ambient_color, ambient_energy, ambient_sky_contribution);
VS::get_singleton()->environment_set_ambient_light(environment, ambient_color, VS::EnvironmentAmbientSource(ambient_source), ambient_energy, ambient_sky_contribution, VS::EnvironmentReflectionSource(reflection_source));
}
void Environment::set_camera_feed_id(int p_camera_feed_id) {
@ -119,6 +100,22 @@ void Environment::set_camera_feed_id(int p_camera_feed_id) {
#endif
};
void Environment::set_ambient_source(AmbientSource p_source) {
ambient_source = p_source;
VS::get_singleton()->environment_set_ambient_light(environment, ambient_color, VS::EnvironmentAmbientSource(ambient_source), ambient_energy, ambient_sky_contribution, VS::EnvironmentReflectionSource(reflection_source));
}
Environment::AmbientSource Environment::get_ambient_source() const {
return ambient_source;
}
void Environment::set_reflection_source(ReflectionSource p_source) {
reflection_source = p_source;
VS::get_singleton()->environment_set_ambient_light(environment, ambient_color, VS::EnvironmentAmbientSource(ambient_source), ambient_energy, ambient_sky_contribution, VS::EnvironmentReflectionSource(reflection_source));
}
Environment::ReflectionSource Environment::get_reflection_source() const {
return reflection_source;
}
Environment::BGMode Environment::get_background() const {
return bg_mode;
@ -133,20 +130,14 @@ float Environment::get_sky_custom_fov() const {
return bg_sky_custom_fov;
}
Basis Environment::get_sky_orientation() const {
return bg_sky_orientation;
void Environment::set_sky_rotation(const Vector3 &p_rotation) {
sky_rotation = p_rotation;
VS::get_singleton()->environment_set_sky_orientation(environment, Basis(p_rotation));
}
Vector3 Environment::get_sky_rotation() const {
// should we cache this? maybe overkill
return bg_sky_orientation.get_euler();
}
Vector3 Environment::get_sky_rotation_degrees() const {
return get_sky_rotation() * 180.0 / Math_PI;
return sky_rotation;
}
Color Environment::get_bg_color() const {
@ -315,14 +306,14 @@ Ref<Texture2D> Environment::get_adjustment_color_correction() const {
void Environment::_validate_property(PropertyInfo &property) const {
if (property.name == "background_sky" || property.name == "background_sky_custom_fov" || property.name == "background_sky_orientation" || property.name == "background_sky_rotation" || property.name == "background_sky_rotation_degrees" || property.name == "ambient_light/sky_contribution") {
if (bg_mode != BG_SKY && bg_mode != BG_COLOR_SKY) {
if (property.name == "sky" || property.name == "sky_custom_fov" || property.name == "sky_rotation" || property.name == "ambient_light/sky_contribution") {
if (bg_mode != BG_SKY && ambient_source != AMBIENT_SOURCE_SKY && reflection_source != REFLECTION_SOURCE_SKY) {
property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL;
}
}
if (property.name == "background_color") {
if (bg_mode != BG_COLOR && bg_mode != BG_COLOR_SKY) {
if (bg_mode != BG_COLOR && ambient_source != AMBIENT_SOURCE_COLOR) {
property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL;
}
}
@ -951,9 +942,7 @@ void Environment::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_background", "mode"), &Environment::set_background);
ClassDB::bind_method(D_METHOD("set_sky", "sky"), &Environment::set_sky);
ClassDB::bind_method(D_METHOD("set_sky_custom_fov", "scale"), &Environment::set_sky_custom_fov);
ClassDB::bind_method(D_METHOD("set_sky_orientation", "orientation"), &Environment::set_sky_orientation);
ClassDB::bind_method(D_METHOD("set_sky_rotation", "euler_radians"), &Environment::set_sky_rotation);
ClassDB::bind_method(D_METHOD("set_sky_rotation_degrees", "euler_degrees"), &Environment::set_sky_rotation_degrees);
ClassDB::bind_method(D_METHOD("set_bg_color", "color"), &Environment::set_bg_color);
ClassDB::bind_method(D_METHOD("set_bg_energy", "energy"), &Environment::set_bg_energy);
ClassDB::bind_method(D_METHOD("set_canvas_max_layer", "layer"), &Environment::set_canvas_max_layer);
@ -961,13 +950,13 @@ void Environment::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_ambient_light_energy", "energy"), &Environment::set_ambient_light_energy);
ClassDB::bind_method(D_METHOD("set_ambient_light_sky_contribution", "energy"), &Environment::set_ambient_light_sky_contribution);
ClassDB::bind_method(D_METHOD("set_camera_feed_id", "camera_feed_id"), &Environment::set_camera_feed_id);
ClassDB::bind_method(D_METHOD("set_ambient_source", "source"), &Environment::set_ambient_source);
ClassDB::bind_method(D_METHOD("set_reflection_source", "source"), &Environment::set_reflection_source);
ClassDB::bind_method(D_METHOD("get_background"), &Environment::get_background);
ClassDB::bind_method(D_METHOD("get_sky"), &Environment::get_sky);
ClassDB::bind_method(D_METHOD("get_sky_custom_fov"), &Environment::get_sky_custom_fov);
ClassDB::bind_method(D_METHOD("get_sky_orientation"), &Environment::get_sky_orientation);
ClassDB::bind_method(D_METHOD("get_sky_rotation"), &Environment::get_sky_rotation);
ClassDB::bind_method(D_METHOD("get_sky_rotation_degrees"), &Environment::get_sky_rotation_degrees);
ClassDB::bind_method(D_METHOD("get_bg_color"), &Environment::get_bg_color);
ClassDB::bind_method(D_METHOD("get_bg_energy"), &Environment::get_bg_energy);
ClassDB::bind_method(D_METHOD("get_canvas_max_layer"), &Environment::get_canvas_max_layer);
@ -975,24 +964,26 @@ void Environment::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_ambient_light_energy"), &Environment::get_ambient_light_energy);
ClassDB::bind_method(D_METHOD("get_ambient_light_sky_contribution"), &Environment::get_ambient_light_sky_contribution);
ClassDB::bind_method(D_METHOD("get_camera_feed_id"), &Environment::get_camera_feed_id);
ClassDB::bind_method(D_METHOD("get_ambient_source"), &Environment::get_ambient_source);
ClassDB::bind_method(D_METHOD("get_reflection_source"), &Environment::get_reflection_source);
ADD_GROUP("Background", "background_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "background_mode", PROPERTY_HINT_ENUM, "Clear Color,Custom Color,Sky,Color+Sky,Canvas,Keep,Camera Feed"), "set_background", "get_background");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "background_sky", PROPERTY_HINT_RESOURCE_TYPE, "Sky"), "set_sky", "get_sky");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "background_sky_custom_fov", PROPERTY_HINT_RANGE, "0,180,0.1"), "set_sky_custom_fov", "get_sky_custom_fov");
ADD_PROPERTY(PropertyInfo(Variant::BASIS, "background_sky_orientation"), "set_sky_orientation", "get_sky_orientation");
// Only display rotation in degrees in the inspector (like in Spatial).
// This avoids displaying the same information twice.
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "background_sky_rotation", PROPERTY_HINT_NONE, "", 0), "set_sky_rotation", "get_sky_rotation");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "background_sky_rotation_degrees", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_sky_rotation_degrees", "get_sky_rotation_degrees");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "background_color"), "set_bg_color", "get_bg_color");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "background_energy", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_bg_energy", "get_bg_energy");
ADD_PROPERTY(PropertyInfo(Variant::INT, "background_mode", PROPERTY_HINT_ENUM, "Clear Color,Custom Color,Sky,Canvas,Keep,Camera Feed"), "set_background", "get_background");
ADD_PROPERTY(PropertyInfo(Variant::INT, "background_canvas_max_layer", PROPERTY_HINT_RANGE, "-1000,1000,1"), "set_canvas_max_layer", "get_canvas_max_layer");
ADD_PROPERTY(PropertyInfo(Variant::INT, "background_camera_feed_id", PROPERTY_HINT_RANGE, "1,10,1"), "set_camera_feed_id", "get_camera_feed_id");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "background_color"), "set_bg_color", "get_bg_color");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "background_energy", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_bg_energy", "get_bg_energy");
ADD_GROUP("Sky", "sky_");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "sky", PROPERTY_HINT_RESOURCE_TYPE, "Sky"), "set_sky", "get_sky");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "sky_custom_fov", PROPERTY_HINT_RANGE, "0,180,0.1"), "set_sky_custom_fov", "get_sky_custom_fov");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "sky_rotation"), "set_sky_rotation", "get_sky_rotation");
ADD_GROUP("Ambient Light", "ambient_light_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "ambient_light_source", PROPERTY_HINT_ENUM, "Background,Disabled,Color,Sky"), "set_ambient_source", "get_ambient_source");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ambient_light_color"), "set_ambient_light_color", "get_ambient_light_color");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "ambient_light_energy", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_ambient_light_energy", "get_ambient_light_energy");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "ambient_light_sky_contribution", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_ambient_light_sky_contribution", "get_ambient_light_sky_contribution");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "ambient_light_energy", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_ambient_light_energy", "get_ambient_light_energy");
ADD_GROUP("Reflected Light", "reflected_light_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "reflected_light_source", PROPERTY_HINT_ENUM, "Background,Disabled,Sky"), "set_reflection_source", "get_reflection_source");
ClassDB::bind_method(D_METHOD("set_fog_enabled", "enabled"), &Environment::set_fog_enabled);
ClassDB::bind_method(D_METHOD("is_fog_enabled"), &Environment::is_fog_enabled);
@ -1282,11 +1273,19 @@ void Environment::_bind_methods() {
BIND_ENUM_CONSTANT(BG_CLEAR_COLOR);
BIND_ENUM_CONSTANT(BG_COLOR);
BIND_ENUM_CONSTANT(BG_SKY);
BIND_ENUM_CONSTANT(BG_COLOR_SKY);
BIND_ENUM_CONSTANT(BG_CANVAS);
BIND_ENUM_CONSTANT(BG_CAMERA_FEED);
BIND_ENUM_CONSTANT(BG_MAX);
BIND_ENUM_CONSTANT(AMBIENT_SOURCE_BG);
BIND_ENUM_CONSTANT(AMBIENT_SOURCE_DISABLED);
BIND_ENUM_CONSTANT(AMBIENT_SOURCE_COLOR);
BIND_ENUM_CONSTANT(AMBIENT_SOURCE_SKY);
BIND_ENUM_CONSTANT(REFLECTION_SOURCE_BG);
BIND_ENUM_CONSTANT(REFLECTION_SOURCE_DISABLED);
BIND_ENUM_CONSTANT(REFLECTION_SOURCE_SKY);
BIND_ENUM_CONSTANT(GLOW_BLEND_MODE_ADDITIVE);
BIND_ENUM_CONSTANT(GLOW_BLEND_MODE_SCREEN);
BIND_ENUM_CONSTANT(GLOW_BLEND_MODE_SOFTLIGHT);
@ -1324,11 +1323,12 @@ Environment::Environment() :
bg_mode = BG_CLEAR_COLOR;
bg_sky_custom_fov = 0;
bg_sky_orientation = Basis();
bg_energy = 1.0;
bg_canvas_max_layer = 0;
ambient_energy = 1.0;
//ambient_sky_contribution = 1.0;
ambient_source = AMBIENT_SOURCE_BG;
reflection_source = REFLECTION_SOURCE_BG;
set_ambient_light_sky_contribution(1.0);
set_camera_feed_id(1);

View file

@ -46,13 +46,25 @@ public:
BG_CLEAR_COLOR,
BG_COLOR,
BG_SKY,
BG_COLOR_SKY,
BG_CANVAS,
BG_KEEP,
BG_CAMERA_FEED,
BG_MAX
};
enum AmbientSource {
AMBIENT_SOURCE_BG,
AMBIENT_SOURCE_DISABLED,
AMBIENT_SOURCE_COLOR,
AMBIENT_SOURCE_SKY,
};
enum ReflectionSource {
REFLECTION_SOURCE_BG,
REFLECTION_SOURCE_DISABLED,
REFLECTION_SOURCE_SKY,
};
enum ToneMapper {
TONE_MAPPER_LINEAR,
TONE_MAPPER_REINHARDT,
@ -92,7 +104,7 @@ private:
BGMode bg_mode;
Ref<Sky> bg_sky;
float bg_sky_custom_fov;
Basis bg_sky_orientation;
Vector3 sky_rotation;
Color bg_color;
float bg_energy;
int bg_canvas_max_layer;
@ -100,6 +112,8 @@ private:
float ambient_energy;
float ambient_sky_contribution;
int camera_feed_id;
AmbientSource ambient_source;
ReflectionSource reflection_source;
ToneMapper tone_mapper;
float tonemap_exposure;
@ -183,11 +197,10 @@ protected:
public:
void set_background(BGMode p_bg);
void set_sky(const Ref<Sky> &p_sky);
void set_sky_custom_fov(float p_scale);
void set_sky_orientation(const Basis &p_orientation);
void set_sky_rotation(const Vector3 &p_euler_rad);
void set_sky_rotation_degrees(const Vector3 &p_euler_deg);
void set_sky_rotation(const Vector3 &p_rotation);
void set_bg_color(const Color &p_color);
void set_bg_energy(float p_energy);
void set_canvas_max_layer(int p_max_layer);
@ -195,13 +208,15 @@ public:
void set_ambient_light_energy(float p_energy);
void set_ambient_light_sky_contribution(float p_energy);
void set_camera_feed_id(int p_camera_feed_id);
void set_ambient_source(AmbientSource p_source);
AmbientSource get_ambient_source() const;
void set_reflection_source(ReflectionSource p_source);
ReflectionSource get_reflection_source() const;
BGMode get_background() const;
Ref<Sky> get_sky() const;
float get_sky_custom_fov() const;
Basis get_sky_orientation() const;
Vector3 get_sky_rotation() const;
Vector3 get_sky_rotation_degrees() const;
Color get_bg_color() const;
float get_bg_energy() const;
int get_canvas_max_layer() const;
@ -412,6 +427,8 @@ public:
};
VARIANT_ENUM_CAST(Environment::BGMode)
VARIANT_ENUM_CAST(Environment::AmbientSource)
VARIANT_ENUM_CAST(Environment::ReflectionSource)
VARIANT_ENUM_CAST(Environment::ToneMapper)
VARIANT_ENUM_CAST(Environment::GlowBlendMode)
VARIANT_ENUM_CAST(Environment::DOFBlurQuality)

View file

@ -461,7 +461,7 @@ void SpatialMaterial::_update_shader() {
code += ",unshaded";
}
if (flags[FLAG_DISABLE_DEPTH_TEST]) {
code += ",depth_test_disable";
code += ",depth_test_disabled";
}
if (flags[FLAG_USE_VERTEX_LIGHTING]) {
code += ",vertex_lighting";

View file

@ -36,7 +36,10 @@ void Sky::set_radiance_size(RadianceSize p_size) {
ERR_FAIL_INDEX(p_size, RADIANCE_SIZE_MAX);
radiance_size = p_size;
_radiance_changed();
static const int size[RADIANCE_SIZE_MAX] = {
32, 64, 128, 256, 512, 1024, 2048
};
VS::get_singleton()->sky_set_radiance_size(sky, size[radiance_size]);
}
Sky::RadianceSize Sky::get_radiance_size() const {
@ -44,12 +47,30 @@ Sky::RadianceSize Sky::get_radiance_size() const {
return radiance_size;
}
void Sky::set_process_mode(ProcessMode p_mode) {
mode = p_mode;
VS::get_singleton()->sky_set_mode(sky, VS::SkyMode(mode));
}
Sky::ProcessMode Sky::get_process_mode() const {
return mode;
}
RID Sky::get_rid() const {
return sky;
}
void Sky::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_radiance_size", "size"), &Sky::set_radiance_size);
ClassDB::bind_method(D_METHOD("get_radiance_size"), &Sky::get_radiance_size);
ClassDB::bind_method(D_METHOD("set_process_mode", "mode"), &Sky::set_process_mode);
ClassDB::bind_method(D_METHOD("get_process_mode"), &Sky::get_process_mode);
ADD_PROPERTY(PropertyInfo(Variant::INT, "radiance_size", PROPERTY_HINT_ENUM, "32,64,128,256,512,1024,2048"), "set_radiance_size", "get_radiance_size");
ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "HighQuality,RealTime"), "set_process_mode", "get_process_mode");
BIND_ENUM_CONSTANT(RADIANCE_SIZE_32);
BIND_ENUM_CONSTANT(RADIANCE_SIZE_64);
@ -59,35 +80,30 @@ void Sky::_bind_methods() {
BIND_ENUM_CONSTANT(RADIANCE_SIZE_1024);
BIND_ENUM_CONSTANT(RADIANCE_SIZE_2048);
BIND_ENUM_CONSTANT(RADIANCE_SIZE_MAX);
BIND_ENUM_CONSTANT(PROCESS_MODE_QUALITY);
BIND_ENUM_CONSTANT(PROCESS_MODE_REALTIME);
}
Sky::Sky() {
mode = PROCESS_MODE_QUALITY;
radiance_size = RADIANCE_SIZE_128;
sky = VS::get_singleton()->sky_create();
}
Sky::~Sky() {
VS::get_singleton()->free(sky);
}
/////////////////////////////////////////
void PanoramaSky::_radiance_changed() {
if (panorama.is_valid()) {
static const int size[RADIANCE_SIZE_MAX] = {
32, 64, 128, 256, 512, 1024, 2048
};
VS::get_singleton()->sky_set_texture(sky, panorama->get_rid(), size[get_radiance_size()]);
}
}
void PanoramaSky::set_panorama(const Ref<Texture2D> &p_panorama) {
panorama = p_panorama;
if (panorama.is_valid()) {
_radiance_changed();
} else {
VS::get_singleton()->sky_set_texture(sky, RID(), 0);
}
RID rid = p_panorama.is_valid() ? p_panorama->get_rid() : RID();
VS::get_singleton()->sky_set_texture(get_rid(), rid);
}
Ref<Texture2D> PanoramaSky::get_panorama() const {
@ -95,11 +111,6 @@ Ref<Texture2D> PanoramaSky::get_panorama() const {
return panorama;
}
RID PanoramaSky::get_rid() const {
return sky;
}
void PanoramaSky::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_panorama", "texture"), &PanoramaSky::set_panorama);
@ -109,27 +120,12 @@ void PanoramaSky::_bind_methods() {
}
PanoramaSky::PanoramaSky() {
sky = VS::get_singleton()->sky_create();
}
PanoramaSky::~PanoramaSky() {
VS::get_singleton()->free(sky);
}
//////////////////////////////////
void ProceduralSky::_radiance_changed() {
if (update_queued)
return; //do nothing yet
static const int size[RADIANCE_SIZE_MAX] = {
32, 64, 128, 256, 512, 1024, 2048
};
VS::get_singleton()->sky_set_texture(sky, texture, size[get_radiance_size()]);
}
Ref<Image> ProceduralSky::_generate_sky() {
update_queued = false;
@ -390,10 +386,6 @@ ProceduralSky::TextureSize ProceduralSky::get_texture_size() const {
return texture_size;
}
RID ProceduralSky::get_rid() const {
return sky;
}
void ProceduralSky::_update_sky() {
bool use_thread = true;
@ -421,7 +413,7 @@ void ProceduralSky::_update_sky() {
} else {
texture = VS::get_singleton()->texture_2d_create(image);
}
_radiance_changed();
VS::get_singleton()->sky_set_texture(get_rid(), texture);
}
}
@ -443,7 +435,8 @@ void ProceduralSky::_thread_done(const Ref<Image> &p_image) {
texture = VS::get_singleton()->texture_2d_create(p_image);
}
_radiance_changed();
VS::get_singleton()->sky_set_texture(get_rid(), texture);
Thread::wait_to_finish(sky_thread);
memdelete(sky_thread);
sky_thread = NULL;
@ -547,8 +540,6 @@ void ProceduralSky::_bind_methods() {
ProceduralSky::ProceduralSky(bool p_desaturate) {
sky = VS::get_singleton()->sky_create();
update_queued = false;
sky_top_color = Color::hex(0xa5d6f1ff);
sky_horizon_color = Color::hex(0xd6eafaff);
@ -589,7 +580,6 @@ ProceduralSky::~ProceduralSky() {
memdelete(sky_thread);
sky_thread = NULL;
}
VS::get_singleton()->free(sky);
if (texture.is_valid()) {
VS::get_singleton()->free(texture);
}

View file

@ -49,38 +49,48 @@ public:
RADIANCE_SIZE_MAX
};
enum ProcessMode {
PROCESS_MODE_QUALITY,
PROCESS_MODE_REALTIME
};
private:
RID sky;
ProcessMode mode;
RadianceSize radiance_size;
protected:
static void _bind_methods();
virtual void _radiance_changed() = 0;
public:
void set_radiance_size(RadianceSize p_size);
RadianceSize get_radiance_size() const;
void set_process_mode(ProcessMode p_mode);
ProcessMode get_process_mode() const;
virtual RID get_rid() const;
Sky();
~Sky();
};
VARIANT_ENUM_CAST(Sky::RadianceSize)
VARIANT_ENUM_CAST(Sky::ProcessMode)
class PanoramaSky : public Sky {
GDCLASS(PanoramaSky, Sky);
private:
RID sky;
Ref<Texture2D> panorama;
protected:
static void _bind_methods();
virtual void _radiance_changed();
public:
void set_panorama(const Ref<Texture2D> &p_panorama);
Ref<Texture2D> get_panorama() const;
virtual RID get_rid() const;
PanoramaSky();
~PanoramaSky();
};
@ -120,7 +130,6 @@ private:
TextureSize texture_size;
RID sky;
RID texture;
bool update_queued;
@ -133,7 +142,6 @@ private:
protected:
static void _bind_methods();
virtual void _radiance_changed();
Ref<Image> _generate_sky();
void _update_sky();
@ -189,8 +197,6 @@ public:
void set_texture_size(TextureSize p_size);
TextureSize get_texture_size() const;
virtual RID get_rid() const;
ProceduralSky(bool p_desaturate = false);
~ProceduralSky();
};

View file

@ -49,6 +49,13 @@ public:
virtual int get_directional_light_shadow_size(RID p_light_intance) = 0;
virtual void set_directional_shadow_count(int p_count) = 0;
/* SKY API */
virtual RID sky_create() = 0;
virtual void sky_set_radiance_size(RID p_sky, int p_radiance_size) = 0;
virtual void sky_set_mode(RID p_sky, VS::SkyMode p_samples) = 0;
virtual void sky_set_texture(RID p_sky, RID p_panorama) = 0;
/* ENVIRONMENT API */
virtual RID environment_create() = 0;
@ -60,7 +67,7 @@ public:
virtual void environment_set_bg_color(RID p_env, const Color &p_color) = 0;
virtual void environment_set_bg_energy(RID p_env, float p_energy) = 0;
virtual void environment_set_canvas_max_layer(RID p_env, int p_max_layer) = 0;
virtual void environment_set_ambient_light(RID p_env, const Color &p_color, float p_energy = 1.0, float p_sky_contribution = 0.0) = 0;
virtual void environment_set_ambient_light(RID p_env, const Color &p_color, VS::EnvironmentAmbientSource p_ambient = VS::ENV_AMBIENT_SOURCE_BG, float p_energy = 1.0, float p_sky_contribution = 0.0, VS::EnvironmentReflectionSource p_reflection_source = VS::ENV_REFLECTION_SOURCE_BG) = 0;
// FIXME: Disabled during Vulkan refactoring, should be ported.
#if 0
virtual void environment_set_camera_feed_id(RID p_env, int p_camera_feed_id) = 0;
@ -82,9 +89,9 @@ public:
virtual 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) = 0;
virtual void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve) = 0;
virtual bool is_environment(RID p_env) = 0;
virtual VS::EnvironmentBG environment_get_background(RID p_env) = 0;
virtual int environment_get_canvas_max_layer(RID p_env) = 0;
virtual bool is_environment(RID p_env) const = 0;
virtual VS::EnvironmentBG environment_get_background(RID p_env) const = 0;
virtual int environment_get_canvas_max_layer(RID p_env) const = 0;
struct InstanceBase;
@ -258,6 +265,7 @@ public:
virtual bool free(RID p_rid) = 0;
virtual void update() = 0;
virtual ~RasterizerScene() {}
};
@ -304,11 +312,6 @@ public:
virtual Size2 texture_size_with_proxy(RID p_proxy) = 0;
/* SKY API */
virtual RID sky_create() = 0;
virtual void sky_set_texture(RID p_sky, RID p_cube_map, int p_radiance_size) = 0;
/* SHADER API */
virtual RID shader_create() = 0;

View file

@ -265,10 +265,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
if ((uint32_t)p_uvs.size() == vertex_count) {
stride += 2;
}
if ((uint32_t)p_bones.size() == vertex_count * 4) {
stride += 4;
}
if ((uint32_t)p_weights.size() == vertex_count * 4) {
if ((uint32_t)p_bones.size() == vertex_count * 4 && (uint32_t)p_weights.size() == vertex_count * 4) {
stride += 4;
}
@ -277,9 +274,9 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
PoolVector<uint8_t> polygon_buffer;
polygon_buffer.resize(buffer_size * sizeof(float));
Vector<RD::VertexDescription> descriptions;
descriptions.resize(5);
descriptions.resize(4);
Vector<RID> buffers;
buffers.resize(5);
buffers.resize(4);
{
PoolVector<uint8_t>::Read r = polygon_buffer.read();
@ -374,7 +371,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
}
//bones
if ((uint32_t)p_indices.size() == vertex_count * 4) {
if ((uint32_t)p_indices.size() == vertex_count * 4 && (uint32_t)p_weights.size() == vertex_count * 4) {
RD::VertexDescription vd;
vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT;
vd.offset = base_offset * sizeof(float);
@ -384,12 +381,22 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
descriptions.write[3] = vd;
const int *bone_ptr = p_bones.ptr();
const float *weight_ptr = p_weights.ptr();
for (uint32_t i = 0; i < vertex_count; i++) {
uptr[base_offset + i * stride + 0] = bone_ptr[i * 4 + 0];
uptr[base_offset + i * stride + 1] = bone_ptr[i * 4 + 1];
uptr[base_offset + i * stride + 2] = bone_ptr[i * 4 + 2];
uptr[base_offset + i * stride + 3] = bone_ptr[i * 4 + 3];
uint16_t *bone16w = (uint16_t *)&uptr[base_offset + i * stride];
uint16_t *weight16w = (uint16_t *)&uptr[base_offset + i * stride + 2];
bone16w[0] = bone_ptr[i * 4 + 0];
bone16w[1] = bone_ptr[i * 4 + 1];
bone16w[2] = bone_ptr[i * 4 + 2];
bone16w[3] = bone_ptr[i * 4 + 3];
weight16w[0] = CLAMP(weight_ptr[i * 4 + 0] * 65535, 0, 65535);
weight16w[1] = CLAMP(weight_ptr[i * 4 + 1] * 65535, 0, 65535);
weight16w[2] = CLAMP(weight_ptr[i * 4 + 2] * 65535, 0, 65535);
weight16w[3] = CLAMP(weight_ptr[i * 4 + 3] * 65535, 0, 65535);
}
base_offset += 4;
@ -404,37 +411,6 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
buffers.write[3] = storage->mesh_get_default_rd_buffer(RasterizerStorageRD::DEFAULT_RD_BUFFER_BONES);
}
//bones
if ((uint32_t)p_weights.size() == vertex_count * 4) {
RD::VertexDescription vd;
vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
vd.offset = base_offset * sizeof(float);
vd.location = VS::ARRAY_WEIGHTS;
vd.stride = stride * sizeof(float);
descriptions.write[4] = vd;
const float *weight_ptr = p_weights.ptr();
for (uint32_t i = 0; i < vertex_count; i++) {
fptr[base_offset + i * stride + 0] = weight_ptr[i * 4 + 0];
fptr[base_offset + i * stride + 1] = weight_ptr[i * 4 + 1];
fptr[base_offset + i * stride + 2] = weight_ptr[i * 4 + 2];
fptr[base_offset + i * stride + 3] = weight_ptr[i * 4 + 3];
}
base_offset += 4;
} else {
RD::VertexDescription vd;
vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
vd.offset = 0;
vd.location = VS::ARRAY_WEIGHTS;
vd.stride = 0;
descriptions.write[4] = vd;
buffers.write[4] = storage->mesh_get_default_rd_buffer(RasterizerStorageRD::DEFAULT_RD_BUFFER_WEIGHTS);
}
//check that everything is as it should be
ERR_FAIL_COND_V(base_offset != stride, 0); //bug
}
@ -913,7 +889,7 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
ERR_CONTINUE(!pb);
//bind pipeline
{
static const PipelineVariant variant[VS::PRIMITIVE_MAX] = { PIPELINE_VARIANT_ATTRIBUTE_POINTS, PIPELINE_VARIANT_ATTRIBUTE_LINES, PIPELINE_VARIANT_ATTRIBUTE_TRIANGLES };
static const PipelineVariant variant[VS::PRIMITIVE_MAX] = { PIPELINE_VARIANT_ATTRIBUTE_POINTS, PIPELINE_VARIANT_ATTRIBUTE_LINES, PIPELINE_VARIANT_ATTRIBUTE_LINES_STRIP, PIPELINE_VARIANT_ATTRIBUTE_TRIANGLES, PIPELINE_VARIANT_ATTRIBUTE_TRIANGLE_STRIP };
ERR_CONTINUE(polygon->primitive < 0 || polygon->primitive >= VS::PRIMITIVE_MAX);
RID pipeline = pipeline_variants->variants[light_mode][variant[polygon->primitive]].get_render_pipeline(pb->vertex_format_id, p_framebuffer_format);
RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, pipeline);
@ -1976,9 +1952,12 @@ void RasterizerCanvasRD::ShaderData::set_code(const String &p_code) {
RD::RENDER_PRIMITIVE_LINES,
RD::RENDER_PRIMITIVE_POINTS,
RD::RENDER_PRIMITIVE_TRIANGLES,
RD::RENDER_PRIMITIVE_TRIANGLE_STRIPS,
RD::RENDER_PRIMITIVE_LINES,
RD::RENDER_PRIMITIVE_LINESTRIPS,
RD::RENDER_PRIMITIVE_POINTS,
};
ShaderVariant shader_variants[PIPELINE_LIGHT_MODE_MAX][PIPELINE_VARIANT_MAX] = {
{ //non lit
SHADER_VARIANT_QUAD,
@ -1988,6 +1967,8 @@ void RasterizerCanvasRD::ShaderData::set_code(const String &p_code) {
SHADER_VARIANT_PRIMITIVE_POINTS,
SHADER_VARIANT_ATTRIBUTES,
SHADER_VARIANT_ATTRIBUTES,
SHADER_VARIANT_ATTRIBUTES,
SHADER_VARIANT_ATTRIBUTES,
SHADER_VARIANT_ATTRIBUTES_POINTS },
{ //lit
SHADER_VARIANT_QUAD_LIGHT,
@ -1997,6 +1978,8 @@ void RasterizerCanvasRD::ShaderData::set_code(const String &p_code) {
SHADER_VARIANT_PRIMITIVE_POINTS_LIGHT,
SHADER_VARIANT_ATTRIBUTES_LIGHT,
SHADER_VARIANT_ATTRIBUTES_LIGHT,
SHADER_VARIANT_ATTRIBUTES_LIGHT,
SHADER_VARIANT_ATTRIBUTES_LIGHT,
SHADER_VARIANT_ATTRIBUTES_POINTS_LIGHT },
};
@ -2283,6 +2266,7 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
RD::RENDER_PRIMITIVE_LINESTRIPS,
RD::RENDER_PRIMITIVE_POINTS,
};
ShaderVariant shader_variants[PIPELINE_LIGHT_MODE_MAX][PIPELINE_VARIANT_MAX] = {
{ //non lit
SHADER_VARIANT_QUAD,

View file

@ -1,5 +1,20 @@
#include "rasterizer_effects_rd.h"
static _FORCE_INLINE_ void store_transform_3x3(const Basis &p_basis, float *p_array) {
p_array[0] = p_basis.elements[0][0];
p_array[1] = p_basis.elements[1][0];
p_array[2] = p_basis.elements[2][0];
p_array[3] = 0;
p_array[4] = p_basis.elements[0][1];
p_array[5] = p_basis.elements[1][1];
p_array[6] = p_basis.elements[2][1];
p_array[7] = 0;
p_array[8] = p_basis.elements[0][2];
p_array[9] = p_basis.elements[1][2];
p_array[10] = p_basis.elements[2][2];
p_array[11] = 0;
}
RID RasterizerEffectsRD::_get_uniform_set_from_texture(RID p_texture) {
if (texture_to_uniform_set_cache.has(p_texture)) {
@ -86,31 +101,127 @@ void RasterizerEffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_framebuff
RD::get_singleton()->draw_list_end();
}
void RasterizerEffectsRD::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) {
zeromem(&roughness.push_constant, sizeof(CubemapRoughnessPushConstant));
roughness.push_constant.face_id = p_face_id;
roughness.push_constant.roughness = p_roughness;
roughness.push_constant.sample_count = p_sample_count;
roughness.push_constant.use_direct_write = p_roughness == 0.0;
//RUN
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);
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, roughness.pipelines[p_source_is_panorama ? CUBEMAP_ROUGHNESS_SOURCE_PANORAMA : CUBEMAP_ROUGHNESS_SOURCE_CUBEMAP].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, &roughness.push_constant, sizeof(CubemapRoughnessPushConstant));
RD::get_singleton()->draw_list_draw(draw_list, true);
RD::get_singleton()->draw_list_end();
}
void RasterizerEffectsRD::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) {
zeromem(&sky.push_constant, sizeof(SkyPushConstant));
sky.push_constant.proj[0] = p_camera.matrix[2][0];
sky.push_constant.proj[1] = p_camera.matrix[0][0];
sky.push_constant.proj[2] = p_camera.matrix[2][1];
sky.push_constant.proj[3] = p_camera.matrix[1][1];
sky.push_constant.alpha = p_alpha;
sky.push_constant.depth = 1.0;
sky.push_constant.multiplier = p_multipler;
store_transform_3x3(p_orientation, sky.push_constant.orientation);
RD::DrawListID draw_list = p_list;
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, sky.pipeline.get_render_pipeline(RD::INVALID_ID, p_fb_format));
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_panorama), 0);
RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
RD::get_singleton()->draw_list_set_push_constant(draw_list, &sky.push_constant, sizeof(SkyPushConstant));
RD::get_singleton()->draw_list_draw(draw_list, true);
}
void RasterizerEffectsRD::make_mipmap(RID p_source_rd_texture, RID p_dest_framebuffer, const Vector2 &p_pixel_size) {
zeromem(&blur.push_constant, sizeof(BlurPushConstant));
blur.push_constant.pixel_size[0] = p_pixel_size.x;
blur.push_constant.pixel_size[1] = p_pixel_size.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);
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur.pipelines[BLUR_MODE_MIPMAP].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();
}
RasterizerEffectsRD::RasterizerEffectsRD() {
// Initialize blur
Vector<String> blur_modes;
blur_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n");
blur_modes.push_back("\n#define MODE_GAUSSIAN_GLOW\n");
blur_modes.push_back("\n#define MODE_GAUSSIAN_GLOW\n#define GLOW_USE_AUTO_EXPOSURE\n");
blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_LOW\n");
blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_MEDIUM\n");
blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_HIGH\n");
blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_LOW\n#define DOF_NEAR_BLUR_MERGE\n");
blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_MEDIUM\n#define DOF_NEAR_BLUR_MERGE\n");
blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_HIGH\n#define DOF_NEAR_BLUR_MERGE\n");
blur_modes.push_back("\n#define MODE_DOF_FAR_BLUR\n#define DOF_QUALITY_LOW\n");
blur_modes.push_back("\n#define MODE_DOF_FAR_BLUR\n#define DOF_QUALITY_MEDIUM\n");
blur_modes.push_back("\n#define MODE_DOF_FAR_BLUR\n#define DOF_QUALITY_HIGH\n");
blur_modes.push_back("\n#define MODE_SSAO_MERGE\n");
blur_modes.push_back("\n#define MODE_SIMPLE_COPY\n");
{
// Initialize blur
Vector<String> blur_modes;
blur_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n");
blur_modes.push_back("\n#define MODE_GAUSSIAN_GLOW\n");
blur_modes.push_back("\n#define MODE_GAUSSIAN_GLOW\n#define GLOW_USE_AUTO_EXPOSURE\n");
blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_LOW\n");
blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_MEDIUM\n");
blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_HIGH\n");
blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_LOW\n#define DOF_NEAR_BLUR_MERGE\n");
blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_MEDIUM\n#define DOF_NEAR_BLUR_MERGE\n");
blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_HIGH\n#define DOF_NEAR_BLUR_MERGE\n");
blur_modes.push_back("\n#define MODE_DOF_FAR_BLUR\n#define DOF_QUALITY_LOW\n");
blur_modes.push_back("\n#define MODE_DOF_FAR_BLUR\n#define DOF_QUALITY_MEDIUM\n");
blur_modes.push_back("\n#define MODE_DOF_FAR_BLUR\n#define DOF_QUALITY_HIGH\n");
blur_modes.push_back("\n#define MODE_SSAO_MERGE\n");
blur_modes.push_back("\n#define MODE_SIMPLE_COPY\n");
blur_modes.push_back("\n#define MODE_MIPMAP\n");
blur.shader.initialize(blur_modes);
zeromem(&blur.push_constant, sizeof(BlurPushConstant));
blur.shader_version = blur.shader.version_create();
blur.shader.initialize(blur_modes);
zeromem(&blur.push_constant, sizeof(BlurPushConstant));
blur.shader_version = blur.shader.version_create();
for (int i = 0; i < BLUR_MODE_MAX; i++) {
blur.pipelines[i].setup(blur.shader.version_get_shader(blur.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);
for (int i = 0; i < BLUR_MODE_MAX; i++) {
blur.pipelines[i].setup(blur.shader.version_get_shader(blur.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);
}
}
{
// Initialize roughness
Vector<String> cubemap_roughness_modes;
cubemap_roughness_modes.push_back("\n#define MODE_SOURCE_PANORAMA\n");
cubemap_roughness_modes.push_back("\n#define MODE_SOURCE_CUBEMAP\n");
roughness.shader.initialize(cubemap_roughness_modes);
roughness.shader_version = roughness.shader.version_create();
for (int i = 0; i < CUBEMAP_ROUGHNESS_SOURCE_MAX; i++) {
roughness.pipelines[i].setup(roughness.shader.version_get_shader(roughness.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);
}
}
{
// Initialize sky
Vector<String> sky_modes;
sky_modes.push_back("");
sky.shader.initialize(sky_modes);
sky.shader_version = sky.shader.version_create();
RD::PipelineDepthStencilState depth_stencil_state;
depth_stencil_state.enable_depth_test = true;
depth_stencil_state.depth_compare_operator = RD::COMPARE_OP_LESS_OR_EQUAL;
sky.pipeline.setup(sky.shader.version_get_shader(sky.shader_version, 0), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), depth_stencil_state, RD::PipelineColorBlendState::create_disabled(), 0);
}
RD::SamplerState sampler;

View file

@ -1,8 +1,11 @@
#ifndef RASTERIZER_EFFECTS_RD_H
#define RASTERIZER_EFFECTS_RD_H
#include "core/math/camera_matrix.h"
#include "render_pipeline_vertex_format_cache_rd.h"
#include "shaders/blur.glsl.gen.h"
#include "servers/visual/rasterizer_rd/shaders/blur.glsl.gen.h"
#include "servers/visual/rasterizer_rd/shaders/cubemap_roughness.glsl.gen.h"
#include "servers/visual/rasterizer_rd/shaders/sky.glsl.gen.h"
class RasterizerEffectsRD {
@ -21,6 +24,7 @@ class RasterizerEffectsRD {
BLUR_MODE_DOF_FAR_HIGH,
BLUR_MODE_SSAO_MERGE,
BLUR_MODE_SIMPLY_COPY,
BLUR_MODE_MIPMAP,
BLUR_MODE_MAX,
};
@ -68,6 +72,44 @@ class RasterizerEffectsRD {
} blur;
enum CubemapRoughnessSource {
CUBEMAP_ROUGHNESS_SOURCE_PANORAMA,
CUBEMAP_ROUGHNESS_SOURCE_CUBEMAP,
CUBEMAP_ROUGHNESS_SOURCE_MAX
};
struct CubemapRoughnessPushConstant {
uint32_t face_id;
uint32_t sample_count;
float roughness;
uint32_t use_direct_write;
};
struct CubemapRoughness {
CubemapRoughnessPushConstant push_constant;
CubemapRoughnessShaderRD shader;
RID shader_version;
RenderPipelineVertexFormatCacheRD pipelines[CUBEMAP_ROUGHNESS_SOURCE_MAX];
} roughness;
struct SkyPushConstant {
float orientation[12];
float proj[4];
float multiplier;
float alpha;
float depth;
float pad;
};
struct Sky {
SkyPushConstant push_constant;
SkyShaderRD shader;
RID shader_version;
RenderPipelineVertexFormatCacheRD pipeline;
} sky;
RID default_sampler;
RID index_buffer;
RID index_array;
@ -79,6 +121,9 @@ class RasterizerEffectsRD {
public:
void copy(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_region);
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);
RasterizerEffectsRD();
~RasterizerEffectsRD();

View file

@ -85,7 +85,7 @@ public:
_create_func = _create_current;
}
virtual bool is_low_end() const { return true; }
virtual bool is_low_end() const { return false; }
static ThreadWorkPool thread_work_pool;

View file

@ -254,6 +254,7 @@ void RasterizerSceneForwardRD::ShaderData::set_code(const String &p_code) {
RD::PipelineDepthStencilState depth_stencil_state;
if (depth_test != DEPTH_TEST_DISABLED) {
depth_stencil_state.enable_depth_test = true;
depth_stencil_state.depth_compare_operator = RD::COMPARE_OP_LESS_OR_EQUAL;
depth_stencil_state.enable_depth_write = depth_draw != DEPTH_DRAW_DISABLED ? true : false;
}
@ -487,7 +488,7 @@ void RasterizerSceneForwardRD::MaterialData::update_parameters(const Map<StringN
}
}
uniform_set = RD::get_singleton()->uniform_set_create(uniforms, scene_singleton->shader.scene_shader.version_get_shader(shader_data->version, 0), 3);
uniform_set = RD::get_singleton()->uniform_set_create(uniforms, scene_singleton->shader.scene_shader.version_get_shader(shader_data->version, 0), 2);
}
RasterizerSceneForwardRD::MaterialData::~MaterialData() {
if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
@ -563,6 +564,13 @@ void RasterizerSceneForwardRD::RenderBufferDataForward::configure(RID p_render_t
color_fb = RD::get_singleton()->framebuffer_create(fb);
}
{
Vector<RID> fb;
fb.push_back(color);
color_only_fb = RD::get_singleton()->framebuffer_create(fb);
}
}
RasterizerSceneRD::RenderBufferData *RasterizerSceneForwardRD::_create_render_buffer_data() {
@ -580,6 +588,7 @@ bool RasterizerSceneForwardRD::free(RID p_rid) {
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;
}
@ -632,13 +641,13 @@ void RasterizerSceneForwardRD::instance_custom_data_update_transform(InstanceBas
/// RENDERING ///
void RasterizerSceneForwardRD::_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, RID p_screen_uniform_set, bool p_no_gi) {
void RasterizerSceneForwardRD::_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) {
RD::DrawListID draw_list = p_draw_list;
RD::FramebufferFormatID framebuffer_format = p_framebuffer_Format;
//global scope bindings
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_screen_uniform_set, 0);
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, render_base_uniform_set, 0);
MaterialData *prev_material = nullptr;
// ShaderData *prev_shader = nullptr;
@ -827,11 +836,10 @@ void RasterizerSceneForwardRD::_render_list(RenderingDevice::DrawListID p_draw_l
}
}
void RasterizerSceneForwardRD::_setup_environment(RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, bool p_no_fog) {
Transform sky_orientation;
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) {
CameraMatrix projection = p_cam_projection;
projection.flip_y();
projection.flip_y(); // Vulkan and modern APIs use Y-Down
//store camera into ubo
store_camera(projection, scene_state.ubo.projection_matrix);
@ -842,8 +850,68 @@ void RasterizerSceneForwardRD::_setup_environment(RID p_environment, const Camer
//time global variables
scene_state.ubo.time = time;
RD::get_singleton()->buffer_update(scene_state.uniform_buffer, 0, sizeof(SceneState::UBO), &scene_state.ubo, true);
if (is_environment(p_environment)) {
VS::EnvironmentBG env_bg = environment_get_background(p_environment);
VS::EnvironmentAmbientSource ambient_src = environment_get_ambient_light_ambient_source(p_environment);
float bg_energy = environment_get_bg_energy(p_environment);
scene_state.ubo.ambient_light_color_energy[3] = bg_energy;
scene_state.ubo.ambient_color_sky_mix = environment_get_ambient_sky_contribution(p_environment);
//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.to_linear();
scene_state.ubo.ambient_light_color_energy[0] = color.r * bg_energy;
scene_state.ubo.ambient_light_color_energy[1] = color.g * bg_energy;
scene_state.ubo.ambient_light_color_energy[2] = color.b * bg_energy;
scene_state.ubo.use_ambient_light = true;
scene_state.ubo.use_ambient_cubemap = false;
} else {
float energy = environment_get_ambient_light_ambient_energy(p_environment);
Color color = environment_get_ambient_light_color(p_environment);
color = color.to_linear();
scene_state.ubo.ambient_light_color_energy[0] = color.r * energy;
scene_state.ubo.ambient_light_color_energy[1] = color.g * energy;
scene_state.ubo.ambient_light_color_energy[2] = color.b * energy;
Basis sky_transform = environment_get_sky_orientation(p_environment);
sky_transform = sky_transform.inverse() * p_cam_transform.basis;
store_transform_3x3(sky_transform, scene_state.ubo.radiance_inverse_xform);
scene_state.ubo.use_ambient_cubemap = (ambient_src == VS::ENV_AMBIENT_SOURCE_BG && env_bg == VS::ENV_BG_SKY) || ambient_src == VS::ENV_AMBIENT_SOURCE_SKY;
scene_state.ubo.use_ambient_light = scene_state.ubo.use_ambient_cubemap || ambient_src == VS::ENV_AMBIENT_SOURCE_COLOR;
}
//specular
VS::EnvironmentReflectionSource ref_src = environment_get_reflection_source(p_environment);
if ((ref_src == VS::ENV_REFLECTION_SOURCE_BG && env_bg == VS::ENV_BG_SKY) || ref_src == VS::ENV_REFLECTION_SOURCE_SKY) {
scene_state.ubo.use_reflection_cubemap = true;
} else {
scene_state.ubo.use_reflection_cubemap = false;
}
} else {
if (p_render_target.is_valid()) {
scene_state.ubo.use_ambient_light = true;
Color clear_color = storage->render_target_get_clear_request_color(p_render_target);
clear_color = clear_color.to_linear();
scene_state.ubo.ambient_light_color_energy[0] = clear_color.r;
scene_state.ubo.ambient_light_color_energy[1] = clear_color.g;
scene_state.ubo.ambient_light_color_energy[2] = clear_color.b;
scene_state.ubo.ambient_light_color_energy[3] = 1.0;
} else {
scene_state.ubo.use_ambient_light = false;
}
scene_state.ubo.use_ambient_cubemap = false;
scene_state.ubo.use_reflection_cubemap = false;
}
#if 0
//bg and ambient
if (p_environment.is_valid()) {
@ -952,6 +1020,8 @@ void RasterizerSceneForwardRD::_setup_environment(RID p_environment, const Camer
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(State::EnvironmentRadianceUBO), &state.env_radiance_data);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
#endif
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) {
@ -1239,6 +1309,38 @@ void RasterizerSceneForwardRD::_fill_render_list(InstanceBase **p_cull_result, i
}
}
void RasterizerSceneForwardRD::_draw_sky(RD::DrawListID p_draw_list, RD::FramebufferFormatID p_fb_format, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform, float p_alpha) {
ERR_FAIL_COND(!is_environment(p_environment));
RID sky = environment_get_sky(p_environment);
ERR_FAIL_COND(!sky.is_valid());
RID panorama = sky_get_panorama_texture_rd(sky);
ERR_FAIL_COND(!panorama.is_valid());
Basis sky_transform = environment_get_sky_orientation(p_environment);
sky_transform.invert();
float multiplier = environment_get_bg_energy(p_environment);
float custom_fov = environment_get_sky_custom_fov(p_environment);
// Camera
CameraMatrix camera;
if (custom_fov) {
float near_plane = p_projection.get_z_near();
float far_plane = p_projection.get_z_far();
float aspect = p_projection.get_aspect();
camera.set_perspective(custom_fov, aspect, near_plane, far_plane);
} else {
camera = p_projection;
}
sky_transform = p_transform.basis * sky_transform;
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) {
RenderBufferDataForward *render_buffer = (RenderBufferDataForward *)p_buffer_data;
@ -1285,12 +1387,15 @@ void RasterizerSceneForwardRD::_render_scene(RenderBufferData *p_buffer_data, co
scene_state.ubo.viewport_size[0] = vp_he.x;
scene_state.ubo.viewport_size[1] = vp_he.y;
RID render_target;
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;
render_target = render_buffer->render_target;
}
_setup_environment(p_environment, p_cam_projection, p_cam_transform, p_reflection_probe.is_valid());
_setup_environment(render_target, p_environment, p_cam_projection, p_cam_transform, p_reflection_probe.is_valid());
#if 0
for (int i = 0; i < p_light_cull_count; i++) {
@ -1356,6 +1461,7 @@ void RasterizerSceneForwardRD::_render_scene(RenderBufferData *p_buffer_data, co
bool use_mrt = false;
#endif
render_list.clear();
_fill_render_list(p_cull_result, p_cull_count, PASS_MODE_COLOR, render_buffer == nullptr);
#if 0
@ -1620,18 +1726,79 @@ void RasterizerSceneForwardRD::_render_scene(RenderBufferData *p_buffer_data, co
}
#endif
RID radiance_cubemap;
bool draw_sky = false;
Color clear_color;
bool keep_color = false;
if (is_environment(p_environment)) {
VS::EnvironmentBG bg_mode = environment_get_background(p_environment);
float bg_energy = environment_get_bg_energy(p_environment);
switch (bg_mode) {
case VS::ENV_BG_CLEAR_COLOR: {
clear_color = render_target.is_valid() ? storage->render_target_get_clear_request_color(render_target) : environment_get_bg_color(p_environment);
clear_color.r *= bg_energy;
clear_color.g *= bg_energy;
clear_color.b *= bg_energy;
} break;
case VS::ENV_BG_COLOR: {
clear_color = environment_get_bg_color(p_environment);
clear_color.r *= bg_energy;
clear_color.g *= bg_energy;
clear_color.b *= bg_energy;
} break;
case VS::ENV_BG_SKY: {
RID sky = environment_get_sky(p_environment);
if (sky.is_valid()) {
radiance_cubemap = sky_get_radiance_texture_rd(sky);
draw_sky = true;
}
} break;
case VS::ENV_BG_CANVAS: {
keep_color = true;
} break;
case VS::ENV_BG_KEEP: {
keep_color = true;
} break;
case VS::ENV_BG_CAMERA_FEED: {
} break;
}
} else {
if (render_target.is_valid()) {
clear_color = storage->render_target_get_clear_request_color(render_target);
}
}
_setup_render_base_uniform_set(RID(), RID(), RID(), RID(), radiance_cubemap);
render_list.sort_by_key(false);
bool can_continue = true; //unless the middle buffers are needed
bool using_separate_specular = false;
{
//regular forward for now
Vector<Color> c;
c.push_back(Color(0, 0, 0, 1));
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(render_buffer->color_fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_CONTINUE, 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, default_render_buffer_uniform_set, render_buffer == nullptr);
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::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::get_singleton()->draw_list_end();
if (using_separate_specular && !can_continue) {
//can't continue, so close the buffers
//RD::get_singleton()->draw_list_begin(render_buffer->color_specular_fb, RD::INITIAL_ACTION_CONTINUE, RD::FINAL_ACTION_READ_COLOR_AND_DEPTH, c);
//RD::get_singleton()->draw_list_end();
}
}
//_render_list
#if 0
if (state.directional_light_count == 0) {
@ -1721,8 +1888,8 @@ void RasterizerSceneForwardRD::_render_scene(RenderBufferData *p_buffer_data, co
render_list.sort_by_reverse_depth_and_priority(true);
{
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(render_buffer->color_fb, RD::INITIAL_ACTION_CONTINUE, RD::FINAL_ACTION_READ_COLOR_DISCARD_DEPTH);
_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, default_render_buffer_uniform_set, render_buffer == nullptr);
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::get_singleton()->draw_list_end();
}
@ -1806,6 +1973,90 @@ void RasterizerSceneForwardRD::_render_scene(RenderBufferData *p_buffer_data, co
#endif
}
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) {
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);
}
//default render buffer and scene state uniform set
Vector<RD::Uniform> uniforms;
{
RD::Uniform u;
u.binding = 1;
u.type = RD::UNIFORM_TYPE_TEXTURE;
RID texture = p_depth_buffer.is_valid() ? p_depth_buffer : storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE);
u.ids.push_back(texture);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 2;
u.type = RD::UNIFORM_TYPE_TEXTURE;
RID texture = p_color_buffer.is_valid() ? p_color_buffer : storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_BLACK);
u.ids.push_back(texture);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 3;
u.type = RD::UNIFORM_TYPE_TEXTURE;
RID texture = p_normal_buffer.is_valid() ? p_normal_buffer : storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_NORMAL);
u.ids.push_back(texture);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 4;
u.type = RD::UNIFORM_TYPE_TEXTURE;
RID texture = p_roughness_limit_buffer.is_valid() ? p_roughness_limit_buffer : storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_BLACK);
u.ids.push_back(texture);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 5;
u.type = RD::UNIFORM_TYPE_TEXTURE;
RID texture = p_radiance_cubemap.is_valid() ? p_radiance_cubemap : storage->texture_rd_get_default(is_using_radiance_cubemap_array() ? RasterizerStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RasterizerStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK);
u.ids.push_back(texture);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.type = RD::UNIFORM_TYPE_SAMPLER;
u.binding = 6;
u.ids.resize(12);
RID *ids_ptr = u.ids.ptrw();
ids_ptr[0] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, VS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
ids_ptr[1] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, VS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
ids_ptr[2] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIMPAMPS, VS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
ids_ptr[3] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, VS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
ids_ptr[4] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIMPAMPS_ANISOTROPIC, VS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
ids_ptr[5] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, VS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
ids_ptr[6] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, VS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
ids_ptr[7] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, VS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
ids_ptr[8] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIMPAMPS, VS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
ids_ptr[9] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, VS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
ids_ptr[10] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIMPAMPS_ANISOTROPIC, VS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
ids_ptr[11] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, VS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 7;
u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
u.ids.push_back(scene_state.uniform_buffer);
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) {
@ -1816,7 +2067,8 @@ void RasterizerSceneForwardRD::set_time(double p_time) {
time = p_time;
}
RasterizerSceneForwardRD::RasterizerSceneForwardRD(RasterizerStorageRD *p_storage) {
RasterizerSceneForwardRD::RasterizerSceneForwardRD(RasterizerStorageRD *p_storage) :
RasterizerSceneRD(p_storage) {
singleton = this;
storage = p_storage;
@ -1824,6 +2076,10 @@ RasterizerSceneForwardRD::RasterizerSceneForwardRD(RasterizerStorageRD *p_storag
{
String defines;
defines += "\n#define MAX_ROUGHNESS_LOD " + itos(get_roughness_layers() - 1) + ".0\n";
if (is_using_radiance_cubemap_array()) {
defines += "\n#define USE_RADIANCE_CUBEMAP_ARRAY \n";
}
Vector<String> shader_versions;
shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n");
@ -1847,7 +2103,7 @@ RasterizerSceneForwardRD::RasterizerSceneForwardRD(RasterizerStorageRD *p_storag
actions.renames["WORLD_MATRIX"] = "world_matrix";
actions.renames["WORLD_NORMAL_MATRIX"] = "world_normal_matrix";
actions.renames["INV_CAMERA_MATRIX"] = "scene_data.camera_inverse_matrix";
actions.renames["INV_CAMERA_MATRIX"] = "scene_data.inv_camera_matrix";
actions.renames["CAMERA_MATRIX"] = "scene_data.camera_matrix";
actions.renames["PROJECTION_MATRIX"] = "projection_matrix";
actions.renames["INV_PROJECTION_MATRIX"] = "scene_data.inv_projection_matrix";
@ -1907,21 +2163,21 @@ RasterizerSceneForwardRD::RasterizerSceneForwardRD(RasterizerStorageRD *p_storag
actions.renames["DIFFUSE_LIGHT"] = "diffuse_light";
actions.renames["SPECULAR_LIGHT"] = "specular_light";
actions.usage_defines["TANGENT"] = "#define ENABLE_TANGENT_INTERP\n";
actions.usage_defines["TANGENT"] = "#define TANGENT_USED\n";
actions.usage_defines["BINORMAL"] = "@TANGENT";
actions.usage_defines["RIM"] = "#define LIGHT_USE_RIM\n";
actions.usage_defines["RIM"] = "#define LIGHT_RIM_USED\n";
actions.usage_defines["RIM_TINT"] = "@RIM";
actions.usage_defines["CLEARCOAT"] = "#define LIGHT_USE_CLEARCOAT\n";
actions.usage_defines["CLEARCOAT"] = "#define LIGHT_CLEARCOAT_USED\n";
actions.usage_defines["CLEARCOAT_GLOSS"] = "@CLEARCOAT";
actions.usage_defines["ANISOTROPY"] = "#define LIGHT_USE_ANISOTROPY\n";
actions.usage_defines["ANISOTROPY"] = "#define LIGHT_ANISOTROPY_USED\n";
actions.usage_defines["ANISOTROPY_FLOW"] = "@ANISOTROPY";
actions.usage_defines["AO"] = "#define ENABLE_AO\n";
actions.usage_defines["AO_LIGHT_AFFECT"] = "#define ENABLE_AO\n";
actions.usage_defines["UV"] = "#define ENABLE_UV_INTERP\n";
actions.usage_defines["UV2"] = "#define ENABLE_UV2_INTERP\n";
actions.usage_defines["NORMALMAP"] = "#define ENABLE_NORMALMAP\n";
actions.usage_defines["AO"] = "#define AO_USED\n";
actions.usage_defines["AO_LIGHT_AFFECT"] = "#define AO_USED\n";
actions.usage_defines["UV"] = "#define UV_USED\n";
actions.usage_defines["UV2"] = "#define UV2_USED\n";
actions.usage_defines["NORMALMAP"] = "#define NORMALMAP_USED\n";
actions.usage_defines["NORMALMAP_DEPTH"] = "@NORMALMAP";
actions.usage_defines["COLOR"] = "#define ENABLE_COLOR_INTERP\n";
actions.usage_defines["COLOR"] = "#define COLOR_USED\n";
actions.usage_defines["INSTANCE_CUSTOM"] = "#define ENABLE_INSTANCE_CUSTOM\n";
actions.usage_defines["POSITION"] = "#define OVERRIDE_POSITION\n";
@ -1982,77 +2238,23 @@ RasterizerSceneForwardRD::RasterizerSceneForwardRD(RasterizerStorageRD *p_storag
scene_pass = 0;
render_pass = 0;
scene_state.uniform_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(SceneState::UBO));
{
//default material and shader
default_shader = storage->shader_create();
storage->shader_set_code(default_shader, "shader_type spatial;\n");
storage->shader_set_code(default_shader, "shader_type spatial; void vertex() { ROUGHNESS = 0.8; } void fragment() { ALBEDO=vec3(0.6); ROUGHNESS=0.8; METALLIC=0.2; } \n");
default_material = storage->material_create();
storage->material_set_shader(default_material, default_shader);
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);
}
//default render buffer and scene state uniform set
{
Vector<RD::Uniform> uniforms;
{
RD::Uniform u;
u.binding = 1;
u.type = RD::UNIFORM_TYPE_TEXTURE;
u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE));
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 2;
u.type = RD::UNIFORM_TYPE_TEXTURE;
u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE));
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 3;
u.type = RD::UNIFORM_TYPE_TEXTURE;
u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE));
uniforms.push_back(u);
}
scene_state.uniform_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(SceneState::UBO));
{
RD::Uniform u;
u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
u.binding = 4;
u.ids.push_back(scene_state.uniform_buffer);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.type = RD::UNIFORM_TYPE_SAMPLER;
u.binding = 5;
u.ids.resize(12);
RID *ids_ptr = u.ids.ptrw();
ids_ptr[0] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, VS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
ids_ptr[1] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, VS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
ids_ptr[2] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIMPAMPS, VS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
ids_ptr[3] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, VS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
ids_ptr[4] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIMPAMPS_ANISOTROPIC, VS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
ids_ptr[5] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, VS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
ids_ptr[6] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, VS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
ids_ptr[7] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, VS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
ids_ptr[8] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIMPAMPS, VS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
ids_ptr[9] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, VS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
ids_ptr[10] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIMPAMPS_ANISOTROPIC, VS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
ids_ptr[11] = storage->sampler_rd_get_default(VS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, VS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
uniforms.push_back(u);
}
default_render_buffer_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, default_shader_rd, 0);
}
}
RasterizerSceneForwardRD::~RasterizerSceneForwardRD() {
//clear base uniform set if still valid
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);
}
}

View file

@ -214,13 +214,11 @@ class RasterizerSceneForwardRD : public RasterizerSceneRD {
RID color;
RID depth;
RID color_fb;
RID color_only_fb;
int width, height;
RID render_target;
RID uniform_set_opaque;
RID uniform_set_alpha;
void clear();
virtual void configure(RID p_render_target, int p_width, int p_height, VS::ViewportMSAA p_msaa);
@ -229,18 +227,8 @@ class RasterizerSceneForwardRD : public RasterizerSceneRD {
virtual RenderBufferData *_create_render_buffer_data();
RID default_render_buffer_uniform_set;
/* Instance Data */
struct InstanceData {
struct UBO {
};
RID state_buffer;
RID uniform_set;
};
RID_Owner<InstanceData> instance_data_owner;
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);
/* Scene State UBO */
@ -260,6 +248,15 @@ class RasterizerSceneForwardRD : public RasterizerSceneRD {
float time;
float reflection_multiplier;
float ambient_light_color_energy[4];
float ambient_color_sky_mix;
uint32_t use_ambient_light;
uint32_t use_ambient_cubemap;
uint32_t use_reflection_cubemap;
float radiance_inverse_xform[12];
};
UBO ubo;
@ -427,14 +424,16 @@ class RasterizerSceneForwardRD : public RasterizerSceneRD {
PASS_MODE_DEPTH_NORMAL_ROUGHNESS,
};
void _setup_environment(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);
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, RID p_screen_uniform_set, bool p_no_gi);
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);
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);

View file

@ -1,4 +1,366 @@
#include "rasterizer_scene_rd.h"
#include "core/project_settings.h"
RID RasterizerSceneRD::sky_create() {
return sky_owner.make_rid(Sky());
}
void RasterizerSceneRD::_sky_invalidate(Sky *p_sky) {
if (!p_sky->dirty) {
p_sky->dirty = true;
p_sky->dirty_list = dirty_sky_list;
dirty_sky_list = p_sky;
}
}
void RasterizerSceneRD::sky_set_radiance_size(RID p_sky, int p_radiance_size) {
Sky *sky = sky_owner.getornull(p_sky);
ERR_FAIL_COND(!sky);
ERR_FAIL_COND(p_radiance_size < 32 || p_radiance_size > 2048);
if (sky->radiance_size == p_radiance_size) {
return;
}
sky->radiance_size = p_radiance_size;
_sky_invalidate(sky);
if (sky->radiance.is_valid()) {
//if size changes, everything must be cleared
RD::get_singleton()->free(sky->radiance);
//everything else gets dependency, erase, so just clean it up
sky->radiance = RID();
sky->layers.clear();
sky->radiance_base_cubemap = RID();
}
}
void RasterizerSceneRD::sky_set_mode(RID p_sky, VS::SkyMode p_mode) {
Sky *sky = sky_owner.getornull(p_sky);
ERR_FAIL_COND(!sky);
if (sky->mode == p_mode) {
return;
}
sky->mode = p_mode;
_sky_invalidate(sky);
}
void RasterizerSceneRD::sky_set_texture(RID p_sky, RID p_panorama) {
Sky *sky = sky_owner.getornull(p_sky);
ERR_FAIL_COND(!sky);
if (sky->panorama.is_valid()) {
sky->panorama = RID();
RD::get_singleton()->free(sky->radiance);
sky->radiance = RID();
}
sky->panorama = p_panorama;
if (!sky->panorama.is_valid())
return; //cleared
_sky_invalidate(sky);
}
void RasterizerSceneRD::_update_dirty_skys() {
Sky *sky = dirty_sky_list;
while (sky) {
//update sky configuration if texture is missing
if (sky->radiance.is_null()) {
//recreate radiance and all data
int mipmaps = Image::get_image_required_mipmaps(sky->radiance_size, sky->radiance_size, Image::FORMAT_RGBAH) + 1;
if (sky->mode == VS::SKY_MODE_REALTIME) {
//use less mipmaps
mipmaps = MIN(8, mipmaps);
}
uint32_t w = sky->radiance_size, h = sky->radiance_size;
if (sky_use_cubemap_array) {
//array (higher quality, 6 times more memory)
RD::TextureFormat tf;
tf.array_layers = roughness_layers * 6;
tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
tf.type = RD::TEXTURE_TYPE_CUBE_ARRAY;
tf.mipmaps = mipmaps;
tf.width = w;
tf.height = h;
tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT;
sky->radiance = RD::get_singleton()->texture_create(tf, RD::TextureView());
for (int i = 0; i < roughness_layers; i++) {
Sky::Layer layer;
uint32_t mmw = w;
uint32_t mmh = h;
layer.mipmaps.resize(mipmaps);
for (int j = 0; j < mipmaps; j++) {
Sky::Layer::Mipmap &mm = layer.mipmaps.write[j];
mm.size.width = mmw;
mm.size.height = mmh;
for (int k = 0; k < 6; k++) {
mm.views[k] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), sky->radiance, i * 6 + k, j);
Vector<RID> fbtex;
fbtex.push_back(mm.views[k]);
mm.framebuffers[k] = RD::get_singleton()->framebuffer_create(fbtex);
}
mmw = MAX(1, mmw >> 1);
mmh = MAX(1, mmh >> 1);
}
sky->layers.push_back(layer);
}
} else {
//regular cubemap, lower quality (aliasing, less memory)
RD::TextureFormat tf;
tf.array_layers = 6;
tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
tf.type = RD::TEXTURE_TYPE_CUBE;
tf.mipmaps = roughness_layers;
tf.width = w;
tf.height = h;
tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT;
sky->radiance = RD::get_singleton()->texture_create(tf, RD::TextureView());
Sky::Layer layer;
uint32_t mmw = w;
uint32_t mmh = h;
layer.mipmaps.resize(roughness_layers);
for (int j = 0; j < roughness_layers; j++) {
Sky::Layer::Mipmap &mm = layer.mipmaps.write[j];
mm.size.width = mmw;
mm.size.height = mmh;
for (int k = 0; k < 6; k++) {
mm.views[k] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), sky->radiance, k, j);
Vector<RID> fbtex;
fbtex.push_back(mm.views[k]);
mm.framebuffers[k] = RD::get_singleton()->framebuffer_create(fbtex);
}
mmw = MAX(1, mmw >> 1);
mmh = MAX(1, mmh >> 1);
}
sky->layers.push_back(layer);
}
sky->radiance_base_cubemap = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), sky->radiance, 0, 0, RD::TEXTURE_SLICE_CUBEMAP);
}
RID panorama_texture = storage->texture_get_rd_texture(sky->panorama);
if (panorama_texture.is_valid()) {
//is there a panorama texture?
if (sky_use_cubemap_array) {
if (sky->mode == VS::SKY_MODE_QUALITY) {
//render directly to the layers
for (int i = 0; i < sky->layers.size(); i++) {
for (int j = 0; j < 6; j++) {
storage->get_effects()->cubemap_roughness(panorama_texture, true, sky->layers[i].mipmaps[0].framebuffers[j], j, sky_ggx_samples_quality, float(i) / (sky->layers.size() - 1.0));
}
}
} else if (sky->mode == VS::SKY_MODE_REALTIME) {
//render to first mipmap
for (int j = 0; j < 6; j++) {
storage->get_effects()->cubemap_roughness(panorama_texture, true, sky->layers[0].mipmaps[0].framebuffers[j], j, sky_ggx_samples_realtime, 0.0);
}
//do the rest in other mipmaps and use cubemap itself as source
for (int i = 1; i < roughness_layers; i++) {
//render using a smaller mipmap, then copy to main layer
for (int j = 0; j < 6; j++) {
//storage->get_effects()->cubemap_roughness(sky->radiance_base_cubemap, false, sky->layers[0].mipmaps[i].framebuffers[0], j, sky_ggx_samples_realtime, float(i) / (sky->layers.size() - 1.0));
storage->get_effects()->cubemap_roughness(panorama_texture, true, sky->layers[0].mipmaps[i].framebuffers[0], j, sky_ggx_samples_realtime, float(i) / (sky->layers.size() - 1.0));
storage->get_effects()->copy(sky->layers[0].mipmaps[i].views[0], sky->layers[i].mipmaps[0].framebuffers[j], Rect2());
}
}
}
//generate mipmaps
for (int i = 0; i < sky->layers.size(); i++) {
for (int j = 0; j < sky->layers[i].mipmaps.size() - 1; j++) {
for (int k = 0; k < 6; k++) {
RID view = sky->layers[i].mipmaps[j].views[k];
RID fb = sky->layers[i].mipmaps[j + 1].framebuffers[k];
Vector2 size = sky->layers[i].mipmaps[j].size;
size = Vector2(1.0 / size.x, 1.0 / size.y);
storage->get_effects()->make_mipmap(view, fb, size);
}
}
}
} else {
if (sky->mode == VS::SKY_MODE_QUALITY) {
//render directly to the layers
for (int i = 0; i < sky->layers[0].mipmaps.size(); i++) {
for (int j = 0; j < 6; j++) {
storage->get_effects()->cubemap_roughness(panorama_texture, true, sky->layers[0].mipmaps[i].framebuffers[j], j, sky_ggx_samples_quality, float(i) / (sky->layers[0].mipmaps.size() - 1.0));
}
}
} else {
for (int j = 0; j < 6; j++) {
storage->get_effects()->cubemap_roughness(panorama_texture, true, sky->layers[0].mipmaps[0].framebuffers[j], j, sky_ggx_samples_realtime, 0);
}
for (int i = 1; i < sky->layers[0].mipmaps.size(); i++) {
for (int j = 0; j < 6; j++) {
storage->get_effects()->cubemap_roughness(sky->radiance_base_cubemap, false, sky->layers[0].mipmaps[i].framebuffers[j], j, sky_ggx_samples_realtime, float(i) / (sky->layers[0].mipmaps.size() - 1.0));
}
}
}
}
}
Sky *next = sky->dirty_list;
sky->dirty_list = nullptr;
sky->dirty = false;
sky = next;
}
dirty_sky_list = nullptr;
}
RID RasterizerSceneRD::sky_get_panorama_texture_rd(RID p_sky) const {
Sky *sky = sky_owner.getornull(p_sky);
ERR_FAIL_COND_V(!sky, RID());
if (sky->panorama.is_null()) {
return RID();
}
return storage->texture_get_rd_texture(sky->panorama, true);
}
RID RasterizerSceneRD::sky_get_radiance_texture_rd(RID p_sky) const {
Sky *sky = sky_owner.getornull(p_sky);
ERR_FAIL_COND_V(!sky, RID());
return sky->radiance;
}
RID RasterizerSceneRD::environment_create() {
return environment_owner.make_rid(Environent());
}
void RasterizerSceneRD::environment_set_background(RID p_env, VS::EnvironmentBG p_bg) {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
env->background = p_bg;
}
void RasterizerSceneRD::environment_set_sky(RID p_env, RID p_sky) {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
env->sky = p_sky;
}
void RasterizerSceneRD::environment_set_sky_custom_fov(RID p_env, float p_scale) {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
env->sky_custom_fov = p_scale;
}
void RasterizerSceneRD::environment_set_sky_orientation(RID p_env, const Basis &p_orientation) {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
env->sky_orientation = p_orientation;
}
void RasterizerSceneRD::environment_set_bg_color(RID p_env, const Color &p_color) {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
env->bg_color = p_color;
}
void RasterizerSceneRD::environment_set_bg_energy(RID p_env, float p_energy) {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
env->bg_energy = p_energy;
}
void RasterizerSceneRD::environment_set_canvas_max_layer(RID p_env, int p_max_layer) {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
env->canvas_max_layer = p_max_layer;
}
void RasterizerSceneRD::environment_set_ambient_light(RID p_env, const Color &p_color, VS::EnvironmentAmbientSource p_ambient, float p_energy, float p_sky_contribution, VS::EnvironmentReflectionSource p_reflection_source) {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
env->ambient_light = p_color;
env->ambient_source = p_ambient;
env->ambient_light_energy = p_energy;
env->ambient_sky_contribution = p_sky_contribution;
env->reflection_source = p_reflection_source;
}
VS::EnvironmentBG RasterizerSceneRD::environment_get_background(RID p_env) const {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, VS::ENV_BG_MAX);
return env->background;
}
RID RasterizerSceneRD::environment_get_sky(RID p_env) const {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, RID());
return env->sky;
}
float RasterizerSceneRD::environment_get_sky_custom_fov(RID p_env) const {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, 0);
return env->sky_custom_fov;
}
Basis RasterizerSceneRD::environment_get_sky_orientation(RID p_env) const {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, Basis());
return env->sky_orientation;
}
Color RasterizerSceneRD::environment_get_bg_color(RID p_env) const {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, Color());
return env->bg_color;
}
float RasterizerSceneRD::environment_get_bg_energy(RID p_env) const {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, 0);
return env->bg_energy;
}
int RasterizerSceneRD::environment_get_canvas_max_layer(RID p_env) const {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, 0);
return env->canvas_max_layer;
}
Color RasterizerSceneRD::environment_get_ambient_light_color(RID p_env) const {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, Color());
return env->ambient_light;
}
VS::EnvironmentAmbientSource RasterizerSceneRD::environment_get_ambient_light_ambient_source(RID p_env) const {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, VS::ENV_AMBIENT_SOURCE_BG);
return env->ambient_source;
}
float RasterizerSceneRD::environment_get_ambient_light_ambient_energy(RID p_env) const {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, 0);
return env->ambient_light_energy;
}
float RasterizerSceneRD::environment_get_ambient_sky_contribution(RID p_env) const {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, 0);
return env->ambient_sky_contribution;
}
VS::EnvironmentReflectionSource RasterizerSceneRD::environment_get_reflection_source(RID p_env) const {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, VS::ENV_REFLECTION_SOURCE_DISABLED);
return env->reflection_source;
}
bool RasterizerSceneRD::is_environment(RID p_env) const {
return environment_owner.owns(p_env);
}
RID RasterizerSceneRD::render_buffers_create() {
RenderBuffers rb;
@ -16,6 +378,14 @@ void RasterizerSceneRD::render_buffers_configure(RID p_render_buffers, RID p_ren
rb->data->configure(p_render_target, p_width, p_height, p_msaa);
}
int RasterizerSceneRD::get_roughness_layers() const {
return roughness_layers;
}
bool RasterizerSceneRD::is_using_radiance_cubemap_array() const {
return sky_use_cubemap_array;
}
void RasterizerSceneRD::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) {
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
@ -30,6 +400,14 @@ bool RasterizerSceneRD::free(RID p_rid) {
RenderBuffers *rb = render_buffers_owner.getornull(p_rid);
memdelete(rb->data);
render_buffers_owner.free(p_rid);
} else if (environment_owner.owns(p_rid)) {
//not much to delete, just free it
environment_owner.free(p_rid);
} else if (sky_owner.owns(p_rid)) {
_update_dirty_skys();
Sky *sky = sky_owner.getornull(p_rid);
RD::get_singleton()->free(sky->radiance); //free radiance, everything else gets dependency-erased
sky_owner.free(p_rid);
} else {
return false;
}
@ -37,5 +415,16 @@ bool RasterizerSceneRD::free(RID p_rid) {
return true;
}
RasterizerSceneRD::RasterizerSceneRD() {
void RasterizerSceneRD::update() {
_update_dirty_skys();
}
RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) {
storage = p_storage;
roughness_layers = GLOBAL_GET("rendering/quality/reflections/roughness_layers");
sky_ggx_samples_quality = GLOBAL_GET("rendering/quality/reflections/ggx_samples");
sky_ggx_samples_realtime = GLOBAL_GET("rendering/quality/reflections/ggx_samples_realtime");
sky_use_cubemap_array = GLOBAL_GET("rendering/quality/reflections/texture_array_reflections");
sky_use_cubemap_array = false;
}

View file

@ -3,6 +3,9 @@
#include "core/rid_owner.h"
#include "servers/visual/rasterizer.h"
#include "servers/visual/rasterizer_rd/rasterizer_storage_rd.h"
#include "servers/visual/rendering_device.h"
class RasterizerSceneRD : public RasterizerScene {
protected:
struct RenderBufferData {
@ -15,6 +18,58 @@ 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) = 0;
private:
int roughness_layers;
RasterizerStorageRD *storage;
struct Sky {
int radiance_size = 256;
VS::SkyMode mode = VS::SKY_MODE_QUALITY;
RID panorama;
RID radiance;
bool dirty = false;
Sky *dirty_list = nullptr;
struct Layer {
struct Mipmap {
RID framebuffers[6];
RID views[6];
Size2i size;
};
Vector<Mipmap> mipmaps;
};
RID radiance_base_cubemap; //cubemap for first layer, first cubemap
Vector<Layer> layers;
};
Sky *dirty_sky_list = nullptr;
void _sky_invalidate(Sky *p_sky);
void _update_dirty_skys();
uint32_t sky_ggx_samples_quality;
uint32_t sky_ggx_samples_realtime;
bool sky_use_cubemap_array;
mutable RID_Owner<Sky> sky_owner;
struct Environent {
VS::EnvironmentBG background = VS::ENV_BG_CLEAR_COLOR;
RID sky;
float sky_custom_fov = 0.0;
Basis sky_orientation;
Color bg_color;
float bg_energy = 1.0;
int canvas_max_layer = 0;
VS::EnvironmentAmbientSource ambient_source = VS::ENV_AMBIENT_SOURCE_BG;
Color ambient_light;
float ambient_light_energy = 1.0;
float ambient_sky_contribution = 1.0;
VS::EnvironmentReflectionSource reflection_source = VS::ENV_REFLECTION_SOURCE_BG;
};
mutable RID_Owner<Environent> environment_owner;
struct RenderBuffers {
RenderBufferData *data = nullptr;
@ -23,7 +78,7 @@ private:
RID render_target;
};
RID_Owner<RenderBuffers> render_buffers_owner;
mutable RID_Owner<RenderBuffers> render_buffers_owner;
public:
/* SHADOW ATLAS API */
@ -36,18 +91,43 @@ public:
int get_directional_light_shadow_size(RID p_light_intance) { return 0; }
void set_directional_shadow_count(int p_count) {}
/* SKY API */
RID sky_create();
void sky_set_radiance_size(RID p_sky, int p_radiance_size);
void sky_set_mode(RID p_sky, VS::SkyMode p_mode);
void sky_set_texture(RID p_sky, RID p_panorama);
RID sky_get_panorama_texture_rd(RID p_sky) const;
RID sky_get_radiance_texture_rd(RID p_sky) const;
/* ENVIRONMENT API */
RID environment_create() { return RID(); }
RID environment_create();
void environment_set_background(RID p_env, VS::EnvironmentBG p_bg) {}
void environment_set_sky(RID p_env, RID p_sky) {}
void environment_set_sky_custom_fov(RID p_env, float p_scale) {}
void environment_set_sky_orientation(RID p_env, const Basis &p_orientation) {}
void environment_set_bg_color(RID p_env, const Color &p_color) {}
void environment_set_bg_energy(RID p_env, float p_energy) {}
void environment_set_canvas_max_layer(RID p_env, int p_max_layer) {}
void environment_set_ambient_light(RID p_env, const Color &p_color, float p_energy = 1.0, float p_sky_contribution = 0.0) {}
void environment_set_background(RID p_env, VS::EnvironmentBG p_bg);
void environment_set_sky(RID p_env, RID p_sky);
void environment_set_sky_custom_fov(RID p_env, float p_scale);
void environment_set_sky_orientation(RID p_env, const Basis &p_orientation);
void environment_set_bg_color(RID p_env, const Color &p_color);
void environment_set_bg_energy(RID p_env, float p_energy);
void environment_set_canvas_max_layer(RID p_env, int p_max_layer);
void environment_set_ambient_light(RID p_env, const Color &p_color, VS::EnvironmentAmbientSource p_ambient = VS::ENV_AMBIENT_SOURCE_BG, float p_energy = 1.0, float p_sky_contribution = 0.0, VS::EnvironmentReflectionSource p_reflection_source = VS::ENV_REFLECTION_SOURCE_BG);
VS::EnvironmentBG environment_get_background(RID p_env) const;
RID environment_get_sky(RID p_env) const;
float environment_get_sky_custom_fov(RID p_env) const;
Basis environment_get_sky_orientation(RID p_env) const;
Color environment_get_bg_color(RID p_env) const;
float environment_get_bg_energy(RID p_env) const;
int environment_get_canvas_max_layer(RID p_env) const;
Color environment_get_ambient_light_color(RID p_env) const;
VS::EnvironmentAmbientSource environment_get_ambient_light_ambient_source(RID p_env) const;
float environment_get_ambient_light_ambient_energy(RID p_env) const;
float environment_get_ambient_sky_contribution(RID p_env) const;
VS::EnvironmentReflectionSource environment_get_reflection_source(RID p_env) const;
bool is_environment(RID p_env) const;
void environment_set_dof_blur_near(RID p_env, bool p_enable, float p_distance, float p_transition, float p_far_amount, VS::EnvironmentDOFBlurQuality p_quality) {}
void environment_set_dof_blur_far(RID p_env, bool p_enable, float p_distance, float p_transition, float p_far_amount, VS::EnvironmentDOFBlurQuality p_quality) {}
@ -66,10 +146,6 @@ 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) {}
bool is_environment(RID p_env) { return false; }
VS::EnvironmentBG environment_get_background(RID p_env) { return VS::ENV_BG_KEEP; }
int environment_get_canvas_max_layer(RID p_env) { return 0; }
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) {}
@ -97,9 +173,14 @@ public:
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);
int get_roughness_layers() const;
bool is_using_radiance_cubemap_array() const;
virtual bool free(RID p_rid);
RasterizerSceneRD();
virtual void update();
RasterizerSceneRD(RasterizerStorageRD *p_storage);
};
#endif // RASTERIZER_SCENE_RD_H

View file

@ -2598,6 +2598,61 @@ RasterizerStorageRD::RasterizerStorageRD() {
default_rd_textures[DEFAULT_RD_TEXTURE_MULTIMESH_BUFFER] = RD::get_singleton()->texture_buffer_create(16, RD::DATA_FORMAT_R8G8B8A8_UNORM, pv);
}
{ //create default cubemap
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;
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_ARRAY_BLACK] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv);
}
}
{ //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++) {

View file

@ -77,6 +77,8 @@ public:
DEFAULT_RD_TEXTURE_NORMAL,
DEFAULT_RD_TEXTURE_ANISO,
DEFAULT_RD_TEXTURE_MULTIMESH_BUFFER,
DEFAULT_RD_TEXTURE_CUBEMAP_BLACK,
DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK,
DEFAULT_RD_TEXTURE_MAX
};
@ -393,11 +395,6 @@ public:
return default_rd_samplers[p_filter][p_repeat];
}
/* SKY API */
RID sky_create() { return RID(); }
void sky_set_texture(RID p_sky, RID p_cube_map, int p_radiance_size) {}
/* SHADER API */
RID shader_create();

View file

@ -6,5 +6,7 @@ if 'RD_GLSL' in env['BUILDERS']:
env.RD_GLSL('canvas.glsl');
env.RD_GLSL('canvas_occlusion.glsl');
env.RD_GLSL('blur.glsl');
env.RD_GLSL('cubemap_roughness.glsl');
env.RD_GLSL('scene_forward.glsl');
env.RD_GLSL('scene_forward_inc.glsl');
env.RD_GLSL('sky.glsl');

View file

@ -85,6 +85,17 @@ const float dof_kernel[21] = float[](0.028174, 0.032676, 0.037311, 0.041944, 0.0
void main() {
#ifdef MODE_MIPMAP
vec2 pix_size = blur.pixel_size;
vec4 color = texture(source_color, uv_interp + vec2(-0.5,-0.5) * pix_size);
color += texture(source_color, uv_interp + vec2(0.5,-0.5) * pix_size);
color += texture(source_color, uv_interp + vec2(0.5,0.5) * pix_size);
color += texture(source_color, uv_interp + vec2(-0.5,0.5) * pix_size);
frag_color = color / 4.0;
#endif
#ifdef MODE_GAUSSIAN_BLUR
//Simpler blur uses SIGMA2 for the gaussian kernel for a stronger effect

View file

@ -13,8 +13,7 @@ layout(location = 0) in vec2 vertex_attrib;
layout(location = 3) in vec4 color_attrib;
layout(location = 4) in vec2 uv_attrib;
layout(location = 6) in uvec4 bone_indices_attrib;
layout(location = 7) in vec4 bone_weights_attrib;
layout(location = 6) in uvec4 bones_attrib;
#endif
@ -68,8 +67,7 @@ void main() {
uv = draw_data.uvs[2];
color = vec4(unpackHalf2x16(draw_data.colors[4]),unpackHalf2x16(draw_data.colors[5]));
}
uvec4 bone_indices = uvec4(0,0,0,0);
vec4 bone_weights = vec4(0,0,0,0);
uvec4 bones = uvec4(0,0,0,0);
#elif defined(USE_ATTRIBUTES)
@ -77,8 +75,7 @@ void main() {
vec4 color = color_attrib;
vec2 uv = uv_attrib;
uvec4 bone_indices = bone_indices_attrib;
vec4 bone_weights = bone_weights_attrib;
uvec4 bones = bones_attrib;
#else
vec2 vertex_base_arr[4] = vec2[](vec2(0.0,0.0),vec2(0.0,1.0),vec2(1.0,1.0),vec2(1.0,0.0));
@ -87,8 +84,7 @@ void main() {
vec2 uv = draw_data.src_rect.xy + abs(draw_data.src_rect.zw) * ((draw_data.flags&FLAGS_TRANSPOSE_RECT)!=0 ? vertex_base.yx : vertex_base.xy);
vec4 color = draw_data.modulation;
vec2 vertex = draw_data.dst_rect.xy + abs(draw_data.dst_rect.zw) * mix(vertex_base, vec2(1.0, 1.0) - vertex_base, lessThan(draw_data.src_rect.zw, vec2(0.0, 0.0)));
uvec4 bone_indices = uvec4(0,0,0,0);
vec4 bone_weights = vec4(0,0,0,0);
uvec4 bones = uvec4(0,0,0,0);
#endif

View file

@ -0,0 +1,234 @@
/* clang-format off */
[vertex]
/* clang-format on */
#version 450
/* clang-format off */
VERSION_DEFINES
/* clang-format on */
layout(location=0) out highp 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 */
#ifdef MODE_SOURCE_PANORAMA
layout( set=0, binding=0 ) uniform sampler2D source_panorama;
#endif
#ifdef MODE_SOURCE_CUBEMAP
layout( set=0, binding=0 ) uniform samplerCube source_cube;
#endif
layout(push_constant, binding = 1, std430) uniform Params {
uint face_id;
uint sample_count;
float roughness;
bool use_direct_write;
} params;
layout(location=0) in vec2 uv_interp;
layout(location = 0) out vec4 frag_color;
#define M_PI 3.14159265359
vec3 texelCoordToVec(vec2 uv, uint faceID) {
mat3 faceUvVectors[6];
/*
// -x
faceUvVectors[0][0] = vec3(0.0, 0.0, 1.0); // u -> +z
faceUvVectors[0][1] = vec3(0.0, -1.0, 0.0); // v -> -y
faceUvVectors[0][2] = vec3(-1.0, 0.0, 0.0); // -x face
// +x
faceUvVectors[1][0] = vec3(0.0, 0.0, -1.0); // u -> -z
faceUvVectors[1][1] = vec3(0.0, -1.0, 0.0); // v -> -y
faceUvVectors[1][2] = vec3(1.0, 0.0, 0.0); // +x face
// -y
faceUvVectors[2][0] = vec3(1.0, 0.0, 0.0); // u -> +x
faceUvVectors[2][1] = vec3(0.0, 0.0, -1.0); // v -> -z
faceUvVectors[2][2] = vec3(0.0, -1.0, 0.0); // -y face
// +y
faceUvVectors[3][0] = vec3(1.0, 0.0, 0.0); // u -> +x
faceUvVectors[3][1] = vec3(0.0, 0.0, 1.0); // v -> +z
faceUvVectors[3][2] = vec3(0.0, 1.0, 0.0); // +y face
// -z
faceUvVectors[4][0] = vec3(-1.0, 0.0, 0.0); // u -> -x
faceUvVectors[4][1] = vec3(0.0, -1.0, 0.0); // v -> -y
faceUvVectors[4][2] = vec3(0.0, 0.0, -1.0); // -z face
// +z
faceUvVectors[5][0] = vec3(1.0, 0.0, 0.0); // u -> +x
faceUvVectors[5][1] = vec3(0.0, -1.0, 0.0); // v -> -y
faceUvVectors[5][2] = vec3(0.0, 0.0, 1.0); // +z face
*/
// -x
faceUvVectors[1][0] = vec3(0.0, 0.0, 1.0); // u -> +z
faceUvVectors[1][1] = vec3(0.0, -1.0, 0.0); // v -> -y
faceUvVectors[1][2] = vec3(-1.0, 0.0, 0.0); // -x face
// +x
faceUvVectors[0][0] = vec3(0.0, 0.0, -1.0); // u -> -z
faceUvVectors[0][1] = vec3(0.0, -1.0, 0.0); // v -> -y
faceUvVectors[0][2] = vec3(1.0, 0.0, 0.0); // +x face
// -y
faceUvVectors[3][0] = vec3(1.0, 0.0, 0.0); // u -> +x
faceUvVectors[3][1] = vec3(0.0, 0.0, -1.0); // v -> -z
faceUvVectors[3][2] = vec3(0.0, -1.0, 0.0); // -y face
// +y
faceUvVectors[2][0] = vec3(1.0, 0.0, 0.0); // u -> +x
faceUvVectors[2][1] = vec3(0.0, 0.0, 1.0); // v -> +z
faceUvVectors[2][2] = vec3(0.0, 1.0, 0.0); // +y face
// -z
faceUvVectors[5][0] = vec3(-1.0, 0.0, 0.0); // u -> -x
faceUvVectors[5][1] = vec3(0.0, -1.0, 0.0); // v -> -y
faceUvVectors[5][2] = vec3(0.0, 0.0, -1.0); // -z face
// +z
faceUvVectors[4][0] = vec3(1.0, 0.0, 0.0); // u -> +x
faceUvVectors[4][1] = vec3(0.0, -1.0, 0.0); // v -> -y
faceUvVectors[4][2] = vec3(0.0, 0.0, 1.0); // +z face
// out = u * s_faceUv[0] + v * s_faceUv[1] + s_faceUv[2].
vec3 result = (faceUvVectors[faceID][0] * uv.x) + (faceUvVectors[faceID][1] * uv.y) + faceUvVectors[faceID][2];
return normalize(result);
}
vec3 ImportanceSampleGGX(vec2 Xi, float Roughness, vec3 N) {
float a = Roughness * Roughness; // DISNEY'S ROUGHNESS [see Burley'12 siggraph]
// Compute distribution direction
float Phi = 2.0 * M_PI * Xi.x;
float CosTheta = sqrt((1.0 - Xi.y) / (1.0 + (a * a - 1.0) * Xi.y));
float SinTheta = sqrt(1.0 - CosTheta * CosTheta);
// Convert to spherical direction
vec3 H;
H.x = SinTheta * cos(Phi);
H.y = SinTheta * sin(Phi);
H.z = CosTheta;
vec3 UpVector = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
vec3 TangentX = normalize(cross(UpVector, N));
vec3 TangentY = cross(N, TangentX);
// Tangent to world space
return TangentX * H.x + TangentY * H.y + N * H.z;
}
// http://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html
float GGX(float NdotV, float a) {
float k = a / 2.0;
return NdotV / (NdotV * (1.0 - k) + k);
}
// http://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html
float G_Smith(float a, float nDotV, float nDotL) {
return GGX(nDotL, a * a) * GGX(nDotV, a * a);
}
float radicalInverse_VdC(uint bits) {
bits = (bits << 16u) | (bits >> 16u);
bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
return float(bits) * 2.3283064365386963e-10; // / 0x100000000
}
vec2 Hammersley(uint i, uint N) {
return vec2(float(i) / float(N), radicalInverse_VdC(i));
}
#ifdef MODE_SOURCE_PANORAMA
vec4 texturePanorama(vec3 normal, sampler2D pano) {
vec2 st = vec2(
atan(normal.x, -normal.z),
acos(normal.y));
if (st.x < 0.0)
st.x += M_PI * 2.0;
st /= vec2(M_PI * 2.0, M_PI);
return textureLod(pano, st, 0.0);
}
#endif
void main() {
vec2 uv = (uv_interp * 2.0) - 1.0;
vec3 N = texelCoordToVec(uv, params.face_id);
//vec4 color = color_interp;
if (params.use_direct_write) {
#ifdef MODE_SOURCE_PANORAMA
frag_color = vec4(texturePanorama(N, source_panorama).rgb, 1.0);
#endif
#ifdef MODE_SOURCE_CUBEMAP
frag_color = vec4(texture(source_cube,N).rgb, 1.0);
#endif
} else {
vec4 sum = vec4(0.0, 0.0, 0.0, 0.0);
for (uint sampleNum = 0u; sampleNum < params.sample_count; sampleNum++) {
vec2 xi = Hammersley(sampleNum, params.sample_count);
vec3 H = ImportanceSampleGGX(xi, params.roughness, N);
vec3 V = N;
vec3 L = (2.0 * dot(V, H) * H - V);
float ndotl = clamp(dot(N, L), 0.0, 1.0);
if (ndotl > 0.0) {
#ifdef MODE_SOURCE_PANORAMA
sum.rgb += texturePanorama(L, source_panorama).rgb * ndotl;
#endif
#ifdef MODE_SOURCE_CUBEMAP
sum.rgb += textureLod(source_cube, L, 0.0).rgb * ndotl;
#endif
sum.a += ndotl;
}
}
sum /= sum.a;
frag_color = vec4(sum.rgb, 1.0);
}
}

View file

@ -44,7 +44,7 @@ layout(location = 2) out vec4 color_interp;
#endif
#if defined(UV_USED)
layout(location = 3) out vec4 uv_interp;
layout(location = 3) out vec2 uv_interp;
#endif
#if defined(UV2_USED) || defined(USE_LIGHTMAP)
@ -186,7 +186,7 @@ VERTEX_SHADER_CODE
#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
@ -215,7 +215,7 @@ layout(location = 2) in vec4 color_interp;
#endif
#if defined(UV_USED)
layout(location = 3) in vec4 uv_interp;
layout(location = 3) in vec2 uv_interp;
#endif
#if defined(UV2_USED) || defined(USE_LIGHTMAP)
@ -351,15 +351,15 @@ LIGHT_SHADER_CODE
float NdotV = dot(N, V);
float cNdotV = max(NdotV, 0.0);
#if defined(DIFFUSE_BURLEY) || defined(SPECULAR_BLINN) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_USE_CLEARCOAT)
#if defined(DIFFUSE_BURLEY) || defined(SPECULAR_BLINN) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_CLEARCOAT_USED)
vec3 H = normalize(V + L);
#endif
#if defined(SPECULAR_BLINN) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_USE_CLEARCOAT)
#if defined(SPECULAR_BLINN) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_CLEARCOAT_USED)
float cNdotH = max(dot(N, H), 0.0);
#endif
#if defined(DIFFUSE_BURLEY) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_USE_CLEARCOAT)
#if defined(DIFFUSE_BURLEY) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_CLEARCOAT_USED)
float cLdotH = max(dot(L, H), 0.0);
#endif
@ -423,7 +423,7 @@ LIGHT_SHADER_CODE
diffuse_light += light_color * diffuse_color * (vec3(1.0 / M_PI) - diffuse_brdf_NL) * transmission * attenuation;
#endif
#if defined(LIGHT_USE_RIM)
#if defined(RIM_LIGHT_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
@ -495,7 +495,7 @@ LIGHT_SHADER_CODE
specular_light += specular_brdf_NL * light_color * specular_blob_intensity * attenuation;
#endif
#if defined(LIGHT_USE_CLEARCOAT)
#if defined(LIGHT_CLEARCOAT_USED)
#if !defined(SPECULAR_SCHLICK_GGX)
float cLdotH5 = SchlickFresnel(cLdotH);
@ -537,7 +537,7 @@ void main() {
float anisotropy = 0.0;
vec2 anisotropy_flow = vec2(1.0, 0.0);
#if defined(ENABLE_AO)
#if defined(AO_USED)
float ao = 1.0;
float ao_light_affect = 0.0;
#endif
@ -651,6 +651,48 @@ FRAGMENT_SHADER_CODE
vec3 diffuse_light = vec3(0.0, 0.0, 0.0);
vec3 ambient_light = vec3( 0.0, 0.0, 0.0);
#ifndef MODE_RENDER_DEPTH
if (scene_data.use_reflection_cubemap){
vec3 ref_vec = reflect(-view, normal);
ref_vec = scene_data.radiance_inverse_xform * ref_vec;
#ifdef USE_RADIANCE_CUBEMAP_ARRAY
float lod,blend;
blend = modf(roughness * MAX_ROUGHNESS_LOD, lod);
specular_light = texture(samplerCubeArray(radiance_cubemap,material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(ref_vec, lod)).rgb;
specular_light = mix(specular_light,texture(samplerCubeArray(radiance_cubemap,material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(ref_vec, lod+1)).rgb,blend);
#else
specular_light = textureLod(samplerCube(radiance_cubemap,material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), ref_vec, roughness * MAX_ROUGHNESS_LOD).rgb;
#endif //USE_RADIANCE_CUBEMAP_ARRAY
specular_light *= scene_data.ambient_light_color_energy.a;
}
#ifndef USE_LIGHTMAP
//lightmap overrides everything
if (scene_data.use_ambient_light){
ambient_light = scene_data.ambient_light_color_energy.rgb;
if (scene_data.use_ambient_cubemap) {
vec3 ambient_dir = scene_data.radiance_inverse_xform * normal;
#ifdef USE_RADIANCE_CUBEMAP_ARRAY
vec3 cubemap_ambient = texture(samplerCubeArray(radiance_cubemap,material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(ambient_dir, MAX_ROUGHNESS_LOD)).rgb;
#else
vec3 cubemap_ambient = textureLod(samplerCube(radiance_cubemap,material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), ambient_dir, MAX_ROUGHNESS_LOD).rgb;
#endif //USE_RADIANCE_CUBEMAP_ARRAY
ambient_light = mix( ambient_light, cubemap_ambient * scene_data.ambient_light_color_energy.a, scene_data.ambient_color_sky_mix );
}
}
#endif // USE_LIGHTMAP
#endif // MODE_RENDER_DEPTH
//radiance
float specular_blob_intensity = 1.0;
@ -722,7 +764,7 @@ FRAGMENT_SHADER_CODE
specular_light *= scene_data.reflection_multiplier;
ambient_light *= albedo; //ambient must be multiplied by albedo at the end
#if defined(ENABLE_AO)
#if defined(AO_USED)
ambient_light *= ao;
ao_light_affect = mix(1.0, ao, ao_light_affect);
specular_light *= ao_light_affect;
@ -753,8 +795,8 @@ FRAGMENT_SHADER_CODE
#ifdef USE_NO_SHADING
frag_color = vec4(albedo, alpha);
#else
//frag_color = vec4(emission + ambient_light + diffuse_light + specular_light, alpha);
frag_color = vec4(1.0);
frag_color = vec4(emission + ambient_light + diffuse_light + specular_light, alpha);
//frag_color = vec4(1.0);
#endif //USE_NO_SHADING

View file

@ -7,8 +7,35 @@
layout(set=0,binding=1) uniform texture2D depth_buffer;
layout(set=0,binding=2) uniform texture2D color_buffer;
layout(set=0,binding=3) uniform texture2D normal_buffer;
layout(set=0,binding=4) uniform texture2D roughness_limit;
layout(set=0,binding=4,std140) uniform SceneData {
#ifdef USE_RADIANCE_CUBEMAP_ARRAY
layout(set = 0, binding = 5) uniform textureCubeArray radiance_cubemap;
#else
layout(set = 0, binding = 5) uniform textureCube radiance_cubemap;
#endif
#define SAMPLER_NEAREST_CLAMP 0
#define SAMPLER_LINEAR_CLAMP 1
#define SAMPLER_NEAREST_WITH_MIMPAMPS_CLAMP 2
#define SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP 3
#define SAMPLER_NEAREST_WITH_MIMPAMPS_ANISOTROPIC_CLAMP 4
#define SAMPLER_LINEAR_WITH_MIPMAPS_ANISOTROPIC_CLAMP 5
#define SAMPLER_NEAREST_REPEAT 6
#define SAMPLER_LINEAR_REPEAT 7
#define SAMPLER_NEAREST_WITH_MIMPAMPS_REPEAT 8
#define SAMPLER_LINEAR_WITH_MIPMAPS_REPEAT 9
#define SAMPLER_NEAREST_WITH_MIMPAMPS_ANISOTROPIC_REPEAT 10
#define SAMPLER_LINEAR_WITH_MIPMAPS_ANISOTROPIC_REPEAT 11
layout(set = 0, binding = 6) uniform sampler material_samplers[12];
layout(set=0,binding=7,std140) uniform SceneData {
mat4 projection_matrix;
mat4 inv_projection_matrix;
@ -27,6 +54,15 @@ layout(set=0,binding=4,std140) uniform SceneData {
float time;
float reflection_multiplier; // one normally, zero when rendering reflections
vec4 ambient_light_color_energy;
float ambient_color_sky_mix;
bool use_ambient_light;
bool use_ambient_cubemap;
bool use_reflection_cubemap;
mat3 radiance_inverse_xform;
#if 0
vec4 ambient_light_color;
vec4 bg_color;
@ -65,7 +101,6 @@ layout(set=0,binding=4,std140) uniform SceneData {
#endif
} scene_data;
layout(set = 0, binding = 5) uniform sampler material_samplers[12];
#if 0
struct DirectionalLightData {

View file

@ -0,0 +1,89 @@
/* clang-format off */
[vertex]
/* clang-format on */
#version 450
/* clang-format off */
VERSION_DEFINES
/* clang-format on */
layout(location =0) out vec2 uv_interp;
layout(push_constant, binding = 1, std430) uniform Params {
mat3 orientation;
vec4 proj;
float multiplier;
float alpha;
float depth;
float pad;
} params;
void main() {
vec2 base_arr[4] = vec2[](vec2(-1.0,-1.0),vec2(-1.0,1.0),vec2(1.0,1.0),vec2(1.0,-1.0));
uv_interp = base_arr[gl_VertexIndex];
gl_Position = vec4(uv_interp,params.depth,1.0);
}
/* clang-format off */
[fragment]
/* clang-format on */
#version 450
/* clang-format off */
VERSION_DEFINES
/* clang-format on */
#define M_PI 3.14159265359
layout(location =0) in vec2 uv_interp;
layout( set=0, binding=0 ) uniform sampler2D source_panorama;
layout(push_constant, binding = 1, std430) uniform Params {
mat3 orientation;
vec4 proj;
float multiplier;
float alpha;
float depth;
float pad;
} params;
vec4 texturePanorama(sampler2D pano, vec3 normal) {
vec2 st = vec2(
atan(normal.x, normal.z),
acos(normal.y));
if (st.x < 0.0)
st.x += M_PI * 2.0;
st /= vec2(M_PI * 2.0, M_PI);
return texture(pano, st);
}
layout(location = 0) out vec4 frag_color;
void main() {
vec3 cube_normal;
cube_normal.z = -1000000.0;
cube_normal.x = (cube_normal.z * (-uv_interp.x - params.proj.x)) / params.proj.y;
cube_normal.y = -(cube_normal.z * (-uv_interp.y - params.proj.z)) / params.proj.w;
cube_normal = mat3(params.orientation) * cube_normal;
cube_normal.z = -cube_normal.z;
frag_color.rgb = texturePanorama(source_panorama, normalize(cube_normal.xyz)).rgb;
frag_color.a = params.alpha;
}

View file

@ -409,7 +409,13 @@ public:
virtual RID texture_create(const TextureFormat &p_format, const TextureView &p_view, const Vector<PoolVector<uint8_t> > &p_data = Vector<PoolVector<uint8_t> >()) = 0;
virtual RID texture_create_shared(const TextureView &p_view, RID p_with_texture) = 0;
virtual RID texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap) = 0;
enum TextureSliceType {
TEXTURE_SLICE_2D,
TEXTURE_SLICE_CUBEMAP
};
virtual RID texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, TextureSliceType p_slice_type = TEXTURE_SLICE_2D) = 0;
virtual Error texture_update(RID p_texture, uint32_t p_layer, const PoolVector<uint8_t> &p_data, bool p_sync_with_draw = false) = 0; //this function can be used from any thread and it takes effect at the begining of the frame, unless sync with draw is used, which is used to mix updates with draw calls
virtual PoolVector<uint8_t> texture_get_data(RID p_texture, uint32_t p_layer) = 0; // CPU textures will return immediately, while GPU textures will most likely force a flush

View file

@ -105,6 +105,8 @@ void VisualServerRaster::draw(bool p_swap_buffers, double frame_step) {
VSG::scene->update_dirty_instances(); //update scene stuff
VSG::scene_render->update();
VSG::viewport->draw_viewports();
VSG::scene->render_probes();
VSG::canvas_render->update();

View file

@ -186,11 +186,6 @@ public:
BIND2(texture_set_force_redraw_if_visible, RID, bool)
/* SKY API */
BIND0R(RID, sky_create)
BIND3(sky_set_texture, RID, RID, int)
/* SHADER API */
BIND0R(RID, shader_create)
@ -494,6 +489,13 @@ public:
//from now on, calls forwarded to this singleton
#define BINDBASE VSG::scene_render
/* SKY API */
BIND0R(RID, sky_create)
BIND2(sky_set_radiance_size, RID, int)
BIND2(sky_set_mode, RID, SkyMode)
BIND2(sky_set_texture, RID, RID)
BIND0R(RID, environment_create)
BIND2(environment_set_background, RID, EnvironmentBG)
@ -503,7 +505,8 @@ public:
BIND2(environment_set_bg_color, RID, const Color &)
BIND2(environment_set_bg_energy, RID, float)
BIND2(environment_set_canvas_max_layer, RID, int)
BIND4(environment_set_ambient_light, RID, const Color &, float, float)
BIND6(environment_set_ambient_light, RID, const Color &, EnvironmentAmbientSource, float, float, EnvironmentReflectionSource)
// FIXME: Disabled during Vulkan refactoring, should be ported.
#if 0
BIND2(environment_set_camera_feed_id, RID, int)

View file

@ -711,7 +711,9 @@ void VisualServerScene::instance_set_use_lightmap(RID p_instance, RID p_lightmap
instance->lightmap = p_lightmap;
}
VSG::scene_render->instance_custom_data_update_lightmap(instance);
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) {

View file

@ -117,11 +117,6 @@ public:
FUNC2(texture_set_force_redraw_if_visible, RID, bool)
/* SKY API */
FUNCRID(sky)
FUNC3(sky_set_texture, RID, RID, int)
/* SHADER API */
FUNCRID(shader)
@ -409,6 +404,13 @@ public:
FUNC2(viewport_set_debug_draw, RID, ViewportDebugDraw)
/* SKY API */
FUNCRID(sky)
FUNC2(sky_set_radiance_size, RID, int)
FUNC2(sky_set_mode, RID, SkyMode)
FUNC2(sky_set_texture, RID, RID)
/* ENVIRONMENT API */
FUNCRID(environment)
@ -420,7 +422,8 @@ public:
FUNC2(environment_set_bg_color, RID, const Color &)
FUNC2(environment_set_bg_energy, RID, float)
FUNC2(environment_set_canvas_max_layer, RID, int)
FUNC4(environment_set_ambient_light, RID, const Color &, float, float)
FUNC6(environment_set_ambient_light, RID, const Color &, EnvironmentAmbientSource, float, float, EnvironmentReflectionSource)
// FIXME: Disabled during Vulkan refactoring, should be ported.
#if 0
FUNC2(environment_set_camera_feed_id, RID, int)

View file

@ -1602,7 +1602,7 @@ void VisualServer::_bind_methods() {
#ifndef _3D_DISABLED
ClassDB::bind_method(D_METHOD("sky_create"), &VisualServer::sky_create);
ClassDB::bind_method(D_METHOD("sky_set_texture", "sky", "cube_map", "radiance_size"), &VisualServer::sky_set_texture);
ClassDB::bind_method(D_METHOD("sky_set_texture", "sky", "panorama"), &VisualServer::sky_set_texture);
#endif
ClassDB::bind_method(D_METHOD("shader_create"), &VisualServer::shader_create);
ClassDB::bind_method(D_METHOD("shader_set_code", "shader", "code"), &VisualServer::shader_set_code);
@ -2171,11 +2171,19 @@ void VisualServer::_bind_methods() {
BIND_ENUM_CONSTANT(ENV_BG_CLEAR_COLOR);
BIND_ENUM_CONSTANT(ENV_BG_COLOR);
BIND_ENUM_CONSTANT(ENV_BG_SKY);
BIND_ENUM_CONSTANT(ENV_BG_COLOR_SKY);
BIND_ENUM_CONSTANT(ENV_BG_CANVAS);
BIND_ENUM_CONSTANT(ENV_BG_KEEP);
BIND_ENUM_CONSTANT(ENV_BG_MAX);
BIND_ENUM_CONSTANT(ENV_AMBIENT_SOURCE_BG);
BIND_ENUM_CONSTANT(ENV_AMBIENT_SOURCE_DISABLED);
BIND_ENUM_CONSTANT(ENV_AMBIENT_SOURCE_COLOR);
BIND_ENUM_CONSTANT(ENV_AMBIENT_SOURCE_SKY);
BIND_ENUM_CONSTANT(ENV_REFLECTION_SOURCE_BG);
BIND_ENUM_CONSTANT(ENV_REFLECTION_SOURCE_DISABLED);
BIND_ENUM_CONSTANT(ENV_REFLECTION_SOURCE_SKY);
BIND_ENUM_CONSTANT(ENV_DOF_BLUR_QUALITY_LOW);
BIND_ENUM_CONSTANT(ENV_DOF_BLUR_QUALITY_MEDIUM);
BIND_ENUM_CONSTANT(ENV_DOF_BLUR_QUALITY_HIGH);
@ -2290,12 +2298,13 @@ VisualServer::VisualServer() {
GLOBAL_DEF("rendering/quality/shadows/filter_mode.mobile", 0);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadows/filter_mode", PropertyInfo(Variant::INT, "rendering/quality/shadows/filter_mode", PROPERTY_HINT_ENUM, "Disabled,PCF5,PCF13"));
GLOBAL_DEF("rendering/quality/reflections/roughness_layers", 6);
GLOBAL_DEF("rendering/quality/reflections/texture_array_reflections", true);
GLOBAL_DEF("rendering/quality/reflections/texture_array_reflections.mobile", false);
GLOBAL_DEF("rendering/quality/reflections/high_quality_ggx", true);
GLOBAL_DEF("rendering/quality/reflections/high_quality_ggx.mobile", false);
GLOBAL_DEF("rendering/quality/reflections/irradiance_max_size", 128);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/reflections/irradiance_max_size", PropertyInfo(Variant::INT, "rendering/quality/reflections/irradiance_max_size", PROPERTY_HINT_RANGE, "32,2048"));
GLOBAL_DEF("rendering/quality/reflections/ggx_samples", 1024);
GLOBAL_DEF("rendering/quality/reflections/ggx_samples.mobile", 128);
GLOBAL_DEF("rendering/quality/reflections/ggx_samples_realtime", 64);
GLOBAL_DEF("rendering/quality/reflections/ggx_samples_realtime.mobile", 16);
GLOBAL_DEF("rendering/quality/shading/force_vertex_shading", false);
GLOBAL_DEF("rendering/quality/shading/force_vertex_shading.mobile", true);

View file

@ -156,11 +156,6 @@ public:
virtual void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) = 0;
/* SKY API */
virtual RID sky_create() = 0;
virtual void sky_set_texture(RID p_sky, RID p_cube_map, int p_radiance_size) = 0;
/* SHADER API */
enum ShaderMode {
@ -678,6 +673,18 @@ public:
virtual void viewport_set_debug_draw(RID p_viewport, ViewportDebugDraw p_draw) = 0;
/* SKY API */
enum SkyMode {
SKY_MODE_QUALITY,
SKY_MODE_REALTIME
};
virtual RID sky_create() = 0;
virtual void sky_set_radiance_size(RID p_sky, int p_radiance_size) = 0;
virtual void sky_set_mode(RID p_sky, SkyMode p_mode) = 0;
virtual void sky_set_texture(RID p_sky, RID p_panorama) = 0;
/* ENVIRONMENT API */
virtual RID environment_create() = 0;
@ -687,13 +694,25 @@ public:
ENV_BG_CLEAR_COLOR,
ENV_BG_COLOR,
ENV_BG_SKY,
ENV_BG_COLOR_SKY,
ENV_BG_CANVAS,
ENV_BG_KEEP,
ENV_BG_CAMERA_FEED,
ENV_BG_MAX
};
enum EnvironmentAmbientSource {
ENV_AMBIENT_SOURCE_BG,
ENV_AMBIENT_SOURCE_DISABLED,
ENV_AMBIENT_SOURCE_COLOR,
ENV_AMBIENT_SOURCE_SKY,
};
enum EnvironmentReflectionSource {
ENV_REFLECTION_SOURCE_BG,
ENV_REFLECTION_SOURCE_DISABLED,
ENV_REFLECTION_SOURCE_SKY,
};
virtual void environment_set_background(RID p_env, EnvironmentBG p_bg) = 0;
virtual void environment_set_sky(RID p_env, RID p_sky) = 0;
virtual void environment_set_sky_custom_fov(RID p_env, float p_scale) = 0;
@ -701,7 +720,7 @@ public:
virtual void environment_set_bg_color(RID p_env, const Color &p_color) = 0;
virtual void environment_set_bg_energy(RID p_env, float p_energy) = 0;
virtual void environment_set_canvas_max_layer(RID p_env, int p_max_layer) = 0;
virtual void environment_set_ambient_light(RID p_env, const Color &p_color, float p_energy = 1.0, float p_sky_contribution = 0.0) = 0;
virtual void environment_set_ambient_light(RID p_env, const Color &p_color, EnvironmentAmbientSource p_ambient = ENV_AMBIENT_SOURCE_BG, float p_energy = 1.0, float p_sky_contribution = 0.0, EnvironmentReflectionSource p_reflection_source = ENV_REFLECTION_SOURCE_BG) = 0;
// FIXME: Disabled during Vulkan refactoring, should be ported.
#if 0
virtual void environment_set_camera_feed_id(RID p_env, int p_camera_feed_id) = 0;
@ -1093,6 +1112,8 @@ VARIANT_ENUM_CAST(VisualServer::LightDirectionalShadowDepthRangeMode);
VARIANT_ENUM_CAST(VisualServer::ReflectionProbeUpdateMode);
VARIANT_ENUM_CAST(VisualServer::ParticlesDrawOrder);
VARIANT_ENUM_CAST(VisualServer::EnvironmentBG);
VARIANT_ENUM_CAST(VisualServer::EnvironmentAmbientSource);
VARIANT_ENUM_CAST(VisualServer::EnvironmentReflectionSource);
VARIANT_ENUM_CAST(VisualServer::EnvironmentDOFBlurQuality);
VARIANT_ENUM_CAST(VisualServer::EnvironmentGlowBlendMode);
VARIANT_ENUM_CAST(VisualServer::EnvironmentToneMapper);