add chromatic version of fast crt shader + auto crt shader

This commit is contained in:
2022-07-21 23:03:52 +02:00
parent 1f5042059c
commit e4579d81bc
5 changed files with 84 additions and 10 deletions

View File

@@ -112,7 +112,7 @@ impl CrtFilter {
} }
impl Filter for CrtFilter { impl Filter for CrtFilter {
fn resize(&self, queue: &wgpu::Queue, new_size: PhysicalSize<u32>) { fn resize(&mut self, queue: &wgpu::Queue, new_size: PhysicalSize<u32>) {
let uniforms = Uniforms { let uniforms = Uniforms {
texture_scale: texture_scale_from_resolution(new_size), texture_scale: texture_scale_from_resolution(new_size),
}; };

View File

@@ -15,6 +15,7 @@ impl FastCrtFilter {
screen: &wgpu::TextureView, screen: &wgpu::TextureView,
resolution: PhysicalSize<u32>, resolution: PhysicalSize<u32>,
surface_format: wgpu::TextureFormat, surface_format: wgpu::TextureFormat,
chromatic: bool,
) -> FastCrtFilter { ) -> FastCrtFilter {
let uniforms = Uniforms { let uniforms = Uniforms {
texture_scale: texture_scale_from_resolution(resolution), texture_scale: texture_scale_from_resolution(resolution),
@@ -104,7 +105,11 @@ impl FastCrtFilter {
}, },
fragment: Some(wgpu::FragmentState { fragment: Some(wgpu::FragmentState {
module: &shader, module: &shader,
entry_point: "fs_main", entry_point: if chromatic {
"fs_main_chromatic"
} else {
"fs_main"
},
targets: &[Some(wgpu::ColorTargetState { targets: &[Some(wgpu::ColorTargetState {
format: surface_format, format: surface_format,
blend: None, blend: None,
@@ -126,7 +131,7 @@ impl FastCrtFilter {
} }
impl Filter for FastCrtFilter { impl Filter for FastCrtFilter {
fn resize(&self, queue: &wgpu::Queue, new_size: PhysicalSize<u32>) { fn resize(&mut self, queue: &wgpu::Queue, new_size: PhysicalSize<u32>) {
let uniforms = Uniforms { let uniforms = Uniforms {
texture_scale: texture_scale_from_resolution(new_size), texture_scale: texture_scale_from_resolution(new_size),
}; };

View File

@@ -34,10 +34,9 @@ fn col_factor(offset: f32) -> f32 {
return 1.0 / (1.0 + offset * offset * 16.0); return 1.0 / (1.0 + offset * offset * 16.0);
} }
@fragment fn sample_screen(tex_coords: vec2<f32>) -> vec4<f32> {
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> { let base = round(tex_coords) - vec2<f32>(0.5);
let base = round(in.tex_coords) - vec2<f32>(0.5); let frac = tex_coords - base;
let frac = in.tex_coords - base;
let top_factor = row_factor(frac.y); let top_factor = row_factor(frac.y);
let bottom_factor = row_factor(frac.y - 1.0); let bottom_factor = row_factor(frac.y - 1.0);
@@ -52,3 +51,16 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
return textureSample(screen_texture, linear_sampler, vec2<f32>(u, v) / vec2<f32>(320.0, 240.0)) * (top_factor + bottom_factor) * (left_factor + right_factor) * 1.1; return textureSample(screen_texture, linear_sampler, vec2<f32>(u, v) / vec2<f32>(320.0, 240.0)) * (top_factor + bottom_factor) * (left_factor + right_factor) * 1.1;
} }
@fragment
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
return sample_screen(in.tex_coords);
}
@fragment
fn fs_main_chromatic(in: VertexOutput) -> @location(0) vec4<f32> {
let r = sample_screen(in.tex_coords + vec2<f32>(0.2, 0.2)).r;
let g = sample_screen(in.tex_coords + vec2<f32>(0.07, -0.27)).g;
let b = sample_screen(in.tex_coords + vec2<f32>(-0.27, 0.07)).b;
return vec4<f32>(r, g, b, 1.0);
}

View File

@@ -73,7 +73,7 @@ impl Window {
present_mode: wgpu::PresentMode::AutoNoVsync, present_mode: wgpu::PresentMode::AutoNoVsync,
}; };
let filter: Box<dyn Filter> = Box::new(CrtFilter::new( let filter: Box<dyn Filter> = Box::new(AutoCrtFilter::new(
&device, &device,
&palette_screen_mode.screen_view, &palette_screen_mode.screen_view,
window.inner_size(), window.inner_size(),
@@ -167,6 +167,7 @@ impl WindowImpl for Window {
&self.palette_screen_mode.screen_view, &self.palette_screen_mode.screen_view,
self.window.inner_size(), self.window.inner_size(),
self.surface_config.format, self.surface_config.format,
false,
)) ))
} }
Some(VirtualKeyCode::Key3) => { Some(VirtualKeyCode::Key3) => {
@@ -177,6 +178,23 @@ impl WindowImpl for Window {
self.surface_config.format, self.surface_config.format,
)) ))
} }
Some(VirtualKeyCode::Key4) => {
self.filter = Box::new(FastCrtFilter::new(
&self.device,
&self.palette_screen_mode.screen_view,
self.window.inner_size(),
self.surface_config.format,
true,
))
}
Some(VirtualKeyCode::Key5) => {
self.filter = Box::new(AutoCrtFilter::new(
&self.device,
&self.palette_screen_mode.screen_view,
self.window.inner_size(),
self.surface_config.format,
))
}
_ => (), _ => (),
} }
@@ -252,10 +270,49 @@ impl WindowImpl for Window {
} }
trait Filter { trait Filter {
fn resize(&self, queue: &wgpu::Queue, new_size: PhysicalSize<u32>); fn resize(&mut self, queue: &wgpu::Queue, new_size: PhysicalSize<u32>);
fn render<'a>(&'a self, render_pass: &mut wgpu::RenderPass<'a>); fn render<'a>(&'a self, render_pass: &mut wgpu::RenderPass<'a>);
} }
struct AutoCrtFilter {
small: CrtFilter,
large: FastCrtFilter,
resolution: PhysicalSize<u32>,
}
impl AutoCrtFilter {
fn new(
device: &wgpu::Device,
screen: &wgpu::TextureView,
resolution: PhysicalSize<u32>,
surface_format: wgpu::TextureFormat,
) -> AutoCrtFilter {
let small = CrtFilter::new(device, screen, resolution, surface_format);
let large = FastCrtFilter::new(device, screen, resolution, surface_format, true);
AutoCrtFilter {
small,
large,
resolution,
}
}
}
impl Filter for AutoCrtFilter {
fn resize(&mut self, queue: &wgpu::Queue, new_size: PhysicalSize<u32>) {
self.small.resize(queue, new_size);
self.large.resize(queue, new_size);
self.resolution = new_size;
}
fn render<'a>(&'a self, render_pass: &mut wgpu::RenderPass<'a>) {
if self.resolution.width < 960 || self.resolution.height < 720 {
self.small.render(render_pass);
} else {
self.large.render(render_pass);
}
}
}
struct PaletteScreenMode { struct PaletteScreenMode {
framebuffer: wgpu::Texture, framebuffer: wgpu::Texture,
palette: wgpu::Texture, palette: wgpu::Texture,

View File

@@ -126,7 +126,7 @@ impl SquareFilter {
} }
impl Filter for SquareFilter { impl Filter for SquareFilter {
fn resize(&self, queue: &wgpu::Queue, new_size: PhysicalSize<u32>) { fn resize(&mut self, queue: &wgpu::Queue, new_size: PhysicalSize<u32>) {
let uniforms = Uniforms { let uniforms = Uniforms {
texture_scale: texture_scale_from_resolution(new_size), texture_scale: texture_scale_from_resolution(new_size),
}; };