Skip to content

Commit e3e4cc5

Browse files
committed
update silhouette normal encoding
1 parent bf816db commit e3e4cc5

File tree

1 file changed

+1
-72
lines changed
  • extensions/2.0/Vendor/EXT_mesh_primitive_edge_visibility

1 file changed

+1
-72
lines changed

extensions/2.0/Vendor/EXT_mesh_primitive_edge_visibility/README.md

Lines changed: 1 addition & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -194,77 +194,10 @@ Assume that the top edge is to be drawn using the same material as the vertical
194194

195195
### Silhouette Normals
196196

197-
The extension's `silhouetteNormals` property specifies the index of an accessor of `SCALAR` type and component type 5123 (unsigned short) providing normal vectors used to determine the visibility of silhouette edges at display time. For each edge encoded as a silhouette (visibility value `1`) in `visibility`, the silhouette normals buffer provides the two outward-facing normal vectors of the pair of triangles sharing the edge. Each normal vector is compressed into 16 bits using an "oct16" encoding. The ordering of the normal vector pairs corresponds to the ordering of the edges in `visibility`; that is, the first pair of normals corresponds to the first edge encoded with visibility `1`, the second pair to the second occurrence of visibility `1`; and so on. The accessor's `count` **MUST** be twice the number of edges encoded with visibility value `1`.
198-
199-
### oct16 encoding
200-
201-
Octahedral normal encoding projects a normal vector onto an octahedron and folds it in half, mapping to two signed normalized components in [-1, 1]. The "oct16" form of this encoding maps each component to the integer range [0, 255], permitting a normal vector to be encoded into two bytes.
202-
203-
TypeScript implementation of oct16 encoding and decoding:
204-
205-
```ts
206-
// A three-dimensional vector.
207-
interface Vec3d { x: number; y: number; z: number; }
208-
209-
// Normalize a 3d vector to a length of 1.
210-
function normalize(vec: Vec3d): void {
211-
const magnitude = Math.sqrt(vec.x * vec.x + vec.y * vec.y + vec.z * vec.z);
212-
const scale = magnitude === 0 ? 0 : 1 / magnitude;
213-
vec.x *= scale;
214-
vec.y *= scale;
215-
vec.z *= scale;
216-
}
217-
218-
// Map a signed normalized value in [-1, 1] to the integer range [0, 255].
219-
function toSNorm(val: number): number {
220-
const clamped = Math.min(Math.max(val, -1), 1);
221-
return Math.round((clamped * 0.5 + 0.5) * 255);
222-
}
223-
224-
// Return -1 for a negative input, otherwise 1.
225-
function signNotZero(val: number): number {
226-
return val < 0.0 ? -1.0 : 1.0;
227-
}
228-
229-
// Encode a normalized 3d vector into a 16-bit unsigned integer.
230-
function oct16EncodeNormal(n: Vec3d): number {
231-
const denom = Math.abs(n.x) + Math.abs(n.y) + Math.abs(n.z);
232-
let rx = n.x / denom;
233-
let ry = n.y / denom;
234-
if (n.z < 0) {
235-
const x = rx;
236-
const y = ry;
237-
rx = (1 - Math.abs(y)) * signNotZero(x);
238-
ry = (1 - Math.abs(x)) * signNotZero(y);
239-
}
240-
241-
return toSNorm(ry) << 8 | toSNorm(rx);
242-
}
243-
244-
// Decode a 16-bit unsigned integer into a normalized 3d vector.
245-
function oct16DecodeNormal(oct16: number): Vec3d {
246-
let x = oct16 & 0xff;
247-
let y = oct16 >> 8;
248-
x = x / 255.0 * 2.0 - 1.0;
249-
y = y / 255.0 * 2.0 - 1.0;
250-
const z = 1 - (Math.abs(x) + Math.abs(y));
251-
252-
const n: Vec3d = { x, y, z };
253-
if (z < 0) {
254-
n.x = (1 - Math.abs(y)) * signNotZero(x);
255-
n.y = (1 - Math.abs(x)) * signNotZero(y);
256-
}
257-
258-
normalize(n);
259-
return n;
260-
}
261-
262-
```
197+
The extension's `silhouetteNormals` property specifies the index of an accessor of type `VEC3` providing normal vectors used to determine the visibility of silhouette edges at display time. For each edge encoded as a silhouette (visibility value `1`) in `visibility`, the silhouette normals buffer provides the two outward-facing normal vectors of the pair of triangles sharing the edge. The normal vectors **MUST** be normalized and use component type 5126 (float), 5120 (byte), or 5122 (short). The ordering of the normal vector pairs corresponds to the ordering of the edges in `visibility`; that is, the first pair of normals corresponds to the first edge encoded with visibility `1`, the second pair to the second occurrence of visibility `1`; and so on. The accessor's `count` **MUST** be twice the number of edges encoded with visibility value `1`.
263198

264199
The `silhouetteNormals` property **MUST** be defined *if and only if* at least one edge is encoded with visibility value `1` in `visibility`.
265200

266-
Engines **MUST** render a silhouette edge unless both adjacent triangles are front-facing or both are back-facing, as determined by their normal vectors.
267-
268201
## Rendering requirements
269202

270203
- Engines **MUST** render all edges according to their specified visibility values, though some engines may permit the user to toggle the display of edges on and off.
@@ -286,7 +219,3 @@ Engines **MUST** render a silhouette edge unless both adjacent triangles are fro
286219
The [pull request](https://github.com/iTwin/itwinjs-core/pull/5581) that informed the design of this extension provides [an iterator](https://github.com/iTwin/itwinjs-core/blob/03b760e1e91bde5221aa7370ea45c52f966e3368/core/frontend/src/common/imdl/CompactEdges.ts#L42) over the `visibility` buffer.
287220

288221
iTwin.js [implements](https://github.com/iTwin/itwinjs-core/blob/03b760e1e91bde5221aa7370ea45c52f966e3368/core/frontend/src/internal/render/webgl/glsl/Edge.ts#L107) conditional display of silhouette edges. It also draws edges in a separate pass from surfaces to [mitigate z-fighting](https://github.com/iTwin/itwinjs-core/blob/03b760e1e91bde5221aa7370ea45c52f966e3368/core/frontend/src/internal/render/webgl/glsl/FeatureSymbology.ts#L426).
289-
290-
## References
291-
292-
- The oct16 normal vector encoding is described in detail in [A Survey of Efficient Representations for Independent Unit Vectors](https://jcgt.org/published/0003/02/01/).

0 commit comments

Comments
 (0)