Add SMAA pass
This commit is contained in:
parent
5b035874ab
commit
57a2ae9c0a
17 changed files with 17394 additions and 10 deletions
1
3rdparty/CMakeLists.txt
vendored
1
3rdparty/CMakeLists.txt
vendored
|
@ -1,3 +1,4 @@
|
||||||
add_subdirectory(imgui)
|
add_subdirectory(imgui)
|
||||||
add_subdirectory(nlohmann)
|
add_subdirectory(nlohmann)
|
||||||
add_subdirectory(stb)
|
add_subdirectory(stb)
|
||||||
|
add_subdirectory(smaa)
|
||||||
|
|
4
3rdparty/smaa/CMakeLists.txt
vendored
Executable file
4
3rdparty/smaa/CMakeLists.txt
vendored
Executable file
|
@ -0,0 +1,4 @@
|
||||||
|
add_library(SMAA INTERFACE)
|
||||||
|
target_include_directories(SMAA INTERFACE include)
|
||||||
|
|
||||||
|
add_library(SMAA::SMAA ALIAS SMAA)
|
14980
3rdparty/smaa/include/AreaTex.h
vendored
Executable file
14980
3rdparty/smaa/include/AreaTex.h
vendored
Executable file
File diff suppressed because it is too large
Load diff
132
3rdparty/smaa/include/SearchTex.h
vendored
Executable file
132
3rdparty/smaa/include/SearchTex.h
vendored
Executable file
|
@ -0,0 +1,132 @@
|
||||||
|
/**
|
||||||
|
* Copyright (C) 2013 Jorge Jimenez (jorge@iryoku.com)
|
||||||
|
* Copyright (C) 2013 Jose I. Echevarria (joseignacioechevarria@gmail.com)
|
||||||
|
* Copyright (C) 2013 Belen Masia (bmasia@unizar.es)
|
||||||
|
* Copyright (C) 2013 Fernando Navarro (fernandn@microsoft.com)
|
||||||
|
* Copyright (C) 2013 Diego Gutierrez (diegog@unizar.es)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is furnished to
|
||||||
|
* do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software. As clarification, there
|
||||||
|
* is no requirement that the copyright notice and permission be included in
|
||||||
|
* binary distributions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SEARCHTEX_H
|
||||||
|
#define SEARCHTEX_H
|
||||||
|
|
||||||
|
#define SEARCHTEX_WIDTH 64
|
||||||
|
#define SEARCHTEX_HEIGHT 16
|
||||||
|
#define SEARCHTEX_PITCH SEARCHTEX_WIDTH
|
||||||
|
#define SEARCHTEX_SIZE (SEARCHTEX_HEIGHT * SEARCHTEX_PITCH)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stored in R8 format. Load it in the following format:
|
||||||
|
* - DX9: D3DFMT_L8
|
||||||
|
* - DX10: DXGI_FORMAT_R8_UNORM
|
||||||
|
*/
|
||||||
|
static const unsigned char searchTexBytes[] = {
|
||||||
|
0xfe, 0xfe, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x7f, 0x7f,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00,
|
||||||
|
0x7f, 0x7f, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0xfe, 0x7f, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0xfe,
|
||||||
|
0xfe, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f,
|
||||||
|
0x7f, 0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xfe, 0xfe, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x7f, 0x7f,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00,
|
||||||
|
0x7f, 0x7f, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0xfe, 0x7f, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0xfe,
|
||||||
|
0xfe, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f,
|
||||||
|
0x7f, 0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x7f,
|
||||||
|
0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f,
|
||||||
|
0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f,
|
||||||
|
0x7f, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00,
|
||||||
|
0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x7f,
|
||||||
|
0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f,
|
||||||
|
0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f,
|
||||||
|
0x7f, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x00, 0x00,
|
||||||
|
0x7f, 0x7f, 0x00, 0x7f, 0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00,
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -57,7 +57,8 @@ set(GRAPH_SRC
|
||||||
src/animationsystem.cpp
|
src/animationsystem.cpp
|
||||||
src/worldmanager.cpp
|
src/worldmanager.cpp
|
||||||
src/assetmanager.cpp
|
src/assetmanager.cpp
|
||||||
src/entityparser.cpp)
|
src/entityparser.cpp
|
||||||
|
src/smaapass.cpp)
|
||||||
|
|
||||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
set(GRAPH_SRC
|
set(GRAPH_SRC
|
||||||
|
@ -77,7 +78,8 @@ target_link_libraries(Graph
|
||||||
Vulkan::Vulkan
|
Vulkan::Vulkan
|
||||||
assimp::assimp
|
assimp::assimp
|
||||||
nlohmann::json
|
nlohmann::json
|
||||||
stb::stb)
|
stb::stb
|
||||||
|
SMAA::SMAA)
|
||||||
|
|
||||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
target_link_libraries(Graph
|
target_link_libraries(Graph
|
||||||
|
@ -102,7 +104,11 @@ add_shaders(Graph
|
||||||
shaders/imgui.frag
|
shaders/imgui.frag
|
||||||
shaders/sky.vert
|
shaders/sky.vert
|
||||||
shaders/sky.frag
|
shaders/sky.frag
|
||||||
shaders/shadow.vert)
|
shaders/shadow.vert
|
||||||
|
shaders/edge.vert
|
||||||
|
shaders/edge.frag
|
||||||
|
shaders/blend.vert
|
||||||
|
shaders/blend.frag)
|
||||||
|
|
||||||
add_data(Graph
|
add_data(Graph
|
||||||
data/suzanne.obj
|
data/suzanne.obj
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "imguipass.h"
|
#include "imguipass.h"
|
||||||
#include "skypass.h"
|
#include "skypass.h"
|
||||||
#include "shadowpass.h"
|
#include "shadowpass.h"
|
||||||
|
#include "smaapass.h"
|
||||||
|
|
||||||
constexpr int numFrameResources = 2;
|
constexpr int numFrameResources = 2;
|
||||||
|
|
||||||
|
@ -55,6 +56,19 @@ struct RenderTarget {
|
||||||
VkSemaphore renderFinishedSemaphore = nullptr;
|
VkSemaphore renderFinishedSemaphore = nullptr;
|
||||||
VkFence* fences = nullptr;
|
VkFence* fences = nullptr;
|
||||||
|
|
||||||
|
// smaa
|
||||||
|
VkImage* edgeImages = nullptr;
|
||||||
|
VkDeviceMemory* edgeMemorys = nullptr;
|
||||||
|
VkImageView* edgeImageViews = nullptr;
|
||||||
|
VkFramebuffer* edgeFramebuffers = nullptr;
|
||||||
|
VkDescriptorSet* edgeDescriptorSets = nullptr;
|
||||||
|
|
||||||
|
VkImage* blendImages = nullptr;
|
||||||
|
VkDeviceMemory* blendMemorys = nullptr;
|
||||||
|
VkImageView* blendImageViews = nullptr;
|
||||||
|
VkFramebuffer* blendFramebuffers = nullptr;
|
||||||
|
VkDescriptorSet* blendDescriptorSets = nullptr;
|
||||||
|
|
||||||
// imgui
|
// imgui
|
||||||
VkBuffer* imguiVertexBuffers = nullptr;
|
VkBuffer* imguiVertexBuffers = nullptr;
|
||||||
VkDeviceMemory* imguiVertexMemorys = nullptr;
|
VkDeviceMemory* imguiVertexMemorys = nullptr;
|
||||||
|
@ -92,7 +106,7 @@ public:
|
||||||
|
|
||||||
VkShaderModule createShader(const char* path);
|
VkShaderModule createShader(const char* path);
|
||||||
|
|
||||||
void uploadImageData(VkImage image, int width, int height, VkDeviceSize size, void* src);
|
void uploadImageData(VkImage image, int width, int height, VkDeviceSize size, const void* src);
|
||||||
|
|
||||||
uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties);
|
uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties);
|
||||||
|
|
||||||
|
@ -193,4 +207,5 @@ private:
|
||||||
#endif
|
#endif
|
||||||
SkyPass* skyPass_ = nullptr;
|
SkyPass* skyPass_ = nullptr;
|
||||||
ShadowPass* shadowPass_ = nullptr;
|
ShadowPass* shadowPass_ = nullptr;
|
||||||
|
SMAAPass* smaaPass_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|
59
include/smaapass.h
Normal file
59
include/smaapass.h
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vulkan/vulkan.h>
|
||||||
|
|
||||||
|
class Renderer;
|
||||||
|
struct RenderTarget;
|
||||||
|
|
||||||
|
class SMAAPass {
|
||||||
|
public:
|
||||||
|
SMAAPass(Renderer& renderer);
|
||||||
|
~SMAAPass();
|
||||||
|
|
||||||
|
void render(VkCommandBuffer commandBuffer, RenderTarget* target);
|
||||||
|
|
||||||
|
void createDescriptorSets(RenderTarget* target);
|
||||||
|
|
||||||
|
VkRenderPass getEdgeRenderPass() const {
|
||||||
|
return edgeRenderPass;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkRenderPass getBlendRenderPass() const {
|
||||||
|
return blendRenderPass;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void loadResources();
|
||||||
|
|
||||||
|
void setupDescriptorLayouts();
|
||||||
|
void createOffscreenResources();
|
||||||
|
void createRenderPasses();
|
||||||
|
void createPipelines();
|
||||||
|
|
||||||
|
VkImage areaImage;
|
||||||
|
VkDeviceMemory areaMemory;
|
||||||
|
VkImageView areaImageView;
|
||||||
|
VkSampler areaSampler;
|
||||||
|
|
||||||
|
VkImage searchImage;
|
||||||
|
VkDeviceMemory searchMemory;
|
||||||
|
VkImageView searchImageView;
|
||||||
|
VkSampler searchSampler;
|
||||||
|
|
||||||
|
VkSampler edgeSampler;
|
||||||
|
VkSampler blendSampler;
|
||||||
|
|
||||||
|
VkRenderPass edgeRenderPass, blendRenderPass;
|
||||||
|
|
||||||
|
// edge
|
||||||
|
VkDescriptorSetLayout edgeDescriptorSetLayout;
|
||||||
|
VkPipelineLayout edgePipelineLayout;
|
||||||
|
VkPipeline edgePipeline;
|
||||||
|
|
||||||
|
// blend
|
||||||
|
VkDescriptorSetLayout blendDescriptorSetLayout;
|
||||||
|
VkPipelineLayout blendPipelineLayout;
|
||||||
|
VkPipeline blendPipeline;
|
||||||
|
|
||||||
|
Renderer& renderer;
|
||||||
|
};
|
27
shaders/blend.frag
Executable file
27
shaders/blend.frag
Executable file
|
@ -0,0 +1,27 @@
|
||||||
|
#version 460 core
|
||||||
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
|
||||||
|
#define SMAA_RT_METRICS vec4(1.0 / 1280.0, 1.0 / 720.0, 1280.0, 720.0)
|
||||||
|
|
||||||
|
#define SMAA_PRESET_ULTRA 1
|
||||||
|
#define SMAA_GLSL_4 1
|
||||||
|
#define SMAA_INCLUDE_VS 0
|
||||||
|
#define SMAA_INCLUDE_PS 1
|
||||||
|
#define SMAA_PREDICATION 1
|
||||||
|
#define SMAA_FLIP_Y 0
|
||||||
|
|
||||||
|
#include "smaa.glsl"
|
||||||
|
|
||||||
|
layout(location = 0) in vec2 inUV;
|
||||||
|
layout(location = 1) in vec4 inOffset[3];
|
||||||
|
layout(location = 5) in vec2 inPixUV;
|
||||||
|
|
||||||
|
layout(location = 0) out vec4 outColor;
|
||||||
|
|
||||||
|
layout(binding = 0) uniform sampler2D edgeSampler;
|
||||||
|
layout(binding = 1) uniform sampler2D areaSampler;
|
||||||
|
layout(binding = 2) uniform sampler2D searchSampler;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
outColor = SMAABlendingWeightCalculationPS(inUV, inPixUV, inOffset, edgeSampler, areaSampler, searchSampler, ivec4(0));
|
||||||
|
}
|
24
shaders/blend.vert
Executable file
24
shaders/blend.vert
Executable file
|
@ -0,0 +1,24 @@
|
||||||
|
#version 460 core
|
||||||
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
|
||||||
|
#define SMAA_RT_METRICS vec4(1.0 / 1280.0, 1.0 / 720.0, 1280.0, 720.0)
|
||||||
|
|
||||||
|
#define SMAA_PRESET_ULTRA 1
|
||||||
|
#define SMAA_GLSL_4 1
|
||||||
|
#define SMAA_INCLUDE_VS 1
|
||||||
|
#define SMAA_INCLUDE_PS 0
|
||||||
|
#define SMAA_PREDICATION 1
|
||||||
|
#define SMAA_FLIP_Y 0
|
||||||
|
|
||||||
|
#include "smaa.glsl"
|
||||||
|
|
||||||
|
layout(location = 0) out vec2 outUV;
|
||||||
|
layout(location = 1) out vec4 outOffset[3];
|
||||||
|
layout(location = 5) out vec2 outPixUV;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
|
||||||
|
gl_Position = vec4(outUV * 2.0 + -1.0, 0.0, 1.0);
|
||||||
|
|
||||||
|
SMAABlendingWeightCalculationVS(outUV, outPixUV, outOffset);
|
||||||
|
}
|
27
shaders/edge.frag
Executable file
27
shaders/edge.frag
Executable file
|
@ -0,0 +1,27 @@
|
||||||
|
#version 460 core
|
||||||
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
|
||||||
|
#define SMAA_RT_METRICS vec4(1.0 / 1280.0, 1.0 / 720.0, 1280.0, 720.0)
|
||||||
|
|
||||||
|
#define SMAA_PRESET_ULTRA 1
|
||||||
|
#define SMAA_GLSL_4 1
|
||||||
|
#define SMAA_INCLUDE_VS 0
|
||||||
|
#define SMAA_INCLUDE_PS 1
|
||||||
|
#define SMAA_PREDICATION 1
|
||||||
|
#define SMAA_FLIP_Y 0
|
||||||
|
|
||||||
|
#include "smaa.glsl"
|
||||||
|
|
||||||
|
layout(location = 0) in vec2 inUV;
|
||||||
|
layout(location = 1) in vec4 inOffset[3];
|
||||||
|
|
||||||
|
layout(location = 0) out vec4 outColor;
|
||||||
|
|
||||||
|
layout(binding = 0) uniform sampler2D imageSampler;
|
||||||
|
layout(binding = 1) uniform sampler2D depthSampler;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec2 edge = SMAALumaEdgeDetectionPS(inUV, inOffset, imageSampler, depthSampler);
|
||||||
|
|
||||||
|
outColor = vec4(edge, 0.0, 1.0);
|
||||||
|
}
|
23
shaders/edge.vert
Executable file
23
shaders/edge.vert
Executable file
|
@ -0,0 +1,23 @@
|
||||||
|
#version 460 core
|
||||||
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
|
||||||
|
#define SMAA_RT_METRICS vec4(1.0 / 1280.0, 1.0 / 720.0, 1280.0, 720.0)
|
||||||
|
|
||||||
|
#define SMAA_PRESET_ULTRA 1
|
||||||
|
#define SMAA_GLSL_4 1
|
||||||
|
#define SMAA_INCLUDE_VS 1
|
||||||
|
#define SMAA_INCLUDE_PS 0
|
||||||
|
#define SMAA_PREDICATION 1
|
||||||
|
#define SMAA_FLIP_Y 0
|
||||||
|
|
||||||
|
#include "smaa.glsl"
|
||||||
|
|
||||||
|
layout(location = 0) out vec2 outUV;
|
||||||
|
layout(location = 1) out vec4 outOffset[3];
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
|
||||||
|
gl_Position = vec4(outUV * 2.0 + -1.0, 0.0, 1.0);
|
||||||
|
|
||||||
|
SMAAEdgeDetectionVS(outUV, outOffset);
|
||||||
|
}
|
|
@ -1,6 +1,19 @@
|
||||||
#version 460 core
|
#version 460 core
|
||||||
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
|
||||||
|
#define SMAA_RT_METRICS vec4(1.0 / 1280.0, 1.0 / 720.0, 1280.0, 720.0)
|
||||||
|
|
||||||
|
#define SMAA_PRESET_ULTRA 1
|
||||||
|
#define SMAA_GLSL_4 1
|
||||||
|
#define SMAA_INCLUDE_VS 0
|
||||||
|
#define SMAA_INCLUDE_PS 1
|
||||||
|
#define SMAA_PREDICATION 1
|
||||||
|
#define SMAA_FLIP_Y 0
|
||||||
|
|
||||||
|
#include "smaa.glsl"
|
||||||
|
|
||||||
layout(location = 0) in vec2 inUV;
|
layout(location = 0) in vec2 inUV;
|
||||||
|
layout(location = 1) in vec4 inOffset;
|
||||||
|
|
||||||
layout(location = 0) out vec4 outColor;
|
layout(location = 0) out vec4 outColor;
|
||||||
|
|
||||||
|
@ -8,9 +21,11 @@ layout(binding = 0) uniform sampler2D sceneSampler;
|
||||||
layout(binding = 1) uniform sampler2D depthSampler;
|
layout(binding = 1) uniform sampler2D depthSampler;
|
||||||
layout(binding = 2) uniform sampler2D nearFieldSampler;
|
layout(binding = 2) uniform sampler2D nearFieldSampler;
|
||||||
layout(binding = 3) uniform sampler2D farFieldSampler;
|
layout(binding = 3) uniform sampler2D farFieldSampler;
|
||||||
|
layout(binding = 4) uniform sampler2D blendSampler;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec3 sceneColor = texture(sceneSampler, inUV).rgb;
|
vec3 sceneColor = vec3(0);
|
||||||
|
sceneColor = SMAANeighborhoodBlendingPS(inUV, inOffset, sceneSampler, blendSampler).rgb;
|
||||||
|
|
||||||
// alpha divide reconstruction
|
// alpha divide reconstruction
|
||||||
vec3 farColor = texture(farFieldSampler, inUV).rgb / max(texture(farFieldSampler, inUV).a, 0.0001) * 0.02;
|
vec3 farColor = texture(farFieldSampler, inUV).rgb / max(texture(farFieldSampler, inUV).a, 0.0001) * 0.02;
|
||||||
|
|
|
@ -1,9 +1,24 @@
|
||||||
#version 460 core
|
#version 460 core
|
||||||
|
#extension GL_GOOGLE_include_directive : enable
|
||||||
|
|
||||||
|
#define SMAA_RT_METRICS vec4(1.0 / 1280.0, 1.0 / 720.0, 1280.0, 720.0)
|
||||||
|
|
||||||
|
#define SMAA_PRESET_ULTRA 1
|
||||||
|
#define SMAA_GLSL_4 1
|
||||||
|
#define SMAA_INCLUDE_VS 1
|
||||||
|
#define SMAA_INCLUDE_PS 0
|
||||||
|
#define SMAA_PREDICATION 1
|
||||||
|
#define SMAA_FLIP_Y 0
|
||||||
|
|
||||||
|
#include "smaa.glsl"
|
||||||
|
|
||||||
layout(location = 0) out vec2 outUV;
|
layout(location = 0) out vec2 outUV;
|
||||||
|
layout(location = 1) out vec4 outOffset;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
|
outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
|
||||||
gl_Position = vec4(outUV * 2.0 + -1.0, 0.0, 1.0);
|
gl_Position = vec4(outUV * 2.0 + -1.0, 0.0, 1.0);
|
||||||
|
|
||||||
|
SMAANeighborhoodBlendingVS(outUV, outOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
1407
shaders/smaa.glsl
Executable file
1407
shaders/smaa.glsl
Executable file
File diff suppressed because it is too large
Load diff
|
@ -64,6 +64,11 @@ void PostPass::createDescriptorSet(RenderTarget* target) {
|
||||||
farFieldImageInfo.imageView = target->farFieldImageViews[i];
|
farFieldImageInfo.imageView = target->farFieldImageViews[i];
|
||||||
farFieldImageInfo.sampler = offscreenSampler_;
|
farFieldImageInfo.sampler = offscreenSampler_;
|
||||||
|
|
||||||
|
VkDescriptorImageInfo blendImageInfo = {};
|
||||||
|
blendImageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||||
|
blendImageInfo.imageView = target->blendImageViews[i];
|
||||||
|
blendImageInfo.sampler = offscreenSampler_;
|
||||||
|
|
||||||
VkWriteDescriptorSet sceneDescriptorWrite = {};
|
VkWriteDescriptorSet sceneDescriptorWrite = {};
|
||||||
sceneDescriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
sceneDescriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||||
sceneDescriptorWrite.descriptorCount = 1;
|
sceneDescriptorWrite.descriptorCount = 1;
|
||||||
|
@ -95,11 +100,20 @@ void PostPass::createDescriptorSet(RenderTarget* target) {
|
||||||
farFieldDescriptorWrite.dstSet = target->postSets[i];
|
farFieldDescriptorWrite.dstSet = target->postSets[i];
|
||||||
farFieldDescriptorWrite.pImageInfo = &farFieldImageInfo;
|
farFieldDescriptorWrite.pImageInfo = &farFieldImageInfo;
|
||||||
|
|
||||||
const std::array<VkWriteDescriptorSet, 4> descriptorWrites = {
|
VkWriteDescriptorSet blendDescriptorWrite = {};
|
||||||
|
blendDescriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||||
|
blendDescriptorWrite.descriptorCount = 1;
|
||||||
|
blendDescriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||||
|
blendDescriptorWrite.dstBinding = 4;
|
||||||
|
blendDescriptorWrite.dstSet = target->postSets[i];
|
||||||
|
blendDescriptorWrite.pImageInfo = &blendImageInfo;
|
||||||
|
|
||||||
|
const std::array<VkWriteDescriptorSet, 5> descriptorWrites = {
|
||||||
sceneDescriptorWrite,
|
sceneDescriptorWrite,
|
||||||
depthDescriptorWrite,
|
depthDescriptorWrite,
|
||||||
nearFieldDescriptorWrite,
|
nearFieldDescriptorWrite,
|
||||||
farFieldDescriptorWrite
|
farFieldDescriptorWrite,
|
||||||
|
blendDescriptorWrite
|
||||||
};
|
};
|
||||||
|
|
||||||
vkUpdateDescriptorSets(renderer_.getDevice(), descriptorWrites.size(), descriptorWrites.data(), 0, nullptr);
|
vkUpdateDescriptorSets(renderer_.getDevice(), descriptorWrites.size(), descriptorWrites.data(), 0, nullptr);
|
||||||
|
@ -130,11 +144,18 @@ void PostPass::createDescriptorSetLayout() {
|
||||||
farFieldSamplerBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
farFieldSamplerBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||||
farFieldSamplerBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
farFieldSamplerBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||||
|
|
||||||
const std::array<VkDescriptorSetLayoutBinding, 4> bindings = {
|
VkDescriptorSetLayoutBinding blendSamplerBinding = {};
|
||||||
|
blendSamplerBinding.binding = 4;
|
||||||
|
blendSamplerBinding.descriptorCount = 1;
|
||||||
|
blendSamplerBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||||
|
blendSamplerBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||||
|
|
||||||
|
const std::array<VkDescriptorSetLayoutBinding, 5> bindings = {
|
||||||
offscreenSamplerBinding,
|
offscreenSamplerBinding,
|
||||||
depthSamplerBinding,
|
depthSamplerBinding,
|
||||||
nearFieldSamplerBinding,
|
nearFieldSamplerBinding,
|
||||||
farFieldSamplerBinding
|
farFieldSamplerBinding,
|
||||||
|
blendSamplerBinding
|
||||||
};
|
};
|
||||||
|
|
||||||
VkDescriptorSetLayoutCreateInfo createInfo = {};
|
VkDescriptorSetLayoutCreateInfo createInfo = {};
|
||||||
|
|
131
src/renderer.cpp
131
src/renderer.cpp
|
@ -36,11 +36,13 @@ Renderer::Renderer(GraphicsConfig config) : config_(config) {
|
||||||
imguiPass_ = new ImGuiPass(*this);
|
imguiPass_ = new ImGuiPass(*this);
|
||||||
#endif
|
#endif
|
||||||
skyPass_ = new SkyPass(*this);
|
skyPass_ = new SkyPass(*this);
|
||||||
|
smaaPass_ = new SMAAPass(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Renderer::~Renderer() {
|
Renderer::~Renderer() {
|
||||||
vkDeviceWaitIdle(device_);
|
vkDeviceWaitIdle(device_);
|
||||||
|
|
||||||
|
delete smaaPass_;
|
||||||
delete skyPass_;
|
delete skyPass_;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
delete imguiPass_;
|
delete imguiPass_;
|
||||||
|
@ -150,6 +152,8 @@ void Renderer::render(World& world, RenderTarget* target) {
|
||||||
vkCmdSetViewport(commandBuffer, 0, 1, &viewport);
|
vkCmdSetViewport(commandBuffer, 0, 1, &viewport);
|
||||||
vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
|
vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
|
||||||
|
|
||||||
|
smaaPass_->render(commandBuffer, target);
|
||||||
|
|
||||||
clearColor = {};
|
clearColor = {};
|
||||||
|
|
||||||
renderPassBeginInfo = {};
|
renderPassBeginInfo = {};
|
||||||
|
@ -304,6 +308,16 @@ RenderTarget* Renderer::createSurfaceRenderTarget(VkSurfaceKHR surface, RenderTa
|
||||||
target->farFieldMemory = new VkDeviceMemory[numFrameResources];
|
target->farFieldMemory = new VkDeviceMemory[numFrameResources];
|
||||||
target->farFieldImageViews = new VkImageView[numFrameResources];
|
target->farFieldImageViews = new VkImageView[numFrameResources];
|
||||||
target->farFieldFramebuffers = new VkFramebuffer[numFrameResources];
|
target->farFieldFramebuffers = new VkFramebuffer[numFrameResources];
|
||||||
|
target->edgeImages = new VkImage[numFrameResources];
|
||||||
|
target->edgeMemorys = new VkDeviceMemory[numFrameResources];
|
||||||
|
target->edgeImageViews = new VkImageView[numFrameResources];
|
||||||
|
target->edgeFramebuffers = new VkFramebuffer[numFrameResources];
|
||||||
|
target->edgeDescriptorSets = new VkDescriptorSet[numFrameResources];
|
||||||
|
target->blendImages = new VkImage[numFrameResources];
|
||||||
|
target->blendMemorys = new VkDeviceMemory[numFrameResources];
|
||||||
|
target->blendImageViews = new VkImageView[numFrameResources];
|
||||||
|
target->blendFramebuffers = new VkFramebuffer[numFrameResources];
|
||||||
|
target->blendDescriptorSets = new VkDescriptorSet[numFrameResources];
|
||||||
target->imguiVertexBuffers = new VkBuffer[numFrameResources];
|
target->imguiVertexBuffers = new VkBuffer[numFrameResources];
|
||||||
target->imguiVertexMemorys = new VkDeviceMemory[numFrameResources];
|
target->imguiVertexMemorys = new VkDeviceMemory[numFrameResources];
|
||||||
target->imguiVertexBufferSizes = new size_t[numFrameResources];
|
target->imguiVertexBufferSizes = new size_t[numFrameResources];
|
||||||
|
@ -530,6 +544,120 @@ RenderTarget* Renderer::createSurfaceRenderTarget(VkSurfaceKHR surface, RenderTa
|
||||||
vkCreateFramebuffer(device_, &framebufferInfo, nullptr, &target->farFieldFramebuffers[i]);
|
vkCreateFramebuffer(device_, &framebufferInfo, nullptr, &target->farFieldFramebuffers[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// edge image
|
||||||
|
{
|
||||||
|
VkImageCreateInfo imageCreateInfo = {};
|
||||||
|
imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||||
|
imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
|
||||||
|
imageCreateInfo.format = VK_FORMAT_R16G16B16A16_SFLOAT;
|
||||||
|
imageCreateInfo.extent.width = target->extent.width;
|
||||||
|
imageCreateInfo.extent.height = target->extent.height;
|
||||||
|
imageCreateInfo.extent.depth = 1;
|
||||||
|
imageCreateInfo.mipLevels = 1;
|
||||||
|
imageCreateInfo.arrayLayers = 1;
|
||||||
|
imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||||
|
imageCreateInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||||
|
|
||||||
|
vkCreateImage(device_, &imageCreateInfo, nullptr, &target->edgeImages[i]);
|
||||||
|
|
||||||
|
VkMemoryRequirements memoryRequirements = {};
|
||||||
|
vkGetImageMemoryRequirements(device_, target->edgeImages[i], &memoryRequirements);
|
||||||
|
|
||||||
|
VkMemoryAllocateInfo allocateInfo = {};
|
||||||
|
allocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||||
|
allocateInfo.allocationSize = memoryRequirements.size;
|
||||||
|
allocateInfo.memoryTypeIndex = findMemoryType(memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||||
|
|
||||||
|
vkAllocateMemory(device_, &allocateInfo, nullptr, &target->edgeMemorys[i]);
|
||||||
|
vkBindImageMemory(device_, target->edgeImages[i], target->edgeMemorys[i], 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// edge image view
|
||||||
|
{
|
||||||
|
VkImageViewCreateInfo createInfo = {};
|
||||||
|
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||||
|
createInfo.image = target->edgeImages[i];
|
||||||
|
createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||||
|
createInfo.format = VK_FORMAT_R16G16B16A16_SFLOAT;
|
||||||
|
createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
|
createInfo.subresourceRange.levelCount = 1;
|
||||||
|
createInfo.subresourceRange.layerCount = 1;
|
||||||
|
|
||||||
|
vkCreateImageView(device_, &createInfo, nullptr, &target->edgeImageViews[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// edge framebuffer
|
||||||
|
{
|
||||||
|
VkFramebufferCreateInfo framebufferInfo = {};
|
||||||
|
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
||||||
|
framebufferInfo.renderPass = smaaPass_->getEdgeRenderPass();
|
||||||
|
framebufferInfo.attachmentCount = 1;
|
||||||
|
framebufferInfo.pAttachments = &target->edgeImageViews[i];
|
||||||
|
framebufferInfo.width = target->extent.width;
|
||||||
|
framebufferInfo.height = target->extent.height;
|
||||||
|
framebufferInfo.layers = 1;
|
||||||
|
|
||||||
|
vkCreateFramebuffer(device_, &framebufferInfo, nullptr, &target->edgeFramebuffers[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// blend image
|
||||||
|
{
|
||||||
|
VkImageCreateInfo imageCreateInfo = {};
|
||||||
|
imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||||
|
imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
|
||||||
|
imageCreateInfo.format = VK_FORMAT_R16G16B16A16_SFLOAT;
|
||||||
|
imageCreateInfo.extent.width = target->extent.width;
|
||||||
|
imageCreateInfo.extent.height = target->extent.height;
|
||||||
|
imageCreateInfo.extent.depth = 1;
|
||||||
|
imageCreateInfo.mipLevels = 1;
|
||||||
|
imageCreateInfo.arrayLayers = 1;
|
||||||
|
imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||||
|
imageCreateInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||||
|
|
||||||
|
vkCreateImage(device_, &imageCreateInfo, nullptr, &target->blendImages[i]);
|
||||||
|
|
||||||
|
VkMemoryRequirements memoryRequirements = {};
|
||||||
|
vkGetImageMemoryRequirements(device_, target->blendImages[i], &memoryRequirements);
|
||||||
|
|
||||||
|
VkMemoryAllocateInfo allocateInfo = {};
|
||||||
|
allocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||||
|
allocateInfo.allocationSize = memoryRequirements.size;
|
||||||
|
allocateInfo.memoryTypeIndex = findMemoryType(memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||||
|
|
||||||
|
vkAllocateMemory(device_, &allocateInfo, nullptr, &target->blendMemorys[i]);
|
||||||
|
vkBindImageMemory(device_, target->blendImages[i], target->blendMemorys[i], 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// blend image view
|
||||||
|
{
|
||||||
|
VkImageViewCreateInfo createInfo = {};
|
||||||
|
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||||
|
createInfo.image = target->blendImages[i];
|
||||||
|
createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||||
|
createInfo.format = VK_FORMAT_R16G16B16A16_SFLOAT;
|
||||||
|
createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
|
createInfo.subresourceRange.levelCount = 1;
|
||||||
|
createInfo.subresourceRange.layerCount = 1;
|
||||||
|
|
||||||
|
vkCreateImageView(device_, &createInfo, nullptr, &target->blendImageViews[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// blend framebuffer
|
||||||
|
{
|
||||||
|
VkFramebufferCreateInfo framebufferInfo = {};
|
||||||
|
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
||||||
|
framebufferInfo.renderPass = smaaPass_->getBlendRenderPass();
|
||||||
|
framebufferInfo.attachmentCount = 1;
|
||||||
|
framebufferInfo.pAttachments = &target->blendImageViews[i];
|
||||||
|
framebufferInfo.width = target->extent.width;
|
||||||
|
framebufferInfo.height = target->extent.height;
|
||||||
|
framebufferInfo.layers = 1;
|
||||||
|
|
||||||
|
vkCreateFramebuffer(device_, &framebufferInfo, nullptr, &target->blendFramebuffers[i]);
|
||||||
|
}
|
||||||
|
|
||||||
// imgui
|
// imgui
|
||||||
{
|
{
|
||||||
target->imguiVertexBuffers[i] = nullptr;
|
target->imguiVertexBuffers[i] = nullptr;
|
||||||
|
@ -544,6 +672,7 @@ RenderTarget* Renderer::createSurfaceRenderTarget(VkSurfaceKHR surface, RenderTa
|
||||||
|
|
||||||
postPass_->createDescriptorSet(target);
|
postPass_->createDescriptorSet(target);
|
||||||
dofPass_->createDescriptorSet(target);
|
dofPass_->createDescriptorSet(target);
|
||||||
|
smaaPass_->createDescriptorSets(target);
|
||||||
|
|
||||||
VkCommandBufferAllocateInfo allocateInfo = {};
|
VkCommandBufferAllocateInfo allocateInfo = {};
|
||||||
allocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
allocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||||
|
@ -890,7 +1019,7 @@ VkShaderModule Renderer::createShader(const char* path) {
|
||||||
return shaderModule;
|
return shaderModule;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::uploadImageData(VkImage image, int width, int height, VkDeviceSize size, void* src) {
|
void Renderer::uploadImageData(VkImage image, int width, int height, VkDeviceSize size, const void* src) {
|
||||||
VkBuffer stagingBuffer;
|
VkBuffer stagingBuffer;
|
||||||
VkDeviceMemory stagingMemory;
|
VkDeviceMemory stagingMemory;
|
||||||
|
|
||||||
|
|
499
src/smaapass.cpp
Normal file
499
src/smaapass.cpp
Normal file
|
@ -0,0 +1,499 @@
|
||||||
|
#include "smaapass.h"
|
||||||
|
|
||||||
|
#include <AreaTex.h>
|
||||||
|
#include <SearchTex.h>
|
||||||
|
|
||||||
|
#include "renderer.h"
|
||||||
|
|
||||||
|
SMAAPass::SMAAPass(Renderer& renderer) : renderer(renderer) {
|
||||||
|
loadResources();
|
||||||
|
|
||||||
|
setupDescriptorLayouts();
|
||||||
|
createOffscreenResources();
|
||||||
|
createRenderPasses();
|
||||||
|
createPipelines();
|
||||||
|
}
|
||||||
|
|
||||||
|
SMAAPass::~SMAAPass() {
|
||||||
|
vkDestroyPipeline(renderer.getDevice(), blendPipeline, nullptr);
|
||||||
|
vkDestroyPipeline(renderer.getDevice(), edgePipeline, nullptr);
|
||||||
|
|
||||||
|
vkDestroyPipelineLayout(renderer.getDevice(), edgePipelineLayout, nullptr);
|
||||||
|
vkDestroyPipelineLayout(renderer.getDevice(), blendPipelineLayout, nullptr);
|
||||||
|
|
||||||
|
vkDestroyRenderPass(renderer.getDevice(), edgeRenderPass, nullptr);
|
||||||
|
vkDestroyRenderPass(renderer.getDevice(), blendRenderPass, nullptr);
|
||||||
|
|
||||||
|
vkDestroySampler(renderer.getDevice(), blendSampler, nullptr);
|
||||||
|
vkDestroySampler(renderer.getDevice(), edgeSampler, nullptr);
|
||||||
|
|
||||||
|
vkDestroyDescriptorSetLayout(renderer.getDevice(), blendDescriptorSetLayout, nullptr);
|
||||||
|
vkDestroyDescriptorSetLayout(renderer.getDevice(), edgeDescriptorSetLayout, nullptr);
|
||||||
|
|
||||||
|
vkDestroySampler(renderer.getDevice(), searchSampler, nullptr);
|
||||||
|
vkDestroySampler(renderer.getDevice(), areaSampler, nullptr);
|
||||||
|
|
||||||
|
vkFreeMemory(renderer.getDevice(), searchMemory, nullptr);
|
||||||
|
vkFreeMemory(renderer.getDevice(), areaMemory, nullptr);
|
||||||
|
|
||||||
|
vkDestroyImageView(renderer.getDevice(), searchImageView, nullptr);
|
||||||
|
vkDestroyImageView(renderer.getDevice(), areaImageView, nullptr);
|
||||||
|
|
||||||
|
vkDestroyImage(renderer.getDevice(), searchImage, nullptr);
|
||||||
|
vkDestroyImage(renderer.getDevice(), areaImage, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMAAPass::render(VkCommandBuffer commandBuffer, RenderTarget* target) {
|
||||||
|
vkCmdPipelineBarrier(commandBuffer,
|
||||||
|
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||||
|
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||||
|
VK_DEPENDENCY_BY_REGION_BIT,
|
||||||
|
0,
|
||||||
|
nullptr,
|
||||||
|
0,
|
||||||
|
nullptr,
|
||||||
|
0,
|
||||||
|
nullptr);
|
||||||
|
|
||||||
|
VkClearValue clearValue = {};
|
||||||
|
clearValue.color = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||||
|
|
||||||
|
VkRenderPassBeginInfo renderPassInfo = {};
|
||||||
|
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||||
|
renderPassInfo.renderPass = edgeRenderPass;
|
||||||
|
renderPassInfo.framebuffer = target->edgeFramebuffers[target->currentResource];
|
||||||
|
renderPassInfo.renderArea.extent.width = 1280;
|
||||||
|
renderPassInfo.renderArea.extent.height = 720;
|
||||||
|
renderPassInfo.clearValueCount = 1;
|
||||||
|
renderPassInfo.pClearValues = &clearValue;
|
||||||
|
|
||||||
|
vkCmdBeginRenderPass(commandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||||
|
|
||||||
|
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, edgePipeline);
|
||||||
|
|
||||||
|
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, edgePipelineLayout, 0, 1, &target->edgeDescriptorSets[target->currentResource],
|
||||||
|
0, nullptr);
|
||||||
|
|
||||||
|
vkCmdDraw(commandBuffer, 3, 1, 0, 0);
|
||||||
|
|
||||||
|
vkCmdEndRenderPass(commandBuffer);
|
||||||
|
|
||||||
|
renderPassInfo.renderPass = blendRenderPass;
|
||||||
|
renderPassInfo.framebuffer = target->blendFramebuffers[target->currentResource];
|
||||||
|
|
||||||
|
vkCmdBeginRenderPass(commandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||||
|
|
||||||
|
// TODO: add a pipeline barrier
|
||||||
|
|
||||||
|
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, blendPipeline);
|
||||||
|
|
||||||
|
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, blendPipelineLayout, 0, 1,
|
||||||
|
&target->blendDescriptorSets[target->currentResource], 0, nullptr);
|
||||||
|
|
||||||
|
vkCmdDraw(commandBuffer, 3, 1, 0, 0);
|
||||||
|
|
||||||
|
vkCmdEndRenderPass(commandBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMAAPass::createDescriptorSets(RenderTarget* target) {
|
||||||
|
// TODO: colmengate these
|
||||||
|
VkDescriptorSetAllocateInfo allocInfo = {};
|
||||||
|
allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
||||||
|
allocInfo.descriptorPool = renderer.getDescriptorPool();
|
||||||
|
allocInfo.descriptorSetCount = target->numImages;
|
||||||
|
|
||||||
|
// FIXME: lol what
|
||||||
|
auto layouts = new VkDescriptorSetLayout[target->numImages];
|
||||||
|
for(uint32_t i = 0; i < target->numImages; i++)
|
||||||
|
layouts[i] = edgeDescriptorSetLayout;
|
||||||
|
|
||||||
|
allocInfo.pSetLayouts = layouts;
|
||||||
|
|
||||||
|
vkAllocateDescriptorSets(renderer.getDevice(), &allocInfo, target->edgeDescriptorSets);
|
||||||
|
|
||||||
|
for(uint32_t i = 0; i < target->numImages; i++)
|
||||||
|
layouts[i] = blendDescriptorSetLayout;
|
||||||
|
|
||||||
|
vkAllocateDescriptorSets(renderer.getDevice(), &allocInfo, target->blendDescriptorSets);
|
||||||
|
|
||||||
|
for(int i = 0; i < target->numImages; i++) {
|
||||||
|
// edge
|
||||||
|
{
|
||||||
|
VkDescriptorImageInfo imageInfo = {};
|
||||||
|
imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||||
|
imageInfo.imageView = target->offscreenColorImageViews[i];
|
||||||
|
imageInfo.sampler = edgeSampler;
|
||||||
|
|
||||||
|
VkDescriptorImageInfo depthInfo = {};
|
||||||
|
depthInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||||
|
depthInfo.imageView = target->offscreenDepthImageViews[i];
|
||||||
|
depthInfo.sampler = edgeSampler;
|
||||||
|
|
||||||
|
VkWriteDescriptorSet descriptorWrites[2] = {};
|
||||||
|
descriptorWrites[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||||
|
descriptorWrites[0].dstSet = target->edgeDescriptorSets[i];
|
||||||
|
descriptorWrites[0].dstBinding = 0;
|
||||||
|
descriptorWrites[0].dstArrayElement = 0;
|
||||||
|
descriptorWrites[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||||
|
descriptorWrites[0].descriptorCount = 1;
|
||||||
|
descriptorWrites[0].pImageInfo = &imageInfo;
|
||||||
|
|
||||||
|
descriptorWrites[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||||
|
descriptorWrites[1].dstSet = target->edgeDescriptorSets[i];
|
||||||
|
descriptorWrites[1].dstBinding = 1;
|
||||||
|
descriptorWrites[1].dstArrayElement = 0;
|
||||||
|
descriptorWrites[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||||
|
descriptorWrites[1].descriptorCount = 1;
|
||||||
|
descriptorWrites[1].pImageInfo = &depthInfo;
|
||||||
|
|
||||||
|
vkUpdateDescriptorSets(renderer.getDevice(), 2, descriptorWrites, 0, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// blend
|
||||||
|
{
|
||||||
|
VkDescriptorImageInfo edgeInfo = {};
|
||||||
|
edgeInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||||
|
edgeInfo.imageView = target->edgeImageViews[i];
|
||||||
|
edgeInfo.sampler = edgeSampler;
|
||||||
|
|
||||||
|
VkDescriptorImageInfo areaInfo = {};
|
||||||
|
areaInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||||
|
areaInfo.imageView = areaImageView;
|
||||||
|
areaInfo.sampler = areaSampler;
|
||||||
|
|
||||||
|
VkDescriptorImageInfo searchInfo = {};
|
||||||
|
searchInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||||
|
searchInfo.imageView = searchImageView;
|
||||||
|
searchInfo.sampler = searchSampler;
|
||||||
|
|
||||||
|
VkWriteDescriptorSet descriptorWrites[3] = {};
|
||||||
|
descriptorWrites[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||||
|
descriptorWrites[0].dstSet = target->blendDescriptorSets[i];
|
||||||
|
descriptorWrites[0].dstBinding = 0;
|
||||||
|
descriptorWrites[0].dstArrayElement = 0;
|
||||||
|
descriptorWrites[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||||
|
descriptorWrites[0].descriptorCount = 1;
|
||||||
|
descriptorWrites[0].pImageInfo = &edgeInfo;
|
||||||
|
|
||||||
|
descriptorWrites[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||||
|
descriptorWrites[1].dstSet = target->blendDescriptorSets[i];
|
||||||
|
descriptorWrites[1].dstBinding = 1;
|
||||||
|
descriptorWrites[1].dstArrayElement = 0;
|
||||||
|
descriptorWrites[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||||
|
descriptorWrites[1].descriptorCount = 1;
|
||||||
|
descriptorWrites[1].pImageInfo = &areaInfo;
|
||||||
|
|
||||||
|
descriptorWrites[2].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||||
|
descriptorWrites[2].dstSet = target->blendDescriptorSets[i];
|
||||||
|
descriptorWrites[2].dstBinding = 2;
|
||||||
|
descriptorWrites[2].dstArrayElement = 0;
|
||||||
|
descriptorWrites[2].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||||
|
descriptorWrites[2].descriptorCount = 1;
|
||||||
|
descriptorWrites[2].pImageInfo = &searchInfo;
|
||||||
|
|
||||||
|
vkUpdateDescriptorSets(renderer.getDevice(), 3, descriptorWrites, 0, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMAAPass::loadResources() {
|
||||||
|
const auto loadResource = [this](const int size, const int width, const int height, const void* data, VkFormat format, VkImage& image, VkDeviceMemory& memory, VkImageView& view) {
|
||||||
|
VkImageCreateInfo imageInfo = {};
|
||||||
|
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||||
|
imageInfo.imageType = VK_IMAGE_TYPE_2D;
|
||||||
|
imageInfo.extent.width = width;
|
||||||
|
imageInfo.extent.height = height;
|
||||||
|
imageInfo.extent.depth = 1;
|
||||||
|
imageInfo.mipLevels = 1;
|
||||||
|
imageInfo.arrayLayers = 1;
|
||||||
|
imageInfo.format = format;
|
||||||
|
imageInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||||
|
imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
|
||||||
|
vkCreateImage(renderer.getDevice(), &imageInfo, nullptr, &image);
|
||||||
|
|
||||||
|
VkMemoryRequirements memRequirements = {};
|
||||||
|
vkGetImageMemoryRequirements(renderer.getDevice(), image, &memRequirements);
|
||||||
|
|
||||||
|
VkMemoryAllocateInfo allocInfo = {};
|
||||||
|
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||||
|
allocInfo.allocationSize = memRequirements.size;
|
||||||
|
allocInfo.memoryTypeIndex = renderer.findMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||||
|
|
||||||
|
vkAllocateMemory(renderer.getDevice(), &allocInfo, nullptr, &memory);
|
||||||
|
|
||||||
|
vkBindImageMemory(renderer.getDevice(), image, memory, 0);
|
||||||
|
|
||||||
|
renderer.uploadImageData(
|
||||||
|
image,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
size,
|
||||||
|
data);
|
||||||
|
|
||||||
|
VkImageViewCreateInfo viewInfo = {};
|
||||||
|
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||||
|
viewInfo.image = image;
|
||||||
|
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||||
|
viewInfo.format = imageInfo.format;
|
||||||
|
viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
|
viewInfo.subresourceRange.levelCount = 1;
|
||||||
|
viewInfo.subresourceRange.layerCount = 1;
|
||||||
|
|
||||||
|
vkCreateImageView(renderer.getDevice(), &viewInfo, nullptr, &view);
|
||||||
|
};
|
||||||
|
|
||||||
|
loadResource(AREATEX_SIZE, AREATEX_WIDTH, AREATEX_HEIGHT, areaTexBytes, VK_FORMAT_R8G8_UNORM, areaImage, areaMemory, areaImageView);
|
||||||
|
loadResource(SEARCHTEX_SIZE, SEARCHTEX_WIDTH, SEARCHTEX_HEIGHT, searchTexBytes, VK_FORMAT_R8_UNORM, searchImage, searchMemory, searchImageView);
|
||||||
|
|
||||||
|
VkSamplerCreateInfo samplerCreateInfo = {};
|
||||||
|
samplerCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
||||||
|
samplerCreateInfo.magFilter = VK_FILTER_LINEAR;
|
||||||
|
samplerCreateInfo.minFilter = VK_FILTER_LINEAR;
|
||||||
|
samplerCreateInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||||
|
samplerCreateInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||||
|
samplerCreateInfo.addressModeV = samplerCreateInfo.addressModeU;
|
||||||
|
samplerCreateInfo.addressModeW = samplerCreateInfo.addressModeU;
|
||||||
|
samplerCreateInfo.mipLodBias = 0.0f;
|
||||||
|
samplerCreateInfo.maxAnisotropy = 0;
|
||||||
|
samplerCreateInfo.minLod = 0.0f;
|
||||||
|
samplerCreateInfo.maxLod = 1.0f;
|
||||||
|
samplerCreateInfo.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
|
||||||
|
|
||||||
|
vkCreateSampler(renderer.getDevice(), &samplerCreateInfo, nullptr, &areaSampler);
|
||||||
|
|
||||||
|
samplerCreateInfo.magFilter = VK_FILTER_NEAREST;
|
||||||
|
samplerCreateInfo.minFilter = VK_FILTER_NEAREST;
|
||||||
|
|
||||||
|
vkCreateSampler(renderer.getDevice(), &samplerCreateInfo, nullptr, &searchSampler);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMAAPass::setupDescriptorLayouts() {
|
||||||
|
// edge
|
||||||
|
{
|
||||||
|
VkDescriptorSetLayoutBinding imageSamplerLayoutBinding = {};
|
||||||
|
imageSamplerLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||||
|
imageSamplerLayoutBinding.descriptorCount = 1;
|
||||||
|
imageSamplerLayoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||||
|
|
||||||
|
VkDescriptorSetLayoutBinding depthSamplerLayoutBinding = {};
|
||||||
|
depthSamplerLayoutBinding.binding = 1;
|
||||||
|
depthSamplerLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||||
|
depthSamplerLayoutBinding.descriptorCount = 1;
|
||||||
|
depthSamplerLayoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||||
|
|
||||||
|
const std::array<VkDescriptorSetLayoutBinding, 2> bindings = {imageSamplerLayoutBinding, depthSamplerLayoutBinding};
|
||||||
|
|
||||||
|
VkDescriptorSetLayoutCreateInfo layoutInfo = {};
|
||||||
|
layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
||||||
|
layoutInfo.bindingCount = bindings.size();
|
||||||
|
layoutInfo.pBindings = bindings.data();
|
||||||
|
|
||||||
|
vkCreateDescriptorSetLayout(renderer.getDevice(), &layoutInfo, nullptr, &edgeDescriptorSetLayout);
|
||||||
|
}
|
||||||
|
|
||||||
|
// blend
|
||||||
|
{
|
||||||
|
VkDescriptorSetLayoutBinding edgeSamplerLayoutBinding = {};
|
||||||
|
edgeSamplerLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||||
|
edgeSamplerLayoutBinding.descriptorCount = 1;
|
||||||
|
edgeSamplerLayoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||||
|
|
||||||
|
VkDescriptorSetLayoutBinding areaSamplerLayoutBinding = {};
|
||||||
|
areaSamplerLayoutBinding.binding = 1;
|
||||||
|
areaSamplerLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||||
|
areaSamplerLayoutBinding.descriptorCount = 1;
|
||||||
|
areaSamplerLayoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||||
|
|
||||||
|
VkDescriptorSetLayoutBinding searchSamplerLayoutBinding = {};
|
||||||
|
searchSamplerLayoutBinding.binding = 2;
|
||||||
|
searchSamplerLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||||
|
searchSamplerLayoutBinding.descriptorCount = 1;
|
||||||
|
searchSamplerLayoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||||
|
|
||||||
|
const std::array<VkDescriptorSetLayoutBinding, 3> bindings = {edgeSamplerLayoutBinding, areaSamplerLayoutBinding, searchSamplerLayoutBinding};
|
||||||
|
|
||||||
|
VkDescriptorSetLayoutCreateInfo layoutInfo = {};
|
||||||
|
layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
||||||
|
layoutInfo.bindingCount = bindings.size();
|
||||||
|
layoutInfo.pBindings = bindings.data();
|
||||||
|
|
||||||
|
vkCreateDescriptorSetLayout(renderer.getDevice(), &layoutInfo, nullptr, &blendDescriptorSetLayout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMAAPass::createOffscreenResources() {
|
||||||
|
const VkFormat colorFormat = VK_FORMAT_R16G16B16A16_SFLOAT;
|
||||||
|
|
||||||
|
VkSamplerCreateInfo samplerCreateInfo = {};
|
||||||
|
samplerCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
||||||
|
samplerCreateInfo.magFilter = VK_FILTER_LINEAR;
|
||||||
|
samplerCreateInfo.minFilter = VK_FILTER_LINEAR;
|
||||||
|
samplerCreateInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||||
|
samplerCreateInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||||
|
samplerCreateInfo.addressModeV = samplerCreateInfo.addressModeU;
|
||||||
|
samplerCreateInfo.addressModeW = samplerCreateInfo.addressModeU;
|
||||||
|
samplerCreateInfo.mipLodBias = 0.0f;
|
||||||
|
samplerCreateInfo.maxAnisotropy = 0;
|
||||||
|
samplerCreateInfo.minLod = 0.0f;
|
||||||
|
samplerCreateInfo.maxLod = 1.0f;
|
||||||
|
samplerCreateInfo.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
|
||||||
|
|
||||||
|
vkCreateSampler(renderer.getDevice(), &samplerCreateInfo, nullptr, &edgeSampler);
|
||||||
|
vkCreateSampler(renderer.getDevice(), &samplerCreateInfo, nullptr, &blendSampler);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMAAPass::createRenderPasses() {
|
||||||
|
VkAttachmentDescription colorAttachment = {};
|
||||||
|
colorAttachment.format = VK_FORMAT_R16G16B16A16_SFLOAT;
|
||||||
|
colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||||
|
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
|
colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
|
colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||||
|
colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
colorAttachment.finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||||
|
|
||||||
|
VkAttachmentReference colorAttachmentRef = {};
|
||||||
|
colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
|
VkSubpassDescription subpass = {};
|
||||||
|
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||||
|
subpass.colorAttachmentCount = 1;
|
||||||
|
subpass.pColorAttachments = &colorAttachmentRef;
|
||||||
|
|
||||||
|
VkSubpassDependency dependency = {};
|
||||||
|
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
|
||||||
|
dependency.dstSubpass = 0;
|
||||||
|
dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||||
|
dependency.srcAccessMask = 0;
|
||||||
|
dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||||
|
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||||
|
|
||||||
|
VkRenderPassCreateInfo renderPassInfo = {};
|
||||||
|
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
||||||
|
renderPassInfo.attachmentCount = 1;
|
||||||
|
renderPassInfo.pAttachments = &colorAttachment;
|
||||||
|
renderPassInfo.subpassCount = 1;
|
||||||
|
renderPassInfo.pSubpasses = &subpass;
|
||||||
|
renderPassInfo.dependencyCount = 1;
|
||||||
|
renderPassInfo.pDependencies = &dependency;
|
||||||
|
|
||||||
|
// FIXME: wot
|
||||||
|
vkCreateRenderPass(renderer.getDevice(), &renderPassInfo, nullptr, &edgeRenderPass);
|
||||||
|
vkCreateRenderPass(renderer.getDevice(), &renderPassInfo, nullptr, &blendRenderPass);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMAAPass::createPipelines() {
|
||||||
|
VkShaderModule edgeVertexShader = renderer.createShader("shaders/edge.vert.spv");
|
||||||
|
VkShaderModule edgeFragmentShader = renderer.createShader("shaders/edge.frag.spv");
|
||||||
|
|
||||||
|
VkPipelineShaderStageCreateInfo vertShaderStageInfo = {};
|
||||||
|
vertShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||||
|
vertShaderStageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT;
|
||||||
|
vertShaderStageInfo.module = edgeVertexShader;
|
||||||
|
vertShaderStageInfo.pName = "main";
|
||||||
|
|
||||||
|
VkPipelineShaderStageCreateInfo fragShaderStageInfo = {};
|
||||||
|
fragShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||||
|
fragShaderStageInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||||
|
fragShaderStageInfo.module = edgeFragmentShader;
|
||||||
|
fragShaderStageInfo.pName = "main";
|
||||||
|
|
||||||
|
VkPipelineShaderStageCreateInfo shaderStages[] = {vertShaderStageInfo, fragShaderStageInfo};
|
||||||
|
|
||||||
|
VkPipelineVertexInputStateCreateInfo vertexInputInfo = {};
|
||||||
|
vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
||||||
|
|
||||||
|
VkPipelineInputAssemblyStateCreateInfo inputAssembly = {};
|
||||||
|
inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
||||||
|
inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
||||||
|
inputAssembly.primitiveRestartEnable = VK_FALSE;
|
||||||
|
|
||||||
|
VkViewport viewport = {};
|
||||||
|
viewport.width = 1280;
|
||||||
|
viewport.height = 720;
|
||||||
|
viewport.maxDepth = 1.0f;
|
||||||
|
|
||||||
|
VkRect2D scissor = {};
|
||||||
|
scissor.extent.width = 1280;
|
||||||
|
scissor.extent.height = 720;
|
||||||
|
|
||||||
|
VkPipelineViewportStateCreateInfo viewportState = {};
|
||||||
|
viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
|
||||||
|
viewportState.viewportCount = 1;
|
||||||
|
viewportState.pViewports = &viewport;
|
||||||
|
viewportState.scissorCount = 1;
|
||||||
|
viewportState.pScissors = &scissor;
|
||||||
|
|
||||||
|
VkPipelineRasterizationStateCreateInfo rasterizer = {};
|
||||||
|
rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
|
||||||
|
rasterizer.depthClampEnable = VK_FALSE;
|
||||||
|
rasterizer.rasterizerDiscardEnable = VK_FALSE;
|
||||||
|
rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
|
||||||
|
rasterizer.lineWidth = 1.0f;
|
||||||
|
rasterizer.cullMode = VK_CULL_MODE_NONE;
|
||||||
|
rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE;
|
||||||
|
rasterizer.depthBiasEnable = VK_FALSE;
|
||||||
|
|
||||||
|
VkPipelineMultisampleStateCreateInfo multisampling = {};
|
||||||
|
multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
|
||||||
|
multisampling.sampleShadingEnable = VK_FALSE;
|
||||||
|
multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
|
||||||
|
VkPipelineColorBlendAttachmentState colorBlendAttachment = {};
|
||||||
|
colorBlendAttachment.colorWriteMask =
|
||||||
|
VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
|
||||||
|
colorBlendAttachment.blendEnable = VK_FALSE;
|
||||||
|
|
||||||
|
VkPipelineColorBlendStateCreateInfo colorBlending = {};
|
||||||
|
colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
|
||||||
|
colorBlending.attachmentCount = 1;
|
||||||
|
colorBlending.pAttachments = &colorBlendAttachment;
|
||||||
|
|
||||||
|
VkPipelineLayoutCreateInfo pipelineLayoutInfo = {};
|
||||||
|
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||||
|
pipelineLayoutInfo.setLayoutCount = 1;
|
||||||
|
pipelineLayoutInfo.pSetLayouts = &edgeDescriptorSetLayout;
|
||||||
|
|
||||||
|
vkCreatePipelineLayout(renderer.getDevice(), &pipelineLayoutInfo, nullptr, &edgePipelineLayout);
|
||||||
|
|
||||||
|
VkGraphicsPipelineCreateInfo pipelineInfo = {};
|
||||||
|
pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
||||||
|
pipelineInfo.stageCount = 2;
|
||||||
|
pipelineInfo.pStages = shaderStages;
|
||||||
|
pipelineInfo.pVertexInputState = &vertexInputInfo;
|
||||||
|
pipelineInfo.pInputAssemblyState = &inputAssembly;
|
||||||
|
pipelineInfo.pViewportState = &viewportState;
|
||||||
|
pipelineInfo.pRasterizationState = &rasterizer;
|
||||||
|
pipelineInfo.pMultisampleState = &multisampling;
|
||||||
|
pipelineInfo.pColorBlendState = &colorBlending;
|
||||||
|
pipelineInfo.layout = edgePipelineLayout;
|
||||||
|
pipelineInfo.renderPass = edgeRenderPass;
|
||||||
|
|
||||||
|
vkCreateGraphicsPipelines(renderer.getDevice(), nullptr, 1, &pipelineInfo, nullptr, &edgePipeline);
|
||||||
|
|
||||||
|
VkShaderModule blendVertexShader = renderer.createShader("shaders/blend.vert.spv");
|
||||||
|
VkShaderModule blendFragmentShader = renderer.createShader("shaders/blend.frag.spv");
|
||||||
|
|
||||||
|
vertShaderStageInfo.module = blendVertexShader;
|
||||||
|
fragShaderStageInfo.module = blendFragmentShader;
|
||||||
|
|
||||||
|
VkPipelineShaderStageCreateInfo newShaderStages[] = {vertShaderStageInfo, fragShaderStageInfo};
|
||||||
|
pipelineInfo.pStages = newShaderStages;
|
||||||
|
|
||||||
|
pipelineLayoutInfo.pSetLayouts = &blendDescriptorSetLayout;
|
||||||
|
|
||||||
|
vkCreatePipelineLayout(renderer.getDevice(), &pipelineLayoutInfo, nullptr, &blendPipelineLayout);
|
||||||
|
|
||||||
|
pipelineInfo.layout = blendPipelineLayout;
|
||||||
|
pipelineInfo.renderPass = blendRenderPass;
|
||||||
|
|
||||||
|
vkCreateGraphicsPipelines(renderer.getDevice(), nullptr, 1, &pipelineInfo, nullptr, &blendPipeline);
|
||||||
|
|
||||||
|
vkDestroyShaderModule(renderer.getDevice(), blendFragmentShader, nullptr);
|
||||||
|
vkDestroyShaderModule(renderer.getDevice(), blendVertexShader, nullptr);
|
||||||
|
|
||||||
|
vkDestroyShaderModule(renderer.getDevice(), edgeFragmentShader, nullptr);
|
||||||
|
vkDestroyShaderModule(renderer.getDevice(), edgeVertexShader, nullptr);
|
||||||
|
}
|
Reference in a new issue