@zephyr3d/scene 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 (236) hide show
  1. package/dist/animation/animation.js +173 -0
  2. package/dist/animation/animation.js.map +1 -0
  3. package/dist/animation/animationset.js +95 -0
  4. package/dist/animation/animationset.js.map +1 -0
  5. package/dist/animation/animationtrack.js +38 -0
  6. package/dist/animation/animationtrack.js.map +1 -0
  7. package/dist/animation/eulerrotationtrack.js +33 -0
  8. package/dist/animation/eulerrotationtrack.js.map +1 -0
  9. package/dist/animation/rotationtrack.js +37 -0
  10. package/dist/animation/rotationtrack.js.map +1 -0
  11. package/dist/animation/scaletrack.js +36 -0
  12. package/dist/animation/scaletrack.js.map +1 -0
  13. package/dist/animation/skeleton.js +97 -0
  14. package/dist/animation/skeleton.js.map +1 -0
  15. package/dist/animation/translationtrack.js +36 -0
  16. package/dist/animation/translationtrack.js.map +1 -0
  17. package/dist/animation/usertrack.js +47 -0
  18. package/dist/animation/usertrack.js.map +1 -0
  19. package/dist/app.js +173 -0
  20. package/dist/app.js.map +1 -0
  21. package/dist/asset/assetmanager.js +476 -0
  22. package/dist/asset/assetmanager.js.map +1 -0
  23. package/dist/asset/builtin.js +373 -0
  24. package/dist/asset/builtin.js.map +1 -0
  25. package/dist/asset/loaders/dds/dds.js +472 -0
  26. package/dist/asset/loaders/dds/dds.js.map +1 -0
  27. package/dist/asset/loaders/dds/dds_loader.js +38 -0
  28. package/dist/asset/loaders/dds/dds_loader.js.map +1 -0
  29. package/dist/asset/loaders/gltf/gltf_loader.js +981 -0
  30. package/dist/asset/loaders/gltf/gltf_loader.js.map +1 -0
  31. package/dist/asset/loaders/gltf/helpers.js +314 -0
  32. package/dist/asset/loaders/gltf/helpers.js.map +1 -0
  33. package/dist/asset/loaders/hdr/hdr.js +175 -0
  34. package/dist/asset/loaders/hdr/hdr.js.map +1 -0
  35. package/dist/asset/loaders/image/tga_Loader.js +117 -0
  36. package/dist/asset/loaders/image/tga_Loader.js.map +1 -0
  37. package/dist/asset/loaders/image/webimage_loader.js +50 -0
  38. package/dist/asset/loaders/image/webimage_loader.js.map +1 -0
  39. package/dist/asset/loaders/loader.js +45 -0
  40. package/dist/asset/loaders/loader.js.map +1 -0
  41. package/dist/asset/model.js +264 -0
  42. package/dist/asset/model.js.map +1 -0
  43. package/dist/blitter/blitter.js +389 -0
  44. package/dist/blitter/blitter.js.map +1 -0
  45. package/dist/blitter/box.js +118 -0
  46. package/dist/blitter/box.js.map +1 -0
  47. package/dist/blitter/copy.js +22 -0
  48. package/dist/blitter/copy.js.map +1 -0
  49. package/dist/blitter/depthlimitedgaussion.js +166 -0
  50. package/dist/blitter/depthlimitedgaussion.js.map +1 -0
  51. package/dist/blitter/gaussianblur.js +229 -0
  52. package/dist/blitter/gaussianblur.js.map +1 -0
  53. package/dist/camera/base.js +90 -0
  54. package/dist/camera/base.js.map +1 -0
  55. package/dist/camera/camera.js +358 -0
  56. package/dist/camera/camera.js.map +1 -0
  57. package/dist/camera/fps.js +246 -0
  58. package/dist/camera/fps.js.map +1 -0
  59. package/dist/camera/orbit.js +157 -0
  60. package/dist/camera/orbit.js.map +1 -0
  61. package/dist/camera/orthocamera.js +126 -0
  62. package/dist/camera/orthocamera.js.map +1 -0
  63. package/dist/camera/perspectivecamera.js +133 -0
  64. package/dist/camera/perspectivecamera.js.map +1 -0
  65. package/dist/index.d.ts +8402 -0
  66. package/dist/index.js +87 -0
  67. package/dist/index.js.map +1 -0
  68. package/dist/input/inputmgr.js +242 -0
  69. package/dist/input/inputmgr.js.map +1 -0
  70. package/dist/material/blinn.js +75 -0
  71. package/dist/material/blinn.js.map +1 -0
  72. package/dist/material/grassmaterial.js +221 -0
  73. package/dist/material/grassmaterial.js.map +1 -0
  74. package/dist/material/lambert.js +52 -0
  75. package/dist/material/lambert.js.map +1 -0
  76. package/dist/material/lightmodel.js +2074 -0
  77. package/dist/material/lightmodel.js.map +1 -0
  78. package/dist/material/lit.js +578 -0
  79. package/dist/material/lit.js.map +1 -0
  80. package/dist/material/material.js +458 -0
  81. package/dist/material/material.js.map +1 -0
  82. package/dist/material/meshmaterial.js +311 -0
  83. package/dist/material/meshmaterial.js.map +1 -0
  84. package/dist/material/mixins/albedocolor.js +130 -0
  85. package/dist/material/mixins/albedocolor.js.map +1 -0
  86. package/dist/material/mixins/texture.js +110 -0
  87. package/dist/material/mixins/texture.js.map +1 -0
  88. package/dist/material/mixins/vertexcolor.js +45 -0
  89. package/dist/material/mixins/vertexcolor.js.map +1 -0
  90. package/dist/material/pbr.js +27 -0
  91. package/dist/material/pbr.js.map +1 -0
  92. package/dist/material/standard.js +282 -0
  93. package/dist/material/standard.js.map +1 -0
  94. package/dist/material/terrainlightmodel.js +259 -0
  95. package/dist/material/terrainlightmodel.js.map +1 -0
  96. package/dist/material/terrainmaterial.js +139 -0
  97. package/dist/material/terrainmaterial.js.map +1 -0
  98. package/dist/material/unlit.js +29 -0
  99. package/dist/material/unlit.js.map +1 -0
  100. package/dist/posteffect/bloom.js +398 -0
  101. package/dist/posteffect/bloom.js.map +1 -0
  102. package/dist/posteffect/compositor.js +264 -0
  103. package/dist/posteffect/compositor.js.map +1 -0
  104. package/dist/posteffect/fxaa.js +291 -0
  105. package/dist/posteffect/fxaa.js.map +1 -0
  106. package/dist/posteffect/grayscale.js +87 -0
  107. package/dist/posteffect/grayscale.js.map +1 -0
  108. package/dist/posteffect/posteffect.js +165 -0
  109. package/dist/posteffect/posteffect.js.map +1 -0
  110. package/dist/posteffect/sao.js +327 -0
  111. package/dist/posteffect/sao.js.map +1 -0
  112. package/dist/posteffect/tonemap.js +112 -0
  113. package/dist/posteffect/tonemap.js.map +1 -0
  114. package/dist/posteffect/water.js +535 -0
  115. package/dist/posteffect/water.js.map +1 -0
  116. package/dist/render/clipmap.js +462 -0
  117. package/dist/render/clipmap.js.map +1 -0
  118. package/dist/render/cluster_light.js +329 -0
  119. package/dist/render/cluster_light.js.map +1 -0
  120. package/dist/render/cull_visitor.js +124 -0
  121. package/dist/render/cull_visitor.js.map +1 -0
  122. package/dist/render/depth_pass.js +47 -0
  123. package/dist/render/depth_pass.js.map +1 -0
  124. package/dist/render/envlight.js +282 -0
  125. package/dist/render/envlight.js.map +1 -0
  126. package/dist/render/forward.js +186 -0
  127. package/dist/render/forward.js.map +1 -0
  128. package/dist/render/forward_pass.js +137 -0
  129. package/dist/render/forward_pass.js.map +1 -0
  130. package/dist/render/helper.js +38 -0
  131. package/dist/render/helper.js.map +1 -0
  132. package/dist/render/primitive.js +246 -0
  133. package/dist/render/primitive.js.map +1 -0
  134. package/dist/render/render_queue.js +163 -0
  135. package/dist/render/render_queue.js.map +1 -0
  136. package/dist/render/renderpass.js +151 -0
  137. package/dist/render/renderpass.js.map +1 -0
  138. package/dist/render/renderscheme.js +61 -0
  139. package/dist/render/renderscheme.js.map +1 -0
  140. package/dist/render/scatteringlut.js +634 -0
  141. package/dist/render/scatteringlut.js.map +1 -0
  142. package/dist/render/shadowmap_pass.js +70 -0
  143. package/dist/render/shadowmap_pass.js.map +1 -0
  144. package/dist/render/sky.js +881 -0
  145. package/dist/render/sky.js.map +1 -0
  146. package/dist/render/temporalcache.js +222 -0
  147. package/dist/render/temporalcache.js.map +1 -0
  148. package/dist/render/watermesh.js +835 -0
  149. package/dist/render/watermesh.js.map +1 -0
  150. package/dist/scene/environment.js +146 -0
  151. package/dist/scene/environment.js.map +1 -0
  152. package/dist/scene/graph_node.js +69 -0
  153. package/dist/scene/graph_node.js.map +1 -0
  154. package/dist/scene/light.js +436 -0
  155. package/dist/scene/light.js.map +1 -0
  156. package/dist/scene/mesh.js +215 -0
  157. package/dist/scene/mesh.js.map +1 -0
  158. package/dist/scene/model.js +111 -0
  159. package/dist/scene/model.js.map +1 -0
  160. package/dist/scene/octree.js +651 -0
  161. package/dist/scene/octree.js.map +1 -0
  162. package/dist/scene/octree_update_visitor.js +16 -0
  163. package/dist/scene/octree_update_visitor.js.map +1 -0
  164. package/dist/scene/raycast_visitor.js +72 -0
  165. package/dist/scene/raycast_visitor.js.map +1 -0
  166. package/dist/scene/scene.js +225 -0
  167. package/dist/scene/scene.js.map +1 -0
  168. package/dist/scene/scene_node.js +299 -0
  169. package/dist/scene/scene_node.js.map +1 -0
  170. package/dist/scene/terrain/grass.js +277 -0
  171. package/dist/scene/terrain/grass.js.map +1 -0
  172. package/dist/scene/terrain/heightfield.js +391 -0
  173. package/dist/scene/terrain/heightfield.js.map +1 -0
  174. package/dist/scene/terrain/patch.js +530 -0
  175. package/dist/scene/terrain/patch.js.map +1 -0
  176. package/dist/scene/terrain/quadtree.js +430 -0
  177. package/dist/scene/terrain/quadtree.js.map +1 -0
  178. package/dist/scene/terrain/terrain.js +258 -0
  179. package/dist/scene/terrain/terrain.js.map +1 -0
  180. package/dist/scene/xform.js +224 -0
  181. package/dist/scene/xform.js.map +1 -0
  182. package/dist/shaders/builtins.js +110 -0
  183. package/dist/shaders/builtins.js.map +1 -0
  184. package/dist/shaders/framework.js +709 -0
  185. package/dist/shaders/framework.js.map +1 -0
  186. package/dist/shaders/lighting.js +335 -0
  187. package/dist/shaders/lighting.js.map +1 -0
  188. package/dist/shaders/misc.js +405 -0
  189. package/dist/shaders/misc.js.map +1 -0
  190. package/dist/shaders/noise.js +157 -0
  191. package/dist/shaders/noise.js.map +1 -0
  192. package/dist/shaders/pbr.js +132 -0
  193. package/dist/shaders/pbr.js.map +1 -0
  194. package/dist/shaders/shadow.js +642 -0
  195. package/dist/shaders/shadow.js.map +1 -0
  196. package/dist/shaders/water.js +630 -0
  197. package/dist/shaders/water.js.map +1 -0
  198. package/dist/shadow/esm.js +235 -0
  199. package/dist/shadow/esm.js.map +1 -0
  200. package/dist/shadow/pcf_opt.js +182 -0
  201. package/dist/shadow/pcf_opt.js.map +1 -0
  202. package/dist/shadow/pcf_pd.js +190 -0
  203. package/dist/shadow/pcf_pd.js.map +1 -0
  204. package/dist/shadow/shadow_impl.js +15 -0
  205. package/dist/shadow/shadow_impl.js.map +1 -0
  206. package/dist/shadow/shadowmapper.js +709 -0
  207. package/dist/shadow/shadowmapper.js.map +1 -0
  208. package/dist/shadow/ssm.js +194 -0
  209. package/dist/shadow/ssm.js.map +1 -0
  210. package/dist/shadow/vsm.js +298 -0
  211. package/dist/shadow/vsm.js.map +1 -0
  212. package/dist/shapes/box.js +313 -0
  213. package/dist/shapes/box.js.map +1 -0
  214. package/dist/shapes/cylinder.js +74 -0
  215. package/dist/shapes/cylinder.js.map +1 -0
  216. package/dist/shapes/plane.js +48 -0
  217. package/dist/shapes/plane.js.map +1 -0
  218. package/dist/shapes/shape.js +33 -0
  219. package/dist/shapes/shape.js.map +1 -0
  220. package/dist/shapes/sphere.js +91 -0
  221. package/dist/shapes/sphere.js.map +1 -0
  222. package/dist/shapes/torus.js +100 -0
  223. package/dist/shapes/torus.js.map +1 -0
  224. package/dist/utility/aabbtree.js +390 -0
  225. package/dist/utility/aabbtree.js.map +1 -0
  226. package/dist/utility/bounding_volume.js +78 -0
  227. package/dist/utility/bounding_volume.js.map +1 -0
  228. package/dist/utility/panorama.js +163 -0
  229. package/dist/utility/panorama.js.map +1 -0
  230. package/dist/utility/pmrem.js +345 -0
  231. package/dist/utility/pmrem.js.map +1 -0
  232. package/dist/utility/shprojection.js +448 -0
  233. package/dist/utility/shprojection.js.map +1 -0
  234. package/dist/values.js +48 -0
  235. package/dist/values.js.map +1 -0
  236. package/package.json +70 -0
@@ -0,0 +1,709 @@
1
+ import { Vector4 } from '@zephyr3d/base';
2
+ import { RENDER_PASS_TYPE_SHADOWMAP, RENDER_PASS_TYPE_DEPTH_ONLY, RENDER_PASS_TYPE_FORWARD, MAX_CLUSTERED_LIGHTS } from '../values.js';
3
+ import { Application } from '../app.js';
4
+ import { ScatteringLut } from '../render/scatteringlut.js';
5
+
6
+ /**
7
+ * Helper shader functions for the builtin material system
8
+ * @public
9
+ */ class ShaderFramework {
10
+ static FOG_TYPE_NONE = 0;
11
+ static FOG_TYPE_LINEAR = 1;
12
+ static FOG_TYPE_EXP = 2;
13
+ static FOG_TYPE_EXP2 = 3;
14
+ static FOG_TYPE_SCATTER = 4;
15
+ static BILLBOARD_SPHERICAL = 1;
16
+ static BILLBOARD_SYLINDRAL = 2;
17
+ static USAGE_VERTEX_COLOR = 'usage_VertexColor';
18
+ static USAGE_WORLD_MATRIX = 'usage_WorldMatrix';
19
+ static USAGE_BONE_MATRICIES = 'usage_BoneMatrices';
20
+ static USAGE_INV_BIND_MATRIX = 'usage_InvBindMatrix';
21
+ static USAGE_BONE_TEXTURE_SIZE = 'usage_BoneTextureSize';
22
+ static USAGE_WORLD_POSITION = 'usage_WorldPosition';
23
+ static USAGE_WORLD_NORMAL = 'usage_WorldNormal';
24
+ static USAGE_WORLD_TANGENT = 'usage_WorldTangent';
25
+ static USAGE_WORLD_BINORMAL = 'usage_WorldBinormal';
26
+ /** @internal */ static _lightUniformShadow = {
27
+ light: {
28
+ envLightStrength: 1,
29
+ shadowCascades: 1,
30
+ positionAndRange: new Vector4(),
31
+ directionAndCutoff: new Vector4(),
32
+ diffuseAndIntensity: new Vector4(),
33
+ cascadeDistances: new Vector4(),
34
+ depthBiasValues: new Vector4(),
35
+ shadowCameraParams: new Vector4(),
36
+ depthBiasScales: new Vector4(),
37
+ shadowMatrices: new Float32Array(16 * 4)
38
+ }
39
+ };
40
+ /** @internal */ static _fogUniforms = {
41
+ fog: {
42
+ fogType: 0,
43
+ fogColor: null,
44
+ // [near, far, top, density]
45
+ fogParams: null
46
+ }
47
+ };
48
+ /**
49
+ * Prepares the fragment shader which is going to be used in our material system
50
+ *
51
+ * @remarks
52
+ * This function will setup all nessesary uniforms acoording to the drawing context
53
+ *
54
+ * @param pb - The program builder
55
+ * @param ctx - The drawing context
56
+ */ static prepareFragmentShader(pb, ctx) {
57
+ this.setupGlobalUniforms(pb, ctx);
58
+ /*
59
+ if (ctx.renderPass.type === RENDER_PASS_TYPE_SHADOWMAP) {
60
+ const scope = pb.getGlobalScope();
61
+ const globalStruct = this.defineGlobalStructShadowMap(pb);
62
+ scope.global = globalStruct().uniform(0);
63
+ // this.prepareFragmentShaderShadowMap(pb, ctx);
64
+ } else {
65
+ //this.prepareFragmentShaderForward(pb, ctx);
66
+ const scope = pb.getGlobalScope();
67
+ const globalStruct = this.defineGlobalStruct(pb, ctx);
68
+ scope.global = globalStruct().uniform(0);
69
+
70
+ this.prepareShadowUniforms(pb, ctx);
71
+ ctx.drawEnvLight && ctx.env.light.envLight.initShaderBindings(pb);
72
+ }
73
+ */ }
74
+ /**
75
+ * Prepares the vertex shader which is going to be used in our material system
76
+ *
77
+ * @remarks
78
+ * This function will setup all nessesary uniforms according to the drawing context
79
+ *
80
+ * @param pb - The program builder
81
+ * @param ctx - The drawing context
82
+ */ static prepareVertexShader(pb, ctx) {
83
+ this.setupGlobalUniforms(pb, ctx);
84
+ this.prepareVertexShaderCommon(pb, ctx);
85
+ }
86
+ /** @internal */ static setupGlobalUniforms(pb, ctx) {
87
+ const scope = pb.getGlobalScope();
88
+ const cameraStruct = pb.defineStruct([
89
+ pb.vec4('position'),
90
+ pb.vec4('clipPlane'),
91
+ pb.mat4('viewProjectionMatrix'),
92
+ pb.mat4('viewMatrix'),
93
+ pb.mat4('rotationMatrix'),
94
+ pb.mat4('projectionMatrix'),
95
+ pb.vec4('params'),
96
+ pb.float('worldUnit')
97
+ ]);
98
+ if (ctx.renderPass.type === RENDER_PASS_TYPE_SHADOWMAP) {
99
+ const lightStruct = pb.defineStruct([
100
+ pb.vec4('positionAndRange'),
101
+ pb.vec4('directionCutoff'),
102
+ pb.mat4('viewMatrix'),
103
+ pb.vec4('depthBias'),
104
+ pb.int('lightType')
105
+ ]);
106
+ const globalStruct = pb.defineStruct([
107
+ cameraStruct('camera'),
108
+ lightStruct('light')
109
+ ]);
110
+ scope.global = globalStruct().uniform(0);
111
+ } else if (ctx.renderPass.type === RENDER_PASS_TYPE_DEPTH_ONLY) {
112
+ const globalStruct = pb.defineStruct([
113
+ cameraStruct('camera')
114
+ ]);
115
+ scope.global = globalStruct().uniform(0);
116
+ } else if (ctx.renderPass.type === RENDER_PASS_TYPE_FORWARD) {
117
+ const useClusteredLighting = !ctx.currentShadowLight;
118
+ const fogStruct = pb.defineStruct([
119
+ pb.int('fogType'),
120
+ pb.vec4('fogColor'),
121
+ pb.vec4('fogParams')
122
+ ]);
123
+ const lightStruct = ctx.currentShadowLight ? pb.defineStruct([
124
+ pb.int('shadowCascades'),
125
+ pb.vec4('positionAndRange'),
126
+ pb.vec4('directionAndCutoff'),
127
+ pb.vec4('diffuseAndIntensity'),
128
+ pb.vec4('cascadeDistances'),
129
+ pb.vec4('depthBiasValues'),
130
+ pb.vec4('shadowCameraParams'),
131
+ pb.vec4('depthBiasScales'),
132
+ pb.vec4[16]('shadowMatrices'),
133
+ pb.float('envLightStrength')
134
+ ]) : pb.defineStruct([
135
+ pb.float('envLightStrength'),
136
+ pb.vec4('clusterParams'),
137
+ pb.ivec4('countParams'),
138
+ pb.ivec2('lightIndexTexSize')
139
+ ]);
140
+ const globalStruct = pb.defineStruct([
141
+ cameraStruct('camera'),
142
+ lightStruct('light'),
143
+ fogStruct('fog')
144
+ ]);
145
+ scope.global = globalStruct().uniform(0);
146
+ if (useClusteredLighting) {
147
+ scope.lightBuffer = pb.vec4[(MAX_CLUSTERED_LIGHTS + 1) * 3]().uniformBuffer(0);
148
+ scope.lightIndexTex = (pb.getDevice().type === 'webgl' ? pb.tex2D() : pb.utex2D()).uniform(0);
149
+ }
150
+ if (ctx.applyFog && ctx.scene.env.sky.drawScatteredFog(ctx)) {
151
+ scope.aerialPerspectiveLUT = pb.tex2D().uniform(0);
152
+ }
153
+ if (ctx.currentShadowLight) {
154
+ const scope = pb.getGlobalScope();
155
+ const shadowMapParams = ctx.shadowMapInfo.get(ctx.currentShadowLight);
156
+ const tex = shadowMapParams.shadowMap.isTextureCube() ? shadowMapParams.shadowMap.isDepth() ? scope.$builder.texCubeShadow() : scope.$builder.texCube() : shadowMapParams.shadowMap.isTexture2D() ? shadowMapParams.shadowMap.isDepth() ? scope.$builder.tex2DShadow() : scope.$builder.tex2D() : shadowMapParams.shadowMap.isDepth() ? scope.$builder.tex2DArrayShadow() : scope.$builder.tex2DArray();
157
+ if (!shadowMapParams.shadowMap.isDepth() && !Application.instance.device.getDeviceCaps().textureCaps.getTextureFormatInfo(shadowMapParams.shadowMap.format).filterable) {
158
+ tex.sampleType('unfilterable-float');
159
+ }
160
+ scope.shadowMap = tex.uniform(0);
161
+ }
162
+ ctx.drawEnvLight && ctx.env.light.envLight.initShaderBindings(pb);
163
+ }
164
+ }
165
+ /** @internal */ static prepareVertexShaderCommon(pb, ctx) {
166
+ const instancing = ctx.instanceData?.worldMatrices?.length > 1;
167
+ const skinning = !!ctx.target?.getBoneMatrices();
168
+ const scope = pb.getGlobalScope();
169
+ if (instancing) {
170
+ const maxNumInstances = Application.instance.device.getDeviceCaps().shaderCaps.maxUniformBufferSize >> 6;
171
+ scope.instanceBufferOffset = pb.uint().uniform(1);
172
+ scope.worldMatrix = pb.mat4[maxNumInstances]().uniformBuffer(3);
173
+ pb.getReflection().tag(ShaderFramework.USAGE_WORLD_MATRIX, ()=>scope.worldMatrix.at(pb.add(scope.instanceBufferOffset, pb.uint(scope.$builtins.instanceIndex))));
174
+ } else {
175
+ scope.worldMatrix = pb.mat4().uniform(1).tag(ShaderFramework.USAGE_WORLD_MATRIX);
176
+ }
177
+ if (skinning) {
178
+ scope.boneMatrices = pb.tex2D().uniform(1).sampleType('unfilterable-float').tag(ShaderFramework.USAGE_BONE_MATRICIES);
179
+ scope.invBindMatrix = pb.mat4().uniform(1).tag(ShaderFramework.USAGE_INV_BIND_MATRIX);
180
+ scope.boneTextureSize = pb.int().uniform(1).tag(ShaderFramework.USAGE_BONE_TEXTURE_SIZE);
181
+ }
182
+ }
183
+ /** @internal */ static setCameraUniforms(bindGroup, ctx, linear) {
184
+ const pos = ctx.camera.getWorldPosition();
185
+ const cameraStruct = {
186
+ position: new Vector4(pos.x, pos.y, pos.z, ctx.camera.clipPlane ? 1 : 0),
187
+ clipPlane: ctx.camera.clipPlane ?? Vector4.zero(),
188
+ viewProjectionMatrix: ctx.camera.viewProjectionMatrix,
189
+ viewMatrix: ctx.camera.viewMatrix,
190
+ rotationMatrix: ctx.camera.getRotationMatrix(),
191
+ projectionMatrix: ctx.camera.getProjectionMatrix(),
192
+ worldUnit: ctx.scene.worldUnit,
193
+ params: new Vector4(ctx.camera.getNearPlane(), ctx.camera.getFarPlane(), ctx.flip ? -1 : 1, linear ? 0 : 1)
194
+ };
195
+ bindGroup.setValue('global', {
196
+ camera: cameraStruct
197
+ });
198
+ }
199
+ /** @internal */ static setLightUniformsShadowMap(bindGroup, ctx, light) {
200
+ if (light) {
201
+ const shadowMapParams = ctx.shadowMapInfo.get(light);
202
+ bindGroup.setValue('global', {
203
+ light: {
204
+ positionAndRange: light.positionAndRange,
205
+ directionCutoff: light.directionAndCutoff,
206
+ viewMatrix: light.viewMatrix,
207
+ depthBias: shadowMapParams.depthBiasValues[0],
208
+ lightType: light.lightType
209
+ }
210
+ });
211
+ }
212
+ }
213
+ /** @internal */ static setFogUniforms(bindGroup, fogType, fogColor, fogParams, aerialPerspectiveLUT) {
214
+ this._fogUniforms.fog.fogColor = fogColor;
215
+ this._fogUniforms.fog.fogParams = fogParams;
216
+ this._fogUniforms.fog.fogType = fogType;
217
+ bindGroup.setValue('global', this._fogUniforms);
218
+ if (aerialPerspectiveLUT) {
219
+ bindGroup.setTexture('aerialPerspectiveLUT', aerialPerspectiveLUT);
220
+ }
221
+ }
222
+ /** @internal */ static setLightUniforms(bindGroup, ctx, clusterParams, countParams, lightBuffer, lightIndexTexture) {
223
+ bindGroup.setValue('global', {
224
+ light: {
225
+ clusterParams: clusterParams,
226
+ countParams: countParams,
227
+ envLightStrength: ctx.env.light.strength ?? 0,
228
+ lightIndexTexSize: new Int32Array([
229
+ lightIndexTexture.width,
230
+ lightIndexTexture.height
231
+ ])
232
+ }
233
+ });
234
+ bindGroup.setBuffer('lightBuffer', lightBuffer);
235
+ bindGroup.setTexture('lightIndexTex', lightIndexTexture);
236
+ ctx.drawEnvLight && ctx.env.light.envLight.updateBindGroup(bindGroup);
237
+ }
238
+ /** @internal */ static setLightUniformsShadow(bindGroup, ctx, light) {
239
+ const shadowMapParams = ctx.shadowMapInfo.get(light);
240
+ this._lightUniformShadow.light.envLightStrength = ctx.env?.light.strength ?? 0;
241
+ this._lightUniformShadow.light.shadowCascades = shadowMapParams.numShadowCascades;
242
+ this._lightUniformShadow.light.positionAndRange.set(light.positionAndRange);
243
+ this._lightUniformShadow.light.directionAndCutoff.set(light.directionAndCutoff);
244
+ this._lightUniformShadow.light.diffuseAndIntensity.set(light.diffuseAndIntensity);
245
+ this._lightUniformShadow.light.cascadeDistances.set(shadowMapParams.cascadeDistances);
246
+ this._lightUniformShadow.light.depthBiasValues.set(shadowMapParams.depthBiasValues[0]);
247
+ this._lightUniformShadow.light.shadowCameraParams.set(shadowMapParams.cameraParams);
248
+ this._lightUniformShadow.light.depthBiasScales.set(shadowMapParams.depthBiasScales);
249
+ this._lightUniformShadow.light.shadowMatrices.set(shadowMapParams.shadowMatrices);
250
+ bindGroup.setValue('global', this._lightUniformShadow);
251
+ bindGroup.setTexture('shadowMap', shadowMapParams.shadowMap, shadowMapParams.shadowMapSampler);
252
+ ctx.drawEnvLight && ctx.env.light.envLight.updateBindGroup(bindGroup);
253
+ }
254
+ /**
255
+ * Gets the uniform variable of type float which holds the strength of the environment light
256
+ *
257
+ * @remarks
258
+ * This function can only be used in the fragment shader
259
+ *
260
+ * @param scope - Current shader scope
261
+ * @returns The uniform variable of which presents the strength of the environment light
262
+ */ static getEnvLightStrength(scope) {
263
+ return scope.global.light.envLightStrength;
264
+ }
265
+ /**
266
+ * Gets the uniform variable of type vec3 which holds the camera position
267
+ * @param scope - Current shader scope
268
+ * @returns The camera position
269
+ */ static getCameraPosition(scope) {
270
+ return scope.global.camera.position.xyz;
271
+ }
272
+ /**
273
+ * Discard the fragment if it was clipped by the clip plane
274
+ * @param scope - Current shader scope
275
+ */ static discardIfClipped(scope) {
276
+ const funcName = 'lib_discardIfClippped';
277
+ const pb = scope.$builder;
278
+ const that = this;
279
+ pb.func(funcName, [], function() {
280
+ this.$if(pb.notEqual(that.getCameraClipPlaneFlag(this), 0), function() {
281
+ this.$l.worldPos = that.getWorldPosition(this);
282
+ this.$l.clipPlane = that.getCameraClipPlane(this);
283
+ this.$if(pb.greaterThan(pb.add(pb.dot(this.worldPos.xyz, this.clipPlane.xyz), this.clipPlane.w), 0), function() {
284
+ pb.discard();
285
+ });
286
+ });
287
+ });
288
+ pb.getGlobalScope()[funcName]();
289
+ }
290
+ /**
291
+ * Gets the clip plane flag
292
+ * @param scope - Current shader scope
293
+ * @returns A float value of 1 indices the clip plane presents, otherwise 0
294
+ */ static getCameraClipPlaneFlag(scope) {
295
+ return scope.global.camera.position.w;
296
+ }
297
+ /**
298
+ * Gets the world unit
299
+ * @param scope - Current shader scope
300
+ * @returns The world unit
301
+ */ static getWorldUnit(scope) {
302
+ return scope.global.camera.worldUnit;
303
+ }
304
+ /**
305
+ * Gets the clip plane
306
+ * @param scope - Current shader scope
307
+ * @returns A vec4 presents the clip plane
308
+ */ static getCameraClipPlane(scope) {
309
+ return scope.global.camera.clipPlane;
310
+ }
311
+ /**
312
+ * Gets the uniform variable of type vec4 which holds the camera parameters
313
+ * @param scope - Current shader scope
314
+ * @returns The camera parameters
315
+ */ static getCameraParams(scope) {
316
+ return scope.global.camera.params;
317
+ }
318
+ /**
319
+ * Gets the uniform variable of type vec4 which holds the fog color
320
+ * @param scope - Current shader scope
321
+ * @returns The fog color
322
+ */ static getFogColor(scope) {
323
+ return scope.global.fog.fogColor;
324
+ }
325
+ /** @internal */ static getClusterParams(scope) {
326
+ return scope.global.light.clusterParams;
327
+ }
328
+ /** @internal */ static getCountParams(scope) {
329
+ return scope.global.light.countParams;
330
+ }
331
+ /** @internal */ static getClusteredLightIndexTexture(scope) {
332
+ return scope.lightIndexTex;
333
+ }
334
+ /**
335
+ * Gets the uniform variable of type vec4 which holds the fog color
336
+ * @param scope - Current shader scope
337
+ * @returns The fog color
338
+ */ static getFogType(scope) {
339
+ return scope.global.fog.fogType;
340
+ }
341
+ /**
342
+ * Gets the aerial perspective LUT
343
+ * @param scope - Current shader scope
344
+ * @returns The aerial perspective LUT texture
345
+ */ static getAerialPerspectiveLUT(scope) {
346
+ return scope.aerialPerspectiveLUT;
347
+ }
348
+ /**
349
+ * Gets the uniform variable of type vec4 which holds the fog parameters
350
+ * @param scope - Current shader scope
351
+ * @returns The fog parameters
352
+ */ static getFogParams(scope) {
353
+ return scope.global.fog.fogParams;
354
+ }
355
+ /**
356
+ * Computes the fog factor for a given view vector
357
+ * @param scope - Current shader scope
358
+ * @param viewDir - the view vector
359
+ * @param fogType - Type of the fog
360
+ * @param fogParams - Fog parameters [start, end, top, density]
361
+ * @returns The computed fog factor
362
+ */ static computeFogFactor(scope, viewDir, fogType, fogParams) {
363
+ const pb = scope.$builder;
364
+ const funcName = 'lib_applyFog';
365
+ const that = this;
366
+ pb.func(funcName, [
367
+ pb.vec3('viewDir'),
368
+ pb.int('fogType'),
369
+ pb.vec4('fogParams')
370
+ ], function() {
371
+ this.$l.distance = pb.length(this.viewDir);
372
+ this.$l.top = pb.max(this.viewDir.y, 0.0001);
373
+ this.$l.distance = pb.mul(this.$l.distance, pb.min(1, pb.div(this.fogParams.z, this.top)));
374
+ this.$if(pb.equal(this.fogType, that.FOG_TYPE_LINEAR), function() {
375
+ this.$return(pb.clamp(pb.div(pb.sub(this.distance, this.fogParams.x), pb.sub(this.fogParams.y, this.fogParams.x)), 0, 1));
376
+ }).$elseif(pb.equal(this.fogType, that.FOG_TYPE_EXP), function() {
377
+ this.$l.e = pb.mul(this.distance, this.fogParams.w);
378
+ this.$return(pb.sub(1, pb.div(1, pb.exp(this.e))));
379
+ }).$elseif(pb.equal(this.fogType, that.FOG_TYPE_EXP2), function() {
380
+ this.$l.e = pb.mul(this.distance, this.fogParams.w);
381
+ this.$return(pb.sub(1, pb.div(1, pb.exp(pb.mul(this.e, this.e)))));
382
+ }).$else(function() {
383
+ this.$return(0);
384
+ });
385
+ });
386
+ return pb.getGlobalScope()[funcName](viewDir, fogType, fogParams);
387
+ }
388
+ /**
389
+ * Computes the fog factor with given type for a given view vector
390
+ * @param scope - Current shader scope
391
+ * @param viewDir - the view vector
392
+ * @param fogParams - The fog params [start, end, top, density]
393
+ * @param fogType - Type of the fog
394
+ * @returns The computed fog factor
395
+ */ static computeFogFactorForType(scope, viewDir, fogParams, fogType) {
396
+ const pb = scope.$builder;
397
+ const funcName = 'lib_applyFog';
398
+ pb.func(funcName, [
399
+ pb.vec3('viewDir'),
400
+ pb.vec4('fogParams')
401
+ ], function() {
402
+ this.$l.distance = pb.length(this.viewDir);
403
+ this.$l.top = pb.max(this.viewDir.y, 0.0001);
404
+ this.$l.distance = pb.mul(this.$l.distance, pb.min(1, pb.div(this.fogParams.z, this.top)));
405
+ if (fogType === 'linear') {
406
+ this.$return(pb.clamp(pb.div(pb.sub(this.distance, this.fogParams.x), pb.sub(this.fogParams.y, this.fogParams.x)), 0, 1));
407
+ } else if (fogType === 'exp') {
408
+ this.$l.e = pb.mul(this.distance, this.fogParams.w);
409
+ this.$return(pb.sub(1, pb.div(1, pb.exp(this.e))));
410
+ } else if (fogType === 'exp2') {
411
+ this.$l.e = pb.mul(this.distance, this.fogParams.w);
412
+ this.$return(pb.sub(1, pb.div(1, pb.exp(pb.mul(this.e, this.e)))));
413
+ } else {
414
+ this.$return(0);
415
+ }
416
+ });
417
+ return pb.getGlobalScope()[funcName](viewDir, fogParams);
418
+ }
419
+ /**
420
+ * Gets the uniform variable of type mat4 which holds the world matrix of current object to be drawn
421
+ * @param scope - Current shader scope
422
+ * @returns The world matrix of current object to be drawn
423
+ */ static getWorldMatrix(scope) {
424
+ return scope.$query(ShaderFramework.USAGE_WORLD_MATRIX);
425
+ }
426
+ /**
427
+ * Gets the uniform variable of type mat4 which holds the view projection matrix of current camera
428
+ * @param scope - Current shader scope
429
+ * @returns The view projection matrix of current camera
430
+ */ static getViewProjectionMatrix(scope) {
431
+ return scope.global.camera.viewProjectionMatrix;
432
+ }
433
+ /**
434
+ * Gets the uniform variable of type mat4 which holds the view projection matrix of current camera
435
+ * @param scope - Current shader scope
436
+ * @returns The view projection matrix of current camera
437
+ */ static getCameraRotationMatrix(scope) {
438
+ return scope.global.camera.rotationMatrix;
439
+ }
440
+ /**
441
+ * Gets the varying input value of type vec4 which holds the world position of current fragment
442
+ *
443
+ * @remarks
444
+ * This function can only be used in the fragment shader
445
+ *
446
+ * @param scope - Current shader scope
447
+ * @returns The world position of current fragment
448
+ */ static getWorldPosition(scope) {
449
+ return scope.$query(ShaderFramework.USAGE_WORLD_POSITION);
450
+ }
451
+ /**
452
+ * Gets the varying input value of type vec3 which holds the world normal of current fragment
453
+ *
454
+ * @remarks
455
+ * This function can only be used in the fragment shader
456
+ *
457
+ * @param scope - Current shader scope
458
+ * @returns The world normal of current fragment
459
+ */ static getWorldNormal(scope) {
460
+ return scope.$query(ShaderFramework.USAGE_WORLD_NORMAL);
461
+ }
462
+ /**
463
+ * Gets the varying input value of type vec3 which holds the world tangent vector of current fragment
464
+ *
465
+ * @remarks
466
+ * This function can only be used in the fragment shader
467
+ *
468
+ * @param scope - Current shader scope
469
+ * @returns The world tangent vector of current fragment
470
+ */ static getWorldTangent(scope) {
471
+ return scope.$query(ShaderFramework.USAGE_WORLD_TANGENT);
472
+ }
473
+ /**
474
+ * Gets the varying input value of type vec3 which holds the world binormal vector of current fragment
475
+ *
476
+ * @remarks
477
+ * This function can only be used in the fragment shader
478
+ *
479
+ * @param scope - Current shader scope
480
+ * @returns The world binormal vector of current fragment
481
+ */ static getWorldBinormal(scope) {
482
+ return scope.$query(ShaderFramework.USAGE_WORLD_BINORMAL);
483
+ }
484
+ /** @internal */ static getCascadeDistances(scope) {
485
+ return scope.global.light.cascadeDistances;
486
+ }
487
+ /** @internal */ static getDepthBiasValues(scope) {
488
+ return scope.global.light.depthBiasValues;
489
+ }
490
+ /** @internal */ static getShadowCameraParams(scope) {
491
+ return scope.global.light.shadowCameraParams;
492
+ }
493
+ /** @internal */ static getDepthBiasScales(scope) {
494
+ return scope.global.light.depthBiasScales;
495
+ }
496
+ /** @internal */ static getNumLights(scope) {
497
+ return scope.global.light.numLights;
498
+ }
499
+ /** @internal */ static getLightTypeForShadow(scope) {
500
+ return scope.global.light.lightType;
501
+ }
502
+ /** @internal */ static getLightPositionAndRangeForShadow(scope) {
503
+ return scope.global.light.positionAndRange;
504
+ }
505
+ /** @internal */ static getLightViewMatrixForShadow(scope) {
506
+ return scope.global.light.viewMatrix;
507
+ }
508
+ /** @internal */ static calculateShadowSpaceVertex(scope, cascade = 0) {
509
+ const pb = scope.$builder;
510
+ const worldPos = ShaderFramework.getWorldPosition(scope);
511
+ return pb.vec4(pb.dot(scope.global.light.shadowMatrices.at(pb.add(pb.mul(cascade, 4), 0)), worldPos), pb.dot(scope.global.light.shadowMatrices.at(pb.add(pb.mul(cascade, 4), 1)), worldPos), pb.dot(scope.global.light.shadowMatrices.at(pb.add(pb.mul(cascade, 4), 2)), worldPos), pb.dot(scope.global.light.shadowMatrices.at(pb.add(pb.mul(cascade, 4), 3)), worldPos));
512
+ }
513
+ /** @internal */ static getLightPositionAndRange(scope, lightIndex) {
514
+ return scope.lightBuffer.at(scope.$builder.mul(lightIndex, 3));
515
+ }
516
+ /** @internal */ static getLightDirectionAndCutoff(scope, lightIndex) {
517
+ return scope.lightBuffer.at(scope.$builder.add(scope.$builder.mul(lightIndex, 3), 1));
518
+ }
519
+ /** @internal */ static getLightColorAndIntensity(scope, lightIndex) {
520
+ return scope.lightBuffer.at(scope.$builder.add(scope.$builder.mul(lightIndex, 3), 2));
521
+ }
522
+ /**
523
+ * Transform vertex position to the clip space and calcuate the world normal and tangent frame if needed
524
+ *
525
+ * @remarks
526
+ * This function handles skin animation and geometry instancing if needed
527
+ *
528
+ * @param scope - Current shader scope
529
+ * @param billboardMode - If not zero, transform vertex as billboard
530
+ */ static ftransform(scope, billboardMode = 0) {
531
+ const pb = scope.$builder;
532
+ const funcName = 'lib_ftransform';
533
+ const that = this;
534
+ pb.func(funcName, [], function() {
535
+ const viewProjMatrix = that.getViewProjectionMatrix(this);
536
+ if (billboardMode === 0) {
537
+ this.$l.worldMatrix = this.$query(ShaderFramework.USAGE_WORLD_MATRIX);
538
+ } else {
539
+ this.$l.rotMat = that.getCameraRotationMatrix(this);
540
+ this.$l.wMat = this.$query(ShaderFramework.USAGE_WORLD_MATRIX);
541
+ if (billboardMode === that.BILLBOARD_SYLINDRAL) {
542
+ this.$l.xaxis = this.rotMat[0].xyz;
543
+ this.$l.xscale = pb.length(this.wMat[0]);
544
+ this.$l.yaxis = pb.vec3(0, 1, 0);
545
+ this.$l.yscale = pb.length(this.wMat[1]);
546
+ this.$l.zaxis = pb.cross(this.xaxis, this.yaxis);
547
+ this.$l.xaxis = pb.cross(this.yaxis, this.zaxis);
548
+ this.$l.zscale = pb.length(this.wMat[2]);
549
+ } else if (billboardMode === that.BILLBOARD_SPHERICAL) {
550
+ this.$l.xaxis = this.rotMat[0].xyz;
551
+ this.$l.xscale = pb.length(this.wMat[0]);
552
+ this.$l.yaxis = this.rotMat[1].xyz;
553
+ this.$l.yscale = pb.length(this.wMat[1]);
554
+ this.$l.zaxis = this.rotMat[2].xyz;
555
+ this.$l.zscale = pb.length(this.wMat[2]);
556
+ } else {
557
+ throw new Error(`ftransform(): invalid billboard mode: ${billboardMode}`);
558
+ }
559
+ this.$l.m0 = pb.vec4(pb.mul(this.xaxis, this.xscale), 0);
560
+ this.$l.m1 = pb.vec4(pb.mul(this.yaxis, this.yscale), 0);
561
+ this.$l.m2 = pb.vec4(pb.mul(this.zaxis, this.zscale), 0);
562
+ //this.$l.xaxis = pb.mul(this.rotMat[0], pb.length(this.wMat[0]));
563
+ //this.$l.yaxis = pb.mul(pb.vec4(0, 1, 0, 0)/*this.rotMat[1]*/, pb.length(this.wMat[1]));
564
+ //this.$l.zaxis = pb.mul(pb.vec4(pb.cross(this.xaxis.xyz, this.yaxis.xyz), 0);
565
+ //this.$l.zaxis = pb.mul(pb.vec4(0, 0, 1, 0)/*this.rotMat[2]*/, pb.length(this.wMat[2]));
566
+ this.$l.worldMatrix = pb.mat4(this.m0, this.m1, this.m2, this.wMat[3]);
567
+ }
568
+ //const worldMatrix = this.$query(ShaderFramework.USAGE_WORLD_MATRIX);
569
+ const pos = pb.getGlobalScope().$getVertexAttrib('position');
570
+ if (this.$query(ShaderFramework.USAGE_BONE_MATRICIES)) {
571
+ this.$l.skinMatrix = that.getSkinMatrix(this);
572
+ }
573
+ this.$l.pos = pb.vec4(pos.xyz, 1);
574
+ if (this.$l.skinMatrix) {
575
+ this.$l.pos = pb.mul(this.$l.skinMatrix, this.$l.pos);
576
+ this.$l.pos = pb.div(this.$l.pos, this.$l.pos.w);
577
+ }
578
+ this.$outputs.worldPosition = pb.mul(this.worldMatrix, this.$l.pos).tag(ShaderFramework.USAGE_WORLD_POSITION);
579
+ that.setClipSpacePosition(this, pb.mul(viewProjMatrix, this.$outputs.worldPosition));
580
+ const norm = pb.getGlobalScope().$getVertexAttrib('normal');
581
+ if (norm) {
582
+ this.$l.norm = pb.vec4(norm.xyz, 0);
583
+ if (this.$l.skinMatrix) {
584
+ this.$l.norm = pb.mul(this.$l.skinMatrix, this.$l.norm);
585
+ }
586
+ this.$outputs.worldNormal = pb.normalize(pb.mul(this.worldMatrix, this.$l.norm).xyz).tag(ShaderFramework.USAGE_WORLD_NORMAL);
587
+ const tan = pb.getGlobalScope().$getVertexAttrib('tangent');
588
+ if (tan) {
589
+ this.$l.tangent = pb.vec4(tan.xyz, 0);
590
+ if (this.$l.skinMatrix) {
591
+ this.$l.tangent = pb.mul(this.$l.skinMatrix, this.$l.tangent);
592
+ }
593
+ this.$outputs.worldTangent = pb.normalize(pb.mul(this.worldMatrix, this.$l.tangent).xyz).tag(ShaderFramework.USAGE_WORLD_TANGENT);
594
+ this.$outputs.worldBinormal = pb.normalize(pb.mul(pb.cross(this.$outputs.worldNormal, this.$outputs.worldTangent), tan.w)).tag(ShaderFramework.USAGE_WORLD_BINORMAL);
595
+ }
596
+ }
597
+ });
598
+ pb.getGlobalScope()[funcName]();
599
+ }
600
+ /**
601
+ * Sets the clip space position in vertex shader
602
+ *
603
+ * @remarks
604
+ * Use this function instead of using
605
+ * <pre>
606
+ * // Do not use this
607
+ * this.$builtins.position = some_value;
608
+ * // Use this
609
+ * ShaderFramework.setClipSpacePosition(some_value);
610
+ * </pre>,
611
+ *
612
+ * @param scope - Current shader scope
613
+ * @param pos - The clip space position to be set
614
+ */ static setClipSpacePosition(scope, pos) {
615
+ const pb = scope.$builder;
616
+ const cameraParams = this.getCameraParams(scope);
617
+ if (cameraParams) {
618
+ scope.$builtins.position = pb.mul(pos, pb.vec4(1, cameraParams.z, 1, 1));
619
+ } else {
620
+ scope.$builtins.position = pos;
621
+ }
622
+ }
623
+ /** @internal */ static getSkinMatrix(scope) {
624
+ const pb = scope.$builder;
625
+ const funcNameGetBoneMatrixFromTexture = 'lib_getBoneMatrixFromTexture';
626
+ pb.func(funcNameGetBoneMatrixFromTexture, [
627
+ pb.int('boneIndex')
628
+ ], function() {
629
+ const boneTexture = this.$query(ShaderFramework.USAGE_BONE_MATRICIES);
630
+ this.$l.w = pb.float(this.$query(ShaderFramework.USAGE_BONE_TEXTURE_SIZE));
631
+ this.$l.pixelIndex = pb.float(pb.mul(this.boneIndex, 4));
632
+ this.$l.xIndex = pb.mod(this.pixelIndex, this.w);
633
+ this.$l.yIndex = pb.floor(pb.div(this.pixelIndex, this.w));
634
+ this.$l.u1 = pb.div(pb.add(this.xIndex, 0.5), this.w);
635
+ this.$l.u2 = pb.div(pb.add(this.xIndex, 1.5), this.w);
636
+ this.$l.u3 = pb.div(pb.add(this.xIndex, 2.5), this.w);
637
+ this.$l.u4 = pb.div(pb.add(this.xIndex, 3.5), this.w);
638
+ this.$l.v = pb.div(pb.add(this.yIndex, 0.5), this.w);
639
+ if (Application.instance.device.type !== 'webgl') {
640
+ this.$l.row1 = pb.textureSampleLevel(boneTexture, pb.vec2(this.u1, this.v), 0);
641
+ this.$l.row2 = pb.textureSampleLevel(boneTexture, pb.vec2(this.u2, this.v), 0);
642
+ this.$l.row3 = pb.textureSampleLevel(boneTexture, pb.vec2(this.u3, this.v), 0);
643
+ this.$l.row4 = pb.textureSampleLevel(boneTexture, pb.vec2(this.u4, this.v), 0);
644
+ } else {
645
+ this.$l.row1 = pb.textureSample(boneTexture, pb.vec2(this.u1, this.v));
646
+ this.$l.row2 = pb.textureSample(boneTexture, pb.vec2(this.u2, this.v));
647
+ this.$l.row3 = pb.textureSample(boneTexture, pb.vec2(this.u3, this.v));
648
+ this.$l.row4 = pb.textureSample(boneTexture, pb.vec2(this.u4, this.v));
649
+ }
650
+ this.$return(pb.mat4(this.row1, this.row2, this.row3, this.row4));
651
+ });
652
+ const funcNameGetSkinningMatrix = 'lib_getSkinningMatrix';
653
+ pb.func(funcNameGetSkinningMatrix, [], function() {
654
+ const invBindMatrix = this.$query(ShaderFramework.USAGE_INV_BIND_MATRIX);
655
+ const blendIndices = pb.getGlobalScope().$getVertexAttrib('blendIndices');
656
+ const blendWeights = pb.getGlobalScope().$getVertexAttrib('blendWeights');
657
+ this.$l.m0 = pb.getGlobalScope()[funcNameGetBoneMatrixFromTexture](pb.int(blendIndices[0]));
658
+ this.$l.m1 = pb.getGlobalScope()[funcNameGetBoneMatrixFromTexture](pb.int(blendIndices[1]));
659
+ this.$l.m2 = pb.getGlobalScope()[funcNameGetBoneMatrixFromTexture](pb.int(blendIndices[2]));
660
+ this.$l.m3 = pb.getGlobalScope()[funcNameGetBoneMatrixFromTexture](pb.int(blendIndices[3]));
661
+ this.$l.m = pb.add(pb.mul(this.m0, blendWeights.x), pb.mul(this.m1, blendWeights.y), pb.mul(this.m2, blendWeights.z), pb.mul(this.m3, blendWeights.w));
662
+ this.$return(pb.mul(invBindMatrix, this.m));
663
+ });
664
+ return pb.getGlobalScope()[funcNameGetSkinningMatrix]();
665
+ }
666
+ static applyFog(scope, color, ctx) {
667
+ if (ctx.applyFog) {
668
+ const pb = scope.$builder;
669
+ if (ctx.env.sky.drawScatteredFog(ctx)) {
670
+ const funcName = 'applyAerialPerspective';
671
+ pb.func(funcName, [
672
+ pb.vec4('color').inout()
673
+ ], function() {
674
+ this.$l.viewDir = pb.sub(ShaderFramework.getWorldPosition(this).xyz, ShaderFramework.getCameraPosition(this));
675
+ this.viewDir.y = pb.max(this.viewDir.y, 0);
676
+ this.$l.distance = pb.mul(pb.length(this.viewDir), ShaderFramework.getWorldUnit(this));
677
+ this.$l.sliceDist = pb.div(pb.mul(ShaderFramework.getCameraParams(this).y, ShaderFramework.getWorldUnit(this)), ScatteringLut.aerialPerspectiveSliceZ);
678
+ this.$l.slice0 = pb.floor(pb.div(this.distance, this.sliceDist));
679
+ this.$l.slice1 = pb.add(this.slice0, 1);
680
+ this.$l.factor = pb.sub(pb.div(this.distance, this.sliceDist), this.slice0);
681
+ this.$l.viewNormal = pb.normalize(this.viewDir);
682
+ this.$l.zenithAngle = pb.asin(this.viewNormal.y);
683
+ this.$l.horizonAngle = pb.atan2(this.viewNormal.z, this.viewNormal.x);
684
+ this.$l.u0 = pb.div(pb.add(this.slice0, pb.div(this.horizonAngle, Math.PI * 2)), ScatteringLut.aerialPerspectiveSliceZ);
685
+ this.$l.u1 = pb.add(this.u0, 1 / ScatteringLut.aerialPerspectiveSliceZ);
686
+ this.$l.v = pb.div(this.zenithAngle, Math.PI / 2);
687
+ this.$l.t0 = pb.textureSampleLevel(ShaderFramework.getAerialPerspectiveLUT(this), pb.vec2(this.u0, this.v), 0);
688
+ this.$l.t1 = pb.textureSampleLevel(ShaderFramework.getAerialPerspectiveLUT(this), pb.vec2(this.u1, this.v), 0);
689
+ this.$l.t = pb.mix(this.t0, this.t1, this.factor);
690
+ this.color = pb.vec4(pb.add(pb.mul(this.color.rgb, this.factor), this.t.rgb), this.color.a);
691
+ });
692
+ scope[funcName](color);
693
+ } else {
694
+ const funcName = 'applyFog';
695
+ pb.func(funcName, [
696
+ pb.vec4('color').inout()
697
+ ], function() {
698
+ this.$l.viewDir = pb.sub(ShaderFramework.getWorldPosition(this).xyz, ShaderFramework.getCameraPosition(this));
699
+ this.$l.fogFactor = ShaderFramework.computeFogFactor(this, this.viewDir, ShaderFramework.getFogType(this), ShaderFramework.getFogParams(this));
700
+ this.color = pb.vec4(pb.mix(this.color.rgb, ShaderFramework.getFogColor(this).rgb, pb.mul(this.fogFactor, this.color.a, this.color.a)), this.color.a);
701
+ });
702
+ scope[funcName](color);
703
+ }
704
+ }
705
+ }
706
+ }
707
+
708
+ export { ShaderFramework };
709
+ //# sourceMappingURL=framework.js.map