载入中...
搜索中...
未找到
ScreenSpaceReflection.cpp
浏览该文件的文档.
2
3#include "common/Exception.h"
4#include "graphics/Canvas.h"
6#include "graphics/Graphics.h"
7#include "graphics/Shader.h"
8#include "graphics/Texture.h"
9#include "graphics/shaders/ssr_frag_spv.inc"
10
11#include <algorithm>
12#include <cmath>
13
14namespace eve::graphics {
15
16namespace {
17Shader *createSsrShader(Graphics *gfx) {
18 std::vector<uint32_t> frag(ssr_frag_spv, ssr_frag_spv + ssr_frag_spv_count);
19 Shader *sh = gfx->newShaderFromSpv({}, frag);
20 sh->declareMatrix("invViewProj");
21 sh->declareVec3("cameraPos");
22 sh->declareFloat("nearZ");
23 sh->declareFloat("farZ");
24 sh->declareFloat("texelW");
25 sh->declareFloat("texelH");
26 sh->declareFloat("maxDist");
27 sh->declareFloat("stepLen");
28 sh->declareFloat("maxSteps");
29 sh->declareFloat("thickness");
30 sh->declareFloat("strength");
31 sh->declareFloat("enabled");
32 sh->declareFloat("bias");
33 return sh;
34}
35} // namespace
36
38 ssr_ = createSsrShader(gfx);
39}
40
42 // Shader is owned by Graphics.
43 gfx_ = nullptr;
44 ssr_ = nullptr;
45}
46
47void ScreenSpaceReflection::setInvViewProj(const glm::mat4 &invViewProj) {
48 invViewProj_ = invViewProj;
49 ssr_->sendMatrix("invViewProj", invViewProj_);
50}
51
52void ScreenSpaceReflection::setCamera(float eyeX, float eyeY, float eyeZ, float targetX,
53 float targetY, float targetZ, float upX, float upY,
54 float upZ, float fovYDeg, float aspect, float nearZ,
55 float farZ) {
56 nearZ_ = nearZ > 1e-4f ? nearZ : 0.1f;
57 farZ_ = farZ > nearZ_ ? farZ : nearZ_ + 1.f;
58 const float aspectSafe = aspect > 1e-4f ? aspect : 1.f;
59 const float fovRad = fovYDeg * 0.017453292519943295f;
60 const glm::mat4 view =
61 glm::lookAtRH(glm::vec3(eyeX, eyeY, eyeZ), glm::vec3(targetX, targetY, targetZ),
62 glm::vec3(upX, upY, upZ));
63 const glm::mat4 proj = perspectiveVulkanRH_ZO(fovRad, aspectSafe, nearZ_, farZ_);
64 setInvViewProj(glm::inverse(proj * view));
65 ssr_->sendFloat("nearZ", nearZ_);
66 ssr_->sendFloat("farZ", farZ_);
67}
68
70 enabled_ = enabled;
71 ssr_->sendFloat("enabled", enabled_ ? 1.f : 0.f);
72}
73
74void ScreenSpaceReflection::setMaxDistance(float v) { setFloat("maxDist", std::max(v, 0.1f)); }
75void ScreenSpaceReflection::setStepLength(float v) { setFloat("stepLen", std::max(v, 0.01f)); }
76void ScreenSpaceReflection::setMaxSteps(int v) { setFloat("maxSteps", float(std::clamp(v, 1, 512))); }
77void ScreenSpaceReflection::setThickness(float v) { setFloat("thickness", std::max(v, 0.0f)); }
78void ScreenSpaceReflection::setStrength(float v) { setFloat("strength", std::max(v, 0.f)); }
79
80bool ScreenSpaceReflection::hasParam(const std::string &name) const {
81 return ssr_ && ssr_->hasUniform(name);
82}
83
84void ScreenSpaceReflection::setFloat(const std::string &name, float value) {
85 if (!ssr_ || !ssr_->hasUniform(name))
86 throw eve::Exception("ScreenSpaceReflection.setFloat: missing param '%s'", name.c_str());
87 ssr_->sendFloat(name, value);
88 if (name == "maxDist") maxDist_ = value;
89 if (name == "stepLen") stepLen_ = value;
90 if (name == "maxSteps") maxSteps_ = value;
91 if (name == "thickness") thickness_ = value;
92 if (name == "strength") strength_ = value;
93}
94
95float ScreenSpaceReflection::getFloat(const std::string &name) const {
96 if (!ssr_ || !ssr_->hasUniform(name))
97 throw eve::Exception("ScreenSpaceReflection.getFloat: missing param '%s'", name.c_str());
98 float v = 0.f;
99 if (ssr_->getFromVar(name, &v, sizeof(v)) == int(sizeof(v))) return v;
100 throw eve::Exception("ScreenSpaceReflection.getFloat: missing param '%s'", name.c_str());
101}
102
103void ScreenSpaceReflection::uploadUniforms(int width, int height) {
104 if (width < 1) width = 1;
105 if (height < 1) height = 1;
106 ssr_->sendMatrix("invViewProj", invViewProj_);
107 ssr_->sendFloat("nearZ", nearZ_);
108 ssr_->sendFloat("farZ", farZ_);
109 ssr_->sendFloat("texelW", 1.f / float(width));
110 ssr_->sendFloat("texelH", 1.f / float(height));
111 ssr_->sendFloat("maxDist", maxDist_);
112 ssr_->sendFloat("stepLen", stepLen_);
113 ssr_->sendFloat("maxSteps", maxSteps_);
114 ssr_->sendFloat("thickness", thickness_);
115 ssr_->sendFloat("strength", strength_);
116 ssr_->sendFloat("enabled", enabled_ ? 1.f : 0.f);
117 ssr_->sendFloat("bias", bias_);
118}
119
121 Texture *worldNormal, Canvas *dest) {
122 if (!gfx) throw eve::Exception("ScreenSpaceReflection: null graphics");
123 if (!dest) throw eve::Exception("ScreenSpaceReflection.applyFromSceneTo: null dest");
124 Canvas *prev = gfx->getCanvas();
125 gfx->setCanvas(dest);
126 applyFromScene(gfx, sceneColor, hwDepth, worldNormal);
127 gfx->setCanvas(prev == gfx ? nullptr : prev);
128}
129
131 if (!reflection_ && gfx_) {
132 reflection_ = gfx_->newCanvas(std::max(1, gfx_->getWidth()), std::max(1, gfx_->getHeight()));
133 }
134 return reflection_;
135}
136
139 return c ? c->getTexture() : nullptr;
140}
141
143 Texture *worldNormal) {
144 if (!gfx) throw eve::Exception("ScreenSpaceReflection: null graphics");
145 if (!sceneColor) throw eve::Exception("ScreenSpaceReflection: null scene color");
146 if (!hwDepth) throw eve::Exception("ScreenSpaceReflection: null depth");
147 (void)worldNormal; // normal is reconstructed from depth in the shader
148 uploadUniforms(sceneColor->getWidth(), sceneColor->getHeight());
149 const float dw = gfx->getCanvas() ? float(gfx->getCanvas()->getWidth()) : float(gfx->getWidth());
150 const float dh =
151 gfx->getCanvas() ? float(gfx->getCanvas()->getHeight()) : float(gfx->getHeight());
152 gfx->drawTexturedRectShaderDepth(sceneColor, hwDepth, ssr_, 0.f, 0.f, dw, dh,
153 Color(1.f, 1.f, 1.f, 1.f));
154}
155
156} // namespace eve::graphics
std::string value
vk::ShaderModule frag
float height
Definition Grass.cpp:235
uint32_t c
int width
float fovRad
glm::mat4 view
glm::mat4 proj
const char * name
Definition RockMesh.cpp:21
bool enabled
int v
virtual int getWidth() const =0
virtual int getHeight() const =0
virtual Canvas * getCanvas() const =0
virtual void setCanvas(Canvas *canvas)=0
nullptr or this → screen. Switching flushes pending draws to the previous target.
virtual Canvas * newCanvas(int width, int height)=0
Create an offscreen render target (sampleable). Owned by Graphics.
int getHeight() const
Definition Graphics.h:118
virtual void drawTexturedRectShaderDepth(Texture *color, Texture *depth, Shader *shader, float x, float y, float w, float h, const Color &tint)=0
Fullscreen/post draw sampling color at binding 0 and depth at binding 1 (hardware D32,...
void applyFromSceneTo(Graphics *gfx, Texture *sceneColor, Texture *hwDepth, Texture *worldNormal, Canvas *dest)
Write the SSR result into the currently bound canvas / dest.
void setCamera(float eyeX, float eyeY, float eyeZ, float targetX, float targetY, float targetZ, float upX, float upY, float upZ, float fovYDeg, float aspect, float nearZ, float farZ)
Camera for depth reconstruction (RH + ZO). Builds inv(viewProj) + near/far.
Texture * getReflectionTexture()
The reflection texture from the owned canvas, or nullptr before first apply.
void setEnabled(bool enabled)
Enable/disable the pass. When disabled it emits transparent (0 hit).
Canvas * getReflectionCanvas()
Owned reflection canvas (created on first use at the current target size).
void setInvViewProj(const glm::mat4 &invViewProj)
float getFloat(const std::string &name) const
void setFloat(const std::string &name, float value)
void applyFromScene(Graphics *gfx, Texture *sceneColor, Texture *hwDepth, Texture *worldNormal)
Write SSR into the currently bound canvas / screen.
bool hasParam(const std::string &name) const
bool hasUniform(const std::string &name) const
Definition Shader.cpp:46
void sendFloat(const std::string &name, float x)
Definition Shader.cpp:82
void sendMatrix(const std::string &name, const glm::mat4 &m)
Definition Shader.cpp:99
int getFromVar(const std::string &name, void *data, size_t size) const
Definition Shader.cpp:71
GPU texture created via Graphics::newTexture. Owns GPU resources through an opaque backend handle.
Definition Texture.h:17
int getWidth() const
Definition Texture.h:26
int getHeight() const
Definition Texture.h:27
卡牌游戏 UI 工具模块:工厂 + 脚本绑定入口。 功能参考 ycarowr/UiCard:扇形手牌布局、抽牌/洗牌、悬浮放大、拖拽到落牌区、 敌方手牌(背面/偷看)、费用不足置灰,以及可实时调节的布局...
Definition AnimTrail.h:6
glm::mat4 perspectiveVulkanRH_ZO(float fovyRad, float aspect, float zNear, float zFar)
Right-handed, zero-to-one depth perspective for Vulkan swapchains.
Definition ClipSpace.h:20
glm::vec4 Color
RGBA color used by every graphics draw call. Lives inside eve::graphics so including a graphics heade...
Definition Color.h:13