载入中...
搜索中...
未找到
Graphics.h
浏览该文件的文档.
1#pragma once
2#include "graphics/Graphics.h"
3#include "graphics/Batcher.h"
4#include "graphics/Texture.h"
5#include "graphics/Mesh.h"
6#include "graphics/Shader.h"
7#include "graphics/Light.h"
9#include "graphics/Shadow.h"
10
11#include <webgpu/webgpu_cpp.h>
12
13#include <atomic>
14#include <memory>
15#include <unordered_map>
16#include <vector>
17#include <cstdint>
18
19#include <glm/glm.hpp>
20
21namespace eve::graphics::webgpu {
22
23class OffscreenCanvas;
24
30struct Mesh3DUBO {
31 glm::mat4 mvp{1.f};
32 glm::mat4 model{1.f};
33 glm::vec4 lightDir{0.4f, 1.f, 0.3f, 0.f}; // xyz = primary dir; w = lightCount
34 glm::vec4 lightColor{1.f, 1.f, 1.f, 0.f}; // rgb = primary color; w = envIntensity
35 glm::vec4 tint{1.f, 1.f, 1.f, 1.f};
36 glm::vec4 cameraPos{0.f, 0.f, 3.f, 0.45f}; // xyz = eye; w = roughness
37 glm::vec4 ambient{0.12f, 0.12f, 0.14f, 0.f}; // rgb = ambient; w = metallic
39 glm::vec4 texBomb{4.f, 0.f, 1.f, 0.f}; // x=cellScale, y=strength, z=rotAmount
40 glm::vec4 parallax{0.f, 8.f, 32.f, 0.f}; // x=scale, y=minLayers, z=maxLayers
41 glm::mat4 view{1.f};
42 glm::vec4 clipInfo{0.1f, 100.f, 0.f, 0.f}; // x=near, y=far
43 glm::vec4 cloud{0.f, 1.5f, 0.f, 0.f}; // x=strength(0=off), y=worldCell, z=time
44 glm::vec4 cloudWind{4.f, 0.f, 0.55f, 0.5f}; // xy=wind vel, z=coverage, w=detail
45};
46static_assert(sizeof(Mesh3DUBO) == 608, "Mesh3DUBO layout must match the WGSL Frame block");
47
51struct GpuTexture {
52 wgpu::Texture texture;
53 wgpu::TextureView view;
54 wgpu::Sampler sampler;
55 // Bind group for the unified 2D layout (color at 0, depth at 1).
56 wgpu::BindGroup tex2DGroup;
57 // Bind group for the mesh3d layout (albedo at 1, normal at 2, env at 3,
58 // height at 6). Rebuilt when the mesh3d pipeline re-creates its layout.
59 wgpu::BindGroup meshGroup;
60 bool isCube = false;
61 int width = 0;
62 int height = 0;
63 uint32_t mipLevels = 1;
65};
66
70struct GpuMesh {
71 wgpu::Buffer vertexBuffer;
72 wgpu::Buffer indexBuffer;
73 uint32_t indexCount = 0;
74 uint32_t vertexCount = 0;
75 uint32_t vertexStride = 0;
76 wgpu::IndexFormat indexFormat = wgpu::IndexFormat::Uint32;
77};
78
83struct GpuShader {
84 wgpu::RenderPipeline swapchainPipeline; // 2D/offscreen color format
85 wgpu::RenderPipeline offscreenPipeline; // RGBA8Unorm canvas format
86 wgpu::RenderPipeline mesh3dPipeline; // scene color format
87 wgpu::RenderPipeline mesh3dXrayPipeline; // depth test/write off + alpha blend
88 wgpu::RenderPipeline shadowPipeline; // depth-only
89 wgpu::RenderPipeline gbufferPipeline; // MRT gbuffer
90 wgpu::PipelineLayout pipelineLayout;
91 wgpu::BindGroupLayout setLayout;
92 bool isMesh3D = false;
93 bool isHair3D = false;
94 bool isShadow = false;
95 bool isGbuffer = false;
96 std::string wgslVert;
97 std::string wgslFrag;
98};
99
100class Graphics final : public eve::graphics::Graphics {
101public:
102 Graphics();
103 ~Graphics() override;
104
105 std::string getBackendName() const override { return "webgpu"; }
106 bool supportsGBufferPost() const override { return false; }
107
108 void initWithWindow(void *nativeWindow) override;
109 void present() override;
110 void pushValidationScope() override;
111 void popValidationScope() override;
112 void requestSurfaceRecreate() override { surfaceNeedsRecreate = true; }
113 void setVSync(bool enabled) override;
114 int getMsaaSamples() const override { return msaaSamples; }
115 void setViewportSize(int width, int height, int pixelwidth, int pixelheight) override;
116 void drawSolidRect(float x, float y, float w, float h, const Color &color,
117 BlendMode blend = BlendMode::Alpha) override;
118 void drawSolidRectRotated(float cx, float cy, float w, float h, float degrees,
119 const Color &color,
120 BlendMode blend = BlendMode::Alpha) override;
121
122 Texture *newTexture(int width, int height, const uint8_t *rgba, bool repeatU = false,
123 bool repeatV = false) override;
124 Texture *newTexture(int width, int height, const uint8_t *rgba,
125 const TextureCreateInfo &info) override;
126 Texture *newCubemap(int faceSize, const uint8_t *rgbaFaces) override;
127 Texture *newCubemap(int faceSize, const uint8_t *rgbaFaces,
128 const TextureCreateInfo &info) override;
129 Texture *newTexture(image::ImageData *data) override;
130 Texture *newTexture(image::ImageData *data, const TextureCreateInfo &info) override;
131 void setTextureSampler(Texture *texture, const TextureSampler &sampler) override;
132 float getMaxAnisotropy() const override;
133 Texture *newTextureFromFile(const std::string &filename) override;
134 bool reloadTextureFromFile(const std::string &filename) override;
135 bool releaseTexture(Texture *texture) override;
136
137 void drawTexturedRect(Texture *texture, float x, float y, float w, float h,
138 const Color &color) override;
139 void drawTexturedRectShader(Texture *texture, Shader *shader, float x, float y, float w, float h,
140 const Color &color) override;
141 void drawTexturedRectUV(Texture *texture, float x, float y, float w, float h, float u0, float v0,
142 float u1, float v1, const Color &color) override;
143 void drawTexturedRectShaderUV(Texture *texture, Shader *shader, float x, float y, float w,
144 float h, float u0, float v0, float u1, float v1,
145 const Color &color, bool rotatedUV = false,
146 BlendMode blend = BlendMode::Alpha) override;
147 void drawTexturedRectShaderUVRotated(Texture *texture, Shader *shader, float cx, float cy,
148 float w, float h, float degrees, float u0, float v0,
149 float u1, float v1, const Color &color,
150 bool rotatedUV = false,
151 BlendMode blend = BlendMode::Alpha) override;
153 float w, float h, const Color &tint) override;
154 void drawTexturedRectLitUV(Texture *albedo, Texture *normal, float x, float y, float w, float h,
155 float u0, float v0, float u1, float v1, const Color &color) override;
156 void setLighting2D(const Lighting2DUBO &ubo) override;
157
158 Shader *newShaderFromSpv(const std::vector<uint32_t> &vertSpv,
159 const std::vector<uint32_t> &fragSpv) override;
160 Shader *newShaderFromSpvFile(const std::string &vertPath, const std::string &fragPath) override;
161 Shader *newShader(const std::string &vertGlsl, const std::string &fragGlsl) override;
162 Shader *newMeshShaderFromSpv(const std::vector<uint32_t> &vertSpv,
163 const std::vector<uint32_t> &fragSpv) override;
164 Shader *newMeshShaderFromWgsl(const std::string &vertWgsl,
165 const std::string &fragWgsl) override;
166 Shader *newMeshShader(const std::string &vertGlsl, const std::string &fragGlsl) override;
167 Shader *newHairShaderFromSpv(const std::vector<uint32_t> &vertSpv,
168 const std::vector<uint32_t> &fragSpv) override;
169 bool releaseShader(Shader *shader) override;
170
171 Mesh *newMeshFromAssimp(const ::aiMesh &mesh) override;
172 Mesh *newMeshFromAssimp(const ::aiMesh &mesh, const aiMatrix4x4 &worldTransform) override;
173 Mesh *newMeshFromArrays(const float *posXYZ, const float *nrmXYZ, const float *uvST,
174 int vertexCount, const uint32_t *indices, int indexCount) override;
175 bool bakeMeshMorph(Mesh *mesh) override;
176 bool updateMeshVertices(Mesh *mesh, const float *posXYZ, const float *nrmXYZ, const float *uvST,
177 int vertexCount, const uint32_t *indices, int indexCount) override;
178 Mesh *newMeshSphere(int slices = 32, int stacks = 16) override;
179 Mesh *newMeshCylinder(int slices = 32, int stacks = 1, bool caps = true) override;
180 bool releaseMesh(Mesh *mesh) override;
181
182 void begin3DFrame() override;
183 void begin3DFrameToCanvas(Canvas *canvas) override;
184 void end3DFrameToCanvas() override;
185 void setMesh3DViewProj(const glm::mat4 &viewProj) override;
186 void setMesh3DView(const glm::mat4 &view) override;
187 void setMesh3DClip(float nearZ, float farZ) override;
188 Texture *getSceneColorTexture() override;
189 void drawMesh(Mesh *mesh, const glm::mat4 &model, Texture *texture, const Color &tint) override;
190 void drawMeshShader(Mesh *mesh, const glm::mat4 &model, Texture *texture, const Color &tint,
191 Shader *shader) override;
192 void drawVoxelFaceInstances(const uint32_t *packed, int count, float originX, float originY,
193 float originZ, const std::string &faceDir, Texture *atlas,
194 int tilesPerRow = 16, const uint32_t *ao = nullptr) override;
195 void setMesh3DNormalTexture(Texture *normal) override;
196 void setMesh3DHeightTexture(Texture *height) override;
197 void setMesh3DSceneDepth(Texture *depth) override;
198 void setMesh3DMaterial(float metallic, float roughness) override;
199 void setMesh3DTexCellBomb(float cellScale, float strength, float rotAmount = 1.f) override;
200 void setMesh3DParallax(float scale, float minLayers = 8.f, float maxLayers = 32.f) override;
201 void setMesh3DLighting(const Lighting3DPack &pack) override;
202 void setCloudShadows(float strength, float worldCell, float time, float windSpeed, float windAngle, float coverage,
203 float detail) override;
204 void setMesh3DClusteredLighting(const ClusteredLightingUpload &upload) override;
205 void setMesh3DClusteredActive(bool active) override;
206 void setMesh3DLight(const glm::vec3 &dir, const glm::vec3 &color) override;
207 void setMesh3DCameraPos(const glm::vec3 &eye) override;
208 void setMesh3DEnv(Texture *cube, float intensity) override;
209 void setMesh3DShadows(const ShadowUpload &upload) override;
210 void setMesh3DShadowReceive(bool receive) override;
211 void beginShadowPass(int cascadeIndex) override;
212 void drawMeshShadow(Mesh *mesh, const glm::mat4 &lightMVP) override;
213 void drawMeshShadowAlpha(Mesh *mesh, const glm::mat4 &lightMVP, Texture *albedo = nullptr) override;
214 void endShadowPass() override;
215
216 void beginGBufferPass(int width, int height) override;
217 void drawMeshGBuffer(Mesh *mesh, const glm::mat4 &mvp, const glm::mat4 &model, float nearZ,
218 float farZ, Texture *albedo = nullptr, float tintR = 1.f, float tintG = 1.f,
219 float tintB = 1.f) override;
220 void drawMeshGBufferAlpha(Mesh *mesh, const glm::mat4 &mvp, const glm::mat4 &model,
221 float nearZ, float farZ, Texture *albedo = nullptr, float tintR = 1.f,
222 float tintG = 1.f, float tintB = 1.f) override;
223 void endGBufferPass() override;
224
225 Canvas *newCanvas(int width, int height) override;
226 void setCanvas(Canvas *canvas) override;
227 bool isCanvasActive() const override;
228 Canvas *getCanvas() const override;
229
230 Texture *getTexture() override;
231 image::ImageData *newImageData() override;
232 void draw(eve::graphics::Graphics *gfx, const glm::mat4 &matrix) const override;
233 void draw(Canvas *C, const glm::mat4 &matrix) const override;
234 void clear(std::optional<Color> color, std::optional<int> stencil,
235 std::optional<double> depth) override;
236 Color getPixel(int x, int y) override;
237
239 void flush2DToCanvas(OffscreenCanvas *canvas);
241 Color getPixelImpl(OffscreenCanvas *canvas, int x, int y);
243
244 wgpu::Instance &getInstance() { return instance; }
245 wgpu::Device &getDevice() { return device; }
246 wgpu::Queue &getQueue() { return queue; }
247 wgpu::Surface &getSurface() { return surface; }
248 WGPUTextureFormat getSurfaceFormat() const { return surfaceFormat; }
249 void *getSdlWindow() const { return sdlWindow; }
250 bool isReady() const { return initialized; }
251
252 // The present overlay is rendered inside the swapchain render pass. The
253 // void* payload is a WGPURenderPassEncoder* on the WebGPU backend.
255
256 friend class OffscreenCanvas;
257
269 struct LitBatch {
270 Texture *albedo = nullptr;
271 Texture *normal = nullptr;
273 };
274
275private:
276 struct Mesh3dDraw {
277 Mesh *mesh = nullptr;
278 Texture *texture = nullptr;
279 glm::mat4 model{1.f};
280 Color tint{1.f};
281 Shader *shader = nullptr;
282 uint32_t frameUboOffset = 0;
283 uint32_t pushUboOffset = 0;
284 uint32_t shadowUboOffset = 0;
285 };
286 struct ShadowDraw {
287 Mesh *mesh = nullptr;
288 glm::mat4 mvp{1.f};
289 };
290 struct GbufferDraw {
291 Mesh *mesh = nullptr;
292 Texture *albedo = nullptr;
293 glm::mat4 mvp{1.f};
294 glm::mat4 model{1.f};
295 float nearZ = 0.1f;
296 float farZ = 100.f;
297 glm::vec4 tint{1.f};
298 uint32_t pushUboOffset = 0;
299 };
300 struct VoxelDraw {
301 uint32_t instanceBufferOffset = 0;
302 uint32_t count = 0;
303 GpuTexture *atlas = nullptr;
304 glm::mat4 viewProj{1.f};
305 glm::vec4 chunkOrigin{0.f};
306 glm::vec4 atlasInfo{16.f, 0.f, 0.f, 0.f};
307 glm::vec4 tint{1.f};
308 uint32_t pushUboOffset = 0;
309 };
310
311 void createInstanceAndAdapter();
312 void requestDevice();
313 void configureSurface(int width, int height);
314 void waitForAdapter();
315 void waitForDevice();
316 void createDefaultTextures();
317 void createPipelineResources();
318 void create2DPipelines();
319 void createMesh3DPipelines();
320 void createShadowPipelines();
321 void createGbufferPipelines();
322 void createVoxelPipelines();
323 void createSceneColorResources(int width, int height);
324 void destroySceneColorResources();
325 void createShadowResources();
326 void destroyShadowResources();
327 void createGbufferResources(int width, int height);
328 void destroyGbufferResources();
329
330 wgpu::RenderPipeline createPipelineForShader(GpuShader *gs, wgpu::TextureFormat format,
331 bool depth, bool mesh3d, bool hair,
332 bool shadow, bool gbuffer,
333 wgpu::PipelineLayout layout);
334 wgpu::BindGroupLayout make2DBindGroupLayout();
335 wgpu::BindGroupLayout makeMesh3DBindGroupLayout();
336 wgpu::BindGroupLayout makeShadowBindGroupLayout();
337 wgpu::BindGroupLayout makeGbufferBindGroupLayout();
338 wgpu::BindGroupLayout makeVoxelBindGroupLayout();
339 wgpu::PipelineLayout make2DPipelineLayout();
340 wgpu::PipelineLayout makeMesh3DPipelineLayout();
341 wgpu::PipelineLayout makeShadowPipelineLayout();
342 wgpu::PipelineLayout makeGbufferPipelineLayout();
343 wgpu::PipelineLayout makeVoxelPipelineLayout();
344
345 GpuTexture *gpuForTexture(Texture *t) const;
346 GpuTexture *gpuForTextureOrWhite(Texture *t) const;
347 wgpu::BindGroup makeTex2DBindGroup(GpuTexture *color, GpuTexture *depth);
348 wgpu::BindGroup makeMeshBindGroup(GpuTexture *albedo, GpuTexture *normal, GpuTexture *env,
349 GpuTexture *height, GpuTexture *depth,
350 uint32_t frameUboOffset, uint32_t shadowUboOffset,
351 uint32_t pushUboOffset);
352 void ensureMeshBindGroupsForDraw(Mesh3dDraw &d);
353 wgpu::Sampler makeSampler(const TextureSampler &sampler, uint32_t mipLevels) const;
354
355 void uploadTexturePixels(GpuTexture *gt, const uint8_t *rgba, int w, int h,
356 const TextureCreateInfo &info);
357 void uploadTexturePixelsMips(GpuTexture *gt, const uint8_t *rgba, int w, int h);
358 void flush2D(wgpu::RenderPassEncoder pass, int viewW, int viewH, WGPUTextureFormat format);
359 void drawTexturedBatch(wgpu::RenderPassEncoder pass, TexturedBatch &tb, int viewW, int viewH,
360 WGPUTextureFormat format, bool offscreen);
361 void drawLitBatch(wgpu::RenderPassEncoder pass, LitBatch &lb, int viewW, int viewH,
362 WGPUTextureFormat format);
363 void flushMesh3D(wgpu::RenderPassEncoder pass, WGPUTextureFormat format);
364 void flushShadowPass(wgpu::RenderPassEncoder pass);
365 void flushGbufferPass(wgpu::RenderPassEncoder pass);
366 void flushVoxelDraws(wgpu::RenderPassEncoder pass, WGPUTextureFormat format);
367
368 // UBO arena: one growable uniform buffer per in-flight frame slot.
369 struct UboArena {
370 wgpu::Buffer buffer;
371 uint64_t capacity = 0;
372 uint64_t used = 0;
373 uint32_t alloc(uint64_t size, uint64_t alignment);
374 void reset() { used = 0; }
375 };
376 UboArena &currentUboArena();
377 void ensureUboArena(UboArena &arena, uint64_t bytes);
378
379 // Vertex arena for batched 2D vertices (one per frame slot).
380 struct VertexArena {
381 wgpu::Buffer buffer;
382 uint64_t capacity = 0;
383 uint64_t used = 0;
384 uint64_t alloc(uint64_t bytes);
385 void reset() { used = 0; }
386 };
387 VertexArena &currentVertexArena();
388 void ensureVertexArena(VertexArena &arena, uint64_t bytes);
389
390 uint32_t frameSlotCount() const { return kFramesInFlight; }
391 uint32_t currentFrameSlot() const { return frameIndex % kFramesInFlight; }
392
393 // ---- state ----
394 bool initialized = false;
395 bool deviceInitDone = false;
396 void *sdlWindow = nullptr;
397 int logicalW = 0, logicalH = 0;
398 int pixelW = 0, pixelH = 0;
399 float maxSamplerAnisotropy = 1.f;
400
401 wgpu::Instance instance;
402 wgpu::Adapter adapter;
403 wgpu::Device device;
404 wgpu::Queue queue;
405 wgpu::Surface surface;
406 WGPUTextureFormat surfaceFormat = WGPUTextureFormat_BGRA8Unorm;
407 std::atomic<bool> surfaceNeedsRecreate{false};
408 bool swapchainConfigured = false;
409 std::atomic<bool> adapterReceived{false};
410 std::atomic<bool> deviceReceived{false};
411 std::string adapterError;
412 std::string deviceError;
413
414 // Per-frame command state (single command buffer per frame).
415 uint32_t frameIndex = 0;
416 static constexpr uint32_t kFramesInFlight = 2;
417 std::vector<UboArena> uboArenas;
418 std::vector<VertexArena> vertexArenas;
419 wgpu::Buffer mesh3dFrameUboPool;
420 uint32_t mesh3dFrameUboSlots[kFramesInFlight]{};
421 wgpu::Buffer shadowUboPool;
422 uint32_t shadowUboSlots[kFramesInFlight]{};
423 wgpu::Buffer pushUboPool;
424 uint32_t pushUboSlots[kFramesInFlight]{};
425
426 // Default / placeholder resources.
427 GpuTexture *whiteTexture = nullptr;
428 GpuTexture *flatNormalTexture = nullptr;
429 GpuTexture *flatNormalTexture3D = nullptr;
430 GpuTexture *flatHeightTexture3D = nullptr;
431 GpuTexture *flatDepthTexture3D = nullptr;
432 GpuTexture *defaultEnvCubemap = nullptr;
433 GpuTexture *shadowDepthArray = nullptr;
434
435 // Pipelines / layouts.
436 wgpu::PipelineLayout tex2DPipelineLayout;
437 wgpu::PipelineLayout mesh3dPipelineLayout;
438 wgpu::PipelineLayout shadowPipelineLayout;
439 wgpu::PipelineLayout gbufferPipelineLayout;
440 wgpu::PipelineLayout voxelPipelineLayout;
441 wgpu::BindGroupLayout tex2DSetLayout;
442 wgpu::BindGroupLayout mesh3dSetLayout;
443 wgpu::BindGroupLayout shadowSetLayout;
444 wgpu::BindGroupLayout gbufferSetLayout;
445 wgpu::BindGroupLayout voxelSetLayout;
446 // Shared filtering sampler for bindings declared as `sampler` in WGSL
447 // (e.g. mesh3d's @binding(7) mainSamp).
448 wgpu::Sampler mainSampler;
449 wgpu::RenderPipeline colorPipeline; // 2D solid
450 wgpu::RenderPipeline texturedPipeline; // 2D textured
451 wgpu::RenderPipeline colorAdditivePipeline;
452 wgpu::RenderPipeline texturedAdditivePipeline;
453 wgpu::RenderPipeline colorOpaquePipeline;
454 wgpu::RenderPipeline texturedOpaquePipeline;
455 wgpu::RenderPipeline mesh3dPipeline;
456 wgpu::RenderPipeline mesh3dShadowPipeline;
457 wgpu::RenderPipeline mesh3dGbufferPipeline;
458 wgpu::RenderPipeline voxelRectPipeline;
459 wgpu::RenderPipeline lit2dPipeline;
460 // RGBA8Unorm (offscreen canvas / scene) variants of the 2D pipelines.
461 wgpu::RenderPipeline offscreenColorPipeline;
462 wgpu::RenderPipeline offscreenTexturedPipeline;
463 wgpu::RenderPipeline offscreenColorAdditivePipeline;
464 wgpu::RenderPipeline offscreenTexturedAdditivePipeline;
465 wgpu::RenderPipeline offscreenColorOpaquePipeline;
466 wgpu::RenderPipeline offscreenTexturedOpaquePipeline;
467 wgpu::RenderPipeline offscreenLitPipeline;
468 // Fullscreen quad used to composite the scene color into the swapchain.
469 wgpu::Buffer fullscreenQuadVb;
470 wgpu::Buffer fullscreenQuadIb;
471 bool fullscreenQuadReady = false;
472
473 // 2D batch state.
474 std::vector<SolidBatch> solidBatches;
475 std::vector<TexturedBatch> texturedBatches;
476 std::vector<LitBatch> litBatches;
477 Lighting2DUBO lighting2dFrame{};
478 enum class OverlayKind : uint8_t { Solid, Textured, Lit };
479 struct OverlaySpan {
480 OverlayKind kind = OverlayKind::Solid;
481 uint32_t index = 0;
482 uint32_t vertBegin = 0;
483 uint32_t vertCount = 0;
484 };
485 std::vector<OverlaySpan> overlaySpans;
486 bool sceneColorComposited = false;
487 void noteSolidOverlay();
488 void noteTexturedOverlay(Texture *tex);
489 void clear2DBatches();
490
491 // 3D frame state.
492 bool frame3DStarted = false;
493 bool sceneColorPassOpen = false;
494 glm::mat4 mesh3dViewProj{1.f};
495 glm::mat4 mesh3dView{1.f};
496 float mesh3dNear = 0.1f, mesh3dFar = 100.f;
497 Texture *sceneColorTexture = nullptr;
498 Texture *mesh3dNormalTexture = nullptr;
499 Texture *mesh3dHeightTexture = nullptr;
500 Texture *mesh3dEnvTexture = nullptr;
501 Texture *mesh3dSceneDepthTexture = nullptr;
502 float mesh3dEnvIntensity = 0.f;
503 float mesh3dMetallic = 0.f;
504 float mesh3dRoughness = 0.45f;
505 float mesh3dTexBombScale = 4.f, mesh3dTexBombStrength = 0.f, mesh3dTexBombRot = 1.f;
506 float mesh3dParallaxScale = 0.f, mesh3dParallaxMin = 8.f, mesh3dParallaxMax = 32.f;
507 glm::vec4 mesh3dCloud{0.f, 1.5f, 0.f, 0.f};
508 glm::vec4 mesh3dCloudWind{4.f, 0.f, 0.55f, 0.5f};
509 Lighting3DPack mesh3dLighting{};
510 ShadowUpload mesh3dShadows{};
511 bool mesh3dShadowReceive = true;
512 bool mesh3dClusteredActive = false;
513 ClusteredLightingUpload mesh3dClustered{};
514 glm::vec3 mesh3dCameraPos{0.f, 0.f, 3.f};
515 bool frameHad3DThisFrame = false;
516 std::vector<Mesh3dDraw> mesh3dDraws;
517 Color clearColor{0.1f, 0.1f, 0.12f, 1.f};
518 bool hasPendingClear = true;
519
520 // Shadow pass state.
521 int shadowPassCascade = -1;
522 std::vector<ShadowDraw> shadowPassDraws;
523 std::vector<ShadowDraw> shadowCascadeDraws[ShadowConfig::kCascades];
524
525 // GBuffer pass state.
526 bool gbufferPassActive = false;
527 bool gbufferPassPending = false;
528 std::vector<GbufferDraw> gbufferPassDraws;
529
530 // Voxel state.
531 std::vector<VoxelDraw> voxelDraws;
532 wgpu::Buffer voxelUnitQuadVerts;
533 wgpu::Buffer voxelUnitQuadIndices;
534 VertexArena voxelInstanceArena;
535
536 // Scene color (offscreen 3D) target.
537 struct SceneColorSlot {
538 wgpu::Texture msaaColor;
539 wgpu::TextureView msaaView;
540 wgpu::Texture color;
541 wgpu::TextureView colorView;
542 wgpu::Texture depth;
543 wgpu::TextureView depthView;
544 GpuTexture colorGpu;
545 Texture colorTex;
546 uint32_t sampleCount = 1;
547 };
548 int sceneColorWidth = 0, sceneColorHeight = 0;
549 WGPUTextureFormat sceneColorFormat = WGPUTextureFormat_RGBA8Unorm;
550 uint32_t sceneColorSamples = 1;
551 std::vector<SceneColorSlot> sceneColorSlots;
552
553 // Shadow map state (CSM, 3 cascade layers).
554 struct ShadowMapSlot {
555 wgpu::Texture texture;
556 wgpu::TextureView view;
557 };
558 std::vector<ShadowMapSlot> shadowMaps;
559 int shadowMapSize = ShadowConfig::kMapSize;
560
561 // GBuffer targets.
562 struct GbufferSlot {
563 wgpu::Texture normal;
564 wgpu::TextureView normalView;
565 wgpu::Texture depthColor;
566 wgpu::TextureView depthColorView;
567 wgpu::Texture albedo;
568 wgpu::TextureView albedoView;
569 wgpu::Texture depth;
570 wgpu::TextureView depthView;
571 GpuTexture normalGpu;
572 GpuTexture depthColorGpu;
573 GpuTexture albedoGpu;
574 GpuTexture depthGpu;
575 Texture normalTex;
576 Texture depthColorTex;
577 Texture albedoTex;
578 Texture depthTex;
579 };
580 int gbufferWidth = 0, gbufferHeight = 0;
581 std::vector<GbufferSlot> gbufferSlots;
582
583 // Canvas state.
584 Canvas *activeCanvas = nullptr;
585 std::vector<std::unique_ptr<eve::graphics::Canvas>> ownedCanvases;
586
587 // Owned resources.
588 std::vector<std::unique_ptr<Texture>> ownedTextures;
589 std::vector<std::unique_ptr<GpuTexture>> ownedGpuTextures;
590 std::unordered_map<std::string, Texture *> texturesByPath;
591 std::vector<std::unique_ptr<Mesh>> ownedMeshes;
592 std::vector<std::unique_ptr<GpuMesh>> ownedGpuMeshes;
593 std::vector<std::unique_ptr<Shader>> ownedShaders;
594 std::vector<std::unique_ptr<GpuShader>> ownedGpuShaders;
595
596 void markSwapchainDirty() override { swapchainConfigured = false; }
597 void rebuildSwapchainIfNeeded();
598 bool acquireSurfaceTexture(wgpu::TextureView &view, wgpu::Texture &texture);
599};
600
601} // namespace eve::graphics::webgpu
bool active
Definition CardTypes.cpp:34
float cx
Definition CardTypes.cpp:31
float cy
Definition CardTypes.cpp:32
float degrees
Definition CardTypes.cpp:33
Tok kind
std::string layout
int y
Definition Grass.cpp:135
int x
Definition Grass.cpp:135
int h
int w
float depth
float roughness
float tb
Texture * normal
Texture * albedo
float metallic
glm::vec3 eye
Mesh * mesh
glm::mat4 viewProj
Shader * shader
glm::mat4 view
glm::mat4 model
bool repeatV
bool repeatU
bool enabled
int d
image::ImageData::Colorf color
float scale
Definition TreeMesh.cpp:122
V3 dir
Definition TreeMesh.cpp:121
Accumulates solid / textured quads in logical (Y-down) coordinates. Used by RenderSystem; not a publi...
Definition Batcher.h:22
void(*)(void *userdata, void *commandBuffer) PresentOverlayFn
Optional overlay drawn inside the swapchain render pass (before end). Used by declarative UI (ImGui)....
Definition Graphics.h:672
GPU mesh handle (+ optional CPU morph targets).
Definition Mesh.h:18
Custom GPU program.
Definition Shader.h:30
GPU texture created via Graphics::newTexture. Owns GPU resources through an opaque backend handle.
Definition Texture.h:17
void drawMeshShadowAlpha(Mesh *mesh, const glm::mat4 &lightMVP, Texture *albedo=nullptr) override
Shadow pass draw with alpha-cutout discard (card/billboard geometry such as sprite-stack slices): tra...
void pushValidationScope() override
Backend hooks so the platform-independent render3D() can wrap its work in a GPU validation error scop...
Texture * newCubemap(int faceSize, const uint8_t *rgbaFaces) override
Create an RGBA8 cubemap from 6 faces packed as +X,-X,+Y,-Y,+Z,-Z (each faceSize×faceSize,...
void setMesh3DEnv(Texture *cube, float intensity) override
Specular IBL environment for subsequent default mesh draws. cube must be from newCubemap (or nullptr ...
void setMesh3DLight(const glm::vec3 &dir, const glm::vec3 &color) override
Directional light for subsequent drawMesh calls (world-space direction toward surface).
void drawMeshShadow(Mesh *mesh, const glm::mat4 &lightMVP) override
Shader * newMeshShader(const std::string &vertGlsl, const std::string &fragGlsl) override
void flush2DToCanvas(OffscreenCanvas *canvas)
Flush accumulated 2D batches into an offscreen canvas target.
void setMesh3DViewProj(const glm::mat4 &viewProj) override
void draw(eve::graphics::Graphics *gfx, const glm::mat4 &matrix) const override
Draws the object with the specified transformation matrix.
void setMesh3DShadowReceive(bool receive) override
Per-draw: when false, shadow sampling is forced off for the next mesh draw.
Shader * newShaderFromSpvFile(const std::string &vertPath, const std::string &fragPath) override
Load SPIR-V from files via Filesystem (empty vertPath → default textured vert).
float getMaxAnisotropy() const override
Device max supported anisotropy (1 if unsupported). Valid after initWithWindow.
Mesh * newMeshSphere(int slices=32, int stacks=16) override
Procedural UV sphere (radius 1, Y-up). Owned by Graphics. slices = longitude divisions,...
Color getPixelImpl(OffscreenCanvas *canvas, int x, int y)
Blocking CPU readback of an offscreen canvas or scene color target.
void clear(std::optional< Color > color, std::optional< int > stencil, std::optional< double > depth) override
void drawMeshGBufferAlpha(Mesh *mesh, const glm::mat4 &mvp, const glm::mat4 &model, float nearZ, float farZ, Texture *albedo=nullptr, float tintR=1.f, float tintG=1.f, float tintB=1.f) override
GBuffer fill with alpha-cutout discard (card/billboard geometry such as sprite-stack slices): same ou...
void setMesh3DNormalTexture(Texture *normal) override
Optional normal map for the next drawMesh / drawMeshShader (nullptr = flat).
void setMesh3DHeightTexture(Texture *height) override
Optional height map for parallax (R channel; nullptr = flat / off).
void begin3DFrame() override
Begin a 3D frame: shadow/gbuffer (if pending) then a sampleable scene color pass (color+depth)....
Mesh * newMeshFromAssimp(const ::aiMesh &mesh) override
int getMsaaSamples() const override
Definition Graphics.h:114
void setMesh3DCameraPos(const glm::vec3 &eye) override
Camera eye used by mesh shaders that need view/rim (stored in Mesh3DUBO).
eve::graphics::Graphics::PresentOverlayFn PresentOverlayFn
Definition Graphics.h:254
void beginGBufferPass(int width, int height) override
Depth/normal(/albedo) fill pass for mid/post effects. One-shot submit (like shadow); call before begi...
WGPUTextureFormat getSurfaceFormat() const
Definition Graphics.h:248
Shader * newMeshShaderFromWgsl(const std::string &vertWgsl, const std::string &fragWgsl) override
Create a Mesh3D custom shader from WGSL source (WebGPU backend). The WGSL must declare the engine's F...
bool bakeMeshMorph(Mesh *mesh) override
If mesh morph weights are dirty, bake blended positions and upload to the GPU VBO....
Texture * newTextureFromFile(const std::string &filename) override
std::string getBackendName() const override
Renderer backend id used by sibling modules (e.g. Gpgpu).
Definition Graphics.h:105
void setViewportSize(int width, int height, int pixelwidth, int pixelheight) override
Sets the current graphics display viewport dimensions.
Definition Graphics.cpp:258
void setMesh3DLighting(const Lighting3DPack &pack) override
Per-frame ambient + up to 8 lights packed into Mesh3DUBO.
image::ImageData * newImageData() override
void drawMeshShader(Mesh *mesh, const glm::mat4 &model, Texture *texture, const Color &tint, Shader *shader) override
Draw mesh with an explicit Mesh3D Shader (nullptr = default PBR pipeline).
void setMesh3DMaterial(float metallic, float roughness) override
Metallic (0..1) and roughness (0..1) for the next default mesh draw.
void drawSolidRectRotated(float cx, float cy, float w, float h, float degrees, const Color &color, BlendMode blend=BlendMode::Alpha) override
Rotated solid quad degrees clockwise (screen Y-down) around (cx, cy).
void setLighting2D(const Lighting2DUBO &ubo) override
Upload per-frame / per-canvas 2D lighting constants for subsequent lit draws.
void setMesh3DShadows(const ShadowUpload &upload) override
Upload CSM constants for subsequent default mesh draws (active=false disables).
Shader * newMeshShaderFromSpv(const std::vector< uint32_t > &vertSpv, const std::vector< uint32_t > &fragSpv) override
Create a Mesh3D custom shader (MeshVertex + Frame UBO + albedo). Empty vert → default mesh3d....
Texture * newTexture(int width, int height, const uint8_t *rgba, bool repeatU=false, bool repeatV=false) override
bool updateMeshVertices(Mesh *mesh, const float *posXYZ, const float *nrmXYZ, const float *uvST, int vertexCount, const uint32_t *indices, int indexCount) override
In-place update of a mesh's vertex/index data (CPU -> host-visible VBO). Mirrors bakeMeshMorph: the u...
void drawMesh(Mesh *mesh, const glm::mat4 &model, Texture *texture, const Color &tint) override
Draw one mesh with model matrix. Requires begin3DFrame() (or an open swapchain pass).
Shader * newHairShaderFromSpv(const std::vector< uint32_t > &vertSpv, const std::vector< uint32_t > &fragSpv) override
Hair/fur card shader (alpha blend + Kajiya-Kay). Empty vert → mesh3d_hair.vert. Owned by Graphics.
Shader * newShaderFromSpv(const std::vector< uint32_t > &vertSpv, const std::vector< uint32_t > &fragSpv) override
Create a custom 2D shader from SPIR-V words (vert + frag). Owned by Graphics. Vertex stage may be emp...
void setMesh3DView(const glm::mat4 &view) override
Camera view matrix for subsequent drawMesh (view-space depth / CSM select).
void drawTexturedRect(Texture *texture, float x, float y, float w, float h, const Color &color) override
void begin3DFrameToCanvas(Canvas *canvas) override
Open a 3D render pass targeting an offscreen Canvas (color + depth) at the canvas size....
void drawTexturedRectUV(Texture *texture, float x, float y, float w, float h, float u0, float v0, float u1, float v1, const Color &color) override
Draw a textured sub-rect (atlas / tile UVs). texture may be null → solid.
bool releaseShader(Shader *shader) override
Eagerly releases a shader created by this Graphics.
void drawMeshGBuffer(Mesh *mesh, const glm::mat4 &mvp, const glm::mat4 &model, float nearZ, float farZ, Texture *albedo=nullptr, float tintR=1.f, float tintG=1.f, float tintB=1.f) override
void setMesh3DClusteredLighting(const ClusteredLightingUpload &upload) override
Enable clustered forward path for subsequent default mesh draws (SSBO light lists)....
void setMesh3DTexCellBomb(float cellScale, float strength, float rotAmount=1.f) override
Texture cell bombing for the next default mesh draw (breaks tiling). cellScale: cells per UV unit (ty...
void initWithWindow(void *nativeWindow) override
Bind to an existing native window (SDL_Window*) and create Vulkan device/swapchain....
Definition Graphics.cpp:90
wgpu::Instance & getInstance()
Definition Graphics.h:244
Mesh * newMeshCylinder(int slices=32, int stacks=1, bool caps=true) override
Procedural Y-up cylinder (radius 1, height 2 centered at origin). slices = longitude divisions; stack...
bool supportsGBufferPost() const override
Whether gbuffer-based post-process shaders (AO, GI) can be created on this backend....
Definition Graphics.h:106
image::ImageData * newImageDataImpl(OffscreenCanvas *canvas)
void drawTexturedRectShaderUVRotated(Texture *texture, Shader *shader, float cx, float cy, float w, float h, float degrees, float u0, float v0, float u1, float v1, const Color &color, bool rotatedUV=false, BlendMode blend=BlendMode::Alpha) override
UV draw rotated degrees clockwise (screen Y-down) around the rect center. texture may be null → solid...
void setMesh3DParallax(float scale, float minLayers=8.f, float maxLayers=32.f) override
Parallax occlusion mapping for the next default mesh draw. scale: UV displacement strength (0=off)....
wgpu::Surface & getSurface()
Definition Graphics.h:247
void drawTexturedRectLitUV(Texture *albedo, Texture *normal, float x, float y, float w, float h, float u0, float v0, float u1, float v1, const Color &color) override
Lit 2D draw (albedo + normal map). Uses Lighting2DUBO from setLighting2D. normal may be null → treate...
Mesh * newMeshFromArrays(const float *posXYZ, const float *nrmXYZ, const float *uvST, int vertexCount, const uint32_t *indices, int indexCount) override
Upload a triangle mesh from packed CPU arrays. Owned by Graphics. posXYZ required (vertexCount*3)....
Shader * newShader(const std::string &vertGlsl, const std::string &fragGlsl) override
Compile GLSL source with glslc (must be on PATH). Empty vertGlsl → default textured vert....
void setMesh3DClusteredActive(bool active) override
Cheap per-draw toggle for the already-uploaded clustered light table. Unlike setMesh3DClusteredLighti...
bool reloadTextureFromFile(const std::string &filename) override
Reload a path-cached texture from disk in place (pointer stable). False if unbound.
void setCloudShadows(float strength, float worldCell, float time, float windSpeed, float windAngle, float coverage, float detail) override
Dynamic cloud shadows cast on the ground by the default PBR mesh path. strength 0 disables (no change...
void setTextureSampler(Texture *texture, const TextureSampler &sampler) override
Recreate the sampler for an existing texture (keeps image / mip chain). No-op when texture is null or...
bool releaseMesh(Mesh *mesh) override
Eagerly releases a mesh created by this Graphics.
void setMesh3DClip(float nearZ, float farZ) override
Near/far used to pack linear depth into scene color A (SSGI).
void setMesh3DSceneDepth(Texture *depth) override
Optional scene hardware depth (G-buffer hwDepth, Vulkan NDC z) bound to mesh3d shader binding 7....
bool releaseTexture(Texture *texture) override
Eagerly releases a texture created by this Graphics.
Color getPixel(int x, int y) override
void drawTexturedRectShaderUV(Texture *texture, Shader *shader, float x, float y, float w, float h, float u0, float v0, float u1, float v1, const Color &color, bool rotatedUV=false, BlendMode blend=BlendMode::Alpha) override
UV draw with an explicit Shader (nullptr = default textured pipeline).
Texture * getTexture() override
Sampleable color buffer; screen Canvas returns nullptr.
void drawSolidRect(float x, float y, float w, float h, const Color &color, BlendMode blend=BlendMode::Alpha) override
Internal immediate-mode helper used by RenderSystem / Batcher.
void drawVoxelFaceInstances(const uint32_t *packed, int count, float originX, float originY, float originZ, const std::string &faceDir, Texture *atlas, int tilesPerRow=16, const uint32_t *ao=nullptr) override
Instanced voxel face rectangles (32-bit packed instances). ao: optional per-instance ambient-occlusio...
Canvas * newCanvas(int width, int height) override
Create an offscreen render target (sampleable). Owned by Graphics.
void drawTexturedRectShader(Texture *texture, Shader *shader, float x, float y, float w, float h, const Color &color) override
Draw with an explicit Shader (nullptr = default textured pipeline).
void drawTexturedRectShaderDepth(Texture *color, Texture *depth, Shader *shader, float x, float y, float w, float h, const Color &tint) override
Fullscreen/post draw sampling color at binding 0 and depth at binding 1 (hardware D32,...
Canvas * getCanvas() const override
void setVSync(bool enabled) override
Prefer uncapped present (IMMEDIATE/MAILBOX) when false, vsync (MAILBOX/FIFO) when true....
Definition Graphics.cpp:252
bool isCanvasActive() const override
void beginShadowPass(int cascadeIndex) override
Depth-only shadow pass for one cascade layer (0..2). Draws are recorded into the next begin3DFrame co...
void requestSurfaceRecreate() override
Request recreation of the platform render surface on the next frame (Android background/foreground de...
Definition Graphics.h:112
Texture * getSceneColorTexture() override
Sampleable 3D color target for the current frame (RGB = lit, A = linear depth). Valid after begin3DFr...
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:26
glm::vec4 Color
RGBA color used by every graphics draw call. Lives inside eve::graphics so including a graphics heade...
Definition Color.h:13
BlendMode
2D quad blend mode (drawn in draw order within a layer).
Definition BlendMode.h:6
CPU-built clustered lighting upload for one frame/camera. Point lights are clustered; directional lig...
GPU light packing for mesh3d / PBR (std140-friendly).
Definition Light.h:85
static constexpr int kMaxLights
Definition Light.h:91
static constexpr int kMapSize
Definition Shadow.h:9
static constexpr int kCascades
Definition Shadow.h:8
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:70
wgpu::IndexFormat indexFormat
Definition Graphics.h:76
A compiled shader: one WebGPU pipeline + layout. Also holds the WGSL sources so custom shaders can be...
Definition Graphics.h:83
wgpu::RenderPipeline mesh3dPipeline
Definition Graphics.h:86
wgpu::RenderPipeline swapchainPipeline
Definition Graphics.h:84
wgpu::BindGroupLayout setLayout
Definition Graphics.h:91
wgpu::PipelineLayout pipelineLayout
Definition Graphics.h:90
wgpu::RenderPipeline mesh3dXrayPipeline
Definition Graphics.h:87
wgpu::RenderPipeline offscreenPipeline
Definition Graphics.h:85
wgpu::RenderPipeline gbufferPipeline
Definition Graphics.h:89
wgpu::RenderPipeline shadowPipeline
Definition Graphics.h:88
Texture resources backed by a wgpu texture + view + sampler + bind groups.
Definition Graphics.h:51
Frame UBO for the mesh3d pipeline. Mirrors the std140 layout of the WGSL Frame block and the legacy V...
Definition Graphics.h:30
Light3DGpu lights[Lighting3DPack::kMaxLights]
Definition Graphics.h:38