-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add god rays, fix bugs with change_node plugin, change warehouse floo…
…r to concrete
- Loading branch information
1 parent
1cec3bf
commit 2e01534
Showing
12 changed files
with
433 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
tool | ||
extends Spatial | ||
|
||
var light : Light | ||
export(float, 0, 2) var exposure := 0.5 setget set_exposure | ||
export(float, EASE) var attenuation := 2.0 setget set_attenuation | ||
export(float, 0, 2) var light_size := 0.5 setget set_light_size | ||
|
||
var clouds : Texture setget set_clouds | ||
|
||
var canvas : MeshInstance | ||
var material := preload("GodRays.tres").duplicate() as ShaderMaterial | ||
|
||
func _notification(what : int) -> void: | ||
if what == NOTIFICATION_PARENTED: | ||
if get_parent() is Light: | ||
light = get_parent() | ||
elif what == NOTIFICATION_UNPARENTED: | ||
light = null | ||
set_clouds(null) | ||
|
||
func _ready() -> void: | ||
if get_child_count() > 0 and get_child(0).owner == null: | ||
remove_child(get_child(0)) | ||
|
||
var mesh := QuadMesh.new() | ||
mesh.size = Vector2(2, 2) | ||
mesh.custom_aabb = AABB(Vector3(1,1,1) * -300000, Vector3(1,1,1) * 600000) | ||
|
||
canvas = MeshInstance.new() | ||
canvas.name = "GodRay" | ||
canvas.mesh = mesh | ||
canvas.material_override = material | ||
add_child(canvas) | ||
|
||
material.setup_local_to_scene() | ||
|
||
set_exposure(exposure) | ||
set_attenuation(attenuation) | ||
set_light_size(light_size) | ||
|
||
set_clouds(null) | ||
|
||
func _process(delta : float) -> void: | ||
if not light: | ||
material.set_shader_param("light_type", 0) | ||
material.set_shader_param("light_pos", Vector3()) | ||
return | ||
|
||
var is_directional := light is DirectionalLight | ||
|
||
material.set_shader_param("light_type", not is_directional) | ||
material.set_shader_param("light_color", light.light_color * light.light_energy) | ||
|
||
if is_directional: | ||
var direction := light.global_transform.basis.z | ||
material.set_shader_param("light_pos", direction) | ||
material.set_shader_param("size", light_size) | ||
else: | ||
var position := light.global_transform.origin | ||
material.set_shader_param("light_pos", position) | ||
material.set_shader_param("size", light_size * (light as OmniLight).omni_range) | ||
|
||
material.set_shader_param("num_samples", ProjectSettings.get_setting("rendering/quality/godrays/sample_number")) | ||
material.set_shader_param("use_pcf5", ProjectSettings.get_setting("rendering/quality/godrays/use_pcf5")) | ||
material.set_shader_param("dither", ProjectSettings.get_setting("rendering/quality/godrays/dither_amount")) | ||
|
||
func set_exposure(value : float) -> void: | ||
exposure = value | ||
material.set_shader_param("exposure", exposure) | ||
if canvas: | ||
canvas.visible = exposure != 0 | ||
|
||
func set_attenuation(value : float) -> void: | ||
attenuation = value | ||
material.set_shader_param("attenuate", attenuation) | ||
if canvas: | ||
canvas.visible = attenuation != 0 | ||
|
||
func set_light_size(value : float) -> void: | ||
light_size = value | ||
if canvas: | ||
canvas.visible = light_size != 0 | ||
|
||
func set_clouds(value : Texture) -> void: | ||
clouds = value | ||
material.set_shader_param("clouds", value) | ||
material.set_shader_param("use_clouds", value != null) |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
[remap] | ||
|
||
importer="texture" | ||
type="StreamTexture" | ||
path="res://.import/GodRays.svg-0e880633ec1b3300b7885fc8b84904ed.stex" | ||
metadata={ | ||
"vram_texture": false | ||
} | ||
|
||
[deps] | ||
|
||
source_file="res://addons/SIsilicon.vfx.godrays/GodRays.svg" | ||
dest_files=[ "res://.import/GodRays.svg-0e880633ec1b3300b7885fc8b84904ed.stex" ] | ||
|
||
[params] | ||
|
||
compress/mode=0 | ||
compress/lossy_quality=0.7 | ||
compress/hdr_mode=0 | ||
compress/bptc_ldr=0 | ||
compress/normal_map=0 | ||
flags/repeat=0 | ||
flags/filter=true | ||
flags/mipmaps=false | ||
flags/anisotropic=false | ||
flags/srgb=2 | ||
process/fix_alpha_border=true | ||
process/premult_alpha=false | ||
process/HDR_as_SRGB=false | ||
process/invert_color=false | ||
process/normal_map_invert_y=false | ||
stream=false | ||
size_limit=0 | ||
detect_3d=true | ||
svg/scale=1.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
[gd_resource type="ShaderMaterial" load_steps=2 format=2] | ||
|
||
[sub_resource type="Shader" id=1] | ||
code = "shader_type spatial; | ||
render_mode unshaded, cull_disabled, skip_vertex_transform, blend_add; | ||
|
||
uniform vec4 light_color: hint_color; | ||
uniform vec3 light_pos; | ||
uniform float size = 1.0; | ||
uniform int light_type = 0; //0 = directional, 1 = omni | ||
|
||
uniform float exposure: hint_range(0,2); | ||
uniform float attenuate = 1.0; | ||
|
||
uniform sampler2D clouds : hint_albedo; | ||
uniform bool use_clouds = false; | ||
|
||
uniform int num_samples = 100; | ||
uniform float dither = 1.0; | ||
uniform bool use_pcf5 = true; | ||
|
||
const float PI = 3.141592653; | ||
const float HALF_PI = PI/2.0; | ||
|
||
varying mat4 inv_project_mat; | ||
varying vec4 light_screen_pos; | ||
varying vec3 camera_pos; | ||
varying float far_plane; | ||
varying float attenuate_size; | ||
|
||
void vertex() { | ||
light_screen_pos = INV_CAMERA_MATRIX * vec4(light_pos, float(light_type)); | ||
attenuate_size = 1.0 / length(light_screen_pos) * size; | ||
|
||
light_screen_pos = PROJECTION_MATRIX * light_screen_pos; | ||
light_screen_pos.xyz /= light_screen_pos.w; | ||
light_screen_pos.xy = light_screen_pos.xy * 0.5 + 0.5; | ||
light_screen_pos.z = -(INV_CAMERA_MATRIX * vec4(light_pos, float(light_type))).z; | ||
|
||
camera_pos = CAMERA_MATRIX[3].xyz; | ||
inv_project_mat = INV_PROJECTION_MATRIX; | ||
vec4 _far_plane = (INV_PROJECTION_MATRIX * vec4(0,0,1,1)); | ||
far_plane = -_far_plane.z / _far_plane.w; | ||
|
||
POSITION = vec4(VERTEX.xy, -1.0, 1.0); | ||
} | ||
|
||
vec3 uv_to_ray(vec2 uv, mat4 inv_cam_matrix) { | ||
vec4 view_space_ray = inv_project_mat * vec4(uv * 2.0 - 1.0, 0, 1); | ||
view_space_ray.xyz /= view_space_ray.w; | ||
view_space_ray.w = 0.0; | ||
|
||
view_space_ray = normalize(view_space_ray); | ||
return (view_space_ray * inv_cam_matrix).xyz; | ||
} | ||
|
||
float depth_texture(sampler2D tex, vec2 uv) { | ||
float depth = clamp(uv, 0.0, 1.0) == uv ? texture(tex, uv).r : 1.0; | ||
vec4 upos = inv_project_mat * vec4(uv*2.0-1.0, depth*2.0-1.0, 1.0); | ||
return -upos.z/upos.w; | ||
} | ||
|
||
vec4 texture_panorama(sampler2D tex, vec3 ray) { | ||
float u = atan(ray.x, ray.z) / (2.0 * PI) + 0.5; | ||
float v = asin(ray.y) / PI + 0.5; | ||
return texture(tex, vec2(u, 1.0 - v)); | ||
} | ||
|
||
float sun_light(sampler2D depth, vec3 ray_o, vec3 ray_d, vec2 uv, vec2 tex_Size) { | ||
float light_depth = mix(light_screen_pos.z, far_plane, float(1-light_type)); | ||
|
||
float is_obstacle = float(depth_texture(depth, uv) < light_depth); | ||
|
||
if(use_pcf5) { | ||
is_obstacle += float(depth_texture(depth, uv + tex_Size*vec2(-1,0)) < light_depth); | ||
is_obstacle += float(depth_texture(depth, uv + tex_Size*vec2(1,0)) < light_depth); | ||
is_obstacle += float(depth_texture(depth, uv + tex_Size*vec2(0,1)) < light_depth); | ||
is_obstacle += float(depth_texture(depth, uv + tex_Size*vec2(0,-1)) < light_depth); | ||
is_obstacle /= 5.0; | ||
} | ||
|
||
if(use_clouds) { | ||
float temp = texture_panorama(clouds, ray_d).a; | ||
if(temp < 0.7) temp = 0.0; | ||
is_obstacle = min(is_obstacle + temp, 1.0); | ||
} | ||
|
||
float sun = 0.0; | ||
if(light_type == 0) { | ||
sun = smoothstep(1.0, 0.0, acos(dot(light_pos, ray_d)) / HALF_PI / size); | ||
} else if(light_type == 1) { | ||
sun = smoothstep(1.0, 0.0, acos(dot(normalize(light_pos - ray_o), ray_d)) / HALF_PI / attenuate_size); | ||
} | ||
|
||
sun *= 1.0 - is_obstacle; | ||
|
||
return max(sun, 0.0); | ||
} | ||
|
||
float variable_smoothstep(float x, float N) { | ||
if(N > 0.0) { | ||
return pow(x, N); | ||
} else if(N < 0.0) { | ||
if(x <= 0.5) { | ||
return pow(2.0*x, -N) / 2.0; | ||
} else { | ||
return 1.0 - pow(2.0*(1.0-x), -N) / 2.0; | ||
} | ||
} | ||
|
||
return 0.0; | ||
} | ||
|
||
uint hash(uint x) { | ||
x = ((x >> uint(16)) ^ x) * uint(73244475); | ||
x = ((x >> uint(16)) ^ x) * uint(73244475); | ||
x = (x >> uint(16)) ^ x; | ||
return x; | ||
} | ||
|
||
float rand_from_seed(inout uint seed) { | ||
int k; | ||
int s = int(seed); | ||
if (s == 0) | ||
s = 305420679; | ||
k = s / 127773; | ||
s = 16807 * (s - k * 127773) - 2836 * k; | ||
if (s < 0) | ||
s += 2147483647; | ||
seed = uint(s); | ||
return float(seed % uint(65536)) / 65535.0; | ||
} | ||
|
||
void fragment() { | ||
if(length(light_color) <= 0.001) | ||
discard; | ||
|
||
vec2 pixel_size = 1.0 / vec2(textureSize(SCREEN_TEXTURE, 0));//vec2(dFdx(SCREEN_UV.x), dFdy(SCREEN_UV.y)) * 1.5; | ||
vec2 screen_uv = SCREEN_UV; | ||
vec2 delta_uv = (light_screen_pos.xy - screen_uv) / (float(num_samples)); | ||
|
||
float light = 0.0; | ||
uint seed = hash(uint(FRAGCOORD.x + FRAGCOORD.y * float(textureSize(SCREEN_TEXTURE, 0).x))); | ||
screen_uv += delta_uv * dither * rand_from_seed(seed); | ||
for(int i = 0; i < num_samples; i++) { | ||
vec3 ray = uv_to_ray(screen_uv, INV_CAMERA_MATRIX); | ||
float sample = sun_light(DEPTH_TEXTURE, camera_pos, ray, screen_uv, pixel_size); | ||
|
||
light += sample; | ||
screen_uv += delta_uv; | ||
} | ||
|
||
vec3 light_dir = light_type == 0 ? light_pos : normalize(light_pos - camera_pos); | ||
float facing_weight = dot(uv_to_ray(vec2(0.5), INV_CAMERA_MATRIX), light_dir); | ||
|
||
ALBEDO = variable_smoothstep(light / float(num_samples), attenuate) * exposure * light_color.rgb * max(facing_weight * facing_weight, 0.0); | ||
|
||
//vec3 ray = uv_to_ray(SCREEN_UV, INV_CAMERA_MATRIX); | ||
//ALBEDO = vec3(sun_light(DEPTH_TEXTURE, camera_pos, ray, SCREEN_UV, pixel_size)); | ||
//ALBEDO = texture(clouds, SCREEN_UV).rgb; | ||
}" | ||
|
||
[resource] | ||
render_priority = 14 | ||
shader = SubResource( 1 ) | ||
shader_param/light_color = null | ||
shader_param/light_pos = null | ||
shader_param/size = 1.0 | ||
shader_param/light_type = 0 | ||
shader_param/exposure = null | ||
shader_param/attenuate = 1.0 | ||
shader_param/use_clouds = false | ||
shader_param/num_samples = 100 | ||
shader_param/dither = 1.0 | ||
shader_param/use_pcf5 = true |
Oops, something went wrong.