GlTF PBR: Difference between revisions
(glTF overrides) |
|||
Line 77: | Line 77: | ||
Note that this is not the same as the glTF uploaded by users. That has filenames in the "uri" field. Somewhere during the upload process, URIs are generated for those files. | Note that this is not the same as the glTF uploaded by users. That has filenames in the "uri" field. Somewhere during the upload process, URIs are generated for those files. | ||
=== glTF overrides=== | |||
Standard glTF material format does not contain texture scale, rotation, or offset information. Those are properties of a face of an in-world object, not the material. That information is sent to the viewer as "glTF overrides". | |||
These are sent to the viewer via the Event Queue system.[https://wiki.secondlife.com/wiki/EventQueueGet]. Along with other events, they show up as LLSD items, with a key "GLTFMaterialOverride". The content is encapsulated in glTF "notation" format, which in turn encapsulates glTF in JSON format. | |||
A raw sample follows. (This will be replaced with a cleaner format). | |||
<pre> | |||
<llsd><map><key>events</key><array><map><key>body</key><map><key>AgentData</key><array><map><key>AgentID</key><uuid>b5fde908-eebf-4505-b686-ca74c3f91979</uuid><key>SessionID</key><uuid /><key>TransactionID</key><uuid /></map></array><key>MethodData</key><array><map><key>Invoice</key><uuid /><key>Method</key><string>GLTFMaterialOverride</string></map></array><key>ParamList</key> | |||
<array><map><key>Parameter</key><string> | |||
<? llsd/notation ?> | |||
{'gltf_json':['{"asset":{"version":"2.0"},"images":[{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"}], | |||
"materials":[{"emissiveTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[3.0,2.0]}},"index":3},"normalTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[3.0,2.0]}},"index":1},"occlusionTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[3.0,2.0]}},"index":4},"pbrMetallicRoughness":{"baseColorTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[3.0,2.0]}},"index":0},"metallicRoughnessTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[3.0,2.0]}},"index":2}}}],"textures":[{"source":0},{"source":1},{"source":2},{"source":3},{"source":4}]}\n','{"asset":{"version":"2.0"},"images":[{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"}],"materials":[{"emissiveTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[3.0,2.0]}},"index":3},"normalTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[3.0,2.0]}},"index":1},"occlusionTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[3.0,2.0]}},"index":4},"pbrMetallicRoughness":{"baseColorTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[3.0,2.0]}},"index":0},"metallicRoughnessTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[3.0,2.0]}},"index":2}}}],"textures":[{"source":0},{"source":1},{"source":2},{"source":3},{"source":4}]}\n','{"asset":{"version":"2.0"},"images":[{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"}],"materials":[{"emissiveTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[3.0,2.0]}},"index":3},"normalTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[3.0,2.0]}},"index":1},"occlusionTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[3.0,2.0]}},"index":4},"pbrMetallicRoughness":{"baseColorTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[3.0,2.0]}},"index":0},"metallicRoughnessTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[3.0,2.0]}},"index":2}}}],"textures":[{"source":0},{"source":1},{"source":2},{"source":3},{"source":4}]}\n','{"asset":{"version":"2.0"},"images":[{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"}],"materials":[{"emissiveTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[3.0,2.0]}},"index":3},"normalTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[3.0,2.0]}},"index":1},"occlusionTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[3.0,2.0]}},"index":4},"pbrMetallicRoughness":{"baseColorTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[3.0,2.0]}},"index":0},"metallicRoughnessTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[3.0,2.0]}},"index":2}}}],"textures":[{"source":0},{"source":1},{"source":2},{"source":3},{"source":4}]}\n','{"asset":{"version":"2.0"},"images":[{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000 | |||
</pre> | |||
=== Reflection Probe === | === Reflection Probe === |
Revision as of 03:31, 15 July 2023
Opensimulator: Documentation: Asset types: GlTF PBR
Both Second Life and Open Simulator are adding a new class of assets for physically-based rendering. For an overview, see PBR Materials in the Second Lif Wiki.[1] This Wiki entry covers how the data about physically based materials is conveyed from server to viewer.
Object updates
Object updates can have "extra parameters", for objects such as lights and flexis. For glTF materials, two new types of "extra parameter" have been added.
Render Material
Extra parameter code: 0x80.
Content: an array of (face index, UUID).
An example is
- LLRenderMaterialParamsItem { idx: 0, id: a99f26b5-1cc1-40bc-a666-a6825592b188 },
- LLRenderMaterialParamsItem { idx: 1, id: a99f26b5-1cc1-40bc-a666-a6825592b188 },
- LLRenderMaterialParamsItem { idx: 2, id: a99f26b5-1cc1-40bc-a666-a6825592b188 },
- LLRenderMaterialParamsItem { idx: 3, id: a99f26b5-1cc1-40bc-a666-a6825592b188 },
- LLRenderMaterialParamsItem { idx: 4, id: a99f26b5-1cc1-40bc-a666-a6825592b188 },
- LLRenderMaterialParamsItem { idx: 5, id: a99f26b5-1cc1-40bc-a666-a6825592b188 }
This indicates that material UUID a99f26b5-1cc1-40bc-a666-a6825592b188 is to be applied to faces 0..5, overriding any classic material information.
All zero UUIDs have been seen in Second Life messages but not in Open Simulator messages. This may be a bug.
The asset for this UUID is fetched using the "ViewerAsset" capability obtained from the seed capability. This will be a URL with no trailing slash. An example from an OSGrid test region:
ViewerAsset": "http://plaza16.osgrid.org:9300/147ae4d1-b064-442c-80b3-f76b59e3fc71
The UUID points to a remote asset stored in binary LLSD format, with a proper binary LLSD header. This contains information for finding the relevant glTF assets. The format of the URL to fetch is
http://VIEWERASSETVALUE?material_id=UUID
which, in this case, would be
http://plaza16.osgrid.org:9300/75357890-ffde-4d96-8473-a663238dcd21?material_id=a99f26b5-1cc1-40bc-a666-a6825592b188
Note that, for Open Simulator, these URLs are only valid for the duration of the login. For Second LIfe, they are persistent.
Reading this URL yields a set of key-value pairs in binary LLSD format, with keys such as "baseColor" and "pbrMetallicRoughness". The values are more UUIDs, requiring another stage of asset fetching.
Example
This was translated from binary LLSD to XML LLSD for readability. SL viewer code indicates that both XML and binary forms of LLSD should be accepted.
<?xml version="1.0" encoding="UTF-8"?> <llsd> <map> <key>data</key> <string>{"asset":{"version":"2.0"},"images":[{"uri":"d1f91bb7-f7d6-d26f-e0d7-568f0ff74279"},{"uri":"d1f91bb7-f7d6-d26f-e0d7-568f0ff74279"},{"uri":"8a45c99a-cf84-77c5-9d9d-5c9875213fe9"}],"materials":[{"normalTexture":{"index":2},"pbrMetallicRoughness":{"baseColorTexture":{"index":0},"metallicRoughnessTexture":{"index":1}}}],"textures":[{"source":0},{"source":1},{"source":2}]} </string> <key>type</key> <string>GLTF 2.0</string> <key>version</key> <string>1.0</string> </map> </llsd>
The LLSD contains a string which is glTF data in JSON format.
{"asset": {"version":"2.0"},"images":[ {"uri":"d1f91bb7-f7d6-d26f-e0d7-568f0ff74279"}, {"uri":"d1f91bb7-f7d6-d26f-e0d7-568f0ff74279"}, {"uri":"8a45c99a-cf84-77c5-9d9d-5c9875213fe9"}], "materials":[ { "normalTexture":{"index":2}, "pbrMetallicRoughness":{"baseColorTexture":{"index":0},metallicRoughnessTexture":{"index":1}}}], "textures":[{"source":0},{"source":1},{"source":2}] }
The format of this data corresponds roughly to the official glTF format specification for materials.. The formal schema for that JSON is in section A22 - JSON Schema for Material.
Note that this is not the same as the glTF uploaded by users. That has filenames in the "uri" field. Somewhere during the upload process, URIs are generated for those files.
glTF overrides
Standard glTF material format does not contain texture scale, rotation, or offset information. Those are properties of a face of an in-world object, not the material. That information is sent to the viewer as "glTF overrides".
These are sent to the viewer via the Event Queue system.[2]. Along with other events, they show up as LLSD items, with a key "GLTFMaterialOverride". The content is encapsulated in glTF "notation" format, which in turn encapsulates glTF in JSON format.
A raw sample follows. (This will be replaced with a cleaner format).
<llsd><map><key>events</key><array><map><key>body</key><map><key>AgentData</key><array><map><key>AgentID</key><uuid>b5fde908-eebf-4505-b686-ca74c3f91979</uuid><key>SessionID</key><uuid /><key>TransactionID</key><uuid /></map></array><key>MethodData</key><array><map><key>Invoice</key><uuid /><key>Method</key><string>GLTFMaterialOverride</string></map></array><key>ParamList</key> <array><map><key>Parameter</key><string> <? llsd/notation ?> {'gltf_json':['{"asset":{"version":"2.0"},"images":[{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"}], "materials":[{"emissiveTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[3.0,2.0]}},"index":3},"normalTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[3.0,2.0]}},"index":1},"occlusionTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[3.0,2.0]}},"index":4},"pbrMetallicRoughness":{"baseColorTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[3.0,2.0]}},"index":0},"metallicRoughnessTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[3.0,2.0]}},"index":2}}}],"textures":[{"source":0},{"source":1},{"source":2},{"source":3},{"source":4}]}\n','{"asset":{"version":"2.0"},"images":[{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"}],"materials":[{"emissiveTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[3.0,2.0]}},"index":3},"normalTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[3.0,2.0]}},"index":1},"occlusionTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[3.0,2.0]}},"index":4},"pbrMetallicRoughness":{"baseColorTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[3.0,2.0]}},"index":0},"metallicRoughnessTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[3.0,2.0]}},"index":2}}}],"textures":[{"source":0},{"source":1},{"source":2},{"source":3},{"source":4}]}\n','{"asset":{"version":"2.0"},"images":[{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"}],"materials":[{"emissiveTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[3.0,2.0]}},"index":3},"normalTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[3.0,2.0]}},"index":1},"occlusionTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[3.0,2.0]}},"index":4},"pbrMetallicRoughness":{"baseColorTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[3.0,2.0]}},"index":0},"metallicRoughnessTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[3.0,2.0]}},"index":2}}}],"textures":[{"source":0},{"source":1},{"source":2},{"source":3},{"source":4}]}\n','{"asset":{"version":"2.0"},"images":[{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"}],"materials":[{"emissiveTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[3.0,2.0]}},"index":3},"normalTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[3.0,2.0]}},"index":1},"occlusionTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[3.0,2.0]}},"index":4},"pbrMetallicRoughness":{"baseColorTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[3.0,2.0]}},"index":0},"metallicRoughnessTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[3.0,2.0]}},"index":2}}}],"textures":[{"source":0},{"source":1},{"source":2},{"source":3},{"source":4}]}\n','{"asset":{"version":"2.0"},"images":[{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000
Reflection Probe
Extra parameter code: 0x90.
Content: One entry of (ambience, clip distance, flags)
More information is needed.