Merge branch 'gradientsobel' into 'master'

Add `GradientSobel` experimental filter that adds object outlines based on the normal map.

See merge request veloren/veloren!3975
This commit is contained in:
Imbris 2023-06-08 16:59:20 +00:00
commit 69dcc12dcd
4 changed files with 67 additions and 3 deletions

View File

@ -45,6 +45,15 @@ uniform u_locals {
#ifdef BLOOM_FACTOR
layout(set = 1, binding = 5)
uniform texture2D t_src_bloom;
#ifdef EXPERIMENTAL_GRADIENTSOBEL
layout(set = 1, binding = 6)
uniform utexture2D t_src_mat;
#endif
#else
#ifdef EXPERIMENTAL_GRADIENTSOBEL
layout(set = 1, binding = 5)
uniform utexture2D t_src_mat;
#endif
#endif
layout(location = 0) out vec4 tgt_color;
@ -165,6 +174,13 @@ vec3 aa_sample(vec2 uv, vec2 off) {
return aa_apply(t_src_color, s_src_color, t_src_depth, s_src_depth, uv * screen_res.xy + off, screen_res.xy).rgb;
}
#endif
#ifdef EXPERIMENTAL_GRADIENTSOBEL
vec3 aa_sample_grad(vec2 uv, vec2 off) {
uvec2 mat_sz = textureSize(usampler2D(t_src_mat, s_src_depth), 0);
uvec4 mat = texelFetch(usampler2D(t_src_mat, s_src_depth), clamp(ivec2(uv * mat_sz + off), ivec2(0), ivec2(mat_sz) - 1), 0);
return vec3(mat.xyz) / 255.0;
}
#endif
#ifdef EXPERIMENTAL_COLORDITHERING
float dither(ivec2 p, float level) {
@ -249,6 +265,21 @@ void main() {
float mag = length(gx) + length(gy);
aa_color.rgb = mix(vec3(0.9), aa_color.rgb * 0.8, clamp(1.0 - mag * 0.3, 0.0, 1.0));
#endif
#ifdef EXPERIMENTAL_GRADIENTSOBEL
vec3 s2[8];
s2[0] = aa_sample_grad(uv, vec2(-1, 1));
s2[1] = aa_sample_grad(uv, vec2( 0, 1));
s2[2] = aa_sample_grad(uv, vec2( 1, 1));
s2[3] = aa_sample_grad(uv, vec2(-1, 0));
s2[4] = aa_sample_grad(uv, vec2( 1, 0));
s2[5] = aa_sample_grad(uv, vec2(-1, -1));
s2[6] = aa_sample_grad(uv, vec2( 0, -1));
s2[7] = aa_sample_grad(uv, vec2( 1, -1));
vec3 gx2 = s2[0] + s2[3] * 2.0 + s2[5] - s2[2] - s2[4] * 2 - s2[7];
vec3 gy2 = s2[0] + s2[1] * 2.0 + s2[2] - s2[5] - s2[6] * 2 - s2[7];
float mag2 = length(gx2) + length(gy2);
aa_color.rgb = mix(vec3(0.0), aa_color.rgb * 0.8, clamp(1.0 - mag2 * 0.3, 0.0, 1.0));
#endif
// Bloom
#ifdef BLOOM_FACTOR

View File

@ -490,6 +490,8 @@ pub enum ExperimentalShader {
/// post-processing so there is potentially a significant performance
/// impact especially with anti aliasing enabled.
Sobel,
/// Like Sobel, but on the gradient texture instead of the color texture.
GradientSobel,
/// Simulate a curved world.
CurvedWorld,
/// Adds extra detail to distant LoD (Level of Detail) terrain procedurally.

View File

@ -1,4 +1,4 @@
use super::super::{Consts, GlobalsLayouts, PipelineModes};
use super::super::{Consts, ExperimentalShader, GlobalsLayouts, PipelineModes};
use bytemuck::{Pod, Zeroable};
use vek::*;
@ -28,6 +28,7 @@ pub struct BindGroup {
pub struct PostProcessLayout {
pub layout: wgpu::BindGroupLayout,
mat_tex_present: bool,
}
impl PostProcessLayout {
@ -86,11 +87,12 @@ impl PostProcessLayout {
},
];
let mut binding = 5;
if pipeline_modes.bloom.is_on() {
bind_entries.push(
// src bloom
wgpu::BindGroupLayoutEntry {
binding: 5,
binding,
visibility: wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::Texture {
sample_type: wgpu::TextureSampleType::Float { filterable: true },
@ -100,6 +102,23 @@ impl PostProcessLayout {
count: None,
},
);
binding += 1;
}
let mat_tex_present = pipeline_modes
.experimental_shaders
.contains(&ExperimentalShader::GradientSobel);
if mat_tex_present {
// Material source
bind_entries.push(wgpu::BindGroupLayoutEntry {
binding,
visibility: wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::Texture {
sample_type: wgpu::TextureSampleType::Uint,
view_dimension: wgpu::TextureViewDimension::D2,
multisampled: false,
},
count: None,
});
}
Self {
@ -107,6 +126,7 @@ impl PostProcessLayout {
label: None,
entries: &bind_entries,
}),
mat_tex_present,
}
}
@ -115,6 +135,7 @@ impl PostProcessLayout {
device: &wgpu::Device,
src_color: &wgpu::TextureView,
src_depth: &wgpu::TextureView,
src_mat: &wgpu::TextureView,
src_bloom: Option<&wgpu::TextureView>,
sampler: &wgpu::Sampler,
depth_sampler: &wgpu::Sampler,
@ -142,6 +163,7 @@ impl PostProcessLayout {
resource: locals.buf().as_entire_binding(),
},
];
let mut binding = 5;
// Optional bloom source
if let Some(src_bloom) = src_bloom {
entries.push(
@ -150,10 +172,17 @@ impl PostProcessLayout {
// TODO: if there is no upscaling we can do the last bloom upsampling in post
// process to save a pass and the need for the final full size bloom render target
wgpu::BindGroupEntry {
binding: 5,
binding,
resource: wgpu::BindingResource::TextureView(src_bloom),
},
);
binding += 1;
}
if self.mat_tex_present {
entries.push(wgpu::BindGroupEntry {
binding,
resource: wgpu::BindingResource::TextureView(src_mat),
});
}
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {

View File

@ -50,6 +50,7 @@ impl Locals {
device,
tgt_color_pp_view,
tgt_depth_view,
tgt_mat_view,
bloom.as_ref().map(|b| b.final_tgt_view),
sampler,
depth_sampler,
@ -99,6 +100,7 @@ impl Locals {
device,
tgt_color_pp_view,
tgt_depth_view,
tgt_mat_view,
bloom.as_ref().map(|b| b.final_tgt_view),
sampler,
depth_sampler,