载入中...
搜索中...
未找到
Waterfall.cpp
浏览该文件的文档.
2
3#include "graphics/Graphics.h"
4#include "graphics/Mesh.h"
7#include "graphics/shaders/waterfall_mesh_frag_spv.inc"
8
9#include <algorithm>
10#include <cmath>
11#include <string>
12#include <vector>
13
14namespace eve::graphics {
15
16namespace {
17
18// Push-constant layout (data[32]):
19// 0 time, 1 flowSpeed, 2 turbulence, 3 streakCount, 4 streakScale,
20// 5 topFoam, 6 bottomFoam, 7 foamAmt, 8 reflIntensity,
21// 9 sunIntensity, 10..12 waterColor.
22// Fragment shader source lives in graphics/shaders/waterfall_mesh.frag; it is
23// precompiled to SPIR-V (waterfall_mesh_frag_spv.inc) so it works on every
24// backend without a runtime glslc.
25const char *kUniformNames[] = {
26 "time", "flowSpeed", "turbulence", "streakCnt", "streakScale",
27 "topFoam", "bottomFoam", "foamAmt", "reflInten", "sunInten", "waterCol",
28};
29const int kUniformCount = int(sizeof(kUniformNames) / sizeof(kUniformNames[0]));
30
31} // namespace
32
34 Shader *sh = nullptr;
35 if (gfx->getBackendName() == "webgpu") {
37 } else {
38 std::vector<uint32_t> frag(waterfall_mesh_frag_spv,
39 waterfall_mesh_frag_spv + waterfall_mesh_frag_spv_count);
40 sh = gfx->newMeshShaderFromSpv({}, frag);
41 }
42 for (int i = 0; i < kUniformCount; ++i) {
43 if (std::string(kUniformNames[i]) == "waterCol")
44 sh->declareVec3(kUniformNames[i]);
45 else
46 sh->declareFloat(kUniformNames[i]);
47 }
48 return sh;
49}
50
51int Waterfall::paramCount() { return kUniformCount; }
52
53std::string Waterfall::paramName(int index) {
54 if (index < 0 || index >= kUniformCount) return {};
55 return kUniformNames[index];
56}
57
58Waterfall::Waterfall(Graphics *gfx) : gfx_(gfx) {
59 shader_ = newWaterfallShader(gfx);
60 bindParams();
61 captureDrawerToken_ = RenderSystem3D::addCaptureExtraDrawer(
62 0xffffffffu,
63 [this](Graphics &, const Camera3D::Data &, const glm::mat4 &, float, uint32_t mask) {
64 if (!reflectionCaptureEnabled_ || (reflectionCaptureMask_ & mask) == 0u) return;
65 draw();
66 });
67}
68
70
71void Waterfall::createSheet(float width, float height, int segX, int segY) {
72 createCurvedSheet(width, height, segX, segY, 0.f, 0.f);
73}
74
75void Waterfall::createCurvedSheet(float width, float height, int segX, int segY,
76 float curveDepth, float lipOverhang) {
77 segX = std::max(1, segX);
78 segY = std::max(1, segY);
79 curveDepth = std::max(0.f, curveDepth);
80 lipOverhang = std::max(0.f, lipOverhang);
81 std::vector<float> pos, nrm, uv;
82 std::vector<uint32_t> idx;
83 for (int y = 0; y <= segY; ++y) {
84 const float v = float(y) / float(segY);
85 const float lowerFan = 1.f + 0.12f * (1.f - v) * (1.f - v);
86 for (int x = 0; x <= segX; ++x) {
87 const float u = float(x) / float(segX);
88 const float across = u * 2.f - 1.f;
89 const float crown = std::max(0.f, 1.f - across * across);
90 const float bow = curveDepth * crown * (0.62f + 0.38f * v);
91 const float lip = lipOverhang * v * v;
92 pos.push_back(across * width * 0.5f * lowerFan);
93 pos.push_back(-height * 0.5f + height * v);
94 pos.push_back(bow + lip);
95 nrm.push_back(0.f);
96 nrm.push_back(0.f);
97 nrm.push_back(1.f);
98 uv.push_back(u);
99 uv.push_back(v);
100 }
101 }
102 for (int y = 0; y < segY; ++y) {
103 for (int x = 0; x < segX; ++x) {
104 const uint32_t a = uint32_t(y * (segX + 1) + x);
105 const uint32_t b = a + 1;
106 const uint32_t c = a + uint32_t(segX + 1);
107 const uint32_t d = c + 1;
108 idx.push_back(a);
109 idx.push_back(b);
110 idx.push_back(c);
111 idx.push_back(b);
112 idx.push_back(d);
113 idx.push_back(c);
114 }
115 }
116 mesh_ = gfx_->newMeshFromArrays(pos.data(), nrm.data(), uv.data(), int(pos.size() / 3),
117 idx.data(), int(idx.size()));
118}
119
120void Waterfall::update(float dt) {
121 time_ += dt;
122 bindParams();
123}
124
125void Waterfall::setTime(float seconds) {
126 time_ = seconds;
127 bindParams();
128}
129
130void Waterfall::setFlowSpeed(float v) { flowSpeed_ = v; }
131void Waterfall::setTurbulence(float v) { turbulence_ = std::max(0.f, v); }
132void Waterfall::setStreakCount(int v) { streakCount_ = std::max(0, v); }
133void Waterfall::setStreakScale(float v) { streakScale_ = std::max(0.1f, v); }
134void Waterfall::setTopFoam(float v) { topFoam_ = std::clamp(v, 0.001f, 0.5f); }
135void Waterfall::setBottomFoam(float v) { bottomFoam_ = std::clamp(v, 0.001f, 0.5f); }
136void Waterfall::setFoamAmount(float v) { foamAmount_ = std::max(0.f, v); }
137void Waterfall::setWaterColor(float r, float g, float b) {
138 waterColor_[0] = r;
139 waterColor_[1] = g;
140 waterColor_[2] = b;
141}
142void Waterfall::setReflectionIntensity(float v) { reflectionIntensity_ = std::max(0.f, v); }
143void Waterfall::setSunIntensity(float v) { sunIntensity_ = std::max(0.f, v); }
144
146 if (!shader_) return;
147 shader_->sendFloat("time", time_);
148 shader_->sendFloat("flowSpeed", flowSpeed_);
149 shader_->sendFloat("turbulence", turbulence_);
150 shader_->sendFloat("streakCnt", float(streakCount_));
151 shader_->sendFloat("streakScale", streakScale_);
152 shader_->sendFloat("topFoam", topFoam_);
153 shader_->sendFloat("bottomFoam", bottomFoam_);
154 shader_->sendFloat("foamAmt", foamAmount_);
155 shader_->sendFloat("reflInten", reflectionIntensity_);
156 shader_->sendFloat("sunInten", sunIntensity_);
157 shader_->sendVec3("waterCol", waterColor_[0], waterColor_[1], waterColor_[2]);
158}
159
161 if (!gfx_ || !mesh_ || !shader_) return;
162 gfx_->drawMeshShader(mesh_, glm::mat4(1.f), nullptr, glm::vec4(1.f), shader_);
163}
164
165} // namespace eve::graphics
float y
Definition AnimClip.cpp:738
float x
Definition AnimClip.cpp:738
int mask
float uv
tensor::Graph g
Definition GpuGraph.cpp:7
vk::ShaderModule frag
float u
Definition Grass.cpp:233
double r
float v
HexVec3 across
std::int32_t c
std::uint32_t height
std::uint32_t width
MeleePoint3 b
Definition MeleeHit.cpp:41
MeleePoint3 a
Definition MeleeHit.cpp:40
int idx
float d
uint32_t index
virtual std::string getBackendName() const =0
Renderer backend id used by sibling modules (e.g. Gpgpu).
virtual Shader * newMeshShaderFromSpv(const std::vector< uint32_t > &vertSpv, const std::vector< uint32_t > &fragSpv)=0
Create a Mesh3D custom shader (MeshVertex + Frame UBO + albedo). Empty vert → default mesh3d....
virtual void drawMeshShader(Mesh *mesh, const glm::mat4 &model, Texture *texture, const Color &tint, Shader *shader)=0
Draw mesh with an explicit Mesh3D Shader (nullptr = default PBR pipeline).
virtual Mesh * newMeshFromArrays(const float *posXYZ, const float *nrmXYZ, const float *uvST, int vertexCount, const uint32_t *indices, int indexCount)=0
Upload a triangle mesh from packed CPU arrays. Owned by Graphics. posXYZ required (vertexCount*3)....
virtual Shader * newMeshShaderFromWgsl(const std::string &vertWgsl, const std::string &fragWgsl)=0
Create a Mesh3D custom shader from WGSL source (WebGPU backend). The WGSL must declare the engine's F...
static void removeCaptureExtraDrawer(uint64_t token)
Unregister an offscreen capture contributor.
static uint64_t addCaptureExtraDrawer(uint32_t reflectionCaptureMask, CaptureExtraDrawer drawer)
Register custom forward geometry for offscreen captures.
Custom GPU program.
Definition Shader.h:39
void sendFloat(const std::string &name, float x)
Definition Shader.cpp:95
void sendVec3(const std::string &name, float x, float y, float z)
Definition Shader.cpp:102
int declareVec3(const std::string &name)
Definition Shader.cpp:45
int declareFloat(const std::string &name)
Reserve sequential float slots in the push-constant block. Returns start index.
Definition Shader.cpp:43
void setSunIntensity(float intensity)
Sets the sun intensity.
void setReflectionIntensity(float intensity)
Sets the reflection intensity.
static int paramCount()
Names of the push-constant parameters (for UI / inspection).
Definition Waterfall.cpp:51
void createSheet(float width, float height, int segX, int segY)
Build a vertical XY plane (facing +Z, Y-up world) sized w×h, UVs [0,1]².
Definition Waterfall.cpp:71
void createCurvedSheet(float width, float height, int segX, int segY, float curveDepth, float lipOverhang)
Build a shaped water curtain with a convex cross-section and projecting lip.
Definition Waterfall.cpp:75
void setStreakCount(int count)
How many layered falling streaks are drawn.
void setFoamAmount(float v)
Sets the foam amount.
void draw()
Draw the waterfall sheet (uses default mesh3d camera / lighting state).
void setWaterColor(float r, float g, float b)
Sets the water color.
void setTurbulence(float t)
Amount of turbulence / white-water streak in the body.
void bindParams()
Upload current params to the shader push constants.
void setBottomFoam(float v)
Sets the bottom foam.
void setStreakScale(float scale)
Horizontal stretch of the falling streaks (1 = circular, >1 elongated).
Waterfall(Graphics *gfx)
Waterfall.
Definition Waterfall.cpp:58
void update(float dt)
Advance the animation clock by dt seconds.
void setTopFoam(float v)
Relative height (0..1) of the top foam lip and bottom splash bands.
void setFlowSpeed(float speed)
Fall speed of the water (scales the downward scroll).
void setTime(float seconds)
Sets the time.
static std::string paramName(int index)
Param name.
Definition Waterfall.cpp:53
constexpr const char * kWaterfallFragWgsl
Waterfall fragment shader WGSL source. @ownership Borrowed immutable string literal; callers must not...
卡牌游戏 UI 工具模块:工厂 + 脚本绑定入口。 功能参考 ycarowr/UiCard:扇形手牌布局、抽牌/洗牌、悬浮放大、拖拽到落牌区、 敌方手牌(背面/偷看)、费用不足置灰,以及可实时调节的布局...
Definition Animation.h:25
Shader * newWaterfallShader(Graphics *gfx)
Create the embedded waterfall fragment shader (owned by Graphics).
Definition Waterfall.cpp:33