@sangwonl/pocato-core 0.4.0 → 0.4.2

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.
package/dist/index.js CHANGED
@@ -629,6 +629,8 @@ uniform vec2 uMouse;
629
629
  uniform vec2 uMove;
630
630
  uniform vec2 uRotate;
631
631
  uniform float uTime;
632
+ uniform float uEffectIntensity;
633
+ uniform float uEffectSpeed;
632
634
  uniform sampler2D uLayer0;
633
635
  uniform sampler2D uLayer1;
634
636
  uniform int uLayerCount;
@@ -691,6 +693,11 @@ const float DEPTH_FAR = 0.1;
691
693
  const float WIDTH_FAR = 0.3;
692
694
  const float SPEED_FAR = 0.1;
693
695
 
696
+ float effectTime() {
697
+ float speed = uEffectSpeed > 0.0 ? uEffectSpeed : 1.0;
698
+ return uTime * speed;
699
+ }
700
+
694
701
  float computeSnow(in vec2 uv, int layerStart, int layerEnd) {
695
702
  const mat3 permutationMatrix = mat3(13.323122, 23.5112, 21.71123, 21.1212, 28.7312, 11.9312, 21.8112, 14.7212, 61.3934);
696
703
  vec2 moveNormalized = uMove.xy / uResolution.xy;
@@ -698,15 +705,16 @@ float computeSnow(in vec2 uv, int layerStart, int layerEnd) {
698
705
  uv.x += moveNormalized.x * 0.2;
699
706
  float totalLayers = float(LAYERS);
700
707
  float accumulation = 0.0;
701
- float depthOfField = 5.0 * sin(uTime * 0.1);
708
+ float snowTime = effectTime();
709
+ float depthOfField = 5.0 * sin(snowTime * 0.1);
702
710
  for (int i = max(layerStart, 0); i < min(layerEnd, LAYERS); i++) {
703
711
  float layer = float(i);
704
712
  float depthFactor = smoothstep(DEPTH_NEAR, DEPTH_FAR, layer / totalLayers);
705
713
  float widthFactor = smoothstep(WIDTH_NEAR, WIDTH_FAR, layer / totalLayers);
706
714
  float speedFactor = smoothstep(SPEED_NEAR, SPEED_FAR, layer / totalLayers);
707
715
  vec2 offsetUv = uv * (1.0 + layer * depthFactor);
708
- float windEffect = widthFactor * mod(layer * 7.238917, 1.0) - widthFactor * 0.1 * sin(uTime * 2.0 + layer);
709
- offsetUv += vec2(offsetUv.y * windEffect, speedFactor * uTime / (1.0 + layer * depthFactor * 0.03));
716
+ float windEffect = widthFactor * mod(layer * 7.238917, 1.0) - widthFactor * 0.1 * sin(snowTime * 2.0 + layer);
717
+ offsetUv += vec2(offsetUv.y * windEffect, speedFactor * snowTime / (1.0 + layer * depthFactor * 0.03));
710
718
  vec3 noiseInput = vec3(floor(offsetUv), 31.189 + layer);
711
719
  vec3 permuted = floor(noiseInput) * 0.00001 + fract(noiseInput);
712
720
  vec3 noise = fract((31415.9 + permuted) / fract(permutationMatrix * permuted));
@@ -721,10 +729,11 @@ float computeSnow(in vec2 uv, int layerStart, int layerEnd) {
721
729
 
722
730
  void main() {
723
731
  vec4 baseTexture = texture2D(uLayer0, vUv);
732
+ float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;
724
733
  gl_FragColor = mix(gl_FragColor, baseTexture, baseTexture.a);
725
734
 
726
735
  float snowEffect = computeSnow(vUv, 5, 15);
727
- gl_FragColor += vec4(vec3(snowEffect), 1.0);
736
+ gl_FragColor += vec4(vec3(snowEffect * effectIntensity), 1.0);
728
737
 
729
738
  float popupMoveOffset = 0.0;
730
739
  vec2 popupOffsetUv = vUv + (uMove.xy / uResolution.xy) * popupMoveOffset;
@@ -732,7 +741,7 @@ void main() {
732
741
  gl_FragColor = mix(gl_FragColor, popupTexture, popupTexture.a);
733
742
 
734
743
  snowEffect = computeSnow(vUv, 16, 20);
735
- gl_FragColor += vec4(vec3(snowEffect), 1.0);
744
+ gl_FragColor += vec4(vec3(snowEffect * effectIntensity), 1.0);
736
745
  }
737
746
  `;
738
747
 
@@ -747,6 +756,8 @@ uniform vec2 uMouse;
747
756
  uniform vec2 uMove;
748
757
  uniform vec2 uRotate;
749
758
  uniform float uTime;
759
+ uniform float uEffectIntensity;
760
+ uniform float uEffectSpeed;
750
761
  uniform sampler2D uLayer0;
751
762
  uniform sampler2D uLayer1;
752
763
  uniform int uLayerCount;
@@ -809,6 +820,11 @@ const float DEPTH_FAR = 0.1;
809
820
  const float WIDTH_FAR = 0.3;
810
821
  const float SPEED_FAR = 0.1;
811
822
 
823
+ float effectTime() {
824
+ float speed = uEffectSpeed > 0.0 ? uEffectSpeed : 1.0;
825
+ return uTime * speed;
826
+ }
827
+
812
828
  float computeSnow(in vec2 uv, int layerStart, int layerEnd) {
813
829
  const mat3 permutationMatrix = mat3(13.323122, 23.5112, 21.71123, 21.1212, 28.7312, 11.9312, 21.8112, 14.7212, 61.3934);
814
830
  vec2 moveNormalized = uMove.xy / uResolution.xy;
@@ -816,15 +832,16 @@ float computeSnow(in vec2 uv, int layerStart, int layerEnd) {
816
832
  uv.x += moveNormalized.x * 0.2;
817
833
  float totalLayers = float(LAYERS);
818
834
  float accumulation = 0.0;
819
- float depthOfField = 5.0 * sin(uTime * 0.1);
835
+ float snowTime = effectTime();
836
+ float depthOfField = 5.0 * sin(snowTime * 0.1);
820
837
  for (int i = max(layerStart, 0); i < min(layerEnd, LAYERS); i++) {
821
838
  float layer = float(i);
822
839
  float depthFactor = smoothstep(DEPTH_NEAR, DEPTH_FAR, layer / totalLayers);
823
840
  float widthFactor = smoothstep(WIDTH_NEAR, WIDTH_FAR, layer / totalLayers);
824
841
  float speedFactor = smoothstep(SPEED_NEAR, SPEED_FAR, layer / totalLayers);
825
842
  vec2 offsetUv = uv * (1.0 + layer * depthFactor);
826
- float windEffect = widthFactor * mod(layer * 7.238917, 1.0) - widthFactor * 0.1 * sin(uTime * 2.0 + layer);
827
- offsetUv += vec2(offsetUv.y * windEffect, speedFactor * uTime / (1.0 + layer * depthFactor * 0.03));
843
+ float windEffect = widthFactor * mod(layer * 7.238917, 1.0) - widthFactor * 0.1 * sin(snowTime * 2.0 + layer);
844
+ offsetUv += vec2(offsetUv.y * windEffect, speedFactor * snowTime / (1.0 + layer * depthFactor * 0.03));
828
845
  vec3 noiseInput = vec3(floor(offsetUv), 31.189 + layer);
829
846
  vec3 permuted = floor(noiseInput) * 0.00001 + fract(noiseInput);
830
847
  vec3 noise = fract((31415.9 + permuted) / fract(permutationMatrix * permuted));
@@ -839,10 +856,11 @@ float computeSnow(in vec2 uv, int layerStart, int layerEnd) {
839
856
 
840
857
  void main() {
841
858
  vec4 baseTexture = texture2D(uLayer0, vUv);
859
+ float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;
842
860
  gl_FragColor = mix(gl_FragColor, baseTexture, baseTexture.a);
843
861
 
844
862
  float snowEffect = computeSnow(vUv, 5, 15);
845
- gl_FragColor += vec4(vec3(snowEffect), 1.0);
863
+ gl_FragColor += vec4(vec3(snowEffect * effectIntensity), 1.0);
846
864
 
847
865
  // 3D parallax offset for popup layer
848
866
  vec2 popupOffset = vec2(-uRotate.x * 0.08, -uRotate.y * 0.06);
@@ -851,7 +869,7 @@ void main() {
851
869
  gl_FragColor = mix(gl_FragColor, popupTexture, popupTexture.a);
852
870
 
853
871
  snowEffect = computeSnow(vUv, 16, 20);
854
- gl_FragColor += vec4(vec3(snowEffect), 1.0);
872
+ gl_FragColor += vec4(vec3(snowEffect * effectIntensity), 1.0);
855
873
  }
856
874
  `;
857
875
 
@@ -866,6 +884,7 @@ uniform vec2 uMouse;
866
884
  uniform vec2 uMove;
867
885
  uniform vec2 uRotate;
868
886
  uniform float uTime;
887
+ uniform float uEffectIntensity;
869
888
  uniform sampler2D uLayer0;
870
889
  uniform sampler2D uLayer1;
871
890
  uniform int uLayerCount;
@@ -881,9 +900,14 @@ varying vec2 vUv;
881
900
  void main() {
882
901
  vec2 pixel = 1.0 / uResolution.xy;
883
902
  vec2 popUpUv = vUv + (uMove.xy / uResolution.xy) * 0.008;
903
+ float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;
884
904
 
885
- vec4 baseColor = kuwahara(uLayer0, vUv, pixel, 4.0);
886
- vec4 popupColor = kuwahara(uLayer1, popUpUv, pixel, 4.0);
905
+ vec4 originalBaseColor = texture2D(uLayer0, vUv);
906
+ vec4 originalPopupColor = texture2D(uLayer1, popUpUv);
907
+ vec4 brushedBaseColor = kuwahara(uLayer0, vUv, pixel, 4.0);
908
+ vec4 brushedPopupColor = kuwahara(uLayer1, popUpUv, pixel, 4.0);
909
+ vec4 baseColor = mix(originalBaseColor, brushedBaseColor, effectIntensity);
910
+ vec4 popupColor = mix(originalPopupColor, brushedPopupColor, effectIntensity);
887
911
 
888
912
  float aSoft = smoothstep(0.4, 1.0, popupColor.a);
889
913
  vec4 pocaColor = mix(baseColor, popupColor, aSoft);
@@ -903,6 +927,7 @@ uniform vec2 uMouse;
903
927
  uniform vec2 uMove;
904
928
  uniform vec2 uRotate;
905
929
  uniform float uTime;
930
+ uniform float uEffectIntensity;
906
931
  uniform sampler2D uLayer0;
907
932
  uniform sampler2D uLayer1;
908
933
  uniform int uLayerCount;
@@ -917,13 +942,18 @@ varying vec2 vUv;
917
942
 
918
943
  void main() {
919
944
  vec2 pixel = 1.0 / uResolution.xy;
945
+ float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;
920
946
 
921
947
  // 3D parallax offset for popup layer
922
948
  vec2 popupOffset = vec2(-uRotate.x * 0.08, -uRotate.y * 0.06);
923
949
  vec2 popUpUv = vUv + popupOffset;
924
950
 
925
- vec4 baseColor = kuwahara(uLayer0, vUv, pixel, 4.0);
926
- vec4 popupColor = kuwahara(uLayer1, popUpUv, pixel, 4.0);
951
+ vec4 originalBaseColor = texture2D(uLayer0, vUv);
952
+ vec4 originalPopupColor = texture2D(uLayer1, popUpUv);
953
+ vec4 brushedBaseColor = kuwahara(uLayer0, vUv, pixel, 4.0);
954
+ vec4 brushedPopupColor = kuwahara(uLayer1, popUpUv, pixel, 4.0);
955
+ vec4 baseColor = mix(originalBaseColor, brushedBaseColor, effectIntensity);
956
+ vec4 popupColor = mix(originalPopupColor, brushedPopupColor, effectIntensity);
927
957
 
928
958
  float aSoft = smoothstep(0.4, 1.0, popupColor.a);
929
959
  vec4 pocaColor = mix(baseColor, popupColor, aSoft);
@@ -943,6 +973,7 @@ uniform vec2 uMouse;
943
973
  uniform vec2 uMove;
944
974
  uniform vec2 uRotate;
945
975
  uniform float uTime;
976
+ uniform float uEffectIntensity;
946
977
  uniform sampler2D uLayer0;
947
978
  uniform sampler2D uLayer1;
948
979
  uniform int uLayerCount;
@@ -959,8 +990,11 @@ varying vec2 vUv;
959
990
  void main() {
960
991
  vec2 pixel = 1.0 / uResolution.xy;
961
992
  vec2 popUpUv = vUv + (uMove.xy / uResolution.xy) * 0.008;
993
+ float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;
962
994
 
963
- vec4 baseColor = gaussianBlur(uLayer0, vUv, pixel, 12);
995
+ vec4 originalBaseColor = texture2D(uLayer0, vUv);
996
+ vec4 blurredBaseColor = gaussianBlur(uLayer0, vUv, pixel, 12);
997
+ vec4 baseColor = mix(originalBaseColor, blurredBaseColor, effectIntensity);
964
998
  vec4 popupColor = texture2D(uLayer1, popUpUv);
965
999
 
966
1000
  float aSoft = smoothstep(0.4, 1.0, popupColor.a);
@@ -981,6 +1015,7 @@ uniform vec2 uMouse;
981
1015
  uniform vec2 uMove;
982
1016
  uniform vec2 uRotate;
983
1017
  uniform float uTime;
1018
+ uniform float uEffectIntensity;
984
1019
  uniform sampler2D uLayer0;
985
1020
  uniform sampler2D uLayer1;
986
1021
  uniform int uLayerCount;
@@ -996,12 +1031,15 @@ varying vec2 vUv;
996
1031
 
997
1032
  void main() {
998
1033
  vec2 pixel = 1.0 / uResolution.xy;
1034
+ float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;
999
1035
 
1000
1036
  // 3D parallax offset for popup layer
1001
1037
  vec2 popupOffset = vec2(-uRotate.x * 0.08, -uRotate.y * 0.06);
1002
1038
  vec2 popUpUv = vUv + popupOffset;
1003
1039
 
1004
- vec4 baseColor = gaussianBlur(uLayer0, vUv, pixel, 12);
1040
+ vec4 originalBaseColor = texture2D(uLayer0, vUv);
1041
+ vec4 blurredBaseColor = gaussianBlur(uLayer0, vUv, pixel, 12);
1042
+ vec4 baseColor = mix(originalBaseColor, blurredBaseColor, effectIntensity);
1005
1043
  vec4 popupColor = texture2D(uLayer1, popUpUv);
1006
1044
 
1007
1045
  float aSoft = smoothstep(0.4, 1.0, popupColor.a);
@@ -1022,6 +1060,8 @@ uniform vec2 uMouse;
1022
1060
  uniform vec2 uMove;
1023
1061
  uniform vec2 uRotate;
1024
1062
  uniform float uTime;
1063
+ uniform float uEffectIntensity;
1064
+ uniform float uEffectSpeed;
1025
1065
  uniform sampler2D uLayer0;
1026
1066
  uniform sampler2D uLayer1;
1027
1067
  uniform int uLayerCount;
@@ -1040,14 +1080,16 @@ vec3 hsv2rgb(vec3 c) {
1040
1080
  void main() {
1041
1081
  vec4 baseColor = texture2D(uLayer0, vUv);
1042
1082
  vec4 popupColor = texture2D(uLayer1, vUv);
1083
+ float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;
1084
+ float effectSpeed = uEffectSpeed > 0.0 ? uEffectSpeed : 1.0;
1043
1085
 
1044
1086
  // Iridescence on base only
1045
1087
  float angle = uRotate.x * 2.0 + uRotate.y * 1.5;
1046
- float hue = fract(vUv.y * 0.8 + vUv.x * 0.3 + angle * 0.5 + uTime * 0.05);
1088
+ float hue = fract(vUv.y * 0.8 + vUv.x * 0.3 + angle * 0.5 + uTime * 0.05 * effectSpeed);
1047
1089
  vec3 rainbow = hsv2rgb(vec3(hue, 0.6, 1.0));
1048
1090
 
1049
1091
  float tiltAmount = length(uRotate) * 3.0;
1050
- float holoIntensity = smoothstep(0.0, 1.0, tiltAmount) * 0.35;
1092
+ float holoIntensity = smoothstep(0.0, 1.0, tiltAmount) * 0.35 * effectIntensity;
1051
1093
 
1052
1094
  vec3 holoBase = baseColor.rgb + rainbow * holoIntensity;
1053
1095
 
@@ -1070,6 +1112,8 @@ uniform vec2 uMouse;
1070
1112
  uniform vec2 uMove;
1071
1113
  uniform vec2 uRotate;
1072
1114
  uniform float uTime;
1115
+ uniform float uEffectIntensity;
1116
+ uniform float uEffectSpeed;
1073
1117
  uniform sampler2D uLayer0;
1074
1118
  uniform sampler2D uLayer1;
1075
1119
  uniform int uLayerCount;
@@ -1087,6 +1131,8 @@ vec3 hsv2rgb(vec3 c) {
1087
1131
 
1088
1132
  void main() {
1089
1133
  vec4 baseColor = texture2D(uLayer0, vUv);
1134
+ float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;
1135
+ float effectSpeed = uEffectSpeed > 0.0 ? uEffectSpeed : 1.0;
1090
1136
 
1091
1137
  // 3D parallax offset for popup layer
1092
1138
  vec2 popupOffset = vec2(-uRotate.x * 0.08, -uRotate.y * 0.06);
@@ -1095,11 +1141,11 @@ void main() {
1095
1141
 
1096
1142
  // Iridescence on base only
1097
1143
  float angle = uRotate.x * 2.0 + uRotate.y * 1.5;
1098
- float hue = fract(vUv.y * 0.8 + vUv.x * 0.3 + angle * 0.5 + uTime * 0.05);
1144
+ float hue = fract(vUv.y * 0.8 + vUv.x * 0.3 + angle * 0.5 + uTime * 0.05 * effectSpeed);
1099
1145
  vec3 rainbow = hsv2rgb(vec3(hue, 0.6, 1.0));
1100
1146
 
1101
1147
  float tiltAmount = length(uRotate) * 3.0;
1102
- float holoIntensity = smoothstep(0.0, 1.0, tiltAmount) * 0.35;
1148
+ float holoIntensity = smoothstep(0.0, 1.0, tiltAmount) * 0.35 * effectIntensity;
1103
1149
 
1104
1150
  vec3 holoBase = baseColor.rgb + rainbow * holoIntensity;
1105
1151
 
@@ -1111,6 +1157,648 @@ void main() {
1111
1157
  }
1112
1158
  `;
1113
1159
 
1160
+ // src/shaders/pulse-lines.frag.ts
1161
+ var pulse_lines_frag_default = glsl`
1162
+ #ifdef GL_ES
1163
+ precision highp float;
1164
+ #endif
1165
+
1166
+ uniform vec2 uResolution;
1167
+ uniform vec2 uMouse;
1168
+ uniform vec2 uMove;
1169
+ uniform vec2 uRotate;
1170
+ uniform float uTime;
1171
+ uniform float uEffectIntensity;
1172
+ uniform float uEffectSpeed;
1173
+ uniform sampler2D uLayer0;
1174
+ uniform sampler2D uLayer1;
1175
+ uniform int uLayerCount;
1176
+
1177
+ varying vec2 vUv;
1178
+
1179
+ #include <utils/defaultLighting>
1180
+
1181
+ float pulseField(vec2 uv, float t) {
1182
+ float dist = length(uv);
1183
+ float band = abs(fract(t - dist * 0.9) - 0.5);
1184
+ float ring = 1.0 - smoothstep(0.03, 0.12, band);
1185
+ float wave = 0.5 + 0.5 * sin((uv.x + uv.y) * 8.0 + t * 2.0);
1186
+ float stripes = 0.5 + 0.5 * sin((uv.x - uv.y) * 14.0 - t * 3.0);
1187
+ return ring * 0.55 + wave * 0.25 + stripes * 0.20;
1188
+ }
1189
+
1190
+ void main() {
1191
+ vec4 baseColor = texture2D(uLayer0, vUv);
1192
+ float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;
1193
+ float effectSpeed = uEffectSpeed > 0.0 ? uEffectSpeed : 1.0;
1194
+ vec2 popupOffset = vec2(-uRotate.x * 0.08, -uRotate.y * 0.06);
1195
+ vec4 popupColor = texture2D(uLayer1, vUv + popupOffset);
1196
+ float popupMix = smoothstep(0.35, 1.0, popupColor.a);
1197
+ vec3 layeredColor = mix(baseColor.rgb, popupColor.rgb, popupMix);
1198
+
1199
+ vec2 centered = (vUv * 2.0 - 1.0);
1200
+ centered.x *= uResolution.x / max(uResolution.y, 1.0);
1201
+
1202
+ float time = uTime * 0.35 * effectSpeed;
1203
+ float field = 0.0;
1204
+
1205
+ for (int j = 0; j < 3; j++) {
1206
+ float jf = float(j);
1207
+ float offset = jf * 0.24;
1208
+ vec2 lane = centered;
1209
+ lane.x += sin(lane.y * 3.0 + time + jf) * 0.18;
1210
+ lane.y += cos(lane.x * 2.2 - time * 1.2 + jf * 0.7) * 0.14;
1211
+ field += pulseField(lane + vec2(offset), time + jf * 0.6);
1212
+ }
1213
+ field /= 3.0;
1214
+
1215
+ float edge = smoothstep(1.2, 0.1, length(centered));
1216
+ float highlight = smoothstep(0.25, 0.95, field) * edge;
1217
+ float glow = smoothstep(0.18, 0.95, field + 0.12 * sin(time + centered.x * 4.0));
1218
+
1219
+ float luminance = dot(layeredColor, vec3(0.299, 0.587, 0.114));
1220
+ vec3 lifted = mix(layeredColor, vec3(luminance), 0.08);
1221
+ vec3 pulseColor = lifted + layeredColor * (0.22 + glow * 0.18) + vec3(0.04) * glow;
1222
+ vec3 finalColor = mix(layeredColor, pulseColor, highlight * 0.88 * effectIntensity);
1223
+ finalColor += (pulseColor - layeredColor) * glow * 0.10 * effectIntensity;
1224
+
1225
+ float finalAlpha = max(baseColor.a, popupColor.a);
1226
+ gl_FragColor = defaultLighting(vec4(finalColor, finalAlpha), uResolution, uRotate, 1.0);
1227
+ }
1228
+ `;
1229
+
1230
+ // src/shaders/gradient-flow.frag.ts
1231
+ var gradient_flow_frag_default = glsl`
1232
+ #ifdef GL_ES
1233
+ precision highp float;
1234
+ #endif
1235
+
1236
+ uniform vec2 uResolution;
1237
+ uniform vec2 uMouse;
1238
+ uniform vec2 uMove;
1239
+ uniform vec2 uRotate;
1240
+ uniform float uTime;
1241
+ uniform float uEffectIntensity;
1242
+ uniform float uEffectSpeed;
1243
+ uniform sampler2D uLayer0;
1244
+ uniform sampler2D uLayer1;
1245
+ uniform int uLayerCount;
1246
+
1247
+ varying vec2 vUv;
1248
+
1249
+ #include <utils/defaultLighting>
1250
+
1251
+ #define S(a,b,t) smoothstep(a,b,t)
1252
+
1253
+ mat2 Rot(float a) {
1254
+ float s = sin(a);
1255
+ float c = cos(a);
1256
+ return mat2(c, -s, s, c);
1257
+ }
1258
+
1259
+ vec2 hash(vec2 p) {
1260
+ p = vec2(dot(p, vec2(2127.1, 81.17)), dot(p, vec2(1269.5, 283.37)));
1261
+ return fract(sin(p) * 43758.5453);
1262
+ }
1263
+
1264
+ float noise(in vec2 p) {
1265
+ vec2 i = floor(p);
1266
+ vec2 f = fract(p);
1267
+ vec2 u = f * f * (3.0 - 2.0 * f);
1268
+
1269
+ float n = mix(
1270
+ mix(
1271
+ dot(-1.0 + 2.0 * hash(i + vec2(0.0, 0.0)), f - vec2(0.0, 0.0)),
1272
+ dot(-1.0 + 2.0 * hash(i + vec2(1.0, 0.0)), f - vec2(1.0, 0.0)),
1273
+ u.x
1274
+ ),
1275
+ mix(
1276
+ dot(-1.0 + 2.0 * hash(i + vec2(0.0, 1.0)), f - vec2(0.0, 1.0)),
1277
+ dot(-1.0 + 2.0 * hash(i + vec2(1.0, 1.0)), f - vec2(1.0, 1.0)),
1278
+ u.x
1279
+ ),
1280
+ u.y
1281
+ );
1282
+
1283
+ return 0.5 + 0.5 * n;
1284
+ }
1285
+
1286
+ void main() {
1287
+ vec4 baseColor = texture2D(uLayer0, vUv);
1288
+ float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;
1289
+ float effectSpeed = uEffectSpeed > 0.0 ? uEffectSpeed : 1.0;
1290
+ vec2 popupOffset = vec2(-uRotate.x * 0.08, -uRotate.y * 0.06);
1291
+ vec4 popupColor = texture2D(uLayer1, vUv + popupOffset);
1292
+ float popupMix = smoothstep(0.35, 1.0, popupColor.a);
1293
+ vec3 layeredColor = mix(baseColor.rgb, popupColor.rgb, popupMix);
1294
+
1295
+ vec2 uv = vUv;
1296
+ float ratio = uResolution.x / max(uResolution.y, 1.0);
1297
+
1298
+ vec2 tuv = uv - 0.5;
1299
+
1300
+ float effectTime = uTime * effectSpeed;
1301
+ float degree = noise(vec2(effectTime * 0.1, tuv.x * tuv.y));
1302
+
1303
+ tuv.y *= 1.0 / ratio;
1304
+ tuv *= Rot(radians((degree - 0.5) * 720.0 + 180.0));
1305
+ tuv.y *= ratio;
1306
+
1307
+ float frequency = 5.0;
1308
+ float amplitude = 30.0;
1309
+ float speed = effectTime * 2.0;
1310
+ tuv.x += sin(tuv.y * frequency + speed) / amplitude;
1311
+ tuv.y += sin(tuv.x * frequency * 1.5 + speed) / (amplitude * 0.5);
1312
+
1313
+ vec3 colorYellow = vec3(0.957, 0.804, 0.623);
1314
+ vec3 colorDeepBlue = vec3(0.192, 0.384, 0.933);
1315
+ vec3 layer1 = mix(colorYellow, colorDeepBlue, S(-0.3, 0.2, (tuv * Rot(radians(-5.0))).x));
1316
+
1317
+ vec3 colorRed = vec3(0.910, 0.510, 0.800);
1318
+ vec3 colorBlue = vec3(0.350, 0.710, 0.953);
1319
+ vec3 layer2 = mix(colorRed, colorBlue, S(-0.3, 0.2, (tuv * Rot(radians(-5.0))).x));
1320
+
1321
+ vec3 waveComp = mix(layer1, layer2, S(0.5, -0.3, tuv.y));
1322
+
1323
+ float luminance = dot(layeredColor, vec3(0.299, 0.587, 0.114));
1324
+ vec3 neutralBase = mix(layeredColor, vec3(luminance), 0.12);
1325
+ vec3 finalComp = mix(neutralBase, waveComp, 0.78 * effectIntensity);
1326
+ finalComp = mix(layeredColor, finalComp, 0.18 * effectIntensity);
1327
+
1328
+ float vignette = smoothstep(1.25, 0.15, length((uv - 0.5) * vec2(ratio, 1.0)));
1329
+ finalComp = mix(finalComp * 0.75, finalComp, vignette);
1330
+
1331
+ gl_FragColor = defaultLighting(vec4(finalComp, max(baseColor.a, popupColor.a)), uResolution, uRotate, 1.0);
1332
+ }
1333
+ `;
1334
+
1335
+ // src/shaders/procedural-ocean.frag.ts
1336
+ var procedural_ocean_frag_default = glsl`
1337
+ #ifdef GL_ES
1338
+ precision highp float;
1339
+ #endif
1340
+
1341
+ #define DRAG_MULT 0.048
1342
+ #define ITERATIONS_RAYMARCH 13
1343
+ #define ITERATIONS_NORMAL 48
1344
+
1345
+ uniform vec2 uResolution;
1346
+ uniform vec2 uMove;
1347
+ uniform vec2 uRotate;
1348
+ uniform float uTime;
1349
+ uniform float uEffectIntensity;
1350
+ uniform float uEffectSpeed;
1351
+ uniform sampler2D uLayer0;
1352
+ uniform sampler2D uLayer1;
1353
+ uniform int uLayerCount;
1354
+
1355
+ varying vec2 vUv;
1356
+
1357
+ const vec2 DEFAULT_VIEW = vec2(0.0, 0.0);
1358
+
1359
+ float effectTime() {
1360
+ float speed = uEffectSpeed > 0.0 ? uEffectSpeed : 1.0;
1361
+ return uTime * speed;
1362
+ }
1363
+
1364
+ vec2 wavedx(vec2 position, vec2 direction, float speed, float frequency, float timeshift) {
1365
+ float x = dot(direction, position) * frequency + timeshift * speed;
1366
+ float wave = exp(sin(x) - 1.0);
1367
+ float dx = wave * cos(x);
1368
+ return vec2(wave, -dx);
1369
+ }
1370
+
1371
+ float getwaves(vec2 position, int iterations) {
1372
+ float iter = 0.0;
1373
+ float phase = 6.0;
1374
+ float speed = 0.4;
1375
+ float weight = 1.0;
1376
+ float w = 0.0;
1377
+ float ws = 0.0;
1378
+ for (int i = 0; i < iterations; i++) {
1379
+ vec2 p = vec2(sin(iter), cos(iter));
1380
+ vec2 res = wavedx(position, p, speed, phase, effectTime());
1381
+ position += p * res.y * weight * DRAG_MULT;
1382
+ w += res.x * weight;
1383
+ iter += 12.0;
1384
+ ws += weight;
1385
+ weight = mix(weight, 0.0, 0.2);
1386
+ phase *= 1.18;
1387
+ speed *= 1.07;
1388
+ }
1389
+ return w / ws;
1390
+ }
1391
+
1392
+ float raymarchwater(vec3 camera, vec3 start, vec3 end, float depth) {
1393
+ vec3 pos = start;
1394
+ float h = 0.0;
1395
+ vec3 dir = normalize(end - start);
1396
+ float eps = 0.01;
1397
+ for (int i = 0; i < 318; i++) {
1398
+ h = getwaves(pos.xz * 0.1, ITERATIONS_RAYMARCH) * depth - depth;
1399
+ float dist_pos = distance(pos, camera);
1400
+ if (h + eps * dist_pos > pos.y) {
1401
+ return dist_pos;
1402
+ }
1403
+ pos += dir * (pos.y - h);
1404
+ }
1405
+ return -1.0;
1406
+ }
1407
+
1408
+ vec3 normal(vec2 pos, float e, float depth) {
1409
+ vec2 ex = vec2(e, 0.0);
1410
+ float h = getwaves(pos * 0.1, ITERATIONS_NORMAL) * depth - depth;
1411
+ float hx = getwaves((pos + ex.xy) * 0.1, ITERATIONS_NORMAL) * depth - depth;
1412
+ float hy = getwaves((pos + ex.yx) * 0.1, ITERATIONS_NORMAL) * depth - depth;
1413
+ vec3 a = vec3(pos.x, h, pos.y);
1414
+ vec3 b = vec3(pos.x + e, hx, pos.y);
1415
+ vec3 c = vec3(pos.x, hy, pos.y + e);
1416
+ return normalize(cross(b - a, c - a));
1417
+ }
1418
+
1419
+ mat3 rotmat(vec3 axis, float angle) {
1420
+ axis = normalize(axis);
1421
+ float s = sin(angle);
1422
+ float c = cos(angle);
1423
+ float oc = 1.0 - c;
1424
+ return mat3(
1425
+ oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s,
1426
+ oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s,
1427
+ oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c
1428
+ );
1429
+ }
1430
+
1431
+ vec3 getRay(vec2 uv) {
1432
+ uv = (uv * 2.0 - 1.0) * vec2(uResolution.x / uResolution.y, 1.0);
1433
+ vec3 proj = normalize(vec3(uv.x, uv.y, 1.0) + vec3(uv.x, uv.y, -1.0) * pow(length(uv), 2.0) * 0.05);
1434
+ vec3 ray = rotmat(vec3(0.0, -1.0, 0.0), 3.0 * (DEFAULT_VIEW.x * 2.0 - 1.0) + uRotate.x * 0.06) *
1435
+ rotmat(vec3(1.0, 0.0, 0.0), 1.5 * (DEFAULT_VIEW.y * 2.0 - 1.0) + uRotate.y * 0.04) *
1436
+ proj;
1437
+ return ray;
1438
+ }
1439
+
1440
+ float intersectPlane(vec3 origin, vec3 direction, vec3 point, vec3 normal) {
1441
+ return clamp(dot(point - origin, normal) / dot(direction, normal), -1.0, 9991999.0);
1442
+ }
1443
+
1444
+ vec3 extra_cheap_atmosphere(vec3 raydir, vec3 sundir) {
1445
+ sundir.y = max(sundir.y, -0.07);
1446
+ float special_trick = 1.0 / (raydir.y * 1.0 + 0.1);
1447
+ float special_trick2 = 1.0 / (sundir.y * 11.0 + 1.0);
1448
+ float raysundt = pow(abs(dot(sundir, raydir)), 2.0);
1449
+ float sundt = pow(max(0.0, dot(sundir, raydir)), 8.0);
1450
+ float mymie = sundt * special_trick * 0.2;
1451
+ vec3 suncolor = mix(vec3(1.0), max(vec3(0.0), vec3(1.0) - vec3(5.5, 13.0, 22.4) / 22.4), special_trick2);
1452
+ vec3 bluesky = vec3(5.5, 13.0, 22.4) / 22.4 * suncolor;
1453
+ vec3 bluesky2 = max(vec3(0.0), bluesky - vec3(5.5, 13.0, 22.4) * 0.002 * (special_trick + -6.0 * sundir.y * sundir.y));
1454
+ bluesky2 *= special_trick * (0.24 + raysundt * 0.24);
1455
+ return bluesky2 * (1.0 + 1.0 * pow(1.0 - raydir.y, 3.0)) + mymie * suncolor;
1456
+ }
1457
+
1458
+ vec3 getatm(vec3 ray) {
1459
+ return extra_cheap_atmosphere(ray, normalize(vec3(1.0))) * 0.5;
1460
+ }
1461
+
1462
+ float sun(vec3 ray) {
1463
+ vec3 sd = normalize(vec3(1.0));
1464
+ return pow(max(0.0, dot(ray, sd)), 528.0) * 110.0;
1465
+ }
1466
+
1467
+ vec3 aces_tonemap(vec3 color) {
1468
+ mat3 m1 = mat3(
1469
+ 0.59719, 0.07600, 0.02840,
1470
+ 0.35458, 0.90834, 0.13383,
1471
+ 0.04823, 0.01566, 0.83777
1472
+ );
1473
+ mat3 m2 = mat3(
1474
+ 1.60475, -0.10208, -0.00327,
1475
+ -0.53108, 1.10813, -0.07276,
1476
+ -0.07367, -0.00605, 1.07602
1477
+ );
1478
+ vec3 v = m1 * color;
1479
+ vec3 a = v * (v + 0.0245786) - 0.000090537;
1480
+ vec3 b = v * (0.983729 * v + 0.4329510) + 0.238081;
1481
+ return pow(clamp(m2 * (a / b), 0.0, 1.0), vec3(1.0 / 2.2));
1482
+ }
1483
+
1484
+ void main() {
1485
+ vec2 uv = vUv;
1486
+ float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;
1487
+ float waterdepth = 2.1;
1488
+ vec3 wfloor = vec3(0.0, -waterdepth, 0.0);
1489
+ vec3 wceil = vec3(0.0, 0.0, 0.0);
1490
+ // vec3 orig = vec3(uMove.x * 0.12, 2.0 + uMove.y * 0.08, 0.0);
1491
+ vec3 orig = vec3(0.0, 2.0, 0.0);
1492
+ vec3 ray = getRay(uv);
1493
+
1494
+ vec4 baseColor = texture2D(uLayer0, uv);
1495
+ // vec2 popupOffset = vec2(-uRotate.x * 0.08, -uRotate.y * 0.06);
1496
+ vec2 popupOffset = vec2(0.0, 0.0);
1497
+ vec4 popupColor = texture2D(uLayer1, uv + popupOffset);
1498
+ float popupMix = smoothstep(0.35, 1.0, popupColor.a);
1499
+ vec3 layeredColor = mix(baseColor.rgb, popupColor.rgb, popupMix);
1500
+ vec3 tint = mix(layeredColor, vec3(dot(layeredColor, vec3(0.299, 0.587, 0.114))), 0.15);
1501
+
1502
+ float hihit = intersectPlane(orig, ray, wceil, vec3(0.0, 1.0, 0.0));
1503
+ if (ray.y >= -0.01) {
1504
+ vec3 C = getatm(ray) * 2.0 + sun(ray);
1505
+ C = aces_tonemap(C);
1506
+ C = mix(C, tint, 0.38 * effectIntensity); // sky tint
1507
+ gl_FragColor = vec4(C, 1.0);
1508
+ return;
1509
+ }
1510
+
1511
+ float lohit = intersectPlane(orig, ray, wfloor, vec3(0.0, 1.0, 0.0));
1512
+ vec3 hipos = orig + ray * hihit;
1513
+ vec3 lopos = orig + ray * lohit;
1514
+ float dist = raymarchwater(orig, hipos, lopos, waterdepth);
1515
+ vec3 pos = orig + ray * dist;
1516
+
1517
+ vec3 N = normal(pos.xz, 0.001, waterdepth);
1518
+ vec2 velocity = N.xz * (1.0 - N.y);
1519
+ N = mix(vec3(0.0, 1.0, 0.0), N, 1.0 / (dist * dist * 0.01 + 1.0));
1520
+ vec3 R = reflect(ray, N);
1521
+ float fresnel = 0.04 + (1.0 - 0.04) * pow(1.0 - max(0.0, dot(-N, ray)), 5.0);
1522
+
1523
+ vec3 C = fresnel * getatm(R) * 2.0 + fresnel * sun(R);
1524
+ C = mix(C, tint, 0.32 * effectIntensity); // water tint
1525
+ C += vec3(velocity.xyx) * 0.01;
1526
+ C = aces_tonemap(C);
1527
+ C = mix(C, layeredColor, 0.75 * effectIntensity); // final color mix
1528
+
1529
+ gl_FragColor = vec4(C, 1.0);
1530
+ }
1531
+ `;
1532
+
1533
+ // src/shaders/rainbow-flow.frag.ts
1534
+ var rainbow_flow_frag_default = glsl`
1535
+ #ifdef GL_ES
1536
+ precision highp float;
1537
+ #endif
1538
+
1539
+ uniform vec2 uResolution;
1540
+ uniform vec2 uMove;
1541
+ uniform vec2 uRotate;
1542
+ uniform float uTime;
1543
+ uniform float uEffectIntensity;
1544
+ uniform float uEffectSpeed;
1545
+ uniform sampler2D uLayer0;
1546
+ uniform sampler2D uLayer1;
1547
+ uniform int uLayerCount;
1548
+
1549
+ varying vec2 vUv;
1550
+
1551
+ #include <utils/defaultLighting>
1552
+
1553
+ vec3 hsv2rgb(vec3 c) {
1554
+ vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
1555
+ vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
1556
+ return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
1557
+ }
1558
+
1559
+ void main() {
1560
+ vec4 baseColor = texture2D(uLayer0, vUv);
1561
+ float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;
1562
+ float effectSpeed = uEffectSpeed > 0.0 ? uEffectSpeed : 1.0;
1563
+ vec2 popupOffset = vec2(-uRotate.x * 0.08, -uRotate.y * 0.06);
1564
+ vec4 popupColor = texture2D(uLayer1, vUv + popupOffset);
1565
+
1566
+ float popupMix = smoothstep(0.35, 1.0, popupColor.a);
1567
+ vec3 layeredColor = mix(baseColor.rgb, popupColor.rgb, popupMix);
1568
+
1569
+ vec2 uv = vUv;
1570
+ float ratio = uResolution.x / max(uResolution.y, 1.0);
1571
+ vec2 centered = (uv - 0.5) * vec2(ratio, 1.0);
1572
+
1573
+ float effectTime = uTime * effectSpeed;
1574
+ float hue = fract((uv.x + uv.y) * 0.25 + effectTime * 0.5);
1575
+ vec3 rainbow = hsv2rgb(vec3(hue, 0.6, 1.0));
1576
+
1577
+ float flow = 0.5 + 0.5 * sin((centered.x + centered.y) * 7.0 + effectTime * 1.8);
1578
+ float stripe = 0.5 + 0.5 * sin((centered.x - centered.y) * 11.0 - effectTime * 1.2);
1579
+ float mask = smoothstep(0.15, 0.95, 0.35 * flow + 0.65 * stripe);
1580
+ float vignette = smoothstep(1.2, 0.15, length(centered));
1581
+
1582
+ vec3 tint = mix(layeredColor, layeredColor * rainbow, 0.22);
1583
+ vec3 finalColor = mix(layeredColor, tint, mask * 0.65 * effectIntensity);
1584
+ finalColor = mix(finalColor * 0.85, finalColor, vignette);
1585
+
1586
+ gl_FragColor = defaultLighting(vec4(finalColor, max(baseColor.a, popupColor.a)), uResolution, uRotate, 1.0);
1587
+ }
1588
+ `;
1589
+
1590
+ // src/shaders/shock-wave.frag.ts
1591
+ var shock_wave_frag_default = glsl`
1592
+ #ifdef GL_ES
1593
+ precision highp float;
1594
+ #endif
1595
+
1596
+ uniform vec2 uResolution;
1597
+ uniform vec2 uMove;
1598
+ uniform vec2 uRotate;
1599
+ uniform float uTime;
1600
+ uniform float uEffectIntensity;
1601
+ uniform float uEffectSpeed;
1602
+ uniform sampler2D uLayer0;
1603
+ uniform sampler2D uLayer1;
1604
+ uniform int uLayerCount;
1605
+
1606
+ varying vec2 vUv;
1607
+
1608
+ #include <utils/defaultLighting>
1609
+
1610
+ #define CENTER vec2(0.5, 0.5)
1611
+ #define PI 3.1415926
1612
+
1613
+ #define force 0.04
1614
+ #define thickness 0.075
1615
+ #define feathering 0.05
1616
+ #define aberrationOffset 0.006
1617
+ #define flashIntensity 3.0
1618
+ #define waveSpeed 0.42
1619
+
1620
+ vec2 centerScaleUV(vec2 uv, vec2 factor) {
1621
+ return (uv - vec2(0.5)) * factor + vec2(0.5);
1622
+ }
1623
+
1624
+ float easeOutSine(float t) {
1625
+ return sin((t * PI) / 2.0);
1626
+ }
1627
+
1628
+ void main() {
1629
+ vec4 baseColor = texture2D(uLayer0, vUv);
1630
+ float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;
1631
+ float effectSpeed = uEffectSpeed > 0.0 ? uEffectSpeed : 1.0;
1632
+ vec2 popupOffset = vec2(-uRotate.x * 0.08, -uRotate.y * 0.06);
1633
+ vec4 popupColor = texture2D(uLayer1, vUv + popupOffset);
1634
+ float popupMix = smoothstep(0.35, 1.0, popupColor.a);
1635
+ vec3 layeredColor = mix(baseColor.rgb, popupColor.rgb, popupMix);
1636
+
1637
+ vec2 screenUV = vUv;
1638
+ float pos = easeOutSine(fract(uTime * waveSpeed * effectSpeed));
1639
+
1640
+ float aspectRatio = uResolution.x / max(uResolution.y, 1.0);
1641
+ vec2 scalingFactor = vec2(aspectRatio, 1.0);
1642
+ scalingFactor *= 2.0;
1643
+ scalingFactor *= 1.0 - thickness - feathering;
1644
+ scalingFactor /= sqrt(pow(aspectRatio, 2.0) + 1.0);
1645
+
1646
+ vec2 scaledUV = centerScaleUV(screenUV, scalingFactor);
1647
+ vec2 displacement = normalize(scaledUV - CENTER + vec2(1e-5)) * force * effectIntensity;
1648
+ float distanceFromCenter = distance(scaledUV, CENTER);
1649
+
1650
+ float innerBound = smoothstep(
1651
+ pos - thickness - feathering,
1652
+ pos - thickness,
1653
+ distanceFromCenter
1654
+ );
1655
+ float outerBound = smoothstep(
1656
+ pos - feathering,
1657
+ pos,
1658
+ distanceFromCenter
1659
+ );
1660
+ float shapeMask = innerBound - outerBound;
1661
+
1662
+ vec2 coords = vUv;
1663
+
1664
+ vec2 texelOffset = displacement * shapeMask;
1665
+ vec2 chromaOffset = texelOffset * 0.5;
1666
+
1667
+ vec3 background;
1668
+ background.r = texture2D(uLayer0, clamp(coords - (texelOffset - aberrationOffset * chromaOffset), vec2(0.0), vec2(1.0))).r;
1669
+ background.g = texture2D(uLayer0, clamp(coords - texelOffset, vec2(0.0), vec2(1.0))).g;
1670
+ background.b = texture2D(uLayer0, clamp(coords - (texelOffset + aberrationOffset * chromaOffset), vec2(0.0), vec2(1.0))).b;
1671
+
1672
+ float flashOpacity = pow(1.0 - pos, 4.0);
1673
+ float flashMask = 1.0 - innerBound;
1674
+ background += flashIntensity * background * flashMask * flashOpacity * 0.12 * effectIntensity;
1675
+
1676
+ vec3 finalColor = mix(background, layeredColor, 0.35);
1677
+ finalColor = mix(finalColor, layeredColor, popupMix * 0.25);
1678
+
1679
+ gl_FragColor = defaultLighting(vec4(finalColor, max(baseColor.a, popupColor.a)), uResolution, uRotate, 1.0);
1680
+ }
1681
+ `;
1682
+
1683
+ // src/shaders/ripple.frag.ts
1684
+ var ripple_frag_default = glsl`
1685
+ #ifdef GL_ES
1686
+ precision highp float;
1687
+ #endif
1688
+
1689
+ uniform vec2 uResolution;
1690
+ uniform vec2 uMove;
1691
+ uniform vec2 uRotate;
1692
+ uniform float uTime;
1693
+ uniform float uEffectIntensity;
1694
+ uniform float uEffectSpeed;
1695
+ uniform sampler2D uLayer0;
1696
+ uniform sampler2D uLayer1;
1697
+ uniform int uLayerCount;
1698
+
1699
+ varying vec2 vUv;
1700
+
1701
+ #include <utils/defaultLighting>
1702
+
1703
+ const vec2 CENTER = vec2(0.5, 0.5);
1704
+ const float EffectDuration = 2.0;
1705
+ const float EffectFadeInTimeFactor = 0.5;
1706
+ const float EffectWidth = 0.8;
1707
+ const float EffectMaxTexelOffset = 0.01;
1708
+
1709
+ vec2 getOffsetFromCenter(vec2 screenCoords, vec2 screenSize) {
1710
+ vec2 halfScreenSize = screenSize / 2.0;
1711
+ return (screenCoords - halfScreenSize) / min(halfScreenSize.x, halfScreenSize.y);
1712
+ }
1713
+
1714
+ vec2 getDistortion(vec2 offsetDirection, float offsetDistance, float time) {
1715
+ float progress = mod(time, EffectDuration) / EffectDuration;
1716
+
1717
+ float halfWidth = EffectWidth / 2.0;
1718
+ float lower = 1.0 - smoothstep(progress - halfWidth, progress, offsetDistance);
1719
+ float upper = smoothstep(progress, progress + halfWidth, offsetDistance);
1720
+ float band = 1.0 - (upper + lower);
1721
+
1722
+ float strength = 1.0 - progress;
1723
+ float fadeStrength = smoothstep(0.0, EffectFadeInTimeFactor, progress);
1724
+ float distortion = band * strength * fadeStrength;
1725
+
1726
+ return distortion * offsetDirection * EffectMaxTexelOffset;
1727
+ }
1728
+
1729
+ void main() {
1730
+ vec4 baseColor = texture2D(uLayer0, vUv);
1731
+ float effectIntensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.0;
1732
+ float effectSpeed = uEffectSpeed > 0.0 ? uEffectSpeed : 1.0;
1733
+ vec2 popupOffset = vec2(-uRotate.x * 0.08, -uRotate.y * 0.06);
1734
+ vec4 popupColor = texture2D(uLayer1, vUv + popupOffset);
1735
+ float popupMix = smoothstep(0.35, 1.0, popupColor.a);
1736
+ vec3 layeredColor = mix(baseColor.rgb, popupColor.rgb, popupMix);
1737
+
1738
+ vec2 screenSize = max(uResolution, vec2(1.0));
1739
+ vec2 screenCoords = vUv * screenSize;
1740
+ vec2 offsetFromCenter = getOffsetFromCenter(screenCoords, screenSize);
1741
+ offsetFromCenter += uMove * 0.12 + uRotate * 0.04;
1742
+
1743
+ float offsetDistance = length(offsetFromCenter);
1744
+ vec2 offsetDirection = normalize(-offsetFromCenter + vec2(1e-5));
1745
+ float effectTime = uTime * effectSpeed;
1746
+ vec2 offset = getDistortion(offsetDirection, offsetDistance, effectTime * 1.2);
1747
+ offset *= effectIntensity;
1748
+
1749
+ vec2 warpedUv = clamp(vUv + offset, vec2(0.0), vec2(1.0));
1750
+ vec3 rippleColor = texture2D(uLayer0, warpedUv).rgb;
1751
+
1752
+ float dist = length((vUv - CENTER) * vec2(screenSize.x / screenSize.y, 1.0));
1753
+ float ring = 1.0 - smoothstep(0.0, 0.55, abs(fract(effectTime * 0.8 - dist * 2.5) - 0.5));
1754
+ float rippleMix = smoothstep(0.15, 0.9, ring);
1755
+
1756
+ vec3 finalColor = mix(layeredColor, rippleColor, rippleMix * 0.8 * effectIntensity);
1757
+ finalColor = mix(finalColor, layeredColor, 0.45);
1758
+ finalColor += layeredColor * rippleMix * 0.05;
1759
+
1760
+ gl_FragColor = defaultLighting(vec4(finalColor, max(baseColor.a, popupColor.a)), uResolution, uRotate, 1.0);
1761
+ }
1762
+ `;
1763
+
1764
+ // src/shaders/lenticular.frag.ts
1765
+ var lenticular_frag_default = glsl`
1766
+ #ifdef GL_ES
1767
+ precision highp float;
1768
+ #endif
1769
+
1770
+ uniform vec2 uResolution;
1771
+ uniform vec2 uMove;
1772
+ uniform vec2 uRotate;
1773
+ uniform float uTime;
1774
+ uniform sampler2D uLayer0;
1775
+ uniform sampler2D uLayer1;
1776
+ uniform int uLayerCount;
1777
+ uniform float uEffectIntensity;
1778
+ uniform float uEffectThreshold;
1779
+
1780
+ varying vec2 vUv;
1781
+
1782
+ #include <utils/defaultLighting>
1783
+
1784
+ void main() {
1785
+ vec4 baseColor = texture2D(uLayer0, vUv);
1786
+ vec4 topColor = texture2D(uLayer1, vUv);
1787
+
1788
+ float intensity = uEffectIntensity > 0.0 ? uEffectIntensity : 1.8;
1789
+ float threshold = uEffectThreshold > 0.0 ? uEffectThreshold : 0.5;
1790
+ float tilt = clamp(abs(uRotate.x) * intensity, 0.0, 1.0);
1791
+ float blend = smoothstep(0.0, threshold, tilt);
1792
+ float baseWeight = 1.0 - blend;
1793
+ float topWeight = blend;
1794
+
1795
+ vec3 finalColor = baseColor.rgb * baseWeight + topColor.rgb * topWeight;
1796
+ float alpha = baseColor.a * baseWeight + topColor.a * topWeight;
1797
+
1798
+ gl_FragColor = defaultLighting(vec4(finalColor, alpha), uResolution, uRotate, 1.0);
1799
+ }
1800
+ `;
1801
+
1114
1802
  // src/renderer/face-renderer.ts
1115
1803
  var FRAG_SHADERS = {
1116
1804
  "glare": glare_frag_default,
@@ -1122,16 +1810,23 @@ var FRAG_SHADERS = {
1122
1810
  "blur": blur_frag_default,
1123
1811
  "blur-3d": blur_3d_frag_default,
1124
1812
  "holo": holo_frag_default,
1125
- "holo-3d": holo_3d_frag_default
1813
+ "holo-3d": holo_3d_frag_default,
1814
+ "pulse-lines": pulse_lines_frag_default,
1815
+ "gradient-flow": gradient_flow_frag_default,
1816
+ "procedural-ocean": procedural_ocean_frag_default,
1817
+ "rainbow-flow": rainbow_flow_frag_default,
1818
+ "shock-wave": shock_wave_frag_default,
1819
+ "ripple": ripple_frag_default,
1820
+ lenticular: lenticular_frag_default
1126
1821
  };
1127
1822
  var MAX_LAYERS = 8;
1128
1823
  var FaceRenderer = class {
1129
- constructor(shader, width, height) {
1824
+ constructor(shader, width, height, effectUniforms) {
1130
1825
  this.loadedLayers = [];
1131
1826
  bootstrapShaders();
1132
1827
  this.scene = new THREE3.Scene();
1133
1828
  this.camera = new THREE3.Camera();
1134
- const uniforms = this.createUniforms(width, height);
1829
+ const uniforms = this.createUniforms(width, height, effectUniforms);
1135
1830
  const rawFrag = shader ?? FRAG_SHADERS["glare"];
1136
1831
  const fragmentShader = resolveIncludes(rawFrag);
1137
1832
  this.material = new THREE3.ShaderMaterial({
@@ -1144,7 +1839,7 @@ var FaceRenderer = class {
1144
1839
  this.mesh = new THREE3.Mesh(geometry, this.material);
1145
1840
  this.scene.add(this.mesh);
1146
1841
  }
1147
- createUniforms(width, height) {
1842
+ createUniforms(width, height, effectUniforms) {
1148
1843
  const uniforms = {
1149
1844
  uTime: { value: 0 },
1150
1845
  uResolution: { value: new THREE3.Vector2(width, height) },
@@ -1158,8 +1853,24 @@ var FaceRenderer = class {
1158
1853
  for (let i = 0; i < MAX_LAYERS; i++) {
1159
1854
  uniforms[`uLayer${i}`] = { value: transparent };
1160
1855
  }
1856
+ if (effectUniforms) {
1857
+ for (const [name, value] of Object.entries(effectUniforms)) {
1858
+ uniforms[name] = { value: toThreeUniformValue(value) };
1859
+ }
1860
+ }
1161
1861
  return uniforms;
1162
1862
  }
1863
+ updateEffectUniforms(values) {
1864
+ if (!values) return;
1865
+ for (const [name, value] of Object.entries(values)) {
1866
+ const nextValue = toThreeUniformValue(value);
1867
+ if (this.material.uniforms[name]) {
1868
+ this.material.uniforms[name].value = nextValue;
1869
+ } else {
1870
+ this.material.uniforms[name] = { value: nextValue };
1871
+ }
1872
+ }
1873
+ }
1163
1874
  async loadLayers(layers, onError) {
1164
1875
  this.disposeLayers();
1165
1876
  const count = Math.min(layers.length, MAX_LAYERS);
@@ -1208,6 +1919,17 @@ var FaceRenderer = class {
1208
1919
  this.material.dispose();
1209
1920
  }
1210
1921
  };
1922
+ function toThreeUniformValue(value) {
1923
+ if (typeof value === "string") {
1924
+ return value.startsWith("#") ? new THREE3.Color(value) : value;
1925
+ }
1926
+ if (Array.isArray(value)) {
1927
+ if (value.length === 2) return new THREE3.Vector2(value[0], value[1]);
1928
+ if (value.length === 3) return new THREE3.Vector3(value[0], value[1], value[2]);
1929
+ return new THREE3.Vector4(value[0], value[1], value[2], value[3]);
1930
+ }
1931
+ return value;
1932
+ }
1211
1933
 
1212
1934
  // src/renderer/index.ts
1213
1935
  var Renderer = class {
@@ -1232,6 +1954,9 @@ var Renderer = class {
1232
1954
  this.injectStyles();
1233
1955
  this.cardEl = document.createElement("div");
1234
1956
  this.cardEl.className = "pocato-card pocato-loading";
1957
+ if (options.preventTouchScroll) {
1958
+ this.cardEl.style.touchAction = "none";
1959
+ }
1235
1960
  this.rotatorEl = document.createElement("div");
1236
1961
  this.rotatorEl.className = "pocato-rotator";
1237
1962
  this.backEl = document.createElement("div");
@@ -1244,9 +1969,21 @@ var Renderer = class {
1244
1969
  this.frontContentEl.className = "pocato-content pocato-front-content";
1245
1970
  this.backContentEl = document.createElement("div");
1246
1971
  this.backContentEl.className = "pocato-content pocato-back-content";
1972
+ this.frontFrameEl = document.createElement("div");
1973
+ this.frontFrameEl.className = "pocato-frame";
1974
+ this.backFrameEl = document.createElement("div");
1975
+ this.backFrameEl.className = "pocato-frame";
1976
+ this.frontFrameShadowEl = document.createElement("div");
1977
+ this.frontFrameShadowEl.className = "pocato-frame-shadow";
1978
+ this.backFrameShadowEl = document.createElement("div");
1979
+ this.backFrameShadowEl.className = "pocato-frame-shadow";
1247
1980
  this.frontEl.appendChild(this.frontCanvas);
1248
1981
  this.frontEl.appendChild(this.frontContentEl);
1982
+ this.frontEl.appendChild(this.frontFrameEl);
1983
+ this.frontEl.appendChild(this.frontFrameShadowEl);
1249
1984
  this.backEl.appendChild(this.backContentEl);
1985
+ this.backEl.appendChild(this.backFrameEl);
1986
+ this.backEl.appendChild(this.backFrameShadowEl);
1250
1987
  this.rotatorEl.appendChild(this.backEl);
1251
1988
  this.rotatorEl.appendChild(this.frontEl);
1252
1989
  this.cardEl.appendChild(this.rotatorEl);
@@ -1260,18 +1997,24 @@ var Renderer = class {
1260
1997
  this.frontFace = new FaceRenderer(
1261
1998
  options.front.shader,
1262
1999
  pixelWidth,
1263
- pixelHeight
2000
+ pixelHeight,
2001
+ options.front.uniforms
1264
2002
  );
1265
2003
  this.backFace = new FaceRenderer(
1266
2004
  this.options.back?.shader,
1267
2005
  pixelWidth,
1268
- pixelHeight
2006
+ pixelHeight,
2007
+ this.options.back?.uniforms
1269
2008
  );
1270
2009
  this.backCanvas = document.createElement("canvas");
1271
2010
  this.backCanvas.className = "pocato-canvas";
1272
2011
  this.backCanvas.width = pixelWidth;
1273
2012
  this.backCanvas.height = pixelHeight;
1274
2013
  this.backEl.insertBefore(this.backCanvas, this.backEl.firstChild);
2014
+ this.applyFrame(this.frontEl, this.frontFrameEl, this.frontFrameShadowEl, options.front.frame);
2015
+ this.applyFrame(this.backEl, this.backFrameEl, this.backFrameShadowEl, options.back?.frame);
2016
+ this.frontFrame = options.front.frame;
2017
+ this.backFrame = options.back?.frame;
1275
2018
  this.loadAllLayers();
1276
2019
  this.setupResizeObserver();
1277
2020
  this.setupIntersectionObserver();
@@ -1291,8 +2034,7 @@ var Renderer = class {
1291
2034
  alpha: true
1292
2035
  });
1293
2036
  this.frontRenderer.setPixelRatio(window.devicePixelRatio);
1294
- const { width, height } = this.container.getBoundingClientRect();
1295
- this.frontRenderer.setSize(width, height);
2037
+ this.resizeFaceRenderer(this.frontEl, this.frontCanvas, this.frontFace, this.frontRenderer, this.frontFrame);
1296
2038
  }
1297
2039
  createBackRenderer() {
1298
2040
  if (this.backRenderer || !this.backCanvas || !this.backFace) return;
@@ -1305,8 +2047,7 @@ var Renderer = class {
1305
2047
  alpha: true
1306
2048
  });
1307
2049
  this.backRenderer.setPixelRatio(window.devicePixelRatio);
1308
- const { width, height } = this.container.getBoundingClientRect();
1309
- this.backRenderer.setSize(width, height);
2050
+ this.resizeFaceRenderer(this.backEl, this.backCanvas, this.backFace, this.backRenderer, this.backFrame);
1310
2051
  }
1311
2052
  disposeFrontRenderer() {
1312
2053
  if (!this.frontRenderer) return;
@@ -1374,7 +2115,6 @@ var Renderer = class {
1374
2115
  width: 100%;
1375
2116
  height: 100%;
1376
2117
  perspective: 1000px;
1377
- touch-action: none;
1378
2118
  user-select: none;
1379
2119
  transform: translate3d(0,0,0);
1380
2120
  opacity: 0;
@@ -1422,24 +2162,83 @@ var Renderer = class {
1422
2162
  background-color: #1a1a2e;
1423
2163
  }
1424
2164
  .pocato-canvas {
1425
- width: 100%;
1426
- height: 100%;
2165
+ position: absolute;
2166
+ inset: var(--pocato-face-padding, 0px);
2167
+ width: calc(100% - var(--pocato-face-padding-total, 0px));
2168
+ height: calc(100% - var(--pocato-face-padding-total, 0px));
1427
2169
  display: block;
1428
2170
  }
1429
2171
  .pocato-content {
1430
2172
  position: absolute;
1431
- top: 0; left: 0;
1432
- width: 100%;
1433
- height: 100%;
2173
+ inset: var(--pocato-face-padding, 0px);
1434
2174
  pointer-events: none;
1435
2175
  z-index: 1;
1436
2176
  }
1437
2177
  .pocato-content > * {
1438
2178
  pointer-events: auto;
1439
2179
  }
2180
+ .pocato-frame {
2181
+ position: absolute;
2182
+ inset: var(--pocato-frame-inset, 0px);
2183
+ z-index: 2;
2184
+ pointer-events: none;
2185
+ opacity: var(--pocato-frame-opacity, 0);
2186
+ }
2187
+ .pocato-frame::before {
2188
+ content: '';
2189
+ position: absolute;
2190
+ inset: 0;
2191
+ border: var(--pocato-frame-width, 0px) solid transparent;
2192
+ background: var(--pocato-frame-background, transparent) border-box;
2193
+ background-size: 220% 220%;
2194
+ -webkit-mask:
2195
+ linear-gradient(#000 0 0) padding-box,
2196
+ linear-gradient(#000 0 0);
2197
+ -webkit-mask-composite: xor;
2198
+ mask:
2199
+ linear-gradient(#000 0 0) padding-box,
2200
+ linear-gradient(#000 0 0);
2201
+ mask-composite: exclude;
2202
+ }
2203
+ .pocato-frame-shadow {
2204
+ position: absolute;
2205
+ inset: var(--pocato-frame-shadow-inset, 0px);
2206
+ z-index: 3;
2207
+ pointer-events: none;
2208
+ opacity: var(--pocato-frame-shadow-opacity, 0);
2209
+ box-shadow: inset 0 0 var(--pocato-frame-shadow-blur, 0px) var(--pocato-frame-shadow-color, rgba(0,0,0,0.4));
2210
+ }
2211
+ .pocato-frame[data-animated="true"]::before {
2212
+ animation: pocato-frame-flow var(--pocato-frame-speed, 3s) linear infinite;
2213
+ }
2214
+ @keyframes pocato-frame-flow {
2215
+ 0% { background-position: 0% 50%; }
2216
+ 50% { background-position: 100% 50%; }
2217
+ 100% { background-position: 0% 50%; }
2218
+ }
1440
2219
  `;
1441
2220
  document.head.appendChild(style);
1442
2221
  }
2222
+ applyFrame(faceEl, frameEl, shadowEl, frame) {
2223
+ const enabled = frame?.enabled ?? false;
2224
+ const facePadding = enabled ? frame?.padding ?? 0 : 0;
2225
+ const frameInset = enabled ? frame?.inset ?? 0 : 0;
2226
+ const frameWidth = enabled ? frame?.width ?? 0 : 0;
2227
+ const shadowEnabled = enabled && (frame?.innerShadow ?? false);
2228
+ faceEl.style.setProperty("--pocato-face-padding", `${facePadding}px`);
2229
+ faceEl.style.setProperty("--pocato-face-padding-total", `${facePadding * 2}px`);
2230
+ faceEl.style.background = enabled ? getFrameBackground(frame) : "";
2231
+ frameEl.style.setProperty("--pocato-frame-opacity", enabled ? "1" : "0");
2232
+ frameEl.style.setProperty("--pocato-frame-inset", `${frameInset}px`);
2233
+ frameEl.style.setProperty("--pocato-frame-width", `${frameWidth}px`);
2234
+ frameEl.style.setProperty("--pocato-frame-speed", `${frame?.animationSpeed ?? 3}s`);
2235
+ frameEl.dataset.animated = enabled && frameWidth > 0 && frame?.animated ? "true" : "false";
2236
+ frameEl.style.setProperty("--pocato-frame-background", getFrameBorderBackground(frame));
2237
+ shadowEl.style.setProperty("--pocato-frame-shadow-inset", `${frameInset + frameWidth}px`);
2238
+ shadowEl.style.setProperty("--pocato-frame-shadow-blur", `${frame?.innerShadowBlur ?? 16}px`);
2239
+ shadowEl.style.setProperty("--pocato-frame-shadow-color", toRgba(frame?.innerShadowColor ?? "#000000", frame?.innerShadowOpacity ?? 0.28));
2240
+ shadowEl.style.setProperty("--pocato-frame-shadow-opacity", shadowEnabled ? "1" : "0");
2241
+ }
1443
2242
  setupResizeObserver() {
1444
2243
  this.resizeObserver = new ResizeObserver((entries) => {
1445
2244
  const entry = entries[0];
@@ -1447,14 +2246,16 @@ var Renderer = class {
1447
2246
  const { width, height } = entry.contentRect;
1448
2247
  if (width === 0 || height === 0) return;
1449
2248
  if (this.frontRenderer) {
1450
- this.frontRenderer.setSize(width, height);
2249
+ this.resizeFaceRenderer(this.frontEl, this.frontCanvas, this.frontFace, this.frontRenderer, this.frontFrame);
2250
+ } else {
2251
+ this.resizeFaceRenderer(this.frontEl, this.frontCanvas, this.frontFace, null, this.frontFrame);
1451
2252
  }
1452
- this.frontFace.updateResolution(this.frontCanvas.width, this.frontCanvas.height);
1453
2253
  if (this.backFace && this.backCanvas) {
1454
2254
  if (this.backRenderer) {
1455
- this.backRenderer.setSize(width, height);
2255
+ this.resizeFaceRenderer(this.backEl, this.backCanvas, this.backFace, this.backRenderer, this.backFrame);
2256
+ } else {
2257
+ this.resizeFaceRenderer(this.backEl, this.backCanvas, this.backFace, null, this.backFrame);
1456
2258
  }
1457
- this.backFace.updateResolution(this.backCanvas.width, this.backCanvas.height);
1458
2259
  }
1459
2260
  });
1460
2261
  this.resizeObserver.observe(this.container);
@@ -1508,6 +2309,38 @@ var Renderer = class {
1508
2309
  updateBackShader(fragmentShader) {
1509
2310
  this.backFace?.updateShader(fragmentShader);
1510
2311
  }
2312
+ updateEffectUniforms(frontUniforms, backUniforms) {
2313
+ this.frontFace.updateEffectUniforms(frontUniforms);
2314
+ this.backFace?.updateEffectUniforms(backUniforms);
2315
+ }
2316
+ updateFrames(frontFrame, backFrame) {
2317
+ if (frontFrame) {
2318
+ this.frontFrame = frontFrame;
2319
+ this.applyFrame(this.frontEl, this.frontFrameEl, this.frontFrameShadowEl, frontFrame);
2320
+ this.resizeFaceRenderer(this.frontEl, this.frontCanvas, this.frontFace, this.frontRenderer, this.frontFrame);
2321
+ }
2322
+ if (backFrame) {
2323
+ this.backFrame = backFrame;
2324
+ this.applyFrame(this.backEl, this.backFrameEl, this.backFrameShadowEl, backFrame);
2325
+ if (this.backFace && this.backCanvas) {
2326
+ this.resizeFaceRenderer(this.backEl, this.backCanvas, this.backFace, this.backRenderer, this.backFrame);
2327
+ }
2328
+ }
2329
+ }
2330
+ resizeFaceRenderer(faceEl, canvas, face, renderer, frame) {
2331
+ const { width, height } = faceEl.getBoundingClientRect();
2332
+ const padding = frame?.enabled ? frame.padding ?? 0 : 0;
2333
+ const nextWidth = Math.max(1, width - padding * 2);
2334
+ const nextHeight = Math.max(1, height - padding * 2);
2335
+ if (renderer) {
2336
+ renderer.setSize(nextWidth, nextHeight);
2337
+ } else {
2338
+ const dpr = window.devicePixelRatio || 1;
2339
+ canvas.width = Math.floor(nextWidth * dpr);
2340
+ canvas.height = Math.floor(nextHeight * dpr);
2341
+ }
2342
+ face.updateResolution(canvas.width, canvas.height);
2343
+ }
1511
2344
  async updateLayers(frontLayers, backLayers) {
1512
2345
  const promises = [];
1513
2346
  if (frontLayers) {
@@ -1544,6 +2377,30 @@ var Renderer = class {
1544
2377
  }
1545
2378
  }
1546
2379
  };
2380
+ function getFrameBackground(frame) {
2381
+ const color = frame?.backgroundColor ?? "#111827";
2382
+ const gradientFrom = frame?.backgroundGradientFrom ?? color;
2383
+ const gradientTo = frame?.backgroundGradientTo ?? color;
2384
+ return frame?.backgroundGradient ? `linear-gradient(135deg, ${gradientFrom}, ${gradientTo})` : color;
2385
+ }
2386
+ function getFrameBorderBackground(frame) {
2387
+ const color = frame?.color ?? "#ffffff";
2388
+ const gradientFrom = frame?.gradientFrom ?? color;
2389
+ const gradientTo = frame?.gradientTo ?? color;
2390
+ const opacity = frame?.borderOpacity ?? 1;
2391
+ return frame?.gradient ? `linear-gradient(120deg, ${toRgba(gradientFrom, opacity)}, ${toRgba(gradientTo, opacity)}, ${toRgba(gradientFrom, opacity)})` : toRgba(color, opacity);
2392
+ }
2393
+ function toRgba(hex, opacity) {
2394
+ const value = hex.replace("#", "");
2395
+ if (value.length !== 6) return `rgba(0, 0, 0, ${opacity})`;
2396
+ const red = Number.parseInt(value.slice(0, 2), 16);
2397
+ const green = Number.parseInt(value.slice(2, 4), 16);
2398
+ const blue = Number.parseInt(value.slice(4, 6), 16);
2399
+ if ([red, green, blue].some((channel) => Number.isNaN(channel))) {
2400
+ return `rgba(0, 0, 0, ${opacity})`;
2401
+ }
2402
+ return `rgba(${red}, ${green}, ${blue}, ${opacity})`;
2403
+ }
1547
2404
 
1548
2405
  // src/animation/spring.ts
1549
2406
  var tasks = /* @__PURE__ */ new Set();
@@ -1765,10 +2622,11 @@ var SPRING_FLIP = { stiffness: 0.03, damping: 0.25 };
1765
2622
  var THROTTLE_MS = 1e3 / 60;
1766
2623
  var DBLCLICK_MS = 200;
1767
2624
  var InteractionHandler = class {
1768
- constructor(container, callbacks, flippable, initialFlipped) {
2625
+ constructor(container, callbacks, flippable, initialFlipped, options = {}) {
1769
2626
  this.container = container;
1770
2627
  this.callbacks = callbacks;
1771
2628
  this.flippable = flippable;
2629
+ this.options = options;
1772
2630
  this.flipped = false;
1773
2631
  this.interacting = false;
1774
2632
  this.boundingRect = { left: 0, top: 0, width: 0, height: 0 };
@@ -1792,15 +2650,20 @@ var InteractionHandler = class {
1792
2650
  this.boundPointerUp = this.onPointerUp.bind(this);
1793
2651
  this.boundClick = this.onClick.bind(this);
1794
2652
  this.boundTouchHandler = (e) => {
2653
+ e.preventDefault();
1795
2654
  e.stopPropagation();
1796
2655
  };
1797
- this.container.addEventListener("pointerdown", this.boundPointerDown);
1798
- this.container.addEventListener("pointermove", this.boundPointerMove);
1799
- this.container.addEventListener("pointerup", this.boundPointerUp);
1800
- this.container.addEventListener("pointercancel", this.boundPointerUp);
1801
- this.container.addEventListener("click", this.boundClick);
1802
- this.container.addEventListener("touchstart", this.boundTouchHandler, { passive: true });
1803
- this.container.addEventListener("touchmove", this.boundTouchHandler, { passive: true });
2656
+ if (this.options.interactive ?? true) {
2657
+ this.container.addEventListener("pointerdown", this.boundPointerDown);
2658
+ this.container.addEventListener("pointermove", this.boundPointerMove);
2659
+ this.container.addEventListener("pointerup", this.boundPointerUp);
2660
+ this.container.addEventListener("pointercancel", this.boundPointerUp);
2661
+ this.container.addEventListener("click", this.boundClick);
2662
+ }
2663
+ if (this.options.preventTouchScroll) {
2664
+ this.container.addEventListener("touchstart", this.boundTouchHandler, { passive: false });
2665
+ this.container.addEventListener("touchmove", this.boundTouchHandler, { passive: false });
2666
+ }
1804
2667
  }
1805
2668
  updateRect(rect) {
1806
2669
  this.boundingRect = rect;
@@ -2089,7 +2952,8 @@ var PocaCard = class extends EventEmitter {
2089
2952
  container,
2090
2953
  {
2091
2954
  front: options.front,
2092
- back: options.back
2955
+ back: options.back,
2956
+ preventTouchScroll: options.preventTouchScroll
2093
2957
  },
2094
2958
  (error) => this.emit("error", error),
2095
2959
  () => this.emit("ready")
@@ -2109,14 +2973,20 @@ var PocaCard = class extends EventEmitter {
2109
2973
  }
2110
2974
  },
2111
2975
  options.flippable ?? false,
2112
- options.initialFlipped ?? false
2113
- );
2114
- this.renderer.getRotatorEl().addEventListener("pointerdown", () => {
2115
- if (this.wiggleController) {
2116
- this.wiggleController.stop();
2117
- this.wiggleController = null;
2976
+ options.initialFlipped ?? false,
2977
+ {
2978
+ interactive: options.interactive,
2979
+ preventTouchScroll: options.preventTouchScroll
2118
2980
  }
2119
- });
2981
+ );
2982
+ if (options.interactive ?? true) {
2983
+ this.renderer.getRotatorEl().addEventListener("pointerdown", () => {
2984
+ if (this.wiggleController) {
2985
+ this.wiggleController.stop();
2986
+ this.wiggleController = null;
2987
+ }
2988
+ });
2989
+ }
2120
2990
  if (options.flipSpeed != null) {
2121
2991
  this.interaction.flipSpeed = options.flipSpeed;
2122
2992
  }
@@ -2161,6 +3031,12 @@ var PocaCard = class extends EventEmitter {
2161
3031
  if (options.front?.layers || options.back?.layers) {
2162
3032
  this.renderer.updateLayers(options.front?.layers, options.back?.layers);
2163
3033
  }
3034
+ if (options.front?.uniforms || options.back?.uniforms) {
3035
+ this.renderer.updateEffectUniforms(options.front?.uniforms, options.back?.uniforms);
3036
+ }
3037
+ if (options.front?.frame || options.back?.frame) {
3038
+ this.renderer.updateFrames(options.front?.frame, options.back?.frame);
3039
+ }
2164
3040
  }
2165
3041
  destroy() {
2166
3042
  this.wiggleController?.stop();
@@ -2181,7 +3057,14 @@ var builtinShaders = {
2181
3057
  blur: blur_frag_default,
2182
3058
  "blur-3d": blur_3d_frag_default,
2183
3059
  brush: brush_frag_default,
2184
- "brush-3d": brush_3d_frag_default
3060
+ "brush-3d": brush_3d_frag_default,
3061
+ "pulse-lines": pulse_lines_frag_default,
3062
+ "gradient-flow": gradient_flow_frag_default,
3063
+ "procedural-ocean": procedural_ocean_frag_default,
3064
+ "rainbow-flow": rainbow_flow_frag_default,
3065
+ "shock-wave": shock_wave_frag_default,
3066
+ "ripple": ripple_frag_default,
3067
+ lenticular: lenticular_frag_default
2185
3068
  };
2186
3069
  export {
2187
3070
  FRAG_SHADERS,