Skip to content

Commit

Permalink
simple UI improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
altunenes committed May 23, 2024
1 parent 8b7eae1 commit 8b8a0c9
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 85 deletions.
8 changes: 4 additions & 4 deletions shaders/expmandelbrotgpu.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ fn implicit(c: vec2<f32>, time: f32) -> vec2<f32> {
z.y = 2.0 * z.x * z.y + c.y;
z.x = xnew;

let dampenedTime: f32 = time / params.tt;
let dampenedTime: f32 = time;
z += 0.1 * vec2<f32>(sin(0.001 * dampenedTime), cos(0.001 * dampenedTime));

if (dot(z, z) > BOUND / 1.2) {
Expand All @@ -55,15 +55,15 @@ fn main(@builtin(position) FragCoord: vec4<f32>) -> @location(0) vec4<f32> {
var BOUND: f32 = params.bound;
var col: vec3<f32> = vec3<f32>(0.0, 0.0, 0.0);
let pan: vec2<f32> = vec2<f32>(params.theta, params.alpha);
let zoomLevel: f32 = osc(params.lambda, params.lambda, 20.0, u_time.time / params.tt);
let zoomLevel: f32 = osc(params.lambda, params.lambda, 20.0, u_time.time * params.tt);
let AA: i32 = i32(params.aa);
let camSpeed: vec2<f32> = vec2<f32>(0.0002, 0.0002);
let camPath: vec2<f32> = vec2<f32>(sin(camSpeed.x * u_time.time / params.tt), cos(camSpeed.y * u_time.time / params.tt));
let camPath: vec2<f32> = vec2<f32>(sin(camSpeed.x), cos(camSpeed.y));
let resolution: vec2<f32> = vec2<f32>(1920.0, 1080.0);
for (var m: i32 = 0; m < AA; m = m + 1) {
for (var n: i32 = 0; n < AA; n = n + 1) {
let uv: vec2<f32> = ((FragCoord.xy + vec2<f32>(f32(m), f32(n)) / f32(AA) - 0.5 * resolution) / min(resolution.y, resolution.x) * zoomLevel + pan + camPath) * 2.033 - vec2<f32>(2.14278);
let z_and_i: vec2<f32> = implicit(uv, u_time.time);
let z_and_i: vec2<f32> = implicit(uv, u_time.time* params.tt);
let iter_ratio: f32 = z_and_i.x / f32(MAX_ITER);
let lenSq: f32 = z_and_i.y;
let exteriorColor: vec3<f32> = params.a + params.b * sin(params.c + vec3<f32>(params.sigma, params.gamma, params.blue) + params.g*PI * vec3<f32>(params.d* iter_ratio) + u_time.time / params.e);
Expand Down
97 changes: 44 additions & 53 deletions shaders/mandelbulb.wgsl
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
const PI: f32 = 3.141592653589793;
const MAX_STEPS: i32 = 150;
const MAX_STEPS: i32 = 250;
const SURFACE_DIST: f32 = 0.001;
const MAX_DIST: f32 = 255.0;
const MAX_DIST: f32 = 150.0;
const BAILOUT: f32 = 4.0;
const POWER: f32 = 8.0;
const AMBIENT: f32 = 0.1;
const SPECULAR_COEFF: f32 = 1.1;
const SHININESS: f32 = 1.0;
const SPECULAR_COEFF: f32 = 0.5;
const SHININESS: f32 = 0.5;
const EPS: vec3<f32> = vec3<f32>(0.001, 0.001, 0.001);
fn applyGamma(color: vec3<f32>, gamma: f32) -> vec3<f32> {
return pow(color, vec3<f32>(1.0 / gamma, 1.0 / gamma, 1.0 / gamma));
}

struct TimeUniform {
time: f32,
};
Expand Down Expand Up @@ -52,7 +49,7 @@ fn osc(minValue: f32, maxValue: f32, interval: f32, pauseDuration: f32, currentT
}
}
fn mandelbulb(pos: vec3<f32>, u_time: TimeUniform) -> f32 {
let dynamicPower: f32 = osc(params.iter, params.iter, 20.0, 5.0, u_time.time);
let power_osc: f32 = osc(params.iter, params.iter, 20.0, 5.0, u_time.time);
var z: vec3<f32> = pos;
var dr: f32 = 1.0;
var r: f32 = 0.0;
Expand All @@ -66,13 +63,13 @@ fn mandelbulb(pos: vec3<f32>, u_time: TimeUniform) -> f32 {
let phi: f32 = atan2(z.y, z.x);

if (r < 1.0) {
dr = pow(r, dynamicPower - 1.0) * dynamicPower * dr + influence * 0.5;
dr = pow(r, power_osc - 1.0) * power_osc * dr + influence * 0.5;
} else {
dr = pow(r, dynamicPower - 1.0) * dynamicPower * dr + influence;
dr = pow(r, power_osc - 1.0) * power_osc * dr + influence;
}
let zr: f32 = pow(r, dynamicPower);
let newTheta: f32 = theta * dynamicPower;
let newPhi: f32 = phi * dynamicPower;
let zr: f32 = pow(r, power_osc);
let newTheta: f32 = theta * power_osc;
let newPhi: f32 = phi * power_osc;

z = zr * vec3<f32>(sin(newTheta) * cos(newPhi), sin(newPhi) * sin(newTheta), cos(newTheta));
z += pos;
Expand All @@ -91,41 +88,33 @@ fn normal(p: vec3<f32>, u_time: TimeUniform) -> vec3<f32> {
);
return normalize(n);
}
fn curvatureColor(normal: vec3<f32>, pos: vec3<f32>, u_time: TimeUniform) -> vec3<f32> {
let eps: f32 = osc(0.0001, 0.0001, 5.0, 0.0, u_time.time);
let n1 = normal(pos + vec3<f32>(eps, 0.0, 0.0), u_time);
let n2 = normal(pos - vec3<f32>(eps, 0.0, 0.0), u_time);
let curvature: f32 = length(n1 - n2) / (2.0 * eps);
return mix(vec3<f32>(0.5, 0.4, 0.3), vec3<f32>(1.0, 1.0, 0.8), curvature);
}
fn getBackground(uv: vec2<f32>) -> vec3<f32> {
let topColor: vec3<f32> = vec3<f32>(1.0, 0.9, 0.8);
let bottomColor: vec3<f32> = vec3<f32>(0.2, 0.1, 0.0);
return mix(bottomColor, topColor, pow(uv.y * 0.5 + 0.5, 0.5));

fn bg(uv: vec2<f32>) -> vec3<f32> {
let top: vec3<f32> = vec3<f32>(1.0, 0.9, 0.8);
let bot: vec3<f32> = vec3<f32>(0.9, 0.1, 0.0);
return mix(bot, top, pow(uv.y * 0.5 + 0.5, 0.5));
}

fn colorize(pos: vec3<f32>, normal: vec3<f32>, dist: f32, viewDir: vec3<f32>, lightDir: vec3<f32>) -> vec3<f32> {
let lightTone: vec3<f32> = vec3<f32>(params.lambda, params.theta, params.alpha);
let middleTone: vec3<f32> = vec3<f32>(params.sigma, params.gamma, params.blue);
let darkTone: vec3<f32> = vec3<f32>(params.a, params.b, params.c);

let first: vec3<f32> = vec3<f32>(params.lambda, params.theta, params.alpha);
let mid: vec3<f32> = vec3<f32>(params.sigma, params.gamma, params.blue);
let end: vec3<f32> = vec3<f32>(params.a, params.b, params.c);
let fresnel: f32 = pow(1.0 - max(dot(normal, viewDir), 0.0), 2.0);
let fresnelColor: vec3<f32> = mix(lightTone, darkTone, fresnel);

let fresnelc: vec3<f32> = mix(first, end, fresnel);
let depthHue: f32 = 0.5 + 0.5 * sin(dist * 1.1 + dot(normal, lightDir) * 0.5);
let depthColor: vec3<f32> = mix(middleTone, darkTone, depthHue);
let depth: vec3<f32> = mix(mid, end, depthHue);

let hueShift: f32 = atan2(pos.y, pos.x) * 0.015;
let colorShift: vec3<f32> = vec3<f32>(sin(hueShift + 1.57), cos(hueShift + 1.57), sin(hueShift - 1.57));
let vibrantColor: vec3<f32> = vec3<f32>(0.7, 0.8, 0.1) + 0.1 * colorShift;
let hShif: f32 = atan2(pos.y, pos.x) * 0.15;
let shift: vec3<f32> = vec3<f32>(sin(hShif + 1.57), cos(hShif + 1.57), sin(hShif - 1.57));
let vC: vec3<f32> = vec3<f32>(0.7, 1.0, 0.5) + 0.2 * shift;

let branchFactor: f32 = length(pos) % 5.0;
let branchColor: vec3<f32> = vec3<f32>(params.d, params.e, params.f) * (0.3 + 0.45 * sin(branchFactor * 12.283185));
let bran: f32 = length(pos) % 1.0;
let branC: vec3<f32> = vec3<f32>(params.d, params.e, params.f) * (0.5 + 0.5 * sin(bran * 12.283185));

var combinedColor: vec3<f32> = mix(fresnelColor, depthColor, 0.1);
combinedColor = mix(combinedColor, vibrantColor, 0.3);
var combo: vec3<f32> = mix(fresnelc, depth, 0.5);
combo = mix(combo, vC, 0.1);

return mix(combinedColor, branchColor, 0.5 + 0.5 * sin(branchFactor * 3.14159265));
return mix(combo, branC, 0.5 + 1.0 * sin(bran * 3.14159265));
}

fn rotateZ(p: vec3<f32>, a: f32) -> vec3<f32> {
Expand All @@ -140,15 +129,15 @@ fn rotateY(p: vec3<f32>, a: f32) -> vec3<f32> {
}


fn calculateLighting(n: vec3<f32>, lightDir: vec3<f32>, viewDir: vec3<f32>, reflectDir: vec3<f32>, u_time: TimeUniform) -> vec3<f32> {
fn light(n: vec3<f32>, lightDir: vec3<f32>, viewDir: vec3<f32>, reflectDir: vec3<f32>, u_time: TimeUniform) -> vec3<f32> {
var diff: f32 = max(dot(n, lightDir), 0.2);
let spec: f32 = pow(max(dot(viewDir, reflectDir), 0.0), SHININESS);
let shadow: f32 = smoothstep(0.3, 1.0, diff);
diff *= shadow;
let POWER2: f32 = osc(params.g, params.g, 10.0, 3.0, u_time.time);
return vec3<f32>(POWER2) + diff + SPECULAR_COEFF * spec;
}
fn dynamicRayMarch(ro: vec3<f32>, rd: vec3<f32>, minDist: f32, maxDist: f32, u_time: TimeUniform) -> f32 {
fn MARCH(ro: vec3<f32>, rd: vec3<f32>, minDist: f32, maxDist: f32, u_time: TimeUniform) -> f32 {
var depth: f32 = 0.0;
for (var i: i32 = 0; i < MAX_STEPS; i = i + 1) {
let pos: vec3<f32> = ro + rd * depth;
Expand All @@ -163,13 +152,16 @@ fn dynamicRayMarch(ro: vec3<f32>, rd: vec3<f32>, minDist: f32, maxDist: f32, u_t
}
return maxDist;
}
fn sharpenEffect(color: vec3<f32>, neighbor1: vec3<f32>, neighbor2: vec3<f32>) -> vec3<f32> {
fn Sharp(color: vec3<f32>, neighbor1: vec3<f32>, neighbor2: vec3<f32>) -> vec3<f32> {
return color + 0.1 * (color - (neighbor1 + neighbor2) * 0.5);
}

fn toneMapping(color: vec3<f32>) -> vec3<f32> {
fn tone(color: vec3<f32>) -> vec3<f32> {
return color / (color + vec3<f32>(1.0));
}
fn applyGamma(color: vec3<f32>, gamma: f32) -> vec3<f32> {
return pow(color, vec3<f32>(1.0 / gamma, 1.0 / gamma, 1.0 / gamma));
}
@fragment
fn main(@builtin(position) FragCoord: vec4<f32>) -> @location(0) vec4<f32> {
let AA_LEVEL: i32 = i32(params.aa);
Expand All @@ -178,25 +170,24 @@ fn main(@builtin(position) FragCoord: vec4<f32>) -> @location(0) vec4<f32> {
var finalColor: vec3<f32> = vec3<f32>(0.0);
var accumm: vec3<f32> = vec3<f32>(0.0);
var neighbor: i32 = 0;
let totalSamples: f32 = f32(AA_LEVEL * AA_LEVEL);
let backgroundColor: vec3<f32> = getBackground(uv);
let power: f32 = osc2(-3.0, -5.0, 25.0, u_time.time);
let backgroundColor: vec3<f32> = bg(uv);
let cameraaaa: f32 = osc2(-3.0, -5.0, 25.0, u_time.time);
for (var i: i32 = 0; i < AA_LEVEL; i = i + 1) {
for (var j: i32 = 0; j < AA_LEVEL; j = j + 1) {
let sampleUV: vec2<f32> = uv + (vec2<f32>(f32(i), f32(j)) - 0.5 * vec2<f32>(f32(AA_LEVEL) - 1.0)) / vec2<f32>(resolution.y, resolution.y) / f32(AA_LEVEL);
let camPos: vec3<f32> = rotateY(vec3<f32>(0.0, 0.0, power), u_time.time * 0.25);
let camPos: vec3<f32> = rotateY(vec3<f32>(0.0, 0.0, cameraaaa), u_time.time * 0.25);
var rayDir: vec3<f32> = normalize(vec3<f32>(sampleUV, 2.0));
rayDir = rotateZ(rayDir, sin(u_time.time * 0.25) * 1.5);
rayDir = rotateY(rayDir, u_time.time * 0.25);
let totalDist: f32 = dynamicRayMarch(camPos, rayDir, SURFACE_DIST, MAX_DIST,u_time);
let totalDist: f32 = MARCH(camPos, rayDir, SURFACE_DIST, MAX_DIST,u_time);
if (totalDist < MAX_DIST) {
let p: vec3<f32> = camPos + totalDist * rayDir;
let n: vec3<f32> = normal(p,u_time);
let lightDir: vec3<f32> = normalize(vec3<f32>(0.5, 1.0, -0.5));
let viewDir: vec3<f32> = normalize(-rayDir);
let reflectDir: vec3<f32> = reflect(-lightDir, n);
let color: vec3<f32> = colorize(p, n, totalDist, viewDir, lightDir);
let lightEffect: vec3<f32> = calculateLighting(n, lightDir, viewDir, reflectDir,u_time);
let lightEffect: vec3<f32> = light(n, lightDir, viewDir, reflectDir,u_time);
finalColor += color * lightEffect;
accumm += color;
neighbor += 1;
Expand All @@ -207,9 +198,9 @@ fn main(@builtin(position) FragCoord: vec4<f32>) -> @location(0) vec4<f32> {
}

if (neighbor > 1) {
finalColor = sharpenEffect(finalColor, accumm / f32(neighbor), finalColor / f32(neighbor));
finalColor = Sharp(finalColor, accumm / f32(neighbor), finalColor / f32(neighbor));
}
finalColor = toneMapping(finalColor);
finalColor = applyGamma(finalColor, 0.5);
finalColor = tone(finalColor);
finalColor = applyGamma(finalColor, 0.5);
return vec4<f32>(finalColor, 1.0);
}
102 changes: 91 additions & 11 deletions src/expmandelbrotgpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,19 +49,65 @@ fn main() {
.run();
}
fn update(app: &App, model: &mut Model, update: Update) {
static mut REVERSE_COLORS: bool = false;

let egui = &mut model.egui;
egui.set_elapsed_time(update.since_start);
let ctx = egui.begin_frame();
if app.keys.down.contains(&Key::H) {
model.settings.show_ui = !model.settings.show_ui;
}
egui::Window::new("Shader Settings").show(&ctx, |ui| {
ui.add(egui::Slider::new(&mut model.settings.lambda, 0.00001..=2.0).text("l"));
ui.add(egui::Slider::new(&mut model.settings.theta, 0.0..=1.5).text("t"));
ui.add(egui::Slider::new(&mut model.settings.alpha, -0.5..=0.5).text("a"));
ui.add(egui::Slider::new(&mut model.settings.sigma, 0.0..=2.0).text("r"));
ui.add(egui::Slider::new(&mut model.settings.gamma, -1.0..=2.0).text("g"));
ui.add(egui::Slider::new(&mut model.settings.blue, 0.0..=2.0).text("b"));
ui.horizontal(|ui| {
ui.add(egui::Slider::new(&mut model.settings.lambda, 0.00001..=2.0).text("zoom"));
if ui.button("-").clicked() {
model.settings.lambda -= 0.00001;
if model.settings.lambda < 0.00001 {
model.settings.lambda = 0.00001;
}
}
if ui.button("+").clicked() {
model.settings.lambda += 0.00001;
if model.settings.lambda > 2.0 {
model.settings.lambda = 2.0;
}
}
});

ui.horizontal(|ui| {
ui.add(egui::Slider::new(&mut model.settings.theta, 0.0..=1.5).text("x_axis"));
if ui.button("-").clicked() {
model.settings.theta -= 0.0001;
if model.settings.theta < 0.0 {
model.settings.theta = 0.0;
}
}
if ui.button("+").clicked() {
model.settings.theta += 0.0001;
if model.settings.theta > 1.5 {
model.settings.theta = 1.5;
}
}
});

ui.horizontal(|ui| {
ui.add(egui::Slider::new(&mut model.settings.alpha, -0.5..=0.5).text("y_axis"));
if ui.button("-").clicked() {
model.settings.alpha -= 0.0001;
if model.settings.alpha < -0.5 {
model.settings.alpha = -0.5;
}
}
if ui.button("+").clicked() {
model.settings.alpha += 0.0001;
if model.settings.alpha > 0.5 {
model.settings.alpha = 0.5;
}
}
});
ui.add(egui::Slider::new(&mut model.settings.sigma, 0.0..=4.0).text("R"));
ui.add(egui::Slider::new(&mut model.settings.gamma, 0.0..=4.0).text("G"));
ui.add(egui::Slider::new(&mut model.settings.blue, 0.0..=4.0).text("B"));
ui.add(egui::Slider::new(&mut model.settings.a, -10.0..=10.5).text("e1"));
ui.add(egui::Slider::new(&mut model.settings.b, -10.0..=10.5).text("e2"));
ui.add(egui::Slider::new(&mut model.settings.c, -10.0..=10.0).text("e3"));
Expand All @@ -71,10 +117,44 @@ fn update(app: &App, model: &mut Model, update: Update) {
ui.add(egui::Slider::new(&mut model.settings.f, 0.002..=3.0).text("c2"));
ui.add(egui::Slider::new(&mut model.settings.iter, 1.0..=2000.0).text("iter"));
ui.add(egui::Slider::new(&mut model.settings.bound, 1.0..=2000.0).text("bound"));
ui.add(egui::Slider::new(&mut model.settings.aa, 0.0..=10.0).text("AA"));
ui.add(egui::Slider::new(&mut model.settings.tt, 1.0..=250.0).text("speed"));
ui.add(egui::Slider::new(&mut model.settings.aa, 0.0..=10.0).text("smart AA"));
ui.add(egui::Slider::new(&mut model.settings.tt, 0.0..=1.0).text("time"));
if ui.button("alternative view").clicked() {
unsafe {
REVERSE_COLORS = !REVERSE_COLORS;
if REVERSE_COLORS {
model.settings.iter = 350.0;
model.settings.bound = 50.0;
model.settings.a = -0.5;
model.settings.b = 0.0;
model.settings.c = 0.0;
model.settings.d = 2.0;
} else {
model.settings.iter = 855.0;
model.settings.bound = 3.5;
model.settings.a = 0.1;
model.settings.b = 0.5;
model.settings.c = 1.0;
model.settings.d = 8.0;
}
}
}
ui.horizontal(|ui| {
if ui.button("Hide UI").clicked() {
model.settings.show_ui = false;
}
ui.label("Press H to revert");
});
});
let params_data = [model.settings.lambda, model.settings.theta,model.settings.alpha, model.settings.sigma,model.settings.gamma,model.settings.blue,model.settings.aa,model.settings.iter,model.settings.bound,model.settings.tt,model.settings.a,model.settings.b,model.settings.c,model.settings.d,model.settings.e,model.settings.f,model.settings.g];

let params_data = [
model.settings.lambda, model.settings.theta, model.settings.alpha,
model.settings.sigma, model.settings.gamma, model.settings.blue,
model.settings.aa, model.settings.iter, model.settings.bound,
model.settings.tt, model.settings.a, model.settings.b,
model.settings.c, model.settings.d, model.settings.e,
model.settings.f, model.settings.g
];
let params_bytes = bytemuck::cast_slice(&params_data);
app.main_window().queue().write_buffer(&model.params_uniform, 0, &params_bytes);
}
Expand Down Expand Up @@ -172,10 +252,10 @@ fn model(app: &App) -> Model {
gamma:0.5,
blue:1.0,
show_ui:true,
aa: 4.0,
aa: 2.0,
iter:855.0,
bound:3.5,
tt:18.0,
tt:0.1,
a:0.1,
b:0.5,
c:1.0,
Expand Down
34 changes: 17 additions & 17 deletions src/mandelbulb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,24 +165,24 @@ fn model(app: &App) -> Model {
label: Some("time_bind_group"),
});
let settings = Settings {
lambda: 2.0,
theta:0.9,
alpha:0.85,
sigma:0.75,
gamma:0.7,
blue:0.65,
show_ui:true,
lambda: 0.8,
theta: 1.0,
alpha: 0.7,
sigma: 0.3,
gamma: 0.7,
blue: 0.3,
show_ui: true,
aa: 2.0,
iter:8.0,
bound:5.05,
tt:0.0001,
a:1.7,
b:1.7,
c:0.1,
d:2.0,
e:3.0,
f:0.7,
g:0.1,
iter: 8.0,
bound: 5.05,
tt: 0.0001,
a: 0.1,
b: 0.4,
c: 0.1,
d: 0.4,
e: 0.2,
f: 0.0,
g: 0.1,
};
let params_data = [settings.lambda, settings.theta, settings.alpha,settings.sigma,settings.gamma,settings.blue,settings.aa,settings.iter,settings.bound,settings.tt,settings.a,settings.b,settings.c,settings.d,settings.e,settings.f,settings.g];
let params_bytes = bytemuck::cast_slice(&params_data);
Expand Down

0 comments on commit 8b8a0c9

Please sign in to comment.