MagicNStuff/source/addons/SunshineClouds2/SunshineClouds.gd

997 lines
40 KiB
GDScript

@tool
extends CompositorEffect
class_name SunshineCloudsGD
@export_tool_button("Refresh Compute", "Clear") var refresh_action = refresh_compute
@export_group("Basic Settings")
@export_range(0, 1) var clouds_coverage : float = 0.7
@export_range(0, 20) var clouds_density : float = 1.0
@export_range(0, 2) var atmospheric_density : float = 0.7
@export_range(0, 10) var lighting_density : float = 0.25
@export_range(0, 1) var fog_effect_ground : float = 1.0
@export_subgroup("Colors")
@export_range(0, 1) var clouds_anisotropy : float = 0.18
@export_range(0, 1) var clouds_powder : float = 0.851
@export var cloud_ambient_color : Color = Color(0.763, 0.786, 0.822)
@export var cloud_ambient_tint : Color = Color(0.132, 0.202, 0.242)
@export var atmosphere_color : Color = Color(0.696, 0.832, 0.989)
@export var ambient_occlusion_color : Color = Color(0.54, 0.108, 0.0, 0.871)
@export_subgroup("Structure")
@export_range(0, 1) var accumulation_decay : float = 0.7
@export_range(100, 1000000) var extra_large_noise_scale : float = 320000.0
@export_range(100, 500000) var large_noise_scale : float = 120000.0
@export_range(100, 100000) var medium_noise_scale : float = 20000.0
@export_range(100, 10000) var small_noise_scale : float = 8500
@export_range(0, 2) var clouds_sharpness : float = 0.84
@export_range(0, 3) var clouds_detail_power : float = 1.0
@export_range(0, 50000) var curl_noise_strength : float = 4500.0
@export_range(0, 2) var lighting_sharpness : float = 0.38
@export_range(0, 1) var wind_swept_range : float = 0.54
@export_range(0, 5000) var wind_swept_strength : float = 3500.0
@export var cloud_floor : float = 1500.0
@export var cloud_ceiling : float = 25000.0
@export_subgroup("Performance")
@export var max_step_count : float = 100
@export var max_lighting_steps : float = 32
@export_enum("Native","Half","Quarter","Eighth") var resolution_scale = 0:
get:
return resolution_scale
set(value):
resolution_scale = value
last_size = Vector2i(0, 0)
lights_updated = true
@export_range(0, 2) var lod_bias : float = 1.0
@export_subgroup("Noise Textures")
@export var dither_noise : Texture3D
@export var height_gradient : Texture2D
@export var extra_large_noise_patterns : Texture2D
@export var large_scale_noise : Texture3D
@export var medium_scale_noise : Texture3D
@export var small_scale_noise : Texture3D
@export var curl_noise : Texture3D
@export_group("Advanced Settings")
@export_subgroup("Visuals")
@export_range(0, 1000) var dither_speed : float = 100.8254
@export_range(0, 20) var blur_power : float = 2.0
@export_range(0, 6) var blur_quality : float = 3.0
@export_subgroup("Reflections")
@export var reflections_globalshaderparam : String = ""
@export_subgroup("Performance")
@export var min_step_distance : float = 200.0
@export var max_step_distance : float = 600.0
@export var lighting_travel_distance : float = 7000.0
@export_subgroup("Mask")
@export var extra_large_used_as_mask : bool = false
@export var mask_width_km : float = 32.0;
@export_group("Compute Shaders")
@export var pre_pass_compute_shader : RDShaderFile
@export var compute_shader : RDShaderFile
@export var post_pass_compute_shader : RDShaderFile
@export_group("Internal Use")
@export var origin_offset : Vector3 = Vector3.ZERO
@export_subgroup("Positions")
@export var wind_direction : Vector3 = Vector3.ZERO
var extra_large_scale_clouds_position : Vector3 = Vector3.ZERO
var large_scale_clouds_position : Vector3 = Vector3.ZERO
var medium_scale_clouds_position : Vector3 = Vector3.ZERO
var detail_clouds_position : Vector3 = Vector3.ZERO
var current_time : float = 0.0
@export_subgroup("Lights")
@export var directional_lights_data : Array[Vector4] = []
@export var point_lights_data : Array[Vector4] = []
@export var point_effector_data : Array[Vector4] = []
var positionQueries : Array[Vector3] = []
var positionQueryCallables : Array[Callable] = []
var positionQuerying : bool = false
var positionResetting : bool = false
var lights_updated = false
var maskDrawnRid : RID = RID()
var rd : RenderingDevice
var shader : RID = RID()
var pipeline : RID = RID()
var prepass_shader : RID = RID()
var prepass_pipeline : RID = RID()
var postpass_shader : RID = RID()
var postpass_pipeline : RID = RID()
var nearest_sampler : RID = RID()
var linear_sampler : RID = RID()
var linear_sampler_no_repeat : RID = RID()
var general_data_buffer : RID = RID()
var light_data_buffer : RID = RID()
var point_sample_data_buffer : RID = RID()
var accumulation_textures : Array[RID] = []
var resized_depth : RID = RID()
var last_size : Vector2i = Vector2i(0, 0)
var color_images : Array[RID] = []
var msaa_color_images : Array[RID] = []
var buffers : RenderSceneBuffersRD
var uniform_sets : Array[RID] = []
var general_data : PackedByteArray
var light_data : PackedByteArray
var accumulation_is_a : bool = false
var ignore_accumilation : bool = false
var first_run : bool = true
var filter_index = 0
var last_render_target : RID
func refresh_compute():
maskDrawnRid = RID()
last_size = Vector2i.ZERO
func update_mask(newMask : RID):
maskDrawnRid = newMask
last_size = Vector2i.ZERO
func add_sample(callable : Callable, position : Vector3):
#if (positionQueries.size() == 32):
#print("Max cloud position sample queue reached (32), query failed.")
#return
positionQueries.append(position)
positionQueryCallables.append(callable)
func _init():
effect_callback_type = CompositorEffect.EFFECT_CALLBACK_TYPE_PRE_TRANSPARENT
access_resolved_depth = true
access_resolved_color = true
needs_motion_vectors = true
RenderingServer.call_on_render_thread(initialize_compute)
func _notification(what):
if what == NOTIFICATION_PREDELETE and is_instance_valid(self):
RenderingServer.call_on_render_thread(clear_compute)
func clear_compute():
if rd:
if shader.is_valid():
rd.free_rid(shader)
shader = RID()
if prepass_shader.is_valid():
rd.free_rid(prepass_shader)
prepass_shader = RID()
if postpass_shader.is_valid():
rd.free_rid(postpass_shader)
postpass_shader = RID()
if nearest_sampler.is_valid():
rd.free_rid(nearest_sampler)
nearest_sampler = RID()
if linear_sampler.is_valid():
rd.free_rid(linear_sampler)
linear_sampler = RID()
if linear_sampler_no_repeat.is_valid():
rd.free_rid(linear_sampler_no_repeat)
linear_sampler_no_repeat = RID()
if general_data_buffer.is_valid():
rd.free_rid(general_data_buffer)
general_data_buffer = RID()
if light_data_buffer.is_valid():
rd.free_rid(light_data_buffer)
light_data_buffer = RID()
if point_sample_data_buffer.is_valid():
rd.free_rid(point_sample_data_buffer)
point_sample_data_buffer = RID()
if resized_depth.is_valid():
rd.free_rid(resized_depth)
resized_depth = RID()
if accumulation_textures.size() > 0:
for item in accumulation_textures:
if item.is_valid():
rd.free_rid(item)
accumulation_textures.clear()
if msaa_color_images.size() > 0:
for item in msaa_color_images:
if item.is_valid():
rd.free_rid(item)
msaa_color_images.clear()
func initialize_compute():
first_run = true
if not rd:
rd = RenderingServer.get_rendering_device()
if not rd:
enabled = false
printerr("No rendering device on load.")
return
clear_compute()
var sampler_state = RDSamplerState.new()
sampler_state.min_filter = RenderingDevice.SAMPLER_FILTER_NEAREST
sampler_state.mag_filter = RenderingDevice.SAMPLER_FILTER_NEAREST
sampler_state.repeat_u = RenderingDevice.SAMPLER_REPEAT_MODE_REPEAT
sampler_state.repeat_v = RenderingDevice.SAMPLER_REPEAT_MODE_REPEAT
sampler_state.repeat_w = RenderingDevice.SAMPLER_REPEAT_MODE_REPEAT
nearest_sampler = rd.sampler_create(sampler_state)
var linear_sampler_state = RDSamplerState.new()
linear_sampler_state.min_filter = RenderingDevice.SAMPLER_FILTER_LINEAR
linear_sampler_state.mag_filter = RenderingDevice.SAMPLER_FILTER_LINEAR
linear_sampler_state.repeat_u = RenderingDevice.SAMPLER_REPEAT_MODE_REPEAT
linear_sampler_state.repeat_v = RenderingDevice.SAMPLER_REPEAT_MODE_REPEAT
linear_sampler_state.repeat_w = RenderingDevice.SAMPLER_REPEAT_MODE_REPEAT
linear_sampler = rd.sampler_create(linear_sampler_state)
var linear_sampler_state_no_repeat = RDSamplerState.new()
linear_sampler_state_no_repeat.min_filter = RenderingDevice.SAMPLER_FILTER_LINEAR
linear_sampler_state_no_repeat.mag_filter = RenderingDevice.SAMPLER_FILTER_LINEAR
linear_sampler_state_no_repeat.repeat_u = RenderingDevice.SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE
linear_sampler_state_no_repeat.repeat_v = RenderingDevice.SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE
linear_sampler_state_no_repeat.repeat_w = RenderingDevice.SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE
linear_sampler_no_repeat = rd.sampler_create(linear_sampler_state_no_repeat)
if not dither_noise:
dither_noise = ResourceLoader.load("res://addons/SunshineClouds2/NoiseTextures/bluenoise_Dither.png")
if not height_gradient:
height_gradient = ResourceLoader.load("res://addons/SunshineClouds2/NoiseTextures/HeightGradient.tres")
if not extra_large_noise_patterns:
extra_large_noise_patterns = ResourceLoader.load("res://addons/SunshineClouds2/NoiseTextures/ExtraLargeScaleNoise.tres")
if not large_scale_noise:
large_scale_noise = ResourceLoader.load("res://addons/SunshineClouds2/NoiseTextures/LargeScaleNoise.tres")
if not medium_scale_noise:
medium_scale_noise = ResourceLoader.load("res://addons/SunshineClouds2/NoiseTextures/MediumScaleNoise.tres")
if not small_scale_noise:
small_scale_noise = ResourceLoader.load("res://addons/SunshineClouds2/NoiseTextures/SmallScaleNoise.tres")
if not curl_noise:
curl_noise = ResourceLoader.load("res://addons/SunshineClouds2/NoiseTextures/curl_noise_varied.tga")
if not compute_shader:
compute_shader = ResourceLoader.load("res://addons/SunshineClouds2/SunshineCloudsCompute.glsl")
if not pre_pass_compute_shader:
pre_pass_compute_shader = ResourceLoader.load("res://addons/SunshineClouds2/SunshineCloudsPreCompute.glsl")
if not post_pass_compute_shader:
post_pass_compute_shader = ResourceLoader.load("res://addons/SunshineClouds2/SunshineCloudsPostCompute.glsl")
if not compute_shader or not pre_pass_compute_shader or not post_pass_compute_shader:
enabled = false
printerr("No Shader found on load.")
clear_compute()
return
var prepass_shader_spirv = pre_pass_compute_shader.get_spirv()
prepass_shader = rd.shader_create_from_spirv(prepass_shader_spirv)
if prepass_shader.is_valid():
prepass_pipeline = rd.compute_pipeline_create(prepass_shader)
else:
enabled = false
printerr("Prepass Shader failed to compile.")
clear_compute()
return
var shader_spirv = compute_shader.get_spirv()
shader = rd.shader_create_from_spirv(shader_spirv)
if shader.is_valid():
pipeline = rd.compute_pipeline_create(shader)
else:
enabled = false
printerr("Shader failed to compile.")
clear_compute()
return
var postpass_shader_spirv = post_pass_compute_shader.get_spirv()
postpass_shader = rd.shader_create_from_spirv(postpass_shader_spirv)
if postpass_shader.is_valid():
postpass_pipeline = rd.compute_pipeline_create(postpass_shader)
else:
enabled = false
printerr("Post pass Shader failed to compile.")
clear_compute()
return
func _render_callback(effect_callback_type, render_data):
if rd == null:
initialize_compute()
elif pipeline.is_valid() and height_gradient and extra_large_noise_patterns and large_scale_noise and medium_scale_noise and small_scale_noise and dither_noise and curl_noise:
buffers = render_data.get_render_scene_buffers() as RenderSceneBuffersRD
if buffers:
var msaa = buffers.get_msaa_3d() != 0
if msaa:
return
var size = buffers.get_internal_size()
if size.x == 0 and size.y == 0:
return
var resscale = int(pow(2.0, float(resolution_scale)))
#match resolution_scale:
#0:
#resscale = 1
#1:
#resscale = 2
#2:
#resscale = 4
#3:
#resscale = 8
var new_size = size / resscale
var view_count = buffers.get_view_count()
var rendersceneData : RenderSceneData = render_data.get_render_scene_data();
if size != last_size or uniform_sets == null or uniform_sets.size() != view_count * 3 or color_images.size() == 0 or color_images[0] != buffers.get_color_layer(0):
initialize_compute()
accumulation_textures.clear()
uniform_sets.clear()
color_images.clear()
msaa_color_images.clear()
#print("postpass_push_constants",postpass_push_constants.size())
for view in range(view_count):
color_images.append(buffers.get_color_layer(view, msaa))
var depth_image : RID = buffers.get_depth_layer(view, msaa)
var blankImageData : PackedByteArray = []
blankImageData.resize(new_size.x * new_size.y * 4 * 4)
var base_colorformat : RDTextureFormat = rd.texture_get_format(color_images[view])
if (msaa):
base_colorformat.usage_bits = RenderingDevice.TEXTURE_USAGE_STORAGE_BIT | RenderingDevice.TEXTURE_USAGE_SAMPLING_BIT | RenderingDevice.TEXTURE_USAGE_CAN_COPY_TO_BIT | RenderingDevice.TEXTURE_USAGE_CAN_COPY_FROM_BIT
msaa_color_images.append(rd.texture_create(base_colorformat, RDTextureView.new(), []))
base_colorformat.format = RenderingDevice.DATA_FORMAT_R32G32B32A32_SFLOAT
base_colorformat.width = new_size.x
base_colorformat.height = new_size.y
accumulation_textures.append(rd.texture_create(base_colorformat, RDTextureView.new(), [blankImageData]))
accumulation_textures.append(rd.texture_create(base_colorformat, RDTextureView.new(), [blankImageData]))
accumulation_textures.append(rd.texture_create(base_colorformat, RDTextureView.new(), [blankImageData]))
accumulation_textures.append(rd.texture_create(base_colorformat, RDTextureView.new(), [blankImageData]))
accumulation_textures.append(rd.texture_create(base_colorformat, RDTextureView.new(), [blankImageData]))
accumulation_textures.append(rd.texture_create(base_colorformat, RDTextureView.new(), [blankImageData]))
#reflections
accumulation_textures.append(rd.texture_create(base_colorformat, RDTextureView.new(), [blankImageData]))
general_data_buffer = rd.uniform_buffer_create(256)
var depthformat : RDTextureFormat = rd.texture_get_format(depth_image)
depthformat.width = new_size.x
depthformat.height = new_size.y
depthformat.format = RenderingDevice.DATA_FORMAT_R32_SFLOAT
depthformat.usage_bits = RenderingDevice.TEXTURE_USAGE_STORAGE_BIT | RenderingDevice.TEXTURE_USAGE_SAMPLING_BIT
resized_depth = rd.texture_create(depthformat, RDTextureView.new(), [])
#Prepass Compute Shader
var prepass_uniforms_array : Array[RDUniform] = []
var prepass_depth_uniform = RDUniform.new()
prepass_depth_uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_SAMPLER_WITH_TEXTURE
prepass_depth_uniform.binding = 0
prepass_depth_uniform.add_id(nearest_sampler)
prepass_depth_uniform.add_id(depth_image)
prepass_uniforms_array.append(prepass_depth_uniform)
var prepass_depth_output_uniform = RDUniform.new()
prepass_depth_output_uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_IMAGE
prepass_depth_output_uniform.binding = 1
prepass_depth_output_uniform.add_id(resized_depth)
prepass_uniforms_array.append(prepass_depth_output_uniform)
var prepass_camera_uniform = RDUniform.new()
prepass_camera_uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_UNIFORM_BUFFER
prepass_camera_uniform.binding = 2
prepass_camera_uniform.add_id(general_data_buffer)
prepass_uniforms_array.append(prepass_camera_uniform)
uniform_sets.append(rd.uniform_set_create(prepass_uniforms_array, prepass_shader, 0))
#Base Compute Shader
var uniforms_array : Array[RDUniform] = []
var output_data_uniform = RDUniform.new()
output_data_uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_IMAGE
output_data_uniform.binding = 0
output_data_uniform.add_id(accumulation_textures[view * 7])
uniforms_array.append(output_data_uniform)
var output_color_uniform = RDUniform.new()
output_color_uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_IMAGE
output_color_uniform.binding = 1
output_color_uniform.add_id(accumulation_textures[view * 7 + 1])
uniforms_array.append(output_color_uniform)
var accum1A_uniform = RDUniform.new()
accum1A_uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_IMAGE
accum1A_uniform.binding = 2
accum1A_uniform.add_id(accumulation_textures[view * 7 + 2])
uniforms_array.append(accum1A_uniform)
var accum1B_uniform = RDUniform.new()
accum1B_uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_IMAGE
accum1B_uniform.binding = 3
accum1B_uniform.add_id(accumulation_textures[view * 7 + 3])
uniforms_array.append(accum1B_uniform)
var accum2A_uniform = RDUniform.new()
accum2A_uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_IMAGE
accum2A_uniform.binding = 4
accum2A_uniform.add_id(accumulation_textures[view * 7 + 4])
uniforms_array.append(accum2A_uniform)
var accum2B_uniform = RDUniform.new()
accum2B_uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_IMAGE
accum2B_uniform.binding = 5
accum2B_uniform.add_id(accumulation_textures[view * 7 + 5])
uniforms_array.append(accum2B_uniform)
var depth_uniform = RDUniform.new()
depth_uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_SAMPLER_WITH_TEXTURE
depth_uniform.binding = 6
depth_uniform.add_id(nearest_sampler)
depth_uniform.add_id(resized_depth)
uniforms_array.append(depth_uniform)
var extra_noise_uniform = RDUniform.new()
extra_noise_uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_SAMPLER_WITH_TEXTURE
extra_noise_uniform.binding = 7
extra_noise_uniform.add_id(linear_sampler)
extra_noise_uniform.add_id(maskDrawnRid if extra_large_used_as_mask && maskDrawnRid.is_valid() else RenderingServer.texture_get_rd_texture(extra_large_noise_patterns.get_rid()))
uniforms_array.append(extra_noise_uniform)
var noise_uniform = RDUniform.new()
noise_uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_SAMPLER_WITH_TEXTURE
noise_uniform.binding = 8
noise_uniform.add_id(linear_sampler)
noise_uniform.add_id(RenderingServer.texture_get_rd_texture(large_scale_noise.get_rid()))
uniforms_array.append(noise_uniform)
var medium_noise_uniform = RDUniform.new()
medium_noise_uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_SAMPLER_WITH_TEXTURE
medium_noise_uniform.binding = 9
medium_noise_uniform.add_id(linear_sampler)
medium_noise_uniform.add_id(RenderingServer.texture_get_rd_texture(medium_scale_noise.get_rid()))
uniforms_array.append(medium_noise_uniform)
var small_noise_uniform = RDUniform.new()
small_noise_uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_SAMPLER_WITH_TEXTURE
small_noise_uniform.binding = 10
small_noise_uniform.add_id(linear_sampler)
small_noise_uniform.add_id(RenderingServer.texture_get_rd_texture(small_scale_noise.get_rid()))
uniforms_array.append(small_noise_uniform)
var curl_noise_uniform = RDUniform.new()
curl_noise_uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_SAMPLER_WITH_TEXTURE
curl_noise_uniform.binding = 11
curl_noise_uniform.add_id(linear_sampler)
curl_noise_uniform.add_id(RenderingServer.texture_get_rd_texture(curl_noise.get_rid()))
uniforms_array.append(curl_noise_uniform)
var dither_noise_uniform = RDUniform.new()
dither_noise_uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_SAMPLER_WITH_TEXTURE
dither_noise_uniform.binding = 12
dither_noise_uniform.add_id(nearest_sampler)
dither_noise_uniform.add_id(RenderingServer.texture_get_rd_texture(dither_noise.get_rid()))
uniforms_array.append(dither_noise_uniform)
var height_gradient_uniform = RDUniform.new()
height_gradient_uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_SAMPLER_WITH_TEXTURE
height_gradient_uniform.binding = 13
height_gradient_uniform.add_id(linear_sampler_no_repeat)
height_gradient_uniform.add_id(RenderingServer.texture_get_rd_texture(height_gradient.get_rid()))
uniforms_array.append(height_gradient_uniform)
var camera_uniform = RDUniform.new()
camera_uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_UNIFORM_BUFFER
camera_uniform.binding = 14
camera_uniform.add_id(general_data_buffer)
uniforms_array.append(camera_uniform)
light_data_buffer = rd.uniform_buffer_create(6272)
var light_data_uniform = RDUniform.new()
light_data_uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_UNIFORM_BUFFER
light_data_uniform.binding = 15
light_data_uniform.add_id(light_data_buffer)
uniforms_array.append(light_data_uniform)
var sampleData : PackedByteArray = []
sampleData.resize(512)
point_sample_data_buffer = rd.storage_buffer_create(512, sampleData)
var point_sample_data_uniform = RDUniform.new()
point_sample_data_uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_STORAGE_BUFFER
point_sample_data_uniform.binding = 16
point_sample_data_uniform.add_id(point_sample_data_buffer)
uniforms_array.append(point_sample_data_uniform)
var cameraData = rendersceneData.get_uniform_buffer()
var camera_data_uniform = RDUniform.new()
camera_data_uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_UNIFORM_BUFFER
camera_data_uniform.binding = 17
camera_data_uniform.add_id(cameraData)
uniforms_array.append(camera_data_uniform)
uniform_sets.append(rd.uniform_set_create(uniforms_array, shader, 0))
#Post Pass Compute Shader
var postpass_uniforms_array : Array[RDUniform] = []
var prepass_color_data_uniform = RDUniform.new()
prepass_color_data_uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_SAMPLER_WITH_TEXTURE
prepass_color_data_uniform.binding = 0
prepass_color_data_uniform.add_id(linear_sampler_no_repeat)
prepass_color_data_uniform.add_id(accumulation_textures[view * 7])
postpass_uniforms_array.append(prepass_color_data_uniform)
var prepass_color_uniform = RDUniform.new()
prepass_color_uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_SAMPLER_WITH_TEXTURE
prepass_color_uniform.binding = 1
prepass_color_uniform.add_id(linear_sampler_no_repeat)
prepass_color_uniform.add_id(accumulation_textures[view * 7 + 1])
postpass_uniforms_array.append(prepass_color_uniform)
var postpass_reflections_uniform = RDUniform.new()
postpass_reflections_uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_IMAGE
postpass_reflections_uniform.binding = 2
postpass_reflections_uniform.add_id(accumulation_textures[view * 7 + 6])
postpass_uniforms_array.append(postpass_reflections_uniform)
if (reflections_globalshaderparam != ""):
var newTexture = Texture2DRD.new()
newTexture.texture_rd_rid = accumulation_textures[view * 7 + 6]
RenderingServer.global_shader_parameter_set(reflections_globalshaderparam, newTexture)
var postpass_color_uniform = RDUniform.new()
postpass_color_uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_IMAGE
postpass_color_uniform.binding = 3
postpass_color_uniform.add_id(msaa_color_images[view] if msaa else color_images[view])
postpass_uniforms_array.append(postpass_color_uniform)
var postpass_depth_uniform = RDUniform.new()
postpass_depth_uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_SAMPLER_WITH_TEXTURE
postpass_depth_uniform.binding = 4
postpass_depth_uniform.add_id(nearest_sampler)
postpass_depth_uniform.add_id(depth_image)
postpass_uniforms_array.append(postpass_depth_uniform)
var postpass_camera_uniform = RDUniform.new()
postpass_camera_uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_UNIFORM_BUFFER
postpass_camera_uniform.binding = 5
postpass_camera_uniform.add_id(general_data_buffer)
postpass_uniforms_array.append(postpass_camera_uniform)
var postpass_light_data_uniform = RDUniform.new()
postpass_light_data_uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_UNIFORM_BUFFER
postpass_light_data_uniform.binding = 6
postpass_light_data_uniform.add_id(light_data_buffer)
postpass_uniforms_array.append(postpass_light_data_uniform)
var postpass_camera_data_uniform = RDUniform.new()
postpass_camera_data_uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_UNIFORM_BUFFER
postpass_camera_data_uniform.binding = 7
postpass_camera_data_uniform.add_id(cameraData)
postpass_uniforms_array.append(postpass_camera_data_uniform)
uniform_sets.append(rd.uniform_set_create(postpass_uniforms_array, postpass_shader, 0))
lights_updated = true
# Push constants and matrix updates
#var ms = StreamPeerBuffer.new()
#ms.put_float(new_size.x)
#ms.put_float(new_size.y)
#ms.put_float(large_noise_scale)
#ms.put_float(medium_noise_scale)
#
#ms.put_float(current_time)
#ms.put_float(clouds_coverage)
#ms.put_float(clouds_density)
#ms.put_float(clouds_detail_power)
#
#ms.put_float(lighting_density)
#ms.put_float(accumulation_decay)
#if (accumulation_is_a):
#ms.put_float(1.0)
#else:
#ms.put_float(0.0)
#ms.put_float(0.0)
#push_constants = ms.get_data_array()
var cameraTR : Transform3D = rendersceneData.get_cam_transform();
var viewProj : Projection = rendersceneData.get_cam_projection();
var rendertarget: RID = buffers.get_render_target()
if rendertarget != last_render_target:
last_render_target = rendertarget
ignore_accumilation = true
else:
ignore_accumilation = false
last_size = size
update_matrices(cameraTR, viewProj, new_size)
if lights_updated or directional_lights_data.size() == 0:
update_lights()
if (!positionQuerying && !positionResetting && positionQueries.size() > 0):
encode_sample_points()
var prepass_x_groups = ((size.x - 1) / 8) + 1
var prepass_y_groups = ((size.y - 1) / 8) + 1
var x_groups = ((size.x - 1) / 8 / resscale) + 1
var y_groups = ((size.y - 1) / 8 / resscale) + 1
for view in view_count:
if (msaa):
rd.texture_copy(color_images[view], msaa_color_images[view], Vector3.ZERO, Vector3.ZERO, Vector3(size.x, size.y, 0.0),0,0,0,0)
var prepass_list = rd.compute_list_begin()
rd.compute_list_bind_compute_pipeline(prepass_list, prepass_pipeline)
rd.compute_list_bind_uniform_set(prepass_list, uniform_sets[view * 3], 0)
rd.compute_list_dispatch(prepass_list, x_groups, y_groups, 1)
rd.compute_list_end()
var compute_list = rd.compute_list_begin()
rd.compute_list_bind_compute_pipeline(compute_list, pipeline)
rd.compute_list_bind_uniform_set(compute_list, uniform_sets[view * 3 + 1], 0)
rd.compute_list_dispatch(compute_list, x_groups, y_groups, 1)
rd.compute_list_end()
var postpass_list = rd.compute_list_begin()
rd.compute_list_bind_compute_pipeline(postpass_list, postpass_pipeline)
rd.compute_list_bind_uniform_set(postpass_list, uniform_sets[view * 3 + 2], 0)
rd.compute_list_dispatch(postpass_list, prepass_x_groups, prepass_y_groups, 1)
rd.compute_list_end()
if (msaa):
rd.texture_copy(msaa_color_images[view], color_images[view], Vector3.ZERO, Vector3.ZERO, Vector3(size.x, size.y, 0.0),0,0,0,0)
if (!positionResetting && positionQuerying):
positionResetting = true
rd.buffer_get_data_async(point_sample_data_buffer, retrieve_position_queries.bind())
#call_deferred("update_callbacktype", cameraTR.origin.y)
#if (cameraTR.origin.y > cloud_floor):
#if (self.effect_callback_type != CompositorEffect.EFFECT_CALLBACK_TYPE_POST_TRANSPARENT):
#self.effect_callback_type = CompositorEffect.EFFECT_CALLBACK_TYPE_POST_TRANSPARENT
#else:
#if (self.effect_callback_type != CompositorEffect.EFFECT_CALLBACK_TYPE_PRE_TRANSPARENT):
#self.effect_callback_type = CompositorEffect.EFFECT_CALLBACK_TYPE_PRE_TRANSPARENT
func retrieve_position_queries(data : PackedByteArray):
var idx = 0
while idx < 512 && positionQueryCallables.size() > 0:
var position : Vector3 = Vector3.ZERO
position.x = data.decode_float(idx)
idx += 4
position.y = data.decode_float(idx)
idx += 4
position.z = data.decode_float(idx)
idx += 4
var density = data.decode_float(idx)
idx += 4
positionQueryCallables[0].call(position, density)
positionQueryCallables.remove_at(0)
positionQuerying = false
positionResetting = false
#func update_callbacktype(lastY : float):
#if (lastY > cloud_floor):
#if (self.effect_callback_type != CompositorEffect.EFFECT_CALLBACK_TYPE_POST_TRANSPARENT):
#self.effect_callback_type = CompositorEffect.EFFECT_CALLBACK_TYPE_POST_TRANSPARENT
#else:
#if (self.effect_callback_type != CompositorEffect.EFFECT_CALLBACK_TYPE_PRE_TRANSPARENT):
#self.effect_callback_type = CompositorEffect.EFFECT_CALLBACK_TYPE_PRE_TRANSPARENT
func update_matrices(camera_tr, view_proj, new_size: Vector2i):
if general_data.size() != 256: #64 * 4 bytes for each float = 256.
general_data.resize(256)
var idx = 0
filter_index += 1
if filter_index > 16:
filter_index = 0
# Camera matrix (16 floats)
#general_data.encode_float(idx, camera_tr.basis.x.x); idx += 4
#general_data.encode_float(idx, camera_tr.basis.x.y); idx += 4
#general_data.encode_float(idx, camera_tr.basis.x.z); idx += 4
#general_data.encode_float(idx, 0); idx += 4
#
#general_data.encode_float(idx, camera_tr.basis.y.x); idx += 4
#general_data.encode_float(idx, camera_tr.basis.y.y); idx += 4
#general_data.encode_float(idx, camera_tr.basis.y.z); idx += 4
#general_data.encode_float(idx, 0); idx += 4
#
#general_data.encode_float(idx, camera_tr.basis.z.x); idx += 4
#general_data.encode_float(idx, camera_tr.basis.z.y); idx += 4
#general_data.encode_float(idx, camera_tr.basis.z.z); idx += 4
#general_data.encode_float(idx, 0); idx += 4
#
#general_data.encode_float(idx, camera_tr.origin.x); idx += 4
#general_data.encode_float(idx, camera_tr.origin.y); idx += 4
#general_data.encode_float(idx, camera_tr.origin.z); idx += 4
#general_data.encode_float(idx, 1.0); idx += 4
#
## Previous or current camera matrix
#var mat = camera_tr if first_run else last_view_mat
#general_data.encode_float(idx, mat.basis.x.x); idx += 4
#general_data.encode_float(idx, mat.basis.x.y); idx += 4
#general_data.encode_float(idx, mat.basis.x.z); idx += 4
#general_data.encode_float(idx, 0); idx += 4
#
#general_data.encode_float(idx, mat.basis.y.x); idx += 4
#general_data.encode_float(idx, mat.basis.y.y); idx += 4
#general_data.encode_float(idx, mat.basis.y.z); idx += 4
#general_data.encode_float(idx, 0); idx += 4
#
#general_data.encode_float(idx, mat.basis.z.x); idx += 4
#general_data.encode_float(idx, mat.basis.z.y); idx += 4
#general_data.encode_float(idx, mat.basis.z.z); idx += 4
#general_data.encode_float(idx, 0); idx += 4
#
#general_data.encode_float(idx, mat.origin.x); idx += 4
#general_data.encode_float(idx, mat.origin.y); idx += 4
#general_data.encode_float(idx, mat.origin.z); idx += 4
#general_data.encode_float(idx, 1.0); idx += 4
#
## Projection matrix (16 floats)
#general_data.encode_float(idx, view_proj.x.x); idx += 4
#general_data.encode_float(idx, view_proj.x.y); idx += 4
#general_data.encode_float(idx, view_proj.x.z); idx += 4
#general_data.encode_float(idx, view_proj.x.w); idx += 4
#
#general_data.encode_float(idx, view_proj.y.x); idx += 4
#general_data.encode_float(idx, view_proj.y.y); idx += 4
#general_data.encode_float(idx, view_proj.y.z); idx += 4
#general_data.encode_float(idx, view_proj.y.w); idx += 4
#
#general_data.encode_float(idx, view_proj.z.x); idx += 4
#general_data.encode_float(idx, view_proj.z.y); idx += 4
#general_data.encode_float(idx, view_proj.z.z); idx += 4
#general_data.encode_float(idx, view_proj.z.w); idx += 4
#
#general_data.encode_float(idx, view_proj.w.x); idx += 4
#general_data.encode_float(idx, view_proj.w.y); idx += 4
#general_data.encode_float(idx, view_proj.w.z); idx += 4
#general_data.encode_float(idx, view_proj.w.w); idx += 4
#
## Previous or current camera matrix
#var proj = view_proj if first_run else last_projection_mat
#general_data.encode_float(idx, proj.x.x); idx += 4
#general_data.encode_float(idx, proj.x.y); idx += 4
#general_data.encode_float(idx, proj.x.z); idx += 4
#general_data.encode_float(idx, proj.x.w); idx += 4
#
#general_data.encode_float(idx, proj.y.x); idx += 4
#general_data.encode_float(idx, proj.y.y); idx += 4
#general_data.encode_float(idx, proj.y.z); idx += 4
#general_data.encode_float(idx, proj.y.w); idx += 4
#
#general_data.encode_float(idx, proj.z.x); idx += 4
#general_data.encode_float(idx, proj.z.y); idx += 4
#general_data.encode_float(idx, proj.z.z); idx += 4
#general_data.encode_float(idx, proj.z.w); idx += 4
#
#general_data.encode_float(idx, proj.w.x); idx += 4
#general_data.encode_float(idx, proj.w.y); idx += 4
#general_data.encode_float(idx, proj.w.z); idx += 4
#general_data.encode_float(idx, proj.w.w); idx += 4
#
#last_projection_mat = view_proj
#last_view_mat = camera_tr
accumulation_is_a = not accumulation_is_a
first_run = false
# Additional data (44 floats)
var width = mask_width_km * 1000.0
if (extra_large_used_as_mask):
general_data.encode_float(idx, origin_offset.x + (width * 0.5) * -1.0); idx += 4
general_data.encode_float(idx, origin_offset.y + (width * 0.5) * -1.0); idx += 4
general_data.encode_float(idx, origin_offset.z + (width * 0.5) * -1.0); idx += 4
general_data.encode_float(idx, width); idx += 4
else:
general_data.encode_float(idx, extra_large_scale_clouds_position.x); idx += 4
general_data.encode_float(idx, extra_large_scale_clouds_position.y); idx += 4
general_data.encode_float(idx, extra_large_scale_clouds_position.z); idx += 4
general_data.encode_float(idx, extra_large_noise_scale); idx += 4
#general_data.encode_float(idx, extra_large_scale_clouds_position.x); idx += 4
#general_data.encode_float(idx, extra_large_scale_clouds_position.y); idx += 4
#general_data.encode_float(idx, extra_large_scale_clouds_position.z); idx += 4
#general_data.encode_float(idx, extra_large_noise_scale); idx += 4
#
general_data.encode_float(idx, large_scale_clouds_position.x); idx += 4
general_data.encode_float(idx, large_scale_clouds_position.y); idx += 4
general_data.encode_float(idx, large_scale_clouds_position.z); idx += 4
general_data.encode_float(idx, lighting_sharpness); idx += 4
general_data.encode_float(idx, medium_scale_clouds_position.x); idx += 4
general_data.encode_float(idx, medium_scale_clouds_position.y); idx += 4
general_data.encode_float(idx, medium_scale_clouds_position.z); idx += 4
general_data.encode_float(idx, lighting_travel_distance); idx += 4
general_data.encode_float(idx, detail_clouds_position.x); idx += 4
general_data.encode_float(idx, detail_clouds_position.y); idx += 4
general_data.encode_float(idx, detail_clouds_position.z); idx += 4
general_data.encode_float(idx, atmospheric_density); idx += 4
general_data.encode_float(idx, cloud_ambient_color.r * cloud_ambient_tint.r); idx += 4
general_data.encode_float(idx, cloud_ambient_color.g * cloud_ambient_tint.g); idx += 4
general_data.encode_float(idx, cloud_ambient_color.b * cloud_ambient_tint.b); idx += 4
general_data.encode_float(idx, cloud_ambient_color.a * cloud_ambient_tint.a); idx += 4
general_data.encode_float(idx, ambient_occlusion_color.r); idx += 4
general_data.encode_float(idx, ambient_occlusion_color.g); idx += 4
general_data.encode_float(idx, ambient_occlusion_color.b); idx += 4
general_data.encode_float(idx, ambient_occlusion_color.a); idx += 4
general_data.encode_float(idx, atmosphere_color.r); idx += 4
general_data.encode_float(idx, atmosphere_color.g); idx += 4
general_data.encode_float(idx, atmosphere_color.b); idx += 4
general_data.encode_float(idx, atmosphere_color.a); idx += 4
general_data.encode_float(idx, small_noise_scale); idx += 4
general_data.encode_float(idx, min_step_distance); idx += 4
general_data.encode_float(idx, max_step_distance); idx += 4
general_data.encode_float(idx, lod_bias); idx += 4
general_data.encode_float(idx, clouds_sharpness); idx += 4
general_data.encode_float(idx, float(directional_lights_data.size()) / 2.0); idx += 4
general_data.encode_float(idx, clouds_powder); idx += 4
general_data.encode_float(idx, clouds_anisotropy); idx += 4
general_data.encode_float(idx, cloud_floor); idx += 4
general_data.encode_float(idx, cloud_ceiling); idx += 4
general_data.encode_float(idx, float(max_step_count)); idx += 4
general_data.encode_float(idx, float(max_lighting_steps)); idx += 4
general_data.encode_float(idx, float(filter_index)); idx += 4
general_data.encode_float(idx, float(blur_power)); idx += 4
general_data.encode_float(idx, float(blur_quality)); idx += 4
general_data.encode_float(idx, float(curl_noise_strength)); idx += 4
general_data.encode_float(idx, wind_direction.x); idx += 4
general_data.encode_float(idx, wind_direction.z); idx += 4
general_data.encode_float(idx, fog_effect_ground); idx += 4
general_data.encode_float(idx, positionQueries.size()); idx += 4
general_data.encode_float(idx, float(point_lights_data.size()) / 2.0); idx += 4
general_data.encode_float(idx, float(point_effector_data.size()) / 2.0); idx += 4
general_data.encode_float(idx, wind_swept_range); idx += 4
general_data.encode_float(idx, wind_swept_strength); idx += 4
general_data.encode_float(idx, new_size.x); idx += 4
general_data.encode_float(idx, new_size.y); idx += 4
general_data.encode_float(idx, large_noise_scale); idx += 4
general_data.encode_float(idx, medium_noise_scale); idx += 4
general_data.encode_float(idx, current_time); idx += 4
general_data.encode_float(idx, clouds_coverage); idx += 4
general_data.encode_float(idx, clouds_density); idx += 4
general_data.encode_float(idx, clouds_detail_power); idx += 4
general_data.encode_float(idx, lighting_density); idx += 4
general_data.encode_float(idx, accumulation_decay if !ignore_accumilation else 0.0); idx += 4
if (accumulation_is_a):
general_data.encode_float(idx, 1.0); idx += 4
else:
general_data.encode_float(idx, 0.0); idx += 4
general_data.encode_float(idx, int(pow(2.0, float(resolution_scale)))); idx += 4
#
#general_data.encode_float(idx, last_size.x); idx += 4
#general_data.encode_float(idx, last_size.y); idx += 4
#general_data.encode_float(idx, 0.0); idx += 4
#general_data.encode_float(idx, 0.0); idx += 4
# Copy to byte buffer
rd.buffer_update(general_data_buffer, 0, general_data.size(), general_data)
func update_lights():
lights_updated = false
if light_data.size() != 6272: #32 + 1024 + 512 * 4 bytes for each float = 6272.
light_data.resize(6272)
if (directional_lights_data.size() == 0): #defaults to having a default light.
directional_lights_data.append(Vector4(0.5, 1.0, 0.5, 16.0))
directional_lights_data.append(Vector4(1.0, 1.0, 1.0, 1.0))
var idx = 0
for i in range(min(directional_lights_data.size(), 8)):
light_data.encode_float(idx, directional_lights_data[i].x)
idx += 4
light_data.encode_float(idx, directional_lights_data[i].y)
idx += 4
light_data.encode_float(idx, directional_lights_data[i].z)
idx += 4
light_data.encode_float(idx, directional_lights_data[i].w)
idx += 4
idx = 128
for i in range(min(point_lights_data.size(), 256)):
light_data.encode_float(idx, point_lights_data[i].x)
idx += 4
light_data.encode_float(idx, point_lights_data[i].y)
idx += 4
light_data.encode_float(idx, point_lights_data[i].z)
idx += 4
light_data.encode_float(idx, point_lights_data[i].w)
idx += 4
idx = 4224
for i in range(min(point_effector_data.size(), 128)):
light_data.encode_float(idx, point_effector_data[i].x)
idx += 4
light_data.encode_float(idx, point_effector_data[i].y)
idx += 4
light_data.encode_float(idx, point_effector_data[i].z)
idx += 4
light_data.encode_float(idx, point_effector_data[i].w)
idx += 4
rd.buffer_update(light_data_buffer, 0, light_data.size(), light_data)
func encode_sample_points():
positionQuerying = true
var sample_points_data_floats : PackedByteArray = []
sample_points_data_floats.resize(512)
var idx = 0
while idx < 512 && positionQueries.size() > 0:
sample_points_data_floats.encode_float(idx, positionQueries[0].x)
idx += 4
sample_points_data_floats.encode_float(idx, positionQueries[0].y)
idx += 4
sample_points_data_floats.encode_float(idx, positionQueries[0].z)
idx += 4
sample_points_data_floats.encode_float(idx, 0.0)
idx += 4
positionQueries.remove_at(0)
rd.buffer_update(point_sample_data_buffer, 0, sample_points_data_floats.size(), sample_points_data_floats)