@woosh/meep-engine 2.40.0 → 2.41.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 (68) hide show
  1. package/core/binary/BinaryBuffer.js +6 -1
  2. package/core/collection/HashMap.d.ts +2 -0
  3. package/core/collection/HashMap.js +22 -0
  4. package/core/geom/3d/normal/hemioct/encode_unit3_hemioct.js +5 -0
  5. package/core/geom/3d/normal/octahedron/decode_octahedron_to_unit.js +31 -0
  6. package/core/geom/3d/normal/octahedron/encode_unit_to_octahedron.js +33 -0
  7. package/core/geom/3d/normal/octahedron/encoding.spec.js +29 -0
  8. package/core/geom/3d/topology/struct/BinaryTopology.js +112 -0
  9. package/core/geom/Quaternion.js +8 -8
  10. package/core/geom/Quaternion.spec.js +13 -0
  11. package/core/geom/Vector1.d.ts +2 -0
  12. package/core/math/sign_not_zero.js +8 -0
  13. package/core/parser/simple/SimpleParser.js +3 -86
  14. package/core/parser/simple/readUnsignedInteger.js +66 -0
  15. package/core/parser/simple/skipWhitespace.js +21 -0
  16. package/editor/view/ecs/components/common/NumberController.js +24 -6
  17. package/engine/EngineHarness.js +6 -1
  18. package/engine/asset/AssetDescription.spec.js +27 -0
  19. package/engine/asset/loaders/GLTFAssetLoader.js +5 -3
  20. package/engine/asset/loaders/image/png/PNG.js +6 -0
  21. package/engine/asset/loaders/image/png/PNGReader.js +41 -0
  22. package/engine/ecs/foliage/ImpostorFoliage.js +4 -0
  23. package/engine/ecs/terrain/tiles/TerrainTile.js +2 -0
  24. package/engine/graphics/ecs/mesh-v2/three_object_to_entity_composition.js +22 -7
  25. package/engine/graphics/filter/ImageFilter.js +2 -1
  26. package/engine/graphics/geometry/MikkT/MikkTSpace.spec.js +7 -1
  27. package/engine/{asset/loaders/geometry/geometry → graphics/geometry/buffered}/computeBufferAttributeHash.js +1 -1
  28. package/engine/{asset/loaders/geometry/geometry → graphics/geometry/buffered}/computeGeometryEquality.js +2 -2
  29. package/engine/{asset/loaders/geometry/geometry → graphics/geometry/buffered}/computeGeometryHash.js +1 -1
  30. package/engine/graphics/geometry/optimization/merge/merge_geometry_hierarchy.js +2 -2
  31. package/engine/graphics/impostors/card_cluster/FacePlaneAssignment.js +30 -0
  32. package/engine/graphics/impostors/card_cluster/README.md +13 -0
  33. package/engine/graphics/impostors/octahedral/ImpostorBaker.js +332 -0
  34. package/engine/graphics/impostors/octahedral/ImpostorCaptureType.js +10 -0
  35. package/engine/graphics/impostors/octahedral/ImpostorDescription.js +63 -0
  36. package/engine/graphics/impostors/octahedral/README.md +29 -0
  37. package/engine/graphics/impostors/octahedral/bake/compute_bounding_sphere.js +42 -0
  38. package/engine/graphics/impostors/octahedral/bake/prepare_bake_material.js +88 -0
  39. package/engine/graphics/impostors/octahedral/grid/HemiOctahedralUvEncoder.js +20 -0
  40. package/engine/graphics/impostors/octahedral/grid/OctahedralUvEncoder.js +25 -0
  41. package/engine/graphics/impostors/octahedral/grid/UvEncoder.js +21 -0
  42. package/engine/graphics/impostors/octahedral/prototypeBaker.js +138 -0
  43. package/engine/graphics/impostors/octahedral/shader/BakeShaderStandard.js +157 -0
  44. package/engine/graphics/impostors/octahedral/shader/ImpostorShaderStandard.js +306 -0
  45. package/engine/graphics/impostors/octahedral/shader/glsl/common.glsl +206 -0
  46. package/engine/graphics/micron/convert_three_object_to_micron.js +2 -2
  47. package/engine/graphics/micron/plugin/MicronRenderPlugin.js +2 -2
  48. package/engine/graphics/particles/node-based/codegen/CodeGenerator.js +1 -1
  49. package/engine/graphics/particles/node-based/nodes/noise/CurlNoiseNode.js +1 -1
  50. package/engine/graphics/render/forward_plus/LightManager.js +25 -0
  51. package/engine/graphics/render/forward_plus/data/TextureBackedMemoryRegion.js +6 -2
  52. package/engine/graphics/render/forward_plus/materials/FP_SHADER_CHUNK_ACCUMULATION.js +6 -11
  53. package/engine/graphics/render/forward_plus/prototype/prototypeLightManager.js +268 -2
  54. package/engine/graphics/render/visibility/hiz/buildCanvasViewFromTexture.js +32 -10
  55. package/engine/graphics/shaders/ScreenSpaceQuadShader.js +4 -14
  56. package/engine/graphics/shaders/glsl_gen_swizzled_read.js +39 -0
  57. package/engine/graphics/texture/atlas/AtlasPatch.js +12 -6
  58. package/engine/logging/ConsoleLoggerBackend.js +15 -0
  59. package/engine/logging/Logger.js +24 -1
  60. package/engine/logging/LoggerBackend.js +1 -0
  61. package/engine/physics/fluid/FluidField.js +9 -0
  62. package/engine/physics/fluid/effector/AbstractFluidEffector.js +6 -0
  63. package/engine/physics/fluid/effector/GlobalFluidEffector.js +12 -0
  64. package/engine/physics/fluid/effector/WakeFluidEffector.js +8 -0
  65. package/engine/ui/GUIEngine.js +8 -1
  66. package/package.json +1 -1
  67. package/view/tooltip/gml/parser/readReferenceToken.js +1 -1
  68. package/engine/asset/GameAssetManager.js +0 -137
@@ -0,0 +1,306 @@
1
+ import { GLSL3, NoBlending, RawShaderMaterial, Vector3 } from "three";
2
+ import chunk_preamble from './glsl/common.glsl';
3
+
4
+ const shader_vx = `
5
+
6
+ in vec2 uv;
7
+ in vec3 position;
8
+
9
+ out vec2 vUv;
10
+ out vec4 plane0;
11
+ out vec4 plane1;
12
+ out vec4 plane2;
13
+
14
+ ${chunk_preamble}
15
+
16
+ void ImposterVertex( inout ImposterData imp )
17
+ {
18
+ //incoming vertex, object space
19
+ vec4 vertex = imp.vertex;
20
+
21
+ //camera in object space
22
+ vec3 objectSpaceCameraPos = mul( unity_WorldToObject, float4(_WorldSpaceCameraPos.xyz,1) ).xyz;
23
+ vec2 texcoord = imp.uv;
24
+ float4x4 objectToWorld = unity_ObjectToWorld;
25
+ float4x4 worldToObject = unity_WorldToObject;
26
+
27
+ vec3 imposterPivotOffset = _ImposterOffset.xyz;
28
+ half framesMinusOne = _ImposterFrames-1;
29
+
30
+ float3 objectScale = float3(length(float3(objectToWorld[0].x, objectToWorld[1].x, objectToWorld[2].x)),
31
+ length(float3(objectToWorld[0].y, objectToWorld[1].y, objectToWorld[2].y)),
32
+ length(float3(objectToWorld[0].z, objectToWorld[1].z, objectToWorld[2].z)));
33
+
34
+ //pivot to camera ray
35
+ float3 pivotToCameraRay = normalize(objectSpaceCameraPos.xyz-imposterPivotOffset.xyz);
36
+
37
+ //scale uv to single frame
38
+ texcoord = vec2(texcoord.x,texcoord.y)*(1.0/_ImposterFrames.x);
39
+
40
+ //radius * 2 * unity scaling
41
+ vec2 size = _ImposterSize.xx * 2.0; // * objectScale.xx; //unity_BillboardSize.xy
42
+
43
+ vec3 projected = SpriteProjection( pivotToCameraRay, _ImposterFrames, size, texcoord.xy );
44
+
45
+ //this creates the proper offset for vertices to camera facing billboard
46
+ vec3 vertexOffset = projected + imposterPivotOffset;
47
+ //subtract from camera pos
48
+ vertexOffset = normalize(objectSpaceCameraPos-vertexOffset);
49
+ //then add the original projected world
50
+ vertexOffset += projected;
51
+ //remove position of vertex
52
+ vertexOffset -= vertex.xyz;
53
+ //add pivot
54
+ vertexOffset += imposterPivotOffset;
55
+
56
+ //camera to projection vector
57
+ vec3 rayDirectionLocal = (imposterPivotOffset + projected) - objectSpaceCameraPos;
58
+
59
+ //projected position to camera ray
60
+ vec3 projInterpolated = normalize( objectSpaceCameraPos - (projected + imposterPivotOffset) );
61
+
62
+ Ray rayLocal;
63
+ rayLocal.Origin = objectSpaceCameraPos-imposterPivotOffset;
64
+ rayLocal.Direction = rayDirectionLocal;
65
+
66
+ vec2 grid = VectorToGrid( pivotToCameraRay );
67
+ vec2 gridRaw = grid;
68
+ grid = saturate((grid+1.0)*0.5); //bias and scale to 0 to 1
69
+ grid *= framesMinusOne;
70
+
71
+ vec2 gridFrac = frac(grid);
72
+
73
+ vec2 gridFloor = floor(grid);
74
+
75
+ vec4 weights = TriangleInterpolate( gridFrac );
76
+
77
+ //3 nearest frames
78
+ vec2 frame0 = gridFloor;
79
+ vec2 frame1 = gridFloor + lerp(vec2(0,1),vec2(1,0),weights.w);
80
+ vec2 frame2 = gridFloor + vec2(1,1);
81
+
82
+ //convert frame coordinate to octahedron direction
83
+ vec3 frame0ray = FrameXYToRay(frame0, framesMinusOne.xx);
84
+ vec3 frame1ray = FrameXYToRay(frame1, framesMinusOne.xx);
85
+ vec3 frame2ray = FrameXYToRay(frame2, framesMinusOne.xx);
86
+
87
+ vec3 planeCenter = vec3(0,0,0);
88
+
89
+ vec3 plane0x;
90
+ vec3 plane0normal = frame0ray;
91
+ vec3 plane0z;
92
+ vec3 frame0local = FrameTransform( projInterpolated, frame0ray, plane0x, plane0z );
93
+ frame0local.xz = frame0local.xz/_ImposterFrames.xx; //for displacement
94
+
95
+ //virtual plane UV coordinates
96
+ vec2 vUv0 = VirtualPlaneUV( plane0normal, plane0x, plane0z, planeCenter, size, rayLocal );
97
+ vUv0 /= _ImposterFrames.xx;
98
+
99
+ vec3 plane1x;
100
+ vec3 plane1normal = frame1ray;
101
+ vec3 plane1z;
102
+ vec3 frame1local = FrameTransform( projInterpolated, frame1ray, plane1x, plane1z);
103
+ frame1local.xz = frame1local.xz/_ImposterFrames.xx; //for displacement
104
+
105
+ //virtual plane UV coordinates
106
+ vec2 vUv1 = VirtualPlaneUV( plane1normal, plane1x, plane1z, planeCenter, size, rayLocal );
107
+ vUv1 /= _ImposterFrames.xx;
108
+
109
+ vec3 plane2x;
110
+ vec3 plane2normal = frame2ray;
111
+ vec3 plane2z;
112
+ vec3 frame2local = FrameTransform( projInterpolated, frame2ray, plane2x, plane2z );
113
+ frame2local.xz = frame2local.xz/_ImposterFrames.xx; //for displacement
114
+
115
+ //virtual plane UV coordinates
116
+ vec2 vUv2 = VirtualPlaneUV( plane2normal, plane2x, plane2z, planeCenter, size, rayLocal );
117
+ vUv2 /= _ImposterFrames.xx;
118
+
119
+ //add offset here
120
+ imp.vertex.xyz += vertexOffset;
121
+ //overwrite others
122
+ imp.uv = texcoord;
123
+ imp.grid = grid;
124
+ imp.frame0 = vec4(vUv0.xy,frame0local.xz);
125
+ imp.frame1 = vec4(vUv1.xy,frame1local.xz);
126
+ imp.frame2 = vec4(vUv2.xy,frame2local.xz);
127
+ }
128
+
129
+ void main() {
130
+ vUv = uv;
131
+
132
+ ImposterData imp;
133
+ imp.vertex = vec4(position, 1.0);
134
+ imp.uv = uv;
135
+
136
+ ImposterVertex(imp);
137
+
138
+ gl_Position = imp.vertex;
139
+
140
+ float3 normalWorld = UnityObjectToWorldDir(v.normal.xyz);
141
+ float3 tangentWorld = UnityObjectToWorldDir(v.tangent.xyz);
142
+ float3x3 tangentToWorld = CreateTangentToWorldPerVertex(normalWorld, tangentWorld, v.tangent.w);
143
+ o.tangentWorld = tangentToWorld[0];
144
+ o.bitangentWorld = tangentToWorld[1];
145
+ o.normalWorld = tangentToWorld[2];
146
+
147
+ //surface
148
+ o.texCoord.xy = imp.uv;
149
+ o.texCoord.zw = imp.grid;
150
+ o.plane0 = imp.frame0;
151
+ o.plane1 = imp.frame1;
152
+ o.plane2 = imp.frame2;
153
+ }
154
+ `;
155
+ const shader_fg = `
156
+
157
+ in vec2 vUv;
158
+
159
+ in vec4 plane0;
160
+ in vec4 plane1;
161
+ in vec4 plane2;
162
+
163
+ struct Material{
164
+ vec3 diffuse;
165
+ vec3 normal;
166
+ float depth;
167
+ float occlusion;
168
+ float roughness;
169
+ float metalness;
170
+ };
171
+
172
+ void ImposterSample( in ImposterData imp, out vec4 baseTex, out vec4 worldNormal )//, out half depth )
173
+ {
174
+ vec2 fracGrid = frac(imp.grid);
175
+
176
+ vec4 weights = TriangleInterpolate( fracGrid );
177
+
178
+ vec2 gridSnap = floor(imp.grid) / _ImposterFrames.xx;
179
+
180
+ vec2 frame0 = gridSnap;
181
+ vec2 frame1 = gridSnap + (lerp(vec2(0,1),vec2(1,0),weights.w)/_ImposterFrames.xx);
182
+ vec2 frame2 = gridSnap + (vec2(1,1)/_ImposterFrames.xx);
183
+
184
+ vec2 vp0uv = frame0 + imp.frame0.xy;
185
+ vec2 vp1uv = frame1 + imp.frame1.xy;
186
+ vec2 vp2uv = frame2 + imp.frame2.xy;
187
+
188
+ //resolution of atlas (Square)
189
+ float textureDims = _ImposterBaseTex_TexelSize.z;
190
+ //fractional frame size, ex 2048/12 = 170.6
191
+ float frameSize = textureDims/_ImposterFrames;
192
+ //actual atlas resolution used, ex 170*12 = 2040
193
+ float actualDims = floor(frameSize) * _ImposterFrames;
194
+ //the scale factor to apply to UV coordinate, ex 2048/2040 = 0.99609375
195
+ float scaleFactor = actualDims / textureDims;
196
+
197
+ vp0uv *= scaleFactor;
198
+ vp1uv *= scaleFactor;
199
+ vp2uv *= scaleFactor;
200
+
201
+ //clamp out neighboring frames TODO maybe discard instead?
202
+ vec2 gridSize = 1.0/_ImposterFrames.xx;
203
+ gridSize *= _ImposterBaseTex_TexelSize.zw;
204
+ gridSize *= _ImposterBaseTex_TexelSize.xy;
205
+ float2 border = _ImposterBaseTex_TexelSize.xy*_ImposterBorderClamp;
206
+
207
+ //vp0uv = clamp(vp0uv,frame0+border,frame0+gridSize-border);
208
+ //vp1uv = clamp(vp1uv,frame1+border,frame1+gridSize-border);
209
+ //vp2uv = clamp(vp2uv,frame2+border,frame2+gridSize-border);
210
+
211
+ //for parallax modify
212
+ vec4 n0 = tex2Dlod( _ImposterWorldNormalDepthTex, vec4(vp0uv, 0, 1 ) );
213
+ vec4 n1 = tex2Dlod( _ImposterWorldNormalDepthTex, vec4(vp1uv, 0, 1 ) );
214
+ vec4 n2 = tex2Dlod( _ImposterWorldNormalDepthTex, vec4(vp2uv, 0, 1 ) );
215
+
216
+ half n0s = 0.5-n0.a;
217
+ half n1s = 0.5-n1.a;
218
+ half n2s = 0.5-n2.a;
219
+
220
+ vec2 n0p = imp.frame0.zw * n0s;
221
+ vec2 n1p = imp.frame1.zw * n1s;
222
+ vec2 n2p = imp.frame2.zw * n2s;
223
+
224
+ //add parallax shift
225
+ vp0uv += n0p;
226
+ vp1uv += n1p;
227
+ vp2uv += n2p;
228
+
229
+ //clamp out neighboring frames TODO maybe discard instead?
230
+ vp0uv = clamp(vp0uv,frame0+border,frame0+gridSize-border);
231
+ vp1uv = clamp(vp1uv,frame1+border,frame1+gridSize-border);
232
+ vp2uv = clamp(vp2uv,frame2+border,frame2+gridSize-border);
233
+
234
+ vec2 ddxy = vec2( ddx(imp.uv.x), ddy(imp.uv.y) );
235
+
236
+ worldNormal = ImposterBlendWeights( _ImposterWorldNormalDepthTex, imp.uv, vp0uv, vp1uv, vp2uv, weights, ddxy );
237
+ baseTex = ImposterBlendWeights( _ImposterBaseTex, imp.uv, vp0uv, vp1uv, vp2uv, weights, ddxy );
238
+
239
+ //pixel depth offset
240
+ //half pdo = 1-baseTex.a;
241
+ //float3 objectScale = float3(length(float3(unity_ObjectToWorld[0].x, unity_ObjectToWorld[1].x, unity_ObjectToWorld[2].x)),
242
+ // length(float3(unity_ObjectToWorld[0].y, unity_ObjectToWorld[1].y, unity_ObjectToWorld[2].y)),
243
+ // length(float3(unity_ObjectToWorld[0].z, unity_ObjectToWorld[1].z, unity_ObjectToWorld[2].z)));
244
+ //vec2 size = _ImposterSize.xx * 2.0;// * objectScale.xx;
245
+ //vec3 viewWorld = mul( UNITY_MATRIX_VP, float4(0,0,1,0) ).xyz;
246
+ //pdo *= size * abs(dot(normalize(imp.viewDirWorld.xyz),viewWorld));
247
+ //depth = pdo;
248
+ }
249
+
250
+ void main(){
251
+
252
+ }
253
+ `;
254
+
255
+ export class ImpostorShaderStandard extends RawShaderMaterial {
256
+ constructor() {
257
+ super({
258
+ fragmentShader: shader_fg,
259
+ vertexShader: shader_vx,
260
+ uniforms: {
261
+ /**
262
+ * RGB + Alpha
263
+ */
264
+ tBase: {
265
+ value: null
266
+ },
267
+ /**
268
+ * Normal+Depth
269
+ */
270
+ tGeometry: {
271
+ value: null
272
+ },
273
+ /**
274
+ * Material properties: Occlusion, Roughness, Metalness
275
+ * Alpha unused
276
+ */
277
+ tMaterial: {
278
+ value: null
279
+ },
280
+ /**
281
+ * Number of frames
282
+ */
283
+ uFrames: {
284
+ value: 0
285
+ },
286
+ /**
287
+ * Radius of bounding sphere of the impostor
288
+ */
289
+ uRadius: {
290
+ value: 0
291
+ },
292
+ /**
293
+ * Impostor offset
294
+ */
295
+ uOffset: {
296
+ value: new Vector3(0, 0, 0)
297
+ }
298
+ },
299
+ glslVersion: GLSL3
300
+ });
301
+
302
+ // Save some effort by disabling blending
303
+ this.blending = NoBlending;
304
+
305
+ }
306
+ }
@@ -0,0 +1,206 @@
1
+ struct ImposterData
2
+ {
3
+ vec2 uv;
4
+ vec2 grid;
5
+ vec4 frame0;
6
+ vec4 frame1;
7
+ vec4 frame2;
8
+ vec4 vertex;
9
+ };
10
+
11
+ struct Ray
12
+ {
13
+ vec3 Origin;
14
+ vec3 Direction;
15
+ };
16
+
17
+ //for hemisphere
18
+ vec3 OctaHemiEnc(vec2 coord)
19
+ {
20
+ coord = vec2(coord.x + coord.y, coord.x - coord.y) * 0.5;
21
+ vec3 vec = vec3(coord.x, 1.0 - dot(vec2(1.0, 1.0), abs(coord.xy)), coord.y);
22
+ return vec;
23
+ }
24
+ //for sphere
25
+ vec3 OctaSphereEnc(vec2 coord)
26
+ {
27
+ vec3 vec = vec3(coord.x, 1.0 - dot(vec2(1.0), abs(coord)), coord.y);
28
+ if (vec.y < 0.0)
29
+ {
30
+ vec2 flip = vec.xz >= 0.0 ? vec2(1.0, 1.0) : vec2(-1.0, -1.0);
31
+ vec.xz = (1-abs(vec.zx)) * flip;
32
+ }
33
+ return vec;
34
+ }
35
+
36
+ vec3 GridToVector(vec2 coord)
37
+ {
38
+ vec3 vec;
39
+ if (_ImposterFullSphere)
40
+ {
41
+ vec = OctaSphereEnc(coord);
42
+ }
43
+ else
44
+ {
45
+ vec = OctaHemiEnc(coord);
46
+ }
47
+ return vec;
48
+ }
49
+
50
+ //for hemisphere
51
+ vec2 VecToHemiOct(vec3 vec)
52
+ {
53
+ vec.xz /= dot(1.0, abs(vec));
54
+ return vec2(vec.x + vec.z, vec.x - vec.z);
55
+ }
56
+
57
+ vec2 VecToSphereOct(vec3 vec)
58
+ {
59
+ vec.xz /= dot(1, abs(vec));
60
+ if (vec.y <= 0)
61
+ {
62
+ vec2 flip = vec.xz >= 0 ? vec2(1, 1) : vec2(-1, -1);
63
+ vec.xz = (1-abs(vec.zx)) * flip;
64
+ }
65
+ return vec.xz;
66
+ }
67
+
68
+ vec2 VectorToGrid(vec3 vec)
69
+ {
70
+ vec2 coord;
71
+
72
+ if (_ImposterFullSphere)
73
+ {
74
+ coord = VecToSphereOct(vec);
75
+ }
76
+ else
77
+ {
78
+ vec.y = max(0.001, vec.y);
79
+ vec = normalize(vec);
80
+ coord = VecToHemiOct(vec);
81
+ }
82
+ return coord;
83
+ }
84
+
85
+ vec3 SpriteProjection(vec3 pivotToCameraRayLocal, float frames, vec2 size, vec2 coord){
86
+ vec3 gridVec = pivotToCameraRayLocal;
87
+
88
+ //octahedron vector, pivot to camera
89
+ vec3 y = normalize(gridVec);
90
+
91
+ vec3 x = normalize(cross(y, vec3(0.0, 1.0, 0.0)));
92
+ vec3 z = normalize(cross(x, y));
93
+
94
+ vec2 uv = ((coord*frames)-0.5) * 2.0;//-1 to 1
95
+
96
+ vec3 newX = x * uv.x;
97
+ vec3 newZ = z * uv.y;
98
+
99
+ vec2 halfSize = size*0.5;
100
+
101
+ newX *= halfSize.x;
102
+ newZ *= halfSize.y;
103
+
104
+ vec3 res = newX + newZ;
105
+
106
+ return res;
107
+ }
108
+
109
+ vec4 TriangleInterpolate(vec2 uv){
110
+ uv = frac(uv);
111
+
112
+ vec2 omuv = vec2(1.0, 1.0) - uv.xy;
113
+
114
+ vec4 res = vec4(0, 0, 0, 0);
115
+ //frame 0
116
+ res.x = min(omuv.x, omuv.y);
117
+ //frame 1
118
+ res.y = abs(dot(uv, vec2(1.0, -1.0)));
119
+ //frame 2
120
+ res.z = min(uv.x, uv.y);
121
+ //mask
122
+ res.w = saturate(ceil(uv.x-uv.y));
123
+
124
+ return res;
125
+ }
126
+
127
+ //frame and framecout, returns
128
+ vec3 FrameXYToRay(vec2 frame, vec2 frameCountMinusOne)
129
+ {
130
+ //divide frame x y by framecount minus one to get 0-1
131
+ vec2 f = frame.xy / frameCountMinusOne;
132
+
133
+ //bias and scale to -1 to 1
134
+ f = (f-0.5)*2.0;
135
+
136
+ //convert to vector, either full sphere or hemi sphere
137
+ vec3 vec = GridToVector(f);
138
+
139
+ vec = normalize(vec);
140
+
141
+ return vec;
142
+ }
143
+
144
+ vec3 ITBasis(vec3 vec, vec3 basedX, vec3 basedY, vec3 basedZ)
145
+ {
146
+ return vec3(dot(basedX, vec), dot(basedY, vec), dot(basedZ, vec));
147
+ }
148
+
149
+ vec3 FrameTransform(vec3 projRay, vec3 frameRay, out vec3 worldX, out vec3 worldZ)
150
+ {
151
+ //TODO something might be wrong here
152
+ worldX = normalize(vec3(-frameRay.z, 0, frameRay.x));
153
+ worldZ = normalize(cross(worldX, frameRay));
154
+
155
+ projRay *= -1.0;
156
+
157
+ vec3 local = normalize(ITBasis(projRay, worldX, frameRay, worldZ));
158
+ return local;
159
+ }
160
+
161
+
162
+ vec4 ImposterBlendWeights(sampler2D tex, vec2 uv, vec2 frame0, vec2 frame1, vec2 frame2, vec4 weights, vec2 ddxy)
163
+ {
164
+ vec4 samp0 = tex2Dgrad(tex, frame0, ddxy.x, ddxy.y);
165
+ vec4 samp1 = tex2Dgrad(tex, frame1, ddxy.x, ddxy.y);
166
+ vec4 samp2 = tex2Dgrad(tex, frame2, ddxy.x, ddxy.y);
167
+
168
+ //vec4 samp0 = tex2Dlod( tex, float4(frame0,0,0) );
169
+ //vec4 samp1 = tex2Dlod( tex, float4(frame1,0,0) );
170
+ //vec4 samp2 = tex2Dlod( tex, float4(frame2,0,0) );
171
+
172
+ vec4 result = samp0*weights.x + samp1*weights.y + samp2*weights.z;
173
+
174
+ return result;
175
+ }
176
+
177
+ vec2 VirtualPlaneUV(vec3 planeNormal, vec3 planeX, vec3 planeZ, vec3 center, vec2 uvScale, Ray rayLocal){
178
+ float normalDotOrigin = dot(planeNormal, rayLocal.Origin);
179
+ float normalDotCenter = dot(planeNormal, center);
180
+ float normalDotRay = dot(planeNormal, rayLocal.Direction);
181
+
182
+ float planeDistance = normalDotOrigin-normalDotCenter;
183
+ planeDistance *= -1.0;
184
+
185
+ float intersect = planeDistance / normalDotRay;
186
+
187
+ vec3 intersection = ((rayLocal.Direction * intersect) + rayLocal.Origin) - center;
188
+
189
+ float dx = dot(planeX, intersection);
190
+ float dz = dot(planeZ, intersection);
191
+
192
+ vec2 uv = vec2(0, 0);
193
+
194
+ if (intersect > 0)
195
+ {
196
+ uv = vec2(dx, dz);
197
+ }
198
+ else
199
+ {
200
+ uv = vec2(0, 0);
201
+ }
202
+
203
+ uv /= uvScale;
204
+ uv += vec2(0.5, 0.5);
205
+ return uv;
206
+ }
@@ -1,6 +1,6 @@
1
1
  import { HashMap } from "../../../core/collection/HashMap.js";
2
- import { computeGeometryHash } from "../../asset/loaders/geometry/geometry/computeGeometryHash.js";
3
- import { computeGeometryEquality } from "../../asset/loaders/geometry/geometry/computeGeometryEquality.js";
2
+ import { computeGeometryHash } from "../geometry/buffered/computeGeometryHash.js";
3
+ import { computeGeometryEquality } from "../geometry/buffered/computeGeometryEquality.js";
4
4
  import { buildMicronGeometryFromBufferGeometry } from "./build/buildMicronGeometryFromBufferGeometry.js";
5
5
  import { ThreeMicronMesh } from "./format/ThreeMicronMesh.js";
6
6
  import { AsyncMapWrapper } from "../../../core/collection/map/AsyncMapWrapper.js";
@@ -3,8 +3,8 @@ import { VGThreeRenderer } from "../render/v1/VGThreeRenderer.js";
3
3
  import { RenderLayer } from "../../render/layers/RenderLayer.js";
4
4
  import { RenderPassType } from "../../render/RenderPassType.js";
5
5
  import { Cache } from "../../../../core/cache/Cache.js";
6
- import { computeGeometryHash } from "../../../asset/loaders/geometry/geometry/computeGeometryHash.js";
7
- import { computeGeometryEquality } from "../../../asset/loaders/geometry/geometry/computeGeometryEquality.js";
6
+ import { computeGeometryHash } from "../../geometry/buffered/computeGeometryHash.js";
7
+ import { computeGeometryEquality } from "../../geometry/buffered/computeGeometryEquality.js";
8
8
  import { CachedAsyncMap } from "../../../../core/collection/map/CachedAsyncMap.js";
9
9
  import { AsyncRemoteHashMap } from "../../../../core/collection/map/AsyncRemoteHashMap.js";
10
10
  import { BufferGeometrySerializationAdapter } from "./serialization/BufferGeometrySerializationAdapter.js";
@@ -14,6 +14,6 @@ export class CodeGenerator {
14
14
  uniforms
15
15
  }) {
16
16
 
17
-
17
+ throw new Error('Not Implemented');
18
18
  }
19
19
  }
@@ -24,7 +24,7 @@ export class CurlNoiseNode extends ShaderNode {
24
24
  ],
25
25
  ParticleDataTypes.Vector3
26
26
  )
27
- ))
27
+ ));
28
28
  }
29
29
 
30
30
  generate_code(instance, output, context, port_variables) {
@@ -303,6 +303,31 @@ export class LightManager {
303
303
  this.__visible_bvh_needs_update = true;
304
304
  }
305
305
 
306
+ /**
307
+ * Please set this to false if you have a lot of overlapping decals in the scene
308
+ * Overlapping decals can provide filtering artifacts due to incorrect mipmap level detection by WebGL
309
+ * see article: https://0fps.net/2013/07/09/texture-atlases-wrapping-and-mip-mapping/
310
+ * NOTE: the technique mentioned in the article above is not implemented, as it would require significant increase in number of texture fetches
311
+ * @param {boolean} v
312
+ */
313
+ set decal_filtering_enabled(v) {
314
+ const t = this.__decal_atlas_texture;
315
+
316
+ if (t.generateMipmaps === v) {
317
+ return;
318
+ }
319
+
320
+ t.generateMipmaps = v;
321
+ }
322
+
323
+ /**
324
+ *
325
+ * @return {boolean}
326
+ */
327
+ get decal_filtering_enabled() {
328
+ return this.__decal_atlas_texture.generateMipmaps;
329
+ }
330
+
306
331
  __update_decal_atlas_texture() {
307
332
  const sampler = this.__decal_atlas.sampler;
308
333
 
@@ -1,7 +1,9 @@
1
- import { DataTexture, NearestFilter, RedFormat, UnsignedByteType } from "three";
1
+ import { ClampToEdgeWrapping, DataTexture, NearestFilter, RedFormat, UnsignedByteType } from "three";
2
2
  import { DataType } from "../../../../../core/collection/table/DataType.js";
3
3
  import { assert } from "../../../../../core/assert.js";
4
- import { DataType2TypedArrayConstructorMapping } from "../../../../../core/collection/table/DataType2TypedArrayConstructorMapping.js";
4
+ import {
5
+ DataType2TypedArrayConstructorMapping
6
+ } from "../../../../../core/collection/table/DataType2TypedArrayConstructorMapping.js";
5
7
  import { max2 } from "../../../../../core/math/max2.js";
6
8
  import { NumericType } from "./NumericType.js";
7
9
  import { computeDataType } from "./computeDataType.js";
@@ -63,6 +65,8 @@ export class TextureBackedMemoryRegion {
63
65
  this.__texture.format = RedFormat;
64
66
  this.__texture.magFilter = NearestFilter;
65
67
  this.__texture.minFilter = NearestFilter;
68
+ this.__texture.wrapS = ClampToEdgeWrapping;
69
+ this.__texture.wrapT = ClampToEdgeWrapping;
66
70
  this.__texture.generateMipmaps = false;
67
71
 
68
72
  /**
@@ -53,30 +53,25 @@ export const FP_SHADER_CHUNK_ACCUMULATION = `
53
53
  vec4 local_position = decal_transform_matrix*vec4(v_world_position, 1.0);
54
54
 
55
55
  if(max3(abs(local_position.xyz)) < 0.5){
56
- // material.diffuseColor = material.diffuseColor*(0.8) + (local_position.xyz + 0.5)*0.2; // display UV
57
-
56
+
58
57
  // we're inside decal volume
59
58
  vec4 light_data_4 = texelFetch(fp_t_light_data, address_to_data_texture_coordinates(light_address+4u), 0);
60
-
59
+
61
60
  // compute normal of the decal
62
61
  vec4 decal_normal = normalize( viewMatrix*decal_transform_matrix*vec4(0.0, 0.0, 1.0, 0.0) );
63
62
  float decal_surface_dot = dot(decal_normal.xyz, geometry.normal);
64
-
63
+
65
64
  // we fade out decals when the projection angle to the surface gets too steep
66
65
  // 0.7 is cos(45deg) and 0.5 is cos(60deg), dot returns cos of angle between two normals
67
66
  float decal_surface_angle_fade = smoothstep(-0.5,-0.7,decal_surface_dot);
68
- // float decal_surface_angle_fade = decal_surface_dot;
69
-
70
-
67
+
71
68
  vec2 decal_uv = (local_position.xy + 0.5)*light_data_4.zw + light_data_4.xy;
72
69
 
73
- //material.diffuseColor = material.diffuseColor*(0.8) + vec3(decal_uv + 0.5, 0.0)*0.2; // display UV
74
70
 
75
-
76
71
  vec4 decal_color = texture(fp_t_decal_atlas, decal_uv);
72
+
77
73
  float decal_alpha = decal_color.a * decal_surface_angle_fade;
78
- // float decal_alpha = decal_color.a;
79
-
74
+
80
75
  material.diffuseColor = material.diffuseColor*(1.0-decal_alpha) + decal_color.xyz*decal_alpha;
81
76
 
82
77
  }