@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,165 @@
1
+ import { Application } from '../app.js';
2
+ import { drawFullscreenQuad } from '../render/helper.js';
3
+
4
+ /**
5
+ * Base class for any type of post effect
6
+ * @public
7
+ */ class AbstractPostEffect {
8
+ _outputTexture;
9
+ _quadVertexLayout;
10
+ _quadRenderStateSet;
11
+ _enabled;
12
+ _opaque;
13
+ _intermediateFramebuffers;
14
+ /**
15
+ * Creates an instance of a post effect
16
+ * @param name - Name of the post effect
17
+ */ constructor(){
18
+ this._outputTexture = null;
19
+ this._quadVertexLayout = null;
20
+ this._quadRenderStateSet = null;
21
+ this._enabled = true;
22
+ this._opaque = false;
23
+ this._intermediateFramebuffers = {};
24
+ }
25
+ /** Whether this post effect is enabled */ get enabled() {
26
+ return this._enabled;
27
+ }
28
+ set enabled(val) {
29
+ this._enabled = !!val;
30
+ }
31
+ /** Whether this post effect will be rendered at opaque phase */ get opaque() {
32
+ return this._opaque;
33
+ }
34
+ /**
35
+ * Check if the post effect should be rendered upside down.
36
+ * @param device - The device object
37
+ * @returns true if the post effect should be rendered upside down
38
+ */ needFlip(device) {
39
+ return device.type === 'webgpu' && !!device.getFramebuffer();
40
+ }
41
+ /**
42
+ * Adds an intermediate frame buffer
43
+ * @param name - Name of the frame buffer
44
+ * @param format - Render target texture format
45
+ * @param useDepth - Whether the scene depth buffer should be attached to the frame buffer
46
+ */ addIntermediateFramebuffer(name, depth) {
47
+ if (this._intermediateFramebuffers[name]) {
48
+ throw new Error(`Intermediate framebuffer already exists: ${name}`);
49
+ }
50
+ this._intermediateFramebuffers[name] = {
51
+ depth,
52
+ framebuffer: null
53
+ };
54
+ }
55
+ /**
56
+ * Gets the intermediate frame buffer by name
57
+ * @param name - Name of the intermediate frame buffer
58
+ * @param width - Width of the frame buffer
59
+ * @param height - Height of the frame buffer
60
+ * @returns The intermediate frame buffer or null if not exists
61
+ *
62
+ * @remarks
63
+ * The intemediate buffer will be resized to fit the given size if needed
64
+ */ getIntermediateFramebuffer(name, format, width, height) {
65
+ const fb = this._intermediateFramebuffers[name];
66
+ if (!fb) {
67
+ return null;
68
+ }
69
+ const device = Application.instance.device;
70
+ const currentDepthBuffer = device.getFramebuffer().getDepthAttachment();
71
+ if (fb.framebuffer) {
72
+ const colorTex = fb.framebuffer.getColorAttachments()[0];
73
+ const depthTex = fb.framebuffer.getDepthAttachment();
74
+ if (colorTex.width !== width || colorTex.height !== height || colorTex.format !== format) {
75
+ fb.framebuffer.dispose();
76
+ colorTex.dispose();
77
+ if (depthTex && depthTex !== currentDepthBuffer) {
78
+ depthTex.dispose();
79
+ }
80
+ fb.framebuffer = null;
81
+ }
82
+ }
83
+ if (!fb.framebuffer) {
84
+ const colorTex = device.createTexture2D(format, width, height, {
85
+ samplerOptions: {
86
+ mipFilter: 'none'
87
+ }
88
+ });
89
+ colorTex.name = `Intermediate-<${name}>`;
90
+ let depthTex = null;
91
+ if (fb.depth === 'current') {
92
+ depthTex = currentDepthBuffer;
93
+ } else if (fb.depth === 'temporal') {
94
+ depthTex = device.createTexture2D('d24s8', width, height);
95
+ depthTex.name = `Intermediate-<${name}>-depth`;
96
+ }
97
+ fb.framebuffer = device.createFrameBuffer([
98
+ colorTex
99
+ ], depthTex);
100
+ }
101
+ return fb.framebuffer;
102
+ }
103
+ /**
104
+ * Disposes the post effect.
105
+ */ dispose() {
106
+ this._quadVertexLayout?.dispose();
107
+ this._quadVertexLayout = null;
108
+ this._quadRenderStateSet = null;
109
+ for(const k in this._intermediateFramebuffers){
110
+ const fb = this._intermediateFramebuffers[k];
111
+ if (fb) {
112
+ const colorAttachment = fb.framebuffer.getColorAttachments()[0];
113
+ fb.framebuffer.dispose();
114
+ colorAttachment.dispose();
115
+ }
116
+ }
117
+ this._intermediateFramebuffers = {};
118
+ }
119
+ /**
120
+ * Draws a fullscreen quad
121
+ * @param renderStateSet - Render states that will be used when drawing the fullscreen quad.
122
+ */ drawFullscreenQuad(renderStateSet) {
123
+ drawFullscreenQuad(renderStateSet);
124
+ /*
125
+ const device = Application.instance.device;
126
+ if (!this._quadVertexLayout) {
127
+ this._quadVertexLayout = this.createVertexLayout(device);
128
+ }
129
+ if (!this._quadRenderStateSet) {
130
+ this._quadRenderStateSet = this.createRenderStates(device);
131
+ }
132
+ const lastRenderState = device.getRenderStates();
133
+ device.setVertexLayout(this._quadVertexLayout);
134
+ device.setRenderStates(renderStateSet ?? this._quadRenderStateSet);
135
+ device.draw('triangle-strip', 0, 4);
136
+ device.setRenderStates(lastRenderState);
137
+ */ }
138
+ /** @internal */ createVertexLayout(device) {
139
+ return device.createVertexLayout({
140
+ vertexBuffers: [
141
+ {
142
+ buffer: device.createVertexBuffer('position_f32x2', new Float32Array([
143
+ -1,
144
+ -1,
145
+ 1,
146
+ -1,
147
+ -1,
148
+ 1,
149
+ 1,
150
+ 1
151
+ ]))
152
+ }
153
+ ]
154
+ });
155
+ }
156
+ /** @internal */ createRenderStates(device) {
157
+ const renderStates = device.createRenderStateSet();
158
+ renderStates.useRasterizerState().setCullMode('none');
159
+ renderStates.useDepthState().enableTest(false).enableWrite(false);
160
+ return renderStates;
161
+ }
162
+ }
163
+
164
+ export { AbstractPostEffect };
165
+ //# sourceMappingURL=posteffect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"posteffect.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,327 @@
1
+ import { isFloatTextureFormat } from '@zephyr3d/device';
2
+ import { Application } from '../app.js';
3
+ import { AbstractPostEffect } from './posteffect.js';
4
+ import { decodeNormalizedFloatFromRGBA, encodeNormalizedFloatToRGBA } from '../shaders/misc.js';
5
+ import { Vector2, Vector4, Matrix4x4 } from '@zephyr3d/base';
6
+ import { AOBilateralBlurBlitter } from '../blitter/depthlimitedgaussion.js';
7
+ import '../shaders/framework.js';
8
+ import { CopyBlitter } from '../blitter/copy.js';
9
+ import '../scene/octree.js';
10
+ import '../material/material.js';
11
+ import '../render/scatteringlut.js';
12
+ import '../material/lambert.js';
13
+ import '../material/blinn.js';
14
+ import '../material/unlit.js';
15
+ import '../material/lightmodel.js';
16
+ import '../render/forward.js';
17
+ import '../render/sky.js';
18
+ import '../render/clipmap.js';
19
+ import { TemporalCache } from '../render/temporalcache.js';
20
+ import '../render/watermesh.js';
21
+
22
+ const NUM_SAMPLES = 7;
23
+ const NUM_RINGS = 4;
24
+ /**
25
+ * The Scalable Ambient Obscurance (SAO) post effect
26
+ * @public
27
+ */ class SAO extends AbstractPostEffect {
28
+ static _nearestSampler = null;
29
+ static _program = null;
30
+ static _programPacked = null;
31
+ static _renderState = null;
32
+ static _renderStateBlend = null;
33
+ _bindgroup;
34
+ _bindgroupPacked;
35
+ _saoScale;
36
+ _saoBias;
37
+ _saoIntensity;
38
+ _saoRadius;
39
+ _saoMinResolution;
40
+ _saoRandomSeed;
41
+ _saoBlurDepthCutoff;
42
+ _blitterH;
43
+ _blitterV;
44
+ _copyBlitter;
45
+ _supported;
46
+ /**
47
+ * Creates an instance of SAO post effect
48
+ */ constructor(){
49
+ super();
50
+ this._bindgroup = null;
51
+ this._bindgroupPacked = null;
52
+ this._supported = true;
53
+ this._opaque = true;
54
+ this._saoScale = 10;
55
+ this._saoBias = 1;
56
+ this._saoIntensity = 0.05;
57
+ this._saoRadius = 100;
58
+ this._saoMinResolution = 0;
59
+ this._saoRandomSeed = 0;
60
+ this._saoBlurDepthCutoff = 1;
61
+ this._blitterH = new AOBilateralBlurBlitter(false);
62
+ this._blitterH.kernelRadius = 8;
63
+ this._blitterH.stdDev = 10;
64
+ this._blitterV = new AOBilateralBlurBlitter(true);
65
+ this._blitterV.kernelRadius = 8;
66
+ this._blitterV.stdDev = 10;
67
+ this._copyBlitter = new CopyBlitter();
68
+ this.addIntermediateFramebuffer('ao', 'current');
69
+ this.addIntermediateFramebuffer('blur', 'current');
70
+ }
71
+ /** Scale value */ get scale() {
72
+ return this._saoScale;
73
+ }
74
+ set scale(val) {
75
+ this._saoScale = val;
76
+ }
77
+ /** Bias value */ get bias() {
78
+ return this._saoBias;
79
+ }
80
+ set bias(val) {
81
+ this._saoBias = val;
82
+ }
83
+ /** Radius value */ get radius() {
84
+ return this._saoRadius;
85
+ }
86
+ set radius(val) {
87
+ this._saoRadius = val;
88
+ }
89
+ /** SAO intensity */ get intensity() {
90
+ return this._saoIntensity;
91
+ }
92
+ set intensity(val) {
93
+ this._saoIntensity = val;
94
+ }
95
+ /** Minimum resolution */ get minResolution() {
96
+ return this._saoMinResolution;
97
+ }
98
+ set minResolution(val) {
99
+ this._saoMinResolution = val;
100
+ }
101
+ /** Blur kernel size */ get blurKernelSize() {
102
+ return this._blitterH.kernelRadius;
103
+ }
104
+ set blurKernelSize(val) {
105
+ val = Math.min(64, Math.max(0, val >> 0));
106
+ this._blitterH.kernelRadius = val;
107
+ this._blitterV.kernelRadius = val;
108
+ }
109
+ /** Gaussian blur stddev value */ get blurStdDev() {
110
+ return this._blitterH.stdDev;
111
+ }
112
+ set blurStdDev(val) {
113
+ this._blitterH.stdDev = val;
114
+ this._blitterV.stdDev = val;
115
+ }
116
+ /** Cutoff of depth limited blur */ get blurDepthCutoff() {
117
+ return this._saoBlurDepthCutoff;
118
+ }
119
+ set blurDepthCutoff(val) {
120
+ this._saoBlurDepthCutoff = val;
121
+ }
122
+ /** {@inheritDoc AbstractPostEffect.requireLinearDepthTexture} */ requireLinearDepthTexture() {
123
+ return true;
124
+ }
125
+ /** {@inheritDoc AbstractPostEffect.requireDepthAttachment} */ requireDepthAttachment() {
126
+ return true;
127
+ }
128
+ /** {@inheritDoc AbstractPostEffect.apply} */ apply(ctx, inputColorTexture, sceneDepthTexture, srgbOutput) {
129
+ const device = Application.instance.device;
130
+ const viewport = device.getViewport();
131
+ this._prepare(device, inputColorTexture);
132
+ this._copyBlitter.srgbOut = srgbOutput;
133
+ this._copyBlitter.blit(inputColorTexture, device.getFramebuffer(), SAO._nearestSampler);
134
+ if (!this._supported) {
135
+ return;
136
+ }
137
+ const fmt = this._getIntermediateTextureFormat(device);
138
+ const depth = device.getFramebuffer().getDepthAttachment();
139
+ const fbao = ctx.defaultViewport ? TemporalCache.getFramebufferVariantSizeWithDepth(depth, 1, fmt, '2d', false) : TemporalCache.getFramebufferFixedSizeWithDepth(depth, 1, fmt, '2d', false);
140
+ const fbblur = ctx.defaultViewport ? TemporalCache.getFramebufferVariantSizeWithDepth(depth, 1, fmt, '2d', false) : TemporalCache.getFramebufferFixedSizeWithDepth(depth, 1, fmt, '2d', false);
141
+ const packed = fbao.getColorAttachments()[0].format === 'rgba8unorm';
142
+ const cameraNearFar = new Vector2(ctx.camera.getNearPlane(), ctx.camera.getFarPlane());
143
+ device.pushDeviceStates();
144
+ device.setFramebuffer(fbao);
145
+ device.clearFrameBuffer(packed ? new Vector4(0, 0, 0, 1) : new Vector4(1, 0, 0, 1), null, null);
146
+ const bindgroup = packed ? this._bindgroupPacked : this._bindgroup;
147
+ bindgroup.setValue('flip', this.needFlip(device) ? 1 : 0);
148
+ bindgroup.setTexture('depthTex', sceneDepthTexture);
149
+ bindgroup.setValue('scale', this._saoScale);
150
+ bindgroup.setValue('invProj', Matrix4x4.invert(ctx.camera.getProjectionMatrix()));
151
+ bindgroup.setValue('bias', this._saoBias);
152
+ bindgroup.setValue('cameraNearFar', cameraNearFar);
153
+ bindgroup.setValue('intensity', this._saoIntensity);
154
+ bindgroup.setValue('kernelRadius', this._saoRadius);
155
+ bindgroup.setValue('minResolution', this._saoMinResolution);
156
+ bindgroup.setValue('size', new Vector2(viewport.width, viewport.height));
157
+ bindgroup.setValue('randomSeed', this._saoRandomSeed);
158
+ device.setRenderStates(SAO._renderState);
159
+ device.setProgram(packed ? SAO._programPacked : SAO._program);
160
+ device.setBindGroup(0, bindgroup);
161
+ this.drawFullscreenQuad(SAO._renderState);
162
+ this._blitterH.size = new Vector2(inputColorTexture.width, inputColorTexture.height);
163
+ this._blitterH.depthTex = sceneDepthTexture;
164
+ this._blitterH.depthCutoff = this._saoBlurDepthCutoff / ctx.camera.getFarPlane();
165
+ this._blitterH.nearestSampler = SAO._nearestSampler;
166
+ this._blitterH.cameraNearFar = cameraNearFar;
167
+ this._blitterH.packed = packed;
168
+ this._blitterH.renderStates = SAO._renderState;
169
+ this._blitterV.size = new Vector2(inputColorTexture.width, inputColorTexture.height);
170
+ this._blitterV.depthTex = sceneDepthTexture;
171
+ this._blitterV.depthCutoff = this._saoBlurDepthCutoff / ctx.camera.getFarPlane();
172
+ this._blitterV.nearestSampler = SAO._nearestSampler;
173
+ this._blitterV.cameraNearFar = cameraNearFar;
174
+ this._blitterV.packed = packed;
175
+ this._blitterV.srgbOut = srgbOutput;
176
+ this._blitterV.renderStates = SAO._renderStateBlend;
177
+ this._blitterH.blit(fbao.getColorAttachments()[0], fbblur);
178
+ device.popDeviceStates();
179
+ this._blitterV.blit(fbblur.getColorAttachments()[0], device.getFramebuffer());
180
+ TemporalCache.releaseFramebuffer(fbao);
181
+ TemporalCache.releaseFramebuffer(fbblur);
182
+ }
183
+ _getIntermediateTextureFormat(device) {
184
+ const texCaps = device.getDeviceCaps().textureCaps;
185
+ return device.type === 'webgl' || !texCaps.supportHalfFloatColorBuffer && !texCaps.supportFloatColorBuffer ? 'rgba8unorm' : texCaps.supportHalfFloatColorBuffer ? 'r16f' : 'r32f';
186
+ }
187
+ /** @internal */ _prepare(device, srcTexture) {
188
+ const fb = device.getFramebuffer();
189
+ const isFloatFramebuffer = fb && isFloatTextureFormat(fb.getColorAttachments()[0].format);
190
+ this._supported = !isFloatFramebuffer || device.getDeviceCaps().framebufferCaps.supportFloatBlending;
191
+ if (this._supported) {
192
+ if (!SAO._nearestSampler) {
193
+ SAO._nearestSampler = device.createSampler({
194
+ magFilter: 'nearest',
195
+ minFilter: 'nearest',
196
+ mipFilter: 'none',
197
+ addressU: 'clamp',
198
+ addressV: 'clamp'
199
+ });
200
+ }
201
+ if (!SAO._renderState) {
202
+ SAO._renderState = device.createRenderStateSet();
203
+ SAO._renderState.useDepthState().enableTest(true).enableWrite(false).setCompareFunc('gt');
204
+ SAO._renderState.useRasterizerState().setCullMode('none');
205
+ SAO._renderStateBlend = device.createRenderStateSet();
206
+ SAO._renderStateBlend.useDepthState().enableTest(true).enableWrite(false).setCompareFunc('gt');
207
+ SAO._renderStateBlend.useRasterizerState().setCullMode('none');
208
+ SAO._renderStateBlend.useBlendingState().enable(true).setBlendFuncRGB('zero', 'src-color').setBlendFuncAlpha('zero', 'one');
209
+ }
210
+ function createProgram(packed) {
211
+ return device.buildRenderProgram({
212
+ vertex (pb) {
213
+ this.flip = pb.int().uniform(0);
214
+ this.$inputs.pos = pb.vec2().attrib('position');
215
+ this.$outputs.uv = pb.vec2();
216
+ pb.main(function() {
217
+ this.$builtins.position = pb.vec4(this.$inputs.pos, 1, 1);
218
+ this.$outputs.uv = pb.add(pb.mul(this.$inputs.pos.xy, 0.5), pb.vec2(0.5));
219
+ this.$if(pb.notEqual(this.flip, 0), function() {
220
+ this.$builtins.position.y = pb.neg(this.$builtins.position.y);
221
+ });
222
+ });
223
+ },
224
+ fragment (pb) {
225
+ this.depthTex = pb.tex2D().sampleType('unfilterable-float').uniform(0);
226
+ this.scale = pb.float().uniform(0);
227
+ this.invProj = pb.mat4().uniform(0);
228
+ this.cameraNearFar = pb.vec2().uniform(0);
229
+ this.intensity = pb.float().uniform(0);
230
+ this.bias = pb.float().uniform(0);
231
+ this.kernelRadius = pb.float().uniform(0);
232
+ this.minResolution = pb.float().uniform(0);
233
+ this.size = pb.vec2().uniform(0);
234
+ this.randomSeed = pb.float().uniform(0);
235
+ this.$l.scaleDividedByCameraFar = pb.float();
236
+ this.$l.minResolutionMultipliedByCameraFar = pb.float();
237
+ pb.func('rand', [
238
+ pb.vec2('uv')
239
+ ], function() {
240
+ this.$l.a = 12.9898;
241
+ this.$l.b = 78.233;
242
+ this.$l.c = 43758.5453;
243
+ this.$l.dt = pb.dot(this.uv, pb.vec2(this.a, this.b));
244
+ this.$l.sn = pb.mod(this.dt, Math.PI);
245
+ this.$return(pb.fract(pb.mul(pb.sin(this.sn), this.c)));
246
+ });
247
+ pb.func('getPositionVS', [
248
+ pb.vec2('uv')
249
+ ], function() {
250
+ this.$l.depthValue = pb.textureSample(this.depthTex, this.uv);
251
+ if (device.type === 'webgl') {
252
+ this.$l.linearDepth = decodeNormalizedFloatFromRGBA(this, this.depthValue);
253
+ } else {
254
+ this.$l.linearDepth = this.depthValue.r;
255
+ }
256
+ this.$l.nonLinearDepth = pb.div(pb.sub(pb.div(this.cameraNearFar.x, this.linearDepth), this.cameraNearFar.y), pb.sub(this.cameraNearFar.x, this.cameraNearFar.y));
257
+ this.$l.clipSpacePos = pb.vec4(pb.sub(pb.mul(this.uv, 2), pb.vec2(1)), pb.sub(pb.mul(this.nonLinearDepth, 2), 1), 1);
258
+ // this.$l.clipSpacePos = pb.vec4(this.uv, this.nonLinearDepth, 1);
259
+ this.$l.vPos = pb.mul(this.invProj, this.clipSpacePos);
260
+ this.vPos = pb.div(this.vPos, this.vPos.w);
261
+ this.$return(this.vPos.xyz);
262
+ });
263
+ pb.func('getOcclusion', [
264
+ pb.vec3('centerPos'),
265
+ pb.vec3('centerNormal'),
266
+ pb.vec3('samplePos')
267
+ ], function() {
268
+ this.$l.viewDelta = pb.sub(this.samplePos, this.centerPos);
269
+ this.$l.viewDistance = pb.length(this.viewDelta);
270
+ this.$l.scaledScreenDistance = pb.mul(this.scaleDividedByCameraFar, this.viewDistance);
271
+ this.$return(pb.div(pb.max(0, pb.sub(pb.div(pb.sub(pb.dot(this.centerNormal, this.viewDelta), this.minResolutionMultipliedByCameraFar), this.scaledScreenDistance), this.bias)), pb.add(pb.mul(this.scaledScreenDistance, this.scaledScreenDistance), 1)));
272
+ });
273
+ pb.func('getAO', [
274
+ pb.vec3('vPos')
275
+ ], function() {
276
+ this.scaleDividedByCameraFar = pb.div(this.scale, this.cameraNearFar.y);
277
+ this.minResolutionMultipliedByCameraFar = pb.mul(this.minResolution, this.cameraNearFar.y);
278
+ this.$l.centerViewNormal = pb.normalize(pb.cross(pb.dpdx(this.vPos), pb.dpdy(this.vPos)));
279
+ this.$l.angle = pb.mul(this.rand(pb.add(this.$inputs.uv, pb.vec2(this.randomSeed))), Math.PI * 2);
280
+ this.$l.radius = pb.div(pb.vec2(pb.mul(this.kernelRadius, 1 / NUM_SAMPLES)), this.size);
281
+ this.$l.radiusStep = this.radius;
282
+ this.$l.occlusionSum = pb.float(0);
283
+ this.$l.weightSum = pb.float(0);
284
+ this.$for(pb.int('i'), 0, NUM_SAMPLES, function() {
285
+ this.$l.sampleUV = pb.add(this.$inputs.uv, pb.mul(pb.vec2(pb.cos(this.angle), pb.sin(this.angle)), this.radius));
286
+ this.radius = pb.add(this.radius, this.radiusStep);
287
+ this.angle = pb.add(this.angle, Math.PI * NUM_RINGS / NUM_SAMPLES);
288
+ this.samplePos = this.getPositionVS(this.sampleUV);
289
+ this.occlusionSum = pb.add(this.occlusionSum, this.getOcclusion(this.vPos, this.centerViewNormal, this.samplePos));
290
+ this.weightSum = pb.add(this.weightSum, 1);
291
+ });
292
+ this.$if(pb.equal(this.weightSum, 0), function() {
293
+ pb.discard();
294
+ });
295
+ this.$return(pb.div(pb.mul(this.occlusionSum, this.intensity), this.weightSum));
296
+ });
297
+ pb.main(function() {
298
+ this.$l.vPos = this.getPositionVS(this.$inputs.uv);
299
+ this.$l.ao = pb.clamp(pb.sub(1, this.getAO(this.vPos)), 0, packed ? 0.999 : 1);
300
+ if (packed) {
301
+ this.$outputs.outColor = encodeNormalizedFloatToRGBA(this, this.ao);
302
+ } else {
303
+ this.$outputs.outColor = pb.vec4(this.ao, this.ao, this.ao, 1);
304
+ }
305
+ });
306
+ }
307
+ });
308
+ }
309
+ if (!SAO._program) {
310
+ SAO._program = createProgram(false);
311
+ SAO._programPacked = createProgram(true);
312
+ }
313
+ if (!this._bindgroup) {
314
+ this._bindgroup = device.createBindGroup(SAO._program.bindGroupLayouts[0]);
315
+ this._bindgroupPacked = device.createBindGroup(SAO._programPacked.bindGroupLayouts[0]);
316
+ }
317
+ }
318
+ }
319
+ /** {@inheritDoc AbstractPostEffect.dispose} */ dispose() {
320
+ super.dispose();
321
+ this._bindgroup?.dispose();
322
+ this._bindgroup = null;
323
+ }
324
+ }
325
+
326
+ export { SAO };
327
+ //# sourceMappingURL=sao.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sao.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,112 @@
1
+ import { Application } from '../app.js';
2
+ import { AbstractPostEffect } from './posteffect.js';
3
+ import { linearToGamma } from '../shaders/misc.js';
4
+
5
+ /**
6
+ * The tonemap post effect
7
+ * @public
8
+ */ class Tonemap extends AbstractPostEffect {
9
+ static _nearestSampler = null;
10
+ static _programTonemap = null;
11
+ _bindgroupTonemap;
12
+ _exposure;
13
+ /**
14
+ * Creates an instance of tonemap post effect
15
+ */ constructor(){
16
+ super();
17
+ this._bindgroupTonemap = null;
18
+ this._opaque = false;
19
+ this._exposure = 1;
20
+ }
21
+ /** Exposure value */ get exposure() {
22
+ return this._exposure;
23
+ }
24
+ set exposure(val) {
25
+ this._exposure = val;
26
+ }
27
+ /** {@inheritDoc AbstractPostEffect.requireLinearDepthTexture} */ requireLinearDepthTexture() {
28
+ return false;
29
+ }
30
+ /** {@inheritDoc AbstractPostEffect.requireDepthAttachment} */ requireDepthAttachment() {
31
+ return false;
32
+ }
33
+ /** {@inheritDoc AbstractPostEffect.apply} */ apply(ctx, inputColorTexture, sceneDepthTexture, srgbOutput) {
34
+ const device = Application.instance.device;
35
+ this._prepare(device, inputColorTexture);
36
+ this._tonemap(device, inputColorTexture, srgbOutput);
37
+ }
38
+ /** @internal */ _tonemap(device, inputColorTexture, sRGBOutput) {
39
+ this._bindgroupTonemap.setValue('srgbOut', sRGBOutput ? 1 : 0);
40
+ this._bindgroupTonemap.setValue('exposure', this._exposure);
41
+ this._bindgroupTonemap.setValue('flip', this.needFlip(device) ? 1 : 0);
42
+ this._bindgroupTonemap.setTexture('tex', inputColorTexture, Tonemap._nearestSampler);
43
+ device.setProgram(Tonemap._programTonemap);
44
+ device.setBindGroup(0, this._bindgroupTonemap);
45
+ this.drawFullscreenQuad();
46
+ }
47
+ /** @internal */ _prepare(device, srcTexture) {
48
+ if (!Tonemap._programTonemap) {
49
+ Tonemap._programTonemap = device.buildRenderProgram({
50
+ vertex (pb) {
51
+ this.flip = pb.int().uniform(0);
52
+ this.$inputs.pos = pb.vec2().attrib('position');
53
+ this.$outputs.uv = pb.vec2();
54
+ pb.main(function() {
55
+ this.$builtins.position = pb.vec4(this.$inputs.pos, 0, 1);
56
+ this.$outputs.uv = pb.add(pb.mul(this.$inputs.pos.xy, 0.5), pb.vec2(0.5));
57
+ this.$if(pb.notEqual(this.flip, 0), function() {
58
+ this.$builtins.position.y = pb.neg(this.$builtins.position.y);
59
+ });
60
+ });
61
+ },
62
+ fragment (pb) {
63
+ this.srgbOut = pb.int().uniform(0);
64
+ this.exposure = pb.float().uniform(0);
65
+ this.tex = pb.tex2D().uniform(0);
66
+ this.$outputs.outColor = pb.vec4();
67
+ pb.func('RRTAndODTFit', [
68
+ pb.vec3('v')
69
+ ], function() {
70
+ this.$l.a = pb.sub(pb.mul(this.v, pb.add(this.v, pb.vec3(0.0245786))), pb.vec3(0.000090537));
71
+ this.$l.b = pb.add(pb.mul(this.v, pb.add(pb.mul(this.v, 0.983729), pb.vec3(0.4329510))), pb.vec3(0.238081));
72
+ this.$return(pb.div(this.a, this.b));
73
+ });
74
+ pb.main(function() {
75
+ this.$l.vSample = pb.textureSample(this.tex, this.$inputs.uv);
76
+ this.$l.ACESInputMat = pb.mat3(0.59719, 0.07600, 0.02840, 0.35458, 0.90834, 0.13383, 0.04823, 0.01566, 0.83777);
77
+ this.$l.ACESOutputMat = pb.mat3(1.60475, -0.10208, -0.00327, -0.53108, 1.10813, -0.07276, -0.07367, -0.00605, 1.07602);
78
+ this.$l.color = pb.mul(this.vSample.rgb, pb.div(this.exposure, 0.6));
79
+ this.color = pb.mul(this.ACESInputMat, this.color);
80
+ this.color = this.RRTAndODTFit(this.color);
81
+ this.color = pb.mul(this.ACESOutputMat, this.color);
82
+ this.color = pb.clamp(this.color, pb.vec3(0), pb.vec3(1));
83
+ this.$if(pb.notEqual(this.srgbOut, 0), function() {
84
+ this.$l.color = linearToGamma(this, this.color);
85
+ });
86
+ this.$outputs.outColor = pb.vec4(this.color, 1);
87
+ });
88
+ }
89
+ });
90
+ }
91
+ if (!this._bindgroupTonemap) {
92
+ this._bindgroupTonemap = device.createBindGroup(Tonemap._programTonemap.bindGroupLayouts[0]);
93
+ }
94
+ if (!Tonemap._nearestSampler) {
95
+ Tonemap._nearestSampler = device.createSampler({
96
+ magFilter: 'nearest',
97
+ minFilter: 'nearest',
98
+ mipFilter: 'none',
99
+ addressU: 'clamp',
100
+ addressV: 'clamp'
101
+ });
102
+ }
103
+ }
104
+ /** {@inheritDoc AbstractPostEffect.dispose} */ dispose() {
105
+ super.dispose();
106
+ this._bindgroupTonemap?.dispose();
107
+ this._bindgroupTonemap = null;
108
+ }
109
+ }
110
+
111
+ export { Tonemap };
112
+ //# sourceMappingURL=tonemap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tonemap.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}