Commit 5562d169 authored by Florian Oetke's avatar Florian Oetke
Browse files

basic transparent pass for particles

parent 95944522
......@@ -2,123 +2,123 @@
"keyframes": [
{
"time": 0.1,
"color": {"mean":{"value":0.8}, "stddev":{"value":0.2}},
"size": {"mean": {"x": 0.08}, "stddev":{"x": 0.04}},
"color": {"mean":{"value":0.8, "alpha":0.5}, "stddev":{"value":0.2}},
"size": {"mean": {"x": 0.5}, "stddev":{"x": 0.1}},
"rotation": {"mean":{"angle":0}, "stddev":{"angle": 1}},
"clip_rect": {"x":0, "y":0, "z":0.2, "w":0.333},
"drag": 0.5
"drag": 0.1
},
{
"time": 0.2,
"color": {"mean":{"value":0.8}, "stddev":{"value":0.2}},
"size": {"mean": {"x": 0.08}, "stddev":{"x": 0.04}},
"color": {"mean":{"value":0.8, "alpha":0.5}, "stddev":{"value":0.2}},
"size": {"mean": {"x": 0.5}, "stddev":{"x": 0.1}},
"rotation": {"mean":{"angle":0}, "stddev":{"angle": 1}},
"clip_rect": {"x":0.2, "y":0, "z":0.2, "w":0.333},
"drag": 0.5
"drag": 0.1
},
{
"time": 0.3,
"color": {"mean":{"value":0.8}, "stddev":{"value":0.2}},
"size": {"mean": {"x": 0.08}, "stddev":{"x": 0.04}},
"color": {"mean":{"value":0.8, "alpha":0.5}, "stddev":{"value":0.2}},
"size": {"mean": {"x": 0.5}, "stddev":{"x": 0.1}},
"rotation": {"mean":{"angle":0}, "stddev":{"angle": 1}},
"clip_rect": {"x":0.4, "y":0, "z":0.2, "w":0.333},
"drag": 0.5
"drag": 0.1
},
{
"time": 0.4,
"color": {"mean":{"value":0.8}, "stddev":{"value":0.2}},
"size": {"mean": {"x": 0.08}, "stddev":{"x": 0.04}},
"color": {"mean":{"value":0.8, "alpha":0.5}, "stddev":{"value":0.2}},
"size": {"mean": {"x": 0.5}, "stddev":{"x": 0.1}},
"rotation": {"mean":{"angle":0}, "stddev":{"angle": 1}},
"clip_rect": {"x":0.6, "y":0, "z":0.2, "w":0.333},
"drag": 0.5
"drag": 0.1
},
{
"time": 0.5,
"color": {"mean":{"value":0.8}, "stddev":{"value":0.2}},
"size": {"mean": {"x": 0.08}, "stddev":{"x": 0.04}},
"color": {"mean":{"value":0.8, "alpha":0.5}, "stddev":{"value":0.2}},
"size": {"mean": {"x": 0.5}, "stddev":{"x": 0.1}},
"rotation": {"mean":{"angle":0}, "stddev":{"angle": 1}},
"clip_rect": {"x":0.8, "y":0, "z":0.2, "w":0.333},
"drag": 0.5
"drag": 0.1
},
{
"time": 0.6,
"color": {"mean":{"value":0.8}, "stddev":{"value":0.2}},
"size": {"mean": {"x": 0.08}, "stddev":{"x": 0.04}},
"color": {"mean":{"value":0.8, "alpha":0.5}, "stddev":{"value":0.2}},
"size": {"mean": {"x": 0.5}, "stddev":{"x": 0.1}},
"rotation": {"mean":{"angle":0}, "stddev":{"angle": 1}},
"clip_rect": {"x":0, "y":0.333, "z":0.2, "w":0.333},
"drag": 0.5
"drag": 0.1
},
{
"time": 0.7,
"color": {"mean":{"value":0.8}, "stddev":{"value":0.2}},
"size": {"mean": {"x": 0.08}, "stddev":{"x": 0.04}},
"color": {"mean":{"value":0.8, "alpha":0.5}, "stddev":{"value":0.2}},
"size": {"mean": {"x": 0.5}, "stddev":{"x": 0.1}},
"rotation": {"mean":{"angle":0}, "stddev":{"angle": 1}},
"clip_rect": {"x":0.2, "y":0.333, "z":0.2, "w":0.333},
"drag": 0.5
"drag": 0.1
},
{
"time": 0.8,
"color": {"mean":{"value":0.8}, "stddev":{"value":0.2}},
"size": {"mean": {"x": 0.08}, "stddev":{"x": 0.04}},
"color": {"mean":{"value":0.8, "alpha":0.5}, "stddev":{"value":0.2}},
"size": {"mean": {"x": 0.5}, "stddev":{"x": 0.1}},
"rotation": {"mean":{"angle":0}, "stddev":{"angle": 1}},
"clip_rect": {"x":0.4, "y":0.333, "z":0.2, "w":0.333},
"drag": 0.5
"drag": 0.1
},
{
"time": 0.9,
"color": {"mean":{"value":0.8}, "stddev":{"value":0.2}},
"size": {"mean": {"x": 0.08}, "stddev":{"x": 0.04}},
"color": {"mean":{"value":0.8, "alpha":0.5}, "stddev":{"value":0.2}},
"size": {"mean": {"x": 0.5}, "stddev":{"x": 0.1}},
"rotation": {"mean":{"angle":0}, "stddev":{"angle": 1}},
"clip_rect": {"x":0.6, "y":0.333, "z":0.2, "w":0.333},
"drag": 0.5
"drag": 0.1
},
{
"time": 1,
"color": {"mean":{"value":0.8}, "stddev":{"value":0.2}},
"size": {"mean": {"x": 0.08}, "stddev":{"x": 0.04}},
"color": {"mean":{"value":0.8, "alpha":0.5}, "stddev":{"value":0.2}},
"size": {"mean": {"x": 0.5}, "stddev":{"x": 0.1}},
"rotation": {"mean":{"angle":0}, "stddev":{"angle": 1}},
"clip_rect": {"x":0.8, "y":0.333, "z":0.2, "w":0.333},
"drag": 0.5
"drag": 0.1
},
{
"time": 1.1,
"color": {"mean":{"value":0.8}, "stddev":{"value":0.2}},
"size": {"mean": {"x": 0.08}, "stddev":{"x": 0.04}},
"color": {"mean":{"value":0.8, "alpha":0.5}, "stddev":{"value":0.2}},
"size": {"mean": {"x": 0.5}, "stddev":{"x": 0.1}},
"rotation": {"mean":{"angle":0}, "stddev":{"angle": 1}},
"clip_rect": {"x":0, "y":0.666, "z":0.2, "w":0.333},
"drag": 0.5
"drag": 0.1
},
{
"time": 1.2,
"color": {"mean":{"value":0.8}, "stddev":{"value":0.2}},
"size": {"mean": {"x": 0.08}, "stddev":{"x": 0.04}},
"color": {"mean":{"value":0.8, "alpha":0.5}, "stddev":{"value":0.2}},
"size": {"mean": {"x": 0.5}, "stddev":{"x": 0.1}},
"rotation": {"mean":{"angle":0}, "stddev":{"angle": 1}},
"clip_rect": {"x":0.2, "y":0.666, "z":0.2, "w":0.333},
"drag": 0.5
"drag": 0.1
},
{
"time": 1.3,
"color": {"mean":{"value":0.8}, "stddev":{"value":0.2}},
"size": {"mean": {"x": 0.08}, "stddev":{"x": 0.04}},
"color": {"mean":{"value":0.8, "alpha":0.5}, "stddev":{"value":0.2}},
"size": {"mean": {"x": 0.5}, "stddev":{"x": 0.1}},
"rotation": {"mean":{"angle":0}, "stddev":{"angle": 1}},
"clip_rect": {"x":0.4, "y":0.666, "z":0.2, "w":0.333},
"drag": 0.5
"drag": 0.1
},
{
"time": 1.4,
"color": {"mean":{"value":0.8}, "stddev":{"value":0.2}},
"size": {"mean": {"x": 0.08}, "stddev":{"x": 0.04}},
"color": {"mean":{"value":0.8, "alpha":0.5}, "stddev":{"value":0.2}},
"size": {"mean": {"x": 0.5}, "stddev":{"x": 0.1}},
"rotation": {"mean":{"angle":0}, "stddev":{"angle": 1}},
"clip_rect": {"x":0.6, "y":0.666, "z":0.2, "w":0.333},
"drag": 0.5
"drag": 0.1
},
{
"time": 1.5,
"color": {"mean":{"value":0.8}, "stddev":{"value":0.2}},
"size": {"mean": {"x": 0.08}, "stddev":{"x": 0.04}},
"color": {"mean":{"value":0.8, "alpha":0.5}, "stddev":{"value":0.2}},
"size": {"mean": {"x": 0.5}, "stddev":{"x": 0.1}},
"rotation": {"mean":{"angle":0}, "stddev":{"angle": 1}},
"clip_rect": {"x":0.8, "y":0.666, "z":0.2, "w":0.333},
"drag": 0.5
"drag": 0.1
}
],
......@@ -126,7 +126,7 @@
"symmetric_scaling": true,
"rotate_with_velocity": false,
"blend": "solid",
"blend": "transparent",
"geometry": "billboard",
"material_id": "tex:smoke_particle.ktx",
......
......@@ -10,7 +10,7 @@
"ttl": {"mean": 20, "stddev": 4},
"velocity": {"mean": 0.5, "stddev": 0.3},
"velocity": {"mean": 0.01, "stddev": 0.008},
"emit_script_id": "comp_shader:particle_spawn_sphere",
......
......@@ -17,6 +17,7 @@
#include <mirrage/renderer/pass/ssao_pass.hpp>
#include <mirrage/renderer/pass/taa_pass.hpp>
#include <mirrage/renderer/pass/tone_mapping_pass.hpp>
#include <mirrage/renderer/pass/transparent_pass.hpp>
namespace mirrage {
......@@ -43,6 +44,7 @@ namespace mirrage {
renderer::make_pass_factory<renderer::Gen_mipmap_pass_factory>(),
renderer::make_pass_factory<renderer::Ssao_pass_factory>(),
renderer::make_pass_factory<renderer::Gi_pass_factory>(),
renderer::make_pass_factory<renderer::Transparent_pass_factory>(),
renderer::make_pass_factory<renderer::Taa_pass_factory>(),
renderer::make_pass_factory<renderer::Depth_of_field_pass_factory>(),
renderer::make_pass_factory<renderer::Bloom_pass_factory>(),
......
......@@ -60,6 +60,7 @@ add_library(mirrage_renderer STATIC
src/pass/ssao_pass.cpp
src/pass/taa_pass.cpp
src/pass/tone_mapping_pass.cpp
src/pass/transparent_pass.cpp
src/animation.cpp
src/animation_comp.cpp
......
......@@ -41,6 +41,11 @@ frag_shader:model_alphatest = shader/model_alphatest.frag.spv
vert_shader:particle = shader/particle.vert.spv
frag_shader:particle_solid = shader/particle_solid.frag.spv
frag_shader:particle_transparent_lit = shader/particle_transparent_lit.frag.spv
frag_shader:particle_transparent_unlit = shader/particle_transparent_unlit.frag.spv
vert_shader:transparent_compose = shader/fullscreen.vert.spv
frag_shader:transparent_compose = shader/transparent_compose.frag.spv
vert_shader:ui = shader/ui.vert.spv
frag_shader:ui = shader/ui.frag.spv
......
......@@ -52,6 +52,8 @@ namespace mirrage::renderer {
float max_display_luminance = 150.0f;
float amient_light_intensity = 0.1f;
int transparent_particle_mip_level = 1;
bool taa = true;
bool ssao = true;
bool bloom = true;
......@@ -79,6 +81,7 @@ namespace mirrage::renderer {
min_display_luminance,
max_display_luminance,
amient_light_intensity,
transparent_particle_mip_level,
taa,
ssao,
bloom,
......@@ -236,6 +239,8 @@ namespace mirrage::renderer {
auto noise_descriptor_set_layout() const noexcept { return *_noise_descriptor_set_layout; }
auto noise_descriptor_set() const noexcept { return *_noise_descriptor_set; }
auto billboard_model() const noexcept -> auto& { return _billboard_model; }
auto model_material_sampler() const noexcept { return _factory->model_material_sampler(); }
auto model_descriptor_set_layout() const noexcept { return _factory->model_descriptor_set_layout(); }
......@@ -292,6 +297,8 @@ namespace mirrage::renderer {
graphic::Image_descriptor_set_layout _noise_descriptor_set_layout;
graphic::DescriptorSet _noise_descriptor_set;
Model _billboard_model;
std::vector<Render_pass_factory*> _pass_factories;
std::vector<std::unique_ptr<Render_pass>> _passes;
......
......@@ -46,8 +46,6 @@ namespace mirrage::renderer {
ecs::Entity_manager& _ecs;
Deferred_renderer& _renderer;
Model _particle_billboard;
util::iter_range<std::vector<Geometry>::iterator> _geometry_range;
util::iter_range<std::vector<Geometry>::iterator> _rigged_geometry_range;
......
#pragma once
#include <mirrage/renderer/deferred_renderer.hpp>
#include <mirrage/graphic/render_pass.hpp>
namespace mirrage::renderer {
class Transparent_pass_factory;
class Transparent_pass : public Render_pass {
public:
using Factory = Transparent_pass_factory;
Transparent_pass(Deferred_renderer&, graphic::Render_target_2D& target);
void update(util::Time dt) override;
void draw(Frame_data&) override;
auto name() const noexcept -> const char* override { return "Transparent"; }
private:
Deferred_renderer& _renderer;
vk::Format _revealage_format;
graphic::Render_target_2D _accum;
graphic::Render_target_2D _revealage;
vk::UniqueSampler _sampler;
graphic::Image_descriptor_set_layout _desc_set_layout;
graphic::DescriptorSet _accum_descriptor_set;
std::vector<graphic::DescriptorSet> _compose_descriptor_sets;
std::vector<graphic::Framebuffer> _accum_framebuffers;
graphic::Render_pass _accum_render_pass;
graphic::Framebuffer _compose_framebuffer;
graphic::Render_pass _compose_render_pass;
};
class Transparent_pass_factory : public Render_pass_factory {
public:
auto id() const noexcept -> Render_pass_id override
{
return render_pass_id_of<Transparent_pass_factory>();
}
auto create_pass(Deferred_renderer&, util::maybe<ecs::Entity_manager&>, Engine&, bool&)
-> std::unique_ptr<Render_pass> override;
auto rank_device(vk::PhysicalDevice, util::maybe<std::uint32_t>, int) -> int override;
void configure_device(vk::PhysicalDevice,
util::maybe<std::uint32_t>,
graphic::Device_create_info&) override;
};
} // namespace mirrage::renderer
#version 450
#extension GL_ARB_separate_shader_objects : enable
#extension GL_ARB_shading_language_420pack : enable
#include "global_uniforms.glsl"
#include "normal_encoding.glsl"
#include "particle/data_structures.glsl"
layout(early_fragment_tests) in;
layout(location = 0) in vec3 view_pos;
layout(location = 1) in vec3 normal;
layout(location = 2) in vec2 tex_coords;
layout(location = 3) in vec4 out_particle_color;
layout(location = 0) out vec4 accum_out;
layout(location = 1) out vec4 revealage_out;
layout(set=1, binding = 0) uniform sampler2D albedo_sampler;
layout(set=1, binding = 1) uniform sampler2D normal_sampler;
layout(set=1, binding = 2) uniform sampler2D brdf_sampler;
layout(set=1, binding = 3) uniform sampler2D emission_sampler;
layout(std140, set=2, binding = 0) readonly buffer Particle_type_config {
PARTICLE_TYPE_CONFIG
} particle_config;
layout(push_constant) uniform Per_model_uniforms {
mat4 model;
vec4 light_color;
vec4 options;
} model_uniforms;
const float PI = 3.14159265359;
vec3 decode_tangent_normal(vec2 tn);
vec3 tangent_space_to_world(vec3 N);
void main() {
vec4 albedo = texture(albedo_sampler, tex_coords);
albedo *= out_particle_color;
if(albedo.a<0.001) {
discard;
}
vec3 N = tangent_space_to_world(decode_tangent_normal(texture(normal_sampler, tex_coords).rg));
vec4 brdf = texture(brdf_sampler, tex_coords);
float roughness = brdf.r;
float metallic = brdf.g;
roughness = mix(0.01, 0.99, roughness*roughness);
float emissive_power = texture(emission_sampler, tex_coords).r;
vec4 result_color = vec4(0,0,0,0);
vec3 transmit = vec3(1.0 - albedo.a);
result_color.rgb += albedo.rgb * emissive_power * albedo.a;
// TODO: lighting
result_color += vec4(albedo.rgb * albedo.a, albedo.a);
/* Modulate the net coverage for composition by the transmission. This does not affect the color channels of the
transparent surface because the caller's BSDF model should have already taken into account if transmission modulates
reflection. This model doesn't handled colored transmission, so it averages the color channels. See
McGuire and Enderton, Colored Stochastic Shadow Maps, ACM I3D, February 2011
http://graphics.cs.williams.edu/papers/CSSM/
for a full explanation and derivation.*/
result_color.a *= 1.0 - clamp((transmit.r + transmit.g + transmit.b) * (1.0 / 3.0), 0, 1);
/* You may need to adjust the w function if you have a very large or very small view volume; see the paper and
presentation slides at http://jcgt.org/published/0002/02/09/ */
// Intermediate terms to be cubed
float a = min(1.0, result_color.a) * 8.0 + 0.01;
float b = -gl_FragCoord.z * 0.95 + 1.0;
/* If your scene has a lot of content very close to the far plane,
then include this line (one rsqrt instruction):
b /= sqrt(1e4 * abs(csZ)); */
float w = clamp(a * a * a * 1e8 * b * b * b, 1e-2, 3e2);
accum_out = result_color * w;
revealage_out = vec4(result_color.a, 0,0,0);
}
vec3 decode_tangent_normal(vec2 tn) {
if(dot(tn,tn)<0.00001)
return vec3(0,0,1);
vec3 N = vec3(tn*2-1, 0);
N.z = sqrt(1 - dot(N.xy, N.xy));
return N;
}
vec3 tangent_space_to_world(vec3 N) {
vec3 VN = normalize(normal);
// calculate tangent
vec3 p_dx = dFdx(view_pos);
vec3 p_dy = dFdy(view_pos);
vec2 tc_dx = dFdx(tex_coords);
vec2 tc_dy = dFdy(tex_coords);
vec3 p_dy_N = cross(p_dy, VN);
vec3 p_dx_N = cross(VN, p_dx);
vec3 T = p_dy_N * tc_dx.x + p_dx_N * tc_dy.x;
vec3 B = p_dy_N * tc_dx.y + p_dx_N * tc_dy.y;
float inv_max = inversesqrt(max(dot(T,T), dot(B,B)));
mat3 TBN = mat3(T*inv_max, B*inv_max, VN);
return normalize(TBN * N);
}
#version 450
#extension GL_ARB_separate_shader_objects : enable
#extension GL_ARB_shading_language_420pack : enable
#include "global_uniforms.glsl"
#include "normal_encoding.glsl"
#include "particle/data_structures.glsl"
layout(early_fragment_tests) in;
layout(location = 0) in vec3 view_pos;
layout(location = 1) in vec3 normal;
layout(location = 2) in vec2 tex_coords;
layout(location = 3) in vec4 out_particle_color;
layout(location = 0) out vec4 depth_out;
layout(location = 1) out vec4 albedo_mat_id_out;
layout(location = 2) out vec4 mat_data_out;
layout(location = 3) out vec4 color_out;
layout(location = 4) out vec4 color_diffuse_out;
layout(set=1, binding = 0) uniform sampler2D albedo_sampler;
layout(set=1, binding = 1) uniform sampler2D normal_sampler;
layout(set=1, binding = 2) uniform sampler2D brdf_sampler;
layout(set=1, binding = 3) uniform sampler2D emission_sampler;
layout(std140, set=2, binding = 0) readonly buffer Particle_type_config {
PARTICLE_TYPE_CONFIG
} particle_config;
layout(push_constant) uniform Per_model_uniforms {
mat4 model;
vec4 light_color;
vec4 options;
} model_uniforms;
const float PI = 3.14159265359;
vec3 decode_tangent_normal(vec2 tn);
vec3 tangent_space_to_world(vec3 N);
void main() {
vec4 albedo = texture(albedo_sampler, tex_coords);
albedo *= out_particle_color;
vec3 N = tangent_space_to_world(decode_tangent_normal(texture(normal_sampler, tex_coords).rg));
vec4 brdf = texture(brdf_sampler, tex_coords);
float roughness = brdf.r;
float metallic = brdf.g;
roughness = mix(0.01, 0.99, roughness*roughness);
depth_out = vec4(-view_pos.z / global_uniforms.proj_planes.y, 0,0,1);
albedo_mat_id_out = vec4(albedo.rgb, 0.0);
mat_data_out = vec4(encode_normal(N), roughness, metallic);
float emissive_power = texture(emission_sampler, tex_coords).r;
color_out = vec4(albedo.rgb * emissive_power * albedo.a, 1.0);
color_diffuse_out = color_out;
}
vec3 decode_tangent_normal(vec2 tn) {
if(dot(tn,tn)<0.00001)
return vec3(0,0,1);
vec3 N = vec3(tn*2-1, 0);
N.z = sqrt(1 - dot(N.xy, N.xy));
return N;
}
vec3 tangent_space_to_world(vec3 N) {
vec3 VN = normalize(normal);
// calculate tangent
vec3 p_dx = dFdx(view_pos);
vec3 p_dy = dFdy(view_pos);
vec2 tc_dx = dFdx(tex_coords);
vec2 tc_dy = dFdy(tex_coords);
vec3 p_dy_N = cross(p_dy, VN);
vec3 p_dx_N = cross(VN, p_dx);
vec3 T = p_dy_N * tc_dx.x + p_dx_N * tc_dy.x;
vec3 B = p_dy_N * tc_dx.y + p_dx_N * tc_dy.y;
float inv_max = inversesqrt(max(dot(T,T), dot(B,B)));
mat3 TBN = mat3(T*inv_max, B*inv_max, VN);
return normalize(TBN * N);
}
#version 450
#extension GL_ARB_separate_shader_objects : enable
#extension GL_ARB_shading_language_420pack : enable
#include "global_uniforms.glsl"
#include "normal_encoding.glsl"
#include "poisson.glsl"
#include "random.glsl"
#include "brdf.glsl"
layout(location = 0) in Vertex_data {
vec2 tex_coords;
} vertex_out;