Skip to content

Commit b4bbdcb

Browse files
committed
Add material diagnostics and realistic surface workflows
1 parent aa39e1a commit b4bbdcb

19 files changed

Lines changed: 476 additions & 80 deletions

‎schemas/tools-v1.schema.json‎

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -650,7 +650,9 @@
650650
"type": { "const": "projectUvs" },
651651
"layer": { "$ref": "#/$defs/geometryLayerName" },
652652
"cornerIndices": { "$ref": "#/$defs/geometryCornerSelection" },
653-
"axis": { "enum": ["xy", "xz", "yz"] },
653+
"projection": { "enum": ["planar", "cylindrical", "spherical"] },
654+
"axis": { "enum": ["xy", "xz", "yz", "x", "y", "z"] },
655+
"center": { "$ref": "#/$defs/geometryVec3" },
654656
"scale": {
655657
"oneOf": [
656658
{ "type": "number", "minimum": -1000000, "maximum": 1000000 },
@@ -1263,6 +1265,7 @@
12631265
"protocolVersion": { "$ref": "#/$defs/protocolVersion" }, "sessionId": { "$ref": "#/$defs/sessionId" }, "projectId": { "$ref": "#/$defs/id" },
12641266
"baseRevision": { "$ref": "#/$defs/revision" }, "idempotencyKey": { "$ref": "#/$defs/idempotencyKey" }, "label": { "$ref": "#/$defs/label" },
12651267
"dryRun": { "type": "boolean" },
1268+
"previewEvidence": { "type": "object", "additionalProperties": false, "properties": { "width": { "type": "integer", "minimum": 16, "maximum": 1920 }, "height": { "type": "integer", "minimum": 16, "maximum": 1080 } } },
12661269
"operations": { "type": "array", "minItems": 1, "maxItems": 128, "items": { "$ref": "#/$defs/operation" } }
12671270
}
12681271
},
@@ -1281,7 +1284,7 @@
12811284
"frame": { "type": "object", "additionalProperties": false, "anyOf": [{ "required": ["targetIds"] }, { "required": ["bounds"] }], "properties": { "targetIds": { "type": "array", "minItems": 1, "maxItems": 100, "items": { "$ref": "#/$defs/id" } }, "bounds": { "$ref": "#/$defs/bounds3" } } },
12821285
"timelineFrame": { "type": "integer", "minimum": -1000000, "maximum": 1000000 },
12831286
"width": { "type": "integer", "minimum": 16, "maximum": 1920 }, "height": { "type": "integer", "minimum": 16, "maximum": 1080 },
1284-
"passes": { "type": "array", "minItems": 1, "maxItems": 2, "items": { "enum": ["beauty", "objectId"] } },
1287+
"passes": { "type": "array", "minItems": 1, "maxItems": 7, "items": { "enum": ["beauty", "raster", "objectId", "albedo", "roughness", "normal", "uv"] } },
12851288
"renderer": { "const": "webgpu" }
12861289
}
12871290
},
@@ -1300,8 +1303,15 @@
13001303
},
13011304
"job": {
13021305
"type": "object", "additionalProperties": false,
1306+
"required": ["action", "projectId", "graphId", "textureId", "output", "resolution", "baseRevision", "idempotencyKey", "label"],
13031307
"properties": {
1304-
"protocolVersion": { "$ref": "#/$defs/protocolVersion" }, "sessionId": { "$ref": "#/$defs/sessionId" }
1308+
"protocolVersion": { "$ref": "#/$defs/protocolVersion" }, "sessionId": { "$ref": "#/$defs/sessionId" },
1309+
"action": { "const": "textureBake" },
1310+
"projectId": { "$ref": "#/$defs/id" }, "graphId": { "$ref": "#/$defs/id" }, "textureId": { "$ref": "#/$defs/id" },
1311+
"output": { "enum": ["albedo", "roughness", "normal"] },
1312+
"resolution": { "type": "array", "minItems": 2, "maxItems": 2, "items": { "type": "integer", "minimum": 1, "maximum": 512 } },
1313+
"name": { "type": "string", "minLength": 1, "maxLength": 160 },
1314+
"baseRevision": { "$ref": "#/$defs/revision" }, "idempotencyKey": { "$ref": "#/$defs/idempotencyKey" }, "label": { "$ref": "#/$defs/label" }
13051315
}
13061316
},
13071317
"project": {

‎src/blender/catalog.mjs‎

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -155,20 +155,20 @@ const entries = [
155155
canonicalRepresentation: 'Entity.transform contains local position, Euler rotation in radians, and non-zero scale vectors.',
156156
mcpWorkflow: ['three_studio_apply: entity.patch|entity.transformMany', 'three_studio_apply: entity.reparent|entity.group|entity.ungroup'],
157157
runtimeNotes: 'The compiler applies local TRS through the canonical parent hierarchy. Grouping rejects non-representable shear instead of silently drifting world placement.',
158-
supportedSubset: ['local translation', 'Euler rotation', 'scale', 'uniform guarded delta transforms', 'parent transforms', 'world-preserving group and ungroup', 'exact numeric layout'],
159-
unsupportedSubset: ['quaternions', 'per-object heterogeneous bulk transforms', 'parent inverse document field', 'apply/freeze transforms', 'transform orientations', 'snapping and proportional editing', 'TRS representation of shear'],
158+
supportedSubset: ['local translation', 'Euler rotation', 'scale', 'uniform guarded delta transforms', 'parent transforms', 'world-preserving group and ungroup', 'exact numeric layout', 'bounded proportional vertex movement with five falloffs'],
159+
unsupportedSubset: ['quaternions', 'per-object heterogeneous bulk transforms', 'parent inverse document field', 'apply/freeze transforms', 'transform orientations', 'snapping', 'TRS representation of shear'],
160160
officialUrls: ['https://docs.blender.org/manual/en/latest/scene_layout/object/editing/transform/introduction.html'],
161161
}),
162162
capability({
163163
id: 'blender/mesh-editing',
164164
domain: 'meshEditing',
165165
label: 'Mesh Editing',
166166
status: 'partial',
167-
canonicalRepresentation: 'Geometry resource recipes or explicit indexed meshes with positions, normals, UVs, colors, and indices.',
168-
mcpWorkflow: ['three_studio_apply: resource.create|resource.patch', 'three_studio_apply: entity.create with components.mesh'],
169-
runtimeNotes: 'Primitive recipes and complete explicit buffers are supported; there is no stateful Edit Mode or topology-operator layer.',
170-
supportedSubset: ['box', 'plane', 'sphere', 'capsule', 'circle', 'cone', 'cylinder', 'torus', 'torus knot', 'lathe', 'tube along a Catmull-Rom path', '2D shape with holes', 'extrude with bevel', 'explicit indexed mesh', 'computed normals'],
171-
unsupportedSubset: ['vertex/edge/face selection', 'topology extrusion operator', 'inset', 'loop cut', 'bevel operator', 'merge/dissolve', 'shape keys', 'sculpt topology'],
167+
canonicalRepresentation: 'Geometry resources include procedural recipes, indexed triangles, and editable polygon-corner meshes with topology hashes, layers, material slots, sharp edges, and creases.',
168+
mcpWorkflow: ['three_studio_inspect: meshElements for exact topology and topologyHash', 'three_studio_apply: geometry.edit with guarded bounded commands', 'three_studio_apply: entity.create with components.mesh'],
169+
runtimeNotes: 'Geometry edits are exact canonical mutations rather than UI selection state; topology and corner attributes propagate together and compile to indexed WebGPU geometry.',
170+
supportedSubset: ['procedural primitives and curves', 'indexed and editable polygon meshes', 'exact vertex/edge/face selections', 'move/scale/rotate/smooth/proportional move', 'subdivide/inset/extrude/bevel/delete/merge', 'normals', 'UV and color layers', 'face materials', 'sharp edges and creases'],
171+
unsupportedSubset: ['loop cut', 'dissolve', 'shape keys', 'interactive selection mode', 'sculpt topology'],
172172
officialUrls: ['https://docs.blender.org/manual/en/latest/modeling/meshes/editing/introduction.html'],
173173
}),
174174
capability({
@@ -179,8 +179,8 @@ const entries = [
179179
canonicalRepresentation: 'Entity.components.modifiers is an ordered, stable-ID stack. Canonical live types are validated strictly; unsupported Blender settings use an explicit bakeBoundary with a validated Blender operatorType and opaque bounded parameters.',
180180
mcpWorkflow: ['three_studio_inspect: modifierDigest for the exact stackHash', 'three_studio_apply: guarded modifier.create|patch|move|delete or modifier.stack.edit', 'three_studio_validate', 'Bake explicit bakeBoundary entries externally before expecting downstream live evaluation.'],
181181
runtimeNotes: 'Array, mirror, and pattern lower to bounded instance transforms. Nine deterministic indexed-mesh modifiers evaluate as derived geometry without mutating the shared base resource. A bakeBoundary stops live downstream evaluation instead of silently approximating it. Blender 5.2\'s complete 83-type RNA inventory remains queryable; authored render-enable flags are preserved but do not claim render/evidence parity.',
182-
supportedSubset: ['ordered stack up to 64 entries', 'stable modifier IDs and exact stack hashes', 'one guarded atomic stack-edit batch', 'array count/offset up to bounded limits', 'single-axis mirror', 'bounded linear/grid/radial/scatter patterns', 'triangulate', 'weld', 'smooth', 'weighted normal subset', 'edge split by angle', 'solidify subset', 'simple/Loop triangle subdivision', 'deterministic decimate subset', 'inline deterministic displacement', 'complete Blender 5.2 Object Modifier Type Items inventory'],
183-
unsupportedSubset: ['full Blender semantic parity for live geometry subsets', 'render/evidence parity for enabledRender', 'downstream live evaluation after bakeBoundary', 'surface masks or collision-aware scatter', 'apply-to-base operation', 'edit cage', 'modifier object/vertex-group references', 'Grease Pencil stroke/layer object model', 'physics solvers'],
182+
supportedSubset: ['ordered stack up to 64 entries', 'stable modifier IDs and exact stack hashes', 'one guarded atomic stack-edit batch', 'array count/offset up to bounded limits', 'single-axis mirror', 'bounded linear/grid/radial/scatter patterns', 'area-weighted surface scatter with normal/gravity alignment and minimum spacing', 'triangulate', 'weld', 'smooth', 'weighted normal subset', 'edge split by angle', 'solidify subset', 'simple/Loop triangle subdivision', 'deterministic decimate subset', 'inline deterministic displacement', 'complete Blender 5.2 Object Modifier Type Items inventory'],
183+
unsupportedSubset: ['full Blender semantic parity for live geometry subsets', 'render/evidence parity for enabledRender', 'downstream live evaluation after bakeBoundary', 'collision-aware scatter beyond minimum spacing', 'apply-to-base operation', 'edit cage', 'general modifier object/vertex-group references', 'Grease Pencil stroke/layer object model', 'physics solvers'],
184184
officialUrls: [
185185
'https://docs.blender.org/manual/en/5.2/modeling/modifiers/introduction.html',
186186
'https://docs.blender.org/api/5.2/bpy_types_enum_items/object_modifier_type_items.html',
@@ -205,9 +205,9 @@ const entries = [
205205
status: 'partial',
206206
canonicalRepresentation: 'Material resources use basic, standard, physical, or toon recipes with linear color and bounded scalar parameters.',
207207
mcpWorkflow: ['three_studio_apply: resource.create materials', 'three_studio_apply: entity.create|entity.patch materialIds'],
208-
runtimeNotes: 'The WebGPU compiler supports one material per mesh and compiles the supported typed graph subset to Three.js TSL NodeMaterials.',
209-
supportedSubset: ['base color', 'roughness', 'metalness', 'emissive', 'opacity', 'clearcoat', 'transmission', 'toon/basic/standard/physical families', 'Blender-shaped live shader graphs'],
210-
unsupportedSubset: ['multiple material slots', 'volume materials', 'true geometric material displacement', 'image texture binding'],
208+
runtimeNotes: 'The WebGPU compiler supports exact face material slots, canonical raster maps, and typed TSL graphs, including a documented view-rim subsurface approximation.',
209+
supportedSubset: ['base color', 'roughness', 'metalness', 'emissive', 'opacity', 'clearcoat', 'transmission', 'multiple face material slots', 'canonical image texture binding', 'subsurface tint/scale approximation', 'toon/basic/standard/physical families', 'Blender-shaped live shader graphs'],
210+
unsupportedSubset: ['volume materials', 'true random-walk subsurface scattering', 'true geometric material displacement'],
211211
officialUrls: ['https://docs.blender.org/manual/en/latest/render/materials/introduction.html'],
212212
}),
213213
capability({
@@ -229,9 +229,9 @@ const entries = [
229229
status: 'partial',
230230
canonicalRepresentation: 'Texture and asset resources plus versioned typed texture graphs with explicit color-space declarations.',
231231
mcpWorkflow: ['three_studio_inspect: graphCatalog domain texture', 'three_studio_apply: resource.create textures|assets|graphs', 'three_studio_validate'],
232-
runtimeNotes: 'Procedural texture graphs compile to live TSL where supported and can be deterministically CPU-evaluated into typed albedo, roughness, normal, and height maps.',
233-
supportedSubset: ['sRGB/non-color declarations', 'UV and generated coordinates', 'checker/gradient/noise/Voronoi/Wave/ramp/math evaluation', 'bounded deterministic CPU bake', 'live procedural TSL'],
234-
unsupportedSubset: ['image decoding and GPU binding through MCP', 'UDIM', 'texture painting', 'file-producing bake jobs'],
232+
runtimeNotes: 'Procedural texture graphs compile live and the textureBake job can commit an albedo, roughness, or normal output as a canonical dataTexture without external files.',
233+
supportedSubset: ['sRGB/non-color declarations', 'UV and generated coordinates', 'checker/gradient/noise/Voronoi/Wave/ramp/math evaluation', 'bounded deterministic CPU bake job', 'canonical raster GPU binding', 'live procedural TSL'],
234+
unsupportedSubset: ['external image-file decoding through MCP', 'UDIM', 'texture painting', 'height-map job output'],
235235
officialUrls: ['https://docs.blender.org/manual/en/latest/render/shader_nodes/textures/index.html'],
236236
}),
237237
capability({
@@ -337,9 +337,9 @@ const entries = [
337337
status: 'planned',
338338
canonicalRepresentation: 'Future versioned compositor graph resources consuming explicit render passes and producing bounded image outputs.',
339339
mcpWorkflow: ['three_studio_render: future diagnostic/render passes', 'three_studio_job: future offline compositor job'],
340-
runtimeNotes: 'Only direct WebGPU beauty evidence is available; no post-render graph is evaluated.',
341-
supportedSubset: [],
342-
unsupportedSubset: ['compositor nodes', 'render-layer inputs', 'AOVs', 'cryptomatte', 'file outputs', 'viewport compositor'],
340+
runtimeNotes: 'No post-render graph is evaluated, but bounded raster, albedo, roughness, normal, UV, and object-ID diagnostic inputs are available.',
341+
supportedSubset: ['diagnostic render inputs for future compositing'],
342+
unsupportedSubset: ['compositor nodes', 'cryptomatte', 'file-output nodes', 'viewport compositor'],
343343
officialUrls: ['https://docs.blender.org/manual/en/latest/compositing/introduction.html'],
344344
}),
345345
capability({
@@ -348,10 +348,10 @@ const entries = [
348348
label: 'Rendering',
349349
status: 'partial',
350350
canonicalRepresentation: 'External Three.js WebGPU renderer plus revision-bound evidence metadata and project render settings.',
351-
mcpWorkflow: ['three_studio_status', 'three_studio_render: beauty with authored camera or exact framing', 'three_studio_inspect: latestEvidence'],
352-
runtimeNotes: 'The persistent native viewport uses WebGPU with shadows. Evidence capture is explicit and offscreen; RTX, animation, and diagnostic passes are capability-gated.',
353-
supportedSubset: ['WebGPU beauty pass', 'native live viewport', 'shadows', 'offscreen PNG evidence', 'perspective and orthographic capture', 'exact revision metadata'],
354-
unsupportedSubset: ['Cycles', 'Eevee parity', 'RTX path tracing', 'AOV/render passes', 'render animation', 'distributed render', 'denoising'],
351+
mcpWorkflow: ['three_studio_status', 'three_studio_render: beauty+raster or material diagnostic passes with authored camera/exact framing', 'three_studio_inspect: latestEvidence|rtxDigest'],
352+
runtimeNotes: 'The persistent native viewport uses WebGPU. Explicit evidence can pair raster and active RTX beauty and can isolate material channels without contaminating the ordinary render loop.',
353+
supportedSubset: ['WebGPU beauty and raster passes', 'native live viewport', 'shadows', 'offscreen PNG evidence', 'albedo/roughness/normal/UV/object-ID diagnostics', 'perspective and orthographic capture', 'exact revision metadata', 'RTX preflight and raster fallback'],
354+
unsupportedSubset: ['Cycles', 'Eevee parity', 'RTX path tracing', 'render animation sequences', 'distributed render', 'denoising'],
355355
officialUrls: ['https://docs.blender.org/manual/en/latest/render/introduction.html'],
356356
}),
357357
capability({
@@ -482,11 +482,11 @@ const entries = [
482482
domain: 'uvEditing',
483483
label: 'UV Editing',
484484
status: 'partial',
485-
canonicalRepresentation: 'Explicit geometry resources may carry one UV attribute array aligned to vertex positions.',
486-
mcpWorkflow: ['three_studio_apply: resource.create|resource.patch indexedMesh with uvs'],
487-
runtimeNotes: 'UV coordinates persist and compile, but texture maps do not yet bind and there is no unwrapping operator.',
488-
supportedSubset: ['single UV attribute import', 'UV buffer validation by vertex count'],
489-
unsupportedSubset: ['unwrap', 'seams', 'multiple UV maps', 'UV islands', 'packing', 'live UV editing'],
485+
canonicalRepresentation: 'Editable polygon meshes own named per-corner UV layers with an explicit active viewport layer; indexed meshes retain one compact UV channel.',
486+
mcpWorkflow: ['three_studio_inspect: meshElements for exact corners and active layer', 'three_studio_apply: geometry.edit create/set/transform/project UV commands'],
487+
runtimeNotes: 'UV edits preserve seams through topology operations. Planar, cylindrical, and spherical projection are live; the active layer binds raster maps and UV graph inputs.',
488+
supportedSubset: ['multiple named UV layers', 'exact per-corner UV edits and seams', 'active UV layer', 'transform UVs', 'planar/cylindrical/spherical projection', 'raster and graph sampling'],
489+
unsupportedSubset: ['angle-based unwrap', 'island packing', 'automatic seam marking', 'UDIM'],
490490
officialUrls: ['https://docs.blender.org/manual/en/latest/modeling/meshes/uv/unwrapping/introduction.html'],
491491
}),
492492
capability({

0 commit comments

Comments
 (0)