react-native-shine 0.2.2 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. package/README.md +22 -7
  2. package/lib/module/components/Content.js +232 -0
  3. package/lib/module/components/Content.js.map +1 -0
  4. package/lib/module/components/Shine.js +33 -0
  5. package/lib/module/components/Shine.js.map +1 -0
  6. package/lib/module/components/ShineGroup.js +92 -0
  7. package/lib/module/components/ShineGroup.js.map +1 -0
  8. package/lib/module/enums/waveCallback.js +19 -0
  9. package/lib/module/enums/waveCallback.js.map +1 -0
  10. package/lib/module/hooks/useAnimationFrame.js +17 -0
  11. package/lib/module/hooks/useAnimationFrame.js.map +1 -0
  12. package/lib/module/hooks/useOrientation.js +10 -0
  13. package/lib/module/hooks/useOrientation.js.map +1 -0
  14. package/lib/module/index.js +6 -219
  15. package/lib/module/index.js.map +1 -1
  16. package/lib/module/shaders/bindGroupLayouts.js +41 -6
  17. package/lib/module/shaders/bindGroupLayouts.js.map +1 -1
  18. package/lib/module/shaders/bindGroupUtils.js +34 -41
  19. package/lib/module/shaders/bindGroupUtils.js.map +1 -1
  20. package/lib/module/shaders/fragmentShaders/colorMaskFragment.js +2 -2
  21. package/lib/module/shaders/fragmentShaders/colorMaskFragment.js.map +1 -1
  22. package/lib/module/shaders/fragmentShaders/glareFragment.js +115 -0
  23. package/lib/module/shaders/fragmentShaders/glareFragment.js.map +1 -0
  24. package/lib/module/shaders/fragmentShaders/holoFragment.js +28 -0
  25. package/lib/module/shaders/fragmentShaders/holoFragment.js.map +1 -0
  26. package/lib/module/shaders/fragmentShaders/maskFragment.js +20 -0
  27. package/lib/module/shaders/fragmentShaders/maskFragment.js.map +1 -0
  28. package/lib/module/shaders/fragmentShaders/reverseHoloFragment.js +46 -0
  29. package/lib/module/shaders/fragmentShaders/reverseHoloFragment.js.map +1 -0
  30. package/lib/module/shaders/pipelineSetups.js +72 -17
  31. package/lib/module/shaders/pipelineSetups.js.map +1 -1
  32. package/lib/module/shaders/{resourceManagement.js → resourceManagement/bitmaps.js} +2 -1
  33. package/lib/module/shaders/resourceManagement/bitmaps.js.map +1 -0
  34. package/lib/module/shaders/resourceManagement/bufferManager.js +46 -0
  35. package/lib/module/shaders/resourceManagement/bufferManager.js.map +1 -0
  36. package/lib/module/shaders/resourceManagement/textures.js +24 -0
  37. package/lib/module/shaders/resourceManagement/textures.js.map +1 -0
  38. package/lib/module/shaders/tgpuUtils.js +19 -1
  39. package/lib/module/shaders/tgpuUtils.js.map +1 -1
  40. package/lib/module/shaders/utils.js +8 -36
  41. package/lib/module/shaders/utils.js.map +1 -1
  42. package/lib/module/shaders/vertexShaders/mainRotationEffectVertex.js +47 -0
  43. package/lib/module/shaders/vertexShaders/mainRotationEffectVertex.js.map +1 -0
  44. package/lib/module/types/size.js +2 -0
  45. package/lib/module/types/size.js.map +1 -0
  46. package/lib/module/types/typeUtils.js +17 -19
  47. package/lib/module/types/typeUtils.js.map +1 -1
  48. package/lib/module/types/vector.js +2 -0
  49. package/lib/module/types/vector.js.map +1 -0
  50. package/lib/module/utils/size.js +25 -0
  51. package/lib/module/utils/size.js.map +1 -0
  52. package/lib/module/utils/vector.js +168 -0
  53. package/lib/module/utils/vector.js.map +1 -0
  54. package/lib/typescript/src/components/Content.d.ts +23 -0
  55. package/lib/typescript/src/components/Content.d.ts.map +1 -0
  56. package/lib/typescript/src/components/Shine.d.ts +7 -0
  57. package/lib/typescript/src/components/Shine.d.ts.map +1 -0
  58. package/lib/typescript/src/components/ShineGroup.d.ts +6 -0
  59. package/lib/typescript/src/components/ShineGroup.d.ts.map +1 -0
  60. package/lib/typescript/src/enums/waveCallback.d.ts +9 -0
  61. package/lib/typescript/src/enums/waveCallback.d.ts.map +1 -0
  62. package/lib/typescript/src/hooks/useAnimationFrame.d.ts +2 -0
  63. package/lib/typescript/src/hooks/useAnimationFrame.d.ts.map +1 -0
  64. package/lib/typescript/src/hooks/useOrientation.d.ts +4 -0
  65. package/lib/typescript/src/hooks/useOrientation.d.ts.map +1 -0
  66. package/lib/typescript/src/index.d.ts +8 -11
  67. package/lib/typescript/src/index.d.ts.map +1 -1
  68. package/lib/typescript/src/shaders/bindGroupLayouts.d.ts +46 -8
  69. package/lib/typescript/src/shaders/bindGroupLayouts.d.ts.map +1 -1
  70. package/lib/typescript/src/shaders/bindGroupUtils.d.ts +9 -9
  71. package/lib/typescript/src/shaders/bindGroupUtils.d.ts.map +1 -1
  72. package/lib/typescript/src/shaders/fragmentShaders/glareFragment.d.ts +8 -0
  73. package/lib/typescript/src/shaders/fragmentShaders/glareFragment.d.ts.map +1 -0
  74. package/lib/typescript/src/shaders/fragmentShaders/holoFragment.d.ts +5 -0
  75. package/lib/typescript/src/shaders/fragmentShaders/holoFragment.d.ts.map +1 -0
  76. package/lib/typescript/src/shaders/fragmentShaders/maskFragment.d.ts +6 -0
  77. package/lib/typescript/src/shaders/fragmentShaders/maskFragment.d.ts.map +1 -0
  78. package/lib/typescript/src/shaders/fragmentShaders/reverseHoloFragment.d.ts +5 -0
  79. package/lib/typescript/src/shaders/fragmentShaders/reverseHoloFragment.d.ts.map +1 -0
  80. package/lib/typescript/src/shaders/pipelineSetups.d.ts +9 -4
  81. package/lib/typescript/src/shaders/pipelineSetups.d.ts.map +1 -1
  82. package/lib/typescript/src/shaders/{resourceManagement.d.ts → resourceManagement/bitmaps.d.ts} +1 -1
  83. package/lib/typescript/src/shaders/resourceManagement/bitmaps.d.ts.map +1 -0
  84. package/lib/typescript/src/shaders/resourceManagement/bufferManager.d.ts +28 -0
  85. package/lib/typescript/src/shaders/resourceManagement/bufferManager.d.ts.map +1 -0
  86. package/lib/typescript/src/shaders/resourceManagement/textures.d.ts +8 -0
  87. package/lib/typescript/src/shaders/resourceManagement/textures.d.ts.map +1 -0
  88. package/lib/typescript/src/shaders/tgpuUtils.d.ts +5 -1
  89. package/lib/typescript/src/shaders/tgpuUtils.d.ts.map +1 -1
  90. package/lib/typescript/src/shaders/utils.d.ts +3 -10
  91. package/lib/typescript/src/shaders/utils.d.ts.map +1 -1
  92. package/lib/typescript/src/shaders/vertexShaders/mainRotationEffectVertex.d.ts +6 -0
  93. package/lib/typescript/src/shaders/vertexShaders/mainRotationEffectVertex.d.ts.map +1 -0
  94. package/lib/typescript/src/types/size.d.ts +5 -0
  95. package/lib/typescript/src/types/size.d.ts.map +1 -0
  96. package/lib/typescript/src/types/typeUtils.d.ts +3 -5
  97. package/lib/typescript/src/types/typeUtils.d.ts.map +1 -1
  98. package/lib/typescript/src/types/types.d.ts +10 -3
  99. package/lib/typescript/src/types/types.d.ts.map +1 -1
  100. package/lib/typescript/src/types/vector.d.ts +11 -0
  101. package/lib/typescript/src/types/vector.d.ts.map +1 -0
  102. package/lib/typescript/src/utils/size.d.ts +5 -0
  103. package/lib/typescript/src/utils/size.d.ts.map +1 -0
  104. package/lib/typescript/src/utils/vector.d.ts +33 -0
  105. package/lib/typescript/src/utils/vector.d.ts.map +1 -0
  106. package/package.json +7 -5
  107. package/scripts/postinstall.js +16 -17
  108. package/src/components/Content.tsx +403 -0
  109. package/src/components/Shine.tsx +38 -0
  110. package/src/components/ShineGroup.tsx +100 -0
  111. package/src/enums/waveCallback.ts +22 -0
  112. package/src/hooks/useAnimationFrame.ts +21 -0
  113. package/src/hooks/useOrientation.ts +18 -0
  114. package/src/index.tsx +14 -322
  115. package/src/shaders/bindGroupLayouts.ts +45 -8
  116. package/src/shaders/bindGroupUtils.ts +50 -65
  117. package/src/shaders/fragmentShaders/colorMaskFragment.ts +2 -2
  118. package/src/shaders/fragmentShaders/glareFragment.ts +143 -0
  119. package/src/shaders/fragmentShaders/holoFragment.ts +35 -0
  120. package/src/shaders/fragmentShaders/maskFragment.ts +31 -0
  121. package/src/shaders/fragmentShaders/reverseHoloFragment.ts +71 -0
  122. package/src/shaders/pipelineSetups.ts +152 -20
  123. package/src/shaders/{resourceManagement.ts → resourceManagement/bitmaps.ts} +1 -0
  124. package/src/shaders/resourceManagement/bufferManager.ts +82 -0
  125. package/src/shaders/resourceManagement/textures.ts +42 -0
  126. package/src/shaders/tgpuUtils.ts +36 -1
  127. package/src/shaders/utils.ts +13 -57
  128. package/src/shaders/vertexShaders/mainRotationEffectVertex.ts +76 -0
  129. package/src/types/size.ts +4 -0
  130. package/src/types/typeUtils.ts +22 -36
  131. package/src/types/types.ts +19 -3
  132. package/src/types/vector.ts +13 -0
  133. package/src/utils/size.ts +12 -0
  134. package/src/utils/vector.ts +132 -0
  135. package/lib/module/shaders/fragmentShaders/bloomFragment.js +0 -66
  136. package/lib/module/shaders/fragmentShaders/bloomFragment.js.map +0 -1
  137. package/lib/module/shaders/resourceManagement.js.map +0 -1
  138. package/lib/typescript/src/shaders/fragmentShaders/bloomFragment.d.ts +0 -6
  139. package/lib/typescript/src/shaders/fragmentShaders/bloomFragment.d.ts.map +0 -1
  140. package/lib/typescript/src/shaders/resourceManagement.d.ts.map +0 -1
  141. package/src/shaders/fragmentShaders/bloomFragment.ts +0 -83
@@ -0,0 +1,143 @@
1
+ import tgpu from 'typegpu';
2
+ import * as d from 'typegpu/data';
3
+ import * as std from 'typegpu/std';
4
+ import {
5
+ rotationBindGroupLayout,
6
+ textureBindGroupLayout,
7
+ glareBindGroupLayout,
8
+ // colorMaskBindGroupLayout,
9
+ } from '../bindGroupLayouts';
10
+ import { glareColorShift, hueShift, overlayChannels } from '../tgpuUtils';
11
+
12
+ export const glareFragment = tgpu['~unstable'].fragmentFn({
13
+ in: { uv: d.vec2f },
14
+ out: d.vec4f,
15
+ })((input) => {
16
+ const texcoord = d.vec2f(input.uv.x, 1.0 - input.uv.y);
17
+ const uv = d.vec2f(input.uv.x, 1.0 - input.uv.y);
18
+ const centeredCoords = std.sub(std.mul(uv, 2.0), 1); //-1 to 1
19
+
20
+ const rot = rotationBindGroupLayout.$.vec;
21
+ const center = std.add(d.vec2f(0.0), d.vec2f(rot.x, rot.y));
22
+
23
+ const glareOptions = glareBindGroupLayout.$.glareOptions;
24
+ const glareIntensity = glareOptions.glareIntensity;
25
+ const glowPower = glareOptions.glowPower;
26
+ const hueBlendPower = glareOptions.hueBlendPower;
27
+ const hueShiftAngleMax = glareOptions.hueShiftAngleMax;
28
+ const hueShiftAngleMin = glareOptions.hueShiftAngleMin;
29
+ const lightIntensity = glareOptions.lightIntensity;
30
+
31
+ // const mask = colorMaskBindGroupLayout.$.mask;
32
+ // const maskedColor = mask.baseColor;
33
+ // const rgbToleranceRange = mask.rgbToleranceRange;
34
+
35
+ let color = std.textureSample(
36
+ textureBindGroupLayout.$.texture,
37
+ textureBindGroupLayout.$.sampler,
38
+ texcoord
39
+ );
40
+
41
+ // const maskedColorLower = std.sub(maskedColor, rgbToleranceRange.lower);
42
+ // const maskedColorUpper = std.add(maskedColor, rgbToleranceRange.upper);
43
+ // const upperCheck = std.all(std.le(color.xyz, maskedColorUpper));
44
+ // const lowerCheck = std.all(std.ge(color.xyz, maskedColorLower));
45
+ // if (upperCheck && lowerCheck) {
46
+ // return color;
47
+ // }
48
+
49
+ //glareIntensity
50
+ const dst = std.exp(-std.distance(center, centeredCoords));
51
+ const distToCenter = std.smoothstep(0.0, 1 / glareIntensity, dst);
52
+
53
+ //glowPower
54
+ let glow = d.vec3f(distToCenter);
55
+ glow = std.mul(glow, glowPower * color.w);
56
+
57
+ //hueBlend
58
+ const hueBlend = (d.f32(hueBlendPower) * dst) / 10.0;
59
+
60
+ //lightIntensity
61
+ glow = std.add(glow, lightIntensity / 10.0);
62
+ let shiftedRGB = glareColorShift(color.xyz, dst / (lightIntensity * 2));
63
+
64
+ //hueShiftAngleMin/Max
65
+ const hueShiftAngle = std.smoothstep(
66
+ hueShiftAngleMin,
67
+ hueShiftAngleMax,
68
+ distToCenter
69
+ );
70
+ const shiftedHue = hueShift(shiftedRGB, hueShiftAngle);
71
+ shiftedRGB = overlayChannels(shiftedRGB, shiftedHue);
72
+
73
+ color = d.vec4f(std.mix(color.xyz, shiftedRGB, hueBlend), color.w);
74
+ const baseColor = color;
75
+ const blendColor = glow;
76
+
77
+ const combined = overlayChannels(baseColor.xyz, blendColor);
78
+ color = d.vec4f(std.mix(color.xyz, combined, glow), color.w);
79
+
80
+ return color;
81
+ });
82
+
83
+ export const newGlareFragment = tgpu['~unstable'].fragmentFn({
84
+ in: { uv: d.vec2f },
85
+ out: d.vec4f,
86
+ })((input) => {
87
+ const texcoord = d.vec2f(input.uv.x, 1.0 - input.uv.y);
88
+ const uv = d.vec2f(input.uv.x, 1.0 - input.uv.y);
89
+ const centeredCoords = std.sub(std.mul(uv, 2.0), 1.0);
90
+
91
+ const rot = rotationBindGroupLayout.$.vec;
92
+ const center = std.add(d.vec2f(0.0), d.vec2f(rot.x, rot.y)); // do not change
93
+
94
+ const opts = glareBindGroupLayout.$.glareOptions;
95
+ const glareIntensity = opts.glareIntensity; // [0..∞): bigger → wider/stronger area
96
+ const glowPower = opts.glowPower; // (0..∞): curve shaping; bigger → softer/wider glow
97
+ const hueBlendPower = opts.hueBlendPower; // [0..1+]: how much hue-shifted color blends in
98
+ const hueShiftAngleMin = opts.hueShiftAngleMin; // radians
99
+ const hueShiftAngleMax = opts.hueShiftAngleMax; // radians
100
+ const lightIntensity = opts.lightIntensity / 1.3; // [0..∞): brightness boost of the glare/bloom
101
+
102
+ let color = std.textureSample(
103
+ textureBindGroupLayout.$.texture,
104
+ textureBindGroupLayout.$.sampler,
105
+ texcoord
106
+ );
107
+
108
+ const dist = std.distance(center, centeredCoords);
109
+ const radial = std.exp(-dist); // (0,1], steeper near center
110
+ const radialScaled = std.mul(
111
+ radial,
112
+ std.add(1.0, std.max(0.0, glareIntensity))
113
+ );
114
+ const influenceRaw = std.smoothstep(0.0, 1.0, radialScaled); // 0..1
115
+ const curveExp = std.clamp(glowPower, 0.05, 64.0);
116
+ const glowMask = std.pow(influenceRaw, std.div(1.0, curveExp)); // 0..1
117
+
118
+ const maskedGlow = std.mul(glowMask, color.w); // 0..1
119
+ const boostedRGB = glareColorShift(color.xyz, maskedGlow);
120
+
121
+ const hueT = std.clamp(maskedGlow, 0.0, 1.0);
122
+ const hueAngle = std.mix(hueShiftAngleMin, hueShiftAngleMax, hueT);
123
+ const hueShifted = hueShift(boostedRGB, hueAngle);
124
+
125
+ const hueMixWeight = std.clamp(
126
+ std.mul(hueBlendPower / 5.0, maskedGlow),
127
+ 0.0,
128
+ 1.0
129
+ );
130
+ const chromaMixed = std.mix(color.xyz, hueShifted, hueMixWeight);
131
+
132
+ const glareStrength = std.clamp(lightIntensity, 0.0, 100.0);
133
+ const glareLayer = std.mul(d.vec3f(maskedGlow), glareStrength);
134
+
135
+ const overlaidRGB = overlayChannels(chromaMixed, glareLayer);
136
+ const finalRGB = std.mix(chromaMixed, overlaidRGB, d.vec3f(maskedGlow));
137
+
138
+ const outRGB = std.clamp(finalRGB, d.vec3f(0.0), d.vec3f(1.0));
139
+
140
+ // if (maskedGlow > 0.6) return d.vec4f(0.0, 0.0, 0.0, 0.0);
141
+
142
+ return d.vec4f(outRGB, color.w);
143
+ });
@@ -0,0 +1,35 @@
1
+ import tgpu from 'typegpu';
2
+ import * as d from 'typegpu/data';
3
+ import * as std from 'typegpu/std';
4
+ import {
5
+ rotationBindGroupLayout,
6
+ textureBindGroupLayout,
7
+ } from '../bindGroupLayouts';
8
+ import { hueShift } from '../tgpuUtils';
9
+ import { waveCallbackSlot } from '../../enums/waveCallback';
10
+
11
+ export const holoFragment = tgpu['~unstable'].fragmentFn({
12
+ in: { uv: d.vec2f },
13
+ out: d.vec4f,
14
+ })((input) => {
15
+ const texcoord = d.vec2f(input.uv.x, 1.0 - input.uv.y);
16
+ const uv = texcoord;
17
+ const textureColor = std.textureSample(
18
+ textureBindGroupLayout.$.texture,
19
+ textureBindGroupLayout.$.sampler,
20
+ texcoord
21
+ );
22
+ const rot = rotationBindGroupLayout.$.vec;
23
+
24
+ const wave = waveCallbackSlot.$(rot.xy);
25
+ const waveX = wave.x;
26
+ const waveY = wave.y;
27
+
28
+ const band = std.add(0.2 * waveX * uv.x, 2 * waveY * uv.y);
29
+
30
+ const hueAngle = std.mul(std.abs(band), (10 * Math.PI * rot.x) / 3);
31
+ const rainbowColor = hueShift(d.vec3f(1.0, 1.0, 1.0), hueAngle);
32
+ const finalColor = std.mul(rainbowColor, 1.0);
33
+
34
+ return d.vec4f(finalColor, 0.7 * textureColor.w);
35
+ });
@@ -0,0 +1,31 @@
1
+ import tgpu from 'typegpu';
2
+ import * as d from 'typegpu/data';
3
+ import * as std from 'typegpu/std';
4
+ import {
5
+ textureBindGroupLayout,
6
+ maskTextureBindGroupLayout,
7
+ } from '../bindGroupLayouts';
8
+
9
+ const maskFragment = tgpu['~unstable'].fragmentFn({
10
+ in: { uv: d.vec2f },
11
+ out: d.vec4f,
12
+ })((input) => {
13
+ const texcoord = d.vec2f(input.uv.x, 1.0 - input.uv.y);
14
+
15
+ const mask = std.textureSample(
16
+ maskTextureBindGroupLayout.$.texture,
17
+ maskTextureBindGroupLayout.$.sampler,
18
+ texcoord
19
+ );
20
+ const reversedMask = d.vec4f(std.sub(1.0, mask.xyz), mask.w);
21
+
22
+ let color = std.textureSample(
23
+ textureBindGroupLayout.$.texture,
24
+ textureBindGroupLayout.$.sampler,
25
+ texcoord
26
+ );
27
+
28
+ return d.vec4f(color.xyz, reversedMask.x);
29
+ });
30
+
31
+ export default maskFragment;
@@ -0,0 +1,71 @@
1
+ import tgpu from 'typegpu';
2
+ import * as d from 'typegpu/data';
3
+ import * as std from 'typegpu/std';
4
+ import {
5
+ textureBindGroupLayout,
6
+ maskTextureBindGroupLayout,
7
+ rotationBindGroupLayout,
8
+ glareBindGroupLayout,
9
+ } from '../bindGroupLayouts';
10
+ import { hueShift } from '../tgpuUtils';
11
+
12
+ export const reverseHoloFragment = tgpu['~unstable'].fragmentFn({
13
+ in: { uv: d.vec2f },
14
+ out: d.vec4f,
15
+ })((input) => {
16
+ const texcoord = d.vec2f(input.uv.x, 1.0 - input.uv.y);
17
+ const uv = texcoord;
18
+ const centeredCoords = std.sub(std.mul(uv, 2.0), 1.0);
19
+
20
+ const rot = rotationBindGroupLayout.$.vec;
21
+ const center = std.add(d.vec2f(0.0), d.vec2f(rot.x, rot.y)); // center from device orientation/touch
22
+
23
+ const opts = glareBindGroupLayout.$.glareOptions;
24
+ const glareIntensity = opts.glareIntensity;
25
+ const glowPower = opts.glowPower;
26
+ const hueBlendPower = opts.hueBlendPower;
27
+ const hueShiftAngleMin = opts.hueShiftAngleMin;
28
+ const hueShiftAngleMax = opts.hueShiftAngleMax;
29
+ const lightIntensity = opts.lightIntensity;
30
+
31
+ const cardColor = std.textureSample(
32
+ textureBindGroupLayout.$.texture,
33
+ textureBindGroupLayout.$.sampler,
34
+ texcoord
35
+ );
36
+
37
+ const holoMaskColor = std.textureSample(
38
+ maskTextureBindGroupLayout.$.texture,
39
+ maskTextureBindGroupLayout.$.sampler,
40
+ texcoord
41
+ );
42
+
43
+ const dist = std.distance(centeredCoords, center);
44
+ const rFalloff = std.exp(-dist);
45
+ const scaledRadial = std.mul(
46
+ rFalloff,
47
+ std.add(1.0, std.max(0.0, glareIntensity))
48
+ );
49
+ const influence = std.smoothstep(0.0, 1.0, scaledRadial);
50
+ const curvePower = std.clamp(glowPower, 0.05, 64.0);
51
+ const glowMask = std.pow(influence, std.div(1.0, curvePower));
52
+
53
+ const holoFactor =
54
+ (1.0 - holoMaskColor.x) * holoMaskColor.w * std.pow(scaledRadial, 1.5);
55
+
56
+ const maskedGlow = std.mul(glowMask, holoFactor); // only affect masked areas
57
+
58
+ const hueAmount = std.mix(
59
+ hueShiftAngleMin,
60
+ hueShiftAngleMax,
61
+ std.clamp(maskedGlow, 0.0, 1.0)
62
+ );
63
+ const sparkleHue = hueShift(cardColor.xyz, hueAmount);
64
+ const hueMixAmt = std.clamp((hueBlendPower / 5.0) * maskedGlow, 0.0, 1.0);
65
+ const chromaMix = std.mix(cardColor.xyz, sparkleHue, hueMixAmt);
66
+
67
+ const shineStrength = std.clamp(lightIntensity, 1.0, 100.0);
68
+ const shineLayer = std.mul(chromaMix, 1.5 * shineStrength * maskedGlow);
69
+
70
+ return d.vec4f(shineLayer, 1 - maskedGlow);
71
+ });
@@ -1,34 +1,53 @@
1
- import type { TgpuRenderPipeline } from 'typegpu';
1
+ import type {
2
+ TgpuBindGroup,
3
+ TgpuRenderPipeline,
4
+ TgpuRoot,
5
+ TgpuTexture,
6
+ } from 'typegpu';
2
7
  import type { BindGroupPair } from '../types/types';
8
+ import {
9
+ maskTextureBindGroupLayout,
10
+ textureBindGroupLayout,
11
+ } from './bindGroupLayouts';
12
+ import mainVertex from './vertexShaders/mainVertex';
13
+ import maskFragment from './fragmentShaders/maskFragment';
14
+ import { reverseHoloFragment } from './fragmentShaders/reverseHoloFragment';
15
+ import { holoFragment } from './fragmentShaders/holoFragment';
16
+ import {
17
+ WAVE_CALLBACKS,
18
+ waveCallbackFn,
19
+ waveCallbackSlot,
20
+ } from '../enums/waveCallback';
3
21
 
4
22
  export const attachBindGroups = (
5
23
  pipeline: TgpuRenderPipeline,
6
- bindGroupPairs: BindGroupPair[]
7
- ) => {
8
- for (const pair of bindGroupPairs) {
9
- pipeline = pipeline.with(pair.layout, pair.group);
10
- }
24
+ bindGroups: TgpuBindGroup[]
25
+ ) =>
26
+ bindGroups.reduce(
27
+ (acc, bindGroup) => acc.with(bindGroup.layout, bindGroup),
28
+ pipeline
29
+ );
11
30
 
12
- return pipeline;
31
+ export const blend: GPUBlendState = {
32
+ color: {
33
+ srcFactor: 'one-minus-src-alpha',
34
+ dstFactor: 'src-alpha',
35
+ operation: 'add',
36
+ } satisfies GPUBlendComponent,
37
+ alpha: {
38
+ srcFactor: 'one-minus-src-alpha',
39
+ dstFactor: 'dst-alpha',
40
+ operation: 'add',
41
+ } satisfies GPUBlendComponent,
13
42
  };
14
43
 
15
44
  export const getDefaultTarget = (
16
- presentationFormat: GPUTextureFormat
45
+ presentationFormat: GPUTextureFormat,
46
+ blendMode?: GPUBlendState
17
47
  ): GPUColorTargetState => {
18
48
  return {
19
49
  format: presentationFormat,
20
- blend: {
21
- color: {
22
- srcFactor: 'src-alpha',
23
- dstFactor: 'one-minus-src-alpha',
24
- operation: 'add',
25
- },
26
- alpha: {
27
- srcFactor: 'one',
28
- dstFactor: 'one-minus-src-alpha',
29
- operation: 'add',
30
- },
31
- },
50
+ blend: blendMode,
32
51
  };
33
52
  };
34
53
 
@@ -42,3 +61,116 @@ export const attachBindGroupsToPass = (
42
61
 
43
62
  return pass;
44
63
  };
64
+
65
+ export const createMaskPipeline = (
66
+ root: TgpuRoot,
67
+ maskTexture: TgpuTexture | undefined,
68
+ bindGroups: TgpuBindGroup[],
69
+ sampler: GPUSampler,
70
+ presentationFormat: GPUTextureFormat
71
+ ): TgpuRenderPipeline | void => {
72
+ if (!maskTexture) return;
73
+
74
+ const maskTextureBindGroup = root.createBindGroup(
75
+ maskTextureBindGroupLayout,
76
+ {
77
+ texture: root.unwrap(maskTexture).createView(),
78
+ sampler,
79
+ }
80
+ );
81
+ const maskBGP: TgpuBindGroup[] = [maskTextureBindGroup];
82
+ for (let i = 0; i < bindGroups.length; i++) {
83
+ maskBGP.push(bindGroups[i]!);
84
+ }
85
+ let maskPipeline = root['~unstable']
86
+ .withVertex(mainVertex, {})
87
+ .withFragment(maskFragment, getDefaultTarget(presentationFormat, blend))
88
+ .createPipeline();
89
+ maskPipeline = attachBindGroups(maskPipeline, maskBGP);
90
+
91
+ return maskPipeline;
92
+ };
93
+
94
+ export const createReverseHoloPipeline = (
95
+ root: TgpuRoot,
96
+ texture: TgpuTexture | undefined,
97
+ bindGroups: TgpuBindGroup[],
98
+ sampler: GPUSampler,
99
+ presentationFormat: GPUTextureFormat
100
+ ): TgpuRenderPipeline | void => {
101
+ if (!texture) return;
102
+
103
+ const reverseHoloBindGroup = root.createBindGroup(
104
+ maskTextureBindGroupLayout,
105
+ {
106
+ texture: root.unwrap(texture).createView(),
107
+ sampler,
108
+ }
109
+ );
110
+ const reverseHoloBGP: TgpuBindGroup[] = [...bindGroups, reverseHoloBindGroup];
111
+
112
+ let reverseHoloPipeline = root['~unstable']
113
+ .withVertex(mainVertex, {})
114
+ .withFragment(
115
+ reverseHoloFragment,
116
+ getDefaultTarget(presentationFormat, blend)
117
+ )
118
+ .createPipeline();
119
+ reverseHoloPipeline = attachBindGroups(reverseHoloPipeline, reverseHoloBGP);
120
+
121
+ return reverseHoloPipeline;
122
+ };
123
+
124
+ export const createRainbowHoloPipeline = (
125
+ root: TgpuRoot,
126
+ texture: TgpuTexture | undefined,
127
+ bindGroups: TgpuBindGroup[],
128
+ sampler: GPUSampler,
129
+ presentationFormat: GPUTextureFormat
130
+ ): TgpuRenderPipeline | void => {
131
+ if (!texture) return;
132
+
133
+ const imageTextureBindGroup = root.createBindGroup(textureBindGroupLayout, {
134
+ texture: root.unwrap(texture).createView(),
135
+ sampler,
136
+ });
137
+
138
+ let rainbowHoloPipeline = root['~unstable']
139
+ .with(waveCallbackSlot, waveCallbackFn(WAVE_CALLBACKS.default))
140
+ .withVertex(mainVertex, {})
141
+ .withFragment(holoFragment, getDefaultTarget(presentationFormat, blend))
142
+ .createPipeline();
143
+
144
+ rainbowHoloPipeline = attachBindGroups(rainbowHoloPipeline, [
145
+ ...bindGroups,
146
+ imageTextureBindGroup,
147
+ ]);
148
+ return rainbowHoloPipeline;
149
+ };
150
+
151
+ export function renderPipelinesInSinglePass(
152
+ root: TgpuRoot,
153
+ pipelines: TgpuRenderPipeline[],
154
+ view: GPUTextureView
155
+ ) {
156
+ const unstableRoot = root['~unstable'];
157
+ const attachment: GPURenderPassColorAttachment = {
158
+ view,
159
+ clearValue: [0, 0, 0, 0],
160
+ loadOp: 'clear',
161
+ storeOp: 'store',
162
+ };
163
+
164
+ unstableRoot.beginRenderPass(
165
+ {
166
+ colorAttachments: [attachment],
167
+ },
168
+ (pass) => {
169
+ for (const pipeline of pipelines) {
170
+ pass.setPipeline(pipeline);
171
+ pass.draw(6);
172
+ }
173
+ }
174
+ );
175
+ unstableRoot.flush();
176
+ }
@@ -13,6 +13,7 @@ const getBitmapFromURI = async (uri: string): Promise<ImageBitmap> => {
13
13
  const blob = await response.blob();
14
14
  const imageBitmap = await createImageBitmap(blob);
15
15
 
16
+ console.log('bitmap size: ', imageBitmap);
16
17
  uriToBitmapMap.set(uri, imageBitmap);
17
18
  return imageBitmap;
18
19
  };
@@ -0,0 +1,82 @@
1
+ import type { TgpuRoot, TgpuBuffer, ValidateBufferSchema } from 'typegpu';
2
+
3
+ export type BufferUsageType = 'uniform' | 'storage' | 'vertex';
4
+
5
+ type BufferWithUsageFromEntry<
6
+ TEntry extends { schema: ValidateBufferSchema<any>; usage: BufferUsageType },
7
+ > = TEntry['usage'] extends 'uniform'
8
+ ? TgpuBuffer<TEntry['schema']> & { usableAsUniform: true }
9
+ : TEntry['usage'] extends 'storage'
10
+ ? TgpuBuffer<TEntry['schema']> & { usableAsStorage: true }
11
+ : TEntry['usage'] extends 'vertex'
12
+ ? TgpuBuffer<TEntry['schema']> & { usableAsVertex: true }
13
+ : never;
14
+
15
+ export class TypedBufferMap<
16
+ TSchemas extends Record<
17
+ string,
18
+ { schema: ValidateBufferSchema<any>; usage: BufferUsageType }
19
+ >,
20
+ > {
21
+ private buffers: {
22
+ [K in keyof TSchemas]?: BufferWithUsageFromEntry<TSchemas[K]>;
23
+ } = {};
24
+
25
+ constructor(private schemas: TSchemas) {}
26
+
27
+ set<K extends keyof TSchemas>(
28
+ key: K,
29
+ buffer: BufferWithUsageFromEntry<TSchemas[K]>
30
+ ): void {
31
+ this.buffers[key] = buffer;
32
+ }
33
+
34
+ get<K extends keyof TSchemas>(
35
+ key: K
36
+ ): BufferWithUsageFromEntry<TSchemas[K]> | undefined {
37
+ return this.buffers[key];
38
+ }
39
+
40
+ addBuffer<K extends keyof TSchemas>(
41
+ root: TgpuRoot,
42
+ key: K,
43
+ initValues?: TSchemas[K]['schema']['_TSType']
44
+ ): BufferWithUsageFromEntry<TSchemas[K]> {
45
+ const entry = this.schemas[key];
46
+ if (!entry) {
47
+ throw new Error(`No schema found for buffer key "${String(key)}"`);
48
+ }
49
+
50
+ const { schema, usage } = entry;
51
+ if (this.buffers[key]) {
52
+ console.warn(`Buffer "${String(key)}" already exists. Skipping...`);
53
+ return this.buffers[key]!;
54
+ }
55
+
56
+ const buffer = initValues
57
+ ? root.createBuffer(schema, initValues)
58
+ : root.createBuffer(schema);
59
+
60
+ const typedBuffer = buffer.$usage(usage) as BufferWithUsageFromEntry<
61
+ TSchemas[K]
62
+ >;
63
+ this.buffers[key] = typedBuffer;
64
+ return typedBuffer;
65
+ }
66
+
67
+ keys(): (keyof TSchemas)[] {
68
+ return Object.keys(this.buffers) as (keyof TSchemas)[];
69
+ }
70
+
71
+ has<K extends keyof TSchemas>(key: K): boolean {
72
+ return !!this.buffers[key];
73
+ }
74
+
75
+ delete<K extends keyof TSchemas>(key: K): void {
76
+ const buf = this.buffers[key];
77
+ if (buf) {
78
+ buf.destroy?.();
79
+ delete this.buffers[key];
80
+ }
81
+ }
82
+ }
@@ -0,0 +1,42 @@
1
+ import { type TextureProps, type TgpuRoot, type TgpuTexture } from 'typegpu';
2
+ import getBitmapFromURI from './bitmaps';
3
+
4
+ export const createTexture = async (
5
+ root: TgpuRoot,
6
+ size: {
7
+ width: number;
8
+ height: number;
9
+ }
10
+ ): Promise<TgpuTexture> => {
11
+ const texture = root['~unstable']
12
+ .createTexture({
13
+ size: [size.width, size.height],
14
+ format: 'rgba8unorm',
15
+ })
16
+ .$usage('sampled', 'render');
17
+
18
+ return texture;
19
+ };
20
+
21
+ export const loadTexture = async (
22
+ root: TgpuRoot,
23
+ imageBitmap: ImageBitmap,
24
+ texture: TgpuTexture
25
+ ) => {
26
+ root.device.queue.copyExternalImageToTexture(
27
+ { source: imageBitmap },
28
+ { texture: root.unwrap(texture) },
29
+ [imageBitmap.width, imageBitmap.height]
30
+ );
31
+ };
32
+
33
+ export async function loadBitmap(
34
+ root: TgpuRoot,
35
+ imageURI: string,
36
+ setTexture: (texture: TgpuTexture<TextureProps>) => void
37
+ ) {
38
+ const bitmap = await getBitmapFromURI(imageURI);
39
+ const texture = await createTexture(root, bitmap);
40
+ setTexture(texture);
41
+ await loadTexture(root, bitmap, texture);
42
+ }
@@ -33,7 +33,7 @@ export const hueShift = tgpu.fn(
33
33
  return d.vec3f(r, g, b);
34
34
  });
35
35
 
36
- export const bloomColorShift = tgpu.fn(
36
+ export const glareColorShift = tgpu.fn(
37
37
  [d.vec3f, d.f32],
38
38
  d.vec3f
39
39
  )((color, power) => {
@@ -73,3 +73,38 @@ export const overlayChannels = tgpu.fn(
73
73
  overlayChannel(base.z, blend.z)
74
74
  );
75
75
  });
76
+
77
+ /** Rec.601 luma */
78
+ export const luma601 = tgpu.fn(
79
+ [d.vec3f],
80
+ d.f32
81
+ )((rgb) => {
82
+ return std.add(
83
+ std.mul(rgb.x, 0.299),
84
+ std.add(std.mul(rgb.y, 0.587), std.mul(rgb.z, 0.114))
85
+ );
86
+ });
87
+
88
+ export const tiltTowardsLighterNeighbor = tgpu.fn(
89
+ [d.vec3f, d.f32],
90
+ d.vec3f
91
+ )((rgb, t) => {
92
+ const toYellow = d.vec3f(std.max(rgb.x, rgb.y), std.max(rgb.x, rgb.y), rgb.z);
93
+ const toCyan = d.vec3f(rgb.x, std.max(rgb.y, rgb.z), std.max(rgb.y, rgb.z));
94
+
95
+ const yYellow = luma601(toYellow);
96
+ const yCyan = luma601(toCyan);
97
+
98
+ const toColor = std.select(toCyan, toYellow, yYellow >= yCyan);
99
+
100
+ const tClamped = std.clamp(t, 0.0, 1.0);
101
+ return std.mix(rgb, toColor, tClamped);
102
+ });
103
+
104
+ export const linearstep = tgpu.fn(
105
+ [d.f32, d.f32, d.f32],
106
+ d.f32
107
+ )((num1, num2, x) => {
108
+ const t = (x - num1) / (num2 - num1);
109
+ return std.clamp(t, 0, 1);
110
+ });