@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.d.ts +31 -2
- package/dist/index.js +940 -57
- package/dist/index.js.map +1 -1
- package/package.json +5 -3
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
|
|
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(
|
|
709
|
-
offsetUv += vec2(offsetUv.y * windEffect, speedFactor *
|
|
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
|
|
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(
|
|
827
|
-
offsetUv += vec2(offsetUv.y * windEffect, speedFactor *
|
|
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
|
|
886
|
-
vec4
|
|
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
|
|
926
|
-
vec4
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1426
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
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
|
-
|
|
2115
|
-
|
|
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,
|