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 } input TransparencyGrid { float2 grid_size, float4 one_color, float4 other_color } stage vertex vert( input { View view }, vertex in { #0 float4 pos, #1 float4 color, #2 float2 uv }, fragment out { float4 color, float2 uv, float4 cs_pos}) { out.color = in.color; out.uv = in.uv; stage.pos = input.view.mvp * float4(in.pos.xyz, 1.0); out.cs_pos = stage.pos; } 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; } stage fragment frag_transparency_grid( input { TransparencyGrid trans_grid, View view }, fragment in { float4 color, float2 uv, float4 cs_pos }) { float2 uv = in.cs_pos.xy / in.cs_pos.w; uv.x = uv.x * (input.view.resolution.x / input.view.resolution.y); float2 grid = floor(uv * input.trans_grid.grid_size); float3 grid_color = float3(0); float grid_sum = grid.x + grid.y; float grid_mod = mod(grid_sum, 2.0); if(grid_mod == 0.0){ grid_color = input.trans_grid.one_color.rgb; } else { grid_color = input.trans_grid.other_color.rgb; } stage.color[0] = float4(grid_color, 1.0 - in.color.a); } 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; }