forked from Hal47/dsfix
-
Notifications
You must be signed in to change notification settings - Fork 0
/
SSAO.cpp
126 lines (115 loc) · 4.95 KB
/
SSAO.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include "SSAO.h"
#include "util.h"
#include <array>
#include <spdlog/formatter.h>
#include <string>
extern HMODULE g_hDll;
SSAO::SSAO(IDirect3DDevice9* device, unsigned int width, unsigned int height, unsigned strength, Type type) noexcept
: Effect(device), width(width), height(height) {
try {
// Setup pixel size macro
std::string pixelSize = fmt::format("float2(1.0 / {}, 1.0 / {})", width, height);
D3DXMACRO strengthMacros[] = {
{"SSAO_STRENGTH_LOW", "1"}, {"SSAO_STRENGTH_MEDIUM", "1"}, {"SSAO_STRENGTH_HIGH", "1"}};
// Setup the defines for compiling the effect
std::array<D3DXMACRO, 3> defines = {
{{"PIXEL_SIZE", pixelSize.c_str()}, strengthMacros[strength], {nullptr, nullptr}}};
DWORD flags = D3DXFX_NOT_CLONEABLE | D3DXSHADER_OPTIMIZATION_LEVEL3;
// Load effect from file
const wchar_t* srcfile = [type]() {
switch (type) {
default:
case Type::HBAO:
return L"HBAO.fx";
case Type::VSSAO:
return L"VSSAO.fx";
case Type::VSSAO2:
return L"VSSAO2.fx";
}
}();
// spdlog::info("{} load, strength {}", srcfile, strengthMacros[strength].Name);
spdlog::info(L"{} load", srcfile);
WRL::ComPtr<ID3DXBuffer> errors;
ThrowIfFailed(::D3DXCreateEffectFromResourceW(device, g_hDll, srcfile, &defines.front(),
nullptr, flags, nullptr, &effect, &errors));
// Create buffers
ThrowIfFailed(device->CreateTexture(width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8,
D3DPOOL_DEFAULT, &buffer1Tex, nullptr));
ThrowIfFailed(buffer1Tex->GetSurfaceLevel(0, &buffer1Surf));
ThrowIfFailed(device->CreateTexture(width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8,
D3DPOOL_DEFAULT, &buffer2Tex, nullptr));
ThrowIfFailed(buffer2Tex->GetSurfaceLevel(0, &buffer2Surf));
// get handles
depthTexHandle = effect->GetParameterByName(nullptr, "depthTex2D");
frameTexHandle = effect->GetParameterByName(nullptr, "frameTex2D");
prevPassTexHandle = effect->GetParameterByName(nullptr, "prevPassTex2D");
} catch (const std::system_error& err) {
spdlog::error(L"{}", DXGetErrorString9W(err.code().value()));
}
}
void SSAO::go(IDirect3DTexture9* frame, IDirect3DTexture9* depth, IDirect3DSurface9* dst) noexcept {
try {
ThrowIfFailed(device->SetVertexDeclaration(vertexDeclaration.Get()));
mainSsaoPass(depth, buffer1Surf.Get());
for (size_t i = 0; i < 1; ++i) {
hBlurPass(depth, buffer1Tex.Get(), buffer2Surf.Get());
vBlurPass(depth, buffer2Tex.Get(), buffer1Surf.Get());
}
combinePass(frame, buffer1Tex.Get(), dst);
} catch (const std::system_error& err) {
spdlog::error(L"{}", DXGetErrorString9W(err.code().value()));
}
}
void SSAO::mainSsaoPass(IDirect3DTexture9* depth, IDirect3DSurface9* dst) {
ThrowIfFailed(device->SetRenderTarget(0, dst));
ThrowIfFailed(device->Clear(0, nullptr, D3DCLEAR_TARGET, D3DCOLOR_ARGB(255, 0, 0, 0), 1.0f, 0));
// Setup variables.
ThrowIfFailed(effect->SetTexture(depthTexHandle, depth));
// Do it!
UINT passes;
ThrowIfFailed(effect->Begin(&passes, 0));
ThrowIfFailed(effect->BeginPass(0));
quad(width, height);
ThrowIfFailed(effect->EndPass());
ThrowIfFailed(effect->End());
}
void SSAO::hBlurPass(IDirect3DTexture9* depth, IDirect3DTexture9* src, IDirect3DSurface9* dst) {
ThrowIfFailed(device->SetRenderTarget(0, dst));
// Setup variables.
ThrowIfFailed(effect->SetTexture(prevPassTexHandle, src));
ThrowIfFailed(effect->SetTexture(depthTexHandle, depth));
// Do it!
UINT passes;
ThrowIfFailed(effect->Begin(&passes, 0));
ThrowIfFailed(effect->BeginPass(1));
quad(width, height);
ThrowIfFailed(effect->EndPass());
ThrowIfFailed(effect->End());
}
void SSAO::vBlurPass(IDirect3DTexture9* depth, IDirect3DTexture9* src, IDirect3DSurface9* dst) {
ThrowIfFailed(device->SetRenderTarget(0, dst));
// Setup variables.
ThrowIfFailed(effect->SetTexture(prevPassTexHandle, src));
ThrowIfFailed(effect->SetTexture(depthTexHandle, depth));
// Do it!
UINT passes;
ThrowIfFailed(effect->Begin(&passes, 0));
ThrowIfFailed(effect->BeginPass(2));
quad(width, height);
ThrowIfFailed(effect->EndPass());
ThrowIfFailed(effect->End());
}
void SSAO::combinePass(IDirect3DTexture9* frame, IDirect3DTexture9* ao, IDirect3DSurface9* dst) {
ThrowIfFailed(device->SetRenderTarget(0, dst));
// device->Clear(0, nullptr, D3DCLEAR_TARGET, D3DCOLOR_ARGB(255, 255, 0, 255), 1.0f, 0);
// Setup variables.
ThrowIfFailed(effect->SetTexture(prevPassTexHandle, ao));
ThrowIfFailed(effect->SetTexture(frameTexHandle, frame));
// Do it!
UINT passes;
ThrowIfFailed(effect->Begin(&passes, 0));
ThrowIfFailed(effect->BeginPass(3));
quad(width, height);
ThrowIfFailed(effect->EndPass());
ThrowIfFailed(effect->End());
}