From c5525158cc07d5ab61c5cdabe7623a907e04ab38 Mon Sep 17 00:00:00 2001 From: Ronja Date: Sat, 27 Nov 2021 12:55:32 +0100 Subject: [PATCH] color displays --- colorpicker.wren | 224 +++++++++++++++--- materials/shaders.emsl | 30 ++- materials/transparency_grid.material_basis.lx | 37 +++ 3 files changed, 252 insertions(+), 39 deletions(-) create mode 100644 materials/transparency_grid.material_basis.lx diff --git a/colorpicker.wren b/colorpicker.wren index bb84295..aba9515 100644 --- a/colorpicker.wren +++ b/colorpicker.wren @@ -10,61 +10,70 @@ import "luxe: string" for Str class ColorPickerData { //parameters - we could make some of this dynamic if we wanted to - triangle_size {35} - outer_ring_size {200} - inner_ring_size {140} + triangle_size:Num {35} + outer_ring_size:Num {200} + inner_ring_size:Num {140} - r{_r} - g{_g} - b{_b} + r:Num{_r} + g:Num{_g} + b:Num{_b} - h{_h} - s{_s} - v{_v} + h:Num{_h} + s:Num{_s} + v:Num{_v} - a{_a} + a:Num{_a} - rgba{[_r, _g, _b, _a]} - hsva{[_h, _s, _v, _a]} + rgba:Color{[_hdr_mul * _r, _hdr_mul * _g, _hdr_mul * _b, _a]} + rgba_ldr:Color{[_r , _g, _b, _a]} + hsva:List{[_h, _s, _v, _a]} //almost a color ^^ - srgb_hex{_srgb_hex} - srgb_hex=(value){_srgb_hex = value} + srgb_hex:Bool{_srgb_hex} + srgb_hex=(value:Bool){_srgb_hex = value} + + hdr_multiplier:Num{_hdr_mul} + hdr_multiplier=(value:Num){_hdr_mul = value} + + allow_hdr:Bool{_allow_hdr} + allow_hdr=(v:Bool){_allow_hdr = v} toString{"Data - HSV:[%(h), %(s), %(v)] - RGB:[%(r), %(g), %(b)] - A:[%(a)]"} construct new(){ + _hdr_mul = 1 set_rgba(Color.hex(0xFFAABB)) } set_rgba(col){set_rgba(col, true)} set_rgba(col, update_spaces){ - if(!ColorPicker.approx(_r, col.r)) _r = col.r - if(!ColorPicker.approx(_g, col.g)) _g = col.g - if(!ColorPicker.approx(_b, col.b)) _b = col.b - if(!ColorPicker.approx(_a, col.a)) _a = col.a + if(!CPHelper.approx(_r, col.r)) _r = col.r + if(!CPHelper.approx(_g, col.g)) _g = col.g + if(!CPHelper.approx(_b, col.b)) _b = col.b + if(!CPHelper.approx(_a, col.a)) _a = col.a if(!update_spaces) return var hsv = Color.rgb2hsv(col) //be careful not to destroy hue when doing rgb to hsv - if(!ColorPicker.approx(_h, hsv.x) && !ColorPicker.approx(_s, 0)) _h = hsv.x - if(!ColorPicker.approx(_s, hsv.y)) _s = hsv.y - if(!ColorPicker.approx(_v, hsv.z)) _v = hsv.z + if(!CPHelper.approx(_h, hsv.x) && !CPHelper.approx(_s, 0) && + !CPHelper.approx(_h, hsv.x-1) && !CPHelper.approx(_h, hsv.x+1)) _h = hsv.x + if(!CPHelper.approx(_s, hsv.y)) _s = hsv.y + if(!CPHelper.approx(_v, hsv.z)) _v = hsv.z } set_hsva(col){set_hsva(col, true)} set_hsva(col, update_spaces){ - if(!ColorPicker.approx(_h, col.x)) _h = col.x - if(!ColorPicker.approx(_s, col.y)) _s = col.y - if(!ColorPicker.approx(_v, col.z)) _v = col.z - if(!ColorPicker.approx(_a, col.a)) _a = col.a + if(!CPHelper.approx(_h, col.x)) _h = col.x + if(!CPHelper.approx(_s, col.y)) _s = col.y + if(!CPHelper.approx(_v, col.z)) _v = col.z + if(!CPHelper.approx(_a, col.a)) _a = col.a if(!update_spaces) return var rgb = Color.hsv2rgb(col) - if(!ColorPicker.approx(_r, rgb.r)) _r = rgb.r - if(!ColorPicker.approx(_g, rgb.g)) _g = rgb.g - if(!ColorPicker.approx(_b, rgb.b)) _b = rgb.b + if(!CPHelper.approx(_r, rgb.r)) _r = rgb.r + if(!CPHelper.approx(_g, rgb.g)) _g = rgb.g + if(!CPHelper.approx(_b, rgb.b)) _b = rgb.b } set_rgba_component(index: Num, value: Num){ @@ -119,7 +128,8 @@ class ColorPickerData { class ColorPicker{ static create(ui: Entity) : Control{ - var data = ColorPickerData.new() + var data: ColorPickerData = ColorPickerData.new() + data.allow_hdr = true //setup root var panel = UIWindow.create(ui) @@ -137,10 +147,18 @@ class ColorPicker{ Control.set_id(panel, "color_view.%(ID.unique())") Control.set_state_data(color_view, data) - var wheel = create_hsv_wheel(ui, color_view) + var wheel_and_color = Control.create(ui) + Control.set_contain(wheel_and_color, UIContain.row | UIContain.hfit | UIContain.vfit | UIContain.start) + Control.set_behave(wheel_and_color, UIBehave.left) + Control.child_add(color_view, wheel_and_color) + + var wheel = CPHelper.create_hsv_wheel(ui, color_view) Control.set_behave(wheel, UIBehave.left | UIBehave.top) Control.set_margin(wheel, 8, 8, 0, 0) - Control.child_add(color_view, wheel) + Control.child_add(wheel_and_color, wheel) + + var color_display = CPHelper.color_display(ui, color_view) + Control.child_add(wheel_and_color, color_display) var component_choice = Control.create(ui) Control.set_contain(component_choice, UIContain.row | UIContain.start) @@ -159,10 +177,10 @@ class ColorPicker{ UIButton.set_text(hsva_button, "hsv") Control.child_add(component_choice, hsva_button) - var rgba_components = rgba_values(ui, color_view) + var rgba_components = CPHelper.rgba_values(ui, color_view) Control.child_add(color_view, rgba_components) - var hsva_components = hsva_values(ui, color_view) + var hsva_components = CPHelper.hsva_values(ui, color_view) Control.set_visible(hsva_components, false) Control.child_add(color_view, hsva_components) @@ -180,7 +198,7 @@ class ColorPicker{ } } - var hex_field = hex_input(ui, color_view) + var hex_field = CPHelper.hex_input(ui, color_view) Control.child_add(color_view, hex_field) var bottom_offset = Control.create(ui) @@ -190,6 +208,138 @@ class ColorPicker{ return panel } +} + +#hidden +class CPHelper{ + static color_display(ui: UI, data_control: Control){ + var data: ColorPickerData = Control.get_state_data(data_control) + + var root = Control.create(ui) + Control.set_behave(root, UIBehave.left | UIBehave.top) + Control.set_contain(root, UIContain.column | UIContain.start | UIContain.hfit | UIContain.vfit) + Control.set_margin(root, 16, 0, 0, 0) + + var color_opaque = UIPanel.create(ui) + UIPanel.set_color(color_opaque, data.rgba_ldr) + UIPanel.set_border(color_opaque, 0, Color.clear) + Control.set_size(color_opaque, 64, 32) + Control.set_margin(color_opaque, 8, 8, 8, 0) + Control.set_behave(color_opaque, UIBehave.left | UIBehave.top) + Control.child_add(root, color_opaque) + + var color_w_trans_bg = Control.create(ui) + Control.set_size(color_w_trans_bg, 64, 32) + Control.set_margin(color_w_trans_bg, 8, 0, 8, 0) + Control.set_behave(color_w_trans_bg, UIBehave.left | UIBehave.top) + Control.child_add(root, color_w_trans_bg) + + var color_alpha = UIPanel.create(ui) + UIPanel.set_color(color_alpha, data.rgba_ldr) + UIPanel.set_border(color_alpha, 0, Color.clear) + Control.set_clip(color_alpha, false) + Control.set_margin(color_alpha, 0, 0, 0, 0) + Control.set_behave(color_alpha, UIBehave.fill) + Control.child_add(color_w_trans_bg, color_alpha) + + var alpha_bg = UIImage.create(ui) + Control.set_margin(alpha_bg, 0, 0, 0, 0) + Control.set_behave(alpha_bg, UIBehave.fill) + var alpha_mat = Material.create("materials/transparency_grid") + UIImage.set_material(alpha_bg, alpha_mat) + Control.child_add(color_w_trans_bg, alpha_bg) + + Control.set_events(data_control){|event| + if(event.type == UIEvent.change){ + var color = data.rgba_ldr + UIImage.set_color(alpha_bg, color) + color.a = 1 + UIPanel.set_color(color_alpha, color) + UIPanel.set_color(color_opaque, color) + } + } + + var hdr_header = UILabel.create(ui) + UILabel.set_text(hdr_header, "HDR:") + UILabel.set_text_size(hdr_header, 14) + Control.set_margin(hdr_header, 8, 8, 0, 0) + Control.set_behave(hdr_header, UIBehave.left | UIBehave.top) + Control.set_size(hdr_header, 64, 32) + Control.child_add(root, hdr_header) + + var hdr_mult_label = UILabel.create(ui) + UILabel.set_text(hdr_mult_label, "multiplier:") + UILabel.set_text_size(hdr_mult_label, 12) + UILabel.set_color(hdr_mult_label, [0.8, 0.8, 0.8, 1]) + Control.set_margin(hdr_mult_label, 8, -10, 0, 0) + Control.set_size(hdr_mult_label, 64, 32) + Control.set_behave(hdr_mult_label, UIBehave.left | UIBehave.top) + Control.child_add(root, hdr_mult_label) + + var hdr_number = UINumber.create(ui) + UINumber.set_value(hdr_number, 1) + UINumber.set_validation(hdr_number) { |input: Num| + return input.max(0) + } + Control.set_size(hdr_number, 64, 32) + Control.set_margin(hdr_number, 8, -4, 0, 0) + Control.set_behave(hdr_number, UIBehave.left | UIBehave.top) + Control.child_add(root, hdr_number) + Control.set_events(hdr_number){|event| + if(event.type == UIEvent.change){ + data.hdr_multiplier = event.change + UI.events_emit(data_control, UIEvent.change, data) + } + } + Control.set_events(data_control){|event| + if(event.type == UIEvent.change){ + UINumber.set_value(hdr_number, data.hdr_multiplier) + } + } + + var color_hdr = UIPanel.create(ui) + UIPanel.set_color(color_hdr, data.rgba_ldr) + UIPanel.set_border(color_hdr, 0, Color.clear) + Control.set_size(color_hdr, 64, 32) + Control.set_margin(color_hdr, 8, 4, 8, 0) + Control.set_behave(color_hdr, UIBehave.left | UIBehave.top) + Control.child_add(root, color_hdr) + Control.set_events(data_control){|event| + if(event.type == UIEvent.change){ + var color = data.rgba + color.a = 1 + UIPanel.set_color(color_hdr, color) + } + } + + var maximize_ldr_button = UIButton.create(ui) + UIButton.set_text(maximize_ldr_button, "maximize LDR") + UIButton.set_text_size(maximize_ldr_button, 12) + Control.set_size(maximize_ldr_button, 80, 24) + Control.set_behave(maximize_ldr_button, UIBehave.left | UIBehave.top) + Control.set_margin(maximize_ldr_button, 0, 4, 8, 0) + Control.child_add(root, maximize_ldr_button) + Control.set_events(maximize_ldr_button) {|event| + if(event.type == UIEvent.press){ + if(data.v < 1 && data.v > 0.001){ + var multiplier = data.hdr_multiplier.min(1/data.v).max(1) + data.hdr_multiplier = data.hdr_multiplier / multiplier + data.set_hsva_component(2, data.v * multiplier) + UI.events_emit(data_control, UIEvent.change, data) + } + } + } + + if(!data.allow_hdr){ + Control.set_visible(hdr_header, false) + Control.set_visible(hdr_mult_label, false) + Control.set_visible(hdr_number, false) + Control.set_visible(maximize_ldr_button, false) + Control.set_visible(color_hdr, false) + } + + return root + } static hex_input(ui: UI, data_control: Control){ var data: ColorPickerData = Control.get_state_data(data_control) @@ -207,7 +357,7 @@ class ColorPicker{ Control.child_add(root, label) var text = UIText.create(ui) - UIText.set_text(text, color_to_hex_string(data.rgba, true)) + UIText.set_text(text, color_to_hex_string(data.rgba_ldr, true)) Control.set_size(text, 128, 32) Control.set_behave(text, UIBehave.left) Control.child_add(root, text) @@ -215,7 +365,7 @@ class ColorPicker{ Control.set_events(data_control) {|event| if(event.type == UIEvent.change){ var data: ColorPickerData = event.change - var color = data.rgba + var color = data.rgba_ldr if(data.srgb_hex){ color.r = color.r.pow(1 / 2.2) color.g = color.g.pow(1 / 2.2) @@ -531,7 +681,7 @@ class ColorPicker{ var style: PathStyle = PathStyle.new() var picker_state: ColorPickerData = Control.get_state_data(data_root) - var color = picker_state.rgba + var color = picker_state.rgba_ldr color.a = 1 var hue = picker_state.h var saturation = picker_state.s.pow(1/base_sat_gamma) diff --git a/materials/shaders.emsl b/materials/shaders.emsl index b799f01..1ec5938 100644 --- a/materials/shaders.emsl +++ b/materials/shaders.emsl @@ -22,15 +22,22 @@ input ColorTriangle { 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}) + 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( @@ -102,6 +109,25 @@ stage fragment frag_color_triangle( 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 @@ -117,4 +143,4 @@ float3 hue2rgb(float hue) { float3 rgb = float3(r,g,b); //combine components rgb = clamp(rgb, 0.0, 1.0); //clamp between 0 and 1 return rgb; -} \ No newline at end of file +} diff --git a/materials/transparency_grid.material_basis.lx b/materials/transparency_grid.material_basis.lx new file mode 100644 index 0000000..d8f48da --- /dev/null +++ b/materials/transparency_grid.material_basis.lx @@ -0,0 +1,37 @@ +material_basis = { + vertex_format = "luxe.textured" + shaders = { + vertex = { library="materials/shaders" function="vert" } + fragment = { library="materials/shaders" function="frag_transparency_grid" } + } + depth_test = true + depth_write = true + depth_compare = "less_equal" + stencil_test = false + write_mask = { red=true green=true blue=true alpha=true } + blending = true + alpha_blend = "add" + rgb_blend = "add" + src_alpha = "source_alpha" + src_rgb = "source_alpha" + dest_alpha = "one_minus_source_alpha" + dest_rgb = "one_minus_source_alpha" + blend_color = [0 0 0 0] + cull = "none" + winding = "counter_clockwise" + layers = ["default"] + inputs = { + trans_grid.grid_size = { + type = "float2", + value = [20, 20] + }, + trans_grid.one_color = { + type = "float4", + value = [0.8, 0.8, 0.8, 1], + }, + trans_grid.other_color = { + type = "float4", + value = [1, 1, 1, 1], + } + } +} \ No newline at end of file