commit
8d9498939f
@ -0,0 +1,2 @@
|
|||||||
|
/target
|
||||||
|
**/*.rs.bk
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,21 @@
|
|||||||
|
[package]
|
||||||
|
authors = ["Rahix <rahix@rahix.de>"]
|
||||||
|
edition = "2018"
|
||||||
|
name = "ggparty-2019"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
glium = "0.22.0"
|
||||||
|
image = "0.20.1"
|
||||||
|
log = "0.4.6"
|
||||||
|
nalgebra = "0.16.9"
|
||||||
|
rand = "0.6.0-pre.1"
|
||||||
|
ezconf = "0.3.0"
|
||||||
|
|
||||||
|
[dependencies.vis-core]
|
||||||
|
git = "https://github.com/Rahix/visualizer2"
|
||||||
|
rev = "a237bb423e3a278a29a25649a7274d3430815596"
|
||||||
|
features = ["cpalrecord", "pulseaudio"]
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
debug=1
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
import sys
|
||||||
|
import math
|
||||||
|
|
||||||
|
def hex2flt(h: str):
|
||||||
|
c_u8 = [int(h[0:2], 16), int(h[2:4], 16), int(h[4:6], 16)]
|
||||||
|
c_flt = [x / 255 for x in c_u8]
|
||||||
|
c_srgb = [x**2 for x in c_flt]
|
||||||
|
c_str = ", ".join(f"{x:7.5f}" for x in c_srgb)
|
||||||
|
print(f"[{c_str}]")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
hex2flt(sys.argv[1])
|
||||||
|
After Width: | Height: | Size: 6.7 KiB |
@ -0,0 +1,651 @@
|
|||||||
|
#[macro_use]
|
||||||
|
extern crate log;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate glium;
|
||||||
|
extern crate nalgebra as na;
|
||||||
|
|
||||||
|
use glium::glutin;
|
||||||
|
use vis_core::analyzer;
|
||||||
|
|
||||||
|
macro_rules! shader_program {
|
||||||
|
// {{{
|
||||||
|
($display:expr, $vert_file:expr, $frag_file:expr) => {{
|
||||||
|
// Use this for debug
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
{
|
||||||
|
let vert_src = {
|
||||||
|
use std::io::Read;
|
||||||
|
let mut buf = String::new();
|
||||||
|
let mut f = std::fs::File::open(format!("src/{}", $vert_file)).unwrap();
|
||||||
|
f.read_to_string(&mut buf).unwrap();
|
||||||
|
|
||||||
|
buf
|
||||||
|
};
|
||||||
|
|
||||||
|
let frag_src = {
|
||||||
|
use std::io::Read;
|
||||||
|
let mut buf = String::new();
|
||||||
|
let mut f = std::fs::File::open(format!("src/{}", $frag_file)).unwrap();
|
||||||
|
f.read_to_string(&mut buf).unwrap();
|
||||||
|
|
||||||
|
buf
|
||||||
|
};
|
||||||
|
|
||||||
|
glium::Program::from_source($display, &vert_src, &frag_src, None).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use this for release
|
||||||
|
#[cfg(not(debug_assertions))]
|
||||||
|
glium::Program::from_source(
|
||||||
|
$display,
|
||||||
|
include_str!($vert_file),
|
||||||
|
include_str!($frag_file),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
}};
|
||||||
|
} // }}}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
struct Vertex {
|
||||||
|
position: [f32; 4],
|
||||||
|
color_id: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
glium::implement_vertex!(Vertex, position, color_id);
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct VisInfo {
|
||||||
|
beat: u64,
|
||||||
|
beat_volume: f32,
|
||||||
|
volume: f32,
|
||||||
|
analyzer: analyzer::FourierAnalyzer,
|
||||||
|
spectrum: analyzer::Spectrum<Vec<f32>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
vis_core::default_config();
|
||||||
|
|
||||||
|
#[cfg(not(debug_assertions))]
|
||||||
|
vis_core::CONFIG.init(
|
||||||
|
[ezconf::Source::Memory(include_str!("../visualizer.toml"))].iter()
|
||||||
|
).unwrap();
|
||||||
|
|
||||||
|
vis_core::default_log();
|
||||||
|
|
||||||
|
let mut frames = {
|
||||||
|
// Analyzer {{{
|
||||||
|
let mut beat = analyzer::BeatBuilder::new().build();
|
||||||
|
let mut beat_num = 0;
|
||||||
|
|
||||||
|
let analyzer = analyzer::FourierBuilder::new().plan();
|
||||||
|
|
||||||
|
vis_core::Visualizer::new(
|
||||||
|
VisInfo {
|
||||||
|
beat: 0,
|
||||||
|
beat_volume: 0.0,
|
||||||
|
volume: 0.0,
|
||||||
|
spectrum: analyzer::Spectrum::new(vec![0.0; analyzer.buckets()], 0.0, 1.0),
|
||||||
|
analyzer,
|
||||||
|
},
|
||||||
|
move |info, samples| {
|
||||||
|
if beat.detect(&samples) {
|
||||||
|
beat_num += 1;
|
||||||
|
}
|
||||||
|
info.beat = beat_num;
|
||||||
|
info.beat_volume = beat.last_volume();
|
||||||
|
info.volume = samples.volume(0.3);
|
||||||
|
|
||||||
|
info.analyzer.analyze(&samples);
|
||||||
|
info.spectrum.fill_from(&info.analyzer.average());
|
||||||
|
|
||||||
|
info
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.async_analyzer(vis_core::CONFIG.get_or("audio.conversions", 300))
|
||||||
|
.frames()
|
||||||
|
// }}}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Config {{{
|
||||||
|
// Window
|
||||||
|
let window_width = vis_core::CONFIG.get_or("window.width", 1280);
|
||||||
|
let window_height = vis_core::CONFIG.get_or("window.height", 720);
|
||||||
|
let aspect = window_width as f32 / window_height as f32;
|
||||||
|
|
||||||
|
// Columns
|
||||||
|
let rows = vis_core::CONFIG.get_or("noa.cols.rows", 50);
|
||||||
|
let cols = vis_core::CONFIG.get_or("noa.cols.num", 30);
|
||||||
|
let nrow = cols * 4;
|
||||||
|
let cols_per_note = vis_core::CONFIG.get_or("noa.cols.note_width", 6);
|
||||||
|
let notes_num = cols * 2 / cols_per_note;
|
||||||
|
let width = vis_core::CONFIG.get_or("noa.cols.width", 10.0);
|
||||||
|
let depth = vis_core::CONFIG.get_or("noa.cols.depth", 30.0);
|
||||||
|
let rowsize = depth / rows as f32;
|
||||||
|
let mid_dist = vis_core::CONFIG.get_or("noa.cols.mid_dist", 0.1);
|
||||||
|
let base_height = vis_core::CONFIG.get_or("noa.cols.base_height", 0.2);
|
||||||
|
let base_speed = vis_core::CONFIG.get_or("noa.cols.speed", 0.1);
|
||||||
|
let slowdown = vis_core::CONFIG.get_or("noa.cols.slowdown", 0.995);
|
||||||
|
let speed_deviation = vis_core::CONFIG.get_or("noa.cols.speed_deviation", 50.0);
|
||||||
|
let ampli_top = vis_core::CONFIG.get_or("noa.cols.amp_top", 0.7);
|
||||||
|
let ampli_bottom = vis_core::CONFIG.get_or("noa.cols.amp_bottom", 0.2);
|
||||||
|
|
||||||
|
let frame_time =
|
||||||
|
std::time::Duration::from_micros(1000000 / vis_core::CONFIG.get_or("noa.fps", 30));
|
||||||
|
|
||||||
|
// Colors
|
||||||
|
let colors: Vec<[f32; 4]> = vis_core::CONFIG.get_or(
|
||||||
|
"noa.cols.colors",
|
||||||
|
vec![
|
||||||
|
[0.30142, 0.01884, 0.00886, 1.0],
|
||||||
|
[0.13589, 0.30142, 0.17280, 1.0],
|
||||||
|
[0.28444, 0.42378, 0.13589, 1.0],
|
||||||
|
[0.56103, 0.49275, 0.12457, 1.0],
|
||||||
|
[0.90064, 0.59079, 0.12457, 1.0],
|
||||||
|
|
||||||
|
[0.90064, 0.59079, 0.12457, 1.0],
|
||||||
|
[0.56103, 0.49275, 0.12457, 1.0],
|
||||||
|
[0.28444, 0.42378, 0.13589, 1.0],
|
||||||
|
[0.13589, 0.30142, 0.17280, 1.0],
|
||||||
|
[0.30142, 0.01884, 0.00886, 1.0],
|
||||||
|
],
|
||||||
|
);
|
||||||
|
let note_roll_size = vis_core::CONFIG.get_or("noa.cols.note_roll", 20) as f32;
|
||||||
|
|
||||||
|
// Camera
|
||||||
|
let cam_height = vis_core::CONFIG.get_or("noa.camera.height", 1.0);
|
||||||
|
let cam_look = vis_core::CONFIG.get_or("noa.camera.look_height", 0.8);
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
// Window Initialization {{{
|
||||||
|
let mut events_loop = glutin::EventsLoop::new();
|
||||||
|
let window = glutin::WindowBuilder::new()
|
||||||
|
.with_dimensions(glutin::dpi::LogicalSize::new(
|
||||||
|
window_width as f64,
|
||||||
|
window_height as f64,
|
||||||
|
))
|
||||||
|
.with_maximized(true)
|
||||||
|
.with_decorations(false)
|
||||||
|
.with_fullscreen(Some(events_loop.get_primary_monitor()))
|
||||||
|
.with_title("Visualizer2 - NoAmbition");
|
||||||
|
|
||||||
|
let context = glutin::ContextBuilder::new()
|
||||||
|
.with_gl(glutin::GlRequest::Specific(glutin::Api::OpenGl, (4, 1)))
|
||||||
|
.with_gl_profile(glutin::GlProfile::Core)
|
||||||
|
.with_multisampling(0);
|
||||||
|
|
||||||
|
let display = glium::Display::new(window, context, &events_loop).unwrap();
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
// Framebuffer Initialization {{{
|
||||||
|
let tex1 = glium::texture::Texture2d::empty_with_format(
|
||||||
|
&display,
|
||||||
|
glium::texture::UncompressedFloatFormat::F32F32F32F32,
|
||||||
|
glium::texture::MipmapsOption::NoMipmap,
|
||||||
|
window_width,
|
||||||
|
window_height,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
let depth1 = glium::texture::DepthTexture2d::empty_with_format(
|
||||||
|
&display,
|
||||||
|
glium::texture::DepthFormat::F32,
|
||||||
|
glium::texture::MipmapsOption::NoMipmap,
|
||||||
|
window_width,
|
||||||
|
window_height,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
let mut framebuffer1 =
|
||||||
|
glium::framebuffer::SimpleFrameBuffer::with_depth_buffer(&display, &tex1, &depth1).unwrap();
|
||||||
|
|
||||||
|
let tex2 = glium::texture::Texture2d::empty_with_format(
|
||||||
|
&display,
|
||||||
|
glium::texture::UncompressedFloatFormat::F32F32F32F32,
|
||||||
|
glium::texture::MipmapsOption::NoMipmap,
|
||||||
|
window_width,
|
||||||
|
window_height,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
let depth2 = glium::texture::DepthTexture2d::empty_with_format(
|
||||||
|
&display,
|
||||||
|
glium::texture::DepthFormat::F32,
|
||||||
|
glium::texture::MipmapsOption::NoMipmap,
|
||||||
|
window_width,
|
||||||
|
window_height,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
let mut framebuffer2 =
|
||||||
|
glium::framebuffer::SimpleFrameBuffer::with_depth_buffer(&display, &tex2, &depth2).unwrap();
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
// Shader Initialization {{{
|
||||||
|
let prepass_program = shader_program!(&display, "shaders/prepass.vert", "shaders/prepass.frag");
|
||||||
|
let background_program =
|
||||||
|
shader_program!(&display, "shaders/pp.vert", "shaders/background.frag");
|
||||||
|
// let fxaa_program = shader_program!(&display, "shaders/pp.vert", "shaders/fxaa.frag");
|
||||||
|
let apply_alpha_program = shader_program!(&display, "shaders/pp.vert", "shaders/apply_alpha.frag");
|
||||||
|
let chromatic_program = shader_program!(&display, "shaders/pp.vert", "shaders/chromatic.frag");
|
||||||
|
let bokeh_program = shader_program!(&display, "shaders/pp.vert", "shaders/bokeh.frag");
|
||||||
|
let color_program = shader_program!(&display, "shaders/pp.vert", "shaders/color.frag");
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
// Buffers {{{
|
||||||
|
|
||||||
|
// Quad {{{
|
||||||
|
let quad_verts = {
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
struct Vertex {
|
||||||
|
position: [f32; 4],
|
||||||
|
texcoord: [f32; 2],
|
||||||
|
}
|
||||||
|
|
||||||
|
glium::implement_vertex!(Vertex, position, texcoord);
|
||||||
|
|
||||||
|
glium::VertexBuffer::new(
|
||||||
|
&display,
|
||||||
|
&[
|
||||||
|
Vertex {
|
||||||
|
position: [-1.0, -1.0, 0.0, 1.0],
|
||||||
|
texcoord: [0.0, 0.0],
|
||||||
|
},
|
||||||
|
Vertex {
|
||||||
|
position: [1.0, -1.0, 0.0, 1.0],
|
||||||
|
texcoord: [1.0, 0.0],
|
||||||
|
},
|
||||||
|
Vertex {
|
||||||
|
position: [1.0, 1.0, 0.0, 1.0],
|
||||||
|
texcoord: [1.0, 1.0],
|
||||||
|
},
|
||||||
|
Vertex {
|
||||||
|
position: [-1.0, 1.0, 0.0, 1.0],
|
||||||
|
texcoord: [0.0, 1.0],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
};
|
||||||
|
let quad_inds = glium::IndexBuffer::new(
|
||||||
|
&display,
|
||||||
|
glium::index::PrimitiveType::TrianglesList,
|
||||||
|
&[0u16, 1, 2, 0, 2, 3],
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
// Lines {{{
|
||||||
|
let (mut lines_verts, mut lines_colors) = {
|
||||||
|
let colsmax = (cols - 1) as f32 / width * 2.0;
|
||||||
|
let rowsmax = (rows - 1) as f32 / depth;
|
||||||
|
let h = base_height / 2.0;
|
||||||
|
let mut v_buf = Vec::with_capacity(rows * cols * 4);
|
||||||
|
|
||||||
|
for row in 0..rows {
|
||||||
|
let y = row as f32 / rowsmax;
|
||||||
|
// Left
|
||||||
|
for col in 0..cols {
|
||||||
|
let x = -(col as f32 / colsmax) - mid_dist;
|
||||||
|
let cid = (cols - col - 1) / cols_per_note;
|
||||||
|
v_buf.push(Vertex {
|
||||||
|
position: [x, y, -h, 1.0],
|
||||||
|
color_id: cid as u16,
|
||||||
|
});
|
||||||
|
v_buf.push(Vertex {
|
||||||
|
position: [x, y, h, 1.0],
|
||||||
|
color_id: cid as u16,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Right
|
||||||
|
for col in 0..cols {
|
||||||
|
let x = (col as f32 / colsmax) + mid_dist;
|
||||||
|
let cid = col / cols_per_note + notes_num / 2;
|
||||||
|
v_buf.push(Vertex {
|
||||||
|
position: [x, y, -h, 1.0],
|
||||||
|
color_id: cid as u16,
|
||||||
|
});
|
||||||
|
v_buf.push(Vertex {
|
||||||
|
position: [x, y, h, 1.0],
|
||||||
|
color_id: cid as u16,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut colors_buf = [[1.0, 0.0, 0.0, 1.0]; 32];
|
||||||
|
for (buf, color) in colors_buf.iter_mut().zip(colors.iter()) {
|
||||||
|
*buf = *color;
|
||||||
|
}
|
||||||
|
let lines_colors =
|
||||||
|
glium::uniforms::UniformBuffer::persistent(&display, colors_buf).unwrap();
|
||||||
|
|
||||||
|
(
|
||||||
|
glium::VertexBuffer::persistent(&display, &v_buf).unwrap(),
|
||||||
|
lines_colors,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
// Points {{{
|
||||||
|
let points_colors = {
|
||||||
|
let mut colors_buf = [[1.0, 0.0, 0.0, 1.0]; 32];
|
||||||
|
for (buf, color) in colors_buf.iter_mut().zip(colors.iter()) {
|
||||||
|
*buf = *color;
|
||||||
|
}
|
||||||
|
glium::uniforms::UniformBuffer::persistent(&display, colors_buf).unwrap()
|
||||||
|
};
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
// Lightning {{{
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
// Image {{{
|
||||||
|
let image = image::load(
|
||||||
|
std::io::Cursor::new(&include_bytes!("logo.png")[..]),
|
||||||
|
image::PNG,
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
.to_rgba();
|
||||||
|
let image_dims = image.dimensions();
|
||||||
|
let image = glium::texture::RawImage2d::from_raw_rgba_reversed(&image.into_raw(), image_dims);
|
||||||
|
let c3_texture = glium::texture::CompressedSrgbTexture2d::new(&display, image).unwrap();
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
let mut previous_time = 0.0;
|
||||||
|
let mut previous_offset = 0.0;
|
||||||
|
let mut rolling_volume = 0.0;
|
||||||
|
let mut write_row = rows * 3 / 4;
|
||||||
|
let mut last_beat = -100.0;
|
||||||
|
|
||||||
|
let mut notes_spectrum = analyzer::Spectrum::new(vec![0.0; notes_num], 220.0, 660.0);
|
||||||
|
let mut notes_rolling_buf = vec![0.0; notes_num];
|
||||||
|
let mut row_buf = Vec::with_capacity(nrow);
|
||||||
|
let mut row_spectrum = vec![0.0; cols];
|
||||||
|
|
||||||
|
let mut beat_rolling = 0.0;
|
||||||
|
let mut last_beat_num = 0;
|
||||||
|
|
||||||
|
let mut maxima_buf = [(0.0, 0.0); 8];
|
||||||
|
|
||||||
|
'main: for frame in frames.iter() {
|
||||||
|
use glium::Surface;
|
||||||
|
|
||||||
|
let start = std::time::Instant::now();
|
||||||
|
let delta = frame.time - previous_time;
|
||||||
|
trace!("Delta: {}s", delta);
|
||||||
|
|
||||||
|
// Audio Info Retrieval {{{
|
||||||
|
let (volume, maxima, notes_rolling_spectrum, base_volume) = frame.info(|info| {
|
||||||
|
rolling_volume = info.volume.max(rolling_volume * slowdown);
|
||||||
|
|
||||||
|
if info.beat != last_beat_num {
|
||||||
|
last_beat = frame.time;
|
||||||
|
last_beat_num = info.beat;
|
||||||
|
}
|
||||||
|
|
||||||
|
let notes_spectrum = info.spectrum.fill_spectrum(&mut notes_spectrum);
|
||||||
|
|
||||||
|
for (n, s) in notes_rolling_buf.iter_mut().zip(notes_spectrum.iter()) {
|
||||||
|
*n = (*n * (note_roll_size - 1.0) + s) / note_roll_size;
|
||||||
|
}
|
||||||
|
let notes_rolling_spectrum = vis_core::analyzer::Spectrum::new(
|
||||||
|
&mut *notes_rolling_buf,
|
||||||
|
notes_spectrum.lowest(),
|
||||||
|
notes_spectrum.highest(),
|
||||||
|
);
|
||||||
|
|
||||||
|
let maxima = notes_rolling_spectrum.find_maxima(&mut maxima_buf);
|
||||||
|
|
||||||
|
(
|
||||||
|
info.volume,
|
||||||
|
maxima,
|
||||||
|
notes_rolling_spectrum,
|
||||||
|
info.beat_volume,
|
||||||
|
)
|
||||||
|
});
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
// GL Matrices {{{
|
||||||
|
let view = na::Matrix4::look_at_rh(
|
||||||
|
&na::Point3::new(0.0, -1.0, cam_height),
|
||||||
|
&na::Point3::new(0.0, 10.0, cam_look),
|
||||||
|
&na::Vector3::new(0.0, 0.0, 1.0),
|
||||||
|
);
|
||||||
|
|
||||||
|
let perspective =
|
||||||
|
na::Matrix4::new_perspective(aspect, std::f32::consts::FRAC_PI_4, 0.001, 100.0);
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
// Grid {{{
|
||||||
|
let speed = base_speed + rolling_volume * speed_deviation;
|
||||||
|
let offset = (previous_offset + delta * speed) % rowsize;
|
||||||
|
let model_grid =
|
||||||
|
na::Translation3::from(na::Vector3::new(0.0, -offset, 0.0)).to_homogeneous();
|
||||||
|
|
||||||
|
// Color Notes {{{
|
||||||
|
{
|
||||||
|
let mut color_buf = lines_colors.map();
|
||||||
|
for color in color_buf.iter_mut() {
|
||||||
|
color[3] = 0.05;
|
||||||
|
}
|
||||||
|
for (f, _) in maxima.iter().take(4) {
|
||||||
|
let note = notes_rolling_spectrum.freq_to_id(*f);
|
||||||
|
color_buf[note][3] = 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
// Spectral Grid {{{
|
||||||
|
if previous_offset > offset {
|
||||||
|
let mut lines_buf = lines_verts.map();
|
||||||
|
// We jumped right here
|
||||||
|
// Save last rows y coordinate
|
||||||
|
row_buf.clear();
|
||||||
|
let last_row_offset = lines_buf.len() - nrow;
|
||||||
|
for i in 0..nrow {
|
||||||
|
row_buf.push(lines_buf[last_row_offset + i].position[1]);
|
||||||
|
}
|
||||||
|
// Copy y coordinate of each line to the next
|
||||||
|
for i in (nrow..(lines_buf.len())).rev() {
|
||||||
|
lines_buf[i].position[1] = lines_buf[i - nrow].position[1];
|
||||||
|
}
|
||||||
|
// Write saved info to first row (cycle rows)
|
||||||
|
for i in 0..nrow {
|
||||||
|
lines_buf[i].position[1] = row_buf[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write spectral information
|
||||||
|
frame.info(|info| {
|
||||||
|
let left = info
|
||||||
|
.analyzer
|
||||||
|
.left()
|
||||||
|
.slice(100.0, 800.0)
|
||||||
|
.fill_buckets(&mut row_spectrum[..]);
|
||||||
|
let row_offset = nrow * write_row;
|
||||||
|
let max = left.max() + 0.0001;
|
||||||
|
for (i, v) in left.iter().enumerate() {
|
||||||
|
lines_buf[row_offset + i * 2 + 1].position[2] =
|
||||||
|
base_height / 2.0 + v / max * ampli_top;
|
||||||
|
lines_buf[row_offset + i * 2].position[2] =
|
||||||
|
-base_height / 2.0 - v / max * ampli_bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
let right = info
|
||||||
|
.analyzer
|
||||||
|
.right()
|
||||||
|
.slice(100.0, 800.0)
|
||||||
|
.fill_buckets(&mut row_spectrum[..]);
|
||||||
|
let row_offset = nrow * write_row + cols * 2;
|
||||||
|
let max = right.max() + 0.0001;
|
||||||
|
for (i, v) in right.iter().enumerate() {
|
||||||
|
lines_buf[row_offset + i * 2 + 1].position[2] =
|
||||||
|
base_height / 2.0 + v / max * ampli_top;
|
||||||
|
lines_buf[row_offset + i * 2].position[2] =
|
||||||
|
-base_height / 2.0 - v / max * ampli_bottom;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
write_row = (write_row + 1) % rows;
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
// Drawing {{{
|
||||||
|
let draw_params = glium::DrawParameters {
|
||||||
|
line_width: Some(1.0),
|
||||||
|
point_size: Some(2.0),
|
||||||
|
blend: glium::Blend {
|
||||||
|
color: glium::BlendingFunction::Addition {
|
||||||
|
source: glium::LinearBlendingFactor::SourceAlpha,
|
||||||
|
destination: glium::LinearBlendingFactor::OneMinusSourceAlpha,
|
||||||
|
},
|
||||||
|
alpha: glium::BlendingFunction::Addition {
|
||||||
|
source: glium::LinearBlendingFactor::One,
|
||||||
|
destination: glium::LinearBlendingFactor::One,
|
||||||
|
},
|
||||||
|
constant_value: (1.0, 1.0, 1.0, 1.0),
|
||||||
|
},
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
framebuffer1.clear_color_and_depth((0.0, 0.0, 0.0, 0.0), 1.0);
|
||||||
|
framebuffer2.clear_color_and_depth((0.0, 0.0, 0.0, 0.0), 1.0);
|
||||||
|
|
||||||
|
let (ref mut fa, ref mut fb) = (&mut framebuffer1, &mut framebuffer2);
|
||||||
|
|
||||||
|
// Lines {{{
|
||||||
|
let uniforms = uniform! {
|
||||||
|
perspective_matrix: Into::<[[f32; 4]; 4]>::into(perspective),
|
||||||
|
view_matrix: Into::<[[f32; 4]; 4]>::into(view),
|
||||||
|
model_matrix: Into::<[[f32; 4]; 4]>::into(model_grid),
|
||||||
|
Colors: &lines_colors,
|
||||||
|
volume: rolling_volume,
|
||||||
|
};
|
||||||
|
fa.draw(
|
||||||
|
&lines_verts,
|
||||||
|
&glium::index::NoIndices(glium::index::PrimitiveType::LinesList),
|
||||||
|
&prepass_program,
|
||||||
|
&uniforms,
|
||||||
|
&draw_params,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
// Points {{{
|
||||||
|
let uniforms = uniform! {
|
||||||
|
perspective_matrix: Into::<[[f32; 4]; 4]>::into(perspective),
|
||||||
|
view_matrix: Into::<[[f32; 4]; 4]>::into(view),
|
||||||
|
model_matrix: Into::<[[f32; 4]; 4]>::into(model_grid),
|
||||||
|
Colors: &points_colors,
|
||||||
|
volume: rolling_volume,
|
||||||
|
};
|
||||||
|
fa.draw(
|
||||||
|
&lines_verts,
|
||||||
|
&glium::index::NoIndices(glium::index::PrimitiveType::Points),
|
||||||
|
&prepass_program,
|
||||||
|
&uniforms,
|
||||||
|
&draw_params,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
// Post-Processing {{{
|
||||||
|
beat_rolling = (beat_rolling * 0.95f32).max(base_volume);
|
||||||
|
|
||||||
|
let (fa, fb) = (fb, fa);
|
||||||
|
let ua = uniform! {
|
||||||
|
previous: tex1.sampled().wrap_function(glium::uniforms::SamplerWrapFunction::Mirror),
|
||||||
|
c3: c3_texture.sampled(),
|
||||||
|
aspect: aspect,
|
||||||
|
time: frame.time,
|
||||||
|
volume: volume,
|
||||||
|
last_beat: frame.time - last_beat,
|
||||||
|
beat: beat_rolling,
|
||||||
|
};
|
||||||
|
let ub = uniform! {
|
||||||
|
previous: tex2.sampled().wrap_function(glium::uniforms::SamplerWrapFunction::Mirror),
|
||||||
|
c3: c3_texture.sampled(),
|
||||||
|
aspect: aspect,
|
||||||
|
time: frame.time,
|
||||||
|
volume: volume,
|
||||||
|
last_beat: frame.time - last_beat,
|
||||||
|
beat: beat_rolling,
|
||||||
|
};
|
||||||
|
|
||||||
|
fa.draw(&quad_verts, &quad_inds, &background_program, &ua, &draw_params)
|
||||||
|
.unwrap();
|
||||||
|
// Apply alpha
|
||||||
|
let (fa, ua, fb, ub) = (fb, ub, fa, ua);
|
||||||
|
fa.draw(&quad_verts, &quad_inds, &apply_alpha_program, &ua, &draw_params)
|
||||||
|
.unwrap();
|
||||||
|
// Do final passes which don't require alpha information anymore
|
||||||
|
let (fa, ua, fb, ub) = (fb, ub, fa, ua);
|
||||||
|
fa.draw(&quad_verts, &quad_inds, &bokeh_program, &ua, &draw_params)
|
||||||
|
.unwrap();
|
||||||
|
let (fa, ua, fb, ub) = (fb, ub, fa, ua);
|
||||||
|
fa.draw(&quad_verts, &quad_inds, &color_program, &ua, &draw_params)
|
||||||
|
.unwrap();
|
||||||
|
let (fa, ua, fb, ub) = (fb, ub, fa, ua);
|
||||||
|
fa.draw(&quad_verts, &quad_inds, &chromatic_program, &ua, &draw_params)
|
||||||
|
.unwrap();
|
||||||
|
#[allow(unused_variables)]
|
||||||
|
let (fa, ua, fb, ub) = (fb, ub, fa, ua);
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
// Finalizing / Draw to screen {{{
|
||||||
|
let target = display.draw();
|
||||||
|
let dims = target.get_dimensions();
|
||||||
|
target.blit_from_simple_framebuffer(
|
||||||
|
&fb,
|
||||||
|
&glium::Rect {
|
||||||
|
left: 0,
|
||||||
|
bottom: 0,
|
||||||
|
width: window_width,
|
||||||
|
height: window_height,
|
||||||
|
},
|
||||||
|
&glium::BlitTarget {
|
||||||
|
left: 0,
|
||||||
|
bottom: 0,
|
||||||
|
width: dims.0 as i32,
|
||||||
|
height: dims.1 as i32,
|
||||||
|
},
|
||||||
|
glium::uniforms::MagnifySamplerFilter::Linear,
|
||||||
|
);
|
||||||
|
target.finish().unwrap();
|
||||||
|
// }}}
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
// Events {{{
|
||||||
|
let mut closed = false;
|
||||||
|
events_loop.poll_events(|ev| match ev {
|
||||||
|
glutin::Event::WindowEvent { event, .. } => match event {
|
||||||
|
glutin::WindowEvent::CloseRequested => closed = true,
|
||||||
|
glutin::WindowEvent::KeyboardInput {
|
||||||
|
input:
|
||||||
|
glutin::KeyboardInput {
|
||||||
|
virtual_keycode: Some(glutin::VirtualKeyCode::Escape),
|
||||||
|
..
|
||||||
|
},
|
||||||
|
..
|
||||||
|
} => closed = true,
|
||||||
|
_ => (),
|
||||||
|
},
|
||||||
|
_ => (),
|
||||||
|
});
|
||||||
|
if closed {
|
||||||
|
break 'main;
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
previous_time = frame.time;
|
||||||
|
previous_offset = offset;
|
||||||
|
|
||||||
|
let end = std::time::Instant::now();
|
||||||
|
let dur = end - start;
|
||||||
|
if dur < frame_time {
|
||||||
|
let sleep = frame_time - dur;
|
||||||
|
std::thread::sleep(sleep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
#version 410
|
||||||
|
|
||||||
|
uniform sampler2D previous;
|
||||||
|
uniform sampler2D c3;
|
||||||
|
uniform float last_beat;
|
||||||
|
uniform float beat;
|
||||||
|
uniform float volume;
|
||||||
|
uniform float aspect;
|
||||||
|
|
||||||
|
smooth in vec2 frag_position;
|
||||||
|
smooth in vec2 frag_texcoord;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 color = texture(previous, frag_texcoord);
|
||||||
|
gl_FragColor = vec4(color.rgb * color.a, 1.0);
|
||||||
|
}
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
#version 410
|
||||||
|
|
||||||
|
uniform sampler2D previous;
|
||||||
|
uniform sampler2D c3;
|
||||||
|
uniform float last_beat;
|
||||||
|
uniform float beat;
|
||||||
|
uniform float volume;
|
||||||
|
uniform float aspect;
|
||||||
|
|
||||||
|
smooth in vec2 frag_position;
|
||||||
|
smooth in vec2 frag_texcoord;
|
||||||
|
|
||||||
|
vec3 background() {
|
||||||
|
vec2 p = frag_position;
|
||||||
|
|
||||||
|
p.y *= 512.0 / 203.0;
|
||||||
|
|
||||||
|
float t = -2.0 / (last_beat*1.5+1.0)+3.0;
|
||||||
|
|
||||||
|
p.x = p.x * aspect + 0.5;
|
||||||
|
p.y -= 0.8;
|
||||||
|
|
||||||
|
p -= vec2(0.5);
|
||||||
|
p = p * t;
|
||||||
|
p += vec2(0.5);
|
||||||
|
|
||||||
|
if(p.x > 1.0 || p.x < 0.0 || p.y > 1.0 || p.y < 0.0){
|
||||||
|
return vec3(0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return texture(c3, p).rgb;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 prev_color = texture(previous, frag_texcoord);
|
||||||
|
vec3 bg_color = background();
|
||||||
|
gl_FragColor = vec4(prev_color.rgb + (1.0 - prev_color.a) * bg_color, 1.0);
|
||||||
|
}
|
||||||
@ -0,0 +1,52 @@
|
|||||||
|
#version 410
|
||||||
|
|
||||||
|
uniform sampler2D previous;
|
||||||
|
uniform sampler2D c3;
|
||||||
|
uniform float last_beat;
|
||||||
|
uniform float beat;
|
||||||
|
uniform float volume;
|
||||||
|
uniform float aspect;
|
||||||
|
|
||||||
|
smooth in vec2 frag_position;
|
||||||
|
smooth in vec2 frag_texcoord;
|
||||||
|
|
||||||
|
// Bokeh disc.
|
||||||
|
// by David Hoskins.
|
||||||
|
// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
|
||||||
|
|
||||||
|
// The Golden Angle is (3.-sqrt(5.0))*PI radians, which doesn't precompiled for some reason.
|
||||||
|
// The compiler is a dunce I tells-ya!!
|
||||||
|
#define GOLDEN_ANGLE 2.39996
|
||||||
|
|
||||||
|
#define ITERATIONS 32
|
||||||
|
|
||||||
|
mat2 rot = mat2(cos(GOLDEN_ANGLE), sin(GOLDEN_ANGLE), -sin(GOLDEN_ANGLE), cos(GOLDEN_ANGLE));
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------------
|
||||||
|
vec3 bokeh(sampler2D tex, vec2 uv, float radius)
|
||||||
|
{
|
||||||
|
vec3 acc = vec3(0.0), div = acc;
|
||||||
|
float r = 1.0;
|
||||||
|
vec2 vangle = vec2(0.0,radius*0.01 / sqrt(float(ITERATIONS)));
|
||||||
|
|
||||||
|
for (int j = 0; j < ITERATIONS; j++)
|
||||||
|
{
|
||||||
|
// the approx increase in the scale of sqrt(0, 1, 2, 3...)
|
||||||
|
r += 1. / r;
|
||||||
|
vangle = rot * vangle;
|
||||||
|
vec3 col = texture(tex, uv + (r-1.0) * vangle).xyz; /// ... Sample the image
|
||||||
|
vec3 bokeh = pow(col, vec3(4.0));
|
||||||
|
acc += col * bokeh;
|
||||||
|
div += bokeh;
|
||||||
|
}
|
||||||
|
return acc / div;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
float blend = 1.0 / (last_beat * 5.0 + 1.0) * 0.2;
|
||||||
|
blend *= pow(1.0 - frag_texcoord.y, 2);
|
||||||
|
vec4 real_color = texture(previous, frag_texcoord);
|
||||||
|
vec4 bokeh_color = vec4(bokeh(previous, frag_texcoord, blend), 1.0);
|
||||||
|
gl_FragColor = max(real_color, bokeh_color);
|
||||||
|
}
|
||||||
@ -0,0 +1,64 @@
|
|||||||
|
#version 410
|
||||||
|
|
||||||
|
|
||||||
|
uniform sampler2D previous;
|
||||||
|
uniform sampler2D c3;
|
||||||
|
uniform float last_beat;
|
||||||
|
uniform float beat;
|
||||||
|
uniform float volume;
|
||||||
|
uniform float aspect;
|
||||||
|
|
||||||
|
smooth in vec2 frag_position;
|
||||||
|
smooth in vec2 frag_texcoord;
|
||||||
|
|
||||||
|
// Chromatic Abberation shader
|
||||||
|
// https://github.com/spite/Wagner/blob/master/fragment-shaders/chromatic-aberration-fs.glsl
|
||||||
|
|
||||||
|
vec2 barrelDistortion(vec2 coord, float amt) {
|
||||||
|
vec2 cc = coord - 0.5;
|
||||||
|
float dist = dot(cc, cc);
|
||||||
|
return coord + cc * dist * amt;
|
||||||
|
}
|
||||||
|
|
||||||
|
float sat( float t )
|
||||||
|
{
|
||||||
|
return clamp( t, 0.0, 1.0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
float linterp( float t ) {
|
||||||
|
return sat( 1.0 - abs( 2.0*t - 1.0 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
float remap( float t, float a, float b ) {
|
||||||
|
return sat( (t - a) / (b - a) );
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 spectrum_offset( float t ) {
|
||||||
|
vec4 ret;
|
||||||
|
float lo = step(t,0.5);
|
||||||
|
float hi = 1.0-lo;
|
||||||
|
float w = linterp( remap( t, 1.0/6.0, 5.0/6.0 ) );
|
||||||
|
ret = vec4(lo,1.0,hi, 1.) * vec4(1.0-w, w, 1.0-w, 1.);
|
||||||
|
|
||||||
|
return pow( ret, vec4(1.0/2.2) );
|
||||||
|
}
|
||||||
|
|
||||||
|
const int num_iter = 20;
|
||||||
|
const float reci_num_iter_f = 1.0 / float(num_iter);
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
float max_distort = 0.5;
|
||||||
|
|
||||||
|
vec4 sumcol = vec4(0.0);
|
||||||
|
vec4 sumw = vec4(0.0);
|
||||||
|
for ( int i=0; i<num_iter;++i )
|
||||||
|
{
|
||||||
|
float t = float(i) * reci_num_iter_f;
|
||||||
|
vec4 w = spectrum_offset( t );
|
||||||
|
sumw += w;
|
||||||
|
sumcol += w * texture( previous, barrelDistortion(frag_texcoord, .6 * max_distort*t ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
gl_FragColor = sumcol / sumw;
|
||||||
|
}
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
#version 410
|
||||||
|
|
||||||
|
uniform sampler2D previous;
|
||||||
|
uniform sampler2D c3;
|
||||||
|
uniform float last_beat;
|
||||||
|
uniform float beat;
|
||||||
|
uniform float volume;
|
||||||
|
uniform float aspect;
|
||||||
|
|
||||||
|
smooth in vec2 frag_position;
|
||||||
|
smooth in vec2 frag_texcoord;
|
||||||
|
|
||||||
|
// RGB/HSV Conversion
|
||||||
|
// Taken from http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl
|
||||||
|
|
||||||
|
vec3 rgb2hsv(vec3 c)
|
||||||
|
{
|
||||||
|
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
|
||||||
|
vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
|
||||||
|
vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
|
||||||
|
|
||||||
|
float d = q.x - min(q.w, q.y);
|
||||||
|
float e = 1.0e-10;
|
||||||
|
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 hsv2rgb(vec3 c)
|
||||||
|
{
|
||||||
|
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
||||||
|
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
|
||||||
|
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 prev_color = texture(previous, frag_texcoord);
|
||||||
|
|
||||||
|
// if (frag_texcoord.x < 0.5) {
|
||||||
|
// gl_FragColor = prev_color;
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// gl_FragColor = mat4(
|
||||||
|
// 1.0, 0.0, 0.0, 0.0,
|
||||||
|
// 0.0, 1.0, -0.1, 0.0,
|
||||||
|
// 0.0, -0.3, 1.0, 0.0,
|
||||||
|
// 0.0, 0.0, 0.0, 1.0
|
||||||
|
// ) * prev_color;
|
||||||
|
gl_FragColor = prev_color;
|
||||||
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
#version 410
|
||||||
|
|
||||||
|
in vec4 position;
|
||||||
|
in vec2 texcoord;
|
||||||
|
|
||||||
|
smooth out vec2 frag_position;
|
||||||
|
smooth out vec2 frag_texcoord;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
frag_texcoord = texcoord;
|
||||||
|
frag_position = position.xy;
|
||||||
|
gl_Position = position;
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
#version 410
|
||||||
|
|
||||||
|
smooth in vec4 frag_position;
|
||||||
|
smooth in vec4 frag_color;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_FragColor = frag_color;
|
||||||
|
}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
#version 410
|
||||||
|
|
||||||
|
uniform mat4 perspective_matrix;
|
||||||
|
uniform mat4 view_matrix;
|
||||||
|
uniform mat4 model_matrix;
|
||||||
|
layout(std140) uniform Colors {
|
||||||
|
vec4 colors[32];
|
||||||
|
};
|
||||||
|
uniform float volume;
|
||||||
|
|
||||||
|
in vec4 position;
|
||||||
|
in uint color_id;
|
||||||
|
|
||||||
|
smooth out vec4 frag_position;
|
||||||
|
smooth out vec4 frag_color;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
frag_position = model_matrix * position;
|
||||||
|
frag_position.z += exp(-pow(frag_position.y / 5.0 - 4.0, 2.0)) * (pow(frag_position.x / 8.0, 2.0) * 2.0 + 0.1) * (volume * 30.0 + 0.1);
|
||||||
|
frag_color = colors[color_id];
|
||||||
|
frag_color.a = frag_color.a * (1.0 - smoothstep(15.0, 25.0, frag_position.y));
|
||||||
|
gl_Position = perspective_matrix * view_matrix * frag_position;
|
||||||
|
}
|
||||||
@ -0,0 +1,40 @@
|
|||||||
|
[audio]
|
||||||
|
window = "nuttall"
|
||||||
|
conversions = 50
|
||||||
|
rate = 8000
|
||||||
|
read_size = 256
|
||||||
|
recorder = "cpal"
|
||||||
|
|
||||||
|
[noa]
|
||||||
|
fps = 40
|
||||||
|
|
||||||
|
[noa.cols]
|
||||||
|
rows = 50
|
||||||
|
num = 30
|
||||||
|
depth = 30.0
|
||||||
|
mid_dist = 0.1
|
||||||
|
speed = 0.1
|
||||||
|
slowdown = 0.995
|
||||||
|
speed_deviation = 50.0
|
||||||
|
width = 10.0
|
||||||
|
note_width = 6
|
||||||
|
colors = [
|
||||||
|
[0.30142, 0.01884, 0.00886, 1.0],
|
||||||
|
[0.13589, 0.30142, 0.17280, 1.0],
|
||||||
|
[0.28444, 0.42378, 0.13589, 1.0],
|
||||||
|
[0.56103, 0.49275, 0.12457, 1.0],
|
||||||
|
[0.90064, 0.59079, 0.12457, 1.0],
|
||||||
|
|
||||||
|
[0.90064, 0.59079, 0.12457, 1.0],
|
||||||
|
[0.56103, 0.49275, 0.12457, 1.0],
|
||||||
|
[0.28444, 0.42378, 0.13589, 1.0],
|
||||||
|
[0.13589, 0.30142, 0.17280, 1.0],
|
||||||
|
[0.30142, 0.01884, 0.00886, 1.0],
|
||||||
|
]
|
||||||
|
|
||||||
|
amp_top = 0.7
|
||||||
|
amp_bottom = 0.2
|
||||||
|
|
||||||
|
[noa.camera]
|
||||||
|
height = 1.0
|
||||||
|
look_height = 0.8
|
||||||
Loading…
Reference in new issue