mirror of
https://github.com/DigvijaysinhGohil/Godot-Shader-Lib.git
synced 2025-01-07 01:43:35 +08:00
RoundedPolygon node added
This commit is contained in:
parent
759cfa6a06
commit
c322de328c
72
addons/ShaderLib/Procedural/Shapes/RoundedPolygon.gd
Normal file
72
addons/ShaderLib/Procedural/Shapes/RoundedPolygon.gd
Normal file
@ -0,0 +1,72 @@
|
||||
@tool
|
||||
class_name VisualShaderNodeProceduralRoundedPolygon extends VisualShaderNodeCustom
|
||||
|
||||
func _init() -> void:
|
||||
_set_input_port_default_value(1, 0.5)
|
||||
_set_input_port_default_value(2, 0.5)
|
||||
_set_input_port_default_value(3, 3)
|
||||
_set_input_port_default_value(4, 1.0)
|
||||
|
||||
output_port_for_preview = 0
|
||||
|
||||
func _get_name() -> String:
|
||||
return "RoundedPolygon"
|
||||
|
||||
func _get_category() -> String:
|
||||
return "Procedural/Shapes"
|
||||
|
||||
func _get_description() -> String:
|
||||
return "Generates a rounded polygon shape based on input UV at the size specified by inputs width and height. The input sides specifies the number of sides, and the input roundness defines the roundness of each corner."
|
||||
|
||||
func _get_return_icon_type() -> VisualShaderNode.PortType:
|
||||
return PORT_TYPE_SCALAR
|
||||
|
||||
func _get_input_port_count() -> int:
|
||||
return 5
|
||||
|
||||
func _get_input_port_name(port: int) -> String:
|
||||
match port:
|
||||
0:
|
||||
return "uv"
|
||||
1:
|
||||
return "width"
|
||||
2:
|
||||
return "height"
|
||||
3:
|
||||
return "sides"
|
||||
4:
|
||||
return "roundness"
|
||||
return ""
|
||||
|
||||
func _get_input_port_type(port: int) -> VisualShaderNode.PortType:
|
||||
match port:
|
||||
0:
|
||||
return PORT_TYPE_VECTOR_2D
|
||||
_:
|
||||
return PORT_TYPE_SCALAR
|
||||
|
||||
func _get_output_port_count() -> int:
|
||||
return 1
|
||||
|
||||
func _get_output_port_name(port: int) -> String:
|
||||
return "output"
|
||||
|
||||
func _get_output_port_type(port: int) -> VisualShaderNode.PortType:
|
||||
return PORT_TYPE_SCALAR
|
||||
|
||||
func _get_global_code(mode: Shader.Mode) -> String:
|
||||
var code: String = preload("RoundedPolygon.gdshaderinc").code
|
||||
return code
|
||||
|
||||
func _get_code(input_vars: Array[String], output_vars: Array[String], mode: Shader.Mode, type: VisualShader.Type) -> String:
|
||||
var uv: String = "UV"
|
||||
|
||||
if input_vars[0]:
|
||||
uv = input_vars[0]
|
||||
|
||||
var width: String = input_vars[1]
|
||||
var height: String = input_vars[2]
|
||||
var sides: String = input_vars[3]
|
||||
var roundness: String = input_vars[4]
|
||||
|
||||
return output_vars[0] + " = rounded_polygon_shape(%s, %s, %s, float(%s), %s);" % [uv, width, height, sides, roundness]
|
@ -0,0 +1,34 @@
|
||||
float rounded_polygon_shape(vec2 uv, float width, float height, float sides, float roundness){
|
||||
uv = uv * 2.0 + vec2(-1.0);
|
||||
roundness /= 10.0;
|
||||
float _epsilon = 1e-6;
|
||||
uv.x = uv.x / ( width + ((width>-_epsilon && width<_epsilon) ? 1.0 : 0.0 * _epsilon));
|
||||
uv.y = uv.y / ( height + ((height>-_epsilon && height<_epsilon) ? 1.0 : 0.0 * _epsilon));
|
||||
roundness = clamp(roundness, 1e-6, 1.0);
|
||||
float _i_sides = floor( abs( sides ) );
|
||||
float _full_angle = 2.0 * PI / _i_sides;
|
||||
float _half_angle = _full_angle / 2.;
|
||||
float _diagonal = 1.0 / cos( _half_angle );
|
||||
float _chamfer_angle = roundness * _half_angle;
|
||||
float _remaining_angle = _half_angle - _chamfer_angle;
|
||||
float _ratio = tan(_remaining_angle) / tan(_half_angle);
|
||||
vec2 _chamfer_center = vec2(cos(_half_angle) , sin(_half_angle))* _ratio * _diagonal;
|
||||
|
||||
float _dist_a = length(_chamfer_center);
|
||||
float _dist_b = 1.0 - _chamfer_center.x;
|
||||
float _uv_scale = _diagonal;
|
||||
uv *= _uv_scale;
|
||||
vec2 _polar_uv = vec2(atan(uv.y, uv.x), length(uv));
|
||||
|
||||
_polar_uv.x += PI / 2.0 + TAU;
|
||||
_polar_uv.x = mod(_polar_uv.x + _half_angle, _full_angle );
|
||||
_polar_uv.x = abs(_polar_uv.x - _half_angle);
|
||||
uv = vec2(cos(_polar_uv.x), sin(_polar_uv.x)) * _polar_uv.y;
|
||||
float _angle_ratio = 1.0 - (_polar_uv.x-_remaining_angle) / _chamfer_angle;
|
||||
float _dist_c = sqrt(_dist_a * _dist_a + _dist_b * _dist_b - 2.0 * _dist_a *_dist_b * cos(PI - _half_angle * _angle_ratio));
|
||||
float output = uv.x;
|
||||
float _chamfer_zone = (_half_angle - _polar_uv.x) < _chamfer_angle ? 1.0 : 0.0;
|
||||
output = mix(uv.x, _polar_uv.y / _dist_c, _chamfer_zone);
|
||||
output = clamp((1.0 - output) / fwidth(output), 0.0, 1.0);
|
||||
return output;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user