Receptors shader refactor

This commit is contained in:
Luke Hubmayer-Werner 2021-01-05 01:38:38 +10:30
parent 75759659ee
commit 026768dff4
2 changed files with 51 additions and 43 deletions

View File

@ -1,10 +1,12 @@
tool tool
extends MeshInstance2D extends MeshInstance2D
var ring_px := 4 # Analogous to diameter export var ring_px := 4 # Analogous to diameter
var receptor_px := 24 # Diameter export var receptor_px := 24 # Diameter
var shadow_px := 8 # Outer edge, analogous to radius export var shadow_px := 8 # Outer edge, analogous to radius
var shadow_color := Color.black export var line_color := Color.blue
export var dot_color := Color.blue
export var shadow_color := Color.black
var center := Vector2(0.0, 0.0) var center := Vector2(0.0, 0.0)
var ring_vertex_count := 36 var ring_vertex_count := 36
@ -108,11 +110,11 @@ func update_ring_mesh():
func _draw(): func _draw():
# draw_old(true, true) # draw_old(true, true)
# draw_tris() draw_tris()
var mesh_v = ring_vertex_count # var mesh_v = ring_vertex_count
var ring_thickness = receptor_px + shadow_px*2 # var ring_thickness = receptor_px + shadow_px*2
var estimated_area = circumscribe_polygon_area(GameTheme.receptor_ring_radius+ring_thickness*0.5, mesh_v) - inscribe_polygon_area(GameTheme.receptor_ring_radius-ring_thickness*0.5, mesh_v) # var estimated_area = circumscribe_polygon_area(GameTheme.receptor_ring_radius+ring_thickness*0.5, mesh_v) - inscribe_polygon_area(GameTheme.receptor_ring_radius-ring_thickness*0.5, mesh_v)
var ideal_ring_area = PI * (pow(GameTheme.receptor_ring_radius+receptor_px/2+shadow_px, 2) - pow(GameTheme.receptor_ring_radius-receptor_px/2-shadow_px, 2)) # var ideal_ring_area = PI * (pow(GameTheme.receptor_ring_radius+receptor_px/2+shadow_px, 2) - pow(GameTheme.receptor_ring_radius-receptor_px/2-shadow_px, 2))
var quad_area = 4*pow(GameTheme.receptor_ring_radius+receptor_px/2+shadow_px, 2) var quad_area = 4*pow(GameTheme.receptor_ring_radius+receptor_px/2+shadow_px, 2)
@ -121,6 +123,10 @@ func _draw():
material.set_shader_param("shadow_thickness", shadow_px/GameTheme.receptor_ring_radius) material.set_shader_param("shadow_thickness", shadow_px/GameTheme.receptor_ring_radius)
material.set_shader_param("shadow_thickness_taper", -0.75) material.set_shader_param("shadow_thickness_taper", -0.75)
material.set_shader_param("px", 0.5/GameTheme.receptor_ring_radius) material.set_shader_param("px", 0.5/GameTheme.receptor_ring_radius)
material.set_shader_param("px2", 1.0/GameTheme.receptor_ring_radius)
material.set_shader_param("line_color", line_color)
material.set_shader_param("dot_color", dot_color)
material.set_shader_param("shadow_color", shadow_color)
func set_ring_vertex_count(num: int): func set_ring_vertex_count(num: int):
assert(num > 3) assert(num > 3)
@ -143,6 +149,7 @@ func _ready():
$"/root".connect("size_changed", self, "update") $"/root".connect("size_changed", self, "update")
#func _process(delta): #func _process(delta):
# update()
# pass # pass
# if not Engine.editor_hint: # if not Engine.editor_hint:
# set_receptor_positions(sin(OS.get_ticks_msec()*0.001*0.0125*PI)*PI) # set_receptor_positions(sin(OS.get_ticks_msec()*0.001*0.0125*PI)*PI)

View File

@ -15,6 +15,7 @@ uniform float dot_radius = 0.033;
uniform float shadow_thickness = 0.01; uniform float shadow_thickness = 0.01;
uniform float shadow_thickness_taper = 0.33; uniform float shadow_thickness_taper = 0.33;
uniform float px = 0.002; // Represents 1px in UV space, for AA purposes uniform float px = 0.002; // Represents 1px in UV space, for AA purposes
uniform float px2 = 0.004; // Represents 2px in UV space, for AA purposes
//void vertex() { //void vertex() {
//} //}
@ -25,45 +26,45 @@ float angle_diff(float a, float b) {
return d; return d;
} }
void fragment() { vec2 line_alpha(float dist) {
if (COLOR.rgba != vec4(1.0, 0.0, 0.0, 1.0)) { // Returns [line, shadow]
COLOR.rgba = vec4(0.0); vec2 output = vec2(0.0);
lowp float dist = distance(UV, vec2(0.0)); float d = abs(dist - 1.0) - line_thickness;
lowp float angle = atan(-UV.y, UV.x); output.x = clamp(-d/px - 1.0, 0.0, 1.0);
float line_alpha = 0.0; output.y = clamp(1.0 - (d - shadow_thickness*shadow_thickness_taper)/(shadow_thickness*(1.0-shadow_thickness_taper)), 0, 1.0);
float dot_alpha = 0.0; return output;
float shadow_alpha = 0.0; }
float px2 = px/2.0;
float diff = abs(dist - 1.0);
float d2 = diff - line_thickness;
if (d2 < -px2){
line_alpha = 1.0;
} else if (d2 < shadow_thickness){
if (d2 < px2)
line_alpha = 1.0 - (d2 + px2)/px;
shadow_alpha = 1.0 - min((d2 - shadow_thickness*shadow_thickness_taper)/(shadow_thickness*(1.0-shadow_thickness_taper)), 1.0);
}
vec2 dot_alpha(vec2 uv) {
// Returns [dot, shadow]
vec2 output = vec2(0.0);
// Iterate over all the receptors and check distance to them // Iterate over all the receptors and check distance to them
float receptor_spacing = TAU/float(num_receptors); float receptor_spacing = TAU/float(num_receptors);
for (float rads=receptor_offset; rads<TAU; rads+=receptor_spacing){ for (float rads=receptor_offset; rads<TAU; rads+=receptor_spacing){
// Check for dot distance // Check for dot distance
vec2 uv = vec2(cos(rads), -sin(rads)); vec2 dot_uv = vec2(cos(rads), -sin(rads));
float dist2 = distance(UV, uv); float d = distance(uv, dot_uv) - dot_radius;
float diff2 = dist2 - dot_radius; output.x = clamp(-d/px - 1.0, output.x, 1.0);
if (diff2 < -px2){ output.y = clamp(1.0 - (d - shadow_thickness*shadow_thickness_taper)/(shadow_thickness*(1.0-shadow_thickness_taper)), output.y, 1.0);
dot_alpha = 1.0;
} else if (diff2 < shadow_thickness){
if (diff2 < px2)
dot_alpha = 1.0 - (diff2 + px2)/px;
shadow_alpha = max(shadow_alpha, 1.0-min((diff2 - shadow_thickness*shadow_thickness_taper)/(shadow_thickness*(1.0-shadow_thickness_taper)), 1.0));
} }
} return output;
line_alpha = max(line_alpha - dot_alpha, 0.0); }
COLOR.rgb = (dot_color.rgb*dot_alpha) + (line_color.rgb*line_alpha) + (shadow_color.rgb*shadow_alpha); const vec4 dbg_color = vec4(1.0, 0.0, 0.0, 1.0);
COLOR.a = dot_alpha + line_alpha*(1.0-dot_alpha); void fragment() {
COLOR.a = COLOR.a + shadow_alpha*(1.0-COLOR.a); if (COLOR.rgba != dbg_color) { // Can't use return in fragment() function
COLOR.rgba = vec4(0.0);
lowp float dist = distance(UV, vec2(0.0));
lowp float angle = atan(-UV.y, UV.x);
vec3 lds_alpha = vec3(0.0);
lds_alpha.yz = dot_alpha(UV);
lds_alpha.xz = clamp(line_alpha(dist), vec2(0.0, lds_alpha.z), vec2(1.0-lds_alpha.y));
// lds_alpha.x = clamp(line_alpha(dist).x, 0.0, 1.0-lds_alpha.y);
lds_alpha = clamp(lds_alpha, 0.0, 1.0);
COLOR.rgb = (dot_color.rgb*lds_alpha.y) + (line_color.rgb*lds_alpha.x) + (shadow_color.rgb*lds_alpha.z);
COLOR.a = lds_alpha.y + lds_alpha.x*(1.0-lds_alpha.y);
COLOR.a = COLOR.a + lds_alpha.z*(1.0-COLOR.a);
COLOR.a = clamp(COLOR.a, 0.0, 1.0); } COLOR.a = clamp(COLOR.a, 0.0, 1.0); }
} }