Add MSAAx4

This commit is contained in:
Imbris 2019-09-25 23:19:45 -04:00
parent b57031804e
commit 432e828517
4 changed files with 167 additions and 73 deletions

View File

@ -2,7 +2,7 @@
#include <globals.glsl>
uniform sampler2D src_color;
uniform sampler2DMS src_color;
in vec2 f_pos;
@ -169,8 +169,15 @@ void main() {
uv = clamp(uv + vec2(sin(uv.y * 16.0 + tick.x), sin(uv.x * 24.0 + tick.x)) * 0.005, 0, 1);
}
vec4 fxaa_color = fxaa_apply(src_color, uv * screen_res.xy * FXAA_SCALE, screen_res.xy * FXAA_SCALE);
//vec4 fxaa_color = fxaa_apply(src_color, uv * screen_res.xy * FXAA_SCALE, screen_res.xy * FXAA_SCALE);
//vec4 fxaa_color = texture(src_color, uv);
ivec2 uv_int = ivec2(uv.x * screen_res.x, uv.y * screen_res.y);
vec4 sample1 = texelFetch(src_color, uv_int, 0);
vec4 sample2 = texelFetch(src_color, uv_int, 1);
vec4 sample3 = texelFetch(src_color, uv_int, 2);
vec4 sample4 = texelFetch(src_color, uv_int, 3);
vec4 fxaa_color = (sample1 + sample2 + sample3 + sample4) / 4.0;
vec4 hsva_color = vec4(rgb2hsv(fxaa_color.rgb), fxaa_color.a);
hsva_color.y *= 1.45;

View File

@ -0,0 +1,94 @@
/// Used to represent one of many possible errors that may be omitted by the rendering subsystem.
#[derive(Debug)]
pub enum RenderError {
PipelineError(gfx::PipelineStateError<String>),
UpdateError(gfx::UpdateError<usize>),
TexUpdateError(gfx::UpdateError<[u16; 3]>),
CombinedError(gfx::CombinedError),
BufferCreationError(gfx::buffer::CreationError),
IncludeError(glsl_include::Error),
MappingError(gfx::mapping::Error),
CopyError(gfx::CopyError<[u16; 3], usize>),
}
impl From<gfx::PipelineStateError<String>> for RenderError {
fn from(err: gfx::PipelineStateError<String>) -> Self {
Self::PipelineError(err)
}
}
impl From<gfx::PipelineStateError<&str>> for RenderError {
fn from(err: gfx::PipelineStateError<&str>) -> Self {
match err {
gfx::PipelineStateError::DescriptorInit(err) => {
gfx::PipelineStateError::DescriptorInit(err.into())
}
err => err,
}
.into()
}
}
impl From<gfx::shade::ProgramError> for RenderError {
fn from(err: gfx::shade::ProgramError) -> Self {
gfx::PipelineStateError::<String>::Program(err).into()
}
}
impl From<gfx::UpdateError<usize>> for RenderError {
fn from(err: gfx::UpdateError<usize>) -> Self {
Self::UpdateError(err)
}
}
impl From<gfx::UpdateError<[u16; 3]>> for RenderError {
fn from(err: gfx::UpdateError<[u16; 3]>) -> Self {
Self::TexUpdateError(err)
}
}
impl From<gfx::CombinedError> for RenderError {
fn from(err: gfx::CombinedError) -> Self {
Self::CombinedError(err)
}
}
impl From<gfx::TargetViewError> for RenderError {
fn from(err: gfx::TargetViewError) -> Self {
Self::CombinedError(err.into())
}
}
impl From<gfx::ResourceViewError> for RenderError {
fn from(err: gfx::ResourceViewError) -> Self {
Self::CombinedError(err.into())
}
}
impl From<gfx::texture::CreationError> for RenderError {
fn from(err: gfx::texture::CreationError) -> Self {
Self::CombinedError(err.into())
}
}
impl From<gfx::buffer::CreationError> for RenderError {
fn from(err: gfx::buffer::CreationError) -> Self {
Self::BufferCreationError(err)
}
}
impl From<glsl_include::Error> for RenderError {
fn from(err: glsl_include::Error) -> Self {
Self::IncludeError(err)
}
}
impl From<gfx::mapping::Error> for RenderError {
fn from(err: gfx::mapping::Error) -> Self {
Self::MappingError(err)
}
}
impl From<gfx::CopyError<[u16; 3], usize>> for RenderError {
fn from(err: gfx::CopyError<[u16; 3], usize>) -> Self {
Self::CopyError(err)
}
}

View File

@ -1,4 +1,5 @@
pub mod consts;
mod error;
pub mod instances;
pub mod mesh;
pub mod model;
@ -10,6 +11,7 @@ mod util;
// Reexports
pub use self::{
consts::Consts,
error::RenderError,
instances::Instances,
mesh::{Mesh, Quad, Tri},
model::{DynamicModel, Model},
@ -37,19 +39,6 @@ use gfx_device_gl as gfx_backend;
use gfx;
/// Used to represent one of many possible errors that may be omitted by the rendering subsystem.
#[derive(Debug)]
pub enum RenderError {
PipelineError(gfx::PipelineStateError<String>),
UpdateError(gfx::UpdateError<usize>),
TexUpdateError(gfx::UpdateError<[u16; 3]>),
CombinedError(gfx::CombinedError),
BufferCreationError(gfx::buffer::CreationError),
IncludeError(glsl_include::Error),
MappingError(gfx::mapping::Error),
CopyError(gfx::CopyError<[u16; 3], usize>),
}
/// Used to represent a specific rendering configuration.
///
/// Note that pipelines are tied to the

View File

@ -169,12 +169,35 @@ impl Renderer {
factory: &mut gfx_device_gl::Factory,
size: (u16, u16),
) -> Result<(TgtColorView, TgtDepthView, TgtColorRes), RenderError> {
let (_, tgt_color_res, tgt_color_view) = factory
.create_render_target::<TgtColorFmt>(size.0, size.1)
.map_err(RenderError::CombinedError)?;;
let tgt_depth_view = factory
.create_depth_stencil_view_only::<TgtDepthFmt>(size.0, size.1)
.map_err(RenderError::CombinedError)?;;
let kind = gfx::texture::Kind::D2(size.0, size.1, gfx::texture::AaMode::Multi(4));
let levels = 1;
let color_cty = <<TgtColorFmt as gfx::format::Formatted>::Channel as gfx::format::ChannelTyped
>::get_channel_type();
let tgt_color_tex = factory.create_texture(
kind,
levels,
gfx::memory::Bind::SHADER_RESOURCE | gfx::memory::Bind::RENDER_TARGET,
gfx::memory::Usage::Data,
Some(color_cty),
)?;
let tgt_color_res = factory.view_texture_as_shader_resource::<TgtColorFmt>(
&tgt_color_tex,
(0, levels - 1),
gfx::format::Swizzle::new(),
)?;
let tgt_color_view = factory.view_texture_as_render_target(&tgt_color_tex, 0, None)?;
let depth_cty = <<TgtDepthFmt as gfx::format::Formatted>::Channel as gfx::format::ChannelTyped>::get_channel_type();
let tgt_depth_tex = factory.create_texture(
kind,
levels,
gfx::memory::Bind::DEPTH_STENCIL,
gfx::memory::Usage::Data,
Some(depth_cty),
)?;
let tgt_depth_view = factory.view_texture_as_depth_stencil_trivial(&tgt_depth_tex)?;
Ok((tgt_color_view, tgt_depth_view, tgt_color_res))
}
@ -319,33 +342,29 @@ impl Renderer {
type WinSurfaceData = <<WinColorFmt as Formatted>::Surface as SurfaceTyped>::DataType;
let download = self
.factory
.create_download_buffer::<WinSurfaceData>(width as usize * height as usize)
.map_err(|err| RenderError::BufferCreationError(err))?;
self.encoder
.copy_texture_to_buffer_raw(
self.win_color_view.raw().get_texture(),
None,
gfx::texture::RawImageInfo {
xoffset: 0,
yoffset: 0,
zoffset: 0,
width,
height,
depth: 0,
format: WinColorFmt::get_format(),
mipmap: 0,
},
download.raw(),
0,
)
.map_err(|err| RenderError::CopyError(err))?;
.create_download_buffer::<WinSurfaceData>(width as usize * height as usize)?;
self.encoder.copy_texture_to_buffer_raw(
self.win_color_view.raw().get_texture(),
None,
gfx::texture::RawImageInfo {
xoffset: 0,
yoffset: 0,
zoffset: 0,
width,
height,
depth: 0,
format: WinColorFmt::get_format(),
mipmap: 0,
},
download.raw(),
0,
)?;
self.flush();
// Assumes that the format is Rgba8.
let raw_data = self
.factory
.read_mapping(&download)
.map_err(|err| RenderError::MappingError(err))?
.read_mapping(&download)?
.chunks_exact(width as usize)
.rev()
.flatten()
@ -722,38 +741,23 @@ fn create_pipeline<'a, P: gfx::pso::PipelineInit>(
ctx: &IncludeContext,
cull_face: gfx::state::CullFace,
) -> Result<GfxPipeline<P>, RenderError> {
let vs = ctx.expand(vs).map_err(RenderError::IncludeError)?;
let fs = ctx.expand(fs).map_err(RenderError::IncludeError)?;
let vs = ctx.expand(vs)?;
let fs = ctx.expand(fs)?;
let program = factory
.link_program(vs.as_bytes(), fs.as_bytes())
.map_err(|err| RenderError::PipelineError(gfx::PipelineStateError::Program(err)))?;
let program = factory.link_program(vs.as_bytes(), fs.as_bytes())?;
Ok(GfxPipeline {
pso: factory
.create_pipeline_from_program(
&program,
gfx::Primitive::TriangleList,
gfx::state::Rasterizer {
front_face: gfx::state::FrontFace::CounterClockwise,
cull_face,
method: gfx::state::RasterMethod::Fill,
offset: None,
samples: Some(gfx::state::MultiSample),
},
pipe,
)
// Do some funky things to work around an oddity in gfx's error ownership rules.
.map_err(|err| {
RenderError::PipelineError(match err {
gfx::PipelineStateError::Program(err) => gfx::PipelineStateError::Program(err),
gfx::PipelineStateError::DescriptorInit(err) => {
gfx::PipelineStateError::DescriptorInit(err.into())
}
gfx::PipelineStateError::DeviceCreate(err) => {
gfx::PipelineStateError::DeviceCreate(err)
}
})
})?,
pso: factory.create_pipeline_from_program(
&program,
gfx::Primitive::TriangleList,
gfx::state::Rasterizer {
front_face: gfx::state::FrontFace::CounterClockwise,
cull_face,
method: gfx::state::RasterMethod::Fill,
offset: None,
samples: Some(gfx::state::MultiSample),
},
pipe,
)?, // Do some funky things to work around an oddity in gfx's error ownership rules.
})
}