载入中...
搜索中...
未找到
Graphics.h
浏览该文件的文档.
1#pragma once
2
3#include "common/Export.h"
4#include "graphics/Batcher.h"
6#include "graphics/Graphics.h"
7#include "graphics/Light.h"
8#include "graphics/Mesh.h"
11#include "graphics/Shader.h"
12#include "graphics/Shadow.h"
13#include "graphics/Texture.h"
14
15#if defined(__EMSCRIPTEN__) && __has_include(<webgpu/webgpu_cpp.h>)
16#include <webgpu/webgpu_cpp.h>
17#else
18#include <dawn/webgpu_cpp.h>
19#endif
20
22
23#include <array>
24#include <atomic>
25#include <cstdint>
26#include <map>
27#include <memory>
28#include <tuple>
29#include <unordered_map>
30#include <vector>
31
32#include <glm/ext/vector_uint4_sized.hpp>
33#include <glm/mat4x4.hpp>
34#include <glm/vec2.hpp>
35#include <glm/vec3.hpp>
36#include <glm/vec4.hpp>
37
38namespace eve::graphics::webgpu {
39
40class OffscreenCanvas;
41struct PbrVariantSources;
42
48struct Mesh3DUBO {
49 glm::mat4 mvp{1.f};
50 glm::mat4 model{1.f};
51 glm::vec4 lightDir{0.4f, 1.f, 0.3f, 0.f}; // xyz = primary dir; w = lightCount
52 glm::vec4 lightColor{1.f, 1.f, 1.f, 0.f}; // rgb = primary color; w = envIntensity
53 glm::vec4 tint{1.f, 1.f, 1.f, 1.f};
54 glm::vec4 cameraPos{0.f, 0.f, 3.f, 0.45f}; // xyz = eye; w = roughness
55 glm::vec4 ambient{0.12f, 0.12f, 0.14f, 0.f}; // rgb = ambient; w = metallic
57 glm::vec4 texBomb{4.f, 0.f, 1.f, 0.f}; // x=cellScale, y=strength, z=rotAmount
58 glm::vec4 parallax{0.f, 8.f, 32.f, 0.f}; // x=scale, y=minLayers, z=maxLayers
59 glm::vec4 surface{0.f, 0.5f, 0.f, 0.f}; // mode, alphaCutoff, ssao, reserved
60 glm::mat4 view{1.f};
61 glm::vec4 clipInfo{0.1f, 100.f, 0.f, 0.f}; // x=near, y=far
62 glm::vec4 cloud{0.f, 1.5f, 0.f, 0.f}; // x=strength(0=off), y=worldCell, z=time
63 glm::vec4 cloudWind{4.f, 0.f, 0.55f, 0.5f}; // xy=wind vel, z=coverage, w=detail
64 glm::vec4 virtualTexture{0.f}; // enabled, pageCountX, pageCountY, border/extent
65 glm::vec4 virtualAtlas{0.f}; // slotsX, slotsY
66 glm::vec4 envProbeCenter{0.f};
67 glm::vec4 envProbeExtent{0.f};
68 glm::vec4 skinInfo{0.f};
71 glm::vec4 diffuseProbeSh[9]{};
72 glm::vec4 diffuseProbeInfo{0.f}; // x = enabled
76 glm::vec4 diffuseVolumeInfo{0.f}; // x = probe count
77 glm::vec4 lodFade{1.f, 0.f, 0.f, 0.f}; // coverage, complementary pattern, enabled
78};
79static_assert(sizeof(Mesh3DUBO) == 2496, "Mesh3DUBO layout must match the WGSL Frame block");
80
82struct MeshVertex {
83 glm::vec3 pos;
84 glm::vec3 normal;
85 glm::vec2 uv;
86 glm::u16vec4 joints{0};
87 glm::vec4 weights{0.f};
88 glm::vec4 color{1.f};
89};
90static_assert(sizeof(MeshVertex) == 72);
91
94 glm::mat4 mvp{1.f};
95 glm::mat4 model{1.f};
96 glm::vec4 clip{0.f};
97 glm::vec4 skinInfo{0.f};
98};
99static_assert(sizeof(SkinPassUBO) == 160);
100
106 glm::mat4 mvp{1.f};
107 glm::mat4 model{1.f};
108 glm::mat4 view{1.f};
109 glm::vec4 lightDir{0.4f, 1.f, 0.3f, 0.f}; // xyz = primary dir; w = 1 if valid
110 glm::vec4 lightColor{1.f, 1.f, 1.f, 0.f}; // rgb = primary; w = envIntensity
111 glm::vec4 tint{1.f, 1.f, 1.f, 1.f};
112 glm::vec4 cameraPos{0.f, 0.f, 3.f, 0.45f}; // xyz = eye; w = roughness
113 glm::vec4 ambient{0.12f, 0.12f, 0.14f, 0.f}; // rgb = ambient; w = metallic
114 glm::vec4 gridInfo{16.f, 9.f, 24.f, 0.f}; // tilesX, tilesY, slices, pointCount
115 glm::vec4 clipInfo{0.1f, 100.f, 1.f, 1.f}; // near, far, screenW, screenH
116 glm::vec4 texBomb{4.f, 0.f, 1.f, 0.f}; // x=cellScale, y=strength, z=rotAmount, w=AO
117 glm::vec4 parallax{0.f, 8.f, 32.f, 0.f}; // x=scale, y=minLayers, z=maxLayers
118 glm::vec4 surface{0.f, 0.5f, 0.f, 0.f}; // mode, alphaCutoff, ssao, reserved
119 glm::vec4 virtualTexture{0.f};
120 glm::vec4 virtualAtlas{0.f};
121 glm::vec4 envProbeCenter{0.f};
122 glm::vec4 envProbeExtent{0.f};
125};
126static_assert(sizeof(Mesh3DClusteredUBO) == 480, "Mesh3DClusteredUBO layout must match the WGSL clustered Frame block");
127
132 wgpu::Texture texture;
133 wgpu::TextureView view;
134 wgpu::Sampler sampler;
135 // Bind group for the unified 2D layout (color at 0, depth at 1).
136 wgpu::BindGroup tex2DGroup;
137 // Bind group for the mesh3d layout (albedo at 1, normal at 2, env at 3,
138 // height at 6). Rebuilt when the mesh3d pipeline re-creates its layout.
139 wgpu::BindGroup meshGroup;
140 bool isCube = false;
141 bool isArray = false;
142 bool isVolume = false;
143 bool isHDR = false;
144 int width = 0;
145 int height = 0;
146 uint32_t mipLevels = 1;
148};
149
153struct GpuMesh {
154 wgpu::Buffer vertexBuffer;
155 wgpu::Buffer indexBuffer;
156 uint64_t vertexCapacity = 0;
157 uint64_t indexCapacity = 0;
158 uint32_t indexCount = 0;
159 uint32_t vertexCount = 0;
160 uint32_t vertexStride = 0;
161 wgpu::IndexFormat indexFormat = wgpu::IndexFormat::Uint32;
162 std::vector<MeshVertex> cpuVertices;
163};
164
169struct GpuShader {
170 wgpu::RenderPipeline swapchainPipeline; // 2D/offscreen color format
171 wgpu::RenderPipeline offscreenPipeline; // RGBA8Unorm canvas format
172 wgpu::RenderPipeline swapchainOpaquePipeline;
173 wgpu::RenderPipeline offscreenOpaquePipeline;
174 wgpu::RenderPipeline hdrOffscreenPipeline;
175 wgpu::RenderPipeline hdrOffscreenOpaquePipeline;
176 wgpu::RenderPipeline mesh3dPipeline; // scene color format
177 wgpu::RenderPipeline mesh3dXrayPipeline; // depth test/write off + alpha blend
178 wgpu::RenderPipeline shadowPipeline; // depth-only
179 wgpu::RenderPipeline gbufferPipeline; // MRT gbuffer
180 wgpu::PipelineLayout pipelineLayout;
181 wgpu::BindGroupLayout setLayout;
182 bool isMesh3D = false;
183 bool isHair3D = false;
184 bool isShadow = false;
185 bool isGbuffer = false;
186 std::string wgslVert;
187 std::string wgslFrag;
188};
189
192public:
193 // Keep the base draw(Drawable*, mat4) overload visible alongside the
194 // canvas composite overloads below.
196
198 Graphics();
200 ~Graphics() override;
201
203 std::string getBackendName() const override { return "webgpu"; }
205 bool supportsGBufferPost() const override { return true; }
207 bool supportsDeferredLighting() const override { return true; }
209 void drawDeferredLighting() override;
211 bool supportsGpuDriven3D() const override { return true; }
213 bool gpuDrivenEnabled() const override { return gpuDrivenEnabled_; }
215 void gpuDrivenSetEnabled(bool enabled) override { gpuDrivenEnabled_ = enabled; }
217 uint32_t gpuDrivenMeshRecord(Mesh *mesh) override;
219 uint32_t gpuDrivenMaterialRecord(Material *material) override;
221 bool gpuDrivenMaterialUsable(Material *material) override;
223 bool gpuDrivenSubmitOpaque(const GpuInstance *instances, uint32_t instanceCount) override;
225 GpuResidentSubmitStatus gpuDrivenSubmitResident(const GpuResidentInstanceBatch &batch) override;
227 bool gpuDrivenCullEnabled() const override { return gpuDrivenEnabled_; }
229 bool gpuDrivenCullBegin(const GpuInstance *instances, uint32_t instanceCount) override;
231 void gpuDrivenCullEmit(const glm::mat4& viewProj, const glm::vec3& eye, float fovYDeg, float nearZ,
232 float farZ) override;
234 void gpuDrivenDrawOpaque() override;
236 bool gpuDrivenResolveWanted() const override;
238 void gpuDrivenRecordVisPass() override;
240 void gpuDrivenResolve() override;
242 uint32_t gpuDrivenVgUpload(const GpuVgAssetUpload &asset) override;
244 uint32_t gpuDrivenVgAssetId(Mesh *mesh) const override;
246 bool gpuDrivenVgAttachToMesh(Mesh *mesh, uint32_t vgAssetId) override;
249 bool gpuDrivenVgSetInstance(uint32_t vgAssetId, const glm::mat4& model, uint32_t materialId) override;
251 void gpuDrivenVgComputeSection(const glm::mat4& viewProj, const glm::vec3& eye, float fovYDeg, float nearZ,
252 float farZ) override;
254 uint32_t debugGpuDrivenVisibleCount() const { return static_cast<uint32_t>(gpuDrivenVisible_.size()); }
256 uint32_t debugGpuDrivenDispatchCount() const { return gpuDrivenDispatchCount_; }
258 uint32_t debugGpuDrivenIndirectDrawCount() const { return gpuDrivenLastIndirectDrawCount_; }
260 uint32_t debugGpuDrivenGpuVisibleCount();
262 uint32_t debugGpuDrivenHzbMipCount() const { return static_cast<uint32_t>(gpuDrivenHzbOffsets_.size()); }
264 uint32_t debugGpuDrivenVgDispatchCount() const { return gpuDrivenVgVisibleDiagnostic_; }
266 uint32_t debugGpuDrivenVgIndirectDrawCount() const { return gpuDrivenVgLastIndirectDrawCount_; }
268 uint32_t debugGpuDrivenVgGpuVisibleCount();
270 [[nodiscard]] Result<void> gpuDrivenReleaseMaterialRecord(Material *material) override;
272 [[nodiscard]] Result<void> debugValidatePbrVariantBaseSources();
274 [[nodiscard]] Result<void> debugValidatePbrVariantSources(const PbrVariantSources &sources);
276 [[nodiscard]] Result<void> debugValidatePbrVariantPipeline(const PbrVariantSources &sources);
277
278 void initHeadless(int width, int height) override;
280 void initWithWindow(void *nativeWindow) override;
282 void present() override;
284 void pushValidationScope() override;
286 void popValidationScope() override;
288 void setMsaaSamples(int samples) override;
290 void requestSurfaceRecreate() override { surfaceNeedsRecreate = true; }
292 void setVSync(bool enabled) override;
294 int getMsaaSamples() const override { return msaaSamples; }
296 void setViewportSize(int width, int height, int pixelwidth, int pixelheight) override;
298 void drawSolidRect(float x, float y, float w, float h, const Color &color,
299 BlendMode blend = BlendMode::Alpha) override;
301 void drawPrimitiveCanvas(const PrimitiveCanvas2D &canvas) override;
303 void drawSolidRectRotated(float cx, float cy, float w, float h, float degrees,
304 const Color &color,
305 BlendMode blend = BlendMode::Alpha) override;
306
308 Texture *newTexture(int width, int height, const uint8_t *rgba, bool repeatU = false,
309 bool repeatV = false) override;
311 Texture *newTexture(int width, int height, const uint8_t *rgba,
312 const TextureCreateInfo &info) override;
313#if !defined(__EMSCRIPTEN__)
316 [[nodiscard]] Result<Texture *> newTextureMipChain(uint32_t width, uint32_t height,
317 uint32_t levels,
318 std::span<const uint8_t> rgba) override;
321 [[nodiscard]] Result<Texture *> newTextureArrayRgba16f(
322 uint32_t width, uint32_t height, uint32_t layers,
323 std::span<const uint16_t> rgbaHalf) override;
326 [[nodiscard]] Result<Texture *> newTexture3DRgba8(uint32_t width, uint32_t height,
327 uint32_t depth,
328 std::span<const uint8_t> rgba) override;
329#endif
331 Texture *newCubemap(int faceSize, const uint8_t *rgbaFaces) override;
333 Texture *newCubemap(int faceSize, const uint8_t *rgbaFaces,
334 const TextureCreateInfo &info) override;
337 Texture *newHDRCubemap(int faceSize) override;
340 bool copyHDRCanvasToCubemapFace(Canvas *source, Texture *cubemap, int face) override;
342 bool copyHDRCanvasesToCubemap(Canvas *const *sources, int faceCount,
343 Texture *cubemap) override;
346 bool filterHDRReflectionCubemap(Texture *cubemap, int sampleCount = 64) override;
348 Texture *newTexture(image::ImageData *data) override;
350 Texture *newTexture(image::ImageData *data, const TextureCreateInfo &info) override;
352 [[nodiscard]] ResultRef<Texture> newSharedTexture(image::ImageData *data, const std::string &contentKey) override;
354 void setTextureSampler(Texture *texture, const TextureSampler &sampler) override;
356 float getMaxAnisotropy() const override;
358 Texture *newTextureFromFile(const std::string &filename) override;
360 bool reloadTextureFromFile(const std::string &filename) override;
362 bool uploadDeferredFileTexture(Texture *texture, image::ImageData *data) override;
364 bool releaseTexture(Texture *texture) override;
366 bool updateTexture(Texture *texture, int width, int height,
367 const uint8_t *rgba) override;
369 eve::Result<void> updateTextureRegion(Texture *texture, int x, int y, int width,
370 int height, std::span<const std::uint8_t> rgba,
371 std::size_t bytesPerRow = 0) override;
373 eve::Result<void> updateTextureRegions(
374 Texture *texture, std::span<const TextureRegionUpload> regions) override;
375
377 void drawTexturedRect(Texture *texture, float x, float y, float w, float h,
378 const Color &color) override;
380 void drawTexturedRectShader(Texture *texture, Shader *shader, float x, float y, float w, float h,
381 const Color &color) override;
383 void drawTexturedRectUV(Texture *texture, float x, float y, float w, float h, float u0, float v0,
384 float u1, float v1, const Color &color) override;
386 void drawTexturedRectShaderUV(Texture *texture, Shader *shader, float x, float y, float w,
387 float h, float u0, float v0, float u1, float v1,
388 const Color &color, bool rotatedUV = false,
389 BlendMode blend = BlendMode::Alpha) override;
391 void drawTexturedRectShaderUVRotated(Texture *texture, Shader *shader, float cx, float cy,
392 float w, float h, float degrees, float u0, float v0,
393 float u1, float v1, const Color &color,
394 bool rotatedUV = false,
395 BlendMode blend = BlendMode::Alpha) override;
397 void drawTexturedRectShaderDepth(Texture *color, Texture *depth, Shader *shader, float x, float y,
398 float w, float h, const Color &tint) override;
400 void drawTexturedRectShaderDepthMotion(Texture *color, Texture *depth, Texture *motion,
401 Shader *shader, float x, float y, float w, float h,
402 const Color &tint) override;
404 void drawTexturedRectShader4(Texture *color, Texture *depth, Texture *motion, Texture *extra,
405 Shader *shader, float x, float y, float w, float h,
406 const Color &tint) override;
408 void drawTexturedRectShader5(Texture *color, Texture *depth, Texture *motion, Texture *extra,
409 Texture *specular, Shader *shader, float x, float y, float w,
410 float h, const Color &tint) override;
412 void drawTexturedRectLitUV(Texture *albedo, Texture *normal, float x, float y, float w, float h, float u0, float v0,
413 float u1, float v1, const Color &color, BlendMode blend = BlendMode::Alpha) override;
415 void drawTexturedRectLitUVRotated(Texture *albedo, Texture *normal, float cx, float cy, float w, float h,
416 float degrees, float u0, float v0, float u1, float v1, const Color &color,
417 BlendMode blend = BlendMode::Alpha) override;
419 void setLighting2D(const Lighting2DUBO &ubo) override;
420
422 Shader *newShaderFromSpv(const std::vector<uint32_t> &vertSpv,
423 const std::vector<uint32_t> &fragSpv) override;
425 Shader *newShaderFromSpvFile(const std::string &vertPath, const std::string &fragPath) override;
427 Shader *newShaderFromWgsl(const std::string &vertWgsl,
428 const std::string &fragWgsl) override;
430 [[nodiscard]] Result<void> replaceShaderFromSpv(
431 Shader &shader, const std::vector<uint32_t> &vertSpv,
432 const std::vector<uint32_t> &fragSpv) override;
434 [[nodiscard]] Result<void> replaceShaderFromWgsl(
435 Shader &shader, const std::string &vertWgsl,
436 const std::string &fragWgsl) override;
438 [[nodiscard]] Result<void> replaceShaderFromGlsl(
439 Shader &shader, const std::string &vertGlsl,
440 const std::string &fragGlsl) override;
442 Shader *newShader(const std::string &vertGlsl, const std::string &fragGlsl) override;
444 Shader *newMeshShaderFromSpv(const std::vector<uint32_t> &vertSpv,
445 const std::vector<uint32_t> &fragSpv) override;
447 Shader *newMeshShaderFromWgsl(const std::string &vertWgsl,
448 const std::string &fragWgsl) override;
450 eve::Result<void> configureMeshShaderSurface(Shader& shader, BlendMode blend,
451 bool depthWrite, bool doubleSided) override;
453 Shader *newMeshShader(const std::string &vertGlsl, const std::string &fragGlsl) override;
455 Shader *newHairShaderFromSpv(const std::vector<uint32_t> &vertSpv,
456 const std::vector<uint32_t> &fragSpv) override;
458 Shader *newHairShaderFromWgsl(const std::string &vertWgsl,
459 const std::string &fragWgsl) override;
461 bool releaseShader(Shader *shader) override;
462
464 Mesh *newMeshFromAssimp(const ::aiMesh &mesh) override;
466 Mesh *newMeshFromAssimp(const ::aiMesh &mesh, const aiMatrix4x4 &worldTransform) override;
468 Mesh *newMeshFromArrays(const float *posXYZ, const float *nrmXYZ, const float *uvST,
469 int vertexCount, const uint32_t *indices, int indexCount) override;
477 Mesh *newMeshFromArraysColored(const float *posXYZ, const float *nrmXYZ, const float *uvST,
478 const float *colorRGBA, int vertexCount,
479 const uint32_t *indices, int indexCount) override;
481 [[nodiscard]] std::optional<eve::graphics::MeshBackendDescriptor> describeMesh(Mesh *mesh) const override;
482 bool bakeMeshMorph(Mesh *mesh) override;
484 bool updateMeshVertices(Mesh *mesh, const float *posXYZ, const float *nrmXYZ, const float *uvST,
485 int vertexCount, const uint32_t *indices, int indexCount) override;
487 bool setMeshSkinningData(Mesh *mesh, const uint16_t *joints4, const float *weights4,
488 int vertexCount) override;
490 Mesh *newMeshSphere(int slices = 32, int stacks = 16) override;
492 Mesh *newMeshCylinder(int slices = 32, int stacks = 1, bool caps = true) override;
494 bool releaseMesh(Mesh *mesh) override;
495
497 void begin3DFrame() override;
499 void begin3DFrameToCanvas(Canvas *canvas) override;
501 void end3DFrameToCanvas() override;
503 void drawPrimitiveScene(const PrimitiveSceneCanvas3D &canvas) override;
505 float getLastOffscreen3DGpuDurationMs() const override {
506 return completedOffscreenTimestampMs.exchange(0.f);
507 }
509 void setMesh3DViewProj(const glm::mat4 &viewProj) override;
511 void setMesh3DView(const glm::mat4 &view) override;
513 void setMesh3DClip(float nearZ, float farZ) override;
515 Texture *getSceneColorTexture() override;
521 Texture *getSceneLinearDepthTexture() override;
523 void drawMesh(Mesh *mesh, const glm::mat4 &model, Texture *texture, const Color &tint) override;
525 void drawMeshShader(Mesh *mesh, const glm::mat4 &model, Texture *texture, const Color &tint,
526 Shader *shader) override;
528 void drawVoxelFaceInstances(const uint32_t *packed, int count, float originX, float originY,
529 float originZ, const std::string &faceDir, Texture *atlas,
530 int tilesPerRow = 16, const uint32_t *ao = nullptr) override;
532 void setMesh3DNormalTexture(Texture *normal) override;
534 void setMesh3DPackedNormalMask(bool enabled) override;
536 void setMesh3DHeightTexture(Texture *height) override;
538 void setMesh3DVirtualTexture(bool enabled, int pageCountX, int pageCountY,
539 int atlasSlotsX, int atlasSlotsY,
540 float borderFraction) override;
542 void setMesh3DSceneDepth(Texture *depth) override;
544 void setMesh3DSceneColor(Texture *color) override;
546 [[nodiscard]] Mesh3DSceneColorCaptureStatus captureMesh3DSceneColor() override;
548 void setMesh3DMaterial(float metallic, float roughness) override;
550 [[nodiscard]] Result<void> setMesh3DPbrSurface(const PbrSurface *surface) override;
552 void setMesh3DSurface(SurfaceMode mode, BlendMode blend, bool depthWrite,
553 bool doubleSided, float alphaCutoff,
554 const std::string &alphaTechnique = "cutoff") override;
556 void setMesh3DTexCellBomb(float cellScale, float strength, float rotAmount = 1.f) override;
558 void setMesh3DParallax(float scale, float minLayers = 8.f, float maxLayers = 32.f) override;
560 void setMesh3DLodDither(float weight, bool reverse, bool enabled) override;
562 void setMesh3DLighting(const Lighting3DPack &pack) override;
564 void setCloudShadows(float strength, float worldCell, float time, float windSpeed, float windAngle, float coverage,
565 float detail) override;
567 void setMesh3DClusteredLighting(const ClusteredLightingUpload &upload) override;
569 void setMesh3DClusteredActive(bool active) override;
571 void setMesh3DSSAO(float intensity) override;
573 void setMesh3DLight(const glm::vec3 &dir, const glm::vec3 &color) override;
575 void setMesh3DCameraPos(const glm::vec3 &eye) override;
577 void setMesh3DEnv(Texture *cube, float intensity) override;
579 void setMesh3DEnvProbe(const glm::vec3 &center, const glm::vec3 &extent) override;
581 void setMesh3DReflectionProbes(const ReflectionProbeUpload &upload) override;
583 void setSceneExposure(float exposure) override { sceneExposure = std::max(exposure, 0.f); }
585 float getSceneExposure() const override { return sceneExposure; }
587 void setSceneColorFilter(const glm::vec3& color) override { sceneColorFilter = glm::max(color, glm::vec3(0.f)); }
589 glm::vec3 getSceneColorFilter() const override { return sceneColorFilter; }
591 void setSceneLiftGammaGain(const glm::vec3& lift, const glm::vec3& inverseGamma, const glm::vec3& gain) override {
592 sceneLift = lift;
593 sceneInverseGamma = glm::max(inverseGamma, glm::vec3(0.001F));
594 sceneGain = gain;
595 }
597 glm::vec3 getSceneLift() const override { return sceneLift; }
599 glm::vec3 getSceneInverseGamma() const override { return sceneInverseGamma; }
601 glm::vec3 getSceneGain() const override { return sceneGain; }
603 void setSceneTransitionFx(float vignette, float vignetteSmoothness, float lensDistortion,
604 float lensScale) override {
605 sceneTransitionVignette = std::clamp(vignette, 0.0F, 1.0F);
606 sceneTransitionVignetteSmoothness = std::clamp(vignetteSmoothness, 0.01F, 1.0F);
607 sceneTransitionLensDistortion = std::clamp(lensDistortion, 0.0F, 1.0F);
608 sceneTransitionLensScale = std::clamp(lensScale, 0.01F, 5.0F);
609 }
611 float getSceneTransitionVignette() const override { return sceneTransitionVignette; }
613 float getSceneTransitionVignetteSmoothness() const override { return sceneTransitionVignetteSmoothness; }
615 float getSceneTransitionLensDistortion() const override { return sceneTransitionLensDistortion; }
617 float getSceneTransitionLensScale() const override { return sceneTransitionLensScale; }
619 void setSceneAutoExposure(bool enabled, float minEV, float maxEV) override {
620 sceneAutoExposure = enabled;
621 sceneAutoExposureMinEV = minEV;
622 sceneAutoExposureMaxEV = maxEV;
623 }
625 bool getSceneAutoExposure() const override { return sceneAutoExposure; }
627 float getSceneAutoExposureMinEV() const override { return sceneAutoExposureMinEV; }
629 float getSceneAutoExposureMaxEV() const override { return sceneAutoExposureMaxEV; }
631 void setSceneBloom(float intensity, float threshold) override {
632 sceneBloomIntensity = intensity;
633 sceneBloomThreshold = threshold;
634 }
636 float getSceneBloomIntensity() const override { return sceneBloomIntensity; }
638 float getSceneBloomThreshold() const override { return sceneBloomThreshold; }
640 void setSceneDepthOfField(float focusDistance, float maxBlurPx, float focusRange, float nearZ,
641 float farZ) override {
642 sceneDofFocusDistance = focusDistance;
643 sceneDofMaxBlurPx = maxBlurPx;
644 sceneDofFocusRange = focusRange;
645 sceneDofNearZ = nearZ;
646 sceneDofFarZ = farZ;
647 }
649 float getSceneDofFocusDistance() const override { return sceneDofFocusDistance; }
651 float getSceneDofMaxBlur() const override { return sceneDofMaxBlurPx; }
653 float getSceneDofFocusRange() const override { return sceneDofFocusRange; }
655 float getSceneDofNearZ() const override { return sceneDofNearZ; }
657 float getSceneDofFarZ() const override { return sceneDofFarZ; }
659 void setMesh3DShadows(const ShadowUpload &upload) override;
661 void setMesh3DShadowReceive(bool receive) override;
663 void setMesh3DSkinInfluenceLimit(SkinInfluenceLimit count) override;
665 void beginShadowPass(int cascadeIndex) override;
667 void drawMeshShadow(Mesh *mesh, const glm::mat4 &lightMVP, bool doubleSided = true) override;
669 void drawMeshShadowAlpha(Mesh *mesh, const glm::mat4 &lightMVP, Texture *albedo = nullptr,
670 bool doubleSided = true, float lodWeight = 1.f,
671 bool lodFadeReverse = false, bool lodDither = false) override;
673 void endShadowPass() override;
674
676 void beginGBufferPass(int width, int height) override;
678 void drawMeshGBuffer(Mesh* mesh, const glm::mat4& mvp, const glm::mat4& model, float nearZ, float farZ,
679 Texture* albedo = nullptr, float tintR = 1.f, float tintG = 1.f, float tintB = 1.f,
680 float motionX = 0.f, float motionY = 0.f, float roughness = 0.45f,
681 float metallic = 0.f) override;
683 void drawMeshGBufferAlpha(Mesh* mesh, const glm::mat4& mvp, const glm::mat4& model, float nearZ, float farZ,
684 Texture* albedo = nullptr, float tintR = 1.f, float tintG = 1.f, float tintB = 1.f,
685 float motionX = 0.f, float motionY = 0.f, float roughness = 0.45f,
686 float metallic = 0.f) override;
688 void endGBufferPass() override;
690 image::ImageData *readGBufferToImageData(const std::string &attachment) override;
691
693 bool supportsDecal() const override { return true; }
695 void beginDecalPass(int width, int height) override;
697 void setDecalCamera(const glm::mat4 &viewProj, float nearZ, float farZ) override;
699 void drawDecal(const glm::mat4 &model, Texture *albedo, Texture *normal, Texture *params,
700 const float uvRect[4], float fade, float normalStrength, float roughnessStrength,
701 float metalStrength, float emissiveStrength, int blendMode = 0,
702 int projectionMode = 0, float blendSharpness = 4.f,
703 float parallaxScale = 0.f, float parallaxMinLayers = 8.f,
704 float parallaxMaxLayers = 24.f, float edgeFadeWidth = 0.06f) override;
706 void endDecalPass() override;
708 image::ImageData *readDecalLayerToImageData(const std::string &attachment) override;
709
711 Canvas *newCanvas(int width, int height) override;
714 Canvas *newHDRCanvas(int width, int height) override;
716 void setCanvas(Canvas *canvas) override;
718 bool isCanvasActive() const override;
720 Canvas *getCanvas() const override;
721
723 Texture *getTexture() override;
725 image::ImageData *newImageData() override;
727 bool beginFrameReadback(const std::string &path) override;
729 int frameReadbackStatus() const override;
731 void pumpReadback();
733 void draw(eve::graphics::Graphics *gfx, const glm::mat4 &matrix) const override;
735 void draw(Canvas *C, const glm::mat4 &matrix) const override;
737 void clear(std::optional<Color> color, std::optional<int> stencil, std::optional<double> depth) override;
739 Color getPixel(int x, int y) override;
740
742 void flush2DToCanvas(OffscreenCanvas *canvas);
744 Color getPixelImpl(OffscreenCanvas *canvas, int x, int y);
746 image::ImageData *newImageDataImpl(OffscreenCanvas *canvas);
749 image::ImageData *newHDRImageDataImpl(OffscreenCanvas *canvas);
750
752 wgpu::Instance &getInstance() { return instance; }
754 wgpu::Device &getDevice() { return device; }
756 wgpu::Queue &getQueue() { return queue; }
758 wgpu::Surface &getSurface() { return surface; }
760 WGPUTextureFormat getSurfaceFormat() const { return surfaceFormat; }
762 void *getSdlWindow() const { return sdlWindow; }
764 bool isReady() const { return initialized; }
765
766 // The present overlay is rendered inside the swapchain render pass. The
767 // void* payload is a WGPURenderPassEncoder* on the WebGPU backend.
769
770 friend class OffscreenCanvas;
771
773 struct SolidBatch {
774 BlendMode blend = BlendMode::Alpha;
776 };
778 Texture *texture = nullptr;
779 Texture *depth = nullptr;
780 Shader *shader = nullptr;
781 BlendMode blend = BlendMode::Alpha;
783 Texture *motion = nullptr;
784 Texture *extra = nullptr;
785 Texture *specular = nullptr;
786 };
787 struct LitBatch {
788 Texture *albedo = nullptr;
789 Texture *normal = nullptr;
790 BlendMode blend = BlendMode::Alpha;
792 };
793
794private:
795 struct Mesh3dDraw {
796 Mesh *mesh = nullptr;
797 Texture *texture = nullptr;
798 Texture *normalTexture = nullptr;
799 Texture *heightTexture = nullptr;
800 glm::vec4 virtualTexture{0.f};
801 glm::vec4 virtualAtlas{0.f};
802 glm::mat4 model{1.f};
803 Color tint{1.f};
804 Shader *shader = nullptr;
805 SurfaceMode surfaceMode = SurfaceMode::Opaque;
806 BlendMode surfaceBlend = BlendMode::Alpha;
807 bool depthWrite = false;
808 bool doubleSided = false;
809 bool shadowReceive = true;
810 float metallic = 0.f;
811 float roughness = 1.f;
812 glm::mat4 viewProj{1.f};
813 glm::mat4 view{1.f};
814 glm::vec3 cameraPos{};
815 Lighting3DPack lighting{};
816 ShadowUpload shadows{};
817 Texture *environment = nullptr;
818 float environmentIntensity = 0.f;
819 int skinInfluenceLimit = 4;
820 float alphaCutoff = 0.5f;
821 std::string alphaTechnique = "cutoff";
822 glm::vec4 lodFade{1.f, 0.f, 0.f, 0.f};
823 std::optional<PbrSurface> pbrSurface;
824 wgpu::Buffer skinBuffer;
825 uint32_t frameUboOffset = 0;
826 uint32_t pushUboOffset = 0;
827 uint32_t shadowUboOffset = 0;
828 uint32_t clusteredUboOffset = 0;
829 };
830 struct ShadowDraw {
831 Mesh *mesh = nullptr;
832 Texture *albedo = nullptr;
833 glm::mat4 mvp{1.f};
834 bool alphaTest = false;
835 bool doubleSided = true;
836 glm::vec4 lodFade{1.f, 0.f, 0.f, 0.f};
837 int skinInfluenceLimit = 4;
838 };
839 struct GbufferDraw {
840 Mesh *mesh = nullptr;
841 Texture *albedo = nullptr;
842 glm::mat4 mvp{1.f};
843 glm::mat4 model{1.f};
844 float nearZ = 0.1f;
845 float farZ = 100.f;
846 glm::vec4 tint{1.f};
847 glm::vec2 motion{0.f};
848 float roughness = 0.45f;
849 float metallic = 0.f;
850 bool alphaTest = false;
851 int skinInfluenceLimit = 4;
852 uint32_t pushUboOffset = 0;
853 };
854 struct VoxelDraw {
855 uint32_t instanceBufferOffset = 0;
856 uint32_t aoBufferOffset = 0;
857 uint32_t count = 0;
858 GpuTexture *atlas = nullptr;
859 glm::mat4 viewProj{1.f};
860 glm::vec4 chunkOrigin{0.f};
861 glm::vec4 atlasInfo{16.f, 0.f, 0.f, 0.f};
862 glm::vec4 tint{1.f};
863 uint32_t pushUboOffset = 0;
864 };
865 struct DecalDraw {
866 glm::mat4 model{1.f};
867 Texture *albedo = nullptr;
868 Texture *normal = nullptr;
869 Texture *params = nullptr;
870 glm::vec4 uvRect{0.f, 0.f, 1.f, 1.f};
871 glm::vec4 fadeParams{1.f, 0.f, 0.f, 0.f};
872 glm::vec4 extraParams{0.f};
873 glm::vec4 surfaceParams{0.f, 8.f, 24.f, 0.06f};
874 };
875
876 void configureSurface(int width, int height);
877 void createDefaultTextures();
878 void createPipelineResources();
879 void create2DPipelines();
880 void createMesh3DPipelines();
881 wgpu::RenderPipeline get2DColorPipeline(BlendMode blend, bool offscreen);
882 wgpu::RenderPipeline get2DTexturedPipeline(BlendMode blend, bool offscreen);
883 wgpu::RenderPipeline get2DLitPipeline(BlendMode blend, WGPUTextureFormat format);
884 wgpu::RenderPipeline getMesh3DPipeline(BlendMode blend, bool depthWrite, bool doubleSided, bool canvasTarget);
885 void createMesh3DClusteredPipeline();
886 void createShadowPipelines();
887 void createGbufferPipelines();
888 void createDecalPipeline();
889 void createVoxelPipelines();
890 void ensureGpuDrivenResources(uint32_t instanceCount, uint32_t bucketCount);
891 void recordGpuDrivenCompute(wgpu::CommandEncoder encoder);
892 void flushGpuDrivenDraws(wgpu::RenderPassEncoder pass, bool canvasTarget,
893 bool hdrCanvas = false);
894 void ensureGpuDrivenVisibilityResources();
895 void recordGpuDrivenVisibility(wgpu::CommandEncoder encoder);
896 void flushGpuDrivenResolve(wgpu::RenderPassEncoder pass);
897 void ensureGpuDrivenVgResources();
898 void recordGpuDrivenVgCompute(wgpu::CommandEncoder encoder);
899 void recordGpuDrivenVgVisibility(wgpu::CommandEncoder encoder);
900 void flushGpuDrivenVgResolve(wgpu::RenderPassEncoder pass);
901 void createSceneColorResources(int width, int height);
902 void destroySceneColorResources();
903 void createShadowResources();
904 void destroyShadowResources();
905 void createGbufferResources(int width, int height);
906 void destroyGbufferResources();
907 void createDecalResources(int width, int height);
908 void destroyDecalResources();
909
910 wgpu::RenderPipeline createPipelineForShader(GpuShader* gs, wgpu::TextureFormat format, bool depth, bool mesh3d,
911 bool hair, bool shadow, bool gbuffer, wgpu::PipelineLayout layout);
912 wgpu::BindGroupLayout make2DBindGroupLayout();
913 wgpu::BindGroupLayout makeMesh3DBindGroupLayout();
914 wgpu::BindGroupLayout makeMesh3DClusteredBindGroupLayout();
915 wgpu::BindGroupLayout makeShadowBindGroupLayout();
916 wgpu::BindGroupLayout makeGbufferBindGroupLayout();
917 wgpu::BindGroupLayout makeDecalBindGroupLayout();
918 wgpu::BindGroupLayout makeVoxelBindGroupLayout();
919 wgpu::PipelineLayout make2DPipelineLayout();
920 wgpu::PipelineLayout makeMesh3DPipelineLayout();
921 wgpu::PipelineLayout makeMesh3DClusteredPipelineLayout();
922 wgpu::PipelineLayout makeShadowPipelineLayout();
923 wgpu::PipelineLayout makeGbufferPipelineLayout();
924 wgpu::PipelineLayout makeDecalPipelineLayout();
925 wgpu::PipelineLayout makeVoxelPipelineLayout();
926
927 GpuTexture *gpuForTexture(Texture *t) const;
928 GpuTexture *gpuForTextureOrWhite(Texture *t) const;
929 wgpu::BindGroup makeTex2DBindGroup(GpuTexture *color, GpuTexture *depth,
930 GpuTexture *motion = nullptr, GpuTexture *extra = nullptr,
931 GpuTexture *specular = nullptr);
932 wgpu::BindGroup makeMeshBindGroup(GpuTexture* albedo, GpuTexture* normal, GpuTexture* env, GpuTexture* height,
933 GpuTexture* depth, GpuTexture* sceneColor, uint32_t frameUboOffset,
934 uint32_t shadowUboOffset, uint32_t pushUboOffset, const wgpu::Buffer& skinBuffer);
935 wgpu::BindGroup makeMesh3DClusteredBindGroup(GpuTexture *albedo, GpuTexture *normal,
936 GpuTexture *env, GpuTexture *height,
937 GpuTexture *depth, wgpu::TextureView aoView,
938 uint32_t frameUboOffset, uint32_t shadowUboOffset);
939 void uploadClusteredLighting(const ClusteredLightingUpload &upload);
940 void ensureMeshBindGroupsForDraw(Mesh3dDraw &d);
941 wgpu::Sampler makeSampler(const TextureSampler &sampler, uint32_t mipLevels) const;
942
943 void uploadTexturePixels(GpuTexture *gt, const uint8_t *rgba, int w, int h,
944 const TextureCreateInfo &info);
945 void uploadTexturePixelsMips(GpuTexture *gt, const uint8_t *rgba, int w, int h);
946 void flush2D(wgpu::RenderPassEncoder pass, int viewW, int viewH, WGPUTextureFormat format);
947 void drawTexturedBatch(wgpu::RenderPassEncoder pass, TexturedBatch &tb, int viewW, int viewH,
948 WGPUTextureFormat format, bool offscreen);
949 void drawLitBatch(wgpu::RenderPassEncoder pass, LitBatch &lb, int viewW, int viewH,
950 WGPUTextureFormat format);
951 void flushMesh3D(wgpu::RenderPassEncoder pass, WGPUTextureFormat format,
952 bool canvasTarget = false);
953 bool drawPbrMesh(wgpu::RenderPassEncoder pass, WGPUTextureFormat format,
954 bool canvasTarget, Mesh3dDraw &draw, GpuMesh &mesh);
955 void flushPrimitive3D(wgpu::RenderPassEncoder pass, WGPUTextureFormat format, uint32_t sampleCount);
956 wgpu::RenderPipeline getPrimitive3DPipeline(PrimitiveDepthMode depth, BlendMode blend, PrimitiveCullMode cull,
957 WGPUTextureFormat format, uint32_t sampleCount);
958 void flushShadowPass(wgpu::RenderPassEncoder pass, int cascade);
959 void flushGbufferPass(wgpu::RenderPassEncoder pass);
960 void flushDecalPass(wgpu::RenderPassEncoder pass);
961 void submitPendingDeferredPasses();
962 void createDeferredLightingPipeline();
963 void destroyDeferredLightingResources();
964 void ensureDeferredLightingClusteredUpload();
966 void flushDeferredLighting(wgpu::RenderPassEncoder pass);
972 bool flushGBufferPassInto(wgpu::CommandEncoder& encoder, bool runAo);
973 void flushVoxelDraws(wgpu::RenderPassEncoder pass, WGPUTextureFormat format);
974
975 // UBO arena: one growable uniform buffer per in-flight frame slot.
976 struct UboArena {
977 wgpu::Buffer buffer;
978 uint64_t capacity = 0;
979 uint64_t used = 0;
981 uint32_t alloc(uint64_t size, uint64_t alignment);
982 std::vector<wgpu::Buffer> palettes;
983 size_t paletteIndex = 0;
985 void reset() {
986 used = 0;
987 paletteIndex = 0;
988 }
989 };
990 wgpu::Buffer uploadSkinPalette(Mesh* mesh);
991 UboArena &currentUboArena();
992 void ensureUboArena(UboArena &arena, uint64_t bytes);
993
994 // Vertex arena for batched 2D vertices (one per frame slot).
995 struct VertexArena {
996 wgpu::Buffer buffer;
997 uint64_t capacity = 0;
998 uint64_t used = 0;
1000 uint64_t alloc(uint64_t bytes);
1002 void reset() { used = 0; }
1003 };
1004 VertexArena &currentVertexArena();
1005 void ensureVertexArena(VertexArena &arena, uint64_t bytes);
1006
1007 uint32_t frameSlotCount() const { return kFramesInFlight; }
1008 uint32_t currentFrameSlot() const { return frameIndex % kFramesInFlight; }
1009
1010 // Per-frame instance arena for voxel faces (packed rect words).
1011 VertexArena voxelInstanceArena;
1012 // Parallel per-frame arena for the AO word (2 bits per corner).
1013 VertexArena voxelAoArena;
1014
1015 // ---- state ----
1016 bool initialized = false;
1017 bool deviceInitDone = false;
1018 bool headless_ = false;
1019 void *sdlWindow = nullptr;
1020 int logicalW = 0, logicalH = 0;
1021 int pixelW = 0, pixelH = 0;
1022 float maxSamplerAnisotropy = 1.f;
1023
1024 wgpu::Instance instance;
1025 wgpu::Adapter adapter;
1026 wgpu::Device device;
1027 wgpu::Queue queue;
1028 wgpu::Surface surface;
1029 Capabilities caps;
1030 WGPUTextureFormat surfaceFormat = WGPUTextureFormat_BGRA8Unorm;
1031 std::atomic<bool> surfaceNeedsRecreate{false};
1032 bool swapchainConfigured = false;
1033
1034 // Per-frame command state (single command buffer per frame).
1035 uint32_t frameIndex = 0;
1036 // Slot rendered by the most recent present (the readback source).
1037 uint32_t lastPresentSlot = 0;
1038 bool sceneColorHistoryValid = false;
1039 std::optional<size_t> mesh3dSceneColorCaptureIndex;
1040 static constexpr uint32_t kFramesInFlight = 2;
1041 std::vector<UboArena> uboArenas;
1042 std::vector<VertexArena> vertexArenas;
1043 wgpu::Buffer mesh3dFrameUboPool;
1044 uint32_t mesh3dFrameUboSlots[kFramesInFlight]{};
1045 wgpu::Buffer shadowUboPool;
1046 uint32_t shadowUboSlots[kFramesInFlight]{};
1047 wgpu::Buffer pushUboPool;
1048 uint32_t pushUboSlots[kFramesInFlight]{};
1049
1050 // Default / placeholder resources.
1051 GpuTexture *whiteTexture = nullptr;
1052 GpuTexture *flatNormalTexture = nullptr;
1053 GpuTexture *flatNormalTexture3D = nullptr;
1054 GpuTexture *flatHeightTexture3D = nullptr;
1055 GpuTexture *flatDepthTexture3D = nullptr;
1056 GpuTexture *defaultEnvCubemap = nullptr;
1057 wgpu::BindGroupLayout reflectionProbeFilterSetLayout;
1058 wgpu::PipelineLayout reflectionProbeFilterPipelineLayout;
1059 wgpu::RenderPipeline reflectionProbeFilterPipeline;
1060 GpuTexture *shadowDepthArray = nullptr;
1061 // 1x1x3 depth-array + comparison sampler used for the mesh3d shadow
1062 // bindings (5/8) when no shadow map exists yet — the bind group layout
1063 // requires those bindings on every draw.
1064 GpuTexture *defaultShadowTex = nullptr;
1065
1066 // Pipelines / layouts.
1067 wgpu::PipelineLayout tex2DPipelineLayout;
1068 wgpu::PipelineLayout mesh3dPipelineLayout;
1069 wgpu::RenderPipeline mesh3dCanvasPipeline;
1070 wgpu::BindGroupLayout mesh3dClusteredSetLayout;
1071 wgpu::PipelineLayout mesh3dClusteredPipelineLayout;
1072 wgpu::RenderPipeline mesh3dClusteredPipeline;
1073 // Double-buffered storage ring for the clustered-forward SSBOs (lights /
1074 // cluster table / light indices), one slot per frame in flight.
1075 struct ClusteredStorage {
1076 wgpu::Buffer lights;
1077 wgpu::Buffer table;
1078 wgpu::Buffer indices;
1079 uint64_t lightsCap = 0;
1080 uint64_t tableCap = 0;
1081 uint64_t indicesCap = 0;
1082 } clusteredStorage[kFramesInFlight];
1083 wgpu::PipelineLayout shadowPipelineLayout;
1084 wgpu::PipelineLayout gbufferPipelineLayout;
1085 wgpu::PipelineLayout decalPipelineLayout;
1086 wgpu::PipelineLayout voxelPipelineLayout;
1087 wgpu::BindGroupLayout tex2DSetLayout;
1088 wgpu::BindGroupLayout mesh3dSetLayout;
1089 wgpu::BindGroupLayout shadowSetLayout;
1090 wgpu::BindGroupLayout gbufferSetLayout;
1091 wgpu::BindGroupLayout decalSetLayout;
1092 wgpu::BindGroupLayout voxelSetLayout;
1093 // Phase D: Hybrid clustered deferred lighting (fullscreen into scene color).
1094 wgpu::BindGroupLayout deferredLightingSetLayout;
1095 wgpu::PipelineLayout deferredLightingPipelineLayout;
1096 wgpu::RenderPipeline deferredLightingPipeline;
1097 wgpu::Sampler deferredLightingNearestSampler;
1098 bool deferredLightingPending_ = false;
1099
1100 // SSAO (screen-space ambient occlusion) resources. The AO pass runs after
1101 // the G-buffer fill and writes aoTex[aoWriteIndex]; the forward mesh pass
1102 // samples the other slot (one frame of latency).
1103 wgpu::PipelineLayout aoPipelineLayout;
1104 wgpu::RenderPipeline aoPipeline;
1105 wgpu::BindGroupLayout aoSetLayout;
1106 wgpu::Texture aoTex[2];
1107 wgpu::TextureView aoView[2];
1108 uint32_t aoWriteIndex = 0;
1109 bool aoReady = false;
1110 wgpu::Buffer aoUbo;
1111 void ensureAOResources(int width, int height);
1112 wgpu::BindGroup makeAOBindGroup(wgpu::TextureView depthView);
1113 // Shared filtering sampler for bindings declared as `sampler` in WGSL
1114 // (e.g. mesh3d's @binding(7) mainSamp).
1115 wgpu::Sampler mainSampler;
1116 wgpu::RenderPipeline colorPipeline; // 2D solid
1117 wgpu::RenderPipeline texturedPipeline; // 2D textured
1118 wgpu::RenderPipeline colorAdditivePipeline;
1119 wgpu::RenderPipeline texturedAdditivePipeline;
1120 wgpu::RenderPipeline colorPremultipliedPipeline;
1121 wgpu::RenderPipeline texturedPremultipliedPipeline;
1122 wgpu::RenderPipeline colorMultiplyPipeline;
1123 wgpu::RenderPipeline texturedMultiplyPipeline;
1124 wgpu::RenderPipeline colorOpaquePipeline;
1125 wgpu::RenderPipeline texturedOpaquePipeline;
1126 wgpu::RenderPipeline sceneTonemapPipeline;
1127 float sceneExposure = 1.f;
1128 glm::vec3 sceneColorFilter{1.f};
1129 glm::vec3 sceneLift{0.f};
1130 glm::vec3 sceneInverseGamma{1.f};
1131 glm::vec3 sceneGain{1.f};
1132 float sceneTransitionVignette = 0.0F;
1133 float sceneTransitionVignetteSmoothness = 0.2F;
1134 float sceneTransitionLensDistortion = 0.0F;
1135 float sceneTransitionLensScale = 1.0F;
1136 bool sceneAutoExposure = false;
1137 float sceneAutoExposureMinEV = -8.f;
1138 float sceneAutoExposureMaxEV = 8.f;
1139 float sceneBloomIntensity = 0.f;
1140 float sceneBloomThreshold = 1.f;
1141 float sceneDofFocusDistance = 0.f;
1142 float sceneDofMaxBlurPx = 0.f;
1143 float sceneDofFocusRange = 8.f;
1144 float sceneDofNearZ = 0.1f;
1145 float sceneDofFarZ = 100.f;
1146 wgpu::RenderPipeline mesh3dPipeline;
1147 wgpu::RenderPipeline mesh3dTransparentPipeline;
1148 static constexpr size_t kMeshPipelineVariants = 20;
1149 std::array<wgpu::RenderPipeline, kMeshPipelineVariants> mesh3dPipelines;
1150 std::array<wgpu::RenderPipeline, kMeshPipelineVariants> mesh3dCanvasPipelines;
1151 wgpu::RenderPipeline mesh3dShadowPipeline;
1152 wgpu::RenderPipeline mesh3dShadowSingleSidedPipeline;
1153 wgpu::RenderPipeline mesh3dShadowAlphaPipeline;
1154 wgpu::RenderPipeline mesh3dShadowAlphaSingleSidedPipeline;
1155 wgpu::RenderPipeline mesh3dGbufferPipeline;
1156 wgpu::RenderPipeline mesh3dGbufferAlphaPipeline;
1157 wgpu::RenderPipeline decalPipeline;
1158 wgpu::RenderPipeline voxelRectPipeline;
1159 wgpu::RenderPipeline lit2dPipeline;
1160 wgpu::RenderPipeline lit2dAdditivePipeline;
1161 wgpu::RenderPipeline lit2dPremultipliedPipeline;
1162 wgpu::RenderPipeline lit2dMultiplyPipeline;
1163 wgpu::RenderPipeline lit2dOpaquePipeline;
1164 // RGBA8Unorm (offscreen canvas / scene) variants of the 2D pipelines.
1165 wgpu::RenderPipeline offscreenColorPipeline;
1166 wgpu::RenderPipeline offscreenTexturedPipeline;
1167 wgpu::RenderPipeline offscreenColorAdditivePipeline;
1168 wgpu::RenderPipeline offscreenTexturedAdditivePipeline;
1169 wgpu::RenderPipeline offscreenColorPremultipliedPipeline;
1170 wgpu::RenderPipeline offscreenTexturedPremultipliedPipeline;
1171 wgpu::RenderPipeline offscreenColorMultiplyPipeline;
1172 wgpu::RenderPipeline offscreenTexturedMultiplyPipeline;
1173 wgpu::RenderPipeline offscreenColorOpaquePipeline;
1174 wgpu::RenderPipeline offscreenTexturedOpaquePipeline;
1175 wgpu::RenderPipeline hdrOffscreenTexturedPipeline;
1176 wgpu::RenderPipeline hdrOffscreenTexturedOpaquePipeline;
1177 wgpu::RenderPipeline offscreenLitPipeline;
1178 wgpu::RenderPipeline offscreenLitAdditivePipeline;
1179 wgpu::RenderPipeline offscreenLitPremultipliedPipeline;
1180 wgpu::RenderPipeline offscreenLitMultiplyPipeline;
1181 wgpu::RenderPipeline offscreenLitOpaquePipeline;
1182 wgpu::RenderPipeline hdrOffscreenLitPipeline;
1183 wgpu::RenderPipeline hdrOffscreenLitAdditivePipeline;
1184 wgpu::RenderPipeline hdrOffscreenLitPremultipliedPipeline;
1185 wgpu::RenderPipeline hdrOffscreenLitMultiplyPipeline;
1186 wgpu::RenderPipeline hdrOffscreenLitOpaquePipeline;
1187 // Fullscreen quad used to composite the scene color into the swapchain.
1188 wgpu::Buffer fullscreenQuadVb;
1189 wgpu::Buffer toneMapQuadVb;
1190 wgpu::Buffer fullscreenQuadIb;
1191 bool fullscreenQuadReady = false;
1192
1193 // 2D batch state.
1194 std::vector<SolidBatch> solidBatches;
1195 std::vector<TexturedBatch> texturedBatches;
1196 std::vector<LitBatch> litBatches;
1197 Lighting2DUBO lighting2dFrame{};
1198 enum class OverlayKind : uint8_t { Solid, Textured, Lit };
1199 struct OverlaySpan {
1200 OverlayKind kind = OverlayKind::Solid;
1201 uint32_t index = 0;
1202 uint32_t vertBegin = 0;
1203 uint32_t vertCount = 0;
1204 };
1205 std::vector<OverlaySpan> overlaySpans;
1206 bool sceneColorComposited = false;
1207 void noteSolidOverlay(uint32_t batchIndex);
1208 void noteTexturedOverlay(Texture *tex, uint32_t batchIndex);
1209 void noteLitOverlay(uint32_t batchIndex);
1210 void clear2DBatches();
1211
1212 // 3D frame state.
1213 bool frame3DStarted = false;
1214 bool sceneColorPassOpen = false;
1215 // Non-null between begin3DFrameToCanvas and the frame's present: the 3D
1216 // scene pass renders into this canvas instead of the scene color target.
1217 OffscreenCanvas *active3DCanvas = nullptr;
1218 bool offscreenTimestampSupported = false;
1219 wgpu::QuerySet offscreenTimestampQuerySet;
1220 wgpu::Buffer offscreenTimestampResolveBuffer;
1221 struct OffscreenTimestampReadback {
1222 Graphics *owner = nullptr;
1223 wgpu::Buffer buffer;
1224 bool pending = false;
1225 };
1226 std::array<OffscreenTimestampReadback, 3> offscreenTimestampReadbacks{};
1227 size_t offscreenTimestampReadbackCursor = 0;
1228 mutable std::atomic<float> completedOffscreenTimestampMs{0.f};
1229 // Most recent 3D render target (scene color or canvas), used by the async
1230 // frame readback.
1231 // Owned copy of the last composed surface, captured only when requested.
1232 wgpu::Texture presentedReadback;
1233 int presentedReadbackW = 0, presentedReadbackH = 0;
1234 WGPUTextureFormat presentedReadbackFormat = WGPUTextureFormat_Undefined;
1235 bool surfaceCanCopySrc = false;
1236 void recordPresentedReadback(wgpu::CommandEncoder &encoder, const wgpu::Texture &surfaceTexture);
1237 wgpu::Texture lastReadbackTex;
1238 int lastReadbackW = 0;
1239 int lastReadbackH = 0;
1240 glm::mat4 mesh3dViewProj{1.f};
1241 glm::mat4 mesh3dView{1.f};
1242 float mesh3dNear = 0.1f, mesh3dFar = 100.f;
1243 struct Primitive3DVertex {
1244 glm::vec4 clipPosition{0.f};
1245 glm::vec4 color{1.f};
1246 };
1247 struct Primitive3DDraw {
1248 ScenePrimitivePaint paint;
1249 float averageDepth = 0.f;
1250 std::size_t sequence = 0;
1251 std::vector<Primitive3DVertex> vertices;
1252 };
1253 std::vector<Primitive3DDraw> primitive3DDraws;
1254 std::unordered_map<std::uint64_t, wgpu::RenderPipeline> primitive3DPipelines;
1255 Texture *sceneColorTexture = nullptr;
1256 Texture *mesh3dNormalTexture = nullptr;
1257 Texture *mesh3dHeightTexture = nullptr;
1258 Texture *mesh3dEnvTexture = nullptr;
1259 Texture *mesh3dSceneDepthTexture = nullptr;
1260 Texture *mesh3dSceneColorTexture = nullptr;
1261 float mesh3dEnvIntensity = 0.f;
1262 glm::vec3 mesh3dEnvProbeCenter{0.f};
1263 glm::vec3 mesh3dEnvProbeExtent{0.f};
1264 ReflectionProbeUpload mesh3dReflectionProbes{};
1265 float mesh3dMetallic = 0.f;
1266 float mesh3dRoughness = 0.45f;
1267 SurfaceMode mesh3dSurfaceMode = SurfaceMode::Opaque;
1268 BlendMode mesh3dSurfaceBlend = BlendMode::Alpha;
1269 bool mesh3dSurfaceDepthWrite = false;
1270 bool mesh3dSurfaceDoubleSided = false;
1271 float mesh3dAlphaCutoff = 0.5f;
1272 std::string mesh3dAlphaTechnique = "cutoff";
1273 glm::vec4 mesh3dLodFade{1.f, 0.f, 0.f, 0.f};
1274 float mesh3dTexBombScale = 4.f, mesh3dTexBombStrength = 0.f, mesh3dTexBombRot = 1.f;
1275 float mesh3dParallaxScale = 0.f, mesh3dParallaxMin = 8.f, mesh3dParallaxMax = 32.f;
1276 glm::vec4 mesh3dVirtualTexture{0.f};
1277 glm::vec4 mesh3dVirtualAtlas{0.f};
1278 float mesh3dSsaoIntensity = 1.f;
1279 glm::vec4 mesh3dCloud{0.f, 1.5f, 0.f, 0.f};
1280 glm::vec4 mesh3dCloudWind{4.f, 0.f, 0.55f, 0.5f};
1281 Lighting3DPack mesh3dLighting{};
1282 ShadowUpload mesh3dShadows{};
1283 bool mesh3dShadowReceive = true;
1284 int mesh3dSkinInfluenceLimit = 4;
1285 bool mesh3dClusteredActive = false;
1286 ClusteredLightingUpload mesh3dClustered{};
1287 glm::vec3 mesh3dCameraPos{0.f, 0.f, 3.f};
1288 bool frameHad3DThisFrame = false;
1289 std::vector<Mesh3dDraw> mesh3dDraws;
1290 std::optional<PbrSurface> mesh3dPbrSurface;
1291 struct PbrResources;
1292 static void deletePbrResources(PbrResources *resources);
1293 std::unique_ptr<PbrResources, void (*)(PbrResources *)> pbrResources_{
1294 nullptr, &deletePbrResources};
1295 Color clearColor{0.1f, 0.1f, 0.12f, 1.f};
1296 bool hasPendingClear = true;
1297
1298 // Shadow pass state.
1299 int shadowPassCascade = -1;
1300 std::vector<ShadowDraw> shadowPassDraws;
1301 std::vector<ShadowDraw> shadowCascadeDraws[ShadowConfig::kTotalLayers];
1302
1303 // GBuffer pass state.
1304 bool gbufferPassActive = false;
1305 bool gbufferPassPending = false;
1306 std::vector<GbufferDraw> gbufferPassDraws;
1307
1308 // Voxel state.
1309 std::vector<VoxelDraw> voxelDraws;
1310 wgpu::Buffer voxelUnitQuadVerts;
1311 wgpu::Buffer voxelUnitQuadIndices;
1312 // Scene color (offscreen 3D) target.
1313 struct SceneColorSlot {
1314 wgpu::Texture msaaColor;
1315 wgpu::TextureView msaaView;
1316 wgpu::Texture color;
1317 wgpu::TextureView colorView;
1318 wgpu::Texture depth;
1319 wgpu::TextureView depthView;
1320 GpuTexture colorGpu;
1321 Texture colorTex;
1322 uint32_t sampleCount = 1;
1323 };
1324 int sceneColorWidth = 0, sceneColorHeight = 0;
1325 // Internal 3D lighting target. Script-created Canvas textures remain
1326 // RGBA8Unorm and are composited after the scene resolve.
1327 WGPUTextureFormat sceneColorFormat = WGPUTextureFormat_RGBA8Unorm;
1328 uint32_t sceneColorSamples = 1;
1329 std::vector<SceneColorSlot> sceneColorSlots;
1330
1331 // Shadow map state (CSM, 3 cascade layers).
1332 struct ShadowMapSlot {
1333 wgpu::Texture texture;
1334 wgpu::TextureView view;
1335 };
1336 std::vector<ShadowMapSlot> shadowMaps;
1337 int shadowMapSize = ShadowConfig::kMapSize;
1338
1339 // GBuffer targets (Phase B: 5 color + depth).
1340 struct GbufferSlot {
1341 wgpu::Texture normal;
1342 wgpu::TextureView normalView;
1343 wgpu::Texture depthColor;
1344 wgpu::TextureView depthColorView;
1345 wgpu::Texture albedo;
1346 wgpu::TextureView albedoView;
1347 wgpu::Texture pbrParams;
1348 wgpu::TextureView pbrParamsView;
1349 wgpu::Texture emissive;
1350 wgpu::TextureView emissiveView;
1351 wgpu::Texture depth;
1352 wgpu::TextureView depthView;
1353 wgpu::Texture visID;
1354 wgpu::TextureView visIDView;
1355 wgpu::Texture visBary;
1356 wgpu::TextureView visBaryView;
1357 GpuTexture normalGpu;
1358 GpuTexture depthColorGpu;
1359 GpuTexture albedoGpu;
1360 GpuTexture pbrParamsGpu;
1361 GpuTexture emissiveGpu;
1362 GpuTexture depthGpu;
1363 Texture normalTex;
1364 Texture depthColorTex;
1365 Texture albedoTex;
1366 Texture pbrParamsTex;
1367 Texture emissiveTex;
1368 Texture depthTex;
1369 };
1370 int gbufferWidth = 0, gbufferHeight = 0;
1371 std::vector<GbufferSlot> gbufferSlots;
1372 uint32_t lastGbufferSlot = 0;
1373 bool gbufferDepthValid_ = false;
1374
1375 struct DecalSlot {
1376 wgpu::Texture albedo;
1377 wgpu::TextureView albedoView;
1378 wgpu::Texture normal;
1379 wgpu::TextureView normalView;
1380 wgpu::Texture params;
1381 wgpu::TextureView paramsView;
1382 };
1383 int decalWidth = 0, decalHeight = 0;
1384 std::vector<DecalSlot> decalSlots;
1385 std::vector<DecalDraw> decalPassDraws;
1386 glm::mat4 decalViewProj{1.f};
1387 bool decalPassActive = false;
1388 bool decalPassPending = false;
1389 bool decalReady = false;
1390 uint32_t lastDecalSlot = 0;
1391 Texture *decalFlatAlbedo = nullptr;
1392 Texture *decalFlatNormal = nullptr;
1393 Texture *decalFlatParams = nullptr;
1394
1395 // Canvas state.
1396 Canvas *activeCanvas = nullptr;
1397 std::vector<std::unique_ptr<eve::graphics::Canvas>> ownedCanvases;
1398
1399 // Owned resources.
1400 std::vector<std::unique_ptr<Texture>> ownedTextures;
1401 std::vector<std::unique_ptr<GpuTexture>> ownedGpuTextures;
1402 std::unordered_map<std::string, Texture *> texturesByPath;
1403 std::unordered_map<std::string, Texture *> sharedTexturesByContent;
1404 std::vector<std::unique_ptr<Mesh>> ownedMeshes;
1405 std::vector<std::unique_ptr<GpuMesh>> ownedGpuMeshes;
1406 std::vector<std::unique_ptr<Shader>> ownedShaders;
1407 std::vector<std::unique_ptr<GpuShader>> ownedGpuShaders;
1408
1409 // GPU-driven resource tables. WebGPU groups instances into conventional
1410 // mesh/material buckets (portable replacement for Vulkan descriptor indexing),
1411 // then compute-compacts visible transforms and emits indirect commands.
1412 bool gpuDrivenEnabled_ = false;
1413 std::vector<Mesh *> gpuDrivenMeshes_;
1414 std::vector<Material *> gpuDrivenMaterials_;
1415 std::vector<uint32_t> gpuDrivenMaterialFree_;
1416 std::unordered_map<Mesh *, uint32_t> gpuDrivenMeshIds_;
1417 std::unordered_map<Material *, uint32_t> gpuDrivenMaterialIds_;
1418 std::vector<GpuInstance> gpuDrivenPending_;
1419 // CPU mirror is diagnostic-only; rendering consumes the compute output.
1420 std::vector<GpuInstance> gpuDrivenVisible_;
1421 struct GpuDrivenBucket {
1422 Mesh *mesh = nullptr;
1423 Material *material = nullptr;
1424 uint32_t outputBase = 0;
1425 uint32_t inputCount = 0;
1426 };
1427 std::vector<GpuDrivenBucket> gpuDrivenBuckets_;
1428 wgpu::BindGroupLayout gpuDrivenComputeSetLayout_;
1429 wgpu::BindGroupLayout gpuDrivenRenderSetLayout_;
1430 wgpu::PipelineLayout gpuDrivenComputePipelineLayout_;
1431 wgpu::PipelineLayout gpuDrivenRenderPipelineLayout_;
1432 wgpu::ComputePipeline gpuDrivenCullPipeline_;
1433 wgpu::BindGroupLayout gpuDrivenHzbSetLayout_;
1434 wgpu::PipelineLayout gpuDrivenHzbPipelineLayout_;
1435 wgpu::ComputePipeline gpuDrivenHzbPipeline_;
1436 wgpu::Buffer gpuDrivenHzbBuffer_;
1437 wgpu::Buffer gpuDrivenHzbParamsBuffer_;
1438 wgpu::BindGroup gpuDrivenHzbBindGroup_;
1439 std::vector<uint32_t> gpuDrivenHzbOffsets_;
1440 uint32_t gpuDrivenHzbWidth_ = 0;
1441 uint32_t gpuDrivenHzbHeight_ = 0;
1442 uint64_t gpuDrivenHzbCapacity_ = 0;
1443 wgpu::RenderPipeline gpuDrivenRenderPipeline_;
1444 wgpu::RenderPipeline gpuDrivenCanvasPipeline_;
1445 wgpu::RenderPipeline gpuDrivenHdrCanvasPipeline_;
1446 wgpu::RenderPipeline gpuDrivenResidentRenderPipeline_;
1447 wgpu::RenderPipeline gpuDrivenResidentCanvasPipeline_;
1448 wgpu::RenderPipeline gpuDrivenResidentHdrCanvasPipeline_;
1449 wgpu::Buffer gpuDrivenParamsBuffer_;
1450 wgpu::Buffer gpuDrivenInputBuffer_;
1451 wgpu::Buffer gpuDrivenVisibleBuffer_;
1452 wgpu::Buffer gpuDrivenIndirectBuffer_;
1453 wgpu::Buffer gpuDrivenVisIndirectBuffer_;
1454 wgpu::BindGroup gpuDrivenComputeBindGroup_;
1455 wgpu::BindGroup gpuDrivenRenderBindGroup_;
1456 uint64_t gpuDrivenInputCapacity_ = 0;
1457 uint64_t gpuDrivenVisibleCapacity_ = 0;
1458 uint64_t gpuDrivenIndirectCapacity_ = 0;
1459 uint64_t gpuDrivenVisIndirectCapacity_ = 0;
1460 uint32_t gpuDrivenDispatchCount_ = 0;
1461 uint32_t gpuDrivenLastIndirectDrawCount_ = 0;
1462 uint32_t gpuDrivenLastBucketCount_ = 0;
1463 bool gpuDrivenComputePending_ = false;
1464 bool gpuDrivenDrawPending_ = false;
1465 bool gpuDrivenResidentDrawPending_ = false;
1466 WGPUBuffer gpuDrivenResidentBuffer_ = nullptr;
1467 uint64_t gpuDrivenResidentOffset_ = 0;
1468 uint64_t gpuDrivenResidentSize_ = 0;
1469 bool gpuDrivenVisPending_ = false;
1470 bool gpuDrivenResolvePending_ = false;
1471 wgpu::BindGroupLayout gpuDrivenVisSetLayout_;
1472 wgpu::BindGroupLayout gpuDrivenResolveSetLayout_;
1473 wgpu::PipelineLayout gpuDrivenVisPipelineLayout_;
1474 wgpu::PipelineLayout gpuDrivenResolvePipelineLayout_;
1475 wgpu::RenderPipeline gpuDrivenVisPipeline_;
1476 wgpu::RenderPipeline gpuDrivenResolvePipeline_;
1477
1478 struct GpuDrivenVgAsset {
1479 wgpu::Buffer positions;
1480 wgpu::Buffer triangles;
1481 wgpu::Buffer clusters;
1482 wgpu::Buffer indirect;
1483 wgpu::Buffer params;
1484 uint32_t vertexCount = 0;
1485 uint32_t triangleCount = 0;
1486 uint32_t clusterCount = 0;
1487 Mesh *mesh = nullptr;
1488 glm::mat4 model{1.f};
1489 uint32_t materialId = kInvalidGpuDrivenSlot;
1490 bool active = false;
1491 };
1492 std::vector<GpuDrivenVgAsset> gpuDrivenVgAssets_;
1493 std::unordered_map<Mesh *, uint32_t> gpuDrivenVgMeshIds_;
1494 wgpu::BindGroupLayout gpuDrivenVgComputeSetLayout_;
1495 wgpu::BindGroupLayout gpuDrivenVgVisSetLayout_;
1496 wgpu::BindGroupLayout gpuDrivenVgResolveSetLayout_;
1497 wgpu::PipelineLayout gpuDrivenVgComputePipelineLayout_;
1498 wgpu::PipelineLayout gpuDrivenVgVisPipelineLayout_;
1499 wgpu::PipelineLayout gpuDrivenVgResolvePipelineLayout_;
1500 wgpu::ComputePipeline gpuDrivenVgCullPipeline_;
1501 wgpu::RenderPipeline gpuDrivenVgVisPipeline_;
1502 wgpu::RenderPipeline gpuDrivenVgResolvePipeline_;
1503 glm::mat4 gpuDrivenVgViewProj_{1.f};
1504 glm::vec3 gpuDrivenVgCameraPos_{0.f};
1505 float gpuDrivenVgFovYDeg_ = 60.f;
1506 float gpuDrivenVgNear_ = 0.1f;
1507 float gpuDrivenVgFar_ = 100.f;
1508 glm::vec4 gpuDrivenVgPlanes_[6]{};
1509 uint32_t gpuDrivenVgVisibleDiagnostic_ = 0;
1510 uint32_t gpuDrivenVgLastIndirectDrawCount_ = 0;
1511 bool gpuDrivenVgComputePending_ = false;
1512 bool gpuDrivenVgVisPending_ = false;
1513 bool gpuDrivenVgResolvePending_ = false;
1514
1515 // Browser async frame readback (avoids ASYNCIFY sleep inside deep
1516 // JS->Squirrel->Graphics call chains).
1517 struct PendingReadback {
1518 std::string path;
1519 int width = 0, height = 0;
1520 uint64_t bytesPerRow = 0;
1521 wgpu::Buffer dst;
1522 bool mapped = false, done = false, ok = false;
1523 bool hdr = false, bgra = false;
1524 };
1525 std::unique_ptr<PendingReadback> pendingReadback_;
1526
1527 // Cached mesh3d bind groups keyed by the frame-slot UBO buffer, texture
1528 // views and shadow resources. Dynamic offsets reuse a group within one
1529 // frame slot; the buffer identity prevents a group from retaining another
1530 // in-flight slot's UBO arena.
1531 using MeshBindGroupKey =
1532 std::tuple<uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t,
1533 uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t>;
1534 std::map<MeshBindGroupKey, wgpu::BindGroup> meshBindGroupCache_;
1535 static constexpr size_t kMaxMeshBindGroupCache = 128;
1536 void clearMeshBindGroupCache() { meshBindGroupCache_.clear(); }
1537
1538 void markSwapchainDirty() override { swapchainConfigured = false; }
1539 void rebuildSwapchainIfNeeded();
1540 bool acquireSurfaceTexture(wgpu::TextureView &view, wgpu::Texture &texture);
1541};
1542
1543} // namespace eve::graphics::webgpu
bool & active
float w
Definition AnimClip.cpp:738
float y
Definition AnimClip.cpp:738
float x
Definition AnimClip.cpp:738
std::vector< QuestEvent > pending
std::vector< BuildingInstanceSnapshot > instances
float normalStrength
float cx
Definition CardTypes.cpp:33
float cy
Definition CardTypes.cpp:34
float degrees
Definition CardTypes.cpp:35
graphics::Texture * albedo
#define EVENGINE_API_BACKENDS
Definition Export.h:108
std::string layout
std::uint32_t vertexCount
std::uint32_t indexCount
std::vector< eve::ProcgenProbeDesc > lights
vkb::Device & device
std::uint32_t instanceCount
std::uint32_t capacity
vk::UniqueSampler sampler
glm::vec4 tint
glm::mat4 mvp
std::vector< std::uint32_t > indices
std::vector< float > positions
float blend
int h
std::uint32_t height
std::uint32_t width
TokenKind kind
std::array< float, 3 > scale
std::uint64_t bytes
std::vector< TriangleRef > triangles
MeshVfxBatchedDraw draw
float roughness
float tb
bool doubleSided
Texture * normal
float alphaCutoff
float metallic
std::vector< std::weak_ptr< DeviceBytes > > resources
Definition OnnxGpgpu.cpp:55
std::unique_ptr< gpgpu::GpuBuffer > buffer
Definition OnnxGpgpu.cpp:26
std::unique_ptr< gpgpu::Sequence > sequence
Definition OnnxGpgpu.cpp:43
std::vector< Point > vertices
std::string path
Definition PlayHost.cpp:110
float d
int detail
float t
bool lodFadeReverse
glm::vec3 eye
Mesh * mesh
float lodWeight
glm::mat4 viewProj
Shader * shader
bool hair
Lighting3DPack lighting
SurfaceMode surfaceMode
glm::mat4 view
glm::mat4 model
Material * material
int skinInfluenceLimit
Color clearColor
bool repeatV
bool repeatU
std::uint32_t count
std::string_view adapter
float size
Definition TreeMesh.cpp:156
int caps
Definition TreeMesh.cpp:162
V3 dir
Definition TreeMesh.cpp:150
uint32_t index
const UnitySourceAsset & source
std::uint32_t depth
Move-only operation result carrying either a value or Status.
Definition Result.h:155
Accumulates solid / textured quads in logical (Y-down) coordinates. Used by RenderSystem; not a publi...
Definition Batcher.h:24
Canvas public API.
Definition Canvas.h:17
virtual void draw(Drawable *drawable, const glm::mat4 &m)
Draws .
bool(*)(void *userdata, void *commandBuffer) PresentOverlayFn
Optional overlay drawn inside the swapchain render pass (before end). Used by declarative UI (ImGui)....
Definition Graphics.h:1606
Packages shading method + surface parameters into one attachable asset.
Definition Material.h:35
GPU mesh handle (+ optional CPU morph targets).
Definition Mesh.h:25
Frame-local Skia-style recorder for 2D line primitives.
Frame-local scene recorder for 3D line primitives.
Custom GPU program.
Definition Shader.h:39
GPU texture created via Graphics::newTexture. Owns GPU resources through an opaque backend handle.
Definition Texture.h:18
EVENGINE_API_BACKENDS public API.
Definition Graphics.h:191
wgpu::Queue & getQueue()
Returns the queue.
Definition Graphics.h:756
glm::vec3 getSceneColorFilter() const override
Returns the scene color filter.
Definition Graphics.h:589
uint32_t debugGpuDrivenIndirectDrawCount() const
Return indexed-indirect commands recorded by the last scene pass.
Definition Graphics.h:258
float getSceneExposure() const override
Returns the scene exposure.
Definition Graphics.h:585
glm::vec3 getSceneGain() const override
Returns the scene gain.
Definition Graphics.h:601
void * getSdlWindow() const
Returns the sdl window.
Definition Graphics.h:762
float getSceneDofMaxBlur() const override
Returns the scene dof max blur.
Definition Graphics.h:651
int getMsaaSamples() const override
Returns the msaa samples.
Definition Graphics.h:294
void setSceneDepthOfField(float focusDistance, float maxBlurPx, float focusRange, float nearZ, float farZ) override
Sets the scene depth of field.
Definition Graphics.h:640
eve::graphics::Graphics::PresentOverlayFn PresentOverlayFn
Definition Graphics.h:768
bool getSceneAutoExposure() const override
Returns the scene auto exposure.
Definition Graphics.h:625
WGPUTextureFormat getSurfaceFormat() const
Returns the surface format.
Definition Graphics.h:760
void setSceneBloom(float intensity, float threshold) override
Sets the scene bloom.
Definition Graphics.h:631
bool isReady() const
True when ready.
Definition Graphics.h:764
uint32_t debugGpuDrivenVisibleCount() const
Return the last CPU compatibility-cull result for backend parity tests.
Definition Graphics.h:254
bool gpuDrivenCullEnabled() const override
Gpu driven cull enabled.
Definition Graphics.h:227
std::string getBackendName() const override
Returns the backend name.
Definition Graphics.h:203
float getSceneTransitionVignette() const override
Returns the scene transition vignette.
Definition Graphics.h:611
uint32_t debugGpuDrivenHzbMipCount() const
Return the active hierarchical-depth mip count for conformance tests.
Definition Graphics.h:262
void setSceneAutoExposure(bool enabled, float minEV, float maxEV) override
Sets the scene auto exposure.
Definition Graphics.h:619
float getSceneDofFarZ() const override
Returns the scene dof far z.
Definition Graphics.h:657
bool supportsDeferredLighting() const override
Supports deferred lighting.
Definition Graphics.h:207
uint32_t debugGpuDrivenDispatchCount() const
Return instances dispatched by the last WebGPU compute cull.
Definition Graphics.h:256
uint32_t debugGpuDrivenVgDispatchCount() const
Return VG clusters dispatched by the last WebGPU compute section.
Definition Graphics.h:264
float getSceneTransitionLensDistortion() const override
Returns the scene transition lens distortion.
Definition Graphics.h:615
bool supportsDecal() const override
Supports decal.
Definition Graphics.h:693
wgpu::Instance & getInstance()
Returns the instance.
Definition Graphics.h:752
void setSceneLiftGammaGain(const glm::vec3 &lift, const glm::vec3 &inverseGamma, const glm::vec3 &gain) override
Sets the scene lift gamma gain.
Definition Graphics.h:591
void setSceneTransitionFx(float vignette, float vignetteSmoothness, float lensDistortion, float lensScale) override
Sets the scene transition fx.
Definition Graphics.h:603
bool supportsGBufferPost() const override
Supports g buffer post.
Definition Graphics.h:205
void setSceneColorFilter(const glm::vec3 &color) override
Sets the scene color filter.
Definition Graphics.h:587
glm::vec3 getSceneInverseGamma() const override
Returns the scene inverse gamma.
Definition Graphics.h:599
float getSceneAutoExposureMaxEV() const override
Returns the scene auto exposure max ev.
Definition Graphics.h:629
float getSceneDofFocusDistance() const override
Returns the scene dof focus distance.
Definition Graphics.h:649
wgpu::Surface & getSurface()
Returns the surface.
Definition Graphics.h:758
float getLastOffscreen3DGpuDurationMs() const override
Returns the last offscreen 3 d gpu duration ms.
Definition Graphics.h:505
float getSceneTransitionVignetteSmoothness() const override
Returns the scene transition vignette smoothness.
Definition Graphics.h:613
float getSceneBloomIntensity() const override
Returns the scene bloom intensity.
Definition Graphics.h:636
glm::vec3 getSceneLift() const override
Returns the scene lift.
Definition Graphics.h:597
void gpuDrivenSetEnabled(bool enabled) override
Gpu driven set enabled.
Definition Graphics.h:215
bool gpuDrivenEnabled() const override
Gpu driven enabled.
Definition Graphics.h:213
float getSceneBloomThreshold() const override
Returns the scene bloom threshold.
Definition Graphics.h:638
float getSceneDofNearZ() const override
Returns the scene dof near z.
Definition Graphics.h:655
float getSceneTransitionLensScale() const override
Returns the scene transition lens scale.
Definition Graphics.h:617
void setSceneExposure(float exposure) override
Sets the scene exposure.
Definition Graphics.h:583
wgpu::Device & getDevice()
Returns the device.
Definition Graphics.h:754
float getSceneAutoExposureMinEV() const override
Returns the scene auto exposure min ev.
Definition Graphics.h:627
float getSceneDofFocusRange() const override
Returns the scene dof focus range.
Definition Graphics.h:653
bool supportsGpuDriven3D() const override
Supports gpu driven 3 d.
Definition Graphics.h:211
void requestSurfaceRecreate() override
Request surface recreate.
Definition Graphics.h:290
uint32_t debugGpuDrivenVgIndirectDrawCount() const
Return per-cluster indirect commands recorded by the VG visibility pass.
Definition Graphics.h:266
Offscreen render target (RGBA8Unorm color, optional Depth32Float). 2D batches are flushed into the ca...
Definition Canvas.h:16
Represents raw pixel data.
Definition ImageData.h:38
std::vector< ParamSpec > params
SurfaceMode
How a 3D surface contributes to depth and color passes.
Definition SurfaceMode.h:6
eve::Color Color
RGBA color used by every graphics draw call. Lives inside eve::graphics so including a graphics heade...
Definition Color.h:13
constexpr uint32_t kInvalidGpuDrivenSlot
GPU-driven rendering shared constants + std430 GPU layouts.
SkinInfluenceLimit
Number of strongest vertex influences retained by GPU skinning.
Definition IGraphics3D.h:19
GpuResidentSubmitStatus
Structured result for direct resident-instance submission.
std::unordered_map< std::string, SkillDefinition > & table()
Definition Skill.cpp:65
BlendMode
Render-neutral 2D blend mode shared by graphics-facing modules.
Definition RenderTypes.h:11
glm::vec4 Color
Render-neutral RGBA color shared by graphics-facing modules.
Definition RenderTypes.h:8
bool enabled
CPU-built clustered lighting upload for one frame/camera. Point lights are clustered; directional lig...
Per-instance GPU record (std430). Mirrors GLSL GpuInstance.
Direct-render description for a GPU-authored array of GpuInstance records. @ownership buckets and buf...
Neutral GPU upload for one virtual-geometry asset. Raw arrays so the graphics module does not depend ...
GPU light packing for mesh3d / PBR (std140-friendly).
Definition Light.h:161
Lighting2DUBO public API.
Definition Light.h:53
Lighting3DPack public API.
Definition Light.h:172
static constexpr int kMaxLights
Definition Light.h:173
static constexpr int kMaxDiffuseVolumeProbes
Definition Light.h:179
Owning material parameter snapshot; texture pointers remain borrowed. Base color/metallic/roughness c...
Definition PbrSurface.h:218
ReflectionProbeUpload public API.
Definition IGraphics3D.h:26
ShadowUpload public API.
Definition Shadow.h:54
Options for Graphics::newTexture / newCubemap. When generateMipmaps is true and sampler....
Sampler state for a Texture (filter, wrap, mip LOD, anisotropy). Defaults match historical engine beh...
Vertex/index buffers for one mesh.
Definition Graphics.h:153
wgpu::IndexFormat indexFormat
Definition Graphics.h:161
std::vector< MeshVertex > cpuVertices
Definition Graphics.h:162
A compiled shader: one WebGPU pipeline + layout. Also holds the WGSL sources so custom shaders can be...
Definition Graphics.h:169
wgpu::RenderPipeline mesh3dPipeline
Definition Graphics.h:176
wgpu::RenderPipeline offscreenOpaquePipeline
Definition Graphics.h:173
wgpu::RenderPipeline swapchainOpaquePipeline
Definition Graphics.h:172
wgpu::RenderPipeline swapchainPipeline
Definition Graphics.h:170
wgpu::BindGroupLayout setLayout
Definition Graphics.h:181
wgpu::PipelineLayout pipelineLayout
Definition Graphics.h:180
wgpu::RenderPipeline mesh3dXrayPipeline
Definition Graphics.h:177
wgpu::RenderPipeline offscreenPipeline
Definition Graphics.h:171
wgpu::RenderPipeline gbufferPipeline
Definition Graphics.h:179
wgpu::RenderPipeline shadowPipeline
Definition Graphics.h:178
wgpu::RenderPipeline hdrOffscreenOpaquePipeline
Definition Graphics.h:175
wgpu::RenderPipeline hdrOffscreenPipeline
Definition Graphics.h:174
Texture resources backed by a wgpu texture + view + sampler + bind groups.
Definition Graphics.h:131
Clustered-forward mesh UBO (matches the Vulkan Mesh3DClusteredUBO and the WGSL clustered Frame block)...
Definition Graphics.h:105
glm::vec4 reflectionProbeCenter[ReflectionProbeUpload::kMaxProbes]
Definition Graphics.h:123
glm::vec4 reflectionProbeExtent[ReflectionProbeUpload::kMaxProbes]
Definition Graphics.h:124
Frame UBO for the mesh3d pipeline. Mirrors the std140 layout of the WGSL Frame block and the legacy V...
Definition Graphics.h:48
glm::vec4 diffuseVolumeExtent[Lighting3DPack::kMaxDiffuseVolumeProbes]
Definition Graphics.h:74
Light3DGpu lights[Lighting3DPack::kMaxLights]
Definition Graphics.h:56
glm::vec4 reflectionProbeCenter[ReflectionProbeUpload::kMaxProbes]
Definition Graphics.h:69
glm::vec4 diffuseVolumeSh[Lighting3DPack::kMaxDiffuseVolumeProbes *9]
Definition Graphics.h:75
glm::vec4 reflectionProbeExtent[ReflectionProbeUpload::kMaxProbes]
Definition Graphics.h:70
glm::vec4 diffuseVolumePosition[Lighting3DPack::kMaxDiffuseVolumeProbes]
Definition Graphics.h:73
MeshVertex public API.
Definition Graphics.h:82
Reproducibly generated full PBR WGSL sources before resource specialization.
SkinPassUBO public API.
Definition Graphics.h:93
glm::vec4 cameraPos
uint32_t outputBase
glm::uvec4 info
glm::vec4 color