@certe/atmos-renderer 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (204) hide show
  1. package/LICENCE +674 -0
  2. package/README.md +166 -0
  3. package/dist/bloom-pass.d.ts +29 -0
  4. package/dist/bloom-pass.d.ts.map +1 -0
  5. package/dist/bloom-pass.js +173 -0
  6. package/dist/bloom-pass.js.map +1 -0
  7. package/dist/bloom-shader.d.ts +9 -0
  8. package/dist/bloom-shader.d.ts.map +1 -0
  9. package/dist/bloom-shader.js +69 -0
  10. package/dist/bloom-shader.js.map +1 -0
  11. package/dist/bounds.d.ts +10 -0
  12. package/dist/bounds.d.ts.map +1 -0
  13. package/dist/bounds.js +37 -0
  14. package/dist/bounds.js.map +1 -0
  15. package/dist/camera.d.ts +31 -0
  16. package/dist/camera.d.ts.map +1 -0
  17. package/dist/camera.js +53 -0
  18. package/dist/camera.js.map +1 -0
  19. package/dist/depth-prepass.d.ts +24 -0
  20. package/dist/depth-prepass.d.ts.map +1 -0
  21. package/dist/depth-prepass.js +107 -0
  22. package/dist/depth-prepass.js.map +1 -0
  23. package/dist/directional-light.d.ts +23 -0
  24. package/dist/directional-light.d.ts.map +1 -0
  25. package/dist/directional-light.js +36 -0
  26. package/dist/directional-light.js.map +1 -0
  27. package/dist/frustum.d.ts +15 -0
  28. package/dist/frustum.d.ts.map +1 -0
  29. package/dist/frustum.js +51 -0
  30. package/dist/frustum.js.map +1 -0
  31. package/dist/fullscreen-quad.d.ts +8 -0
  32. package/dist/fullscreen-quad.d.ts.map +1 -0
  33. package/dist/fullscreen-quad.js +30 -0
  34. package/dist/fullscreen-quad.js.map +1 -0
  35. package/dist/geometry.d.ts +28 -0
  36. package/dist/geometry.d.ts.map +1 -0
  37. package/dist/geometry.js +245 -0
  38. package/dist/geometry.js.map +1 -0
  39. package/dist/grid-renderer.d.ts +10 -0
  40. package/dist/grid-renderer.d.ts.map +1 -0
  41. package/dist/grid-renderer.js +77 -0
  42. package/dist/grid-renderer.js.map +1 -0
  43. package/dist/grid-shader.d.ts +3 -0
  44. package/dist/grid-shader.d.ts.map +1 -0
  45. package/dist/grid-shader.js +89 -0
  46. package/dist/grid-shader.js.map +1 -0
  47. package/dist/index.d.ts +64 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +45 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/light.d.ts +59 -0
  52. package/dist/light.d.ts.map +1 -0
  53. package/dist/light.js +184 -0
  54. package/dist/light.js.map +1 -0
  55. package/dist/material-asset.d.ts +19 -0
  56. package/dist/material-asset.d.ts.map +1 -0
  57. package/dist/material-asset.js +30 -0
  58. package/dist/material-asset.js.map +1 -0
  59. package/dist/material.d.ts +50 -0
  60. package/dist/material.d.ts.map +1 -0
  61. package/dist/material.js +48 -0
  62. package/dist/material.js.map +1 -0
  63. package/dist/mesh-renderer.d.ts +43 -0
  64. package/dist/mesh-renderer.d.ts.map +1 -0
  65. package/dist/mesh-renderer.js +162 -0
  66. package/dist/mesh-renderer.js.map +1 -0
  67. package/dist/mesh.d.ts +16 -0
  68. package/dist/mesh.d.ts.map +1 -0
  69. package/dist/mesh.js +33 -0
  70. package/dist/mesh.js.map +1 -0
  71. package/dist/mipmap-generator.d.ts +7 -0
  72. package/dist/mipmap-generator.d.ts.map +1 -0
  73. package/dist/mipmap-generator.js +96 -0
  74. package/dist/mipmap-generator.js.map +1 -0
  75. package/dist/pbr-wgsl.d.ts +12 -0
  76. package/dist/pbr-wgsl.d.ts.map +1 -0
  77. package/dist/pbr-wgsl.js +159 -0
  78. package/dist/pbr-wgsl.js.map +1 -0
  79. package/dist/pipeline.d.ts +13 -0
  80. package/dist/pipeline.d.ts.map +1 -0
  81. package/dist/pipeline.js +77 -0
  82. package/dist/pipeline.js.map +1 -0
  83. package/dist/point-light.d.ts +16 -0
  84. package/dist/point-light.d.ts.map +1 -0
  85. package/dist/point-light.js +22 -0
  86. package/dist/point-light.js.map +1 -0
  87. package/dist/point-shadow-pass.d.ts +24 -0
  88. package/dist/point-shadow-pass.d.ts.map +1 -0
  89. package/dist/point-shadow-pass.js +192 -0
  90. package/dist/point-shadow-pass.js.map +1 -0
  91. package/dist/point-shadow-shader.d.ts +12 -0
  92. package/dist/point-shadow-shader.d.ts.map +1 -0
  93. package/dist/point-shadow-shader.js +52 -0
  94. package/dist/point-shadow-shader.js.map +1 -0
  95. package/dist/register-builtins.d.ts +2 -0
  96. package/dist/register-builtins.d.ts.map +1 -0
  97. package/dist/register-builtins.js +98 -0
  98. package/dist/register-builtins.js.map +1 -0
  99. package/dist/render-system.d.ts +99 -0
  100. package/dist/render-system.d.ts.map +1 -0
  101. package/dist/render-system.js +476 -0
  102. package/dist/render-system.js.map +1 -0
  103. package/dist/scene-depth.d.ts +36 -0
  104. package/dist/scene-depth.d.ts.map +1 -0
  105. package/dist/scene-depth.js +183 -0
  106. package/dist/scene-depth.js.map +1 -0
  107. package/dist/shader.d.ts +3 -0
  108. package/dist/shader.d.ts.map +1 -0
  109. package/dist/shader.js +144 -0
  110. package/dist/shader.js.map +1 -0
  111. package/dist/shadow-fragment-wgsl.d.ts +13 -0
  112. package/dist/shadow-fragment-wgsl.d.ts.map +1 -0
  113. package/dist/shadow-fragment-wgsl.js +205 -0
  114. package/dist/shadow-fragment-wgsl.js.map +1 -0
  115. package/dist/shadow-manager.d.ts +46 -0
  116. package/dist/shadow-manager.d.ts.map +1 -0
  117. package/dist/shadow-manager.js +259 -0
  118. package/dist/shadow-manager.js.map +1 -0
  119. package/dist/shadow-pass.d.ts +31 -0
  120. package/dist/shadow-pass.d.ts.map +1 -0
  121. package/dist/shadow-pass.js +135 -0
  122. package/dist/shadow-pass.js.map +1 -0
  123. package/dist/shadow-shader.d.ts +10 -0
  124. package/dist/shadow-shader.d.ts.map +1 -0
  125. package/dist/shadow-shader.js +24 -0
  126. package/dist/shadow-shader.js.map +1 -0
  127. package/dist/shadow-uniforms.d.ts +38 -0
  128. package/dist/shadow-uniforms.d.ts.map +1 -0
  129. package/dist/shadow-uniforms.js +97 -0
  130. package/dist/shadow-uniforms.js.map +1 -0
  131. package/dist/skinned-geometry.d.ts +14 -0
  132. package/dist/skinned-geometry.d.ts.map +1 -0
  133. package/dist/skinned-geometry.js +23 -0
  134. package/dist/skinned-geometry.js.map +1 -0
  135. package/dist/skinned-mesh-renderer.d.ts +54 -0
  136. package/dist/skinned-mesh-renderer.d.ts.map +1 -0
  137. package/dist/skinned-mesh-renderer.js +177 -0
  138. package/dist/skinned-mesh-renderer.js.map +1 -0
  139. package/dist/skinned-pipeline.d.ts +16 -0
  140. package/dist/skinned-pipeline.d.ts.map +1 -0
  141. package/dist/skinned-pipeline.js +112 -0
  142. package/dist/skinned-pipeline.js.map +1 -0
  143. package/dist/skinned-shader.d.ts +7 -0
  144. package/dist/skinned-shader.d.ts.map +1 -0
  145. package/dist/skinned-shader.js +52 -0
  146. package/dist/skinned-shader.js.map +1 -0
  147. package/dist/skinned-shadow-shader.d.ts +6 -0
  148. package/dist/skinned-shadow-shader.d.ts.map +1 -0
  149. package/dist/skinned-shadow-shader.js +31 -0
  150. package/dist/skinned-shadow-shader.js.map +1 -0
  151. package/dist/spot-light.d.ts +24 -0
  152. package/dist/spot-light.d.ts.map +1 -0
  153. package/dist/spot-light.js +41 -0
  154. package/dist/spot-light.js.map +1 -0
  155. package/dist/spot-shadow-pass.d.ts +36 -0
  156. package/dist/spot-shadow-pass.d.ts.map +1 -0
  157. package/dist/spot-shadow-pass.js +144 -0
  158. package/dist/spot-shadow-pass.js.map +1 -0
  159. package/dist/ssao-pass.d.ts +37 -0
  160. package/dist/ssao-pass.d.ts.map +1 -0
  161. package/dist/ssao-pass.js +208 -0
  162. package/dist/ssao-pass.js.map +1 -0
  163. package/dist/ssao-shader.d.ts +9 -0
  164. package/dist/ssao-shader.d.ts.map +1 -0
  165. package/dist/ssao-shader.js +120 -0
  166. package/dist/ssao-shader.js.map +1 -0
  167. package/dist/terrain-mesh-renderer.d.ts +39 -0
  168. package/dist/terrain-mesh-renderer.d.ts.map +1 -0
  169. package/dist/terrain-mesh-renderer.js +131 -0
  170. package/dist/terrain-mesh-renderer.js.map +1 -0
  171. package/dist/terrain-pipeline.d.ts +17 -0
  172. package/dist/terrain-pipeline.d.ts.map +1 -0
  173. package/dist/terrain-pipeline.js +70 -0
  174. package/dist/terrain-pipeline.js.map +1 -0
  175. package/dist/terrain-shader.d.ts +10 -0
  176. package/dist/terrain-shader.d.ts.map +1 -0
  177. package/dist/terrain-shader.js +154 -0
  178. package/dist/terrain-shader.js.map +1 -0
  179. package/dist/texture.d.ts +20 -0
  180. package/dist/texture.d.ts.map +1 -0
  181. package/dist/texture.js +87 -0
  182. package/dist/texture.js.map +1 -0
  183. package/dist/tonemap-pass.d.ts +22 -0
  184. package/dist/tonemap-pass.d.ts.map +1 -0
  185. package/dist/tonemap-pass.js +125 -0
  186. package/dist/tonemap-pass.js.map +1 -0
  187. package/dist/unlit-pipeline.d.ts +12 -0
  188. package/dist/unlit-pipeline.d.ts.map +1 -0
  189. package/dist/unlit-pipeline.js +59 -0
  190. package/dist/unlit-pipeline.js.map +1 -0
  191. package/dist/unlit-shader.d.ts +3 -0
  192. package/dist/unlit-shader.d.ts.map +1 -0
  193. package/dist/unlit-shader.js +33 -0
  194. package/dist/unlit-shader.js.map +1 -0
  195. package/dist/webgpu-device.d.ts +13 -0
  196. package/dist/webgpu-device.d.ts.map +1 -0
  197. package/dist/webgpu-device.js +70 -0
  198. package/dist/webgpu-device.js.map +1 -0
  199. package/dist/wireframe-pipeline.d.ts +7 -0
  200. package/dist/wireframe-pipeline.d.ts.map +1 -0
  201. package/dist/wireframe-pipeline.js +72 -0
  202. package/dist/wireframe-pipeline.js.map +1 -0
  203. package/package.json +28 -0
  204. package/src/index.ts +87 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shadow-uniforms.js","sourceRoot":"","sources":["../src/shadow-uniforms.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAEvC,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC;AACtC,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC;AACxC,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC;AAEvC,sEAAsE;AACtE,MAAM,CAAC,MAAM,gBAAgB,GAAG,UAAU,CAAC;AAE3C,MAAM,UAAU,2BAA2B,CAAC,MAAiB;IAC3D,OAAO,MAAM,CAAC,qBAAqB,CAAC;QAClC,OAAO,EAAE;YACP,oBAAoB;YACpB,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE;YAChF,wBAAwB;YACxB,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE;YACpF,+BAA+B;YAC/B,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE;YACrF,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE;YACrF,+BAA+B;YAC/B,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE;YACrF,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE;YACrF,gCAAgC;YAChC,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,EAAE;YAC5G,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,EAAE;YAC5G,kCAAkC;YAClC,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE;YACrF,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE;YACrF,EAAE,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE;YACtF,EAAE,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE;SACvF;KACF,CAAC,CAAC;AACL,CAAC;AAUD,MAAM,UAAU,0BAA0B,CACxC,MAAiB,EACjB,MAA0B;IAE1B,MAAM,aAAa,GAAG,MAAM,CAAC,YAAY,CAAC;QACxC,IAAI,EAAE,mBAAmB;QACzB,KAAK,EAAE,cAAc,CAAC,OAAO,GAAG,cAAc,CAAC,QAAQ;KACxD,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,IAAI,WAAW,CAAC,mBAAmB,CAAC,CAAC;IAClD,MAAM,GAAG,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC;IAClC,wCAAwC;IACxC,MAAM,WAAW,GAAG,GAAG,GAAG,CAAC,CAAC;IAC5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE;QAAE,GAAG,CAAC,WAAW,GAAG,CAAC,CAAC,GAAG,gBAAgB,CAAC;IACrE,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,aAAa,EAAE,CAAC,EAAE,IAAkC,CAAC,CAAC;IAE/E,MAAM,KAAK,GAAG,MAAM,CAAC,aAAa,CAAC;QACjC,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;QACZ,MAAM,EAAE,cAAc;QACtB,KAAK,EAAE,eAAe,CAAC,eAAe,GAAG,eAAe,CAAC,iBAAiB;KAC3E,CAAC,CAAC;IACH,MAAM,WAAW,GAAG,KAAK,CAAC,UAAU,EAAE,CAAC;IAEvC,MAAM,OAAO,GAAG,MAAM,CAAC,aAAa,CAAC;QACnC,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACf,MAAM,EAAE,cAAc;QACtB,KAAK,EAAE,eAAe,CAAC,eAAe,GAAG,eAAe,CAAC,iBAAiB;KAC3E,CAAC,CAAC;IACH,MAAM,aAAa,GAAG,OAAO,CAAC,UAAU,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;IAEhE,MAAM,OAAO,GAAG,MAAM,CAAC,aAAa,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;IAE1D,MAAM,SAAS,GAAG,MAAM,CAAC,eAAe,CAAC;QACvC,MAAM;QACN,OAAO,EAAE;YACP,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,aAAa,EAAE,EAAE;YACnD,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE;YACjC,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE;YACrC,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE;YACrC,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE;YACrC,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE;YACrC,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,aAAa,EAAE;YACvC,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,aAAa,EAAE;YACvC,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE;YACrC,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE;YACrC,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE;YACtC,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE;SACvC;KACF,CAAC,CAAC;IAEH,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;AAC3E,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Skinned vertex format constants.
3
+ * Layout: position(3) + normal(3) + uv(2) + joints_u16x4(2) + weights_f32x4(4) = 14 floats = 56 bytes
4
+ *
5
+ * Joints are packed as 4 × u16 (8 bytes at byte offset 32).
6
+ * Weights are 4 × f32 (16 bytes at byte offset 40).
7
+ */
8
+ /** Floats per skinned vertex: 3 + 3 + 2 + 2(u16x4 packed) + 4 = 14 */
9
+ export declare const SKINNED_VERTEX_STRIDE_FLOATS = 14;
10
+ /** Bytes per skinned vertex */
11
+ export declare const SKINNED_VERTEX_STRIDE_BYTES = 56;
12
+ /** GPU vertex buffer layout for skinned meshes. */
13
+ export declare const SKINNED_VERTEX_BUFFER_LAYOUT: GPUVertexBufferLayout;
14
+ //# sourceMappingURL=skinned-geometry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skinned-geometry.d.ts","sourceRoot":"","sources":["../src/skinned-geometry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,sEAAsE;AACtE,eAAO,MAAM,4BAA4B,KAAK,CAAC;AAE/C,+BAA+B;AAC/B,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAE9C,mDAAmD;AACnD,eAAO,MAAM,4BAA4B,EAAE,qBAS1C,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Skinned vertex format constants.
3
+ * Layout: position(3) + normal(3) + uv(2) + joints_u16x4(2) + weights_f32x4(4) = 14 floats = 56 bytes
4
+ *
5
+ * Joints are packed as 4 × u16 (8 bytes at byte offset 32).
6
+ * Weights are 4 × f32 (16 bytes at byte offset 40).
7
+ */
8
+ /** Floats per skinned vertex: 3 + 3 + 2 + 2(u16x4 packed) + 4 = 14 */
9
+ export const SKINNED_VERTEX_STRIDE_FLOATS = 14;
10
+ /** Bytes per skinned vertex */
11
+ export const SKINNED_VERTEX_STRIDE_BYTES = 56;
12
+ /** GPU vertex buffer layout for skinned meshes. */
13
+ export const SKINNED_VERTEX_BUFFER_LAYOUT = {
14
+ arrayStride: SKINNED_VERTEX_STRIDE_BYTES,
15
+ attributes: [
16
+ { shaderLocation: 0, offset: 0, format: 'float32x3' }, // position
17
+ { shaderLocation: 1, offset: 12, format: 'float32x3' }, // normal
18
+ { shaderLocation: 2, offset: 24, format: 'float32x2' }, // uv
19
+ { shaderLocation: 3, offset: 32, format: 'uint16x4' }, // joint indices (u16x4)
20
+ { shaderLocation: 4, offset: 40, format: 'float32x4' }, // joint weights
21
+ ],
22
+ };
23
+ //# sourceMappingURL=skinned-geometry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skinned-geometry.js","sourceRoot":"","sources":["../src/skinned-geometry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,sEAAsE;AACtE,MAAM,CAAC,MAAM,4BAA4B,GAAG,EAAE,CAAC;AAE/C,+BAA+B;AAC/B,MAAM,CAAC,MAAM,2BAA2B,GAAG,EAAE,CAAC;AAE9C,mDAAmD;AACnD,MAAM,CAAC,MAAM,4BAA4B,GAA0B;IACjE,WAAW,EAAE,2BAA2B;IACxC,UAAU,EAAE;QACV,EAAE,cAAc,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,EAAI,WAAW;QACpE,EAAE,cAAc,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,EAAI,SAAS;QACnE,EAAE,cAAc,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,EAAI,KAAK;QAC/D,EAAE,cAAc,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,EAAK,wBAAwB;QAClF,EAAE,cAAc,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,EAAI,gBAAgB;KAC3E;CACF,CAAC"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * SkinnedMeshRenderer: renders a mesh with GPU skinning.
3
+ * Same pattern as MeshRenderer but adds a bone storage buffer (group 3).
4
+ */
5
+ import { Component } from '@certe/atmos-core';
6
+ import type { Mat4Type } from '@certe/atmos-math';
7
+ import type { Mesh } from './mesh.js';
8
+ import type { SkinnedPipelineResources } from './skinned-pipeline.js';
9
+ import type { Material } from './material.js';
10
+ import type { BoundingSphere } from './bounds.js';
11
+ /** Minimal context for SkinnedMeshRenderer — satisfied by RenderSystem via duck typing. */
12
+ export interface SkinnedRendererContext {
13
+ readonly device: GPUDevice;
14
+ readonly skinnedPipelineResources: SkinnedPipelineResources;
15
+ }
16
+ export declare class SkinnedMeshRenderer extends Component {
17
+ mesh: Mesh | null;
18
+ material: Material | null;
19
+ meshSource: string;
20
+ materialSource: string;
21
+ castShadow: boolean;
22
+ jointCount: number;
23
+ uniformBuffer: GPUBuffer | null;
24
+ bindGroup: GPUBindGroup | null;
25
+ materialBindGroup: GPUBindGroup | null;
26
+ /** Storage buffer for bone matrices (jointCount * 64 bytes). */
27
+ boneBuffer: GPUBuffer | null;
28
+ /** Bind group for group 3 (bone matrices). */
29
+ boneBindGroup: GPUBindGroup | null;
30
+ /** Shadow bone bind group (group 2 in shadow pipeline). */
31
+ shadowBoneBindGroup: GPUBindGroup | null;
32
+ private _device;
33
+ private _pipelineResources;
34
+ private readonly _mvp;
35
+ private readonly _invModel;
36
+ private readonly _normalMat;
37
+ private readonly _matData;
38
+ private _lastTextureVersion;
39
+ private readonly _worldBoundsCenter;
40
+ private readonly _worldBounds;
41
+ init(ctx: SkinnedRendererContext, mesh: Mesh, jointCount: number, material?: Material): void;
42
+ initMaterialBindGroup(sceneBuffer: GPUBuffer): void;
43
+ /**
44
+ * Write bone matrices from the sibling AnimationMixer component.
45
+ * Call this after AnimationMixer.onUpdate() has run.
46
+ */
47
+ writeBoneMatrices(boneMatrices: Float32Array): void;
48
+ writeUniforms(viewProjection: Mat4Type): void;
49
+ draw(pass: GPURenderPassEncoder, shadowBindGroup?: GPUBindGroup): void;
50
+ get worldBoundingSphere(): BoundingSphere | null;
51
+ onDestroy(): void;
52
+ destroyMesh(): void;
53
+ }
54
+ //# sourceMappingURL=skinned-mesh-renderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skinned-mesh-renderer.d.ts","sourceRoot":"","sources":["../src/skinned-mesh-renderer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAE9C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACtE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD,2FAA2F;AAC3F,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,wBAAwB,EAAE,wBAAwB,CAAC;CAC7D;AAID,qBAAa,mBAAoB,SAAQ,SAAS;IAChD,IAAI,EAAE,IAAI,GAAG,IAAI,CAAQ;IACzB,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAQ;IACjC,UAAU,SAAM;IAChB,cAAc,SAAa;IAC3B,UAAU,UAAQ;IAClB,UAAU,SAAK;IAEf,aAAa,EAAE,SAAS,GAAG,IAAI,CAAQ;IACvC,SAAS,EAAE,YAAY,GAAG,IAAI,CAAQ;IACtC,iBAAiB,EAAE,YAAY,GAAG,IAAI,CAAQ;IAE9C,gEAAgE;IAChE,UAAU,EAAE,SAAS,GAAG,IAAI,CAAQ;IACpC,8CAA8C;IAC9C,aAAa,EAAE,YAAY,GAAG,IAAI,CAAQ;IAC1C,2DAA2D;IAC3D,mBAAmB,EAAE,YAAY,GAAG,IAAI,CAAQ;IAEhD,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,kBAAkB,CAAyC;IAEnE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA2B;IAChD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA2B;IACrD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA2B;IACtD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA+C;IACxE,OAAO,CAAC,mBAAmB,CAAM;IAEjC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAuB;IAC1D,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAkE;IAE/F,IAAI,CACF,GAAG,EAAE,sBAAsB,EAC3B,IAAI,EAAE,IAAI,EACV,UAAU,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,QAAQ,GAClB,IAAI;IA0CP,qBAAqB,CAAC,WAAW,EAAE,SAAS,GAAG,IAAI;IA8BnD;;;OAGG;IACH,iBAAiB,CAAC,YAAY,EAAE,YAAY,GAAG,IAAI;IAKnD,aAAa,CAAC,cAAc,EAAE,QAAQ,GAAG,IAAI;IAwB7C,IAAI,CAAC,IAAI,EAAE,oBAAoB,EAAE,eAAe,CAAC,EAAE,YAAY,GAAG,IAAI;IAYtE,IAAI,mBAAmB,IAAI,cAAc,GAAG,IAAI,CAkB/C;IAED,SAAS,IAAI,IAAI;IAWjB,WAAW,IAAI,IAAI;CAOpB"}
@@ -0,0 +1,177 @@
1
+ /**
2
+ * SkinnedMeshRenderer: renders a mesh with GPU skinning.
3
+ * Same pattern as MeshRenderer but adds a bone storage buffer (group 3).
4
+ */
5
+ import { Component } from '@certe/atmos-core';
6
+ import { Mat4 } from '@certe/atmos-math';
7
+ import { writeMaterialUniforms, MATERIAL_UNIFORM_SIZE } from './material.js';
8
+ import { getWhiteFallbackTexture, getFlatNormalFallback, getDefaultMetallicRoughnessFallback } from './texture.js';
9
+ const OBJECT_UNIFORM_SIZE = 192;
10
+ export class SkinnedMeshRenderer extends Component {
11
+ mesh = null;
12
+ material = null;
13
+ meshSource = '';
14
+ materialSource = 'Default';
15
+ castShadow = true;
16
+ jointCount = 0;
17
+ uniformBuffer = null;
18
+ bindGroup = null;
19
+ materialBindGroup = null;
20
+ /** Storage buffer for bone matrices (jointCount * 64 bytes). */
21
+ boneBuffer = null;
22
+ /** Bind group for group 3 (bone matrices). */
23
+ boneBindGroup = null;
24
+ /** Shadow bone bind group (group 2 in shadow pipeline). */
25
+ shadowBoneBindGroup = null;
26
+ _device = null;
27
+ _pipelineResources = null;
28
+ _mvp = Mat4.create();
29
+ _invModel = Mat4.create();
30
+ _normalMat = Mat4.create();
31
+ _matData = new Float32Array(MATERIAL_UNIFORM_SIZE / 4);
32
+ _lastTextureVersion = -1;
33
+ _worldBoundsCenter = new Float32Array(3);
34
+ _worldBounds = { center: this._worldBoundsCenter, radius: 0 };
35
+ init(ctx, mesh, jointCount, material) {
36
+ const { device, skinnedPipelineResources: pipelineResources } = ctx;
37
+ this._device = device;
38
+ this._pipelineResources = pipelineResources;
39
+ this.mesh = mesh;
40
+ this.jointCount = jointCount;
41
+ this.material = material ?? null;
42
+ this.uniformBuffer = device.createBuffer({
43
+ size: OBJECT_UNIFORM_SIZE,
44
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
45
+ });
46
+ this.bindGroup = device.createBindGroup({
47
+ layout: pipelineResources.objectBindGroupLayout,
48
+ entries: [
49
+ { binding: 0, resource: { buffer: this.uniformBuffer } },
50
+ ],
51
+ });
52
+ // Bone storage buffer
53
+ const boneBufferSize = Math.max(jointCount, 1) * 64;
54
+ this.boneBuffer = device.createBuffer({
55
+ size: boneBufferSize,
56
+ usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,
57
+ });
58
+ this.boneBindGroup = device.createBindGroup({
59
+ layout: pipelineResources.boneBindGroupLayout,
60
+ entries: [
61
+ { binding: 0, resource: { buffer: this.boneBuffer } },
62
+ ],
63
+ });
64
+ this.shadowBoneBindGroup = device.createBindGroup({
65
+ layout: pipelineResources.shadowBoneBGL,
66
+ entries: [
67
+ { binding: 0, resource: { buffer: this.boneBuffer } },
68
+ ],
69
+ });
70
+ }
71
+ initMaterialBindGroup(sceneBuffer) {
72
+ if (!this._device || !this._pipelineResources || !this.material)
73
+ return;
74
+ if (this.materialBindGroup)
75
+ return;
76
+ if (!this.material.uniformBuffer) {
77
+ this.material.uniformBuffer = this._device.createBuffer({
78
+ size: MATERIAL_UNIFORM_SIZE,
79
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
80
+ });
81
+ this.material.dirty = true;
82
+ }
83
+ const tex = this.material.albedoTexture ?? getWhiteFallbackTexture(this._device);
84
+ const nrm = this.material.normalTexture ?? getFlatNormalFallback(this._device);
85
+ const mr = this.material.metallicRoughnessTexture ?? getDefaultMetallicRoughnessFallback(this._device);
86
+ this.materialBindGroup = this._device.createBindGroup({
87
+ layout: this._pipelineResources.materialBindGroupLayout,
88
+ entries: [
89
+ { binding: 0, resource: { buffer: this.material.uniformBuffer } },
90
+ { binding: 1, resource: { buffer: sceneBuffer } },
91
+ { binding: 2, resource: tex.view },
92
+ { binding: 3, resource: tex.sampler },
93
+ { binding: 4, resource: nrm.view },
94
+ { binding: 5, resource: nrm.sampler },
95
+ { binding: 6, resource: mr.view },
96
+ { binding: 7, resource: mr.sampler },
97
+ ],
98
+ });
99
+ }
100
+ /**
101
+ * Write bone matrices from the sibling AnimationMixer component.
102
+ * Call this after AnimationMixer.onUpdate() has run.
103
+ */
104
+ writeBoneMatrices(boneMatrices) {
105
+ if (!this._device || !this.boneBuffer)
106
+ return;
107
+ this._device.queue.writeBuffer(this.boneBuffer, 0, boneMatrices);
108
+ }
109
+ writeUniforms(viewProjection) {
110
+ if (!this._device || !this.uniformBuffer)
111
+ return;
112
+ const model = this.gameObject.transform.worldMatrix;
113
+ Mat4.multiply(this._mvp, viewProjection, model);
114
+ Mat4.invert(this._invModel, model);
115
+ Mat4.transpose(this._normalMat, this._invModel);
116
+ this._device.queue.writeBuffer(this.uniformBuffer, 0, this._mvp);
117
+ this._device.queue.writeBuffer(this.uniformBuffer, 64, model);
118
+ this._device.queue.writeBuffer(this.uniformBuffer, 128, this._normalMat);
119
+ if (this.material && this.material.textureVersion !== this._lastTextureVersion) {
120
+ this._lastTextureVersion = this.material.textureVersion;
121
+ this.materialBindGroup = null;
122
+ }
123
+ if (this.material?.dirty && this.material.uniformBuffer) {
124
+ writeMaterialUniforms(this._matData, this.material);
125
+ this._device.queue.writeBuffer(this.material.uniformBuffer, 0, this._matData);
126
+ this.material.dirty = false;
127
+ }
128
+ }
129
+ draw(pass, shadowBindGroup) {
130
+ if (!this.mesh || !this.bindGroup || !this._pipelineResources || !this.materialBindGroup || !this.boneBindGroup)
131
+ return;
132
+ pass.setPipeline(this._pipelineResources.pipeline);
133
+ pass.setBindGroup(0, this.bindGroup);
134
+ pass.setBindGroup(1, this.materialBindGroup);
135
+ if (shadowBindGroup)
136
+ pass.setBindGroup(2, shadowBindGroup);
137
+ pass.setBindGroup(3, this.boneBindGroup);
138
+ pass.setVertexBuffer(0, this.mesh.vertexBuffer);
139
+ pass.setIndexBuffer(this.mesh.indexBuffer, this.mesh.indexFormat);
140
+ pass.drawIndexed(this.mesh.indexCount);
141
+ }
142
+ get worldBoundingSphere() {
143
+ const bounds = this.mesh?.bounds;
144
+ if (!bounds)
145
+ return null;
146
+ const model = this.gameObject.transform.worldMatrix;
147
+ const cx = bounds.center[0];
148
+ const cy = bounds.center[1];
149
+ const cz = bounds.center[2];
150
+ this._worldBoundsCenter[0] = model[0] * cx + model[4] * cy + model[8] * cz + model[12];
151
+ this._worldBoundsCenter[1] = model[1] * cx + model[5] * cy + model[9] * cz + model[13];
152
+ this._worldBoundsCenter[2] = model[2] * cx + model[6] * cy + model[10] * cz + model[14];
153
+ const sx = Math.sqrt(model[0] * model[0] + model[1] * model[1] + model[2] * model[2]);
154
+ const sy = Math.sqrt(model[4] * model[4] + model[5] * model[5] + model[6] * model[6]);
155
+ const sz = Math.sqrt(model[8] * model[8] + model[9] * model[9] + model[10] * model[10]);
156
+ this._worldBounds.radius = bounds.radius * Math.max(sx, sy, sz);
157
+ return this._worldBounds;
158
+ }
159
+ onDestroy() {
160
+ this.uniformBuffer?.destroy();
161
+ this.boneBuffer?.destroy();
162
+ this.uniformBuffer = null;
163
+ this.boneBuffer = null;
164
+ this.bindGroup = null;
165
+ this.materialBindGroup = null;
166
+ this.boneBindGroup = null;
167
+ this.shadowBoneBindGroup = null;
168
+ }
169
+ destroyMesh() {
170
+ if (this.mesh) {
171
+ this.mesh.vertexBuffer.destroy();
172
+ this.mesh.indexBuffer.destroy();
173
+ this.mesh = null;
174
+ }
175
+ }
176
+ }
177
+ //# sourceMappingURL=skinned-mesh-renderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skinned-mesh-renderer.js","sourceRoot":"","sources":["../src/skinned-mesh-renderer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Skinned PBR render pipeline.
3
+ * Same bind groups 0-2 as the regular PBR pipeline, plus group 3 for bone matrices (storage buffer).
4
+ */
5
+ export interface SkinnedPipelineResources {
6
+ pipeline: GPURenderPipeline;
7
+ objectBindGroupLayout: GPUBindGroupLayout;
8
+ materialBindGroupLayout: GPUBindGroupLayout;
9
+ shadowBindGroupLayout: GPUBindGroupLayout;
10
+ boneBindGroupLayout: GPUBindGroupLayout;
11
+ /** Shadow pipeline for skinned meshes (depth-only with skinning). */
12
+ shadowPipeline: GPURenderPipeline;
13
+ shadowBoneBGL: GPUBindGroupLayout;
14
+ }
15
+ export declare function createSkinnedPBRPipeline(device: GPUDevice, _format: GPUTextureFormat): SkinnedPipelineResources;
16
+ //# sourceMappingURL=skinned-pipeline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skinned-pipeline.d.ts","sourceRoot":"","sources":["../src/skinned-pipeline.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,qBAAqB,EAAE,kBAAkB,CAAC;IAC1C,uBAAuB,EAAE,kBAAkB,CAAC;IAC5C,qBAAqB,EAAE,kBAAkB,CAAC;IAC1C,mBAAmB,EAAE,kBAAkB,CAAC;IACxC,qEAAqE;IACrE,cAAc,EAAE,iBAAiB,CAAC;IAClC,aAAa,EAAE,kBAAkB,CAAC;CACnC;AAED,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,gBAAgB,GACxB,wBAAwB,CAgH1B"}
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Skinned PBR render pipeline.
3
+ * Same bind groups 0-2 as the regular PBR pipeline, plus group 3 for bone matrices (storage buffer).
4
+ */
5
+ import { SKINNED_VERTEX_SHADER } from './skinned-shader.js';
6
+ import { FRAGMENT_SHADER } from './shader.js';
7
+ import { SKINNED_VERTEX_BUFFER_LAYOUT, SKINNED_VERTEX_STRIDE_BYTES } from './skinned-geometry.js';
8
+ import { SKINNED_SHADOW_VERTEX_SHADER } from './skinned-shadow-shader.js';
9
+ import { createShadowBindGroupLayout } from './shadow-uniforms.js';
10
+ import { HDR_FORMAT, MSAA_SAMPLE_COUNT } from './pipeline.js';
11
+ export function createSkinnedPBRPipeline(device, _format) {
12
+ const vertexModule = device.createShaderModule({ code: SKINNED_VERTEX_SHADER });
13
+ const fragmentModule = device.createShaderModule({ code: FRAGMENT_SHADER });
14
+ // Group 0: per-object uniforms (same as regular pipeline)
15
+ const objectBindGroupLayout = device.createBindGroupLayout({
16
+ entries: [
17
+ { binding: 0, visibility: GPUShaderStage.VERTEX, buffer: { type: 'uniform' } },
18
+ ],
19
+ });
20
+ // Group 1: material + scene (same as regular pipeline)
21
+ const materialBindGroupLayout = device.createBindGroupLayout({
22
+ entries: [
23
+ { binding: 0, visibility: GPUShaderStage.FRAGMENT, buffer: { type: 'uniform' } },
24
+ { binding: 1, visibility: GPUShaderStage.FRAGMENT, buffer: { type: 'uniform' } },
25
+ { binding: 2, visibility: GPUShaderStage.FRAGMENT, texture: { sampleType: 'float' } },
26
+ { binding: 3, visibility: GPUShaderStage.FRAGMENT, sampler: { type: 'filtering' } },
27
+ { binding: 4, visibility: GPUShaderStage.FRAGMENT, texture: { sampleType: 'float' } },
28
+ { binding: 5, visibility: GPUShaderStage.FRAGMENT, sampler: { type: 'filtering' } },
29
+ { binding: 6, visibility: GPUShaderStage.FRAGMENT, texture: { sampleType: 'float' } },
30
+ { binding: 7, visibility: GPUShaderStage.FRAGMENT, sampler: { type: 'filtering' } },
31
+ ],
32
+ });
33
+ // Group 2: shadows
34
+ const shadowBindGroupLayout = createShadowBindGroupLayout(device);
35
+ // Group 3: bone matrices (storage buffer, vertex stage)
36
+ const boneBindGroupLayout = device.createBindGroupLayout({
37
+ entries: [
38
+ { binding: 0, visibility: GPUShaderStage.VERTEX, buffer: { type: 'read-only-storage' } },
39
+ ],
40
+ });
41
+ const pipelineLayout = device.createPipelineLayout({
42
+ bindGroupLayouts: [objectBindGroupLayout, materialBindGroupLayout, shadowBindGroupLayout, boneBindGroupLayout],
43
+ });
44
+ const pipeline = device.createRenderPipeline({
45
+ layout: pipelineLayout,
46
+ vertex: {
47
+ module: vertexModule,
48
+ entryPoint: 'main',
49
+ buffers: [SKINNED_VERTEX_BUFFER_LAYOUT],
50
+ },
51
+ fragment: {
52
+ module: fragmentModule,
53
+ entryPoint: 'main',
54
+ targets: [{ format: HDR_FORMAT }],
55
+ },
56
+ multisample: { count: MSAA_SAMPLE_COUNT },
57
+ primitive: { topology: 'triangle-list', cullMode: 'back' },
58
+ depthStencil: {
59
+ depthWriteEnabled: true,
60
+ depthCompare: 'less',
61
+ format: 'depth24plus',
62
+ },
63
+ });
64
+ // --- Skinned shadow pipeline ---
65
+ const shadowShaderModule = device.createShaderModule({ code: SKINNED_SHADOW_VERTEX_SHADER });
66
+ const shadowLightVPBGL = device.createBindGroupLayout({
67
+ entries: [
68
+ { binding: 0, visibility: GPUShaderStage.VERTEX, buffer: { type: 'uniform' } },
69
+ ],
70
+ });
71
+ const shadowBoneBGL = device.createBindGroupLayout({
72
+ entries: [
73
+ { binding: 0, visibility: GPUShaderStage.VERTEX, buffer: { type: 'read-only-storage' } },
74
+ ],
75
+ });
76
+ const shadowPipelineLayout = device.createPipelineLayout({
77
+ bindGroupLayouts: [objectBindGroupLayout, shadowLightVPBGL, shadowBoneBGL],
78
+ });
79
+ const shadowPipeline = device.createRenderPipeline({
80
+ layout: shadowPipelineLayout,
81
+ vertex: {
82
+ module: shadowShaderModule,
83
+ entryPoint: 'main',
84
+ buffers: [{
85
+ arrayStride: SKINNED_VERTEX_STRIDE_BYTES,
86
+ attributes: [
87
+ { shaderLocation: 0, offset: 0, format: 'float32x3' }, // position
88
+ { shaderLocation: 3, offset: 32, format: 'uint16x4' }, // joints
89
+ { shaderLocation: 4, offset: 40, format: 'float32x4' }, // weights
90
+ ],
91
+ }],
92
+ },
93
+ primitive: { topology: 'triangle-list', cullMode: 'back' },
94
+ depthStencil: {
95
+ depthWriteEnabled: true,
96
+ depthCompare: 'less',
97
+ format: 'depth32float',
98
+ depthBias: 2,
99
+ depthBiasSlopeScale: 2.0,
100
+ },
101
+ });
102
+ return {
103
+ pipeline,
104
+ objectBindGroupLayout,
105
+ materialBindGroupLayout,
106
+ shadowBindGroupLayout,
107
+ boneBindGroupLayout,
108
+ shadowPipeline,
109
+ shadowBoneBGL,
110
+ };
111
+ }
112
+ //# sourceMappingURL=skinned-pipeline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skinned-pipeline.js","sourceRoot":"","sources":["../src/skinned-pipeline.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Skinned PBR vertex shader.
3
+ * Reads bone matrices from a storage buffer (group 3) and applies GPU skinning.
4
+ * Outputs the same VertexOutput as the regular PBR shader, so the FRAGMENT_SHADER is reused.
5
+ */
6
+ export declare const SKINNED_VERTEX_SHADER = "\nstruct ObjectUniforms {\n mvp: mat4x4<f32>,\n model: mat4x4<f32>,\n normalMatrix: mat4x4<f32>,\n};\n\n@group(0) @binding(0) var<uniform> object: ObjectUniforms;\n@group(3) @binding(0) var<storage, read> boneMatrices: array<mat4x4<f32>>;\n\nstruct VertexInput {\n @location(0) position: vec3<f32>,\n @location(1) normal: vec3<f32>,\n @location(2) uv: vec2<f32>,\n @location(3) joints: vec4<u32>,\n @location(4) weights: vec4<f32>,\n};\n\nstruct VertexOutput {\n @builtin(position) clipPosition: vec4<f32>,\n @location(0) worldPosition: vec3<f32>,\n @location(1) worldNormal: vec3<f32>,\n @location(2) uv: vec2<f32>,\n};\n\n@vertex\nfn main(input: VertexInput) -> VertexOutput {\n // Compute skin matrix from bone weights\n let skin = boneMatrices[input.joints.x] * input.weights.x\n + boneMatrices[input.joints.y] * input.weights.y\n + boneMatrices[input.joints.z] * input.weights.z\n + boneMatrices[input.joints.w] * input.weights.w;\n\n let skinnedPos = skin * vec4<f32>(input.position, 1.0);\n let skinnedNormal = (skin * vec4<f32>(input.normal, 0.0)).xyz;\n\n let worldPos = object.model * skinnedPos;\n\n var output: VertexOutput;\n output.clipPosition = object.mvp * skinnedPos;\n output.worldPosition = worldPos.xyz;\n output.worldNormal = (object.normalMatrix * vec4<f32>(skinnedNormal, 0.0)).xyz;\n output.uv = input.uv;\n return output;\n}\n";
7
+ //# sourceMappingURL=skinned-shader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skinned-shader.d.ts","sourceRoot":"","sources":["../src/skinned-shader.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,eAAO,MAAM,qBAAqB,k4CA6CjC,CAAC"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Skinned PBR vertex shader.
3
+ * Reads bone matrices from a storage buffer (group 3) and applies GPU skinning.
4
+ * Outputs the same VertexOutput as the regular PBR shader, so the FRAGMENT_SHADER is reused.
5
+ */
6
+ export const SKINNED_VERTEX_SHADER = /* wgsl */ `
7
+ struct ObjectUniforms {
8
+ mvp: mat4x4<f32>,
9
+ model: mat4x4<f32>,
10
+ normalMatrix: mat4x4<f32>,
11
+ };
12
+
13
+ @group(0) @binding(0) var<uniform> object: ObjectUniforms;
14
+ @group(3) @binding(0) var<storage, read> boneMatrices: array<mat4x4<f32>>;
15
+
16
+ struct VertexInput {
17
+ @location(0) position: vec3<f32>,
18
+ @location(1) normal: vec3<f32>,
19
+ @location(2) uv: vec2<f32>,
20
+ @location(3) joints: vec4<u32>,
21
+ @location(4) weights: vec4<f32>,
22
+ };
23
+
24
+ struct VertexOutput {
25
+ @builtin(position) clipPosition: vec4<f32>,
26
+ @location(0) worldPosition: vec3<f32>,
27
+ @location(1) worldNormal: vec3<f32>,
28
+ @location(2) uv: vec2<f32>,
29
+ };
30
+
31
+ @vertex
32
+ fn main(input: VertexInput) -> VertexOutput {
33
+ // Compute skin matrix from bone weights
34
+ let skin = boneMatrices[input.joints.x] * input.weights.x
35
+ + boneMatrices[input.joints.y] * input.weights.y
36
+ + boneMatrices[input.joints.z] * input.weights.z
37
+ + boneMatrices[input.joints.w] * input.weights.w;
38
+
39
+ let skinnedPos = skin * vec4<f32>(input.position, 1.0);
40
+ let skinnedNormal = (skin * vec4<f32>(input.normal, 0.0)).xyz;
41
+
42
+ let worldPos = object.model * skinnedPos;
43
+
44
+ var output: VertexOutput;
45
+ output.clipPosition = object.mvp * skinnedPos;
46
+ output.worldPosition = worldPos.xyz;
47
+ output.worldNormal = (object.normalMatrix * vec4<f32>(skinnedNormal, 0.0)).xyz;
48
+ output.uv = input.uv;
49
+ return output;
50
+ }
51
+ `;
52
+ //# sourceMappingURL=skinned-shader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skinned-shader.js","sourceRoot":"","sources":["../src/skinned-shader.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,CAAC,MAAM,qBAAqB,GAAG,UAAU,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6C9C,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Depth-only vertex shader for skinned shadow passes.
3
+ * Applies bone skinning before the lightVP transform. No fragment shader (depth-only).
4
+ */
5
+ export declare const SKINNED_SHADOW_VERTEX_SHADER = "\nstruct ObjectUniforms {\n mvp: mat4x4<f32>,\n model: mat4x4<f32>,\n normalMatrix: mat4x4<f32>,\n};\n\n@group(0) @binding(0) var<uniform> object: ObjectUniforms;\n@group(1) @binding(0) var<uniform> lightVP: mat4x4<f32>;\n@group(2) @binding(0) var<storage, read> boneMatrices: array<mat4x4<f32>>;\n\n@vertex\nfn main(\n @location(0) position: vec3<f32>,\n @location(3) joints: vec4<u32>,\n @location(4) weights: vec4<f32>,\n) -> @builtin(position) vec4<f32> {\n let skin = boneMatrices[joints.x] * weights.x\n + boneMatrices[joints.y] * weights.y\n + boneMatrices[joints.z] * weights.z\n + boneMatrices[joints.w] * weights.w;\n\n let skinnedPos = skin * vec4<f32>(position, 1.0);\n return lightVP * object.model * skinnedPos;\n}\n";
6
+ //# sourceMappingURL=skinned-shadow-shader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skinned-shadow-shader.d.ts","sourceRoot":"","sources":["../src/skinned-shadow-shader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,4BAA4B,swBAyBxC,CAAC"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Depth-only vertex shader for skinned shadow passes.
3
+ * Applies bone skinning before the lightVP transform. No fragment shader (depth-only).
4
+ */
5
+ export const SKINNED_SHADOW_VERTEX_SHADER = /* wgsl */ `
6
+ struct ObjectUniforms {
7
+ mvp: mat4x4<f32>,
8
+ model: mat4x4<f32>,
9
+ normalMatrix: mat4x4<f32>,
10
+ };
11
+
12
+ @group(0) @binding(0) var<uniform> object: ObjectUniforms;
13
+ @group(1) @binding(0) var<uniform> lightVP: mat4x4<f32>;
14
+ @group(2) @binding(0) var<storage, read> boneMatrices: array<mat4x4<f32>>;
15
+
16
+ @vertex
17
+ fn main(
18
+ @location(0) position: vec3<f32>,
19
+ @location(3) joints: vec4<u32>,
20
+ @location(4) weights: vec4<f32>,
21
+ ) -> @builtin(position) vec4<f32> {
22
+ let skin = boneMatrices[joints.x] * weights.x
23
+ + boneMatrices[joints.y] * weights.y
24
+ + boneMatrices[joints.z] * weights.z
25
+ + boneMatrices[joints.w] * weights.w;
26
+
27
+ let skinnedPos = skin * vec4<f32>(position, 1.0);
28
+ return lightVP * object.model * skinnedPos;
29
+ }
30
+ `;
31
+ //# sourceMappingURL=skinned-shadow-shader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skinned-shadow-shader.js","sourceRoot":"","sources":["../src/skinned-shadow-shader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,CAAC,MAAM,4BAA4B,GAAG,UAAU,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;CAyBrD,CAAC"}
@@ -0,0 +1,24 @@
1
+ import { Component } from '@certe/atmos-core';
2
+ /**
3
+ * Spot light component.
4
+ * Position is derived from Transform's world position (worldMatrix[12..14]).
5
+ * Direction is derived from Transform's forward vector (-Z in world space).
6
+ * innerAngle / outerAngle are half-angles in radians (max outerAngle = 60deg = 120deg full cone).
7
+ */
8
+ export declare class SpotLight extends Component {
9
+ color: Float32Array<ArrayBuffer>;
10
+ intensity: number;
11
+ range: number;
12
+ /** Half-angle of the inner (full-brightness) cone in radians. Default ~25deg. */
13
+ innerAngle: number;
14
+ /** Half-angle of the outer (falloff) cone in radians. Default ~35deg, max 60deg. */
15
+ outerAngle: number;
16
+ castShadows: boolean;
17
+ shadowIntensity: number;
18
+ shadowResolution: number;
19
+ /** Extract world position into `out`. */
20
+ getWorldPosition(out: Float32Array): Float32Array;
21
+ /** Extract world direction (negated Z column of worldMatrix, normalized) into `out`. */
22
+ getWorldDirection(out: Float32Array): Float32Array;
23
+ }
24
+ //# sourceMappingURL=spot-light.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spot-light.d.ts","sourceRoot":"","sources":["../src/spot-light.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAE9C;;;;;GAKG;AACH,qBAAa,SAAU,SAAQ,SAAS;IACtC,KAAK,4BAA+B;IACpC,SAAS,SAAO;IAChB,KAAK,SAAQ;IACb,iFAAiF;IACjF,UAAU,SAAsB;IAChC,oFAAoF;IACpF,UAAU,SAAsB;IAChC,WAAW,UAAS;IACpB,eAAe,SAAO;IACtB,gBAAgB,SAAQ;IAExB,yCAAyC;IACzC,gBAAgB,CAAC,GAAG,EAAE,YAAY,GAAG,YAAY;IAQjD,wFAAwF;IACxF,iBAAiB,CAAC,GAAG,EAAE,YAAY,GAAG,YAAY;CAYnD"}
@@ -0,0 +1,41 @@
1
+ import { Component } from '@certe/atmos-core';
2
+ /**
3
+ * Spot light component.
4
+ * Position is derived from Transform's world position (worldMatrix[12..14]).
5
+ * Direction is derived from Transform's forward vector (-Z in world space).
6
+ * innerAngle / outerAngle are half-angles in radians (max outerAngle = 60deg = 120deg full cone).
7
+ */
8
+ export class SpotLight extends Component {
9
+ color = new Float32Array([1, 1, 1]);
10
+ intensity = 1.0;
11
+ range = 10.0;
12
+ /** Half-angle of the inner (full-brightness) cone in radians. Default ~25deg. */
13
+ innerAngle = 25 * Math.PI / 180;
14
+ /** Half-angle of the outer (falloff) cone in radians. Default ~35deg, max 60deg. */
15
+ outerAngle = 35 * Math.PI / 180;
16
+ castShadows = false;
17
+ shadowIntensity = 1.0;
18
+ shadowResolution = 1024;
19
+ /** Extract world position into `out`. */
20
+ getWorldPosition(out) {
21
+ const m = this.gameObject.transform.worldMatrix;
22
+ out[0] = m[12];
23
+ out[1] = m[13];
24
+ out[2] = m[14];
25
+ return out;
26
+ }
27
+ /** Extract world direction (negated Z column of worldMatrix, normalized) into `out`. */
28
+ getWorldDirection(out) {
29
+ const m = this.gameObject.transform.worldMatrix;
30
+ let x = m[8];
31
+ let y = m[9];
32
+ let z = m[10];
33
+ const len = Math.sqrt(x * x + y * y + z * z);
34
+ const inv = len > 0 ? 1 / len : 0;
35
+ out[0] = -x * inv;
36
+ out[1] = -y * inv;
37
+ out[2] = -z * inv;
38
+ return out;
39
+ }
40
+ }
41
+ //# sourceMappingURL=spot-light.js.map