载入中...
搜索中...
未找到
Water.cpp
浏览该文件的文档.
1#include "graphics/Water.h"
2
3#include "graphics/Graphics.h"
4#include "graphics/GBuffer.h"
5#include "graphics/Mesh.h"
10#include "graphics/shaders/water_frag_spv.inc"
11#include "graphics/shaders/water_vert_spv.inc"
12#include "image/ImageData.h"
13
14#include <cmath>
15#include <limits>
16#include <string>
17#include <vector>
18
19namespace eve::graphics {
20
21namespace {
22
23// Push-constant layout (data[32]):
24// 0 time, 1 waveSpeed, 2 waveAmp, 3 waveScale, 4 rippleAmp,
25// 5 rippleCount, 6 rippleInterval, 7 foamWidth, 8 foamSoftness,
26// 9 foamStrength, 10..12 deepColor, 13..15 shallowColor,
27// 16 depthDistance, 17..19 foamColor, 20 reflectionIntensity,
28// 21..23 reflectionTint, 24 sunIntensity, 25 fresnelPower,
29// 26 causticsStrength, 27 signedSsrStrength, 28 refractionStrength,
30// 29 signedOpacityAndDepthAvailability, 30 causticsScale, 31 waveSharpness.
31
32const char *kUniformNames[] = {
33 "time", "waveSpeed", "waveAmp", "waveScale", "rippleAmp",
34 "rippleCnt", "rippleInt", "foamWidth", "foamSoftness", "foamStrength",
35 "deepColor", "shallowColor", "depthDistance", "foamColor", "reflInten",
36 "reflTint", "sunInten", "fresnelPower", "causticsStrength", "ssrStrength",
37 "refractionStrength", "opacityAndDepth", "causticsScale", "waveSharpness",
38};
39const int kUniformCount = int(sizeof(kUniformNames) / sizeof(kUniformNames[0]));
40
41} // namespace
42
43namespace {
44Result<glm::ivec2> waterPointCounts(const WaterMeshSettings& settings) {
46 !std::isfinite(settings.sizeX) || !std::isfinite(settings.sizeY) || !std::isfinite(settings.sizeZ) ||
47 !std::isfinite(settings.densityX) || !std::isfinite(settings.densityY) ||
48 !std::isfinite(settings.height) || settings.sizeX <= 0.0F || settings.sizeY <= 0.0F ||
49 settings.sizeZ <= 0.0F || settings.densityX <= 0.0F || settings.densityY <= 0.0F) {
51 DiagnosticCode::InvalidArgument, "water.mesh: finite positive size/density and a supported shape are required"));
52 }
53 const double scale = settings.type == WaterMeshType::Plane ? 1.0 : 0.5;
54 const double rawX = double(settings.densityX) / 40.0 * double(settings.sizeX) * scale;
55 const double rawY = double(settings.densityY) / 40.0 * double(settings.sizeZ) * scale;
56 if (rawX > 4096.0 || rawY > 4096.0)
58 Diagnostic::error(DiagnosticCode::InvalidArgument, "water.mesh: generated axis point count exceeds 4096"));
59 int x = static_cast<int>(std::nearbyint(rawX));
60 int y = static_cast<int>(std::nearbyint(rawY));
61 if (settings.type == WaterMeshType::Plane) {
62 ++x;
63 ++y;
64 if (x < 2 || y < 2)
66 Diagnostic::error(DiagnosticCode::InvalidArgument, "water.mesh: plane requires at least one polygon"));
67 } else if (x < 1 || y < 1) {
69 Diagnostic::error(DiagnosticCode::InvalidArgument, "water.mesh: circle requires at least one ring"));
70 }
72}
73
74int waterCirclePoint(int ring, int extent) {
75 if (ring < 0) return 0;
76 const int count = (ring + 1) * 6;
77 extent %= count;
78 if (extent < 0) extent += count;
79 return 3 * ring * (ring + 1) + extent + 1;
80}
81
82template <typename Stop, typename Value, typename Project>
83Value sampleStops(const std::vector<Stop>& stops, float time, Project project) {
84 if (time <= stops.front().time) return project(stops.front());
85 if (time >= stops.back().time) return project(stops.back());
86 for (std::size_t i = 1; i < stops.size(); ++i) if (time <= stops[i].time) {
87 const auto& a = stops[i - 1]; const auto& b = stops[i];
88 const float t = (time - a.time) / (b.time - a.time);
89 return project(a) + (project(b) - project(a)) * t;
90 }
91 return project(stops.back());
92}
93} // namespace
94
95Result<void> WaterDepthGradient::addColorStop(float time, float red, float green, float blue) {
96 if (!std::isfinite(time) || !std::isfinite(red) || !std::isfinite(green) || !std::isfinite(blue) ||
97 time < 0.0F || time > 1.0F || red < 0.0F || red > 1.0F || green < 0.0F || green > 1.0F ||
98 blue < 0.0F || blue > 1.0F)
100 "water.gradient: normalized finite RGB stop required"));
101 auto candidate = colorStops; candidate.push_back({time, {red, green, blue}});
102 std::stable_sort(candidate.begin(), candidate.end(), [](const auto& a, const auto& b) { return a.time < b.time; });
103 colorStops = std::move(candidate); return Result<void>::success();
104}
105
107 if (!std::isfinite(time) || !std::isfinite(alpha) || time < 0.0F || time > 1.0F || alpha < 0.0F || alpha > 1.0F)
109 "water.gradient: normalized finite alpha stop required"));
110 auto candidate = alphaStops; candidate.push_back({time, alpha});
111 std::stable_sort(candidate.begin(), candidate.end(), [](const auto& a, const auto& b) { return a.time < b.time; });
112 alphaStops = std::move(candidate); return Result<void>::success();
113}
114
116
118 auto counts = waterPointCounts(settings);
119 if (!counts) return Result<int>::failure(counts.status());
120 const std::int64_t triangles = settings.type == WaterMeshType::Plane
121 ? std::int64_t(counts.value().x - 1) * (counts.value().y - 1) * 2
122 : std::int64_t(counts.value().x) * counts.value().x * 6;
123 if (triangles <= 0 || triangles > std::numeric_limits<int>::max() / 3)
125 Diagnostic::error(DiagnosticCode::InvalidArgument, "water.mesh: triangle count is not representable"));
126 return Result<int>::success(static_cast<int>(triangles));
127}
128
130 // Use precompiled SPIR-V (not runtime glslc) so the water shader also works
131 // on platforms without a runtime compiler (e.g. Windows).
132 Shader *sh = nullptr;
133 if (gfx->getBackendName() == "webgpu") {
135 } else {
136 std::vector<uint32_t> vert(water_vert_spv, water_vert_spv + water_vert_spv_count);
137 std::vector<uint32_t> frag(water_frag_spv, water_frag_spv + water_frag_spv_count);
138 sh = gfx->newMeshShaderFromSpv(vert, frag);
139 }
140 gfx->configureMeshShaderSurface(*sh, BlendMode::Alpha, false, false)
141 .expect("water requires alpha blending with depth writes disabled");
142 for (int i = 0; i < kUniformCount; ++i) {
143 const std::string name(kUniformNames[i]);
144 if (name == "deepColor" || name == "shallowColor" || name == "foamColor" || name == "reflTint")
145 sh->declareVec3(kUniformNames[i]);
146 else
147 sh->declareFloat(kUniformNames[i]);
148 }
149 return sh;
150}
151
152int Water::paramCount() { return kUniformCount; }
153
154std::string Water::paramName(int index) {
155 if (index < 0 || index >= kUniformCount) return {};
156 return kUniformNames[index];
157}
158
159Water::Water(Graphics *gfx) : gfx_(gfx) {
160 shader_ = newWaterShader(gfx);
161 bindParams();
162 captureDrawerToken_ = RenderSystem3D::addCaptureExtraDrawer(
163 0xffffffffu,
164 [this](Graphics &, const Camera3D::Data &, const glm::mat4 &, float, uint32_t mask) {
165 if (!reflectionCaptureEnabled_ || (reflectionCaptureMask_ & mask) == 0u) return;
166 drawReflectionCapture();
167 });
168}
169
171
172void Water::createPlane(float sizeX, float sizeZ, int segX, int segZ) {
173 segX = std::max(1, segX);
174 segZ = std::max(1, segZ);
175 std::vector<float> pos, nrm, uv;
176 std::vector<uint32_t> idx;
177 for (int z = 0; z <= segZ; ++z) {
178 for (int x = 0; x <= segX; ++x) {
179 pos.push_back(-sizeX * 0.5f + sizeX * float(x) / segX);
180 pos.push_back(0.f);
181 pos.push_back(-sizeZ * 0.5f + sizeZ * float(z) / segZ);
182 nrm.push_back(0.f);
183 nrm.push_back(1.f);
184 nrm.push_back(0.f);
185 uv.push_back(float(x) / segX);
186 uv.push_back(float(z) / segZ);
187 }
188 }
189 for (int z = 0; z < segZ; ++z) {
190 for (int x = 0; x < segX; ++x) {
191 const uint32_t a = uint32_t(z * (segX + 1) + x);
192 const uint32_t b = a + 1;
193 const uint32_t c = a + uint32_t(segX + 1);
194 const uint32_t d = c + 1;
195 idx.push_back(a);
196 idx.push_back(c);
197 idx.push_back(b);
198 idx.push_back(b);
199 idx.push_back(c);
200 idx.push_back(d);
201 }
202 }
203 mesh_ = gfx_->newMeshFromArrays(pos.data(), nrm.data(), uv.data(), int(pos.size() / 3),
204 idx.data(), int(idx.size()));
205}
206
208 auto counts = waterPointCounts(settings);
209 if (!counts) return Result<int>::failure(counts.status());
210 auto triangleCount = calculateWaterMeshTriangles(settings);
211 if (!triangleCount) return Result<int>::failure(triangleCount.status());
212 if (!gfx_)
214 Diagnostic::error(DiagnosticCode::PreconditionViolation, "water.mesh: graphics owner is unavailable"));
215
216 std::vector<float> pos, nrm, uv;
217 std::vector<uint32_t> idx;
218 if (settings.type == WaterMeshType::Plane) {
219 const int nx = counts.value().x, nz = counts.value().y;
220 pos.reserve(std::size_t(nx) * nz * 3); nrm.reserve(std::size_t(nx) * nz * 3);
221 uv.reserve(std::size_t(nx) * nz * 2); idx.reserve(std::size_t(triangleCount.value()) * 3);
222 const float sx = settings.sizeX / float(nx - 1), sz = settings.sizeZ / float(nz - 1);
223 for (int z = 0; z < nz; ++z) for (int x = 0; x < nx; ++x) {
224 pos.insert(pos.end(), {(float(nx - 1) * 0.5F - x) * sx, settings.height * settings.sizeY,
225 (float(nz - 1) * 0.5F - z) * sz});
226 nrm.insert(nrm.end(), {0.0F, 1.0F, 0.0F});
227 uv.insert(uv.end(), {(float(nx / 2) - x) / float(nx), (float(nz / 2) - z) / float(nz)});
228 }
229 for (int z = 0; z < nz - 1; ++z) for (int x = 0; x < nx - 1; ++x) {
230 const uint32_t a = uint32_t(z * nx + x), b = a + 1, c = a + uint32_t(nx), d = c + 1;
231 idx.insert(idx.end(), {a, c, b, c, d, b});
232 }
233 } else {
234 const int rings = counts.value().x;
235 const std::size_t vertexCount = 1u + 3u * std::size_t(rings) * std::size_t(rings + 1);
236 pos.reserve(vertexCount * 3); nrm.reserve(vertexCount * 3); uv.reserve(vertexCount * 2);
237 idx.reserve(std::size_t(triangleCount.value()) * 3);
238 const float scaleX = (settings.sizeX * 0.5F) / float(rings);
239 const float scaleZ = (settings.sizeZ * 0.5F) / float(counts.value().y);
240 pos.insert(pos.end(), {0.0F, 0.0F, 0.0F}); nrm.insert(nrm.end(), {0.0F, 1.0F, 0.0F});
241 uv.insert(uv.end(), {0.0F, 0.0F});
242 for (int ring = 0; ring < rings; ++ring) {
243 const int ringPoints = (ring + 1) * 6;
244 const float step = 2.0F * 3.14159265358979323846F / float(ringPoints);
245 for (int point = 0; point < ringPoints; ++point) {
246 const float cx = std::cos(step * point) * float(ring + 1);
247 const float cz = std::sin(-step * point) * float(ring + 1);
248 pos.insert(pos.end(), {cx * scaleX, 0.0F, cz * scaleZ});
249 nrm.insert(nrm.end(), {0.0F, 1.0F, 0.0F});
250 uv.insert(uv.end(), {cx / settings.densityX, cz / settings.densityX});
251 }
252 }
253 for (int ring = 0; ring < rings; ++ring) {
254 int other = 0;
255 for (int point = 0; point < (ring + 1) * 6; ++point) {
256 if (point % (ring + 1) != 0) {
257 idx.insert(idx.end(), {uint32_t(waterCirclePoint(ring - 1, other + 1)),
258 uint32_t(waterCirclePoint(ring - 1, other)),
259 uint32_t(waterCirclePoint(ring, point)),
260 uint32_t(waterCirclePoint(ring, point)),
261 uint32_t(waterCirclePoint(ring, point + 1)),
262 uint32_t(waterCirclePoint(ring - 1, other + 1))});
263 ++other;
264 } else {
265 idx.insert(idx.end(), {uint32_t(waterCirclePoint(ring, point)),
266 uint32_t(waterCirclePoint(ring, point + 1)),
267 uint32_t(waterCirclePoint(ring - 1, other))});
268 }
269 }
270 }
271 }
272 Mesh* candidate = gfx_->newMeshFromArrays(pos.data(), nrm.data(), uv.data(), int(pos.size() / 3), idx.data(),
273 int(idx.size()));
274 if (!candidate)
276 Diagnostic::error(DiagnosticCode::Failed, "water.mesh: graphics mesh allocation failed"));
277 mesh_ = candidate;
278 return Result<int>::success(int(pos.size() / 3));
279}
280
282 if (!gfx_ || resolution < 2 || resolution > 4096 || gradient.colorStops.empty() || gradient.alphaStops.empty())
284 DiagnosticCode::InvalidArgument, "water.gradient: graphics, color/alpha keys and resolution 2..4096 required"));
285 for (std::size_t i = 1; i < gradient.colorStops.size(); ++i)
286 if (gradient.colorStops[i - 1].time == gradient.colorStops[i].time)
288 "water.gradient: duplicate color times are ambiguous"));
289 for (std::size_t i = 1; i < gradient.alphaStops.size(); ++i)
290 if (gradient.alphaStops[i - 1].time == gradient.alphaStops[i].time)
292 "water.gradient: duplicate alpha times are ambiguous"));
293 image::ImageData pixels(resolution, resolution, "RGBA8");
294 for (int x = 0; x < resolution; ++x) {
295 const float t = float(x) / float(resolution);
296 const glm::vec3 color = sampleStops<WaterGradientColorStop, glm::vec3>(
297 gradient.colorStops, t, [](const auto& stop) { return stop.color; });
298 const float alpha = sampleStops<WaterGradientAlphaStop, float>(
299 gradient.alphaStops, t, [](const auto& stop) { return stop.alpha; });
300 for (int y = 0; y < resolution; ++y)
301 pixels.setPixel(x, y, image::ImageData::Colorf{color.r, color.g, color.b, alpha});
302 }
303 Texture* candidate = gfx_->newTextureFromImageData(&pixels, false, false);
304 if (!candidate)
306 "water.gradient: texture allocation failed"));
307 depthGradientTexture_ = candidate;
308 return Result<int>::success(resolution * resolution);
309}
310
311void Water::update(float dt) {
312 time_ += dt;
313 bindParams();
314}
315
316void Water::setTime(float seconds) {
317 time_ = seconds;
318 bindParams();
319}
320
321void Water::setWaveSpeed(float v) { config_.waveSpeed = std::clamp(v, -20.0F, 20.0F); }
322void Water::setWaveAmplitude(float v) { config_.waveAmplitude = std::clamp(v, 0.0F, 4.0F); }
323void Water::setRippleAmplitude(float v) { config_.rippleAmplitude = std::clamp(v, 0.0F, 4.0F); }
324void Water::setEdgeFalloff(float v) { config_.foamWidth = std::clamp(v, 0.001F, 1000.0F); }
325void Water::setRippleCount(int v) { config_.rippleCount = std::clamp(v, 0, 8); }
326void Water::setRippleInterval(float v) { config_.rippleInterval = std::clamp(v, 0.05F, 60.0F); }
327void Water::setWaveScale(float v) { config_.waveScale = std::clamp(v, 0.01F, 256.0F); }
329 if (!std::isfinite(degrees))
331 Diagnostic::error(DiagnosticCode::InvalidArgument, "water.direction: finite degrees required"));
332 waveDirectionAngle_ = std::fmod(degrees, 360.0F);
333 if (waveDirectionAngle_ < 0.0F) waveDirectionAngle_ += 360.0F;
334 return Result<void>::success();
335}
336void Water::setWaterColor(float r, float g, float b) {
337 config_.deepColor = glm::max(glm::vec3(r, g, b), glm::vec3(0.0F));
338}
339void Water::setReflectionTint(float r, float g, float b) {
340 config_.reflectionTint = glm::max(glm::vec3(r, g, b), glm::vec3(0.0F));
341}
342void Water::setReflectionIntensity(float v) { config_.reflectionIntensity = std::clamp(v, 0.0F, 4.0F); }
343void Water::setSunIntensity(float v) { config_.sunIntensity = std::clamp(v, 0.0F, 8.0F); }
346 config_.screenSpaceReflectionStrength = std::clamp(strength, 0.0F, 4.0F);
347}
348void Water::setViewport(float w, float h) {
349 viewportW_ = std::max(0.f, w);
350 viewportH_ = std::max(0.f, h);
351}
352
354 if (!shader_) return;
355 shader_->sendFloat("time", time_);
356 shader_->sendFloat("waveSpeed", config_.waveSpeed);
357 shader_->sendFloat("waveAmp", config_.waveAmplitude);
358 shader_->sendFloat("waveScale", config_.waveScale);
359 shader_->sendFloat("rippleAmp", config_.rippleAmplitude);
360 // Preserve the 128-byte portable parameter block: the integer part is ripple count and
361 // [0,0.5) stores PWS_WaterSystem.directionAngle / 720. Shaders decode both independently.
362 shader_->sendFloat("rippleCnt", float(config_.rippleCount) + waveDirectionAngle_ / 720.0F);
363 shader_->sendFloat("rippleInt", config_.rippleInterval);
364 shader_->sendFloat("foamWidth", config_.foamWidth);
365 shader_->sendFloat("foamSoftness", config_.foamSoftness);
366 shader_->sendFloat("foamStrength", config_.foamStrength);
367 shader_->sendVec3("deepColor", config_.deepColor.x, config_.deepColor.y, config_.deepColor.z);
368 shader_->sendVec3("shallowColor", config_.shallowColor.x, config_.shallowColor.y, config_.shallowColor.z);
369 shader_->sendFloat("depthDistance", depthGradientTexture_ ? -config_.depthDistance : config_.depthDistance);
370 shader_->sendVec3("foamColor", config_.foamColor.x, config_.foamColor.y, config_.foamColor.z);
371 shader_->sendFloat("reflInten", config_.reflectionIntensity);
372 shader_->sendVec3("reflTint", config_.reflectionTint.x, config_.reflectionTint.y, config_.reflectionTint.z);
373 shader_->sendFloat("sunInten", config_.sunIntensity);
374 shader_->sendFloat("fresnelPower", config_.fresnelPower);
375 shader_->sendFloat("causticsStrength", config_.causticsStrength);
376 shader_->sendFloat("ssrStrength", config_.screenSpaceReflection ? config_.screenSpaceReflectionStrength : -1.0F);
377 shader_->sendFloat("refractionStrength", config_.refractionStrength);
378 shader_->sendFloat("opacityAndDepth", -(config_.opacity + 1.0F));
379 shader_->sendFloat("causticsScale", config_.causticsScale);
380 shader_->sendFloat("waveSharpness", config_.waveSharpness);
381}
382
383Result<void> Water::applyConfigJson(const std::string& json) {
384 auto candidate = WaterStyleConfig::fromJson(json);
385 if (!candidate) return Result<void>::failure(candidate.status());
386 config_ = std::move(candidate).takeValue();
387 bindParams();
388 return Result<void>::success();
389}
390
391Result<std::string> Water::configJson() const { return config_.toJson(); }
392
393void Water::draw() { drawWithReflection(nullptr, 0.0F); }
394
395void Water::drawWithPlanarReflection(Texture* planarReflection, float strength) {
396 drawWithReflection(planarReflection, std::clamp(strength, 0.0F, 4.0F));
397}
398
399void Water::drawWithReflection(Texture* requestedReflection, float requestedStrength) {
400 if (!gfx_ || !mesh_ || !shader_) return;
401 bindParams();
402 Texture *reflection = requestedReflection;
403 float reflectionStrength = requestedReflection ? requestedStrength : -1.0F;
404 RenderControl *rc = gfx_->getRenderControl();
405 if (!reflection && config_.screenSpaceReflection && rc && rc->isEnabled("ssr")) {
407 if (ssr->hasValidHistory()) {
408 reflection = ssr->getReflectionTexture();
409 reflectionStrength = config_.screenSpaceReflectionStrength;
410 }
411 }
412 shader_->sendFloat("ssrStrength", reflection ? reflectionStrength : -1.0F);
413 Texture *depth = rc && rc->getGBuffer() ? rc->getGBuffer()->getDepthTexture() : nullptr;
414 Texture *sceneColor = gfx_->getSceneColorTexture();
415 shader_->sendFloat("opacityAndDepth", depth ? config_.opacity : -(config_.opacity + 1.0F));
416 shader_->sendFloat("refractionStrength", sceneColor ? config_.refractionStrength : 0.0F);
417 gfx_->setMesh3DHeightTexture(reflection);
418 gfx_->setMesh3DNormalTexture(depthGradientTexture_);
420 gfx_->drawMeshShader(mesh_, glm::mat4(1.f), sceneColor, glm::vec4(1.f), shader_);
421 gfx_->setMesh3DHeightTexture(nullptr);
422 gfx_->setMesh3DNormalTexture(nullptr);
423 gfx_->setMesh3DSceneDepth(nullptr);
424}
425
426void Water::drawReflectionCapture() {
427 if (!gfx_ || !mesh_ || !shader_) return;
428 bindParams();
429 // Probe captures must never sample the main-view SSR history: that creates
430 // view-dependent feedback and recursively bakes an old reflection into the cube.
431 shader_->sendFloat("ssrStrength", -1.0F);
432 shader_->sendFloat("opacityAndDepth", -(config_.opacity + 1.0F));
433 shader_->sendFloat("refractionStrength", 0.0F);
434 gfx_->setMesh3DHeightTexture(nullptr);
435 gfx_->setMesh3DNormalTexture(depthGradientTexture_);
436 gfx_->drawMeshShader(mesh_, glm::mat4(1.f), nullptr, glm::vec4(1.f), shader_);
437 gfx_->setMesh3DNormalTexture(nullptr);
438 // Restore the authored state for a subsequent main-view draw in the same frame.
439 shader_->sendFloat("ssrStrength", config_.screenSpaceReflection ? config_.screenSpaceReflectionStrength : -1.0F);
440 shader_->sendFloat("refractionStrength", config_.refractionStrength);
441}
442
443} // namespace eve::graphics
float w
Definition AnimClip.cpp:738
float y
Definition AnimClip.cpp:738
float x
Definition AnimClip.cpp:738
float z
Definition AnimClip.cpp:738
int mask
float cx
Definition CardTypes.cpp:33
float degrees
Definition CardTypes.cpp:35
float uv
float nx
float nz
std::uint32_t vertexCount
tensor::Graph g
Definition GpuGraph.cpp:7
vk::ShaderModule vert
vk::ShaderModule frag
float u
Definition Grass.cpp:233
double r
float v
std::int32_t c
int h
std::array< float, 3 > scale
std::string name
MeleePoint3 b
Definition MeleeHit.cpp:41
MeleePoint3 a
Definition MeleeHit.cpp:40
std::vector< TriangleRef > triangles
int idx
float d
float t
uint8_t * pixels
std::uint32_t count
TerrainThermalSettings settings
float opacity
float step
Definition TreeMesh.cpp:314
uint32_t index
std::uint32_t depth
glm::vec3 point
static Diagnostic error(DiagnosticCode code, std::string message, std::string path={}, DiagnosticDetails details={}, std::string source={})
Construct an error diagnostic with the standard error severity.
Definition Diagnostic.h:125
void expect(std::string_view message) const
Require success for a void operation.
Definition Result.h:548
Move-only operation result carrying either a value or Status.
Definition Result.h:155
static Result success(T value)
Construct a successful result owning value.
Definition Result.h:164
static Result failure(Status status)
Construct a failed result from a structured status.
Definition Result.h:175
Texture * getDepthTexture() const
Returns the depth texture.
Definition GBuffer.h:51
ScreenSpaceReflection * pipelineScreenSpaceReflection()
Pipeline screen space reflection.
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....
Texture * newTextureFromImageData(image::ImageData *data, bool repeatU=false, bool repeatV=false)
Creates a texture from image data. @ownership Caller deletes unless documented otherwise.
virtual void setMesh3DSceneDepth(Texture *depth)=0
Optional scene hardware depth (G-buffer hwDepth, Vulkan NDC z) bound to mesh3d shader binding 7....
virtual eve::Result< void > configureMeshShaderSurface(Shader &, BlendMode, bool, bool)
Prepare a custom mesh shader's blend, depth and culling state.
Definition Graphics.h:1830
virtual Texture * getSceneColorTexture()
Sampleable 3D color target for the current frame (RGB = lit, A = linear depth). Valid after begin3DFr...
Definition Graphics.h:1047
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).
RenderControl * getRenderControl()
Shared compilable 3D render control (features → pass list + GBuffer). Owned by Graphics; valid for th...
Definition Graphics.cpp:254
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...
virtual void setMesh3DNormalTexture(Texture *normal)=0
Optional normal map for the next drawMesh / drawMeshShader (nullptr = flat).
virtual void setMesh3DHeightTexture(Texture *height)=0
Optional height map for parallax (R channel; nullptr = flat / off).
GPU mesh handle (+ optional CPU morph targets).
Definition Mesh.h:25
Declarative, compilable 3D render control.
bool isEnabled(const std::string &feature) const
True when enabled.
GBuffer * getGBuffer()
Returns the g buffer.
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.
Screen-space reflections (SSR) as a fullscreen post pass. @lifetime All Graphics and texture argument...
bool hasValidHistory() const
True once a temporally resolved reflection frame is safe to sample.
Texture * getReflectionTexture()
The reflection texture from the owned canvas, or nullptr before first apply.
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
GPU texture created via Graphics::newTexture. Owns GPU resources through an opaque backend handle.
Definition Texture.h:18
Result< void > setWaveDirectionAngle(float degrees)
Set Pcg PWS_WaterSystem wave direction in finite degrees around world Y.
Definition Water.cpp:328
void setScreenSpaceReflection(bool enabled, float strength=0.85f)
Optional screen-space reflection overlay. When enabled, the shader samples the temporally resolved SS...
Definition Water.cpp:344
void setWaveAmplitude(float amp)
Amplitude of the shore-edge waves.
Definition Water.cpp:322
Result< int > createProceduralMesh(const WaterMeshSettings &settings)
Validate, generate and atomically publish a Pcg-compatible plane or concentric-circle mesh.
Definition Water.cpp:207
static std::string paramName(int index)
Param name.
Definition Water.cpp:154
void setRippleAmplitude(float amp)
Amplitude of the occasional middle drop ripples.
Definition Water.cpp:323
Result< std::string > configJson() const
Return the canonical current eve.graphics.stylized-water/1 JSON snapshot.
Definition Water.cpp:391
void setWaveSpeed(float speed)
Sets the wave speed.
Definition Water.cpp:321
Water(Graphics *gfx)
Water.
Definition Water.cpp:159
void update(float dt)
Advance the animation clock by dt seconds.
Definition Water.cpp:311
void draw()
Draw the water plane (uses default mesh3d camera / lighting state).
Definition Water.cpp:393
void setEdgeFalloff(float edge)
Compatibility setter for the world-space shoreline foam width.
Definition Water.cpp:324
void createPlane(float sizeX, float sizeZ, int segX, int segZ)
Build a flat XZ plane (Y-up) sized sizeX × sizeZ with UVs in [0,1]².
Definition Water.cpp:172
void setSunIntensity(float intensity)
Sets the sun intensity.
Definition Water.cpp:343
void setReflectionTint(float r, float g, float b)
Sets the reflection tint.
Definition Water.cpp:339
void setTime(float seconds)
Sets the time.
Definition Water.cpp:316
void setReflectionIntensity(float intensity)
Sets the reflection intensity.
Definition Water.cpp:342
static int paramCount()
Names of the push-constant parameters (for UI / inspection).
Definition Water.cpp:152
void setWaveScale(float scale)
Sets the wave scale.
Definition Water.cpp:327
Result< int > setDepthGradient(const WaterDepthGradient &gradient, int resolution)
Bake Pcg GenerateColorDepth semantics and atomically publish the clamp-sampled texture.
Definition Water.cpp:281
void setRippleInterval(float seconds)
Seconds between drop ripples.
Definition Water.cpp:326
void bindParams()
Upload current params to the shader push constants.
Definition Water.cpp:353
void setViewport(float width, float height)
Window / target size in pixels, used to compute screen-space UVs.
Definition Water.cpp:348
void setRippleCount(int count)
How many expanding drop ripples exist.
Definition Water.cpp:325
void setWaterColor(float r, float g, float b)
Sets the water color.
Definition Water.cpp:336
Result< void > applyConfigJson(const std::string &json)
Atomically replace all authored parameters from eve.graphics.stylized-water/1 JSON.
Definition Water.cpp:383
void drawWithPlanarReflection(Texture *planarReflection, float strength=1.0F)
Draw with an optional caller-rendered planar reflection.
Definition Water.cpp:395
Represents raw pixel data.
Definition ImageData.h:38
medialoader::Colorf Colorf
Definition ImageData.h:41
std::variant< std::monostate, std::int64_t, double, std::string, bool > Value
Definition Database.h:26
ssq::Table project(HSQUIRRELVM vm, const eve::Result< void > &result)
Project a completed editing result that has no payload.
constexpr char kWaterFragWgsl[]
Backend-parity stylized-water WGSL source with depth foam and scene-color refraction.
Definition WaterWgsl.h:36
constexpr char kWaterVertWgsl[]
Vertex-displaced low-frequency water layers for the WebGPU backend.
Definition WaterWgsl.h:6
卡牌游戏 UI 工具模块:工厂 + 脚本绑定入口。 功能参考 ycarowr/UiCard:扇形手牌布局、抽牌/洗牌、悬浮放大、拖拽到落牌区、 敌方手牌(背面/偷看)、费用不足置灰,以及可实时调节的布局...
Definition Animation.h:25
Result< int > calculateWaterMeshTriangles(const WaterMeshSettings &settings)
Calculate Pcg PWS_WaterSystem's triangle count without allocating a mesh.
Definition Water.cpp:117
Shader * newWaterShader(Graphics *gfx)
Create the embedded water fragment shader (owned by Graphics).
Definition Water.cpp:129
bool enabled
Caller-owned color and alpha keys used to bake a water depth-ramp texture.
Definition Water.h:41
std::vector< WaterGradientAlphaStop > alphaStops
Definition Water.h:43
std::vector< WaterGradientColorStop > colorStops
Definition Water.h:42
Result< void > addAlphaStop(float time, float alpha)
Add a finite normalized alpha stop, preserving no external reference.
Definition Water.cpp:106
void clear()
Remove all owned color and alpha stops.
Definition Water.cpp:115
Result< void > addColorStop(float time, float red, float green, float blue)
Add a finite normalized RGB stop, preserving no external reference.
Definition Water.cpp:95
Authored dimensions and density for Pcg-compatible procedural water geometry.
Definition Water.h:18
Result< std::string > toJson() const
Serialize canonical JSON after validation.
static Result< WaterStyleConfig > fromJson(std::string_view json)
Parse JSON and decode version one transactionally.
glm::uvec4 counts
glm::vec4 color