@woosh/meep-engine 2.40.1 → 2.42.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 (75) hide show
  1. package/core/collection/HashMap.d.ts +2 -0
  2. package/core/collection/HashMap.js +22 -0
  3. package/core/geom/3d/apply_mat4_transform_to_v3_array.js +2 -4
  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/sphere/sphere_radius_sqr_from_v3_array_transformed.js +28 -0
  9. package/core/geom/3d/topology/struct/BinaryTopology.js +112 -0
  10. package/core/geom/Quaternion.js +14 -0
  11. package/core/math/sign_not_zero.js +8 -0
  12. package/core/parser/simple/SimpleParser.js +3 -86
  13. package/core/parser/simple/readUnsignedInteger.js +66 -0
  14. package/core/parser/simple/skipWhitespace.js +21 -0
  15. package/engine/EngineHarness.js +13 -3
  16. package/engine/asset/AssetDescription.spec.js +27 -0
  17. package/engine/asset/loaders/GLTFAssetLoader.js +5 -3
  18. package/engine/ecs/foliage/ImpostorFoliage.js +4 -0
  19. package/engine/ecs/transform/Transform.js +23 -3
  20. package/engine/graphics/ecs/decal/v2/Decal.d.ts +11 -0
  21. package/engine/graphics/ecs/decal/v2/Decal.js +50 -0
  22. package/engine/graphics/ecs/decal/v2/FPDecalSystem.d.ts +8 -0
  23. package/engine/graphics/ecs/decal/v2/FPDecalSystem.js +213 -0
  24. package/engine/graphics/ecs/decal/v2/prototypeDecalSystem.js +237 -0
  25. package/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +8 -1
  26. package/engine/graphics/ecs/mesh-v2/build_three_object.js +4 -0
  27. package/engine/graphics/ecs/mesh-v2/three_object_to_entity_composition.js +22 -7
  28. package/engine/graphics/filter/ImageFilter.js +2 -1
  29. package/engine/graphics/geometry/MikkT/MikkTSpace.js +466 -305
  30. package/engine/graphics/geometry/MikkT/MikkTSpace.spec.js +7 -1
  31. package/engine/{asset/loaders/geometry/geometry → graphics/geometry/buffered}/computeBufferAttributeHash.js +1 -1
  32. package/engine/{asset/loaders/geometry/geometry → graphics/geometry/buffered}/computeGeometryEquality.js +2 -2
  33. package/engine/{asset/loaders/geometry/geometry → graphics/geometry/buffered}/computeGeometryHash.js +1 -1
  34. package/engine/graphics/geometry/optimization/merge/merge_geometry_hierarchy.js +2 -2
  35. package/engine/graphics/impostors/card_cluster/FacePlaneAssignment.js +30 -0
  36. package/engine/graphics/impostors/card_cluster/README.md +13 -0
  37. package/engine/graphics/impostors/octahedral/ImpostorBaker.js +345 -0
  38. package/engine/graphics/impostors/octahedral/ImpostorCaptureType.js +10 -0
  39. package/engine/graphics/impostors/octahedral/ImpostorDescription.js +69 -0
  40. package/engine/graphics/impostors/octahedral/README.md +30 -0
  41. package/engine/graphics/impostors/octahedral/bake/compute_bounding_sphere.js +45 -0
  42. package/engine/graphics/impostors/octahedral/bake/compute_bounding_sphere_radius_only.js +37 -0
  43. package/engine/graphics/impostors/octahedral/bake/prepare_bake_material.js +117 -0
  44. package/engine/graphics/impostors/octahedral/grid/HemiOctahedralUvEncoder.js +20 -0
  45. package/engine/graphics/impostors/octahedral/grid/OctahedralUvEncoder.js +25 -0
  46. package/engine/graphics/impostors/octahedral/grid/UvEncoder.js +21 -0
  47. package/engine/graphics/impostors/octahedral/prototypeBaker.js +237 -0
  48. package/engine/graphics/impostors/octahedral/shader/BakeShaderStandard.js +196 -0
  49. package/engine/graphics/impostors/octahedral/shader/ImpostorShaderStandard.js +306 -0
  50. package/engine/graphics/impostors/octahedral/shader/ImpostorShaderV0.js +349 -0
  51. package/engine/graphics/impostors/octahedral/shader/ImpostorShaderV1.js +74 -0
  52. package/engine/graphics/impostors/octahedral/shader/glsl/common.glsl +206 -0
  53. package/engine/graphics/impostors/octahedral/shader/glsl/v1/common.glsl +209 -0
  54. package/engine/graphics/impostors/octahedral/shader/glsl/v1/flagment.glsl +80 -0
  55. package/engine/graphics/impostors/octahedral/shader/glsl/v1/vertex.glsl +350 -0
  56. package/engine/graphics/micron/convert_three_object_to_micron.js +2 -2
  57. package/engine/graphics/micron/plugin/MicronRenderPlugin.js +2 -2
  58. package/engine/graphics/micron/render/v1/getTransformedPositionsCached.js +1 -1
  59. package/engine/graphics/particles/node-based/codegen/CodeGenerator.js +1 -1
  60. package/engine/graphics/particles/node-based/nodes/noise/CurlNoiseNode.js +1 -1
  61. package/engine/graphics/render/forward_plus/LightManager.js +1 -1
  62. package/engine/graphics/render/forward_plus/materials/FP_SHADER_CHUNK_ACCUMULATION.js +1 -3
  63. package/engine/graphics/render/forward_plus/materials/FP_SHADER_CHUNK_PREAMBLE.js +2 -1
  64. package/engine/graphics/render/forward_plus/model/Decal.js +19 -2
  65. package/engine/graphics/render/visibility/hiz/buildCanvasViewFromTexture.js +32 -10
  66. package/engine/graphics/shaders/ScreenSpaceQuadShader.js +4 -14
  67. package/engine/graphics/shaders/glsl_gen_swizzled_read.js +39 -0
  68. package/engine/graphics/texture/sampler/Sampler2D.js +10 -10
  69. package/engine/graphics/texture/sampler/prototypeSamplerFiltering.js +117 -11
  70. package/engine/graphics/texture/sampler/resize/sampler2d_downsample_mipmap.js +66 -0
  71. package/engine/graphics/texture/sampler/sampler2_d_scale_down_lanczos.js +2 -2
  72. package/engine/ui/GUIEngine.js +8 -1
  73. package/package.json +1 -1
  74. package/view/tooltip/gml/parser/readReferenceToken.js +1 -1
  75. 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,349 @@
1
+ import {
2
+ AddEquation,
3
+ CustomBlending,
4
+ GLSL3,
5
+ OneFactor,
6
+ OneMinusSrcAlphaFactor,
7
+ RawShaderMaterial,
8
+ Vector3
9
+ } from "three";
10
+
11
+ /*
12
+ *
13
+ * For ray projection using projection matrix : https://encreative.blogspot.com/2019/05/computing-ray-origin-and-direction-from.html
14
+ */
15
+ const shader_vx = `
16
+
17
+ in vec2 uv;
18
+ in vec3 position;
19
+ in vec3 normal;
20
+
21
+ out vec2 vUv;
22
+ out vec4 plane0;
23
+ out vec4 plane1;
24
+ out vec4 plane2;
25
+
26
+ out vec3 local_ray_near;
27
+ out vec3 local_ray_far;
28
+
29
+ uniform mat4 modelViewMatrix;
30
+ uniform mat4 projectionMatrix;
31
+ uniform mat3 normalMatrix;
32
+
33
+ uniform vec3 uOffset;
34
+ uniform float uRadius;
35
+ uniform float uFrames;
36
+
37
+ void main() {
38
+ vUv = uv;
39
+
40
+ vec2 framesMinusOne = uFrames - vec2(1.0);
41
+
42
+ mat4 m4 = modelViewMatrix;
43
+
44
+ m4[0][0] = 1.0;
45
+ m4[0][1] = 0.0;
46
+ m4[0][2] = 0.0;
47
+
48
+ m4[1][0] = 0.0;
49
+ m4[1][1] = 1.0;
50
+ m4[1][2] = 0.0;
51
+
52
+ m4[2][0] = 0.0;
53
+ m4[2][1] = 0.0;
54
+ m4[2][2] = 1.0;
55
+
56
+ vec3 object_scale = vec3(
57
+ length(modelViewMatrix[0].xyz),
58
+ length(modelViewMatrix[1].xyz),
59
+ length(modelViewMatrix[2].xyz)
60
+ );
61
+
62
+ // scale by object's baking bounding sphere's radius
63
+ float card_diameter = uRadius*2.0;
64
+ object_scale *= card_diameter;
65
+
66
+ vec3 transformedNormal = normalize(normalMatrix * normal);
67
+
68
+ vec4 mvPosition = m4 * vec4( object_scale*(position+uOffset/card_diameter), 1.0 );
69
+
70
+ gl_Position = projectionMatrix * mvPosition;
71
+
72
+ mat4 inverse_matrix = inverse(projectionMatrix * modelViewMatrix);
73
+
74
+ //
75
+ //get 2D projection of this vertex in normalized device coordinates
76
+ vec2 pos = gl_Position.xy/gl_Position.w;
77
+
78
+ //compute ray's start and end as inversion of this coordinates
79
+ //in near and far clip planes
80
+ vec4 near_4 = inverse_matrix * (vec4(pos, -1.0, 1.0));
81
+ vec4 far_4 = inverse_matrix * (vec4(pos, 1.0, 1.0));
82
+
83
+ local_ray_near = near_4.xyz / near_4.w;
84
+ local_ray_far = far_4.xyz/ far_4.w;
85
+ }
86
+ `;
87
+ const shader_fg = `
88
+ precision highp float;
89
+ precision highp int;
90
+
91
+ const float depth_scale = 0.5;
92
+
93
+ in vec2 vUv;
94
+
95
+ in vec4 plane0;
96
+ in vec4 plane1;
97
+ in vec4 plane2;
98
+
99
+ in vec3 vViewPosition;
100
+ in vec3 vFacingDirection;
101
+
102
+ out vec4 color_out;
103
+
104
+ uniform sampler2D tBase;
105
+ uniform sampler2D tGeometry;
106
+ uniform float uFrames;
107
+ uniform float uDepthScale;
108
+ uniform bool uIsFullSphere;
109
+
110
+
111
+ in vec3 local_ray_near;
112
+ in vec3 local_ray_far;
113
+
114
+ struct Material{
115
+ vec3 diffuse;
116
+ vec3 normal;
117
+ float depth;
118
+ float occlusion;
119
+ float roughness;
120
+ float metalness;
121
+ };
122
+
123
+ vec2 VecToSphereOct(vec3 pivotToCamera)
124
+ {
125
+ vec3 octant = sign(pivotToCamera);
126
+
127
+ // |x| + |y| + |z| = 1
128
+ float sum = dot(pivotToCamera, octant);
129
+ vec3 octahedron = pivotToCamera / sum;
130
+
131
+ if (octahedron.y < 0.0){
132
+ vec3 absolute = abs(octahedron);
133
+ octahedron.xz = octant.xz * vec2(1.0 - absolute.z, 1.0 - absolute.x);
134
+ }
135
+ return octahedron.xz;
136
+ }
137
+
138
+ //for hemisphere
139
+ vec2 VecToHemiSphereOct(vec3 vec)
140
+ {
141
+ vec.y = max(vec.y, 0.001);
142
+ vec = normalize(vec);
143
+ vec3 octant = sign(vec);
144
+
145
+ // |x| + |y| + |z| = 1
146
+ float sum = dot(vec, octant);
147
+ vec3 octahedron = vec / sum;
148
+
149
+ return vec2(
150
+ octahedron.x + octahedron.z,
151
+ octahedron.z - octahedron.x
152
+ );
153
+ }
154
+
155
+ vec2 VectorToGrid(vec3 vec)
156
+ {
157
+ if (uIsFullSphere)
158
+ {
159
+ return VecToSphereOct(vec);
160
+ }
161
+ else
162
+ {
163
+ return VecToHemiSphereOct(vec);
164
+ }
165
+ }
166
+
167
+ vec4 TriangleInterpolate(vec2 uv){
168
+ uv = fract(uv);
169
+
170
+ vec2 omuv = vec2(1.0, 1.0) - uv.xy;
171
+
172
+ vec4 res = vec4(0, 0, 0, 0);
173
+ //frame 0
174
+ res.x = min(omuv.x, omuv.y);
175
+ //frame 1
176
+ res.y = abs(dot(uv, vec2(1.0, -1.0)));
177
+ //frame 2
178
+ res.z = min(uv.x, uv.y);
179
+ //mask
180
+ res.w = clamp(ceil(uv.x-uv.y),0.0, 1.0);
181
+
182
+ return res;
183
+ }
184
+
185
+
186
+ vec4 ImposterBlendWeights(sampler2D tex, vec2 frame0, vec2 frame1, vec2 frame2, vec4 weights, vec4 ddxy)
187
+ {
188
+ vec4 samp0 = textureGrad(tex, frame0, ddxy.xy, ddxy.zw);
189
+ vec4 samp1 = textureGrad(tex, frame1, ddxy.xy, ddxy.zw);
190
+ vec4 samp2 = textureGrad(tex, frame2, ddxy.xy, ddxy.zw);
191
+
192
+ vec4 result = samp0*weights.x + samp1*weights.y + samp2*weights.z;
193
+
194
+ return result;
195
+ }
196
+
197
+ vec2 recalculateUV(vec2 uv_f, vec2 frame, vec2 xy_f, vec2 frame_size, float d_scale, sampler2D depthTexture)
198
+ {
199
+ //clamp for parallax sampling
200
+ uv_f = clamp(uv_f, vec2(0), vec2(1));
201
+ vec2 uv_quad = frame_size * (frame + uv_f);
202
+ //paralax
203
+ float n_depth = (texture( depthTexture, uv_quad, -16.0 )).a;
204
+ uv_f = xy_f * (0.5-n_depth) * d_scale + uv_f;
205
+ //clamp parallax offset
206
+ uv_f = clamp(uv_f, vec2(0), vec2(1));
207
+ uv_f = frame_size * (frame + uv_f);
208
+ //clamped full UV
209
+ return clamp(uv_f, vec2(0), vec2(1));
210
+ }
211
+
212
+ void calcuateXYbasis(vec3 plane_normal, out vec3 plane_x, out vec3 plane_y)
213
+ {
214
+ vec3 up = vec3(0,1,0);
215
+ //cross product doesnt work if we look directly from bottom
216
+ if (abs(plane_normal.y) > 0.999f)
217
+ {
218
+ up = vec3(0,0,1);
219
+ }
220
+ plane_x = normalize(cross(plane_normal, up));
221
+ plane_y = normalize(cross(plane_x, plane_normal));
222
+ }
223
+
224
+ vec3 projectOnPlaneBasis(vec3 ray, vec3 plane_normal, vec3 plane_x, vec3 plane_y)
225
+ {
226
+ //reproject plane normal onto planeXY basos
227
+ return normalize(vec3(
228
+ dot(plane_x,ray),
229
+ dot(plane_y,ray),
230
+ dot(plane_normal,ray)
231
+ ));
232
+ }
233
+
234
+ vec2 recompute_uv(vec2 frame, vec2 frame_uv, sampler2D gBuffer){
235
+ vec2 frame_size = vec2(1.0/ uFrames);
236
+
237
+ vec2 source_uv = (frame + frame_uv)*frame_size;
238
+
239
+ float n_depth = texture(gBuffer, source_uv).a;
240
+
241
+ vec2 offset = clamp(length(frame_uv*2.0 - 1.0)*vec2(0.5-n_depth )*depth_scale, 0.0, 1.0);
242
+
243
+ return clamp(( frame + frame_uv+offset)*frame_size,0.0, 1.0);
244
+ // return source_uv;
245
+ }
246
+
247
+ void main(){
248
+ vec3 view_direction = normalize(local_ray_near-local_ray_far);
249
+
250
+ vec2 octahedral_uv = clamp(VectorToGrid(view_direction)*0.5 + 0.5, 0.0, 1.0);
251
+ vec2 grid = octahedral_uv * vec2(uFrames - 1.0);
252
+
253
+ vec2 gridFrac = fract(grid);
254
+ vec2 gridFloor = floor(grid);
255
+
256
+ vec4 weights = TriangleInterpolate( gridFrac );
257
+
258
+ //3 nearest frames
259
+ vec2 frame0 = gridFloor;
260
+ vec2 frame1 = gridFloor + mix(vec2(0,1),vec2(1,0),weights.w);
261
+ vec2 frame2 = gridFloor + vec2(1.0,1.0);
262
+
263
+ vec4 ddxy = vec4( dFdx(vUv.xy), dFdy(vUv.xy) );
264
+
265
+ vec2 frame_uv = vUv;
266
+ vec2 frame_size = vec2(1.0/ uFrames);
267
+
268
+ vec4 texel_color = ImposterBlendWeights(
269
+ tBase,
270
+ (frame0 + frame_uv) * frame_size,
271
+ (frame1 + frame_uv) * frame_size,
272
+ (frame2 + frame_uv) * frame_size,
273
+ weights, ddxy
274
+ );
275
+
276
+ // texel_color = vec4(texel_color.aaa, 1.0);
277
+
278
+ if(texel_color.a <= 0.5){
279
+ texel_color.r = 1.0;
280
+ discard;
281
+ }
282
+
283
+ color_out = texel_color;
284
+ // color_out = vec4( snapped_oct_uv, 1.0, 1.0);
285
+ }
286
+ `;
287
+
288
+ export class ImpostorShaderV0 extends RawShaderMaterial {
289
+ constructor() {
290
+ super({
291
+ fragmentShader: shader_fg,
292
+ vertexShader: shader_vx,
293
+ uniforms: {
294
+ /**
295
+ * RGB + Alpha
296
+ */
297
+ tBase: {
298
+ value: null
299
+ },
300
+ /**
301
+ * Normal+Depth
302
+ */
303
+ tGeometry: {
304
+ value: null
305
+ },
306
+ /**
307
+ * Material properties: Occlusion, Roughness, Metalness
308
+ * Alpha unused
309
+ */
310
+ tMaterial: {
311
+ value: null
312
+ },
313
+ /**
314
+ * Number of frames
315
+ */
316
+ uFrames: {
317
+ value: 0
318
+ },
319
+ /**
320
+ * Radius of bounding sphere of the impostor
321
+ */
322
+ uRadius: {
323
+ value: 0
324
+ },
325
+ /**
326
+ * Impostor offset
327
+ */
328
+ uOffset: {
329
+ value: new Vector3(0, 0, 0)
330
+ },
331
+ uIsFullSphere: {
332
+ value: false
333
+ },
334
+ uDepthScale:{
335
+ // value should be in range between 0 and 1
336
+ value:1
337
+ }
338
+ },
339
+ glslVersion: GLSL3
340
+ });
341
+
342
+ // Save some effort by disabling blending
343
+ this.blending = CustomBlending;
344
+ this.blendEquation = AddEquation;
345
+ this.blendSrc = OneFactor;
346
+ this.blendDst = OneMinusSrcAlphaFactor;
347
+
348
+ }
349
+ }