Useful Gradient Effects All-in-one Shader

Make ALL these gradient effects in ONE shader! 

一个把我想要的各种功能缝在一起的shader。

Shader code
shader_type canvas_item;
//A shader by 刚学shader的小策划@SL

uniform float effect_filling: hint_range(0.0, 1.0, 0.01) = 1.0;
uniform float angle: hint_range(-180.0, 180.0, 0.1) = 0.0;
uniform float keep_saturation: hint_range(0.0, 1.0, 0.01) = 1.0;
uniform float keep_luminance: hint_range(0.0, 1.0, 0.01) = 1.0;
uniform vec4 color_start: source_color = vec4(1.0);
uniform float start_pos: hint_range(0.0, 1.0, 0.01) = 0.0;
uniform vec4 color_mid: source_color = vec4(1.0);
uniform float mid_pos: hint_range(0.0, 1.0, 0.01) = 0.5;
uniform vec4 color_end: source_color = vec4(1.0);
uniform float end_pos: hint_range(0.0, 1.0, 0.01) = 1.0;
uniform bool midpos_enabled = false;

uniform float range_start: hint_range(0.0, 1.0, 0.01) = 0.0;
uniform float range_end: hint_range(0.0, 1.0, 0.01) = 1.0;
uniform float range_softedge: hint_range(0.0, 1.0, 0.01) = 0.1;

//Functions from @nonunknown
vec3 rgb2hsv(vec3 c)
{
    vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
    vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
    vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));

    float d = q.x - min(q.w, q.y);
    float e = 1.0e-10;
    return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}

vec3 hsv2rgb(vec3 c)
{
    vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
    vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
    return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
}

void fragment() {
	vec4 tex = texture(TEXTURE, UV);
	vec3 hsv = rgb2hsv(tex.rgb);
	
	vec2 angle_vec = vec2(cos(angle/180.0*PI),sin(angle/180.0*PI));
	float _uv_pos = dot(vec2(UV.x-0.5, UV.y-0.5),angle_vec) + 0.5;
	
	// the .r here represents HUE, .g is SATURATION, .b is LUMINANCE
	vec4 color = vec4(1.0);
	
	if (_uv_pos < start_pos) {color = color_start;}
	if (_uv_pos > end_pos) {color = color_end;}
	
	if (_uv_pos > start_pos && _uv_pos < end_pos){
		if (midpos_enabled && mid_pos > start_pos && mid_pos < end_pos){
			if (_uv_pos > mid_pos){
				color = mix(color_mid, color_end, (_uv_pos-mid_pos)/(end_pos-mid_pos));
			}
			else{
				color = mix(color_start, color_mid,(_uv_pos-start_pos)/(mid_pos-start_pos));
			}
		}
		else {
			color = mix(color_start, color_end, (_uv_pos-start_pos)/(end_pos-start_pos));
		}
	}
	
	vec3 _c = rgb2hsv(color.rgb);
	vec3 new_color = vec3(_c.r,mix(_c.g,hsv.g,keep_saturation),mix(_c.b,hsv.b,keep_luminance));
	
	tex = vec4(hsv2rgb(new_color),tex.a);
	
	//Range参数在这里生效:超出Range范围时调整其实际filling值
	float _filling = effect_filling;
	
	if (range_start > 0.0){
		if (_uv_pos < (range_start - range_softedge)){_filling = 0.0;}
		if (_uv_pos > (range_start - range_softedge) && _uv_pos < (range_start + range_softedge)){
			_filling *= (_uv_pos - (range_start - range_softedge))/ (range_softedge*2.0) ;}
		}
		
	if (range_end < 1.0 && range_end > range_start){
		if (_uv_pos > (range_end + range_softedge)){_filling = 0.0;}
		if (_uv_pos > (range_end - range_softedge) && _uv_pos < (range_end + range_softedge)){
			_filling *= 1.0 - (_uv_pos - (range_end - range_softedge))/ (range_softedge*2.0) ;}
		}
	
	COLOR = mix( texture(TEXTURE, UV), tex, _filling);
	COLOR.a = texture(TEXTURE, UV).a;
}
Tags
2d, Color, godot4, gradient, light, palette
The shader code and all code snippets in this post are under CC0 license and can be used freely without the author's permission. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.

More from SL

Simple Clipping with Adjustable Softedge

Simple Gradient Mapping

Related shaders

All in one outline shader

Moon Shader 2D All Phases and Roughened Shadow

color splash (show only one color)

Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments