Files
EVEngine/docs/usr/modules/graphics.md
T
Cursor Agentand西风逍遥游 580e23e10d Fix MapFog look: soft dual clouds, organic unlock edges
Rewrite the cloud generator for large seamless billows, retune the
shader toward a translucent dual-scroll sheet (not wallpaper noise or
swiss-cheese density), and stamp a soft hi-res mask in the example so
unlock holes read as cloudy edges instead of hard grid rectangles.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-09-11 16:05:42 +00:00

24 KiB
Raw Blame History

图形渲染模块

脚本入口: eve.Graphics()

清屏、2D 图元、纹理、Canvas、摄像机和 3D 渲染。Camera2D/Camera3D 提供屏幕与世界坐标换算,供 2D/3D 拾取使用;形状命中测试见 Math,物理体查询见 Physics。

基本用法

gfx.setBackgroundColor(0.08, 0.1, 0.16, 1.0);
gfx.clear();
gfx.drawSolidRect(40, 40, 160, 80, 0.2, 0.7, 1.0, 1.0);

对象关系与调用时机

Graphics 管理设备、swapchain、camera、light 和提交;Texture/Shader/Mesh/Renderable 是资源或场景对象。CPU 资源创建在 init,帧内只更新参数并 draw。

目标导向指南

绘制 2D 游戏帧

在 eve_render() 开始调用 clear(),随后按背景、地图、角色、粒子、UI 的顺序提交。纯色占位使用 drawSolidRect();已有 Texture 使用 drawTexturedRect()。需要围绕矩形中心旋转的精灵可调用 drawTexturedRectRotated(texture, centerX, centerY, width, height, degrees, r, g, b, a);屏幕坐标 Y 轴向下,因此正角度表现为顺时针旋转。正常主循环由引擎负责 present。

drawText(font, text, x, y, r, g, b, a, scale) 在当前屏幕或 Canvas 坐标的任意 位置绘制 UTF-8 文本,(x, y) 是该行左上角。font 必须是 newFont() 返回的字体; 绘制调用不读取或修改当前字体状态。原有的 print(text, x, y, r, g, b, a, scale) 继续保留,并使用 setFont() 选择的当前字体。

需要 UV 动画、旋转、独立混合模式或程序化变换时,使用脚本精灵对象:

local sprite = gfx.newSprite2D();
sprite.setTexture(sheet.getTexture());
sprite.setQuad(quad);
sprite.setPosition(400, 270);
sprite.setScale(2.0, 2.0);
sprite.setRotation(30.0); // degree, rotate around rect center
sprite.setAnchor(0.25, 0.75); // normalized rotation pivot
sprite.setFlip(true, false);  // mirror UV without negative scale
sprite.setBlend("alpha"); // alpha | premultiplied | additive | multiply

// eve_render: clear/draw background first, then submit all live Sprite2D objects
gfx.renderSprites();

Sprite2D 还提供 size、color、layer、visible、receiveLight、castOcclusion 等属性。 裁边动画通常由 SpriteAnim.bindSprite(sprite) 自动调用 setFrameLayout,无需游戏代码逐帧修正偏移。 不再使用时调用 destroy();renderSprites() 是聚合提交接口,不要再把同一精灵加入另一条 2D 队列,以免重复绘制。

渲染带光照的 3D 对象

初始化时创建 mesh、shader 和 renderable,设置 camera、ambient 和 directional light;每帧只更新 transform/material 参数,最后调用 render3D()。阴影开关、bias 和 strength 应逐场景调节。

Camera3D 默认使用透视投影。等距视图可调用 setOrthographic(height),其中 height 是世界空间中的垂直可视范围;setPerspective() 恢复透视投影。 setClipPlanes(near, far) 配置两种投影共用的近、远裁剪面,并要求 0 < near < far。getEyeX/Y/Z 与 getTargetX/Y/Z 读取世界空间眼点和注视点; getFov() 返回垂直视野(度),与 setFov() 对应。

跨帧绘制 3D 基础图形

调试可视化、编辑器辅助线和玩法范围提示应使用持久 Primitive3D,不需要保留帧内 Canvas。Graphics 是图形场景的唯一所有者;脚本对象只保存带 owner、index 和 generation 的句柄。对象被移除、Graphics 销毁或槽位复用后,旧代理会通过 isStale() 明确失效。

local created = gfx.newPrimitiveLine3D(
    0.0, 0.0, 0.0, 4.0, 1.0, -2.0, 1.0, 0.7, 0.1, 1.0, 3.0);
if (created.ok) {
    debugLine <- created.value;
    debugLine.setDash(12.0, 8.0, 0.0, "screen"); // screen | world
    debugLine.setDepthMode("test");         // test-write | test | ignore
}

local sphereResult = gfx.newPrimitiveSphere3D(0.0, 1.0, -4.0, 1.5, 0.2, 0.8, 1.0, 1.0, 2.0);
local boxResult = gfx.newPrimitiveAabb3D(-1.0, 0.0, -1.0, 1.0, 2.0, 1.0, 1.0, 1.0, 0.0, 1.0, 2.0);

newPrimitiveLine3D(...)、newPrimitiveSphere3D(...) 和 newPrimitiveAabb3D(...) 返回统一 Result 表;成功后的 value 是 owned Primitive3D。 代理提供 setVisible(bool)、setColor(r,g,b,a)、setLineWidth(width)、 setDash(draw,gap,phase,space)、clearDash()、setDepthMode(mode)、remove() 和 setObjectId(id)、isStale();ownership() 固定返回 "owned"。所有修改和移除操作都返回 Result,必须检查 ok 或显式忽略;代理析构会 移除仍存活的图形。

持久图形还提供以下创建入口,参数末尾均为 r,g,b,a,width(浮点数),返回相同 Result/owned proxy:

方法 几何参数(在颜色和线宽之前)
newPrimitiveDisk3D x,y,z,nx,ny,nz,radius
newPrimitiveCylinder3D ax,ay,az,bx,by,bz,radius
newPrimitiveCapsule3D ax,ay,az,bx,by,bz,radius
newPrimitiveCone3D x,y,z,dx,dy,dz,height,radius
newPrimitiveArrow3D ax,ay,az,bx,by,bz,headLength,headRadius
newPrimitivePolyline3D xyz,closed;xyz 为至少两个点的扁平浮点数组,闭合至少三个点
newPrimitiveObb3D xyz;中心和三个 halfAxis 共 12 个浮点数
newPrimitiveFrustum3D xyz;8 个角点,共 24 个浮点数,顺序与 C++ Frustum 一致
newPrimitiveGrid3D xyz,cellsU,cellsV;原点、axisU、axisV 共 9 个浮点数,格数为 1–4096 的整数
newPrimitiveArc3D xyz,radius,start,sweep;中心、法线、起始方向共 9 个浮点数,角度为弧度

这些图形默认描边;setPaintMode("fill"|"stroke"|"fill-stroke") 切换填充方式。 代理支持 setWidthSpace("screen"|"world")、setLineCap("butt"|"square"|"round")、 setLineJoin("miter"|"bevel"|"round")、setCullMode("none"|"back"|"front")、 setBlendMode("alpha"|"opaque"|"additive"|"premultiplied"|"multiply")。 setTransform(elements) 接受 16 个浮点数的列主序矩阵,整体替换局部到世界变换。 setLayer(layer) 设置非负 uint32 排序层。 gfx.setPrimitiveTransforms3D(proxies,matrices) 批量替换同一 Graphics 所属图形的变换。 proxies 为 Primitive3D 数组;matrices 是每对象 16 个浮点数的扁平列主序矩阵数组。 成功返回 Result 表与 count;任一代理失效、类型错误、owner 不匹配或矩阵非法时整批不修改。 同一代理重复出现时最后一个矩阵生效;空批次成功且 count 为 0。最多接受 65536 个对象。 setPolyline(xyz,closed) 将代理几何替换为新的 owning 折线,保留画笔、变换、可见性和句柄。 所有设置返回 Result;非法模式、矩阵长度或失效代理不会修改原图形。 上述操作在 VM 所在线程同步执行,不保留调用方数组,不调用外部回调。

实时编辑与替换 Shader

开发工具可保留已有 Shader 对象及其材质引用,仅替换内部后端资源:

local result = gfx.replaceShaderFromGlsl(shader, vertexSource, fragmentSource);
// Vulkan SPIR-V:gfx.replaceShaderFromSpv(shader, vertexWords, fragmentWords)
// words 数组须为 uint32 范围整数;先用 spirv-val 验证字节码。返回 Result,失败保留旧管线。
// WebGPU 后端使用:gfx.replaceShaderFromWgsl(shader, vertexSource, fragmentSource)
if (!result.ok) {
    print(result.diagnostics);
}

这些接口都返回统一的结构化 Result,调用方必须检查 ok 或显式忽略结果。编译或 管线创建失败时,原 Shader facade、已声明 uniform 以及上一份可用管线保持不变, 因此编辑器可继续显示最后一次成功的效果。空的 vertex source 表示沿用引擎默认顶点 阶段;调用必须发生在 Graphics 所属的渲染线程。GLSL 是 Vulkan 开发路径,WGSL 是 WebGPU 开发路径;当前后端不支持对应源码格式时会返回 Unsupported 和诊断信息。

纹理过滤(mipmap / 各向异性 / LOD)

默认 newTexture 仍为线性过滤、单级 mip(兼容旧行为)。需要三线性与各向异性时:

// generateMipmaps=true, maxAnisotropy=16, filter/mipmap="linear", lodBias=0
tex <- gfx.newTextureWithSampler(img, false, false, true, 16.0, "linear", "linear", 0.0);
print(tex.getMipmapCount());
gfx.setTextureSampler(tex, "nearest", "none", 1.0, 0.0); // 像素风
print(gfx.getMaxAnisotropy());

C++ 侧使用 TextureCreateInfo::withMipmaps() / TextureSampler::anisotropic(),并通过同名 setTextureSampler 重载热更新采样状态(字符串版参数与脚本一致)。filter 只接受 nearest/linear,mipmap 只接受 none/nearest/linear,传错会抛异常而不是静默回退。Cubemap(IBL)默认生成完整 mip 链,供 textureLod 按粗糙度采样。

几何 LOD:Renderable3D.setMeshLod(index, mesh, switchDistance),RenderSystem3D 按相机距离选择网格。

需要把运行对象交给 Editor/MCP 等跨帧工具时,同时读取 Renderable3D.getEntityId() 与 getEntityGeneration();两者共同构成临时 ECS handle, generation 用于拒绝实体销毁后被复用的旧 id。不要只长期保存 entity id。 Agent 完成材质事务后,可用 getTintR()、getTintG()、getTintB() 与 getRoughness() 独立核对字段材质的运行时状态。

材质(Material)与模型部件

把着色方法(pbr / unlit / hair / custom)、贴图和 PBR 参数打成一个 Material,挂到整模或某个部件:

local mat = gfx.newMaterial();
mat.setShadingModel("pbr");
mat.setAlbedoTexture(albedo);
mat.setNormalTexture(nrm);
mat.setSurfaceMode("transparent"); // opaque | masked | transparent
mat.setBlendMode("alpha");         // alpha | premultiplied | additive | multiply
mat.setDepthWrite(false);
mat.setDoubleSided(true);
mat.setSortPriority(0);             // 同优先级按相机深度从后向前排序
mat.setMetallic(0.2);
mat.setRoughness(0.5);

local r = Renderable3D.create();
r.setMaterial(mat);                 // 整模
// 或多部件:r.setPart(0, "body", bodyMesh, bodyMat);
r.setPartSortPriority(0, 100);      // 每实例覆盖透明排序,不修改共享 Material
r.clearPartSortPriority(0);         // 恢复使用 Material.getSortPriority()
local effectiveOrder = r.getPartSortPriority(0);

遮罩材质使用 setSurfaceMode("masked")、setAlphaCutoff() 和 setAlphaTechnique("cutoff" | "dither" | "coverage")。对应查询接口为 getSurfaceMode()、getBlendMode()、getDepthWrite()、getDoubleSided()、 getSortPriority()、getAlphaCutoff() 和 getAlphaTechnique()。纹理 Alpha 数据可用 Texture.setAlphaConvention("straight" | "premultiplied") 声明,并通过 Texture.getAlphaConvention() 查询。

虚拟纹理材质通过 setVirtualTexture(albedoAtlas, normalAtlas, pageTable, pageCountX, pageCountY, borderFraction) 显式启用 atlas/page-table 路径; usesVirtualTexture() 可查询当前模式,clearVirtualTexture() 恢复传统材质贴图路径。 三个纹理对象必须至少存活到材质停止使用它们为止; 参数校验失败时 setVirtualTexture() 会抛出包含诊断信息的脚本异常。

高级渲染与屏幕空间效果

GBuffer、毛发、体积光、AO、GI 与抗锯齿集中在 高级渲染与屏幕空间效果,避免各类渲染特性持续修改本概览。

2D 屏幕拾取

Camera2D 用 setPosition / setZoom 控制视口中心与缩放;screenToWorldX/Y(screenX, screenY, viewW, viewH) 把鼠标像素换成世界坐标(viewW/H 通常取 gfx.getWidth/Height),再交给 Math 的 pointIn* 或 Physics 的 testPoint / queryAABB。

3D 屏幕拾取

Camera3D.screenToRay(screenX, screenY, viewW, viewH) 写入眼点与单位方向,用 getScreenRayOrigin* / getScreenRayDir* 读取,再对包围球/盒调用 Math 的 raycastSphere / raycastBox。

曲面瀑布

Waterfall.createCurvedSheet(width, height, segX, segY, curveDepth, lipOverhang) 创建带横向弧度和顶部探出段的细分瀑布网格,适合贴合崖壁并形成自然的离壁水帘;原有 createSheet(width, height) 仍用于平面瀑布。

local fall = gfx.newWaterfall();
fall.createCurvedSheet(3.0, 7.0, 28, 48, 0.75, 0.85);

风格化水体配置

Water.applyConfigJson(json) 使用 eve.graphics.stylized-water 版本化 schema 一次性校验并应用深浅水色、波浪、泡沫、透明度、折射、反射和焦散参数;失败时保留原配置。Water.configJson() 返回当前配置的规范 JSON,可用于编辑器属性面板、预设保存和运行时复制。

local water = gfx.newWater();
water.createPlane(14.0, 14.0, 64, 64);
local current = water.configJson();
water.applyConfigJson(current);

常见问题

  • 忘记每帧 clear(),保留未定义的旧帧内容。
  • 每帧编译 shader 或上传纹理。
  • 2D/UI/3D 提交顺序错误导致覆盖。
  • 拾取时 viewW/H 与实际渲染 drawable 不一致,射线会偏。

Agent 运行时观察

eve_renderable3d_get 使用完整 ECS entityId + generation 读取 live Renderable3D 的 transform、 field-backed PBR 参数与资源占用标志;陈旧 identity 返回结构化 stale。 eve_editor_execute_observe 的默认 renderable3d observer 在写入前验证同一 identity,再通过 Editor 事务修改目标,并在一个响应中返回 live before/after、事务回执和 Editor snapshot。传入 expect JSON 子集和可选 tolerance 后,引擎还会返回 converged、maxError 与不匹配字段路径, Agent 可直接决定是否继续纠正;无效期望会在写入前拒绝。同一协议还支持 scene-node observer, 因此 Agent 不必为场景和渲染对象维护两套调用编排。

API 快查

drawScene3DRGBA(x, y, w, h, r, g, b, a) 把最近一次 render3D() 产生的正式 场景颜色复合到当前目标(交换链或 Canvas)。它适合自定义编辑器把与游戏相同的场景 呈现在任意 Viewport 中;与 renderScene3DToCanvas 的独立预览渲染不同,它复用完整 运行时场景管线。

updateTextureFromImageData(texture, imageData) 将尺寸相同的 RGBA8 ImageData 重新上传到由当前 Graphics 后端创建的已有纹理;纹理对象保持不变,可继续被材质引用。 该方法必须在渲染线程调用,后端所有权、格式或尺寸不匹配时抛出异常。

C++ 渲染适配器可调用 updateTextureRegion(texture,x,y,width,height,rgba,bytesPerRow) 更新单 mip RGBA8 纹理的子矩形。Vulkan 使用 staging buffer 和原图 copyBufferToImage, WebGPU 使用带 origin 的 WriteTexture;两者都不重建 Texture、采样器或描述符。 多个离散矩形应使用 updateTextureRegions(texture, regions):它在任何写入前验证整个 批次;Vulkan 将所有 region 紧密打包进一个 staging buffer 并只提交一次。

下列方法名来自当前 Squirrel 绑定;同一模块创建的辅助对象(例如 World、Body、Source)的方法也列在这里。

  • bakeMeshMorph()、newMeshFromArrays()、updateMeshVertices()、clear()、clearMorphWeights()、declareFloat()、declareMatrix()、declareVec2()、declareVec3()、declareVec4()
  • drawSolidRect()、drawTexturedRect()、drawTexturedRectRotated()、drawOcclusionSolid()、drawOcclusionTexture()、getCastShadow()、getCastOcclusion()、getDirX()、getDirY()、getDirZ()、getEyeX()、getEyeY()、getEyeZ()、getFov()、getHeight()、getMorphCount()
  • getMorphName()、getMorphWeight()、getName()、getRadius()、getScreenRayDirX()、getScreenRayDirY()、getScreenRayDirZ()、getScreenRayOriginX()
  • getScreenRayOriginY()、getScreenRayOriginZ()、getShader()、getShadowBias()、getShadowStrength()、getType()、getUniformIndex()、getVertexCount()、getIndexCount()
  • getTargetX()、getTargetY()、getTargetZ()、getVolumetric()、getVolumetricIntensity()、getWidth()、getX()、getY()、getYaw()、getZ()、getZoom()、hasMorph()、hasMorphData()
  • hasUniform()、isEnabled()、isMorphDirty()、newHairShader()、newMeshCylinder()、newMeshShader()、newMeshShaderVF()、newMeshSphere()、newQuad()、newShader()
  • newShaderFromSpvFile()、replaceShaderFromGlsl()、replaceShaderFromWgsl()、newTexture()、newTextureWithSampler()、updateTextureFromImageData()、setTextureSampler()、getMaxAnisotropy()、newVolumetric()、newAmbientOcclusion()、newGlobalIllumination()、newAntiAliasing()、setMsaaSamples()、getMsaaSamples()、present()、render3D()、reset()、screenToRay()、screenToWorldX()、screenToWorldY()
  • sendFloat()、sendVec2()、sendVec3()、sendVec4()、setActive()、setAmbient()、setBackgroundColor()、setCamera()
  • setCanvas()、setCastOcclusion()、setCastShadow()、setCloudShadows()、setColor()、setDirection()、setDirectionalLight()、setEnabled()、setEnvIntensity()、setEnvMap()
  • setEye()、setFov()、setMesh()、getMesh()、setMeshLod()、clearMeshLod()、getMeshLodCount()、getMeshLodLevelAtDistance()、setMetallic()、setMorphWeight()、setNormalTexture()、setHeightTexture()、setPosition()、setRadius()
  • setReceiveLight()、setReceiveShadow()、setRotation()、setRoughness()、setScale()、setShader()、setHair()、getHair()、setShadowBias()、setShadowStrength()
  • setTarget()、setTexCellBomb()、getTexCellBombScale()、getTexCellBombStrength()、getTexCellBombRotation()、setParallax()、getParallaxScale()、getParallaxMinLayers()、getParallaxMaxLayers()、setTexture()、setTint()、setType()、setUp()、setViewport()、setVisible()、setVolumetric()、setVolumetricIntensity()、setYaw()
  • setZoom()、worldToScreenX()、worldToScreenY()、Texture.getMipmapCount()
  • 字体:newFont()、setFont()、getFont()、drawText()、print()、getAscent()、getBaseline()、hasGlyph()
  • AlphaMask:newAlphaMask()、setThreshold()、getThreshold()、setSoftness()、getSoftness()、setInverted()、getInverted()
  • MapFog:newMapFog()、update()、setTime()、getTime()、setCloudTexture()、getCloudTexture()、setMaskTexture()、getMaskTexture()、setCloudTiling()、setCloudSpeed()、setDistort()、setDistortFix()、setFogColor()、setFogAlpha()、setEdgeSoftness()、setShadowEnabled()、setShadow()、setSelectStrength()、setDissolveScale()、setCloudMix()、setCloudDensity()、getCloudTileA()、getCloudTileB()、getFogAlpha()、getShadowEnabled()、makeCloudTexture()、draw()(大地图迷雾:双层云 + mask R/G/B)
  • Sprite2D:setPosition()、getX()、getY()、setRotation()、getRotation()、setScale()、getScaleX()、getScaleY()、setSize()、getWidth()、getHeight()、setTexture()、getTexture()、setQuad()、getQuad()、setColor()、setLayer()、getLayer()、setVisible()、getVisible()、setReceiveLight()、getReceiveLight()、setBlend()、getBlend()、setAnchor()、getAnchorX()、getAnchorY()、setFlip()、getFlipX()、getFlipY()、setFrameLayout()、setCastOcclusion()、getCastOcclusion()、destroy()
  • Volumetric:setQuality、setMode、scatter、applyFromScene、rayMarch、applyFog、setFogHeight、setFogStart、setFogEnd、setCamera、setLightDirection、setDensity 等
  • FogVolume:setShape/getShape、setPosition、setSize、setExtinction/getExtinction、setAlbedo、setEmissive、setAnisotropy/getAnisotropy、setEdgeFalloff/getEdgeFalloff。setNoise(amount, scale, seed) 可加入确定性的世界空间密度变化,getNoiseAmount/getNoiseScale/getNoiseSeed 返回当前设置;调用 Volumetric.setCamera() 后,通过 injectFroxelLocalVolume(volume) 按当前视锥注入 froxel 网格。
  • Volumetric froxel:configureFroxelGrid、clearFroxelGrid、 injectFroxelHeightFog、integrateFroxel、uploadFroxel、 applyFroxel、applyFroxelTo
  • AmbientOcclusion:setQuality、setMode、setCamera、setRadius、setBias、setIntensity、setPower、compute、blur、applyOverlay、applyFromDepth、resolutionFor 等
  • GlobalIllumination:setQuality、setCamera、setRadius、setIntensity、setLightDirection、setLightColor、applyFromDepth、getSampleCount 等
  • AntiAliasing:setQuality、setMode、apply、applyTo、applyCanvas、applyCanvasTo、suggestScale、resolutionFor、setFloat、getFloat 等

使用要点

  • 模块对象和它创建的资源对象应保存在全局或实体状态中,不要在每帧重复创建。
  • 带 update(dt) 的系统应在 eve_update 调用;绘制方法应在 eve_render 调用。
  • 参数约束、默认值和返回类型以对应模块头文件及 addFunc 绑定为准;本文 API 快查与当前源码同步生成。

源码: src/modules/graphics/ 相关测试: 在 test/ 中搜索 graphics、Camera2D、Camera3D。

HDR 与反射探针绑定

下列绑定用于 HDR 图像、反射探针采集/注册、天空环境、曝光、Bloom 与反射链质量控制:

applyConfiguredToCamera、applyToCamera、clearReflectionProbe、configureInfluence、filterAndPublish、getActiveCubemap、getAdaptiveFaceBudget、getAdaptiveFilterSamples、getBloomIntensity、getBloomThreshold、getCaptureClusteredLighting、getCaptureFarDistance、getCaptureLodDistanceScale、getCaptureMask、getCaptureTransparent、getCenterX、getCenterY、getCenterZ、getCount、getEnvProbeCenterX、getEnvProbeCenterY、getEnvProbeCenterZ、getEnvProbeExtentX、getEnvProbeExtentY、getEnvProbeExtentZ、getEnvironmentLighting、getEnvironmentLightingIntensity、getExposure、getFaceCanvas、getGpuBudgetMs、getInfluenceBlendDistance、getInfluenceExtentX、getInfluenceExtentY、getInfluenceExtentZ、getInfluenceIntensity、getInfluencePriority、getLastCandidateCount、getLastCapturedFaceCount、getLastFilterSampleCount、getLastPublishedCount、getLastSelectedCount、getMaxRoughness、getPendingFaceCount、getPostProcessQuality、getPublishedRevision、getReflectionCaptureEnabled、getReflectionCaptureMask、getReflectionProbeCount、getReflectionQuality、getRefreshInterval、getResolution、getResolutionScale、getRevision、getSelectionHysteresis、getSkyB、getSkyFaceColor、getSkyFaceTexture、getSkyFaceTextureScale、getSkyG、getSkyIntensity、getSkyR、getSmoothedGpuDurationMs、getStagedRevision、getStagingCubemap、getThickness、getTotalCapturedFaceCount、getUpdateMode、hasEnvProbe、isAutoExposure、isCaptureComplete、isCapturePending、isRecaptureQueued、newHDRImageData、newReflectionProbeCapture、newReflectionProbeRegistry、queueCapture、queueCaptureAABB、remove、reportGpuDurationMs、requestCapture、setAutoExposure、setBloom、setCaptureClusteredLighting、setCaptureLodDistanceScale、setCaptureMask、setCaptureTransparent、setEnvironmentLighting、setExposure、setGpuBudgetMs、setMaxRoughness、setReflectionCaptureEnabled、setReflectionCaptureMask、setReflectionProbe、setReflectionQuality、setRefreshInterval、setResolutionScale、setSelectionHysteresis、setSkyColor、setSkyFaceColor、setSkyFaceTexture、setSkyFaceTextureScale、setUpdateMode、stageCapturedFaces、tick、tickAdaptive、updateCamera。

预编译网格 Shader 与画布快照

gfx.loadMeshShaderSpv(vertexPath, fragmentPath) 从 VFS 加载 Vulkan SPIR-V,返回统一 Result。 空 vertexPath 使用默认 Mesh3D 顶点着色器;fragmentPath 必填。成功后 value 是 Graphics 所有的借用 Shader,只在 Graphics 生命周期内使用。调用者须预先编译匹配 Mesh3D 布局的程序。 加载失败返回诊断,不修改已有材质。仅在渲染/VM owner 线程同步调用。

canvas.readPixels() 返回独立 RGBA8 ImageData 的 Result;成功时脚本拥有 value, 之后修改或清空画布不影响快照。调用前先提交离屏绘制批次;此操作等待 GPU,适合验证、 导出,不适合每帧执行。失败返回诊断,不改变画布。HDR 使用既有独立接口。

Vulkan RGBA8 画布在分次提交之间保留像素,显式 clear 在下一次绘制提交时执行。 参考 examples/ink-arena,可用片元着色器和 alpha 混合在 GPU 上累积表面墨迹。