Modification du shader de ciel pour ajouter la gestion du soleil.

This commit is contained in:
osquallo 2019-10-08 20:06:33 +02:00
parent 96db8d8f2d
commit 34bfcd6c24
6 changed files with 304 additions and 36 deletions

View file

@ -23,6 +23,8 @@ func _ready():
$settings.show()
$sky/viewport/sprite.set_time_of_day( 8.0, $light_system/directional_light, 25.0 )
func _process( delta ):
iTime+=delta

View file

@ -1,16 +1,17 @@
[gd_scene load_steps=22 format=2]
[gd_scene load_steps=23 format=2]
[ext_resource path="res://previewer/previewer.gd" type="Script" id=1]
[ext_resource path="res://shaders/sky.shader" type="Shader" id=2]
[ext_resource path="res://previewer/sky.gd" type="Script" id=3]
[ext_resource path="res://previewer/dummy/dummy.tscn" type="PackedScene" id=4]
[ext_resource path="res://textures/tilables/basic_texture_1024.png" type="Texture" id=5]
[ext_resource path="res://meshes/decors/rocks/cliff_001.tscn" type="PackedScene" id=6]
[ext_resource path="res://meshes/props/pendo_teddy/pendo_teddy.tscn" type="PackedScene" id=7]
[ext_resource path="res://meshes/props/travel_box/container.tscn" type="PackedScene" id=8]
[ext_resource path="res://meshes/props/reference_box/reference_box.tscn" type="PackedScene" id=9]
[ext_resource path="res://meshes/props/fountain_suzanha/Fountain_suzanha.tscn" type="PackedScene" id=10]
[ext_resource path="res://previewer/settings.tscn" type="PackedScene" id=11]
[ext_resource path="res://textures/sky/milkywaypan_brunier_2048.jpg" type="Texture" id=3]
[ext_resource path="res://previewer/sky.gd" type="Script" id=4]
[ext_resource path="res://previewer/dummy/dummy.tscn" type="PackedScene" id=5]
[ext_resource path="res://textures/tilables/basic_texture_1024.png" type="Texture" id=6]
[ext_resource path="res://meshes/decors/rocks/cliff_001.tscn" type="PackedScene" id=7]
[ext_resource path="res://meshes/props/pendo_teddy/pendo_teddy.tscn" type="PackedScene" id=8]
[ext_resource path="res://meshes/props/travel_box/container.tscn" type="PackedScene" id=9]
[ext_resource path="res://meshes/props/reference_box/reference_box.tscn" type="PackedScene" id=10]
[ext_resource path="res://meshes/props/fountain_suzanha/Fountain_suzanha.tscn" type="PackedScene" id=11]
[ext_resource path="res://previewer/settings.tscn" type="PackedScene" id=12]
[sub_resource type="OpenSimplexNoise" id=1]
period = 8.0
@ -29,7 +30,19 @@ shader_param/COVERAGE = 0.5
shader_param/THICKNESS = 25.0
shader_param/ABSORPTION = 1.031
shader_param/STEPS = 25
shader_param/earth_radius_km = 6371.0
shader_param/atmo_radius_km = 6471.0
shader_param/cam_height_m = 1.8
shader_param/sun_pos = Vector3( 1, 1, 1 )
shader_param/sun_intensity = 22.0
shader_param/rayleigh_coeff = Vector3( 5.5, 13, 22.4 )
shader_param/mie_coeff = 21.0
shader_param/rayleigh_scale = 800.0
shader_param/mie_scale = 120.0
shader_param/mie_scatter_dir = 0.758
shader_param/rotate_night_sky = null
shader_param/iChannel0 = SubResource( 2 )
shader_param/night_sky = ExtResource( 3 )
[sub_resource type="ImageTexture" id=4]
size = Vector2( 1280, 720 )
@ -51,7 +64,7 @@ ambient_light_energy = 3.82
[sub_resource type="SpatialMaterial" id=8]
flags_unshaded = true
flags_world_triplanar = true
albedo_texture = ExtResource( 5 )
albedo_texture = ExtResource( 6 )
uv1_scale = Vector3( 122, 122, 122 )
[sub_resource type="PlaneMesh" id=9]
@ -80,12 +93,12 @@ render_target_update_mode = 3
material = SubResource( 3 )
texture = SubResource( 4 )
centered = false
script = ExtResource( 3 )
script = ExtResource( 4 )
[node name="world_environment" type="WorldEnvironment" parent="."]
environment = SubResource( 7 )
[node name="dummy" parent="." instance=ExtResource( 4 )]
[node name="dummy" parent="." instance=ExtResource( 5 )]
[node name="terrain" type="Spatial" parent="."]
@ -93,44 +106,44 @@ environment = SubResource( 7 )
transform = Transform( 60.964, 0, 0, 0, 1.21928, 0, 0, 0, 60.964, 0, 0, 0 )
mesh = SubResource( 9 )
[node name="cliff" parent="terrain" instance=ExtResource( 6 )]
[node name="cliff" parent="terrain" instance=ExtResource( 7 )]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -48.2121 )
moss_height = 15.0
moss_fade = 2.5
[node name="props" type="Spatial" parent="."]
[node name="pendo_teddy" parent="props" instance=ExtResource( 7 )]
[node name="pendo_teddy" parent="props" instance=ExtResource( 8 )]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -3 )
[node name="container" parent="props" instance=ExtResource( 8 )]
[node name="container" parent="props" instance=ExtResource( 9 )]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -5 )
color = Color( 0.145098, 0.0980392, 0.713726, 1 )
lid_angle = 45.0
[node name="container_2" parent="props" instance=ExtResource( 8 )]
[node name="container_2" parent="props" instance=ExtResource( 9 )]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -1.24144, 0, -5 )
color = Color( 0.491686, 0.159256, 0.832031, 1 )
lid_angle = 90.0
[node name="container_3" parent="props" instance=ExtResource( 8 )]
[node name="container_3" parent="props" instance=ExtResource( 9 )]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -2.6614, 0, -5 )
color = Color( 0.360784, 1, 0, 1 )
lid_angle = 12.0
[node name="container_4" parent="props" instance=ExtResource( 8 )]
[node name="container_4" parent="props" instance=ExtResource( 9 )]
transform = Transform( 0.457191, 0, 0.889369, 0, 1, 0, -0.889369, 0, 0.457191, -3.94754, 4.76837e-007, -4.27729 )
color = Color( 0.972549, 0.196078, 0.0431373, 1 )
[node name="reference_box" parent="props" instance=ExtResource( 9 )]
[node name="reference_box" parent="props" instance=ExtResource( 10 )]
[node name="Fountain_suzanha" parent="props" instance=ExtResource( 10 )]
[node name="Fountain_suzanha" parent="props" instance=ExtResource( 11 )]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 5, 0.472, -5 )
[node name="light_system" type="Spatial" parent="."]
[node name="directional_light" type="DirectionalLight" parent="light_system"]
transform = Transform( 0.522088, 0.655715, -0.545401, 0, 0.639473, 0.768814, 0.852892, -0.401389, 0.333861, 0, 13.7088, 0 )
transform = Transform( 0.522088, 0.655715, -0.545401, 0, 0.639473, 0.768814, 0.852892, -0.401388, 0.333861, 0, 13.7088, 0 )
light_energy = 2.21
shadow_enabled = true
@ -139,7 +152,7 @@ transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 21.7307, 0 )
extents = Vector3( 63.192, 25, 76.323 )
data = SubResource( 10 )
[node name="settings" parent="." instance=ExtResource( 11 )]
[node name="settings" parent="." instance=ExtResource( 12 )]
margin_left = -475.0
margin_top = -243.0
margin_right = -219.0

View file

@ -13,3 +13,7 @@ func _on_sky_absorption_value_changed(value):
func _on_sky_steps_value_changed(value):
sky_sprite.step_scb( value )
func _on_sky_time_value_changed(value):
sky_sprite.set_time_of_day( value, get_tree().get_root().get_node("$light_system/directional_light"), 25.0 )

View file

@ -63,12 +63,12 @@ max_value = 1.0
step = 0.001
value = 0.5
[node name="sky_thickness_box_2" type="HBoxContainer" parent="scroll_container/controls/sky_box"]
[node name="sky_thickness_box" type="HBoxContainer" parent="scroll_container/controls/sky_box"]
margin_top = 20.0
margin_right = 256.0
margin_bottom = 36.0
[node name="label" type="Label" parent="scroll_container/controls/sky_box/sky_thickness_box_2"]
[node name="label" type="Label" parent="scroll_container/controls/sky_box/sky_thickness_box"]
margin_top = 1.0
margin_right = 126.0
margin_bottom = 15.0
@ -76,19 +76,19 @@ size_flags_horizontal = 3
text = "Thickness"
align = 2
[node name="sky_thickness" type="HSlider" parent="scroll_container/controls/sky_box/sky_thickness_box_2"]
[node name="sky_thickness" type="HSlider" parent="scroll_container/controls/sky_box/sky_thickness_box"]
margin_left = 130.0
margin_right = 256.0
margin_bottom = 16.0
size_flags_horizontal = 3
value = 25.0
[node name="sky_absorption_box_3" type="HBoxContainer" parent="scroll_container/controls/sky_box"]
[node name="sky_absorption_box" type="HBoxContainer" parent="scroll_container/controls/sky_box"]
margin_top = 40.0
margin_right = 256.0
margin_bottom = 56.0
[node name="label" type="Label" parent="scroll_container/controls/sky_box/sky_absorption_box_3"]
[node name="label" type="Label" parent="scroll_container/controls/sky_box/sky_absorption_box"]
margin_top = 1.0
margin_right = 126.0
margin_bottom = 15.0
@ -96,7 +96,7 @@ size_flags_horizontal = 3
text = "Absorbtion"
align = 2
[node name="sky_absorption" type="HSlider" parent="scroll_container/controls/sky_box/sky_absorption_box_3"]
[node name="sky_absorption" type="HSlider" parent="scroll_container/controls/sky_box/sky_absorption_box"]
margin_left = 130.0
margin_right = 256.0
margin_bottom = 16.0
@ -105,12 +105,12 @@ max_value = 10.0
step = 0.001
value = 1.031
[node name="sky_steps_box_4" type="HBoxContainer" parent="scroll_container/controls/sky_box"]
[node name="sky_steps_box" type="HBoxContainer" parent="scroll_container/controls/sky_box"]
margin_top = 60.0
margin_right = 256.0
margin_bottom = 76.0
[node name="label" type="Label" parent="scroll_container/controls/sky_box/sky_steps_box_4"]
[node name="label" type="Label" parent="scroll_container/controls/sky_box/sky_steps_box"]
margin_top = 1.0
margin_right = 126.0
margin_bottom = 15.0
@ -118,13 +118,36 @@ size_flags_horizontal = 3
text = "Steps"
align = 2
[node name="sky_steps" type="HSlider" parent="scroll_container/controls/sky_box/sky_steps_box_4"]
[node name="sky_steps" type="HSlider" parent="scroll_container/controls/sky_box/sky_steps_box"]
margin_left = 130.0
margin_right = 256.0
margin_bottom = 16.0
size_flags_horizontal = 3
value = 25.0
[node name="sky_time_box" type="HBoxContainer" parent="scroll_container/controls/sky_box"]
margin_top = 60.0
margin_right = 256.0
margin_bottom = 76.0
[node name="label" type="Label" parent="scroll_container/controls/sky_box/sky_time_box"]
margin_top = 1.0
margin_right = 126.0
margin_bottom = 15.0
size_flags_horizontal = 3
text = "Time of day"
align = 2
[node name="sky_time" type="HSlider" parent="scroll_container/controls/sky_box/sky_time_box"]
margin_left = 130.0
margin_right = 256.0
margin_bottom = 16.0
size_flags_horizontal = 3
max_value = 24.0
step = 0.01
value = 8.0
[connection signal="value_changed" from="scroll_container/controls/sky_box/sky_coverage_box/sky_coverage" to="." method="_on_sky_coverage_value_changed"]
[connection signal="value_changed" from="scroll_container/controls/sky_box/sky_thickness_box_2/sky_thickness" to="." method="_on_sky_thickness_value_changed"]
[connection signal="value_changed" from="scroll_container/controls/sky_box/sky_absorption_box_3/sky_absorption" to="." method="_on_sky_absorption_value_changed"]
[connection signal="value_changed" from="scroll_container/controls/sky_box/sky_steps_box_4/sky_steps" to="." method="_on_sky_steps_value_changed"]
[connection signal="value_changed" from="scroll_container/controls/sky_box/sky_thickness_box/sky_thickness" to="." method="_on_sky_thickness_value_changed"]
[connection signal="value_changed" from="scroll_container/controls/sky_box/sky_absorption_box/sky_absorption" to="." method="_on_sky_absorption_value_changed"]
[connection signal="value_changed" from="scroll_container/controls/sky_box/sky_steps_box/sky_steps" to="." method="_on_sky_steps_value_changed"]
[connection signal="value_changed" from="scroll_container/controls/sky_box/sky_time_box/sky_time" to="." method="_on_sky_time_value_changed"]

View file

@ -20,3 +20,27 @@ func absb_scb(value):
func step_scb(value):
self.material.set("shader_param/STEPS",value)
export var sun_position = Vector3(0.0, 1.0, 0.0) setget set_sun_position, get_sun_position
func set_sun_position(new_position):
sun_position = new_position
if self.material:
self.material.set_shader_param("sun_pos", sun_position)
# _trigger_update_sky()
func get_sun_position():
return sun_position
func set_time_of_day(hours, directional_light, horizontal_angle = 0.0):
var sun_position = Vector3(0.0, -100.0, 0.0)
sun_position = sun_position.rotated(Vector3(1.0, 0.0, 0.0), hours * PI / 12.0)
sun_position = sun_position.rotated(Vector3(0.0, 1.0, 0.0), horizontal_angle)
if directional_light:
var t = directional_light.transform
t.origin = sun_position
directional_light.transform = t.looking_at(Vector3(0.0, 0.0, 0.0), Vector3(0.0, 1.0, 0.0))
directional_light.light_energy = 1.0 - clamp(abs(hours - 12.0) / 6.0, 0.0, 1.0)
# and update our sky
set_sun_position(sun_position)

View file

@ -10,6 +10,171 @@ uniform float THICKNESS :hint_range(0,100); //25.
uniform float ABSORPTION :hint_range(0,10); //1.030725
uniform int STEPS :hint_range(0,100); //25
////////////////////////////////
uniform float earth_radius_km = 6371;
uniform float atmo_radius_km = 6471;
uniform float cam_height_m = 1.8;
//uniform vec3 sun_pos = vec3(0.0, 0.1, -0.5);
uniform vec3 sun_pos = vec3(1.0, 1.0, 1.0);
uniform float sun_intensity = 22.0;
uniform vec3 rayleigh_coeff = vec3(5.5, 13.0, 22.4); // we divide this by 100000
uniform float mie_coeff = 21.0; // we divide this by 100000
uniform float rayleigh_scale = 800;
uniform float mie_scale = 120;
uniform float mie_scatter_dir = 0.758;
uniform sampler2D night_sky : hint_black_albedo;
uniform mat3 rotate_night_sky;
// Atmosphere code from: https://github.com/wwwtyro/glsl-atmosphere
vec2 rsi(vec3 r0, vec3 rd, float sr) {
// ray-sphere intersection that assumes
// the sphere is centered at the origin.
// No intersection when result.x > result.y
float a = dot(rd, rd);
float b = 2.0 * dot(rd, r0);
float c = dot(r0, r0) - (sr * sr);
float d = (b*b) - 4.0*a*c;
if (d < 0.0) return vec2(100000.0,-100000.0);
return vec2(
(-b - sqrt(d))/(2.0*a),
(-b + sqrt(d))/(2.0*a)
);
}
vec3 atmosphere(vec3 r, vec3 r0, vec3 pSun, float iSun, float rPlanet, float rAtmos, vec3 kRlh, float kMie, float shRlh, float shMie, float g) {
float PI = 3.14159265358979;
int iSteps = 16;
int jSteps = 8;
// Normalize the sun and view directions.
pSun = normalize(pSun);
r = normalize(r);
// Calculate the step size of the primary ray.
vec2 p = rsi(r0, r, rAtmos);
if (p.x > p.y) return vec3(0,0,0);
p.y = min(p.y, rsi(r0, r, rPlanet).x);
float iStepSize = (p.y - p.x) / float(iSteps);
// Initialize the primary ray time.
float iTimeBis = 0.0;
// Initialize accumulators for Rayleigh and Mie scattering.
vec3 totalRlh = vec3(0,0,0);
vec3 totalMie = vec3(0,0,0);
// Initialize optical depth accumulators for the primary ray.
float iOdRlh = 0.0;
float iOdMie = 0.0;
// Calculate the Rayleigh and Mie phases.
float mu = dot(r, pSun);
float mumu = mu * mu;
float gg = g * g;
float pRlh = 3.0 / (16.0 * PI) * (1.0 + mumu);
float pMie = 3.0 / (8.0 * PI) * ((1.0 - gg) * (mumu + 1.0)) / (pow(1.0 + gg - 2.0 * mu * g, 1.5) * (2.0 + gg));
// Sample the primary ray.
for (int i = 0; i < iSteps; i++) {
// Calculate the primary ray sample position.
vec3 iPos = r0 + r * (iTimeBis + iStepSize * 0.5);
// Calculate the height of the sample.
float iHeight = length(iPos) - rPlanet;
// Calculate the optical depth of the Rayleigh and Mie scattering for this step.
float odStepRlh = exp(-iHeight / shRlh) * iStepSize;
float odStepMie = exp(-iHeight / shMie) * iStepSize;
// Accumulate optical depth.
iOdRlh += odStepRlh;
iOdMie += odStepMie;
// Calculate the step size of the secondary ray.
float jStepSize = rsi(iPos, pSun, rAtmos).y / float(jSteps);
// Initialize the secondary ray time.
float jTime = 0.0;
// Initialize optical depth accumulators for the secondary ray.
float jOdRlh = 0.0;
float jOdMie = 0.0;
// Sample the secondary ray.
for (int j = 0; j < jSteps; j++) {
// Calculate the secondary ray sample position.
vec3 jPos = iPos + pSun * (jTime + jStepSize * 0.5);
// Calculate the height of the sample.
float jHeight = length(jPos) - rPlanet;
// Accumulate the optical depth.
jOdRlh += exp(-jHeight / shRlh) * jStepSize;
jOdMie += exp(-jHeight / shMie) * jStepSize;
// Increment the secondary ray time.
jTime += jStepSize;
}
// Calculate attenuation.
vec3 attn = exp(-(kMie * (iOdMie + jOdMie) + kRlh * (iOdRlh + jOdRlh)));
// Accumulate scattering.
totalRlh += odStepRlh * attn;
totalMie += odStepMie * attn;
// Increment the primary ray time.
iTimeBis += iStepSize;
}
// Calculate and return the final color.
return iSun * (pRlh * kRlh * totalRlh + pMie * kMie * totalMie);
}
// and our application
vec3 ray_dir_from_uv(vec2 uv) {
float PI = 3.14159265358979;
vec3 dir;
float x = sin(PI * uv.y);
dir.y = cos(PI * uv.y);
dir.x = x * sin(2.0 * PI * (0.5 - uv.x));
dir.z = x * cos(2.0 * PI * (0.5 - uv.x));
return dir;
}
vec2 uv_from_ray_dir(vec3 dir) {
float PI = 3.14159265358979;
vec2 uv;
uv.y = acos(dir.y) / PI;
dir.y = 0.0;
dir = normalize(dir);
uv.x = acos(dir.z) / (2.0 * PI);
if (dir.x < 0.0) {
uv.x = 1.0 - uv.x;
}
uv.x = 0.5 - uv.x;
if (uv.x < 0.0) {
uv.x += 1.0;
}
return uv;
}
////////////////////////////////
float noise( in vec3 x )
{
x*=0.01;
@ -166,7 +331,8 @@ void mainImage( out vec4 fragColor, in vec2 fragCoord, in vec2 iResolution)
panorama_uv(fragCoord,ro,rd,iResolution);
vec3 sky = render_sky_color(rd);
// vec3 sky = render_sky_color(rd);
vec3 sky = vec3( 0.0, 0.0, 0.0);
vec4 cld = vec4(0.);
float skyPow = dot(rd, vec3(0.0, -1.0, 0.0));
float horizonPow =1.-pow(1.0-abs(skyPow), 5.0);
@ -189,6 +355,42 @@ void mainImage( out vec4 fragColor, in vec2 fragCoord, in vec2 iResolution)
}
void fragment(){
//////////////////////////////////
vec3 dir = ray_dir_from_uv(UV);
// determine our sky color
vec3 color = atmosphere(
vec3( dir.x, -dir.y, dir.z )
, vec3(0.0, earth_radius_km * 100.0 + cam_height_m * 0.1, 0.0)
, sun_pos
, sun_intensity
, earth_radius_km * 100.0
, atmo_radius_km * 100.0
, rayleigh_coeff / 100000.0
, mie_coeff / 100000.0
, rayleigh_scale
, mie_scale
, mie_scatter_dir
);
// Apply exposure.
color = 1.0 - exp(-1.0 * color);
// Mix in night sky (already sRGB)
if (dir.y > 0.0) {
float f = (0.21 * color.r) + (0.72 * color.g) + (0.07 * color.b);
float cutoff = 0.1;
vec2 ns_uv = uv_from_ray_dir(rotate_night_sky * dir);
color += texture(night_sky, ns_uv).rgb * clamp((cutoff - f) / cutoff, 0.0, 1.0);
}
COLOR = vec4(color, 1.0);
////////////////////////////////////////
vec2 iResolution=1./TEXTURE_PIXEL_SIZE;
mainImage(COLOR,UV*iResolution,iResolution);
COLOR = vec4(color, 1.0)+COLOR;
}