Refactor to hand-mode UI and reorganize WGSL shader
Replace spatial force / stats panels with unified hand force panels; simplify app.rs wiring and reorganize shader.wgsl for the hand rendering layout.
This commit is contained in:
60
src/app.rs
60
src/app.rs
@@ -13,7 +13,7 @@ use crate::{
|
||||
},
|
||||
ui::{
|
||||
ConfigPanelState, ConnectPanelState, FloatingPanelState, MatrixConfigState,
|
||||
draw_config_panel, draw_spatial_force_panel, draw_stats_panel, panel_restore_item,
|
||||
draw_config_panel, draw_hand_force_panels, panel_restore_item,
|
||||
},
|
||||
};
|
||||
use eframe::{egui, egui_wgpu};
|
||||
@@ -167,12 +167,7 @@ impl EskinDesktopApp {
|
||||
live_rates: LiveRateMeters::new(),
|
||||
context_menu_open: false,
|
||||
context_menu_pos: egui::pos2(24.0, 48.0),
|
||||
active_mode: ActiveMode::Finger(FingerMode {
|
||||
rows: 12,
|
||||
cols: 7,
|
||||
range: 0..7000,
|
||||
dot: true,
|
||||
}),
|
||||
active_mode: ActiveMode::Hand(HandGatewayMode { range: 0..7000 }),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,7 +185,6 @@ impl EskinDesktopApp {
|
||||
active_mode: self.active_mode.clone(),
|
||||
},
|
||||
));
|
||||
self.paint_spatial_force_overlay(ui, rect);
|
||||
}
|
||||
|
||||
fn paint_spatial_force_overlay(&self, ui: &egui::Ui, rect: egui::Rect) {
|
||||
@@ -223,11 +217,7 @@ impl EskinDesktopApp {
|
||||
}
|
||||
|
||||
fn draw_workspace(&mut self, ui: &mut egui::Ui) {
|
||||
if self.breakout_visible {
|
||||
self.draw_split_workspace(ui);
|
||||
} else {
|
||||
self.draw_wgpu_background_rect(ui, ui.max_rect());
|
||||
}
|
||||
self.draw_wgpu_background_rect(ui, ui.max_rect());
|
||||
}
|
||||
|
||||
fn draw_split_workspace(&mut self, ui: &mut egui::Ui) {
|
||||
@@ -295,9 +285,7 @@ impl EskinDesktopApp {
|
||||
self.signal_history.remove(0);
|
||||
}
|
||||
|
||||
if self.config_state.mode == SerialMode::Hand {
|
||||
update_hand_signal_histories(&mut self.hand_signal_histories, &sample.matrix);
|
||||
}
|
||||
update_hand_signal_histories(&mut self.hand_signal_histories, &sample.matrix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -423,12 +411,6 @@ impl EskinDesktopApp {
|
||||
self.matrix_config_panel.visible = false;
|
||||
self.context_menu_open = false;
|
||||
|
||||
if self.breakout_visible {
|
||||
self.config_panel.visible = false;
|
||||
self.stats_panel.visible = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(next_mode) = draw_config_panel(
|
||||
ctx,
|
||||
&mut self.config_panel,
|
||||
@@ -439,39 +421,11 @@ impl EskinDesktopApp {
|
||||
self.live_rates.sample_rate_hz,
|
||||
self.live_rates.render_rate_hz,
|
||||
) {
|
||||
if next_mode == SerialMode::Hand {
|
||||
self.config_state.mode = SerialMode::Finger;
|
||||
self.connect_state.mode = SerialMode::Finger;
|
||||
self.config_state.baud_rate = SerialMode::Finger.baud_rate();
|
||||
self.active_mode = ActiveMode::Finger(FingerMode {
|
||||
rows: self.matrix_config.rows,
|
||||
cols: self.matrix_config.cols,
|
||||
range: 0..7000,
|
||||
dot: true,
|
||||
});
|
||||
self.breakout_visible = true;
|
||||
} else {
|
||||
self.switch_mode(next_mode);
|
||||
}
|
||||
self.switch_mode(next_mode);
|
||||
}
|
||||
|
||||
if self.config_state.mode == SerialMode::Finger {
|
||||
self.stats_panel.visible = true;
|
||||
draw_stats_panel(
|
||||
ctx,
|
||||
&mut self.stats_panel,
|
||||
&self.signal_history,
|
||||
self.latest_spatial_force,
|
||||
);
|
||||
} else {
|
||||
self.stats_panel.visible = false;
|
||||
}
|
||||
|
||||
if let Some(force) = self.latest_spatial_force {
|
||||
self.spatial_force_panel_force = Some(force);
|
||||
}
|
||||
|
||||
draw_spatial_force_panel(ctx, self.spatial_force_panel_force, &self.signal_history);
|
||||
self.stats_panel.visible = false;
|
||||
draw_hand_force_panels(ctx, true, &self.hand_signal_histories);
|
||||
}
|
||||
|
||||
fn draw_panel_context_menu(&mut self, ctx: &egui::Context) {
|
||||
|
||||
29
src/ui.rs
29
src/ui.rs
@@ -104,10 +104,10 @@ impl Default for ConfigPanelState {
|
||||
.unwrap_or_else(|| "COM3".to_owned());
|
||||
|
||||
Self {
|
||||
mode: SerialMode::Finger,
|
||||
mode: SerialMode::Hand,
|
||||
port,
|
||||
available_ports,
|
||||
baud_rate: 921_600,
|
||||
baud_rate: SerialMode::Hand.baud_rate(),
|
||||
data_bits: 8,
|
||||
stop_bits: 1,
|
||||
parity: Parity::None,
|
||||
@@ -126,7 +126,7 @@ impl Default for ConnectPanelState {
|
||||
let port = serial_enum().unwrap_or_default();
|
||||
let selected_port = port.first().cloned().unwrap_or_default();
|
||||
Self {
|
||||
mode: SerialMode::Finger,
|
||||
mode: SerialMode::Hand,
|
||||
port,
|
||||
selected_port,
|
||||
duration: 10,
|
||||
@@ -499,27 +499,14 @@ pub fn draw_spatial_force_panel(
|
||||
}
|
||||
|
||||
fn draw_mode_row(ui: &mut egui::Ui, config: &mut ConfigPanelState) -> Option<SerialMode> {
|
||||
let mut changed_to = None;
|
||||
config.mode = SerialMode::Hand;
|
||||
config.baud_rate = SerialMode::Hand.baud_rate();
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
ui.colored_label(dim_text(), "模式");
|
||||
ui.colored_label(dim_text(), "Mode");
|
||||
ui.add_space(12.0);
|
||||
|
||||
if mode_button(ui, &mut config.mode, SerialMode::Finger, "指尖模块") {
|
||||
changed_to = Some(SerialMode::Finger)
|
||||
}
|
||||
if mode_button(ui, &mut config.mode, SerialMode::Hand, "游戏体验") {
|
||||
changed_to = Some(SerialMode::Hand)
|
||||
}
|
||||
// mode_button(ui, &mut config.mode, SerialMode::Model, "模型");
|
||||
|
||||
// Legacy reconnect controls. Current sensors run fixed 921600 baud without auto-reconnect UI.
|
||||
// ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
|
||||
// ui.checkbox(&mut config.auto_reconnect, "自动");
|
||||
// ui.colored_label(dim_text(), "重连");
|
||||
// });
|
||||
ui.label(style::panel_title("Hand Gateway"));
|
||||
});
|
||||
|
||||
changed_to
|
||||
None
|
||||
}
|
||||
|
||||
fn draw_connection_row(
|
||||
|
||||
@@ -63,7 +63,7 @@ fn linear_to_srgb(linear: vec3f) -> vec3f {
|
||||
|
||||
fn output_color(linear_rgb: vec3f, alpha: f32) -> vec4f {
|
||||
let clamped = clamp(linear_rgb, vec3f(0.0), vec3f(1.0));
|
||||
if (u.color.w > 0.5) {
|
||||
if u.color.w > 0.5 {
|
||||
return vec4f(clamped, alpha);
|
||||
}
|
||||
|
||||
@@ -91,12 +91,12 @@ fn range_stop_color(index: u32) -> vec3f {
|
||||
fn sample_range_color(value: f32) -> vec3f {
|
||||
let t = saturate(value);
|
||||
|
||||
if (t <= 0.33) {
|
||||
if t <= 0.33 {
|
||||
let local = smoothstep(0.0, 0.33, t);
|
||||
return mix(range_stop_color(0u), range_stop_color(1u), local);
|
||||
}
|
||||
|
||||
if (t <= 0.66) {
|
||||
if t <= 0.66 {
|
||||
let local = smoothstep(0.33, 0.66, t);
|
||||
return mix(range_stop_color(1u), range_stop_color(2u), local);
|
||||
}
|
||||
@@ -105,7 +105,6 @@ fn sample_range_color(value: f32) -> vec3f {
|
||||
return mix(range_stop_color(2u), range_stop_color(3u), local);
|
||||
}
|
||||
|
||||
|
||||
// background
|
||||
struct BackgroundVertexOutput {
|
||||
@builtin(position) clip_position: vec4f,
|
||||
@@ -129,7 +128,6 @@ fn fs_background(@builtin(position) frag_coord: vec4f) -> @location(0) vec4f {
|
||||
return output_color(vec3f(0.0, 0.0, 0.0), 1.0);
|
||||
}
|
||||
|
||||
|
||||
// hand image background
|
||||
struct HandImageVertexOutput {
|
||||
@builtin(position) clip_position: vec4f,
|
||||
@@ -167,7 +165,7 @@ fn fs_hand_image(in: HandImageVertexOutput) -> @location(0) vec4f {
|
||||
let image_aspect = u.image.x / max(u.image.y, 1.0);
|
||||
|
||||
var uv = in.screen_uv;
|
||||
if (viewport_aspect > image_aspect) {
|
||||
if viewport_aspect > image_aspect {
|
||||
let image_width = image_aspect / viewport_aspect;
|
||||
uv.x = (uv.x - (1.0 - image_width) * 0.5) / image_width;
|
||||
} else {
|
||||
@@ -175,7 +173,7 @@ fn fs_hand_image(in: HandImageVertexOutput) -> @location(0) vec4f {
|
||||
uv.y = (uv.y - (1.0 - image_height) * 0.5) / image_height;
|
||||
}
|
||||
|
||||
if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) {
|
||||
if uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0 {
|
||||
discard;
|
||||
}
|
||||
|
||||
@@ -183,7 +181,6 @@ fn fs_hand_image(in: HandImageVertexOutput) -> @location(0) vec4f {
|
||||
return output_color(color.rgb, color.a);
|
||||
}
|
||||
|
||||
|
||||
// glyph
|
||||
struct GlyphVertexInput {
|
||||
@location(0) local: vec2f,
|
||||
@@ -226,45 +223,45 @@ fn digit_segment_on(digit: u32, segment: u32) -> bool {
|
||||
|
||||
fn seven_segment_digit_alpha(local: vec2f, digit: u32) -> f32 {
|
||||
var alpha = 0.0;
|
||||
if (digit_segment_on(digit, 0u)) {
|
||||
if digit_segment_on(digit, 0u) {
|
||||
alpha = max(alpha, rect_alpha(local, vec2f(0.0, 0.70), vec2f(0.38, 0.078)));
|
||||
}
|
||||
if (digit_segment_on(digit, 1u)) {
|
||||
if digit_segment_on(digit, 1u) {
|
||||
alpha = max(alpha, rect_alpha(local, vec2f(0.39, 0.36), vec2f(0.078, 0.335)));
|
||||
}
|
||||
if (digit_segment_on(digit, 2u)) {
|
||||
if digit_segment_on(digit, 2u) {
|
||||
alpha = max(alpha, rect_alpha(local, vec2f(0.39, -0.36), vec2f(0.078, 0.335)));
|
||||
}
|
||||
if (digit_segment_on(digit, 3u)) {
|
||||
if digit_segment_on(digit, 3u) {
|
||||
alpha = max(alpha, rect_alpha(local, vec2f(0.0, -0.70), vec2f(0.38, 0.078)));
|
||||
}
|
||||
if (digit_segment_on(digit, 4u)) {
|
||||
if digit_segment_on(digit, 4u) {
|
||||
alpha = max(alpha, rect_alpha(local, vec2f(-0.39, -0.36), vec2f(0.078, 0.335)));
|
||||
}
|
||||
if (digit_segment_on(digit, 5u)) {
|
||||
if digit_segment_on(digit, 5u) {
|
||||
alpha = max(alpha, rect_alpha(local, vec2f(-0.39, 0.36), vec2f(0.078, 0.335)));
|
||||
}
|
||||
if (digit_segment_on(digit, 6u)) {
|
||||
if digit_segment_on(digit, 6u) {
|
||||
alpha = max(alpha, rect_alpha(local, vec2f(0.0, 0.0), vec2f(0.35, 0.075)));
|
||||
}
|
||||
return alpha;
|
||||
}
|
||||
|
||||
fn digit_count(value: u32) -> u32 {
|
||||
if (value >= 1000u) {
|
||||
if value >= 1000u {
|
||||
return 4u;
|
||||
}
|
||||
if (value >= 100u) {
|
||||
if value >= 100u {
|
||||
return 3u;
|
||||
}
|
||||
if (value >= 10u) {
|
||||
if value >= 10u {
|
||||
return 2u;
|
||||
}
|
||||
return 1u;
|
||||
}
|
||||
|
||||
fn digit_at(value: u32, slot: u32, count: u32) -> u32 {
|
||||
if (count == 4u) {
|
||||
if count == 4u {
|
||||
switch slot {
|
||||
case 0u: { return (value / 1000u) % 10u; }
|
||||
case 1u: { return (value / 100u) % 10u; }
|
||||
@@ -272,14 +269,14 @@ fn digit_at(value: u32, slot: u32, count: u32) -> u32 {
|
||||
default: { return value % 10u; }
|
||||
}
|
||||
}
|
||||
if (count == 3u) {
|
||||
if count == 3u {
|
||||
switch slot {
|
||||
case 0u: { return (value / 100u) % 10u; }
|
||||
case 1u: { return (value / 10u) % 10u; }
|
||||
default: { return value % 10u; }
|
||||
}
|
||||
}
|
||||
if (count == 2u) {
|
||||
if count == 2u {
|
||||
return select(value % 10u, (value / 10u) % 10u, slot == 0u);
|
||||
}
|
||||
return value % 10u;
|
||||
@@ -294,7 +291,7 @@ fn number_alpha(local: vec2f, display_value: f32) -> f32 {
|
||||
var alpha = 0.0;
|
||||
|
||||
for (var slot = 0u; slot < 4u; slot = slot + 1u) {
|
||||
if (slot < count) {
|
||||
if slot < count {
|
||||
let center_x = start_x + f32(slot) * slot_width;
|
||||
let digit_local = vec2f((local.x - center_x) / (slot_width * 0.78), local.y / 0.92);
|
||||
let digit = digit_at(value, slot, count);
|
||||
@@ -335,8 +332,7 @@ struct DotVertexInput {
|
||||
|
||||
struct DotInstanceInput {
|
||||
@location(1) world_position: vec4f,
|
||||
@location(2) style: vec4f
|
||||
}
|
||||
@location(2) style: vec4f}
|
||||
|
||||
struct DotVertexOutput {
|
||||
@builtin(position) clip_position: vec4f,
|
||||
@@ -358,7 +354,7 @@ fn hand_image_uv_to_clip(image_uv: vec2f) -> vec2f {
|
||||
|
||||
var screen_uv = image_uv;
|
||||
|
||||
if (viewport_aspect > image_aspect) {
|
||||
if viewport_aspect > image_aspect {
|
||||
let image_width = image_aspect / viewport_aspect;
|
||||
screen_uv.x = image_uv.x * image_width + (1.0 - image_width) * 0.5;
|
||||
} else {
|
||||
@@ -390,8 +386,6 @@ fn fingertip_film_alpha(
|
||||
local: vec2f,
|
||||
half_width: f32,
|
||||
cap_center_y: f32,
|
||||
rear_edge_y: f32,
|
||||
rear_bulge: f32,
|
||||
softness: f32,
|
||||
) -> f32 {
|
||||
// Top/front of the film is a closed round fingertip cap.
|
||||
@@ -399,14 +393,10 @@ fn fingertip_film_alpha(
|
||||
let cap = (1.0 - smoothstep(half_width, half_width + softness, cap_dist))
|
||||
* (1.0 - smoothstep(cap_center_y - softness, cap_center_y + softness, local.y));
|
||||
|
||||
// The rear half keeps nearly parallel sides and ends with a shallow arc;
|
||||
// it deliberately does not converge back into another capsule end.
|
||||
let x_norm = clamp(abs(local.x) / max(half_width, 0.001), 0.0, 1.0);
|
||||
let rear_curve_y = rear_edge_y + rear_bulge * (1.0 - x_norm * x_norm);
|
||||
// The rear remains open; the carrier quad clips the membrane at its end.
|
||||
let side = 1.0 - smoothstep(half_width, half_width + softness, abs(local.x));
|
||||
let rear = 1.0 - smoothstep(rear_curve_y, rear_curve_y + softness, local.y);
|
||||
let body_gate = smoothstep(cap_center_y - softness, cap_center_y + softness, local.y);
|
||||
let body = side * rear * body_gate;
|
||||
let body = side * body_gate;
|
||||
|
||||
return max(cap, body);
|
||||
}
|
||||
@@ -427,38 +417,77 @@ fn vs_hand_membrane(vertex: DotVertexInput, instance: DotInstanceInput) -> HandM
|
||||
|
||||
@fragment
|
||||
fn fs_hand_membrane(in: HandMembraneVertexOutput) -> @location(0) vec4f {
|
||||
// The film shape matches the fingertip: closed round front, parallel rear sides,
|
||||
// and a shallow rear arc instead of a second capsule end.
|
||||
let panel = fingertip_film_alpha(in.local, 0.66, -0.38, 0.72, 0.18, 0.045);
|
||||
let inner = fingertip_film_alpha(in.local, 0.54, -0.36, 0.64, 0.12, 0.060);
|
||||
let border = clamp(panel - inner * 0.52, 0.0, 1.0);
|
||||
let p = in.local;
|
||||
|
||||
// Dense mesh: the live 12x7 pressure dots sit over this finer sensor lattice.
|
||||
let uv = clamp(in.local * 0.5 + vec2f(0.5, 0.5), vec2f(0.0, 0.0), vec2f(1.0, 1.0));
|
||||
let grid = vec2f(18.0, 34.0);
|
||||
let cell = uv * grid - vec2f(0.5, 0.5);
|
||||
let nearest = abs(fract(cell + vec2f(0.5, 0.5)) - vec2f(0.5, 0.5));
|
||||
let grid_line = max(
|
||||
1.0 - smoothstep(0.014, 0.038, nearest.x),
|
||||
1.0 - smoothstep(0.014, 0.038, nearest.y),
|
||||
let halo_shape = fingertip_film_alpha(p, 0.72, -0.39, 0.060);
|
||||
let panel = fingertip_film_alpha(p, 0.66, -0.38, 0.040);
|
||||
let rim_inner = fingertip_film_alpha(p, 0.60, -0.36, 0.040);
|
||||
let clear_inner = fingertip_film_alpha(p, 0.49, -0.31, 0.180);
|
||||
|
||||
let halo = clamp(halo_shape - panel, 0.0, 1.0);
|
||||
let border = clamp(panel - rim_inner, 0.0, 1.0);
|
||||
let edge_fade = pow(clamp(1.0 - clear_inner, 0.0, 1.0), 1.15) * panel;
|
||||
|
||||
// Micro lattice.
|
||||
let uv = clamp(
|
||||
p * vec2f(0.52, 0.46) + vec2f(0.5, 0.46),
|
||||
vec2f(0.0, 0.0),
|
||||
vec2f(1.0, 1.0),
|
||||
);
|
||||
let joint = 1.0 - smoothstep(0.070, 0.150, length(nearest * vec2f(1.18, 1.0)));
|
||||
let center_shadow = 1.0 - smoothstep(0.10, 0.76, length(in.local * vec2f(0.92, 0.66)));
|
||||
|
||||
let top_light = smoothstep(-0.52, 0.16, -in.local.y) * 0.20;
|
||||
let side_glow = smoothstep(0.30, 0.70, abs(in.local.x)) * 0.26;
|
||||
let lift_shadow = smoothstep(0.48, 0.86, in.local.y) * (1.0 - smoothstep(0.50, 0.86, abs(in.local.x))) * 0.13;
|
||||
let scan = (0.5 + 0.5 * sin((uv.y * 76.0 + uv.x * 9.0) * 6.28318)) * 0.030;
|
||||
let grid = vec2f(18.0, 34.0);
|
||||
let cell_uv = fract(uv * grid) - vec2f(0.5, 0.5);
|
||||
|
||||
let membrane_color = vec3f(0.006, 0.28, 0.38);
|
||||
let line_color = vec3f(0.12, 0.72, 0.88);
|
||||
let rim_color = vec3f(0.18, 0.98, 1.0);
|
||||
let color = membrane_color * (0.68 + top_light + side_glow + scan)
|
||||
+ line_color * (grid_line * 0.20 + joint * 0.42)
|
||||
+ rim_color * (border * 0.92 + side_glow * 0.18)
|
||||
- vec3f(0.0, 0.16, 0.24) * center_shadow * 0.30
|
||||
- vec3f(0.0, 0.10, 0.16) * lift_shadow;
|
||||
let alpha = panel * (0.24 + grid_line * 0.10 + joint * 0.23 + border * 0.42);
|
||||
let node = 1.0 - smoothstep(
|
||||
0.070,
|
||||
0.165,
|
||||
length(cell_uv * vec2f(1.0, 1.08)),
|
||||
);
|
||||
|
||||
let mesh_x = smoothstep(0.455, 0.495, abs(cell_uv.x));
|
||||
let mesh_y = smoothstep(0.455, 0.495, abs(cell_uv.y));
|
||||
let mesh = max(mesh_x, mesh_y);
|
||||
let lattice = (node * 0.90 + mesh * 0.10) * rim_inner;
|
||||
|
||||
// Blue glass highlights.
|
||||
let side_glow = smoothstep(0.28, 0.66, abs(p.x)) * panel;
|
||||
let top_light = smoothstep(0.10, 0.78, -p.y) * panel;
|
||||
|
||||
let sheen_axis = p.x * 0.88 + p.y * 0.22 + 0.16;
|
||||
let sheen = (1.0 - smoothstep(0.0, 0.11, abs(sheen_axis))) * panel;
|
||||
let scan = (0.5 + 0.5 * sin((uv.y * 76.0 + uv.x * 9.0) * 6.28318)) * 0.025;
|
||||
|
||||
// Temporary synthetic pressure hotspot. Real hand pressure dots are drawn above this pass.
|
||||
let pressure_center = vec2f(-0.10, -0.15);
|
||||
let pressure_dist = length((p - pressure_center) * vec2f(1.0, 0.72));
|
||||
let pressure = (1.0 - smoothstep(0.04, 0.37, pressure_dist)) * rim_inner;
|
||||
let pressure_hot = (1.0 - smoothstep(0.015, 0.13, pressure_dist)) * rim_inner;
|
||||
|
||||
let membrane_color = vec3f(0.006, 0.028, 0.110);
|
||||
let inner_cyanblue = vec3f(0.012, 0.110, 0.320);
|
||||
let lattice_color = vec3f(0.040, 0.420, 0.760);
|
||||
let rim_color = vec3f(0.120, 0.720, 0.950);
|
||||
|
||||
let pressure_green = vec3f(0.00, 0.66, 0.22);
|
||||
let pressure_lime = vec3f(0.18, 1.00, 0.50);
|
||||
|
||||
let color = membrane_color * panel * (0.36 + top_light * 0.08 + scan)
|
||||
+ inner_cyanblue * edge_fade * 0.72
|
||||
+ lattice_color * lattice * 0.66
|
||||
+ rim_color * (border * 0.90 + edge_fade * 0.16 + halo * 0.16 + side_glow * 0.08 + sheen * 0.10)
|
||||
+ pressure_green * pressure * 0.70
|
||||
+ pressure_lime * pressure_hot * 0.82;
|
||||
|
||||
let alpha = clamp(
|
||||
panel * 0.08
|
||||
+ edge_fade * 0.43
|
||||
+ border * 0.20
|
||||
+ halo * 0.04
|
||||
+ lattice * 0.055
|
||||
+ pressure * 0.05,
|
||||
0.0,
|
||||
0.78,
|
||||
);
|
||||
|
||||
return output_color(color, alpha);
|
||||
}
|
||||
@@ -621,7 +650,6 @@ fn fs_dot(in: DotVertexOutput) -> @location(0) vec4f {
|
||||
return output_color(color, alpha);
|
||||
}
|
||||
|
||||
|
||||
// model
|
||||
struct ModelVertexInput {
|
||||
@location(0) position: vec3f,
|
||||
@@ -740,11 +768,11 @@ fn aces_tonemap(x: vec3f) -> vec3f {
|
||||
|
||||
fn material_normal(in: ModelVertexOutput, front_facing: bool) -> vec3f {
|
||||
var n = normalize(in.world_normal);
|
||||
if (!front_facing && material.flags.w > 0.5) {
|
||||
if !front_facing && material.flags.w > 0.5 {
|
||||
n = -n;
|
||||
}
|
||||
|
||||
if (material.flags.z < 0.5) {
|
||||
if material.flags.z < 0.5 {
|
||||
return n;
|
||||
}
|
||||
|
||||
@@ -764,17 +792,17 @@ fn fs_model(in: ModelVertexOutput, @builtin(front_facing) front_facing: bool) ->
|
||||
let base_color = base_sample * material.base_color * in.color;
|
||||
let alpha_mode = material.emissive_alpha.w;
|
||||
var alpha = base_color.a;
|
||||
if (alpha_mode < 0.5) {
|
||||
if alpha_mode < 0.5 {
|
||||
alpha = 1.0;
|
||||
} else if (alpha_mode < 1.5) {
|
||||
if (alpha < material.flags.x) {
|
||||
} else if alpha_mode < 1.5 {
|
||||
if alpha < material.flags.x {
|
||||
discard;
|
||||
}
|
||||
alpha = 1.0;
|
||||
}
|
||||
|
||||
let debug_mode = u32(u.render_options.x + 0.5);
|
||||
if (debug_mode == 1u) {
|
||||
if debug_mode == 1u {
|
||||
return output_color(base_color.rgb, alpha);
|
||||
}
|
||||
|
||||
@@ -840,7 +868,7 @@ fn fs_model(in: ModelVertexOutput, @builtin(front_facing) front_facing: bool) ->
|
||||
let ambient_strength = 0.08;
|
||||
// Temporary neutral linear ambient term until a real IBL/HDR environment is added.
|
||||
var ambient = vec3f(0.0);
|
||||
if (u.render_options.y > 0.5) {
|
||||
if u.render_options.y > 0.5 {
|
||||
let ambient_diffuse = albedo * (1.0 - metallic) * ambient_color * ambient_strength;
|
||||
let ambient_specular = f_ambient * ambient_color * ambient_strength * (1.0 - roughness * 0.55);
|
||||
ambient = (ambient_diffuse + ambient_specular) * ao;
|
||||
@@ -848,7 +876,7 @@ fn fs_model(in: ModelVertexOutput, @builtin(front_facing) front_facing: bool) ->
|
||||
|
||||
let exposed_color = (ambient + key + fill + emissive) * max(u.render_options.w, 0.0);
|
||||
var color = exposed_color;
|
||||
if (u.render_options.z > 0.5) {
|
||||
if u.render_options.z > 0.5 {
|
||||
color = aces_tonemap(exposed_color);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user