[gd_resource type="ShaderMaterial" load_steps=2 format=2] [sub_resource type="Shader" id=1] code = "shader_type canvas_item; const int MAX_STEPS = 100; const float MAX_DIST = 100.; const float SURF_DIST = .01; uniform float dist_from_center = 2.; uniform float rotation_speed = 6.; //uniform bool player = true; uniform vec3 player = vec3(0,1,0); uniform vec3 light_pos = vec3(0,4,0); uniform float light_intensity = 1.; uniform float zoom = 2.; uniform int state = 0; // To keep between 0 and 1 uniform float shadow_factor = .1; float getDist(vec3 p,float time){ // float dist_from_center = 2. * sin(3. * time); vec4 sphere1 = vec4(0,0,-100,1); vec4 sphere2 = vec4(0,0,-100,1); vec4 sphere3 = vec4(0,0,-100,1); if(state == 1){ sphere1 = vec4(0,1.1,0,1); }else if(state != 0){ sphere1 = vec4(dist_from_center*cos(rotation_speed*time + 3.14159 * 0. * 2. / float(state)),1.1, dist_from_center*sin(rotation_speed*time + 3.14159 + 3.14159 * 0. * 2. / float(state)),1); sphere2 = vec4(dist_from_center*cos(rotation_speed*time + 3.14159 * 1. * 2. / float(state)),1.1, dist_from_center*sin(rotation_speed*time + 3.14159 + 3.14159 * 1. * 2. / float(state)),1); sphere3 = vec4(dist_from_center*cos(rotation_speed*time + 3.14159 * 2. * 2. / float(state)),1.1, dist_from_center*sin(rotation_speed*time + 3.14159 + 3.14159 * 2. * 2. / float(state)),1); } float sphere1_dist = length(p - sphere1.xyz) - sphere1.w; float sphere2_dist = length(p - sphere2.xyz) - sphere2.w; float sphere3_dist = length(p - sphere3.xyz) - sphere3.w; // If you want the plane uncomment this and the lines that use plane float plane_dist = p.y; return min(min(min(sphere1_dist,sphere2_dist),sphere3_dist),plane_dist); //return min(min(sphere1_dist,sphere2_dist),sphere3_dist); } float rayMarch(vec3 ro, vec3 rd,float time){ float d = .0; for(int i = 0; i < MAX_STEPS; i++){ vec3 p = ro + rd * d; float ds = getDist(p,time); d += ds; if(d > MAX_DIST || ds <= SURF_DIST) break; } return d; } vec3 getNormal(vec3 p,float time){ float d = getDist(p,time); vec2 e = vec2(.1,0); // We can find the normal using the points around the hit point vec3 n = d - vec3( getDist(p-e.xyy,time), getDist(p-e.yxy,time), getDist(p-e.yyx,time) ); return normalize(n); } float getLight(vec3 p,float time){ vec3 l = normalize(light_pos - p) * light_intensity; vec3 n = getNormal(p,time); float dif = clamp(dot(n,l),.0,1.); float d = rayMarch(p + n * SURF_DIST * 2.,l,time); if(d < length(light_pos - p)){ dif *= shadow_factor; } return dif; } void fragment( ) { // Assume the width and height to be the same vec2 uv = (UV - vec2(0.5)) * zoom; vec3 col = vec3(0.0); vec3 r_origin = vec3(.0,8.,.0); vec3 r_dir = normalize(vec3(uv.y,-1.,uv.x)); float d = rayMarch(r_origin,r_dir,TIME); vec3 p = r_origin + r_dir * d; float diff = getLight(p,TIME); //col = vec3(diff * float(!player),diff * float(player),0); col = vec3(diff) * player; COLOR = vec4(col,1); }" [resource] resource_local_to_scene = true shader = SubResource( 1 ) shader_param/dist_from_center = 0.7 shader_param/rotation_speed = 4.0 shader_param/player = Vector3( 0, 1, 0 ) shader_param/light_pos = Vector3( 0, 4, 0 ) shader_param/light_intensity = 1.0 shader_param/zoom = 1.0 shader_param/state = 0 shader_param/shadow_factor = 1.0