Merge pull request #37179 from clayjohn/VULKAN-sky-shader
Implement Sky Shaders
This commit is contained in:
commit
ed9a0d0484
41 changed files with 2541 additions and 1127 deletions
|
@ -1,10 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<class name="PanoramaSky" inherits="Sky" version="4.0">
|
||||
<class name="PanoramaSkyMaterial" inherits="Material" version="4.0">
|
||||
<brief_description>
|
||||
A type of [Sky] used to draw a background texture.
|
||||
A [Material] used with [Sky] to draw a background texture.
|
||||
</brief_description>
|
||||
<description>
|
||||
A resource referenced in an [Environment] that is used to draw a background. The Panorama sky functions similar to skyboxes in other engines, except it uses an equirectangular sky map instead of a cube map.
|
||||
A resource referenced in a [Sky] that is used to draw a background. The Panorama sky material functions similar to skyboxes in other engines, except it uses an equirectangular sky map instead of a cube map.
|
||||
Using an HDR panorama is strongly recommended for accurate, high-quality reflections. Godot supports the Radiance HDR ([code].hdr[/code]) and OpenEXR ([code].exr[/code]) image formats for this purpose.
|
||||
You can use [url=https://danilw.github.io/GLSL-howto/cubemap_to_panorama_js/cubemap_to_panorama.html]this tool[/url] to convert a cube map to an equirectangular sky map.
|
||||
</description>
|
||||
|
@ -14,7 +14,7 @@
|
|||
</methods>
|
||||
<members>
|
||||
<member name="panorama" type="Texture2D" setter="set_panorama" getter="get_panorama">
|
||||
[Texture2D] to be applied to the PanoramaSky.
|
||||
[Texture2D] to be applied to the [PanoramaSkyMaterial].
|
||||
</member>
|
||||
</members>
|
||||
<constants>
|
49
doc/classes/PhysicalSkyMaterial.xml
Normal file
49
doc/classes/PhysicalSkyMaterial.xml
Normal file
|
@ -0,0 +1,49 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<class name="PhysicalSkyMaterial" inherits="Material" version="4.0">
|
||||
<brief_description>
|
||||
[Sky] [Material] used for a physically based sky.
|
||||
</brief_description>
|
||||
<description>
|
||||
The [PhysicalSkyMaterial] uses the Preetham analytic daylight model to draw a sky based on physical properties. This results in a substantially more realistic sky than the [ProceduralSkyMaterial], but it is slightly slower and less flexible.
|
||||
The [PhysicalSkyMaterial] only supports one sun. The color, energy, and direction of the sun are taken from the first [DirectionalLight] in the scene tree.
|
||||
As it is based on a daylight model, the sky fades to black as the sunset ends. If you want a full day/night cycle, you will have to add a night sky by converting this to a [ShaderMaterial] and adding a night sky directly into the resulting shader.
|
||||
</description>
|
||||
<tutorials>
|
||||
</tutorials>
|
||||
<methods>
|
||||
</methods>
|
||||
<members>
|
||||
<member name="dither_strength" type="float" setter="set_dither_strength" getter="get_dither_strength" default="1.0">
|
||||
Sets the amount of dithering to use. Dithering helps reduce banding that appears from the smooth changes in color in the sky. Use the lowest value possible, higher amounts may add fuzziness to the sky.
|
||||
</member>
|
||||
<member name="exposure" type="float" setter="set_exposure" getter="get_exposure" default="0.1">
|
||||
Sets the exposure of the sky. Higher exposure values make the entire sky brighter.
|
||||
</member>
|
||||
<member name="ground_color" type="Color" setter="set_ground_color" getter="get_ground_color" default="Color( 1, 1, 1, 1 )">
|
||||
Modulates the [Color] on the bottom half of the sky to represent the ground.
|
||||
</member>
|
||||
<member name="mie_coefficient" type="float" setter="set_mie_coefficient" getter="get_mie_coefficient" default="0.005">
|
||||
Controls the strength of mie scattering for the sky. Mie scattering results from light colliding with larger particles (like water). On earth, mie scattering results in a whiteish color around the sun and horizon.
|
||||
</member>
|
||||
<member name="mie_color" type="Color" setter="set_mie_color" getter="get_mie_color" default="Color( 0.36, 0.56, 0.82, 1 )">
|
||||
Controls the [Color] of the mie scattering effect. While not physically accurate, this allows for the creation of alien looking planets.
|
||||
</member>
|
||||
<member name="mie_eccentricity" type="float" setter="set_mie_eccentricity" getter="get_mie_eccentricity" default="0.8">
|
||||
Controls the direction of the mie scattering. A value of [code]1[/code] means that when light hits a particle it passing through straight forward. A value of [code]-1[/code] means that all light is scatter backwards.
|
||||
</member>
|
||||
<member name="rayleigh_coefficient" type="float" setter="set_rayleigh_coefficient" getter="get_rayleigh_coefficient" default="2.0">
|
||||
Controls the strength of the rayleigh scattering. Rayleigh scattering results from light colliding with small particles. It is responsible for the blue color of the sky.
|
||||
</member>
|
||||
<member name="rayleigh_color" type="Color" setter="set_rayleigh_color" getter="get_rayleigh_color" default="Color( 0.056, 0.14, 0.3, 1 )">
|
||||
Controls the [Color] of the rayleigh scattering. While not physically accurate, this allows for the creation of alien looking planets. For example, setting this to a red [Color] results in a mars looking atmosphere with a corresponding blue sunset.
|
||||
</member>
|
||||
<member name="sun_disk_scale" type="float" setter="set_sun_disk_scale" getter="get_sun_disk_scale" default="1.0">
|
||||
Sets the size of the sun disk. Default value is based on Sol's perceived size from Earth.
|
||||
</member>
|
||||
<member name="turbidity" type="float" setter="set_turbidity" getter="get_turbidity" default="10.0">
|
||||
Sets the thickness of the atmosphere. High turbidity creates a foggy looking atmosphere, while a low turbidity results in a clearer atmosphere.
|
||||
</member>
|
||||
</members>
|
||||
<constants>
|
||||
</constants>
|
||||
</class>
|
|
@ -1,84 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<class name="ProceduralSky" inherits="Sky" version="4.0">
|
||||
<brief_description>
|
||||
Type of [Sky] that is generated procedurally based on user input parameters.
|
||||
</brief_description>
|
||||
<description>
|
||||
ProceduralSky provides a way to create an effective background quickly by defining procedural parameters for the sun, the sky and the ground. The sky and ground are very similar, they are defined by a color at the horizon, another color, and finally an easing curve to interpolate between these two colors. Similarly, the sun is described by a position in the sky, a color, and an easing curve. However, the sun also defines a minimum and maximum angle, these two values define at what distance the easing curve begins and ends from the sun, and thus end up defining the size of the sun in the sky.
|
||||
The ProceduralSky is updated on the CPU after the parameters change. It is stored in a texture and then displayed as a background in the scene. This makes it relatively unsuitable for real-time updates during gameplay. However, with a small enough texture size, it can still be updated relatively frequently, as it is updated on a background thread when multi-threading is available.
|
||||
</description>
|
||||
<tutorials>
|
||||
</tutorials>
|
||||
<methods>
|
||||
</methods>
|
||||
<members>
|
||||
<member name="ground_bottom_color" type="Color" setter="set_ground_bottom_color" getter="get_ground_bottom_color" default="Color( 0.156863, 0.184314, 0.211765, 1 )">
|
||||
Color of the ground at the bottom.
|
||||
</member>
|
||||
<member name="ground_curve" type="float" setter="set_ground_curve" getter="get_ground_curve" default="0.02">
|
||||
How quickly the [member ground_horizon_color] fades into the [member ground_bottom_color].
|
||||
</member>
|
||||
<member name="ground_energy" type="float" setter="set_ground_energy" getter="get_ground_energy" default="1.0">
|
||||
Amount of energy contribution from the ground.
|
||||
</member>
|
||||
<member name="ground_horizon_color" type="Color" setter="set_ground_horizon_color" getter="get_ground_horizon_color" default="Color( 0.423529, 0.396078, 0.372549, 1 )">
|
||||
Color of the ground at the horizon.
|
||||
</member>
|
||||
<member name="sky_curve" type="float" setter="set_sky_curve" getter="get_sky_curve" default="0.09">
|
||||
How quickly the [member sky_horizon_color] fades into the [member sky_top_color].
|
||||
</member>
|
||||
<member name="sky_energy" type="float" setter="set_sky_energy" getter="get_sky_energy" default="1.0">
|
||||
Amount of energy contribution from the sky.
|
||||
</member>
|
||||
<member name="sky_horizon_color" type="Color" setter="set_sky_horizon_color" getter="get_sky_horizon_color" default="Color( 0.839216, 0.917647, 0.980392, 1 )">
|
||||
Color of the sky at the horizon.
|
||||
</member>
|
||||
<member name="sky_top_color" type="Color" setter="set_sky_top_color" getter="get_sky_top_color" default="Color( 0.647059, 0.839216, 0.945098, 1 )">
|
||||
Color of the sky at the top.
|
||||
</member>
|
||||
<member name="sun_angle_max" type="float" setter="set_sun_angle_max" getter="get_sun_angle_max" default="100.0">
|
||||
Distance from center of sun where it fades out completely.
|
||||
</member>
|
||||
<member name="sun_angle_min" type="float" setter="set_sun_angle_min" getter="get_sun_angle_min" default="1.0">
|
||||
Distance from sun where it goes from solid to starting to fade.
|
||||
</member>
|
||||
<member name="sun_color" type="Color" setter="set_sun_color" getter="get_sun_color" default="Color( 1, 1, 1, 1 )">
|
||||
The sun's color.
|
||||
</member>
|
||||
<member name="sun_curve" type="float" setter="set_sun_curve" getter="get_sun_curve" default="0.05">
|
||||
How quickly the sun fades away between [member sun_angle_min] and [member sun_angle_max].
|
||||
</member>
|
||||
<member name="sun_energy" type="float" setter="set_sun_energy" getter="get_sun_energy" default="1.0">
|
||||
Amount of energy contribution from the sun.
|
||||
</member>
|
||||
<member name="sun_latitude" type="float" setter="set_sun_latitude" getter="get_sun_latitude" default="35.0">
|
||||
The sun's height using polar coordinates.
|
||||
</member>
|
||||
<member name="sun_longitude" type="float" setter="set_sun_longitude" getter="get_sun_longitude" default="0.0">
|
||||
The direction of the sun using polar coordinates.
|
||||
</member>
|
||||
<member name="texture_size" type="int" setter="set_texture_size" getter="get_texture_size" enum="ProceduralSky.TextureSize" default="2">
|
||||
Size of [Texture2D] that the ProceduralSky will generate. The size is set using [enum TextureSize].
|
||||
</member>
|
||||
</members>
|
||||
<constants>
|
||||
<constant name="TEXTURE_SIZE_256" value="0" enum="TextureSize">
|
||||
Sky texture will be 256x128.
|
||||
</constant>
|
||||
<constant name="TEXTURE_SIZE_512" value="1" enum="TextureSize">
|
||||
Sky texture will be 512x256.
|
||||
</constant>
|
||||
<constant name="TEXTURE_SIZE_1024" value="2" enum="TextureSize">
|
||||
Sky texture will be 1024x512. This is the default size.
|
||||
</constant>
|
||||
<constant name="TEXTURE_SIZE_2048" value="3" enum="TextureSize">
|
||||
Sky texture will be 2048x1024.
|
||||
</constant>
|
||||
<constant name="TEXTURE_SIZE_4096" value="4" enum="TextureSize">
|
||||
Sky texture will be 4096x2048.
|
||||
</constant>
|
||||
<constant name="TEXTURE_SIZE_MAX" value="5" enum="TextureSize">
|
||||
Represents the size of the [enum TextureSize] enum.
|
||||
</constant>
|
||||
</constants>
|
||||
</class>
|
52
doc/classes/ProceduralSkyMaterial.xml
Normal file
52
doc/classes/ProceduralSkyMaterial.xml
Normal file
|
@ -0,0 +1,52 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<class name="ProceduralSkyMaterial" inherits="Material" version="4.0">
|
||||
<brief_description>
|
||||
A [Material] used with [Sky] to generate a background based on user input parameters.
|
||||
</brief_description>
|
||||
<description>
|
||||
ProceduralSkyMaterial provides a way to create an effective background quickly by defining procedural parameters for the sun, the sky and the ground. The sky and ground are very similar, they are defined by a color at the horizon, another color, and finally an easing curve to interpolate between these two colors. Similarly, the sun is described by a position in the sky, a color, and an easing curve. However, the sun also defines a minimum and maximum angle, these two values define at what distance the easing curve begins and ends from the sun, and thus end up defining the size of the sun in the sky.
|
||||
The [ProceduralSkyMaterial] uses a lightweight shader to draw the sky and is thus suited for real time updates. When you do not need a quick sky that is not realistic, this is a good option.
|
||||
The [ProceduralSkyMaterial] supports up to 4 suns. Each sun takes its color, energy, and direction from the corresponding [DirectionalLight] in the scene.
|
||||
</description>
|
||||
<tutorials>
|
||||
</tutorials>
|
||||
<methods>
|
||||
</methods>
|
||||
<members>
|
||||
<member name="ground_bottom_color" type="Color" setter="set_ground_bottom_color" getter="get_ground_bottom_color" default="Color( 0.12, 0.12, 0.13, 1 )">
|
||||
Color of the ground at the bottom. Blends with [member ground_horizon_color].
|
||||
</member>
|
||||
<member name="ground_curve" type="float" setter="set_ground_curve" getter="get_ground_curve" default="0.02">
|
||||
How quickly the [member ground_horizon_color] fades into the [member ground_bottom_color].
|
||||
</member>
|
||||
<member name="ground_energy" type="float" setter="set_ground_energy" getter="get_ground_energy" default="1.0">
|
||||
Amount of energy contribution from the ground.
|
||||
</member>
|
||||
<member name="ground_horizon_color" type="Color" setter="set_ground_horizon_color" getter="get_ground_horizon_color" default="Color( 0.37, 0.33, 0.31, 1 )">
|
||||
Color of the ground at the horizon. Blends with [member ground_bottom_color].
|
||||
</member>
|
||||
<member name="sky_curve" type="float" setter="set_sky_curve" getter="get_sky_curve" default="0.09">
|
||||
How quickly the [member sky_horizon_color] fades into the [member sky_top_color].
|
||||
</member>
|
||||
<member name="sky_energy" type="float" setter="set_sky_energy" getter="get_sky_energy" default="1.0">
|
||||
Amount of energy contribution from the sky.
|
||||
</member>
|
||||
<member name="sky_horizon_color" type="Color" setter="set_sky_horizon_color" getter="get_sky_horizon_color" default="Color( 0.55, 0.69, 0.81, 1 )">
|
||||
Color of the sky at the horizon. Blends with [member sky_top_color].
|
||||
</member>
|
||||
<member name="sky_top_color" type="Color" setter="set_sky_top_color" getter="get_sky_top_color" default="Color( 0.35, 0.46, 0.71, 1 )">
|
||||
Color of the sky at the top. Blends with [member sky_horizon_color].
|
||||
</member>
|
||||
<member name="sun_angle_max" type="float" setter="set_sun_angle_max" getter="get_sun_angle_max" default="100.0">
|
||||
Distance from center of sun where it fades out completely.
|
||||
</member>
|
||||
<member name="sun_angle_min" type="float" setter="set_sun_angle_min" getter="get_sun_angle_min" default="1.0">
|
||||
Distance from sun where it goes from solid to starting to fade.
|
||||
</member>
|
||||
<member name="sun_curve" type="float" setter="set_sun_curve" getter="get_sun_curve" default="0.05">
|
||||
How quickly the sun fades away between [member sun_angle_min] and [member sun_angle_max].
|
||||
</member>
|
||||
</members>
|
||||
<constants>
|
||||
</constants>
|
||||
</class>
|
|
@ -1036,7 +1036,7 @@
|
|||
<member name="rendering/quality/reflection_atlas/reflection_count" type="int" setter="" getter="" default="64">
|
||||
Number of cubemaps to store in the reflection atlas. The number of [ReflectionProbe]s in a scene will be limited by this amount. A higher number requires more VRAM.
|
||||
</member>
|
||||
<member name="rendering/quality/reflection_atlas/reflection_size" type="int" setter="" getter="" default="128">
|
||||
<member name="rendering/quality/reflection_atlas/reflection_size" type="int" setter="" getter="" default="256">
|
||||
Size of cubemap faces for [ReflectionProbe]s. A higher number requires more VRAM and may make reflection probe updating slower.
|
||||
</member>
|
||||
<member name="rendering/quality/reflection_atlas/reflection_size.mobile" type="int" setter="" getter="" default="128">
|
||||
|
@ -1051,7 +1051,7 @@
|
|||
<member name="rendering/quality/reflections/ggx_samples.mobile" type="int" setter="" getter="" default="128">
|
||||
Lower-end override for [member rendering/quality/reflections/ggx_samples] on mobile devices, due to performance concerns or driver support.
|
||||
</member>
|
||||
<member name="rendering/quality/reflections/roughness_layers" type="int" setter="" getter="" default="6">
|
||||
<member name="rendering/quality/reflections/roughness_layers" type="int" setter="" getter="" default="8">
|
||||
Limits the number of layers to use in radiance maps when using importance sampling. A lower number will be slightly faster and take up less VRAM.
|
||||
</member>
|
||||
<member name="rendering/quality/reflections/texture_array_reflections" type="bool" setter="" getter="" default="true">
|
||||
|
|
|
@ -66,5 +66,8 @@
|
|||
<constant name="MODE_PARTICLES" value="2" enum="Mode">
|
||||
Mode used to calculate particle information on a per-particle basis. Not used for drawing.
|
||||
</constant>
|
||||
<constant name="MODE_SKY" value="3" enum="Mode">
|
||||
Mode used for drawing skies. Only works with shaders attached to [Sky] objects.
|
||||
</constant>
|
||||
</constants>
|
||||
</class>
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<class name="Sky" inherits="Resource" version="4.0">
|
||||
<brief_description>
|
||||
The base class for [PanoramaSky] and [ProceduralSky].
|
||||
Background that uses a [Material] to draw a sky.
|
||||
</brief_description>
|
||||
<description>
|
||||
The base class for [PanoramaSky] and [ProceduralSky].
|
||||
The [Sky] class uses a [Material] to draw the background and update the reflection/radiance cubemaps.
|
||||
</description>
|
||||
<tutorials>
|
||||
</tutorials>
|
||||
|
@ -14,11 +14,14 @@
|
|||
<member name="process_mode" type="int" setter="set_process_mode" getter="get_process_mode" enum="Sky.ProcessMode" default="0">
|
||||
Sets the method for generating the radiance map from the sky. The radiance map is a cubemap with increasingly blurry versions of the sky corresponding to different levels of roughness. Radiance maps can be expensive to calculate. See [enum ProcessMode] for options.
|
||||
</member>
|
||||
<member name="radiance_size" type="int" setter="set_radiance_size" getter="get_radiance_size" enum="Sky.RadianceSize" default="2">
|
||||
<member name="radiance_size" type="int" setter="set_radiance_size" getter="get_radiance_size" enum="Sky.RadianceSize" default="3">
|
||||
The [Sky]'s radiance map size. The higher the radiance map size, the more detailed the lighting from the [Sky] will be.
|
||||
See [enum RadianceSize] constants for values.
|
||||
[b]Note:[/b] Some hardware will have trouble with higher radiance sizes, especially [constant RADIANCE_SIZE_512] and above. Only use such high values on high-end hardware.
|
||||
</member>
|
||||
<member name="sky_material" type="Material" setter="set_material" getter="get_material">
|
||||
[Material] used to draw the background. Can be [PanoramaSkyMaterial], [ProceduralSkyMaterial], [PhysicalSkyMaterial], or even a [ShaderMaterial] if you want to use your own custom shader.
|
||||
</member>
|
||||
</members>
|
||||
<constants>
|
||||
<constant name="RADIANCE_SIZE_32" value="0" enum="RadianceSize">
|
||||
|
@ -50,7 +53,7 @@
|
|||
</constant>
|
||||
<constant name="PROCESS_MODE_REALTIME" value="1" enum="ProcessMode">
|
||||
Uses the fast filtering algorithm to process the radiance map. In general this results in lower quality, but substantially faster run times.
|
||||
[b]Note:[/b] The fast filtering algorithm is limited to 128x128 cubemaps, so [member radiance_size] must be set to [constant RADIANCE_SIZE_128].
|
||||
[b]Note:[/b] The fast filtering algorithm is limited to 256x256 cubemaps, so [member radiance_size] must be set to [constant RADIANCE_SIZE_256].
|
||||
</constant>
|
||||
</constants>
|
||||
</class>
|
||||
|
|
|
@ -2744,14 +2744,15 @@
|
|||
Once finished with your RID, you will want to free the RID using the VisualServer's [method free_rid] static method.
|
||||
</description>
|
||||
</method>
|
||||
<method name="sky_set_texture">
|
||||
<method name="sky_set_material">
|
||||
<return type="void">
|
||||
</return>
|
||||
<argument index="0" name="sky" type="RID">
|
||||
</argument>
|
||||
<argument index="1" name="panorama" type="RID">
|
||||
<argument index="1" name="material" type="RID">
|
||||
</argument>
|
||||
<description>
|
||||
Sets the material that the sky uses to render the background and reflection maps.
|
||||
</description>
|
||||
</method>
|
||||
<method name="spot_light_create">
|
||||
|
@ -3155,7 +3156,10 @@
|
|||
<constant name="SHADER_PARTICLES" value="2" enum="ShaderMode">
|
||||
Shader is a particle shader.
|
||||
</constant>
|
||||
<constant name="SHADER_MAX" value="3" enum="ShaderMode">
|
||||
<constant name="SHADER_SKY" value="3" enum="ShaderMode">
|
||||
Shader is a sky shader.
|
||||
</constant>
|
||||
<constant name="SHADER_MAX" value="4" enum="ShaderMode">
|
||||
Represents the size of the [enum ShaderMode] enum.
|
||||
</constant>
|
||||
<constant name="ARRAY_VERTEX" value="0" enum="ArrayType">
|
||||
|
|
|
@ -58,6 +58,7 @@ public:
|
|||
void sky_set_mode(RID p_sky, VS::SkyMode p_samples) {}
|
||||
void sky_set_texture(RID p_sky, RID p_panorama) {}
|
||||
void sky_set_texture(RID p_sky, RID p_cube_map, int p_radiance_size) {}
|
||||
void sky_set_material(RID p_sky, RID p_material) {}
|
||||
|
||||
/* ENVIRONMENT API */
|
||||
|
||||
|
@ -313,6 +314,11 @@ public:
|
|||
void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) {}
|
||||
#endif
|
||||
|
||||
/* 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() { return RID(); }
|
||||
|
|
|
@ -1427,6 +1427,8 @@ void RasterizerStorageGLES2::shader_set_code(RID p_shader, const String &p_code)
|
|||
mode = VS::SHADER_CANVAS_ITEM;
|
||||
else if (mode_string == "particles")
|
||||
mode = VS::SHADER_PARTICLES;
|
||||
else if (mode_string == "sky")
|
||||
mode = VS::SHADER_SKY;
|
||||
else
|
||||
mode = VS::SHADER_SPATIAL;
|
||||
|
||||
|
|
|
@ -6584,6 +6584,18 @@ EditorNode::EditorNode() {
|
|||
particles_mat_convert.instance();
|
||||
resource_conversion_plugins.push_back(particles_mat_convert);
|
||||
|
||||
Ref<ProceduralSkyMaterialConversionPlugin> procedural_sky_mat_convert;
|
||||
procedural_sky_mat_convert.instance();
|
||||
resource_conversion_plugins.push_back(procedural_sky_mat_convert);
|
||||
|
||||
Ref<PanoramaSkyMaterialConversionPlugin> panorama_sky_mat_convert;
|
||||
panorama_sky_mat_convert.instance();
|
||||
resource_conversion_plugins.push_back(panorama_sky_mat_convert);
|
||||
|
||||
Ref<PhysicalSkyMaterialConversionPlugin> physical_sky_mat_convert;
|
||||
physical_sky_mat_convert.instance();
|
||||
resource_conversion_plugins.push_back(physical_sky_mat_convert);
|
||||
|
||||
Ref<VisualShaderConversionPlugin> vshader_convert;
|
||||
vshader_convert.instance();
|
||||
resource_conversion_plugins.push_back(vshader_convert);
|
||||
|
|
|
@ -187,8 +187,7 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme =
|
|||
exceptions.insert("EditorHandle");
|
||||
exceptions.insert("Editor3DHandle");
|
||||
exceptions.insert("Godot");
|
||||
exceptions.insert("PanoramaSky");
|
||||
exceptions.insert("ProceduralSky");
|
||||
exceptions.insert("Sky");
|
||||
exceptions.insert("EditorControlAnchor");
|
||||
exceptions.insert("DefaultProjectIcon");
|
||||
exceptions.insert("GuiCloseCustomizable");
|
||||
|
|
1
editor/icons/Sky.svg
Normal file
1
editor/icons/Sky.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="1040.4" y2="1050.4"><stop offset="0" stop-color="#1ec3ff"/><stop offset="1" stop-color="#b2e1ff"/></linearGradient><g transform="translate(0 -1037.4)"><path d="m8 1040.4a7 7 0 0 0 -7 7 7 7 0 0 0 .68555 3h12.631a7 7 0 0 0 .68359-3 7 7 0 0 0 -7-7z" fill="url(#a)"/><path d="m10 7c-.554 0-1 .446-1 1h-1c-.554 0-1 .446-1 1s.446 1 1 1h2c.554 0 1-.446 1-1h1c.554 0 1-.446 1-1s-.446-1-1-1zm-7 3c-.554 0-1 .446-1 1s.446 1 1 1h1c.554 0 1-.446 1-1s-.446-1-1-1z" fill="#fff" transform="translate(0 1037.4)"/></g></svg>
|
After Width: | Height: | Size: 705 B |
|
@ -33,6 +33,7 @@
|
|||
#include "editor/editor_scale.h"
|
||||
#include "scene/gui/viewport_container.h"
|
||||
#include "scene/resources/particles_material.h"
|
||||
#include "scene/resources/sky_material.h"
|
||||
|
||||
void MaterialEditor::_notification(int p_what) {
|
||||
|
||||
|
@ -221,8 +222,8 @@ void EditorInspectorPluginMaterial::parse_begin(Object *p_object) {
|
|||
|
||||
EditorInspectorPluginMaterial::EditorInspectorPluginMaterial() {
|
||||
env.instance();
|
||||
Ref<ProceduralSky> proc_sky = memnew(ProceduralSky(true));
|
||||
env->set_sky(proc_sky);
|
||||
Ref<Sky> sky = memnew(Sky());
|
||||
env->set_sky(sky);
|
||||
env->set_background(Environment::BG_COLOR);
|
||||
env->set_ambient_source(Environment::AMBIENT_SOURCE_SKY);
|
||||
env->set_reflection_source(Environment::REFLECTION_SOURCE_SKY);
|
||||
|
@ -356,3 +357,117 @@ Ref<Resource> CanvasItemMaterialConversionPlugin::convert(const Ref<Resource> &p
|
|||
smat->set_render_priority(mat->get_render_priority());
|
||||
return smat;
|
||||
}
|
||||
|
||||
String ProceduralSkyMaterialConversionPlugin::converts_to() const {
|
||||
|
||||
return "ShaderMaterial";
|
||||
}
|
||||
bool ProceduralSkyMaterialConversionPlugin::handles(const Ref<Resource> &p_resource) const {
|
||||
|
||||
Ref<ProceduralSkyMaterial> mat = p_resource;
|
||||
return mat.is_valid();
|
||||
}
|
||||
Ref<Resource> ProceduralSkyMaterialConversionPlugin::convert(const Ref<Resource> &p_resource) const {
|
||||
|
||||
Ref<ProceduralSkyMaterial> mat = p_resource;
|
||||
ERR_FAIL_COND_V(!mat.is_valid(), Ref<Resource>());
|
||||
|
||||
Ref<ShaderMaterial> smat;
|
||||
smat.instance();
|
||||
|
||||
Ref<Shader> shader;
|
||||
shader.instance();
|
||||
|
||||
String code = VS::get_singleton()->shader_get_code(mat->get_shader_rid());
|
||||
|
||||
shader->set_code(code);
|
||||
|
||||
smat->set_shader(shader);
|
||||
|
||||
List<PropertyInfo> params;
|
||||
VS::get_singleton()->shader_get_param_list(mat->get_shader_rid(), ¶ms);
|
||||
|
||||
for (List<PropertyInfo>::Element *E = params.front(); E; E = E->next()) {
|
||||
Variant value = VS::get_singleton()->material_get_param(mat->get_rid(), E->get().name);
|
||||
smat->set_shader_param(E->get().name, value);
|
||||
}
|
||||
|
||||
smat->set_render_priority(mat->get_render_priority());
|
||||
return smat;
|
||||
}
|
||||
|
||||
String PanoramaSkyMaterialConversionPlugin::converts_to() const {
|
||||
|
||||
return "ShaderMaterial";
|
||||
}
|
||||
bool PanoramaSkyMaterialConversionPlugin::handles(const Ref<Resource> &p_resource) const {
|
||||
|
||||
Ref<PanoramaSkyMaterial> mat = p_resource;
|
||||
return mat.is_valid();
|
||||
}
|
||||
Ref<Resource> PanoramaSkyMaterialConversionPlugin::convert(const Ref<Resource> &p_resource) const {
|
||||
|
||||
Ref<PanoramaSkyMaterial> mat = p_resource;
|
||||
ERR_FAIL_COND_V(!mat.is_valid(), Ref<Resource>());
|
||||
|
||||
Ref<ShaderMaterial> smat;
|
||||
smat.instance();
|
||||
|
||||
Ref<Shader> shader;
|
||||
shader.instance();
|
||||
|
||||
String code = VS::get_singleton()->shader_get_code(mat->get_shader_rid());
|
||||
|
||||
shader->set_code(code);
|
||||
|
||||
smat->set_shader(shader);
|
||||
|
||||
List<PropertyInfo> params;
|
||||
VS::get_singleton()->shader_get_param_list(mat->get_shader_rid(), ¶ms);
|
||||
|
||||
for (List<PropertyInfo>::Element *E = params.front(); E; E = E->next()) {
|
||||
Variant value = VS::get_singleton()->material_get_param(mat->get_rid(), E->get().name);
|
||||
smat->set_shader_param(E->get().name, value);
|
||||
}
|
||||
|
||||
smat->set_render_priority(mat->get_render_priority());
|
||||
return smat;
|
||||
}
|
||||
|
||||
String PhysicalSkyMaterialConversionPlugin::converts_to() const {
|
||||
|
||||
return "ShaderMaterial";
|
||||
}
|
||||
bool PhysicalSkyMaterialConversionPlugin::handles(const Ref<Resource> &p_resource) const {
|
||||
|
||||
Ref<PhysicalSkyMaterial> mat = p_resource;
|
||||
return mat.is_valid();
|
||||
}
|
||||
Ref<Resource> PhysicalSkyMaterialConversionPlugin::convert(const Ref<Resource> &p_resource) const {
|
||||
|
||||
Ref<PhysicalSkyMaterial> mat = p_resource;
|
||||
ERR_FAIL_COND_V(!mat.is_valid(), Ref<Resource>());
|
||||
|
||||
Ref<ShaderMaterial> smat;
|
||||
smat.instance();
|
||||
|
||||
Ref<Shader> shader;
|
||||
shader.instance();
|
||||
|
||||
String code = VS::get_singleton()->shader_get_code(mat->get_shader_rid());
|
||||
|
||||
shader->set_code(code);
|
||||
|
||||
smat->set_shader(shader);
|
||||
|
||||
List<PropertyInfo> params;
|
||||
VS::get_singleton()->shader_get_param_list(mat->get_shader_rid(), ¶ms);
|
||||
|
||||
for (List<PropertyInfo>::Element *E = params.front(); E; E = E->next()) {
|
||||
Variant value = VS::get_singleton()->material_get_param(mat->get_rid(), E->get().name);
|
||||
smat->set_shader_param(E->get().name, value);
|
||||
}
|
||||
|
||||
smat->set_render_priority(mat->get_render_priority());
|
||||
return smat;
|
||||
}
|
||||
|
|
|
@ -127,4 +127,31 @@ public:
|
|||
virtual Ref<Resource> convert(const Ref<Resource> &p_resource) const;
|
||||
};
|
||||
|
||||
class ProceduralSkyMaterialConversionPlugin : public EditorResourceConversionPlugin {
|
||||
GDCLASS(ProceduralSkyMaterialConversionPlugin, EditorResourceConversionPlugin);
|
||||
|
||||
public:
|
||||
virtual String converts_to() const;
|
||||
virtual bool handles(const Ref<Resource> &p_resource) const;
|
||||
virtual Ref<Resource> convert(const Ref<Resource> &p_resource) const;
|
||||
};
|
||||
|
||||
class PanoramaSkyMaterialConversionPlugin : public EditorResourceConversionPlugin {
|
||||
GDCLASS(PanoramaSkyMaterialConversionPlugin, EditorResourceConversionPlugin);
|
||||
|
||||
public:
|
||||
virtual String converts_to() const;
|
||||
virtual bool handles(const Ref<Resource> &p_resource) const;
|
||||
virtual Ref<Resource> convert(const Ref<Resource> &p_resource) const;
|
||||
};
|
||||
|
||||
class PhysicalSkyMaterialConversionPlugin : public EditorResourceConversionPlugin {
|
||||
GDCLASS(PhysicalSkyMaterialConversionPlugin, EditorResourceConversionPlugin);
|
||||
|
||||
public:
|
||||
virtual String converts_to() const;
|
||||
virtual bool handles(const Ref<Resource> &p_resource) const;
|
||||
virtual Ref<Resource> convert(const Ref<Resource> &p_resource) const;
|
||||
};
|
||||
|
||||
#endif // MATERIAL_EDITOR_PLUGIN_H
|
||||
|
|
|
@ -505,7 +505,7 @@ private:
|
|||
set_message(TTR("Couldn't create project.godot in project path."), MESSAGE_ERROR);
|
||||
} else {
|
||||
f->store_line("[gd_resource type=\"Environment\" load_steps=2 format=2]");
|
||||
f->store_line("[sub_resource type=\"ProceduralSky\" id=1]");
|
||||
f->store_line("[sub_resource type=\"Sky\" id=1]");
|
||||
f->store_line("[resource]");
|
||||
f->store_line("background_mode = 2");
|
||||
f->store_line("background_sky = SubResource( 1 )");
|
||||
|
|
|
@ -158,6 +158,7 @@
|
|||
#include "scene/resources/resource_format_text.h"
|
||||
#include "scene/resources/segment_shape_2d.h"
|
||||
#include "scene/resources/sky.h"
|
||||
#include "scene/resources/sky_material.h"
|
||||
#include "scene/resources/sphere_shape.h"
|
||||
#include "scene/resources/surface_tool.h"
|
||||
#include "scene/resources/text_file.h"
|
||||
|
@ -609,6 +610,10 @@ void register_scene_types() {
|
|||
SceneTree::add_idle_callback(ParticlesMaterial::flush_changes);
|
||||
ParticlesMaterial::init_shaders();
|
||||
|
||||
ClassDB::register_class<ProceduralSkyMaterial>();
|
||||
ClassDB::register_class<PanoramaSkyMaterial>();
|
||||
ClassDB::register_class<PhysicalSkyMaterial>();
|
||||
|
||||
ClassDB::register_virtual_class<Mesh>();
|
||||
ClassDB::register_class<ArrayMesh>();
|
||||
ClassDB::register_class<MultiMesh>();
|
||||
|
@ -659,9 +664,7 @@ void register_scene_types() {
|
|||
ClassDB::register_class<World2D>();
|
||||
ClassDB::register_virtual_class<Texture>();
|
||||
ClassDB::register_virtual_class<Texture2D>();
|
||||
ClassDB::register_virtual_class<Sky>();
|
||||
ClassDB::register_class<PanoramaSky>();
|
||||
ClassDB::register_class<ProceduralSky>();
|
||||
ClassDB::register_class<Sky>();
|
||||
ClassDB::register_class<StreamTexture>();
|
||||
ClassDB::register_class<ImageTexture>();
|
||||
ClassDB::register_class<AtlasTexture>();
|
||||
|
|
|
@ -48,6 +48,8 @@ void Shader::set_code(const String &p_code) {
|
|||
mode = MODE_CANVAS_ITEM;
|
||||
} else if (type == "particles") {
|
||||
mode = MODE_PARTICLES;
|
||||
} else if (type == "sky") {
|
||||
mode = MODE_SKY;
|
||||
} else {
|
||||
mode = MODE_SPATIAL;
|
||||
}
|
||||
|
@ -158,6 +160,7 @@ void Shader::_bind_methods() {
|
|||
BIND_ENUM_CONSTANT(MODE_SPATIAL);
|
||||
BIND_ENUM_CONSTANT(MODE_CANVAS_ITEM);
|
||||
BIND_ENUM_CONSTANT(MODE_PARTICLES);
|
||||
BIND_ENUM_CONSTANT(MODE_SKY);
|
||||
}
|
||||
|
||||
Shader::Shader() {
|
||||
|
|
|
@ -47,6 +47,7 @@ public:
|
|||
MODE_SPATIAL,
|
||||
MODE_CANVAS_ITEM,
|
||||
MODE_PARTICLES,
|
||||
MODE_SKY,
|
||||
MODE_MAX
|
||||
};
|
||||
|
||||
|
|
|
@ -56,6 +56,18 @@ Sky::ProcessMode Sky::get_process_mode() const {
|
|||
return mode;
|
||||
}
|
||||
|
||||
void Sky::set_material(const Ref<Material> &p_material) {
|
||||
sky_material = p_material;
|
||||
RID material_rid;
|
||||
if (sky_material.is_valid())
|
||||
material_rid = sky_material->get_rid();
|
||||
VS::get_singleton()->sky_set_material(sky, material_rid);
|
||||
}
|
||||
|
||||
Ref<Material> Sky::get_material() const {
|
||||
return sky_material;
|
||||
}
|
||||
|
||||
RID Sky::get_rid() const {
|
||||
|
||||
return sky;
|
||||
|
@ -69,6 +81,10 @@ void Sky::_bind_methods() {
|
|||
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);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_material", "material"), &Sky::set_material);
|
||||
ClassDB::bind_method(D_METHOD("get_material"), &Sky::get_material);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "sky_material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,PanoramaSkyMaterial,ProceduralSkyMaterial,PhysicalSkyMaterial"), "set_material", "get_material");
|
||||
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");
|
||||
|
||||
|
@ -87,500 +103,11 @@ void Sky::_bind_methods() {
|
|||
|
||||
Sky::Sky() {
|
||||
mode = PROCESS_MODE_QUALITY;
|
||||
radiance_size = RADIANCE_SIZE_128;
|
||||
radiance_size = RADIANCE_SIZE_256;
|
||||
sky = VS::get_singleton()->sky_create();
|
||||
}
|
||||
|
||||
Sky::~Sky() {
|
||||
|
||||
VS::get_singleton()->free(sky);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////
|
||||
|
||||
void PanoramaSky::set_panorama(const Ref<Texture2D> &p_panorama) {
|
||||
|
||||
panorama = p_panorama;
|
||||
|
||||
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 {
|
||||
|
||||
return panorama;
|
||||
}
|
||||
|
||||
void PanoramaSky::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_panorama", "texture"), &PanoramaSky::set_panorama);
|
||||
ClassDB::bind_method(D_METHOD("get_panorama"), &PanoramaSky::get_panorama);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "panorama", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_panorama", "get_panorama");
|
||||
}
|
||||
|
||||
PanoramaSky::PanoramaSky() {
|
||||
}
|
||||
|
||||
PanoramaSky::~PanoramaSky() {
|
||||
}
|
||||
//////////////////////////////////
|
||||
|
||||
Ref<Image> ProceduralSky::_generate_sky() {
|
||||
|
||||
update_queued = false;
|
||||
|
||||
Vector<uint8_t> imgdata;
|
||||
|
||||
static const int size[TEXTURE_SIZE_MAX] = {
|
||||
256, 512, 1024, 2048, 4096
|
||||
};
|
||||
|
||||
int w = size[texture_size];
|
||||
int h = w / 2;
|
||||
|
||||
imgdata.resize(w * h * 4); //RGBE
|
||||
|
||||
{
|
||||
uint8_t *dataw = imgdata.ptrw();
|
||||
|
||||
uint32_t *ptr = (uint32_t *)dataw;
|
||||
|
||||
Color sky_top_linear = sky_top_color.to_linear();
|
||||
Color sky_horizon_linear = sky_horizon_color.to_linear();
|
||||
|
||||
Color ground_bottom_linear = ground_bottom_color.to_linear();
|
||||
Color ground_horizon_linear = ground_horizon_color.to_linear();
|
||||
|
||||
Color sun_linear;
|
||||
sun_linear.r = sun_color.r * sun_energy;
|
||||
sun_linear.g = sun_color.g * sun_energy;
|
||||
sun_linear.b = sun_color.b * sun_energy;
|
||||
|
||||
Vector3 sun(0, 0, -1);
|
||||
|
||||
sun = Basis(Vector3(1, 0, 0), Math::deg2rad(sun_latitude)).xform(sun);
|
||||
sun = Basis(Vector3(0, 1, 0), Math::deg2rad(sun_longitude)).xform(sun);
|
||||
|
||||
sun.normalize();
|
||||
|
||||
for (int i = 0; i < w; i++) {
|
||||
|
||||
float u = float(i) / (w - 1);
|
||||
float phi = u * 2.0 * Math_PI;
|
||||
|
||||
for (int j = 0; j < h; j++) {
|
||||
|
||||
float v = float(j) / (h - 1);
|
||||
float theta = v * Math_PI;
|
||||
|
||||
Vector3 normal(
|
||||
Math::sin(phi) * Math::sin(theta) * -1.0,
|
||||
Math::cos(theta),
|
||||
Math::cos(phi) * Math::sin(theta) * -1.0);
|
||||
|
||||
normal.normalize();
|
||||
|
||||
float v_angle = Math::acos(CLAMP(normal.y, -1.0, 1.0));
|
||||
|
||||
Color color;
|
||||
|
||||
if (normal.y < 0) {
|
||||
//ground
|
||||
|
||||
float c = (v_angle - (Math_PI * 0.5)) / (Math_PI * 0.5);
|
||||
color = ground_horizon_linear.linear_interpolate(ground_bottom_linear, Math::ease(c, ground_curve));
|
||||
color.r *= ground_energy;
|
||||
color.g *= ground_energy;
|
||||
color.b *= ground_energy;
|
||||
} else {
|
||||
float c = v_angle / (Math_PI * 0.5);
|
||||
color = sky_horizon_linear.linear_interpolate(sky_top_linear, Math::ease(1.0 - c, sky_curve));
|
||||
color.r *= sky_energy;
|
||||
color.g *= sky_energy;
|
||||
color.b *= sky_energy;
|
||||
|
||||
float sun_angle = Math::rad2deg(Math::acos(CLAMP(sun.dot(normal), -1.0, 1.0)));
|
||||
|
||||
if (sun_angle < sun_angle_min) {
|
||||
color = color.blend(sun_linear);
|
||||
} else if (sun_angle < sun_angle_max) {
|
||||
|
||||
float c2 = (sun_angle - sun_angle_min) / (sun_angle_max - sun_angle_min);
|
||||
c2 = Math::ease(c2, sun_curve);
|
||||
|
||||
color = color.blend(sun_linear).linear_interpolate(color, c2);
|
||||
}
|
||||
}
|
||||
|
||||
ptr[j * w + i] = color.to_rgbe9995();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ref<Image> image;
|
||||
image.instance();
|
||||
image->create(w, h, false, Image::FORMAT_RGBE9995, imgdata);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
void ProceduralSky::set_sky_top_color(const Color &p_sky_top) {
|
||||
|
||||
sky_top_color = p_sky_top;
|
||||
_queue_update();
|
||||
}
|
||||
|
||||
Color ProceduralSky::get_sky_top_color() const {
|
||||
|
||||
return sky_top_color;
|
||||
}
|
||||
|
||||
void ProceduralSky::set_sky_horizon_color(const Color &p_sky_horizon) {
|
||||
|
||||
sky_horizon_color = p_sky_horizon;
|
||||
_queue_update();
|
||||
}
|
||||
Color ProceduralSky::get_sky_horizon_color() const {
|
||||
|
||||
return sky_horizon_color;
|
||||
}
|
||||
|
||||
void ProceduralSky::set_sky_curve(float p_curve) {
|
||||
|
||||
sky_curve = p_curve;
|
||||
_queue_update();
|
||||
}
|
||||
float ProceduralSky::get_sky_curve() const {
|
||||
|
||||
return sky_curve;
|
||||
}
|
||||
|
||||
void ProceduralSky::set_sky_energy(float p_energy) {
|
||||
|
||||
sky_energy = p_energy;
|
||||
_queue_update();
|
||||
}
|
||||
float ProceduralSky::get_sky_energy() const {
|
||||
|
||||
return sky_energy;
|
||||
}
|
||||
|
||||
void ProceduralSky::set_ground_bottom_color(const Color &p_ground_bottom) {
|
||||
|
||||
ground_bottom_color = p_ground_bottom;
|
||||
_queue_update();
|
||||
}
|
||||
Color ProceduralSky::get_ground_bottom_color() const {
|
||||
|
||||
return ground_bottom_color;
|
||||
}
|
||||
|
||||
void ProceduralSky::set_ground_horizon_color(const Color &p_ground_horizon) {
|
||||
|
||||
ground_horizon_color = p_ground_horizon;
|
||||
_queue_update();
|
||||
}
|
||||
Color ProceduralSky::get_ground_horizon_color() const {
|
||||
|
||||
return ground_horizon_color;
|
||||
}
|
||||
|
||||
void ProceduralSky::set_ground_curve(float p_curve) {
|
||||
|
||||
ground_curve = p_curve;
|
||||
_queue_update();
|
||||
}
|
||||
float ProceduralSky::get_ground_curve() const {
|
||||
|
||||
return ground_curve;
|
||||
}
|
||||
|
||||
void ProceduralSky::set_ground_energy(float p_energy) {
|
||||
|
||||
ground_energy = p_energy;
|
||||
_queue_update();
|
||||
}
|
||||
float ProceduralSky::get_ground_energy() const {
|
||||
|
||||
return ground_energy;
|
||||
}
|
||||
|
||||
void ProceduralSky::set_sun_color(const Color &p_sun) {
|
||||
|
||||
sun_color = p_sun;
|
||||
_queue_update();
|
||||
}
|
||||
Color ProceduralSky::get_sun_color() const {
|
||||
|
||||
return sun_color;
|
||||
}
|
||||
|
||||
void ProceduralSky::set_sun_latitude(float p_angle) {
|
||||
|
||||
sun_latitude = p_angle;
|
||||
_queue_update();
|
||||
}
|
||||
float ProceduralSky::get_sun_latitude() const {
|
||||
|
||||
return sun_latitude;
|
||||
}
|
||||
|
||||
void ProceduralSky::set_sun_longitude(float p_angle) {
|
||||
|
||||
sun_longitude = p_angle;
|
||||
_queue_update();
|
||||
}
|
||||
float ProceduralSky::get_sun_longitude() const {
|
||||
|
||||
return sun_longitude;
|
||||
}
|
||||
|
||||
void ProceduralSky::set_sun_angle_min(float p_angle) {
|
||||
|
||||
sun_angle_min = p_angle;
|
||||
_queue_update();
|
||||
}
|
||||
float ProceduralSky::get_sun_angle_min() const {
|
||||
|
||||
return sun_angle_min;
|
||||
}
|
||||
|
||||
void ProceduralSky::set_sun_angle_max(float p_angle) {
|
||||
|
||||
sun_angle_max = p_angle;
|
||||
_queue_update();
|
||||
}
|
||||
float ProceduralSky::get_sun_angle_max() const {
|
||||
|
||||
return sun_angle_max;
|
||||
}
|
||||
|
||||
void ProceduralSky::set_sun_curve(float p_curve) {
|
||||
|
||||
sun_curve = p_curve;
|
||||
_queue_update();
|
||||
}
|
||||
float ProceduralSky::get_sun_curve() const {
|
||||
|
||||
return sun_curve;
|
||||
}
|
||||
|
||||
void ProceduralSky::set_sun_energy(float p_energy) {
|
||||
|
||||
sun_energy = p_energy;
|
||||
_queue_update();
|
||||
}
|
||||
float ProceduralSky::get_sun_energy() const {
|
||||
|
||||
return sun_energy;
|
||||
}
|
||||
|
||||
void ProceduralSky::set_texture_size(TextureSize p_size) {
|
||||
ERR_FAIL_INDEX(p_size, TEXTURE_SIZE_MAX);
|
||||
|
||||
texture_size = p_size;
|
||||
_queue_update();
|
||||
}
|
||||
ProceduralSky::TextureSize ProceduralSky::get_texture_size() const {
|
||||
return texture_size;
|
||||
}
|
||||
|
||||
void ProceduralSky::_update_sky() {
|
||||
|
||||
bool use_thread = true;
|
||||
if (first_time) {
|
||||
use_thread = false;
|
||||
first_time = false;
|
||||
}
|
||||
#ifdef NO_THREADS
|
||||
use_thread = false;
|
||||
#endif
|
||||
if (use_thread) {
|
||||
|
||||
if (!sky_thread) {
|
||||
sky_thread = Thread::create(_thread_function, this);
|
||||
regen_queued = false;
|
||||
} else {
|
||||
regen_queued = true;
|
||||
}
|
||||
|
||||
} else {
|
||||
Ref<Image> image = _generate_sky();
|
||||
if (texture.is_valid()) {
|
||||
RID new_texture = VS::get_singleton()->texture_2d_create(image);
|
||||
VS::get_singleton()->texture_replace(texture, new_texture);
|
||||
} else {
|
||||
texture = VS::get_singleton()->texture_2d_create(image);
|
||||
}
|
||||
VS::get_singleton()->sky_set_texture(get_rid(), texture);
|
||||
}
|
||||
}
|
||||
|
||||
void ProceduralSky::_queue_update() {
|
||||
|
||||
if (update_queued)
|
||||
return;
|
||||
|
||||
update_queued = true;
|
||||
call_deferred("_update_sky");
|
||||
}
|
||||
|
||||
void ProceduralSky::_thread_done(const Ref<Image> &p_image) {
|
||||
|
||||
if (texture.is_valid()) {
|
||||
RID new_texture = VS::get_singleton()->texture_2d_create(p_image);
|
||||
VS::get_singleton()->texture_replace(texture, new_texture);
|
||||
} else {
|
||||
texture = VS::get_singleton()->texture_2d_create(p_image);
|
||||
}
|
||||
|
||||
VS::get_singleton()->sky_set_texture(get_rid(), texture);
|
||||
|
||||
Thread::wait_to_finish(sky_thread);
|
||||
memdelete(sky_thread);
|
||||
sky_thread = NULL;
|
||||
if (regen_queued) {
|
||||
sky_thread = Thread::create(_thread_function, this);
|
||||
regen_queued = false;
|
||||
}
|
||||
}
|
||||
|
||||
void ProceduralSky::_thread_function(void *p_ud) {
|
||||
|
||||
ProceduralSky *psky = (ProceduralSky *)p_ud;
|
||||
psky->call_deferred("_thread_done", psky->_generate_sky());
|
||||
}
|
||||
|
||||
void ProceduralSky::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("_update_sky"), &ProceduralSky::_update_sky);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_sky_top_color", "color"), &ProceduralSky::set_sky_top_color);
|
||||
ClassDB::bind_method(D_METHOD("get_sky_top_color"), &ProceduralSky::get_sky_top_color);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_sky_horizon_color", "color"), &ProceduralSky::set_sky_horizon_color);
|
||||
ClassDB::bind_method(D_METHOD("get_sky_horizon_color"), &ProceduralSky::get_sky_horizon_color);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_sky_curve", "curve"), &ProceduralSky::set_sky_curve);
|
||||
ClassDB::bind_method(D_METHOD("get_sky_curve"), &ProceduralSky::get_sky_curve);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_sky_energy", "energy"), &ProceduralSky::set_sky_energy);
|
||||
ClassDB::bind_method(D_METHOD("get_sky_energy"), &ProceduralSky::get_sky_energy);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_ground_bottom_color", "color"), &ProceduralSky::set_ground_bottom_color);
|
||||
ClassDB::bind_method(D_METHOD("get_ground_bottom_color"), &ProceduralSky::get_ground_bottom_color);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_ground_horizon_color", "color"), &ProceduralSky::set_ground_horizon_color);
|
||||
ClassDB::bind_method(D_METHOD("get_ground_horizon_color"), &ProceduralSky::get_ground_horizon_color);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_ground_curve", "curve"), &ProceduralSky::set_ground_curve);
|
||||
ClassDB::bind_method(D_METHOD("get_ground_curve"), &ProceduralSky::get_ground_curve);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_ground_energy", "energy"), &ProceduralSky::set_ground_energy);
|
||||
ClassDB::bind_method(D_METHOD("get_ground_energy"), &ProceduralSky::get_ground_energy);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_sun_color", "color"), &ProceduralSky::set_sun_color);
|
||||
ClassDB::bind_method(D_METHOD("get_sun_color"), &ProceduralSky::get_sun_color);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_sun_latitude", "degrees"), &ProceduralSky::set_sun_latitude);
|
||||
ClassDB::bind_method(D_METHOD("get_sun_latitude"), &ProceduralSky::get_sun_latitude);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_sun_longitude", "degrees"), &ProceduralSky::set_sun_longitude);
|
||||
ClassDB::bind_method(D_METHOD("get_sun_longitude"), &ProceduralSky::get_sun_longitude);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_sun_angle_min", "degrees"), &ProceduralSky::set_sun_angle_min);
|
||||
ClassDB::bind_method(D_METHOD("get_sun_angle_min"), &ProceduralSky::get_sun_angle_min);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_sun_angle_max", "degrees"), &ProceduralSky::set_sun_angle_max);
|
||||
ClassDB::bind_method(D_METHOD("get_sun_angle_max"), &ProceduralSky::get_sun_angle_max);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_sun_curve", "curve"), &ProceduralSky::set_sun_curve);
|
||||
ClassDB::bind_method(D_METHOD("get_sun_curve"), &ProceduralSky::get_sun_curve);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_sun_energy", "energy"), &ProceduralSky::set_sun_energy);
|
||||
ClassDB::bind_method(D_METHOD("get_sun_energy"), &ProceduralSky::get_sun_energy);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_texture_size", "size"), &ProceduralSky::set_texture_size);
|
||||
ClassDB::bind_method(D_METHOD("get_texture_size"), &ProceduralSky::get_texture_size);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("_thread_done", "image"), &ProceduralSky::_thread_done);
|
||||
|
||||
ADD_GROUP("Sky", "sky_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "sky_top_color"), "set_sky_top_color", "get_sky_top_color");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "sky_horizon_color"), "set_sky_horizon_color", "get_sky_horizon_color");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sky_curve", PROPERTY_HINT_EXP_EASING), "set_sky_curve", "get_sky_curve");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sky_energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_sky_energy", "get_sky_energy");
|
||||
|
||||
ADD_GROUP("Ground", "ground_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ground_bottom_color"), "set_ground_bottom_color", "get_ground_bottom_color");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ground_horizon_color"), "set_ground_horizon_color", "get_ground_horizon_color");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ground_curve", PROPERTY_HINT_EXP_EASING), "set_ground_curve", "get_ground_curve");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ground_energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_ground_energy", "get_ground_energy");
|
||||
|
||||
ADD_GROUP("Sun", "sun_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "sun_color"), "set_sun_color", "get_sun_color");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_latitude", PROPERTY_HINT_RANGE, "-180,180,0.01"), "set_sun_latitude", "get_sun_latitude");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_longitude", PROPERTY_HINT_RANGE, "-180,180,0.01"), "set_sun_longitude", "get_sun_longitude");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_angle_min", PROPERTY_HINT_RANGE, "0,360,0.01"), "set_sun_angle_min", "get_sun_angle_min");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_angle_max", PROPERTY_HINT_RANGE, "0,360,0.01"), "set_sun_angle_max", "get_sun_angle_max");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_curve", PROPERTY_HINT_EXP_EASING), "set_sun_curve", "get_sun_curve");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_sun_energy", "get_sun_energy");
|
||||
|
||||
ADD_GROUP("Texture2D", "texture_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_size", PROPERTY_HINT_ENUM, "256,512,1024,2048,4096"), "set_texture_size", "get_texture_size");
|
||||
|
||||
BIND_ENUM_CONSTANT(TEXTURE_SIZE_256);
|
||||
BIND_ENUM_CONSTANT(TEXTURE_SIZE_512);
|
||||
BIND_ENUM_CONSTANT(TEXTURE_SIZE_1024);
|
||||
BIND_ENUM_CONSTANT(TEXTURE_SIZE_2048);
|
||||
BIND_ENUM_CONSTANT(TEXTURE_SIZE_4096);
|
||||
BIND_ENUM_CONSTANT(TEXTURE_SIZE_MAX);
|
||||
}
|
||||
|
||||
ProceduralSky::ProceduralSky(bool p_desaturate) {
|
||||
|
||||
update_queued = false;
|
||||
sky_top_color = Color::hex(0xa5d6f1ff);
|
||||
sky_horizon_color = Color::hex(0xd6eafaff);
|
||||
sky_curve = 0.09;
|
||||
sky_energy = 1;
|
||||
|
||||
ground_bottom_color = Color::hex(0x282f36ff);
|
||||
ground_horizon_color = Color::hex(0x6c655fff);
|
||||
ground_curve = 0.02;
|
||||
ground_energy = 1;
|
||||
|
||||
if (p_desaturate) {
|
||||
sky_top_color.set_hsv(sky_top_color.get_h(), 0, sky_top_color.get_v());
|
||||
sky_horizon_color.set_hsv(sky_horizon_color.get_h(), 0, sky_horizon_color.get_v());
|
||||
ground_bottom_color.set_hsv(ground_bottom_color.get_h(), 0, ground_bottom_color.get_v());
|
||||
ground_horizon_color.set_hsv(ground_horizon_color.get_h(), 0, ground_horizon_color.get_v());
|
||||
}
|
||||
sun_color = Color(1, 1, 1);
|
||||
sun_latitude = 35;
|
||||
sun_longitude = 0;
|
||||
sun_angle_min = 1;
|
||||
sun_angle_max = 100;
|
||||
sun_curve = 0.05;
|
||||
sun_energy = 1;
|
||||
|
||||
texture_size = TEXTURE_SIZE_1024;
|
||||
sky_thread = NULL;
|
||||
regen_queued = false;
|
||||
first_time = true;
|
||||
|
||||
_queue_update();
|
||||
}
|
||||
|
||||
ProceduralSky::~ProceduralSky() {
|
||||
|
||||
if (sky_thread) {
|
||||
Thread::wait_to_finish(sky_thread);
|
||||
memdelete(sky_thread);
|
||||
sky_thread = NULL;
|
||||
}
|
||||
if (texture.is_valid()) {
|
||||
VS::get_singleton()->free(texture);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -32,6 +32,7 @@
|
|||
#define SKY_H
|
||||
|
||||
#include "core/os/thread.h"
|
||||
#include "scene/resources/material.h"
|
||||
#include "scene/resources/texture.h"
|
||||
|
||||
class Sky : public Resource {
|
||||
|
@ -58,6 +59,7 @@ private:
|
|||
RID sky;
|
||||
ProcessMode mode;
|
||||
RadianceSize radiance_size;
|
||||
Ref<Material> sky_material;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
@ -69,6 +71,9 @@ public:
|
|||
void set_process_mode(ProcessMode p_mode);
|
||||
ProcessMode get_process_mode() const;
|
||||
|
||||
void set_material(const Ref<Material> &p_material);
|
||||
Ref<Material> get_material() const;
|
||||
|
||||
virtual RID get_rid() const;
|
||||
|
||||
Sky();
|
||||
|
@ -78,129 +83,4 @@ public:
|
|||
VARIANT_ENUM_CAST(Sky::RadianceSize)
|
||||
VARIANT_ENUM_CAST(Sky::ProcessMode)
|
||||
|
||||
class PanoramaSky : public Sky {
|
||||
GDCLASS(PanoramaSky, Sky);
|
||||
|
||||
private:
|
||||
Ref<Texture2D> panorama;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
void set_panorama(const Ref<Texture2D> &p_panorama);
|
||||
Ref<Texture2D> get_panorama() const;
|
||||
|
||||
PanoramaSky();
|
||||
~PanoramaSky();
|
||||
};
|
||||
|
||||
class ProceduralSky : public Sky {
|
||||
GDCLASS(ProceduralSky, Sky);
|
||||
|
||||
public:
|
||||
enum TextureSize {
|
||||
TEXTURE_SIZE_256,
|
||||
TEXTURE_SIZE_512,
|
||||
TEXTURE_SIZE_1024,
|
||||
TEXTURE_SIZE_2048,
|
||||
TEXTURE_SIZE_4096,
|
||||
TEXTURE_SIZE_MAX
|
||||
};
|
||||
|
||||
private:
|
||||
Thread *sky_thread;
|
||||
Color sky_top_color;
|
||||
Color sky_horizon_color;
|
||||
float sky_curve;
|
||||
float sky_energy;
|
||||
|
||||
Color ground_bottom_color;
|
||||
Color ground_horizon_color;
|
||||
float ground_curve;
|
||||
float ground_energy;
|
||||
|
||||
Color sun_color;
|
||||
float sun_latitude;
|
||||
float sun_longitude;
|
||||
float sun_angle_min;
|
||||
float sun_angle_max;
|
||||
float sun_curve;
|
||||
float sun_energy;
|
||||
|
||||
TextureSize texture_size;
|
||||
|
||||
RID texture;
|
||||
|
||||
bool update_queued;
|
||||
bool regen_queued;
|
||||
|
||||
bool first_time;
|
||||
|
||||
void _thread_done(const Ref<Image> &p_image);
|
||||
static void _thread_function(void *p_ud);
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
Ref<Image> _generate_sky();
|
||||
void _update_sky();
|
||||
|
||||
void _queue_update();
|
||||
|
||||
public:
|
||||
void set_sky_top_color(const Color &p_sky_top);
|
||||
Color get_sky_top_color() const;
|
||||
|
||||
void set_sky_horizon_color(const Color &p_sky_horizon);
|
||||
Color get_sky_horizon_color() const;
|
||||
|
||||
void set_sky_curve(float p_curve);
|
||||
float get_sky_curve() const;
|
||||
|
||||
void set_sky_energy(float p_energy);
|
||||
float get_sky_energy() const;
|
||||
|
||||
void set_ground_bottom_color(const Color &p_ground_bottom);
|
||||
Color get_ground_bottom_color() const;
|
||||
|
||||
void set_ground_horizon_color(const Color &p_ground_horizon);
|
||||
Color get_ground_horizon_color() const;
|
||||
|
||||
void set_ground_curve(float p_curve);
|
||||
float get_ground_curve() const;
|
||||
|
||||
void set_ground_energy(float p_energy);
|
||||
float get_ground_energy() const;
|
||||
|
||||
void set_sun_color(const Color &p_sun);
|
||||
Color get_sun_color() const;
|
||||
|
||||
void set_sun_latitude(float p_angle);
|
||||
float get_sun_latitude() const;
|
||||
|
||||
void set_sun_longitude(float p_angle);
|
||||
float get_sun_longitude() const;
|
||||
|
||||
void set_sun_angle_min(float p_angle);
|
||||
float get_sun_angle_min() const;
|
||||
|
||||
void set_sun_angle_max(float p_angle);
|
||||
float get_sun_angle_max() const;
|
||||
|
||||
void set_sun_curve(float p_curve);
|
||||
float get_sun_curve() const;
|
||||
|
||||
void set_sun_energy(float p_energy);
|
||||
float get_sun_energy() const;
|
||||
|
||||
void set_texture_size(TextureSize p_size);
|
||||
TextureSize get_texture_size() const;
|
||||
|
||||
ProceduralSky(bool p_desaturate = false);
|
||||
~ProceduralSky();
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(ProceduralSky::TextureSize)
|
||||
|
||||
#endif // SKY_H
|
||||
|
|
626
scene/resources/sky_material.cpp
Normal file
626
scene/resources/sky_material.cpp
Normal file
|
@ -0,0 +1,626 @@
|
|||
/*************************************************************************/
|
||||
/* sky_material.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md) */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "sky_material.h"
|
||||
|
||||
void ProceduralSkyMaterial::set_sky_top_color(const Color &p_sky_top) {
|
||||
|
||||
sky_top_color = p_sky_top;
|
||||
VS::get_singleton()->material_set_param(_get_material(), "sky_top_color", sky_top_color.to_linear());
|
||||
}
|
||||
|
||||
Color ProceduralSkyMaterial::get_sky_top_color() const {
|
||||
|
||||
return sky_top_color;
|
||||
}
|
||||
|
||||
void ProceduralSkyMaterial::set_sky_horizon_color(const Color &p_sky_horizon) {
|
||||
|
||||
sky_horizon_color = p_sky_horizon;
|
||||
VS::get_singleton()->material_set_param(_get_material(), "sky_horizon_color", sky_horizon_color.to_linear());
|
||||
}
|
||||
Color ProceduralSkyMaterial::get_sky_horizon_color() const {
|
||||
|
||||
return sky_horizon_color;
|
||||
}
|
||||
|
||||
void ProceduralSkyMaterial::set_sky_curve(float p_curve) {
|
||||
|
||||
sky_curve = p_curve;
|
||||
VS::get_singleton()->material_set_param(_get_material(), "sky_curve", sky_curve);
|
||||
}
|
||||
float ProceduralSkyMaterial::get_sky_curve() const {
|
||||
|
||||
return sky_curve;
|
||||
}
|
||||
|
||||
void ProceduralSkyMaterial::set_sky_energy(float p_energy) {
|
||||
|
||||
sky_energy = p_energy;
|
||||
VS::get_singleton()->material_set_param(_get_material(), "sky_energy", sky_energy);
|
||||
}
|
||||
float ProceduralSkyMaterial::get_sky_energy() const {
|
||||
|
||||
return sky_energy;
|
||||
}
|
||||
|
||||
void ProceduralSkyMaterial::set_ground_bottom_color(const Color &p_ground_bottom) {
|
||||
|
||||
ground_bottom_color = p_ground_bottom;
|
||||
VS::get_singleton()->material_set_param(_get_material(), "ground_bottom_color", ground_bottom_color.to_linear());
|
||||
}
|
||||
Color ProceduralSkyMaterial::get_ground_bottom_color() const {
|
||||
|
||||
return ground_bottom_color;
|
||||
}
|
||||
|
||||
void ProceduralSkyMaterial::set_ground_horizon_color(const Color &p_ground_horizon) {
|
||||
|
||||
ground_horizon_color = p_ground_horizon;
|
||||
VS::get_singleton()->material_set_param(_get_material(), "ground_horizon_color", ground_horizon_color.to_linear());
|
||||
}
|
||||
Color ProceduralSkyMaterial::get_ground_horizon_color() const {
|
||||
|
||||
return ground_horizon_color;
|
||||
}
|
||||
|
||||
void ProceduralSkyMaterial::set_ground_curve(float p_curve) {
|
||||
|
||||
ground_curve = p_curve;
|
||||
VS::get_singleton()->material_set_param(_get_material(), "ground_curve", ground_curve);
|
||||
}
|
||||
float ProceduralSkyMaterial::get_ground_curve() const {
|
||||
|
||||
return ground_curve;
|
||||
}
|
||||
|
||||
void ProceduralSkyMaterial::set_ground_energy(float p_energy) {
|
||||
|
||||
ground_energy = p_energy;
|
||||
VS::get_singleton()->material_set_param(_get_material(), "ground_energy", ground_energy);
|
||||
}
|
||||
float ProceduralSkyMaterial::get_ground_energy() const {
|
||||
|
||||
return ground_energy;
|
||||
}
|
||||
|
||||
void ProceduralSkyMaterial::set_sun_angle_min(float p_angle) {
|
||||
|
||||
sun_angle_min = p_angle;
|
||||
VS::get_singleton()->material_set_param(_get_material(), "sun_angle_min", Math::deg2rad(sun_angle_min));
|
||||
}
|
||||
float ProceduralSkyMaterial::get_sun_angle_min() const {
|
||||
|
||||
return sun_angle_min;
|
||||
}
|
||||
|
||||
void ProceduralSkyMaterial::set_sun_angle_max(float p_angle) {
|
||||
|
||||
sun_angle_max = p_angle;
|
||||
VS::get_singleton()->material_set_param(_get_material(), "sun_angle_max", Math::deg2rad(sun_angle_max));
|
||||
}
|
||||
float ProceduralSkyMaterial::get_sun_angle_max() const {
|
||||
|
||||
return sun_angle_max;
|
||||
}
|
||||
|
||||
void ProceduralSkyMaterial::set_sun_curve(float p_curve) {
|
||||
|
||||
sun_curve = p_curve;
|
||||
VS::get_singleton()->material_set_param(_get_material(), "sun_curve", sun_curve);
|
||||
}
|
||||
float ProceduralSkyMaterial::get_sun_curve() const {
|
||||
|
||||
return sun_curve;
|
||||
}
|
||||
|
||||
bool ProceduralSkyMaterial::_can_do_next_pass() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
Shader::Mode ProceduralSkyMaterial::get_shader_mode() const {
|
||||
|
||||
return Shader::MODE_SKY;
|
||||
}
|
||||
|
||||
RID ProceduralSkyMaterial::get_shader_rid() const {
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
void ProceduralSkyMaterial::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_sky_top_color", "color"), &ProceduralSkyMaterial::set_sky_top_color);
|
||||
ClassDB::bind_method(D_METHOD("get_sky_top_color"), &ProceduralSkyMaterial::get_sky_top_color);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_sky_horizon_color", "color"), &ProceduralSkyMaterial::set_sky_horizon_color);
|
||||
ClassDB::bind_method(D_METHOD("get_sky_horizon_color"), &ProceduralSkyMaterial::get_sky_horizon_color);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_sky_curve", "curve"), &ProceduralSkyMaterial::set_sky_curve);
|
||||
ClassDB::bind_method(D_METHOD("get_sky_curve"), &ProceduralSkyMaterial::get_sky_curve);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_sky_energy", "energy"), &ProceduralSkyMaterial::set_sky_energy);
|
||||
ClassDB::bind_method(D_METHOD("get_sky_energy"), &ProceduralSkyMaterial::get_sky_energy);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_ground_bottom_color", "color"), &ProceduralSkyMaterial::set_ground_bottom_color);
|
||||
ClassDB::bind_method(D_METHOD("get_ground_bottom_color"), &ProceduralSkyMaterial::get_ground_bottom_color);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_ground_horizon_color", "color"), &ProceduralSkyMaterial::set_ground_horizon_color);
|
||||
ClassDB::bind_method(D_METHOD("get_ground_horizon_color"), &ProceduralSkyMaterial::get_ground_horizon_color);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_ground_curve", "curve"), &ProceduralSkyMaterial::set_ground_curve);
|
||||
ClassDB::bind_method(D_METHOD("get_ground_curve"), &ProceduralSkyMaterial::get_ground_curve);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_ground_energy", "energy"), &ProceduralSkyMaterial::set_ground_energy);
|
||||
ClassDB::bind_method(D_METHOD("get_ground_energy"), &ProceduralSkyMaterial::get_ground_energy);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_sun_angle_min", "degrees"), &ProceduralSkyMaterial::set_sun_angle_min);
|
||||
ClassDB::bind_method(D_METHOD("get_sun_angle_min"), &ProceduralSkyMaterial::get_sun_angle_min);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_sun_angle_max", "degrees"), &ProceduralSkyMaterial::set_sun_angle_max);
|
||||
ClassDB::bind_method(D_METHOD("get_sun_angle_max"), &ProceduralSkyMaterial::get_sun_angle_max);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_sun_curve", "curve"), &ProceduralSkyMaterial::set_sun_curve);
|
||||
ClassDB::bind_method(D_METHOD("get_sun_curve"), &ProceduralSkyMaterial::get_sun_curve);
|
||||
|
||||
ADD_GROUP("Sky", "sky_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "sky_top_color"), "set_sky_top_color", "get_sky_top_color");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "sky_horizon_color"), "set_sky_horizon_color", "get_sky_horizon_color");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sky_curve", PROPERTY_HINT_EXP_EASING), "set_sky_curve", "get_sky_curve");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sky_energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_sky_energy", "get_sky_energy");
|
||||
|
||||
ADD_GROUP("Ground", "ground_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ground_bottom_color"), "set_ground_bottom_color", "get_ground_bottom_color");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ground_horizon_color"), "set_ground_horizon_color", "get_ground_horizon_color");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ground_curve", PROPERTY_HINT_EXP_EASING), "set_ground_curve", "get_ground_curve");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ground_energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_ground_energy", "get_ground_energy");
|
||||
|
||||
ADD_GROUP("Sun", "sun_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_angle_min", PROPERTY_HINT_RANGE, "0,360,0.01"), "set_sun_angle_min", "get_sun_angle_min");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_angle_max", PROPERTY_HINT_RANGE, "0,360,0.01"), "set_sun_angle_max", "get_sun_angle_max");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_curve", PROPERTY_HINT_EXP_EASING), "set_sun_curve", "get_sun_curve");
|
||||
}
|
||||
|
||||
ProceduralSkyMaterial::ProceduralSkyMaterial() {
|
||||
|
||||
String code = "shader_type sky;\n\n";
|
||||
|
||||
code += "uniform vec4 sky_top_color : hint_color = vec4(0.35, 0.46, 0.71, 1.0);\n";
|
||||
code += "uniform vec4 sky_horizon_color : hint_color = vec4(0.55, 0.69, 0.81, 1.0);\n";
|
||||
code += "uniform float sky_curve : hint_range(0, 1) = 0.09;\n";
|
||||
code += "uniform float sky_energy = 1.0;\n\n";
|
||||
code += "uniform vec4 ground_bottom_color : hint_color = vec4(0.12, 0.12, 0.13, 1.0);\n";
|
||||
code += "uniform vec4 ground_horizon_color : hint_color = vec4(0.37, 0.33, 0.31, 1.0);\n";
|
||||
code += "uniform float ground_curve : hint_range(0, 1) = 0.02;\n";
|
||||
code += "uniform float ground_energy = 1.0;\n\n";
|
||||
code += "uniform float sun_angle_min = 0.01;\n";
|
||||
code += "uniform float sun_angle_max = 1.0;\n";
|
||||
code += "uniform float sun_curve : hint_range(0, 1) = 0.05;\n\n";
|
||||
code += "const float PI = 3.1415926535897932384626433833;\n\n";
|
||||
code += "void fragment() {\n";
|
||||
code += "\tfloat v_angle = acos(clamp(EYEDIR.y, -1.0, 1.0));\n";
|
||||
code += "\tfloat c = (1.0 - v_angle / (PI * 0.5));\n";
|
||||
code += "\tvec3 sky = mix(sky_horizon_color.rgb, sky_top_color.rgb, clamp(1.0 - pow(1.0 - c, 1.0 / sky_curve), 0.0, 1.0));\n";
|
||||
code += "\tsky *= sky_energy;\n";
|
||||
code += "\tif (LIGHT0_ENABLED) {\n";
|
||||
code += "\t\tfloat sun_angle = acos(dot(LIGHT0_DIRECTION, EYEDIR));\n";
|
||||
code += "\t\tif (sun_angle < sun_angle_min) {\n";
|
||||
code += "\t\t\tsky = LIGHT0_COLOR * LIGHT0_ENERGY;\n";
|
||||
code += "\t\t} else if (sun_angle < sun_angle_max) {\n";
|
||||
code += "\t\t\tfloat c2 = (sun_angle - sun_angle_min) / (sun_angle_max - sun_angle_min);\n";
|
||||
code += "\t\t\tsky = mix(LIGHT0_COLOR * LIGHT0_ENERGY, sky, clamp(1.0 - pow(1.0 - c2, 1.0 / sun_curve), 0.0, 1.0));\n";
|
||||
code += "\t\t}\n";
|
||||
code += "\t}\n";
|
||||
code += "\tif (LIGHT1_ENABLED) {\n";
|
||||
code += "\t\tfloat sun_angle = acos(dot(LIGHT1_DIRECTION, EYEDIR));\n";
|
||||
code += "\t\tif (sun_angle < sun_angle_min) {\n";
|
||||
code += "\t\t\tsky = LIGHT1_COLOR * LIGHT1_ENERGY;\n";
|
||||
code += "\t\t} else if (sun_angle < sun_angle_max) {\n";
|
||||
code += "\t\t\tfloat c2 = (sun_angle - sun_angle_min) / (sun_angle_max - sun_angle_min);\n";
|
||||
code += "\t\t\tsky = mix(LIGHT1_COLOR * LIGHT1_ENERGY, sky, clamp(1.0 - pow(1.0 - c2, 1.0 / sun_curve), 0.0, 1.0));\n";
|
||||
code += "\t\t}\n";
|
||||
code += "\t}\n";
|
||||
code += "\tif (LIGHT2_ENABLED) {\n";
|
||||
code += "\t\tfloat sun_angle = acos(dot(LIGHT2_DIRECTION, EYEDIR));\n";
|
||||
code += "\t\tif (sun_angle < sun_angle_min) {\n";
|
||||
code += "\t\t\tsky = LIGHT2_COLOR * LIGHT2_ENERGY;\n";
|
||||
code += "\t\t} else if (sun_angle < sun_angle_max) {\n";
|
||||
code += "\t\t\tfloat c2 = (sun_angle - sun_angle_min) / (sun_angle_max - sun_angle_min);\n";
|
||||
code += "\t\t\tsky = mix(LIGHT2_COLOR * LIGHT2_ENERGY, sky, clamp(1.0 - pow(1.0 - c2, 1.0 / sun_curve), 0.0, 1.0));\n";
|
||||
code += "\t\t}\n";
|
||||
code += "\t}\n";
|
||||
code += "\tif (LIGHT3_ENABLED) {\n";
|
||||
code += "\t\tfloat sun_angle = acos(dot(LIGHT3_DIRECTION, EYEDIR));\n";
|
||||
code += "\t\tif (sun_angle < sun_angle_min) {\n";
|
||||
code += "\t\t\tsky = LIGHT3_COLOR * LIGHT3_ENERGY;\n";
|
||||
code += "\t\t} else if (sun_angle < sun_angle_max) {\n";
|
||||
code += "\t\t\tfloat c2 = (sun_angle - sun_angle_min) / (sun_angle_max - sun_angle_min);\n";
|
||||
code += "\t\t\tsky = mix(LIGHT3_COLOR * LIGHT3_ENERGY, sky, clamp(1.0 - pow(1.0 - c2, 1.0 / sun_curve), 0.0, 1.0));\n";
|
||||
code += "\t\t}\n";
|
||||
code += "\t}\n";
|
||||
code += "\tc = (v_angle - (PI * 0.5)) / (PI * 0.5);\n";
|
||||
code += "\tvec3 ground = mix(ground_horizon_color.rgb, ground_bottom_color.rgb, clamp(1.0 - pow(1.0 - c, 1.0 / ground_curve), 0.0, 1.0));\n";
|
||||
code += "\tground *= ground_energy;\n";
|
||||
code += "\tCOLOR = mix(ground, sky, step(0.0, EYEDIR.y));\n";
|
||||
code += "}\n";
|
||||
|
||||
shader = VS::get_singleton()->shader_create();
|
||||
|
||||
VS::get_singleton()->shader_set_code(shader, code);
|
||||
|
||||
VS::get_singleton()->material_set_shader(_get_material(), shader);
|
||||
|
||||
set_sky_top_color(Color(0.35, 0.46, 0.71));
|
||||
set_sky_horizon_color(Color(0.55, 0.69, 0.81));
|
||||
set_sky_curve(0.09);
|
||||
set_sky_energy(1.0);
|
||||
|
||||
set_ground_bottom_color(Color(0.12, 0.12, 0.13));
|
||||
set_ground_horizon_color(Color(0.37, 0.33, 0.31));
|
||||
set_ground_curve(0.02);
|
||||
set_ground_energy(1.0);
|
||||
|
||||
set_sun_angle_min(1.0);
|
||||
set_sun_angle_max(100.0);
|
||||
set_sun_curve(0.05);
|
||||
}
|
||||
|
||||
ProceduralSkyMaterial::~ProceduralSkyMaterial() {
|
||||
}
|
||||
|
||||
/////////////////////////////////////////
|
||||
/* PanoramaSkyMaterial */
|
||||
|
||||
void PanoramaSkyMaterial::set_panorama(const Ref<Texture2D> &p_panorama) {
|
||||
|
||||
panorama = p_panorama;
|
||||
VS::get_singleton()->material_set_param(_get_material(), "source_panorama", panorama);
|
||||
}
|
||||
|
||||
Ref<Texture2D> PanoramaSkyMaterial::get_panorama() const {
|
||||
|
||||
return panorama;
|
||||
}
|
||||
|
||||
bool PanoramaSkyMaterial::_can_do_next_pass() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
Shader::Mode PanoramaSkyMaterial::get_shader_mode() const {
|
||||
|
||||
return Shader::MODE_SKY;
|
||||
}
|
||||
|
||||
RID PanoramaSkyMaterial::get_shader_rid() const {
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
void PanoramaSkyMaterial::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_panorama", "texture"), &PanoramaSkyMaterial::set_panorama);
|
||||
ClassDB::bind_method(D_METHOD("get_panorama"), &PanoramaSkyMaterial::get_panorama);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "panorama", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_panorama", "get_panorama");
|
||||
}
|
||||
|
||||
PanoramaSkyMaterial::PanoramaSkyMaterial() {
|
||||
String code = "shader_type sky;\n\n";
|
||||
|
||||
code += "uniform sampler2D source_panorama : filter_linear;\n";
|
||||
code += "void fragment() {\n";
|
||||
code += "\tCOLOR = texture(source_panorama, SKY_COORDS).rgb;\n";
|
||||
code += "}";
|
||||
|
||||
shader = VS::get_singleton()->shader_create();
|
||||
|
||||
VS::get_singleton()->shader_set_code(shader, code);
|
||||
|
||||
VS::get_singleton()->material_set_shader(_get_material(), shader);
|
||||
}
|
||||
|
||||
PanoramaSkyMaterial::~PanoramaSkyMaterial() {
|
||||
VS::get_singleton()->free(shader);
|
||||
VS::get_singleton()->material_set_shader(_get_material(), RID());
|
||||
}
|
||||
//////////////////////////////////
|
||||
/* PhysicalSkyMaterial */
|
||||
|
||||
void PhysicalSkyMaterial::set_rayleigh_coefficient(float p_rayleigh) {
|
||||
|
||||
rayleigh = p_rayleigh;
|
||||
VS::get_singleton()->material_set_param(_get_material(), "rayleigh", rayleigh);
|
||||
}
|
||||
float PhysicalSkyMaterial::get_rayleigh_coefficient() const {
|
||||
|
||||
return rayleigh;
|
||||
}
|
||||
|
||||
void PhysicalSkyMaterial::set_rayleigh_color(Color p_rayleigh_color) {
|
||||
|
||||
rayleigh_color = p_rayleigh_color;
|
||||
VS::get_singleton()->material_set_param(_get_material(), "rayleigh_color", rayleigh_color);
|
||||
}
|
||||
Color PhysicalSkyMaterial::get_rayleigh_color() const {
|
||||
|
||||
return rayleigh_color;
|
||||
}
|
||||
|
||||
void PhysicalSkyMaterial::set_mie_coefficient(float p_mie) {
|
||||
|
||||
mie = p_mie;
|
||||
VS::get_singleton()->material_set_param(_get_material(), "mie", mie);
|
||||
}
|
||||
float PhysicalSkyMaterial::get_mie_coefficient() const {
|
||||
|
||||
return mie;
|
||||
}
|
||||
|
||||
void PhysicalSkyMaterial::set_mie_eccentricity(float p_eccentricity) {
|
||||
|
||||
mie_eccentricity = p_eccentricity;
|
||||
VS::get_singleton()->material_set_param(_get_material(), "mie_eccentricity", mie_eccentricity);
|
||||
}
|
||||
float PhysicalSkyMaterial::get_mie_eccentricity() const {
|
||||
|
||||
return mie_eccentricity;
|
||||
}
|
||||
|
||||
void PhysicalSkyMaterial::set_mie_color(Color p_mie_color) {
|
||||
|
||||
mie_color = p_mie_color;
|
||||
VS::get_singleton()->material_set_param(_get_material(), "mie_color", mie_color);
|
||||
}
|
||||
Color PhysicalSkyMaterial::get_mie_color() const {
|
||||
return mie_color;
|
||||
}
|
||||
|
||||
void PhysicalSkyMaterial::set_turbidity(float p_turbidity) {
|
||||
|
||||
turbidity = p_turbidity;
|
||||
VS::get_singleton()->material_set_param(_get_material(), "turbidity", turbidity);
|
||||
}
|
||||
float PhysicalSkyMaterial::get_turbidity() const {
|
||||
|
||||
return turbidity;
|
||||
}
|
||||
|
||||
void PhysicalSkyMaterial::set_sun_disk_scale(float p_sun_disk_scale) {
|
||||
|
||||
sun_disk_scale = p_sun_disk_scale;
|
||||
VS::get_singleton()->material_set_param(_get_material(), "sun_disk_scale", sun_disk_scale);
|
||||
}
|
||||
float PhysicalSkyMaterial::get_sun_disk_scale() const {
|
||||
|
||||
return sun_disk_scale;
|
||||
}
|
||||
|
||||
void PhysicalSkyMaterial::set_ground_color(Color p_ground_color) {
|
||||
|
||||
ground_color = p_ground_color;
|
||||
VS::get_singleton()->material_set_param(_get_material(), "ground_color", ground_color);
|
||||
}
|
||||
Color PhysicalSkyMaterial::get_ground_color() const {
|
||||
|
||||
return ground_color;
|
||||
}
|
||||
|
||||
void PhysicalSkyMaterial::set_exposure(float p_exposure) {
|
||||
|
||||
exposure = p_exposure;
|
||||
VS::get_singleton()->material_set_param(_get_material(), "exposure", exposure);
|
||||
}
|
||||
float PhysicalSkyMaterial::get_exposure() const {
|
||||
|
||||
return exposure;
|
||||
}
|
||||
|
||||
void PhysicalSkyMaterial::set_dither_strength(float p_dither_strength) {
|
||||
|
||||
dither_strength = p_dither_strength;
|
||||
VS::get_singleton()->material_set_param(_get_material(), "dither_strength", dither_strength);
|
||||
}
|
||||
float PhysicalSkyMaterial::get_dither_strength() const {
|
||||
|
||||
return dither_strength;
|
||||
}
|
||||
|
||||
bool PhysicalSkyMaterial::_can_do_next_pass() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
Shader::Mode PhysicalSkyMaterial::get_shader_mode() const {
|
||||
|
||||
return Shader::MODE_SKY;
|
||||
}
|
||||
|
||||
RID PhysicalSkyMaterial::get_shader_rid() const {
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
void PhysicalSkyMaterial::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_rayleigh_coefficient", "rayleigh"), &PhysicalSkyMaterial::set_rayleigh_coefficient);
|
||||
ClassDB::bind_method(D_METHOD("get_rayleigh_coefficient"), &PhysicalSkyMaterial::get_rayleigh_coefficient);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_rayleigh_color", "color"), &PhysicalSkyMaterial::set_rayleigh_color);
|
||||
ClassDB::bind_method(D_METHOD("get_rayleigh_color"), &PhysicalSkyMaterial::get_rayleigh_color);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_mie_coefficient", "mie"), &PhysicalSkyMaterial::set_mie_coefficient);
|
||||
ClassDB::bind_method(D_METHOD("get_mie_coefficient"), &PhysicalSkyMaterial::get_mie_coefficient);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_mie_eccentricity", "eccentricity"), &PhysicalSkyMaterial::set_mie_eccentricity);
|
||||
ClassDB::bind_method(D_METHOD("get_mie_eccentricity"), &PhysicalSkyMaterial::get_mie_eccentricity);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_mie_color", "color"), &PhysicalSkyMaterial::set_mie_color);
|
||||
ClassDB::bind_method(D_METHOD("get_mie_color"), &PhysicalSkyMaterial::get_mie_color);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_turbidity", "turbidity"), &PhysicalSkyMaterial::set_turbidity);
|
||||
ClassDB::bind_method(D_METHOD("get_turbidity"), &PhysicalSkyMaterial::get_turbidity);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_sun_disk_scale", "scale"), &PhysicalSkyMaterial::set_sun_disk_scale);
|
||||
ClassDB::bind_method(D_METHOD("get_sun_disk_scale"), &PhysicalSkyMaterial::get_sun_disk_scale);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_ground_color", "color"), &PhysicalSkyMaterial::set_ground_color);
|
||||
ClassDB::bind_method(D_METHOD("get_ground_color"), &PhysicalSkyMaterial::get_ground_color);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_exposure", "exposure"), &PhysicalSkyMaterial::set_exposure);
|
||||
ClassDB::bind_method(D_METHOD("get_exposure"), &PhysicalSkyMaterial::get_exposure);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_dither_strength", "strength"), &PhysicalSkyMaterial::set_dither_strength);
|
||||
ClassDB::bind_method(D_METHOD("get_dither_strength"), &PhysicalSkyMaterial::get_dither_strength);
|
||||
|
||||
ADD_GROUP("Rayleigh", "rayleigh_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rayleigh_coefficient", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_rayleigh_coefficient", "get_rayleigh_coefficient");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "rayleigh_color"), "set_rayleigh_color", "get_rayleigh_color");
|
||||
|
||||
ADD_GROUP("Mie", "mie_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mie_coefficient", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_mie_coefficient", "get_mie_coefficient");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mie_eccentricity", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_mie_eccentricity", "get_mie_eccentricity");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "mie_color"), "set_mie_color", "get_mie_color");
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "turbidity", PROPERTY_HINT_RANGE, "0,1000,0.01"), "set_turbidity", "get_turbidity");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_disk_scale", PROPERTY_HINT_RANGE, "0,360,0.01"), "set_sun_disk_scale", "get_sun_disk_scale");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ground_color"), "set_ground_color", "get_ground_color");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "exposure", PROPERTY_HINT_RANGE, "0,128,0.01"), "set_exposure", "get_exposure");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dither_strength", PROPERTY_HINT_RANGE, "0,10,0.01"), "set_dither_strength", "get_dither_strength");
|
||||
}
|
||||
|
||||
PhysicalSkyMaterial::PhysicalSkyMaterial() {
|
||||
String code = "shader_type sky;\n\n";
|
||||
|
||||
code += "uniform float rayleigh : hint_range(0, 64) = 2.0;\n";
|
||||
code += "uniform vec4 rayleigh_color : hint_color = vec4(0.056, 0.14, 0.3, 1.0);\n";
|
||||
code += "uniform float mie : hint_range(0, 1) = 0.005;\n";
|
||||
code += "uniform float mie_eccentricity : hint_range(-1, 1) = 0.8;\n";
|
||||
code += "uniform vec4 mie_color : hint_color = vec4(0.36, 0.56, 0.82, 1.0);\n\n";
|
||||
|
||||
code += "uniform float turbidity : hint_range(0, 1000) = 10.0;\n";
|
||||
code += "uniform float sun_disk_scale : hint_range(0, 360) = 1.0;\n";
|
||||
code += "uniform vec4 ground_color : hint_color = vec4(1.0);\n";
|
||||
code += "uniform float exposure : hint_range(0, 128) = 0.1;\n";
|
||||
code += "uniform float dither_strength : hint_range(0, 10) = 1.0;\n\n";
|
||||
|
||||
code += "const float PI = 3.141592653589793238462643383279502884197169;\n";
|
||||
code += "const vec3 UP = vec3( 0.0, 1.0, 0.0 );\n\n";
|
||||
|
||||
code += "// Sun constants\n";
|
||||
code += "const float SOL_SIZE = 0.00872663806;\n";
|
||||
code += "const float SUN_ENERGY = 1000.0;\n\n";
|
||||
|
||||
code += "// optical length at zenith for molecules\n";
|
||||
code += "const float rayleigh_zenith_size = 8.4e3;\n";
|
||||
code += "const float mie_zenith_size = 1.25e3;\n\n";
|
||||
|
||||
code += "float henyey_greenstein(float cos_theta, float g) {\n";
|
||||
code += "\tconst float k = 0.0795774715459;\n";
|
||||
code += "\treturn k * (1.0 - g * g) / (pow(1.0 + g * g - 2.0 * g * cos_theta, 1.5));\n";
|
||||
code += "}\n\n";
|
||||
|
||||
code += "// From: https://www.shadertoy.com/view/4sfGzS credit to iq\n";
|
||||
code += "float hash(vec3 p) {\n";
|
||||
code += "\tp = fract( p * 0.3183099 + 0.1 );\n";
|
||||
code += "\tp *= 17.0;\n";
|
||||
code += "\treturn fract(p.x * p.y * p.z * (p.x + p.y + p.z));\n";
|
||||
code += "}\n\n";
|
||||
|
||||
code += "void fragment() {\n";
|
||||
code += "\tfloat zenith_angle = clamp( dot(UP, normalize(LIGHT0_DIRECTION)), -1.0, 1.0 );\n";
|
||||
code += "\tfloat sun_energy = max(0.0, 1.0 - exp(-((PI * 0.5) - acos(zenith_angle)))) * SUN_ENERGY * LIGHT0_ENERGY;\n";
|
||||
code += "\tfloat sun_fade = 1.0 - clamp(1.0 - exp(LIGHT0_DIRECTION.y), 0.0, 1.0);\n\n";
|
||||
|
||||
code += "\t// rayleigh coefficients\n";
|
||||
code += "\tfloat rayleigh_coefficient = rayleigh - ( 1.0 * ( 1.0 - sun_fade ) );\n";
|
||||
code += "\tvec3 rayleigh_beta = rayleigh_coefficient * rayleigh_color.rgb * 0.0001;\n";
|
||||
code += "\t// mie coefficients from Preetham\n";
|
||||
code += "\tvec3 mie_beta = turbidity * mie * mie_color.rgb * 0.000434;\n\n";
|
||||
|
||||
code += "\t// optical length\n";
|
||||
code += "\tfloat zenith = acos(max(0.0, dot(UP, EYEDIR)));\n";
|
||||
code += "\tfloat optical_mass = 1.0 / (cos(zenith) + 0.15 * pow(93.885 - degrees(zenith), -1.253));\n";
|
||||
code += "\tfloat rayleigh_scatter = rayleigh_zenith_size * optical_mass;\n";
|
||||
code += "\tfloat mie_scatter = mie_zenith_size * optical_mass;\n\n";
|
||||
|
||||
code += "\t// light extinction based on thickness of atmosphere\n";
|
||||
code += "\tvec3 extinction = exp(-(rayleigh_beta * rayleigh_scatter + mie_beta * mie_scatter));\n\n";
|
||||
|
||||
code += "\t// in scattering\n";
|
||||
code += "\tfloat cos_theta = dot(EYEDIR, normalize(LIGHT0_DIRECTION));\n\n";
|
||||
|
||||
code += "\tfloat rayleigh_phase = (3.0 / (16.0 * PI)) * (1.0 + pow(cos_theta * 0.5 + 0.5, 2.0));\n";
|
||||
code += "\tvec3 betaRTheta = rayleigh_beta * rayleigh_phase;\n\n";
|
||||
|
||||
code += "\tfloat mie_phase = henyey_greenstein(cos_theta, mie_eccentricity);\n";
|
||||
code += "\tvec3 betaMTheta = mie_beta * mie_phase;\n\n";
|
||||
|
||||
code += "\tvec3 Lin = pow(sun_energy * ((betaRTheta + betaMTheta) / (rayleigh_beta + mie_beta)) * (1.0 - extinction), vec3(1.5));\n";
|
||||
code += "\t// Hack from https://github.com/mrdoob/three.js/blob/master/examples/jsm/objects/Sky.js\n";
|
||||
code += "\tLin *= mix(vec3(1.0), pow(sun_energy * ((betaRTheta + betaMTheta) / (rayleigh_beta + mie_beta)) * extinction, vec3(0.5)), clamp(pow(1.0 - zenith_angle, 5.0), 0.0, 1.0));\n\n";
|
||||
|
||||
code += "\t// Hack in the ground color\n";
|
||||
code += "\tLin *= mix(ground_color.rgb, vec3(1.0), smoothstep(-0.1, 0.1, dot(UP, EYEDIR)));\n\n";
|
||||
|
||||
code += "\t// Solar disk and out-scattering\n";
|
||||
code += "\tfloat sunAngularDiameterCos = cos(SOL_SIZE * sun_disk_scale);\n";
|
||||
code += "\tfloat sunAngularDiameterCos2 = cos(SOL_SIZE * sun_disk_scale*0.5);\n";
|
||||
code += "\tfloat sundisk = smoothstep(sunAngularDiameterCos, sunAngularDiameterCos2, cos_theta);\n";
|
||||
code += "\tvec3 L0 = (sun_energy * 1900.0 * extinction) * sundisk * LIGHT0_COLOR;\n";
|
||||
code += "\t// Note: Add nightime here: L0 += night_sky * extinction\n\n";
|
||||
|
||||
code += "\tvec3 color = (Lin + L0) * 0.04;\n";
|
||||
code += "\tCOLOR = pow(color, vec3(1.0 / (1.2 + (1.2 * sun_fade))));\n";
|
||||
code += "\tCOLOR *= exposure;\n";
|
||||
code += "\t// Make optional, eliminates banding\n";
|
||||
code += "\tCOLOR += (hash(EYEDIR * 1741.9782) * 0.08 - 0.04) * 0.008 * dither_strength;\n";
|
||||
code += "}\n";
|
||||
|
||||
shader = VS::get_singleton()->shader_create();
|
||||
|
||||
VS::get_singleton()->shader_set_code(shader, code);
|
||||
|
||||
VS::get_singleton()->material_set_shader(_get_material(), shader);
|
||||
|
||||
set_rayleigh_coefficient(2.0);
|
||||
set_rayleigh_color(Color(0.056, 0.14, 0.3));
|
||||
set_mie_coefficient(0.005);
|
||||
set_mie_eccentricity(0.8);
|
||||
set_mie_color(Color(0.36, 0.56, 0.82));
|
||||
set_turbidity(10.0);
|
||||
set_sun_disk_scale(1.0);
|
||||
set_ground_color(Color(1.0, 1.0, 1.0));
|
||||
set_exposure(0.1);
|
||||
set_dither_strength(1.0);
|
||||
}
|
||||
|
||||
PhysicalSkyMaterial::~PhysicalSkyMaterial() {
|
||||
VS::get_singleton()->free(shader);
|
||||
VS::get_singleton()->material_set_shader(_get_material(), RID());
|
||||
}
|
190
scene/resources/sky_material.h
Normal file
190
scene/resources/sky_material.h
Normal file
|
@ -0,0 +1,190 @@
|
|||
/*************************************************************************/
|
||||
/* sky_material.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md) */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "core/rid.h"
|
||||
#include "scene/resources/material.h"
|
||||
|
||||
#ifndef SKY_MATERIAL_H
|
||||
#define SKY_MATERIAL_H
|
||||
|
||||
class ProceduralSkyMaterial : public Material {
|
||||
|
||||
GDCLASS(ProceduralSkyMaterial, Material);
|
||||
|
||||
private:
|
||||
Color sky_top_color;
|
||||
Color sky_horizon_color;
|
||||
float sky_curve;
|
||||
float sky_energy;
|
||||
|
||||
Color ground_bottom_color;
|
||||
Color ground_horizon_color;
|
||||
float ground_curve;
|
||||
float ground_energy;
|
||||
|
||||
float sun_angle_min;
|
||||
float sun_angle_max;
|
||||
float sun_curve;
|
||||
|
||||
RID shader;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
virtual bool _can_do_next_pass() const;
|
||||
|
||||
public:
|
||||
void set_sky_top_color(const Color &p_sky_top);
|
||||
Color get_sky_top_color() const;
|
||||
|
||||
void set_sky_horizon_color(const Color &p_sky_horizon);
|
||||
Color get_sky_horizon_color() const;
|
||||
|
||||
void set_sky_curve(float p_curve);
|
||||
float get_sky_curve() const;
|
||||
|
||||
void set_sky_energy(float p_energy);
|
||||
float get_sky_energy() const;
|
||||
|
||||
void set_ground_bottom_color(const Color &p_ground_bottom);
|
||||
Color get_ground_bottom_color() const;
|
||||
|
||||
void set_ground_horizon_color(const Color &p_ground_horizon);
|
||||
Color get_ground_horizon_color() const;
|
||||
|
||||
void set_ground_curve(float p_curve);
|
||||
float get_ground_curve() const;
|
||||
|
||||
void set_ground_energy(float p_energy);
|
||||
float get_ground_energy() const;
|
||||
|
||||
void set_sun_angle_min(float p_angle);
|
||||
float get_sun_angle_min() const;
|
||||
|
||||
void set_sun_angle_max(float p_angle);
|
||||
float get_sun_angle_max() const;
|
||||
|
||||
void set_sun_curve(float p_curve);
|
||||
float get_sun_curve() const;
|
||||
|
||||
virtual Shader::Mode get_shader_mode() const;
|
||||
RID get_shader_rid() const;
|
||||
|
||||
ProceduralSkyMaterial();
|
||||
~ProceduralSkyMaterial();
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
/* PanoramaSkyMaterial */
|
||||
|
||||
class PanoramaSkyMaterial : public Material {
|
||||
GDCLASS(PanoramaSkyMaterial, Material);
|
||||
|
||||
private:
|
||||
Ref<Texture2D> panorama;
|
||||
RID shader;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
virtual bool _can_do_next_pass() const;
|
||||
|
||||
public:
|
||||
void set_panorama(const Ref<Texture2D> &p_panorama);
|
||||
Ref<Texture2D> get_panorama() const;
|
||||
|
||||
virtual Shader::Mode get_shader_mode() const;
|
||||
RID get_shader_rid() const;
|
||||
|
||||
PanoramaSkyMaterial();
|
||||
~PanoramaSkyMaterial();
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
/* PanoramaSkyMaterial */
|
||||
|
||||
class PhysicalSkyMaterial : public Material {
|
||||
GDCLASS(PhysicalSkyMaterial, Material);
|
||||
|
||||
private:
|
||||
RID shader;
|
||||
|
||||
float rayleigh;
|
||||
Color rayleigh_color;
|
||||
float mie;
|
||||
float mie_eccentricity;
|
||||
Color mie_color;
|
||||
float turbidity;
|
||||
float sun_disk_scale;
|
||||
Color ground_color;
|
||||
float exposure;
|
||||
float dither_strength;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
virtual bool _can_do_next_pass() const;
|
||||
|
||||
public:
|
||||
void set_rayleigh_coefficient(float p_rayleigh);
|
||||
float get_rayleigh_coefficient() const;
|
||||
|
||||
void set_rayleigh_color(Color p_rayleigh_color);
|
||||
Color get_rayleigh_color() const;
|
||||
|
||||
void set_turbidity(float p_turbidity);
|
||||
float get_turbidity() const;
|
||||
|
||||
void set_mie_coefficient(float p_mie);
|
||||
float get_mie_coefficient() const;
|
||||
|
||||
void set_mie_eccentricity(float p_eccentricity);
|
||||
float get_mie_eccentricity() const;
|
||||
|
||||
void set_mie_color(Color p_mie_color);
|
||||
Color get_mie_color() const;
|
||||
|
||||
void set_sun_disk_scale(float p_sun_disk_scale);
|
||||
float get_sun_disk_scale() const;
|
||||
|
||||
void set_ground_color(Color p_ground_color);
|
||||
Color get_ground_color() const;
|
||||
|
||||
void set_exposure(float p_exposure);
|
||||
float get_exposure() const;
|
||||
|
||||
void set_dither_strength(float p_dither_strength);
|
||||
float get_dither_strength() const;
|
||||
|
||||
virtual Shader::Mode get_shader_mode() const;
|
||||
RID get_shader_rid() const;
|
||||
|
||||
PhysicalSkyMaterial();
|
||||
~PhysicalSkyMaterial();
|
||||
};
|
||||
|
||||
#endif /* !SKY_MATERIAL_H */
|
|
@ -56,7 +56,7 @@ public:
|
|||
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;
|
||||
virtual void sky_set_material(RID p_sky, RID p_material) = 0;
|
||||
|
||||
/* ENVIRONMENT API */
|
||||
|
||||
|
|
|
@ -248,57 +248,6 @@ void RasterizerEffectsRD::gaussian_glow(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, float p_size) {
|
||||
|
||||
zeromem(&roughness.push_constant, sizeof(CubemapRoughnessPushConstant));
|
||||
|
||||
roughness.push_constant.face_id = p_face_id > 9 ? 0 : 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;
|
||||
roughness.push_constant.face_size = p_size;
|
||||
|
||||
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
|
||||
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, roughness.pipelines[p_source_is_panorama ? CUBEMAP_ROUGHNESS_SOURCE_PANORAMA : CUBEMAP_ROUGHNESS_SOURCE_CUBEMAP]);
|
||||
|
||||
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0);
|
||||
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_framebuffer), 1);
|
||||
|
||||
RD::get_singleton()->compute_list_set_push_constant(compute_list, &roughness.push_constant, sizeof(CubemapRoughnessPushConstant));
|
||||
|
||||
int x_groups = (p_size - 1) / 8 + 1;
|
||||
int y_groups = (p_size - 1) / 8 + 1;
|
||||
|
||||
RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, p_face_id > 9 ? 6 : 1);
|
||||
|
||||
RD::get_singleton()->compute_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));
|
||||
|
@ -756,12 +705,38 @@ void RasterizerEffectsRD::roughness_limit(RID p_source_normal, RID p_roughness,
|
|||
RD::get_singleton()->compute_list_end();
|
||||
}
|
||||
|
||||
void RasterizerEffectsRD::cubemap_downsample(RID p_source_cubemap, bool p_source_is_panorama, RID p_dest_cubemap, const Size2i &p_size) {
|
||||
void RasterizerEffectsRD::cubemap_roughness(RID p_source_rd_texture, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size) {
|
||||
|
||||
zeromem(&roughness.push_constant, sizeof(CubemapRoughnessPushConstant));
|
||||
|
||||
roughness.push_constant.face_id = p_face_id > 9 ? 0 : 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;
|
||||
roughness.push_constant.face_size = p_size;
|
||||
|
||||
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
|
||||
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, roughness.pipeline);
|
||||
|
||||
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0);
|
||||
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_framebuffer), 1);
|
||||
|
||||
RD::get_singleton()->compute_list_set_push_constant(compute_list, &roughness.push_constant, sizeof(CubemapRoughnessPushConstant));
|
||||
|
||||
int x_groups = (p_size - 1) / 8 + 1;
|
||||
int y_groups = (p_size - 1) / 8 + 1;
|
||||
|
||||
RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, p_face_id > 9 ? 6 : 1);
|
||||
|
||||
RD::get_singleton()->compute_list_end();
|
||||
}
|
||||
|
||||
void RasterizerEffectsRD::cubemap_downsample(RID p_source_cubemap, RID p_dest_cubemap, const Size2i &p_size) {
|
||||
|
||||
cubemap_downsampler.push_constant.face_size = p_size.x;
|
||||
|
||||
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
|
||||
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, cubemap_downsampler.pipelines[p_source_is_panorama ? CUBEMAP_DOWNSAMPLER_SOURCE_PANORAMA : CUBEMAP_DOWNSAMPLER_SOURCE_CUBEMAP]);
|
||||
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, cubemap_downsampler.pipeline);
|
||||
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_cubemap), 0);
|
||||
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_cubemap), 1);
|
||||
|
||||
|
@ -805,6 +780,41 @@ void RasterizerEffectsRD::cubemap_filter(RID p_source_cubemap, Vector<RID> p_des
|
|||
RD::get_singleton()->compute_list_end();
|
||||
}
|
||||
|
||||
void RasterizerEffectsRD::render_sky(RD::DrawListID p_list, float p_time, RID p_fb, RID p_samplers, RID p_lights, RenderPipelineVertexFormatCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, const CameraMatrix &p_camera, const Basis &p_orientation, float p_multiplier, const Vector3 &p_position) {
|
||||
|
||||
SkyPushConstant sky_push_constant;
|
||||
|
||||
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.position[0] = p_position.x;
|
||||
sky_push_constant.position[1] = p_position.y;
|
||||
sky_push_constant.position[2] = p_position.z;
|
||||
sky_push_constant.multiplier = p_multiplier;
|
||||
sky_push_constant.time = p_time;
|
||||
store_transform_3x3(p_orientation, sky_push_constant.orientation);
|
||||
|
||||
RenderingDevice::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(p_fb);
|
||||
|
||||
RD::DrawListID draw_list = p_list;
|
||||
|
||||
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, p_pipeline->get_render_pipeline(RD::INVALID_ID, fb_format));
|
||||
|
||||
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_samplers, 0);
|
||||
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_uniform_set, 1);
|
||||
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_texture_set, 2);
|
||||
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_lights, 3);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
RasterizerEffectsRD::RasterizerEffectsRD() {
|
||||
|
||||
{
|
||||
|
@ -838,31 +848,12 @@ RasterizerEffectsRD::RasterizerEffectsRD() {
|
|||
{
|
||||
// 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");
|
||||
cubemap_roughness_modes.push_back("");
|
||||
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] = RD::get_singleton()->compute_pipeline_create(roughness.shader.version_get_shader(roughness.shader_version, i));
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// 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);
|
||||
roughness.pipeline = RD::get_singleton()->compute_pipeline_create(roughness.shader.version_get_shader(roughness.shader_version, 0));
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -999,15 +990,12 @@ RasterizerEffectsRD::RasterizerEffectsRD() {
|
|||
{
|
||||
//Initialize cubemap downsampler
|
||||
Vector<String> cubemap_downsampler_modes;
|
||||
cubemap_downsampler_modes.push_back("\n#define MODE_SOURCE_PANORAMA\n");
|
||||
cubemap_downsampler_modes.push_back("\n#define MODE_SOURCE_CUBEMAP\n");
|
||||
cubemap_downsampler_modes.push_back("");
|
||||
cubemap_downsampler.shader.initialize(cubemap_downsampler_modes);
|
||||
|
||||
cubemap_downsampler.shader_version = cubemap_downsampler.shader.version_create();
|
||||
|
||||
for (int i = 0; i < CUBEMAP_DOWNSAMPLER_SOURCE_MAX; i++) {
|
||||
cubemap_downsampler.pipelines[i] = RD::get_singleton()->compute_pipeline_create(cubemap_downsampler.shader.version_get_shader(cubemap_downsampler.shader_version, i));
|
||||
}
|
||||
cubemap_downsampler.pipeline = RD::get_singleton()->compute_pipeline_create(cubemap_downsampler.shader.version_get_shader(cubemap_downsampler.shader_version, 0));
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -1091,7 +1079,6 @@ RasterizerEffectsRD::~RasterizerEffectsRD() {
|
|||
RD::get_singleton()->free(filter.coefficient_buffer);
|
||||
blur.shader.version_free(blur.shader_version);
|
||||
roughness.shader.version_free(roughness.shader_version);
|
||||
sky.shader.version_free(sky.shader_version);
|
||||
tonemap.shader.version_free(tonemap.shader_version);
|
||||
luminance_reduce.shader.version_free(luminance_reduce.shader_version);
|
||||
copy.shader.version_free(copy.shader_version);
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#define RASTERIZER_EFFECTS_RD_H
|
||||
|
||||
#include "core/math/camera_matrix.h"
|
||||
#include "render_pipeline_vertex_format_cache_rd.h"
|
||||
#include "servers/visual/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h"
|
||||
#include "servers/visual/rasterizer_rd/shaders/blur.glsl.gen.h"
|
||||
#include "servers/visual/rasterizer_rd/shaders/bokeh_dof.glsl.gen.h"
|
||||
#include "servers/visual/rasterizer_rd/shaders/copy.glsl.gen.h"
|
||||
|
@ -41,7 +41,6 @@
|
|||
#include "servers/visual/rasterizer_rd/shaders/cubemap_roughness.glsl.gen.h"
|
||||
#include "servers/visual/rasterizer_rd/shaders/luminance_reduce.glsl.gen.h"
|
||||
#include "servers/visual/rasterizer_rd/shaders/roughness_limiter.glsl.gen.h"
|
||||
#include "servers/visual/rasterizer_rd/shaders/sky.glsl.gen.h"
|
||||
#include "servers/visual/rasterizer_rd/shaders/ssao.glsl.gen.h"
|
||||
#include "servers/visual/rasterizer_rd/shaders/ssao_blur.glsl.gen.h"
|
||||
#include "servers/visual/rasterizer_rd/shaders/ssao_minify.glsl.gen.h"
|
||||
|
@ -116,12 +115,6 @@ 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;
|
||||
|
@ -136,26 +129,9 @@ class RasterizerEffectsRD {
|
|||
CubemapRoughnessPushConstant push_constant;
|
||||
CubemapRoughnessShaderRD shader;
|
||||
RID shader_version;
|
||||
RID pipelines[CUBEMAP_ROUGHNESS_SOURCE_MAX];
|
||||
RID pipeline;
|
||||
} 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;
|
||||
|
||||
enum TonemapMode {
|
||||
TONEMAP_MODE_NORMAL,
|
||||
TONEMAP_MODE_BICUBIC_GLOW_FILTER,
|
||||
|
@ -359,12 +335,6 @@ class RasterizerEffectsRD {
|
|||
|
||||
} roughness_limiter;
|
||||
|
||||
enum CubemapDownsamplerSource {
|
||||
CUBEMAP_DOWNSAMPLER_SOURCE_PANORAMA,
|
||||
CUBEMAP_DOWNSAMPLER_SOURCE_CUBEMAP,
|
||||
CUBEMAP_DOWNSAMPLER_SOURCE_MAX
|
||||
};
|
||||
|
||||
struct CubemapDownsamplerPushConstant {
|
||||
uint32_t face_size;
|
||||
float pad[3];
|
||||
|
@ -375,7 +345,7 @@ class RasterizerEffectsRD {
|
|||
CubemapDownsamplerPushConstant push_constant;
|
||||
CubemapDownsamplerShaderRD shader;
|
||||
RID shader_version;
|
||||
RID pipelines[CUBEMAP_DOWNSAMPLER_SOURCE_MAX];
|
||||
RID pipeline;
|
||||
|
||||
} cubemap_downsampler;
|
||||
|
||||
|
@ -399,6 +369,15 @@ class RasterizerEffectsRD {
|
|||
|
||||
} filter;
|
||||
|
||||
struct SkyPushConstant {
|
||||
float orientation[12];
|
||||
float proj[4];
|
||||
float position[3];
|
||||
float multiplier;
|
||||
float time;
|
||||
float pad[3];
|
||||
};
|
||||
|
||||
RID default_sampler;
|
||||
RID default_mipmap_sampler;
|
||||
RID index_buffer;
|
||||
|
@ -421,8 +400,7 @@ public:
|
|||
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 gaussian_glow(RID p_source_rd_texture, RID p_framebuffer_half, RID p_rd_texture_half, RID p_dest_framebuffer, const Vector2 &p_pixel_size, float p_strength = 1.0, bool p_first_pass = false, float p_luminance_cap = 16.0, float p_exposure = 1.0, float p_bloom = 0.0, float p_hdr_bleed_treshold = 1.0, float p_hdr_bleed_scale = 1.0, RID p_auto_exposure = RID(), float p_auto_exposure_grey = 1.0);
|
||||
|
||||
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, float p_size);
|
||||
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 cubemap_roughness(RID p_source_rd_texture, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size);
|
||||
void make_mipmap(RID p_source_rd_texture, RID p_framebuffer_half, const Vector2 &p_pixel_size);
|
||||
void copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_rect, float p_z_near, float p_z_far, float p_bias, bool p_dp_flip);
|
||||
void luminance_reduction(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set = false);
|
||||
|
@ -468,11 +446,12 @@ public:
|
|||
void generate_ssao(RID p_depth_buffer, RID p_normal_buffer, const Size2i &p_depth_buffer_size, RID p_depth_mipmaps_texture, const Vector<RID> &depth_mipmaps, RID p_ao1, bool p_half_size, RID p_ao2, RID p_upscale_buffer, float p_intensity, float p_radius, float p_bias, const CameraMatrix &p_projection, VS::EnvironmentSSAOQuality p_quality, VS::EnvironmentSSAOBlur p_blur, float p_edge_sharpness);
|
||||
|
||||
void roughness_limit(RID p_source_normal, RID p_roughness, const Size2i &p_size, float p_curve);
|
||||
void cubemap_downsample(RID p_source_cubemap, bool p_source_is_panorama, RID p_dest_cubemap, const Size2i &p_size);
|
||||
void cubemap_downsample(RID p_source_cubemap, RID p_dest_cubemap, const Size2i &p_size);
|
||||
void cubemap_filter(RID p_source_cubemap, Vector<RID> p_dest_cubemap, bool p_use_array);
|
||||
void render_sky(RD::DrawListID p_list, float p_time, RID p_fb, RID p_samplers, RID p_lights, RenderPipelineVertexFormatCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, const CameraMatrix &p_camera, const Basis &p_orientation, float p_multiplier, const Vector3 &p_position);
|
||||
|
||||
RasterizerEffectsRD();
|
||||
~RasterizerEffectsRD();
|
||||
};
|
||||
|
||||
#endif // EFFECTS_RD_H
|
||||
#endif // !RASTERIZER_EFFECTS_RD_H
|
||||
|
|
|
@ -76,6 +76,8 @@ static _FORCE_INLINE_ void store_camera(const CameraMatrix &p_mtx, float *p_arra
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* SCENE SHADER */
|
||||
void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) {
|
||||
//compile
|
||||
|
||||
|
@ -345,6 +347,7 @@ void RasterizerSceneHighEndRD::ShaderData::set_default_texture_param(const Strin
|
|||
default_texture_params[p_name] = p_texture;
|
||||
}
|
||||
}
|
||||
|
||||
void RasterizerSceneHighEndRD::ShaderData::get_param_list(List<PropertyInfo> *p_param_list) const {
|
||||
|
||||
Map<int, StringName> order;
|
||||
|
@ -377,6 +380,7 @@ bool RasterizerSceneHighEndRD::ShaderData::is_param_texture(const StringName &p_
|
|||
bool RasterizerSceneHighEndRD::ShaderData::is_animated() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RasterizerSceneHighEndRD::ShaderData::casts_shadows() const {
|
||||
return false;
|
||||
}
|
||||
|
@ -499,6 +503,7 @@ void RasterizerSceneHighEndRD::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), MATERIAL_UNIFORM_SET);
|
||||
}
|
||||
|
||||
RasterizerSceneHighEndRD::MaterialData::~MaterialData() {
|
||||
if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
|
||||
RD::get_singleton()->free(uniform_set);
|
||||
|
@ -1290,38 +1295,6 @@ void RasterizerSceneHighEndRD::_fill_render_list(InstanceBase **p_cull_result, i
|
|||
}
|
||||
}
|
||||
|
||||
void RasterizerSceneHighEndRD::_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 RasterizerSceneHighEndRD::_setup_reflections(RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, const Transform &p_camera_inverse_transform, RID p_environment) {
|
||||
|
||||
for (int i = 0; i < p_reflection_probe_cull_count; i++) {
|
||||
|
@ -1460,6 +1433,7 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig
|
|||
|
||||
uint32_t light_count = 0;
|
||||
scene_state.ubo.directional_light_count = 0;
|
||||
sky_scene_state.directional_light_count = 0;
|
||||
|
||||
for (int i = 0; i < p_light_cull_count; i++) {
|
||||
|
||||
|
@ -1535,6 +1509,27 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig
|
|||
light_data.fade_to = -light_data.shadow_split_offsets[3];
|
||||
}
|
||||
|
||||
// Copy to SkyDirectionalLightData
|
||||
if (sky_scene_state.directional_light_count < sky_scene_state.max_directional_lights) {
|
||||
|
||||
SkyDirectionalLightData &sky_light_data = sky_scene_state.directional_lights[sky_scene_state.directional_light_count];
|
||||
|
||||
Vector3 world_direction = light_transform.basis.xform(Vector3(0, 0, 1)).normalized();
|
||||
|
||||
sky_light_data.direction[0] = world_direction.x;
|
||||
sky_light_data.direction[1] = world_direction.y;
|
||||
sky_light_data.direction[2] = -world_direction.z;
|
||||
|
||||
sky_light_data.energy = light_data.energy / Math_PI;
|
||||
|
||||
sky_light_data.color[0] = light_data.color[0];
|
||||
sky_light_data.color[1] = light_data.color[1];
|
||||
sky_light_data.color[2] = light_data.color[2];
|
||||
|
||||
sky_light_data.enabled = true;
|
||||
sky_scene_state.directional_light_count++;
|
||||
}
|
||||
|
||||
scene_state.ubo.directional_light_count++;
|
||||
} break;
|
||||
case VS::LIGHT_SPOT:
|
||||
|
@ -1705,6 +1700,7 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
|
|||
scene_state.ubo.viewport_size[1] = vp_he.y;
|
||||
|
||||
Size2 screen_pixel_size;
|
||||
Size2i screen_size;
|
||||
RID opaque_framebuffer;
|
||||
RID depth_framebuffer;
|
||||
RID alpha_framebuffer;
|
||||
|
@ -1715,6 +1711,8 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
|
|||
if (render_buffer) {
|
||||
screen_pixel_size.width = 1.0 / render_buffer->width;
|
||||
screen_pixel_size.height = 1.0 / render_buffer->height;
|
||||
screen_size.x = render_buffer->width;
|
||||
screen_size.y = render_buffer->height;
|
||||
|
||||
opaque_framebuffer = render_buffer->color_fb;
|
||||
|
||||
|
@ -1755,6 +1753,8 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
|
|||
uint32_t resolution = reflection_probe_instance_get_resolution(p_reflection_probe);
|
||||
screen_pixel_size.width = 1.0 / resolution;
|
||||
screen_pixel_size.height = 1.0 / resolution;
|
||||
screen_size.x = resolution;
|
||||
screen_size.y = resolution;
|
||||
|
||||
opaque_framebuffer = reflection_probe_instance_get_framebuffer(p_reflection_probe, p_reflection_probe_pass);
|
||||
depth_framebuffer = reflection_probe_instance_get_depth_framebuffer(p_reflection_probe, p_reflection_probe_pass);
|
||||
|
@ -1809,7 +1809,19 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
|
|||
case VS::ENV_BG_SKY: {
|
||||
RID sky = environment_get_sky(p_environment);
|
||||
if (sky.is_valid()) {
|
||||
|
||||
RENDER_TIMESTAMP("Setup Sky");
|
||||
CameraMatrix projection = p_cam_projection;
|
||||
if (p_reflection_probe.is_valid()) {
|
||||
CameraMatrix correction;
|
||||
correction.set_depth_correction(true);
|
||||
projection = correction * p_cam_projection;
|
||||
}
|
||||
|
||||
_setup_sky(p_environment, p_cam_transform.origin, screen_size);
|
||||
_update_sky(p_environment, projection, p_cam_transform);
|
||||
radiance_uniform_set = sky_get_radiance_uniform_set_rd(sky, default_shader_rd, RADIANCE_UNIFORM_SET);
|
||||
|
||||
draw_sky = true;
|
||||
}
|
||||
} break;
|
||||
|
@ -1902,9 +1914,7 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
|
|||
projection = correction * p_cam_projection;
|
||||
}
|
||||
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(opaque_framebuffer, RD::INITIAL_ACTION_CONTINUE, can_continue ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, can_continue ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ);
|
||||
_draw_sky(draw_list, RD::get_singleton()->framebuffer_get_format(opaque_framebuffer), p_environment, projection, p_cam_transform, 1.0);
|
||||
RD::get_singleton()->draw_list_end();
|
||||
_draw_sky(can_continue, opaque_framebuffer, p_environment, projection, p_cam_transform);
|
||||
|
||||
if (using_separate_specular && !can_continue) {
|
||||
//can't continue, so close the buffers
|
||||
|
@ -2371,7 +2381,7 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag
|
|||
singleton = this;
|
||||
storage = p_storage;
|
||||
|
||||
/* SHADER */
|
||||
/* SCENE SHADER */
|
||||
|
||||
{
|
||||
String defines;
|
||||
|
|
|
@ -48,7 +48,7 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD {
|
|||
MATERIAL_UNIFORM_SET = 5
|
||||
};
|
||||
|
||||
/* Shader */
|
||||
/* Scene Shader */
|
||||
|
||||
enum ShaderVersion {
|
||||
SHADER_VERSION_DEPTH_PASS,
|
||||
|
@ -569,8 +569,6 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD {
|
|||
|
||||
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(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color);
|
||||
virtual void _render_shadow(RID p_framebuffer, InstanceBase **p_cull_result, int p_cull_count, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -36,6 +36,7 @@
|
|||
#include "servers/visual/rasterizer_rd/rasterizer_storage_rd.h"
|
||||
#include "servers/visual/rasterizer_rd/shaders/giprobe.glsl.gen.h"
|
||||
#include "servers/visual/rasterizer_rd/shaders/giprobe_debug.glsl.gen.h"
|
||||
#include "servers/visual/rasterizer_rd/shaders/sky.glsl.gen.h"
|
||||
#include "servers/visual/rendering_device.h"
|
||||
|
||||
class RasterizerSceneRD : public RasterizerScene {
|
||||
|
@ -47,6 +48,29 @@ public:
|
|||
};
|
||||
|
||||
protected:
|
||||
double time;
|
||||
|
||||
// Skys need less info from Directional Lights than the normal shaders
|
||||
struct SkyDirectionalLightData {
|
||||
|
||||
float direction[3];
|
||||
float energy;
|
||||
float color[3];
|
||||
uint32_t enabled;
|
||||
};
|
||||
|
||||
struct SkySceneState {
|
||||
|
||||
SkyDirectionalLightData *directional_lights;
|
||||
SkyDirectionalLightData *last_frame_directional_lights;
|
||||
uint32_t max_directional_lights;
|
||||
uint32_t directional_light_count;
|
||||
uint32_t last_frame_directional_light_count;
|
||||
RID directional_light_buffer;
|
||||
RID sampler_uniform_set;
|
||||
RID light_uniform_set;
|
||||
} sky_scene_state;
|
||||
|
||||
struct RenderBufferData {
|
||||
|
||||
virtual void configure(RID p_color_buffer, RID p_depth_buffer, int p_width, int p_height, VS::ViewportMSAA p_msaa) = 0;
|
||||
|
@ -69,9 +93,14 @@ protected:
|
|||
|
||||
void _process_ssao(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const CameraMatrix &p_projection);
|
||||
|
||||
void _setup_sky(RID p_environment, const Vector3 &p_position, const Size2i p_screen_size);
|
||||
void _update_sky(RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform);
|
||||
void _draw_sky(bool p_can_continue, RID p_fb, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform);
|
||||
|
||||
private:
|
||||
VS::ViewportDebugDraw debug_draw = VS::VIEWPORT_DEBUG_DRAW_DISABLED;
|
||||
double time_step = 0;
|
||||
static RasterizerSceneRD *singleton;
|
||||
|
||||
int roughness_layers;
|
||||
|
||||
|
@ -102,31 +131,160 @@ private:
|
|||
DownsampleLayer downsampled_layer;
|
||||
RID coefficient_buffer;
|
||||
|
||||
bool dirty = true;
|
||||
|
||||
Vector<Layer> layers;
|
||||
};
|
||||
|
||||
void _clear_reflection_data(ReflectionData &rd);
|
||||
void _update_reflection_data(ReflectionData &rd, int p_size, int p_mipmaps, bool p_use_array, RID p_base_cube, int p_base_layer, bool p_low_quality);
|
||||
void _create_reflection_from_panorama(ReflectionData &rd, RID p_panorama, bool p_quality);
|
||||
void _create_reflection_from_base_mipmap(ReflectionData &rd, bool p_use_arrays, bool p_quality, int p_cube_side, int p_base_layer);
|
||||
void _update_reflection_mipmaps(ReflectionData &rd, bool p_quality);
|
||||
void _create_reflection_fast_filter(ReflectionData &rd, bool p_use_arrays);
|
||||
void _create_reflection_importance_sample(ReflectionData &rd, bool p_use_arrays, int p_cube_side, int p_base_layer);
|
||||
void _update_reflection_mipmaps(ReflectionData &rd);
|
||||
|
||||
/* Sky shader */
|
||||
|
||||
enum SkyVersion {
|
||||
SKY_VERSION_BACKGROUND,
|
||||
SKY_VERSION_HALF_RES,
|
||||
SKY_VERSION_QUARTER_RES,
|
||||
SKY_VERSION_CUBEMAP,
|
||||
SKY_VERSION_MAX
|
||||
};
|
||||
|
||||
struct SkyShader {
|
||||
SkyShaderRD shader;
|
||||
ShaderCompilerRD compiler;
|
||||
|
||||
RID default_shader;
|
||||
RID default_material;
|
||||
RID default_shader_rd;
|
||||
} sky_shader;
|
||||
|
||||
struct SkyShaderData : public RasterizerStorageRD::ShaderData {
|
||||
bool valid;
|
||||
RID version;
|
||||
|
||||
RenderPipelineVertexFormatCacheRD pipelines[SKY_VERSION_MAX];
|
||||
Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
|
||||
Vector<ShaderCompilerRD::GeneratedCode::Texture> texture_uniforms;
|
||||
|
||||
Vector<uint32_t> ubo_offsets;
|
||||
uint32_t ubo_size;
|
||||
|
||||
String path;
|
||||
String code;
|
||||
Map<StringName, RID> default_texture_params;
|
||||
|
||||
bool uses_time;
|
||||
bool uses_position;
|
||||
bool uses_half_res;
|
||||
bool uses_quarter_res;
|
||||
bool uses_light;
|
||||
|
||||
virtual void set_code(const String &p_Code);
|
||||
virtual void set_default_texture_param(const StringName &p_name, RID p_texture);
|
||||
virtual void get_param_list(List<PropertyInfo> *p_param_list) const;
|
||||
virtual bool is_param_texture(const StringName &p_param) const;
|
||||
virtual bool is_animated() const;
|
||||
virtual bool casts_shadows() const;
|
||||
virtual Variant get_default_parameter(const StringName &p_parameter) const;
|
||||
SkyShaderData();
|
||||
virtual ~SkyShaderData();
|
||||
};
|
||||
|
||||
RasterizerStorageRD::ShaderData *_create_sky_shader_func();
|
||||
static RasterizerStorageRD::ShaderData *_create_sky_shader_funcs() {
|
||||
return static_cast<RasterizerSceneRD *>(singleton)->_create_sky_shader_func();
|
||||
};
|
||||
|
||||
struct SkyMaterialData : public RasterizerStorageRD::MaterialData {
|
||||
uint64_t last_frame;
|
||||
SkyShaderData *shader_data;
|
||||
RID uniform_buffer;
|
||||
RID uniform_set;
|
||||
Vector<RID> texture_cache;
|
||||
Vector<uint8_t> ubo_data;
|
||||
bool uniform_set_updated;
|
||||
|
||||
virtual void set_render_priority(int p_priority) {}
|
||||
virtual void set_next_pass(RID p_pass) {}
|
||||
virtual void update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
|
||||
virtual ~SkyMaterialData();
|
||||
};
|
||||
|
||||
RasterizerStorageRD::MaterialData *_create_sky_material_func(SkyShaderData *p_shader);
|
||||
static RasterizerStorageRD::MaterialData *_create_sky_material_funcs(RasterizerStorageRD::ShaderData *p_shader) {
|
||||
return static_cast<RasterizerSceneRD *>(singleton)->_create_sky_material_func(static_cast<SkyShaderData *>(p_shader));
|
||||
};
|
||||
|
||||
enum SkyTextureSetVersion {
|
||||
SKY_TEXTURE_SET_BACKGROUND,
|
||||
SKY_TEXTURE_SET_HALF_RES,
|
||||
SKY_TEXTURE_SET_QUARTER_RES,
|
||||
SKY_TEXTURE_SET_CUBEMAP0,
|
||||
SKY_TEXTURE_SET_CUBEMAP1,
|
||||
SKY_TEXTURE_SET_CUBEMAP2,
|
||||
SKY_TEXTURE_SET_CUBEMAP3,
|
||||
SKY_TEXTURE_SET_CUBEMAP4,
|
||||
SKY_TEXTURE_SET_CUBEMAP5,
|
||||
SKY_TEXTURE_SET_CUBEMAP_HALF_RES0,
|
||||
SKY_TEXTURE_SET_CUBEMAP_HALF_RES1,
|
||||
SKY_TEXTURE_SET_CUBEMAP_HALF_RES2,
|
||||
SKY_TEXTURE_SET_CUBEMAP_HALF_RES3,
|
||||
SKY_TEXTURE_SET_CUBEMAP_HALF_RES4,
|
||||
SKY_TEXTURE_SET_CUBEMAP_HALF_RES5,
|
||||
SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES0,
|
||||
SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES1,
|
||||
SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES2,
|
||||
SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES3,
|
||||
SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES4,
|
||||
SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES5,
|
||||
SKY_TEXTURE_SET_MAX
|
||||
};
|
||||
|
||||
enum SkySet {
|
||||
SKY_SET_SAMPLERS,
|
||||
SKY_SET_MATERIAL,
|
||||
SKY_SET_TEXTURES,
|
||||
SKY_SET_LIGHTS,
|
||||
SKY_SET_MAX
|
||||
};
|
||||
|
||||
/* SKY */
|
||||
struct Sky {
|
||||
RID radiance;
|
||||
RID half_res_pass;
|
||||
RID half_res_framebuffer;
|
||||
RID quarter_res_pass;
|
||||
RID quarter_res_framebuffer;
|
||||
Size2i screen_size;
|
||||
|
||||
RID texture_uniform_sets[SKY_TEXTURE_SET_MAX];
|
||||
RID uniform_set;
|
||||
int radiance_size = 128;
|
||||
|
||||
RID material;
|
||||
RID uniform_buffer;
|
||||
|
||||
int radiance_size = 256;
|
||||
|
||||
VS::SkyMode mode = VS::SKY_MODE_QUALITY;
|
||||
RID panorama;
|
||||
|
||||
ReflectionData reflection;
|
||||
bool dirty = false;
|
||||
Sky *dirty_list = nullptr;
|
||||
|
||||
//State to track when radiance cubemap needs updating
|
||||
SkyMaterialData *prev_material;
|
||||
Vector3 prev_position;
|
||||
float prev_time;
|
||||
};
|
||||
|
||||
Sky *dirty_sky_list = nullptr;
|
||||
|
||||
void _sky_invalidate(Sky *p_sky);
|
||||
void _update_dirty_skys();
|
||||
RID _get_sky_textures(Sky *p_sky, SkyTextureSetVersion p_version);
|
||||
|
||||
uint32_t sky_ggx_samples_quality;
|
||||
bool sky_use_cubemap_array;
|
||||
|
@ -647,11 +805,11 @@ public:
|
|||
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);
|
||||
void sky_set_material(RID p_sky, RID p_material);
|
||||
|
||||
RID sky_get_panorama_texture_rd(RID p_sky) const;
|
||||
RID sky_get_radiance_texture_rd(RID p_sky) const;
|
||||
RID sky_get_radiance_uniform_set_rd(RID p_sky, RID p_shader, int p_set) const;
|
||||
RID sky_get_material(RID p_sky) const;
|
||||
|
||||
/* ENVIRONMENT API */
|
||||
|
||||
|
|
|
@ -881,6 +881,8 @@ void RasterizerStorageRD::shader_set_code(RID p_shader, const String &p_code) {
|
|||
new_type = SHADER_TYPE_PARTICLES;
|
||||
else if (mode_string == "spatial")
|
||||
new_type = SHADER_TYPE_3D;
|
||||
else if (mode_string == "sky")
|
||||
new_type = SHADER_TYPE_SKY;
|
||||
else
|
||||
new_type = SHADER_TYPE_MAX;
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ public:
|
|||
SHADER_TYPE_2D,
|
||||
SHADER_TYPE_3D,
|
||||
SHADER_TYPE_PARTICLES,
|
||||
SHADER_TYPE_SKY,
|
||||
SHADER_TYPE_MAX
|
||||
};
|
||||
|
||||
|
|
|
@ -30,13 +30,7 @@ VERSION_DEFINES
|
|||
layout(local_size_x = BLOCK_SIZE, local_size_y = BLOCK_SIZE, local_size_z = 1) in;
|
||||
/* 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_cubemap;
|
||||
#endif
|
||||
|
||||
layout(rgba16f, set = 1, binding = 0) uniform restrict writeonly imageCube dest_cubemap;
|
||||
|
||||
|
@ -83,32 +77,6 @@ float calcWeight(float u, float v) {
|
|||
return val * sqrt(val);
|
||||
}
|
||||
|
||||
#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
|
||||
|
||||
vec4 get_texture(vec3 p_dir) {
|
||||
#ifdef MODE_SOURCE_PANORAMA
|
||||
return texturePanorama(normalize(p_dir), source_panorama);
|
||||
#else
|
||||
return textureLod(source_cubemap, normalize(p_dir), 0.0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void main() {
|
||||
uvec3 id = gl_GlobalInvocationID;
|
||||
uint face_size = params.face_size;
|
||||
|
@ -138,81 +106,81 @@ void main() {
|
|||
switch (id.z) {
|
||||
case 0:
|
||||
get_dir_0(dir, u0, v0);
|
||||
color = get_texture(dir) * weights[0];
|
||||
color = textureLod(source_cubemap, normalize(dir), 0.0) * weights[0];
|
||||
|
||||
get_dir_0(dir, u1, v0);
|
||||
color += get_texture(dir) * weights[1];
|
||||
color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[1];
|
||||
|
||||
get_dir_0(dir, u0, v1);
|
||||
color += get_texture(dir) * weights[2];
|
||||
color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[2];
|
||||
|
||||
get_dir_0(dir, u1, v1);
|
||||
color += get_texture(dir) * weights[3];
|
||||
color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[3];
|
||||
break;
|
||||
case 1:
|
||||
get_dir_1(dir, u0, v0);
|
||||
color = get_texture(dir) * weights[0];
|
||||
color = textureLod(source_cubemap, normalize(dir), 0.0) * weights[0];
|
||||
|
||||
get_dir_1(dir, u1, v0);
|
||||
color += get_texture(dir) * weights[1];
|
||||
color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[1];
|
||||
|
||||
get_dir_1(dir, u0, v1);
|
||||
color += get_texture(dir) * weights[2];
|
||||
color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[2];
|
||||
|
||||
get_dir_1(dir, u1, v1);
|
||||
color += get_texture(dir) * weights[3];
|
||||
color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[3];
|
||||
break;
|
||||
case 2:
|
||||
get_dir_2(dir, u0, v0);
|
||||
color = get_texture(dir) * weights[0];
|
||||
color = textureLod(source_cubemap, normalize(dir), 0.0) * weights[0];
|
||||
|
||||
get_dir_2(dir, u1, v0);
|
||||
color += get_texture(dir) * weights[1];
|
||||
color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[1];
|
||||
|
||||
get_dir_2(dir, u0, v1);
|
||||
color += get_texture(dir) * weights[2];
|
||||
color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[2];
|
||||
|
||||
get_dir_2(dir, u1, v1);
|
||||
color += get_texture(dir) * weights[3];
|
||||
color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[3];
|
||||
break;
|
||||
case 3:
|
||||
get_dir_3(dir, u0, v0);
|
||||
color = get_texture(dir) * weights[0];
|
||||
color = textureLod(source_cubemap, normalize(dir), 0.0) * weights[0];
|
||||
|
||||
get_dir_3(dir, u1, v0);
|
||||
color += get_texture(dir) * weights[1];
|
||||
color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[1];
|
||||
|
||||
get_dir_3(dir, u0, v1);
|
||||
color += get_texture(dir) * weights[2];
|
||||
color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[2];
|
||||
|
||||
get_dir_3(dir, u1, v1);
|
||||
color += get_texture(dir) * weights[3];
|
||||
color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[3];
|
||||
break;
|
||||
case 4:
|
||||
get_dir_4(dir, u0, v0);
|
||||
color = get_texture(dir) * weights[0];
|
||||
color = textureLod(source_cubemap, normalize(dir), 0.0) * weights[0];
|
||||
|
||||
get_dir_4(dir, u1, v0);
|
||||
color += get_texture(dir) * weights[1];
|
||||
color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[1];
|
||||
|
||||
get_dir_4(dir, u0, v1);
|
||||
color += get_texture(dir) * weights[2];
|
||||
color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[2];
|
||||
|
||||
get_dir_4(dir, u1, v1);
|
||||
color += get_texture(dir) * weights[3];
|
||||
color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[3];
|
||||
break;
|
||||
default:
|
||||
get_dir_5(dir, u0, v0);
|
||||
color = get_texture(dir) * weights[0];
|
||||
color = textureLod(source_cubemap, normalize(dir), 0.0) * weights[0];
|
||||
|
||||
get_dir_5(dir, u1, v0);
|
||||
color += get_texture(dir) * weights[1];
|
||||
color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[1];
|
||||
|
||||
get_dir_5(dir, u0, v1);
|
||||
color += get_texture(dir) * weights[2];
|
||||
color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[2];
|
||||
|
||||
get_dir_5(dir, u1, v1);
|
||||
color += get_texture(dir) * weights[3];
|
||||
color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[3];
|
||||
break;
|
||||
}
|
||||
imageStore(dest_cubemap, ivec3(id), color);
|
||||
|
|
|
@ -262,28 +262,66 @@ void main() {
|
|||
// write color
|
||||
color.xyz = max(vec3(0.0), color.xyz);
|
||||
color.w = 1.0;
|
||||
#ifdef USE_TEXTURE_ARRAY
|
||||
id.xy *= uvec2(2, 2);
|
||||
#endif
|
||||
|
||||
switch (level) {
|
||||
case 0:
|
||||
imageStore(dest_cubemap0, ivec3(id), color);
|
||||
#ifdef USE_TEXTURE_ARRAY
|
||||
imageStore(dest_cubemap0, ivec3(id) + ivec3(1.0, 0.0, 0.0), color);
|
||||
imageStore(dest_cubemap0, ivec3(id) + ivec3(0.0, 1.0, 0.0), color);
|
||||
imageStore(dest_cubemap0, ivec3(id) + ivec3(1.0, 1.0, 0.0), color);
|
||||
#endif
|
||||
break;
|
||||
case 1:
|
||||
imageStore(dest_cubemap1, ivec3(id), color);
|
||||
#ifdef USE_TEXTURE_ARRAY
|
||||
imageStore(dest_cubemap1, ivec3(id) + ivec3(1.0, 0.0, 0.0), color);
|
||||
imageStore(dest_cubemap1, ivec3(id) + ivec3(0.0, 1.0, 0.0), color);
|
||||
imageStore(dest_cubemap1, ivec3(id) + ivec3(1.0, 1.0, 0.0), color);
|
||||
#endif
|
||||
break;
|
||||
case 2:
|
||||
imageStore(dest_cubemap2, ivec3(id), color);
|
||||
#ifdef USE_TEXTURE_ARRAY
|
||||
imageStore(dest_cubemap2, ivec3(id) + ivec3(1.0, 0.0, 0.0), color);
|
||||
imageStore(dest_cubemap2, ivec3(id) + ivec3(0.0, 1.0, 0.0), color);
|
||||
imageStore(dest_cubemap2, ivec3(id) + ivec3(1.0, 1.0, 0.0), color);
|
||||
#endif
|
||||
break;
|
||||
case 3:
|
||||
imageStore(dest_cubemap3, ivec3(id), color);
|
||||
#ifdef USE_TEXTURE_ARRAY
|
||||
imageStore(dest_cubemap3, ivec3(id) + ivec3(1.0, 0.0, 0.0), color);
|
||||
imageStore(dest_cubemap3, ivec3(id) + ivec3(0.0, 1.0, 0.0), color);
|
||||
imageStore(dest_cubemap3, ivec3(id) + ivec3(1.0, 1.0, 0.0), color);
|
||||
#endif
|
||||
break;
|
||||
case 4:
|
||||
imageStore(dest_cubemap4, ivec3(id), color);
|
||||
#ifdef USE_TEXTURE_ARRAY
|
||||
imageStore(dest_cubemap4, ivec3(id) + ivec3(1.0, 0.0, 0.0), color);
|
||||
imageStore(dest_cubemap4, ivec3(id) + ivec3(0.0, 1.0, 0.0), color);
|
||||
imageStore(dest_cubemap4, ivec3(id) + ivec3(1.0, 1.0, 0.0), color);
|
||||
#endif
|
||||
break;
|
||||
case 5:
|
||||
imageStore(dest_cubemap5, ivec3(id), color);
|
||||
#ifdef USE_TEXTURE_ARRAY
|
||||
imageStore(dest_cubemap5, ivec3(id) + ivec3(1.0, 0.0, 0.0), color);
|
||||
imageStore(dest_cubemap5, ivec3(id) + ivec3(0.0, 1.0, 0.0), color);
|
||||
imageStore(dest_cubemap5, ivec3(id) + ivec3(1.0, 1.0, 0.0), color);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
imageStore(dest_cubemap6, ivec3(id), color);
|
||||
#ifdef USE_TEXTURE_ARRAY
|
||||
imageStore(dest_cubemap6, ivec3(id) + ivec3(1.0, 0.0, 0.0), color);
|
||||
imageStore(dest_cubemap6, ivec3(id) + ivec3(0.0, 1.0, 0.0), color);
|
||||
imageStore(dest_cubemap6, ivec3(id) + ivec3(1.0, 1.0, 0.0), color);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,13 +10,7 @@ VERSION_DEFINES
|
|||
layout(local_size_x = GROUP_SIZE, local_size_y = GROUP_SIZE, local_size_z = 1) in;
|
||||
/* 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(rgba16f, set = 1, binding = 0) uniform restrict writeonly imageCube dest_cubemap;
|
||||
|
||||
|
@ -115,24 +109,6 @@ 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() {
|
||||
uvec3 id = gl_GlobalInvocationID;
|
||||
id.z += params.face_id;
|
||||
|
@ -144,15 +120,7 @@ void main() {
|
|||
|
||||
if (params.use_direct_write) {
|
||||
|
||||
#ifdef MODE_SOURCE_PANORAMA
|
||||
imageStore(dest_cubemap, ivec3(id), vec4(texturePanorama(N, source_panorama).rgb, 1.0));
|
||||
#endif
|
||||
|
||||
#ifdef MODE_SOURCE_CUBEMAP
|
||||
imageStore(dest_cubemap, ivec3(id), vec4(texture(source_cube, N).rgb, 1.0));
|
||||
|
||||
#endif
|
||||
|
||||
} else {
|
||||
|
||||
vec4 sum = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
|
@ -167,13 +135,8 @@ void main() {
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,10 +11,8 @@ 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;
|
||||
vec4 position_multiplier;
|
||||
float time;
|
||||
}
|
||||
params;
|
||||
|
||||
|
@ -22,7 +20,7 @@ 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);
|
||||
gl_Position = vec4(uv_interp, 1.0, 1.0);
|
||||
}
|
||||
|
||||
/* clang-format off */
|
||||
|
@ -37,43 +35,91 @@ VERSION_DEFINES
|
|||
layout(location = 0) in vec2 uv_interp;
|
||||
/* clang-format on */
|
||||
|
||||
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;
|
||||
vec4 position_multiplier;
|
||||
float time; //TODO consider adding vec2 screen res, and float radiance size
|
||||
}
|
||||
params;
|
||||
|
||||
vec4 texturePanorama(sampler2D pano, vec3 normal) {
|
||||
layout(set = 0, binding = 0) uniform sampler material_samplers[12];
|
||||
|
||||
vec2 st = vec2(
|
||||
atan(normal.x, normal.z),
|
||||
acos(normal.y));
|
||||
#ifdef USE_MATERIAL_UNIFORMS
|
||||
layout(set = 1, binding = 0, std140) uniform MaterialUniforms{
|
||||
/* clang-format off */
|
||||
|
||||
if (st.x < 0.0)
|
||||
st.x += M_PI * 2.0;
|
||||
MATERIAL_UNIFORMS
|
||||
|
||||
st /= vec2(M_PI * 2.0, M_PI);
|
||||
/* clang-format on */
|
||||
} material;
|
||||
#endif
|
||||
|
||||
return texture(pano, st);
|
||||
layout(set = 2, binding = 0) uniform textureCube radiance;
|
||||
layout(set = 2, binding = 1) uniform texture2D half_res;
|
||||
layout(set = 2, binding = 2) uniform texture2D quarter_res;
|
||||
|
||||
struct DirectionalLightData {
|
||||
vec3 direction;
|
||||
float energy;
|
||||
vec3 color;
|
||||
bool enabled;
|
||||
};
|
||||
|
||||
layout(set = 3, binding = 0, std140) uniform DirectionalLights {
|
||||
DirectionalLightData data[MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS];
|
||||
}
|
||||
directional_lights;
|
||||
|
||||
/* clang-format off */
|
||||
|
||||
FRAGMENT_SHADER_GLOBALS
|
||||
|
||||
/* clang-format on */
|
||||
|
||||
layout(location = 0) out vec4 frag_color;
|
||||
|
||||
void main() {
|
||||
|
||||
vec3 cube_normal;
|
||||
cube_normal.z = -1000000.0;
|
||||
cube_normal.z = -1.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;
|
||||
cube_normal = normalize(cube_normal);
|
||||
|
||||
frag_color.rgb = texturePanorama(source_panorama, normalize(cube_normal.xyz)).rgb;
|
||||
frag_color.a = params.alpha;
|
||||
vec2 uv = uv_interp * 0.5 + 0.5;
|
||||
|
||||
vec2 panorama_coords = vec2(atan(cube_normal.x, cube_normal.z), acos(cube_normal.y));
|
||||
|
||||
if (panorama_coords.x < 0.0) {
|
||||
panorama_coords.x += M_PI * 2.0;
|
||||
}
|
||||
|
||||
panorama_coords /= vec2(M_PI * 2.0, M_PI);
|
||||
|
||||
vec3 color = vec3(0.0, 0.0, 0.0);
|
||||
float alpha = 1.0; // Only available to subpasses
|
||||
|
||||
// unused, just here to make our compiler happy, make sure we don't execute any light code the user adds in..
|
||||
#ifndef REALLYINCLUDETHIS
|
||||
{
|
||||
/* clang-format off */
|
||||
|
||||
LIGHT_SHADER_CODE
|
||||
|
||||
/* clang-format on */
|
||||
}
|
||||
#endif
|
||||
{
|
||||
/* clang-format off */
|
||||
|
||||
FRAGMENT_SHADER_CODE
|
||||
|
||||
/* clang-format on */
|
||||
}
|
||||
|
||||
frag_color.rgb = color * params.position_multiplier.w;
|
||||
frag_color.a = alpha;
|
||||
}
|
||||
|
|
|
@ -285,7 +285,43 @@ ShaderTypes::ShaderTypes() {
|
|||
shader_modes[VS::SHADER_PARTICLES].modes.push_back("disable_velocity");
|
||||
shader_modes[VS::SHADER_PARTICLES].modes.push_back("keep_data");
|
||||
|
||||
/************ SKY **************************/
|
||||
|
||||
shader_modes[VS::SHADER_SKY].functions["global"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT);
|
||||
shader_modes[VS::SHADER_SKY].functions["fragment"].built_ins["COLOR"] = ShaderLanguage::TYPE_VEC3;
|
||||
shader_modes[VS::SHADER_SKY].functions["fragment"].built_ins["ALPHA"] = ShaderLanguage::TYPE_FLOAT;
|
||||
shader_modes[VS::SHADER_SKY].functions["fragment"].built_ins["EYEDIR"] = constt(ShaderLanguage::TYPE_VEC3);
|
||||
shader_modes[VS::SHADER_SKY].functions["fragment"].built_ins["SCREEN_UV"] = constt(ShaderLanguage::TYPE_VEC2);
|
||||
shader_modes[VS::SHADER_SKY].functions["fragment"].built_ins["SKY_COORDS"] = constt(ShaderLanguage::TYPE_VEC2);
|
||||
shader_modes[VS::SHADER_SKY].functions["fragment"].built_ins["POSITION"] = constt(ShaderLanguage::TYPE_VEC3);
|
||||
shader_modes[VS::SHADER_SKY].functions["fragment"].built_ins["HALF_RES_TEXTURE"] = constt(ShaderLanguage::TYPE_SAMPLER2D);
|
||||
shader_modes[VS::SHADER_SKY].functions["fragment"].built_ins["QUARTER_RES_TEXTURE"] = constt(ShaderLanguage::TYPE_SAMPLER2D);
|
||||
shader_modes[VS::SHADER_SKY].functions["fragment"].built_ins["RADIANCE"] = constt(ShaderLanguage::TYPE_SAMPLERCUBE);
|
||||
shader_modes[VS::SHADER_SKY].functions["fragment"].built_ins["AT_HALF_RES_PASS"] = constt(ShaderLanguage::TYPE_BOOL);
|
||||
shader_modes[VS::SHADER_SKY].functions["fragment"].built_ins["AT_QUARTER_RES_PASS"] = constt(ShaderLanguage::TYPE_BOOL);
|
||||
shader_modes[VS::SHADER_SKY].functions["fragment"].built_ins["AT_CUBEMAP_PASS"] = constt(ShaderLanguage::TYPE_BOOL);
|
||||
shader_modes[VS::SHADER_SKY].functions["fragment"].built_ins["LIGHT0_ENABLED"] = constt(ShaderLanguage::TYPE_BOOL);
|
||||
shader_modes[VS::SHADER_SKY].functions["fragment"].built_ins["LIGHT0_DIRECTION"] = constt(ShaderLanguage::TYPE_VEC3);
|
||||
shader_modes[VS::SHADER_SKY].functions["fragment"].built_ins["LIGHT0_ENERGY"] = constt(ShaderLanguage::TYPE_FLOAT);
|
||||
shader_modes[VS::SHADER_SKY].functions["fragment"].built_ins["LIGHT0_COLOR"] = constt(ShaderLanguage::TYPE_VEC3);
|
||||
shader_modes[VS::SHADER_SKY].functions["fragment"].built_ins["LIGHT1_ENABLED"] = constt(ShaderLanguage::TYPE_BOOL);
|
||||
shader_modes[VS::SHADER_SKY].functions["fragment"].built_ins["LIGHT1_DIRECTION"] = constt(ShaderLanguage::TYPE_VEC3);
|
||||
shader_modes[VS::SHADER_SKY].functions["fragment"].built_ins["LIGHT1_ENERGY"] = constt(ShaderLanguage::TYPE_FLOAT);
|
||||
shader_modes[VS::SHADER_SKY].functions["fragment"].built_ins["LIGHT1_COLOR"] = constt(ShaderLanguage::TYPE_VEC3);
|
||||
shader_modes[VS::SHADER_SKY].functions["fragment"].built_ins["LIGHT2_ENABLED"] = constt(ShaderLanguage::TYPE_BOOL);
|
||||
shader_modes[VS::SHADER_SKY].functions["fragment"].built_ins["LIGHT2_DIRECTION"] = constt(ShaderLanguage::TYPE_VEC3);
|
||||
shader_modes[VS::SHADER_SKY].functions["fragment"].built_ins["LIGHT2_ENERGY"] = constt(ShaderLanguage::TYPE_FLOAT);
|
||||
shader_modes[VS::SHADER_SKY].functions["fragment"].built_ins["LIGHT2_COLOR"] = constt(ShaderLanguage::TYPE_VEC3);
|
||||
shader_modes[VS::SHADER_SKY].functions["fragment"].built_ins["LIGHT3_ENABLED"] = constt(ShaderLanguage::TYPE_BOOL);
|
||||
shader_modes[VS::SHADER_SKY].functions["fragment"].built_ins["LIGHT3_DIRECTION"] = constt(ShaderLanguage::TYPE_VEC3);
|
||||
shader_modes[VS::SHADER_SKY].functions["fragment"].built_ins["LIGHT3_ENERGY"] = constt(ShaderLanguage::TYPE_FLOAT);
|
||||
shader_modes[VS::SHADER_SKY].functions["fragment"].built_ins["LIGHT3_COLOR"] = constt(ShaderLanguage::TYPE_VEC3);
|
||||
|
||||
shader_modes[VS::SHADER_SKY].modes.push_back("use_half_res_pass");
|
||||
shader_modes[VS::SHADER_SKY].modes.push_back("use_quarter_res_pass");
|
||||
|
||||
shader_types.insert("spatial");
|
||||
shader_types.insert("canvas_item");
|
||||
shader_types.insert("particles");
|
||||
shader_types.insert("sky");
|
||||
}
|
||||
|
|
|
@ -507,7 +507,7 @@ public:
|
|||
BIND0R(RID, sky_create)
|
||||
BIND2(sky_set_radiance_size, RID, int)
|
||||
BIND2(sky_set_mode, RID, SkyMode)
|
||||
BIND2(sky_set_texture, RID, RID)
|
||||
BIND2(sky_set_material, RID, RID)
|
||||
|
||||
BIND0R(RID, environment_create)
|
||||
|
||||
|
|
|
@ -419,7 +419,7 @@ public:
|
|||
FUNCRID(sky)
|
||||
FUNC2(sky_set_radiance_size, RID, int)
|
||||
FUNC2(sky_set_mode, RID, SkyMode)
|
||||
FUNC2(sky_set_texture, RID, RID)
|
||||
FUNC2(sky_set_material, RID, RID)
|
||||
|
||||
/* ENVIRONMENT API */
|
||||
|
||||
|
|
|
@ -1578,7 +1578,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", "panorama"), &VisualServer::sky_set_texture);
|
||||
ClassDB::bind_method(D_METHOD("sky_set_material", "sky", "material"), &VisualServer::sky_set_material);
|
||||
#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);
|
||||
|
@ -1971,6 +1971,7 @@ void VisualServer::_bind_methods() {
|
|||
BIND_ENUM_CONSTANT(SHADER_SPATIAL);
|
||||
BIND_ENUM_CONSTANT(SHADER_CANVAS_ITEM);
|
||||
BIND_ENUM_CONSTANT(SHADER_PARTICLES);
|
||||
BIND_ENUM_CONSTANT(SHADER_SKY);
|
||||
BIND_ENUM_CONSTANT(SHADER_MAX);
|
||||
|
||||
BIND_ENUM_CONSTANT(ARRAY_VERTEX);
|
||||
|
@ -2311,13 +2312,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 (Fastest),PCF5,PCF13 (Slowest)"));
|
||||
|
||||
GLOBAL_DEF("rendering/quality/reflections/roughness_layers", 6);
|
||||
GLOBAL_DEF("rendering/quality/reflections/roughness_layers", 8);
|
||||
GLOBAL_DEF("rendering/quality/reflections/texture_array_reflections", true);
|
||||
GLOBAL_DEF("rendering/quality/reflections/texture_array_reflections.mobile", false);
|
||||
GLOBAL_DEF("rendering/quality/reflections/ggx_samples", 1024);
|
||||
GLOBAL_DEF("rendering/quality/reflections/ggx_samples.mobile", 128);
|
||||
GLOBAL_DEF("rendering/quality/reflections/fast_filter_high_quality", false);
|
||||
GLOBAL_DEF("rendering/quality/reflection_atlas/reflection_size", 128);
|
||||
GLOBAL_DEF("rendering/quality/reflection_atlas/reflection_size", 256);
|
||||
GLOBAL_DEF("rendering/quality/reflection_atlas/reflection_size.mobile", 128);
|
||||
GLOBAL_DEF("rendering/quality/reflection_atlas/reflection_count", 64);
|
||||
|
||||
|
|
|
@ -160,6 +160,7 @@ public:
|
|||
SHADER_SPATIAL,
|
||||
SHADER_CANVAS_ITEM,
|
||||
SHADER_PARTICLES,
|
||||
SHADER_SKY,
|
||||
SHADER_MAX
|
||||
};
|
||||
|
||||
|
@ -681,7 +682,7 @@ public:
|
|||
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;
|
||||
virtual void sky_set_material(RID p_sky, RID p_material) = 0;
|
||||
|
||||
/* ENVIRONMENT API */
|
||||
|
||||
|
|
Loading…
Reference in a new issue