120 lines
No EOL
3.3 KiB
Text
120 lines
No EOL
3.3 KiB
Text
input View {
|
|
mat4 mvp,
|
|
mat4 proj,
|
|
mat4 proj_inverse,
|
|
mat4 view,
|
|
mat4 world, //geometry.world atm
|
|
float2 fov, //fov.x, fov.y
|
|
float2 resolution,
|
|
float4 target_region,
|
|
float4 target_region_size
|
|
}
|
|
|
|
input ColorWheel {
|
|
float outer_distance,
|
|
float inner_distance
|
|
}
|
|
|
|
input ColorTriangle {
|
|
float hue,
|
|
float size,
|
|
float value_gamma,
|
|
float saturation_gamma
|
|
}
|
|
|
|
stage vertex vert(
|
|
input { View view },
|
|
vertex in { #0 float4 pos, #1 float4 color, #2 float2 uv },
|
|
fragment out { float4 color, float2 uv})
|
|
{
|
|
out.color = in.color;
|
|
out.uv = in.uv;
|
|
|
|
stage.pos = input.view.mvp * float4(in.pos.xyz, 1.0);
|
|
}
|
|
|
|
stage fragment frag_color_ring(
|
|
input { ColorWheel wheel },
|
|
fragment in { float4 color, float2 uv })
|
|
{
|
|
float TAU = 6.2831853071795864769252867665590057683943387987502116419498891846;
|
|
|
|
float2 centered_coords = in.uv - 0.5;
|
|
float center_dist = length(centered_coords);
|
|
|
|
float change = dFdx(in.uv.x); //this assumes the object is unrotated and uniformly scaled
|
|
float alpha = clamp(min(center_dist - input.wheel.inner_distance, -center_dist + input.wheel.outer_distance - change) / change, 0.0, 1.0);
|
|
|
|
float angle = atan(centered_coords.y, centered_coords.x);
|
|
float normalized_angle = mod(angle / TAU + 0.25, 1.0);
|
|
float3 hue = hue2rgb(normalized_angle);
|
|
|
|
float4 color = float4(float3(hue), alpha);
|
|
|
|
if(color.a <= 0.0) {
|
|
discard;
|
|
return;
|
|
}
|
|
|
|
stage.color[0] = color;
|
|
}
|
|
|
|
stage fragment frag_color_triangle(
|
|
input { ColorTriangle triangle },
|
|
fragment in { float4 color, float2 uv })
|
|
{
|
|
float TAU = 6.283185307179586;
|
|
float cos30 = 0.866025403784438; //cos(30°)
|
|
float tan60 = 1.732050807568877;
|
|
float tan60sq = 3.0;
|
|
float sin30 = 0.5;
|
|
|
|
float size = input.triangle.size;
|
|
float2 centered_coords = in.uv - sin30;
|
|
|
|
float2 down = float2(0.0, -1.0);
|
|
float2 top_right = float2(cos30, sin30);
|
|
float2 top_left = float2(-cos30, sin30);
|
|
|
|
float down_dist = dot(down, centered_coords) + size;
|
|
float top_right_dist = dot(top_right, centered_coords) + size;
|
|
float top_left_dist = dot(top_left, centered_coords) + size;
|
|
float dist = min(min(top_right_dist, top_left_dist), down_dist);
|
|
|
|
float change = length(float2(dFdx(in.uv.x), dFdy(in.uv.y))); //this assumes the object is uniformly scaled (rotation is fine)
|
|
float alpha = clamp(dist/change, 0.0, 1.0);
|
|
|
|
float hue = input.triangle.hue;
|
|
float saturation = down_dist / (down_dist + top_right_dist);
|
|
saturation = pow(saturation, input.triangle.saturation_gamma);
|
|
float value = 1.0 - (top_left_dist / (size * tan60sq));
|
|
value = pow(value, input.triangle.value_gamma);
|
|
float3 color_rgb = hsv2rgb(float3(hue, saturation, value));
|
|
//color_rgb = float3(fract(saturation)); //debug
|
|
|
|
float4 color = float4(color_rgb, alpha);
|
|
|
|
if(color.a <= 0.0) {
|
|
discard;
|
|
return;
|
|
}
|
|
|
|
stage.color[0] = color;
|
|
}
|
|
|
|
float3 hsv2rgb(float3 hsv){
|
|
float3 rgb = hue2rgb(hsv.x); //apply hue
|
|
rgb = mix(float3(1.0), rgb, hsv.y); //apply saturation
|
|
rgb = rgb * hsv.z; //apply value
|
|
return rgb;
|
|
}
|
|
|
|
float3 hue2rgb(float hue) {
|
|
hue = fract(hue); //only use fractional part
|
|
float r = abs(hue * 6.0 - 3.0) - 1.0; //red
|
|
float g = 2.0 - abs(hue * 6.0 - 2.0); //green
|
|
float b = 2.0 - abs(hue * 6.0 - 4.0); //blue
|
|
float3 rgb = float3(r,g,b); //combine components
|
|
rgb = clamp(rgb, 0.0, 1.0); //clamp between 0 and 1
|
|
return rgb;
|
|
} |