react-native-shine 0.4.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/lib/module/components/Content.js +39 -34
  2. package/lib/module/components/Content.js.map +1 -1
  3. package/lib/module/components/ShineGroup.js +0 -2
  4. package/lib/module/components/ShineGroup.js.map +1 -1
  5. package/lib/module/config/debugMode.js +5 -0
  6. package/lib/module/config/debugMode.js.map +1 -0
  7. package/lib/module/enums/colorPresets.js +71 -0
  8. package/lib/module/enums/colorPresets.js.map +1 -0
  9. package/lib/module/enums/waveCallback.js +2 -1
  10. package/lib/module/enums/waveCallback.js.map +1 -1
  11. package/lib/module/index.js +1 -0
  12. package/lib/module/index.js.map +1 -1
  13. package/lib/module/shaders/bindGroupLayouts.js +11 -1
  14. package/lib/module/shaders/bindGroupLayouts.js.map +1 -1
  15. package/lib/module/shaders/fragmentShaders/baseTextureFragment.js +28 -0
  16. package/lib/module/shaders/fragmentShaders/baseTextureFragment.js.map +1 -0
  17. package/lib/module/shaders/fragmentShaders/colorMaskFragment.js +42 -6
  18. package/lib/module/shaders/fragmentShaders/colorMaskFragment.js.map +1 -1
  19. package/lib/module/shaders/fragmentShaders/glareFragment.js +4 -5
  20. package/lib/module/shaders/fragmentShaders/glareFragment.js.map +1 -1
  21. package/lib/module/shaders/fragmentShaders/holoFragment.js +10 -2
  22. package/lib/module/shaders/fragmentShaders/holoFragment.js.map +1 -1
  23. package/lib/module/shaders/fragmentShaders/maskFragment.js +1 -0
  24. package/lib/module/shaders/fragmentShaders/maskFragment.js.map +1 -1
  25. package/lib/module/shaders/fragmentShaders/reverseHoloFragment.js +1 -0
  26. package/lib/module/shaders/fragmentShaders/reverseHoloFragment.js.map +1 -1
  27. package/lib/module/shaders/resourceManagement/bitmaps.js +4 -3
  28. package/lib/module/shaders/resourceManagement/bitmaps.js.map +1 -1
  29. package/lib/module/shaders/resourceManagement/bufferManager.js +6 -1
  30. package/lib/module/shaders/resourceManagement/bufferManager.js.map +1 -1
  31. package/lib/module/shaders/resourceManagement/textures.js.map +1 -1
  32. package/lib/module/shaders/tgpuUtils.js +62 -34
  33. package/lib/module/shaders/tgpuUtils.js.map +1 -1
  34. package/lib/module/shaders/vertexShaders/mainRotationEffectVertex.js +1 -0
  35. package/lib/module/shaders/vertexShaders/mainRotationEffectVertex.js.map +1 -1
  36. package/lib/module/shaders/vertexShaders/mainVertex.js +1 -0
  37. package/lib/module/shaders/vertexShaders/mainVertex.js.map +1 -1
  38. package/lib/module/types/typeUtils.js +39 -4
  39. package/lib/module/types/typeUtils.js.map +1 -1
  40. package/lib/module/utils/vector.js +7 -0
  41. package/lib/module/utils/vector.js.map +1 -1
  42. package/lib/typescript/src/components/Content.d.ts +4 -2
  43. package/lib/typescript/src/components/Content.d.ts.map +1 -1
  44. package/lib/typescript/src/components/ShineGroup.d.ts +1 -1
  45. package/lib/typescript/src/components/ShineGroup.d.ts.map +1 -1
  46. package/lib/typescript/src/config/debugMode.d.ts +3 -0
  47. package/lib/typescript/src/config/debugMode.d.ts.map +1 -0
  48. package/lib/typescript/src/enums/colorPresets.d.ts +33 -0
  49. package/lib/typescript/src/enums/colorPresets.d.ts.map +1 -0
  50. package/lib/typescript/src/index.d.ts +1 -0
  51. package/lib/typescript/src/index.d.ts.map +1 -1
  52. package/lib/typescript/src/shaders/bindGroupLayouts.d.ts +32 -10
  53. package/lib/typescript/src/shaders/bindGroupLayouts.d.ts.map +1 -1
  54. package/lib/typescript/src/shaders/bindGroupUtils.d.ts +20 -0
  55. package/lib/typescript/src/shaders/bindGroupUtils.d.ts.map +1 -1
  56. package/lib/typescript/src/shaders/fragmentShaders/baseTextureFragment.d.ts +5 -0
  57. package/lib/typescript/src/shaders/fragmentShaders/baseTextureFragment.d.ts.map +1 -0
  58. package/lib/typescript/src/shaders/fragmentShaders/colorMaskFragment.d.ts.map +1 -1
  59. package/lib/typescript/src/shaders/fragmentShaders/glareFragment.d.ts.map +1 -1
  60. package/lib/typescript/src/shaders/fragmentShaders/holoFragment.d.ts.map +1 -1
  61. package/lib/typescript/src/shaders/resourceManagement/bitmaps.d.ts.map +1 -1
  62. package/lib/typescript/src/shaders/resourceManagement/bufferManager.d.ts.map +1 -1
  63. package/lib/typescript/src/shaders/resourceManagement/textures.d.ts +3 -3
  64. package/lib/typescript/src/shaders/resourceManagement/textures.d.ts.map +1 -1
  65. package/lib/typescript/src/shaders/tgpuUtils.d.ts +1 -0
  66. package/lib/typescript/src/shaders/tgpuUtils.d.ts.map +1 -1
  67. package/lib/typescript/src/types/typeUtils.d.ts +10 -0
  68. package/lib/typescript/src/types/typeUtils.d.ts.map +1 -1
  69. package/lib/typescript/src/types/types.d.ts +10 -0
  70. package/lib/typescript/src/types/types.d.ts.map +1 -1
  71. package/lib/typescript/src/utils/vector.d.ts +1 -0
  72. package/lib/typescript/src/utils/vector.d.ts.map +1 -1
  73. package/package.json +4 -4
  74. package/src/components/Content.tsx +48 -22
  75. package/src/components/ShineGroup.tsx +0 -2
  76. package/src/config/debugMode.ts +2 -0
  77. package/src/enums/colorPresets.ts +41 -0
  78. package/src/enums/waveCallback.ts +1 -1
  79. package/src/index.tsx +1 -0
  80. package/src/shaders/bindGroupLayouts.ts +10 -0
  81. package/src/shaders/fragmentShaders/baseTextureFragment.ts +18 -0
  82. package/src/shaders/fragmentShaders/colorMaskFragment.ts +55 -4
  83. package/src/shaders/fragmentShaders/glareFragment.ts +2 -4
  84. package/src/shaders/fragmentShaders/holoFragment.ts +7 -1
  85. package/src/shaders/resourceManagement/bitmaps.ts +4 -3
  86. package/src/shaders/resourceManagement/bufferManager.ts +10 -1
  87. package/src/shaders/resourceManagement/textures.ts +3 -3
  88. package/src/shaders/tgpuUtils.ts +55 -43
  89. package/src/types/typeUtils.ts +36 -2
  90. package/src/types/types.ts +7 -0
  91. package/src/utils/vector.ts +4 -0
@@ -0,0 +1,41 @@
1
+ import type { vec3 } from '../types/types';
2
+
3
+ export const ColorPresets = {
4
+ // --- Primary & Secondary ---
5
+ RED: [255, 0, 0], // #FF0000
6
+ GREEN: [0, 255, 0], // #00FF00
7
+ BLUE: [0, 0, 255], // #0000FF
8
+ YELLOW: [255, 255, 0], // #FFFF00
9
+ CYAN: [0, 255, 255], // #00FFFF
10
+ MAGENTA: [255, 0, 255], // #FF00FF
11
+
12
+ // --- Grayscale ---
13
+ WHITE: [255, 255, 255], // #FFFFFF
14
+ BLACK: [0, 0, 0], // #000000
15
+ GRAY: [128, 128, 128], // #808080
16
+ LIGHT_GRAY: [211, 211, 211], // #D3D3D3
17
+ DARK_GRAY: [105, 105, 105], // #696969
18
+
19
+ // --- Common Colors ---
20
+ ORANGE: [255, 165, 0], // #FFA500
21
+ PURPLE: [128, 0, 128], // #800080
22
+ BROWN: [165, 42, 42], // #A52A2A
23
+ PINK: [255, 192, 203], // #FFC0CB
24
+ LIME_GREEN: [50, 205, 50], // #32CD32
25
+ FOREST_GREEN: [34, 139, 34], // #228B22
26
+ OLIVE: [128, 128, 0], // #808000
27
+ TEAL: [0, 128, 128], // #008080
28
+ NAVY: [0, 0, 128], // #000080
29
+ ROYAL_BLUE: [65, 105, 225], // #4169E1
30
+ SKY_BLUE: [135, 206, 235], // #87CEEB
31
+ INDIGO: [75, 0, 130], // #4B0082
32
+ VIOLET: [238, 130, 238], // #EE82EE
33
+ MAROON: [128, 0, 0], // #800000
34
+
35
+ // --- Hues & Tints ---
36
+ GOLD: [255, 215, 0], // #FFD700
37
+ TOMATO: [255, 99, 71], // #FF6347
38
+ SALMON: [250, 128, 114], // #FA8072
39
+ BEIGE: [245, 245, 220], // #F5F5DC
40
+ POTATO: [222, 184, 135], // #DEB887
41
+ } as const satisfies Record<string, vec3>;
@@ -3,7 +3,7 @@ import * as std from 'typegpu/std';
3
3
  import * as d from 'typegpu/data';
4
4
 
5
5
  const defaultWave = (pos: d.v2f) => {
6
- 'kernel';
6
+ 'use gpu';
7
7
 
8
8
  const x = pos.x;
9
9
  const y = pos.y;
package/src/index.tsx CHANGED
@@ -16,3 +16,4 @@ export { ShineGroup } from './components/ShineGroup';
16
16
  export type { ShineProps } from './components/Shine';
17
17
  export * from './utils/vector';
18
18
  export type { V2d, V3d } from './types/vector';
19
+ export * from './enums/colorPresets';
@@ -39,6 +39,16 @@ export const colorMaskSchema = d.struct({
39
39
  upper: d.vec3f,
40
40
  lower: d.vec3f,
41
41
  }),
42
+ hueToleranceRange: d.struct({
43
+ upper: d.f32,
44
+ lower: d.f32,
45
+ }),
46
+ useHSV: d.align(16, d.u32),
47
+ brightnessTolerance: d.f32,
48
+ saturationTolerance: d.f32,
49
+ lowSaturationThreshold: d.f32,
50
+ lowBrightnessThreshold: d.f32,
51
+ debugMode: d.u32,
42
52
  });
43
53
 
44
54
  export type ColorMaskSchema = typeof colorMaskSchema;
@@ -0,0 +1,18 @@
1
+ import tgpu from 'typegpu';
2
+ import * as d from 'typegpu/data';
3
+ import * as std from 'typegpu/std';
4
+ import { textureBindGroupLayout } from '../bindGroupLayouts';
5
+
6
+ export const baseTextureFragment = tgpu['~unstable'].fragmentFn({
7
+ in: { uv: d.vec2f },
8
+ out: d.vec4f,
9
+ })((input) => {
10
+ const texcoord = d.vec2f(input.uv.x, 1.0 - input.uv.y);
11
+ let color = std.textureSample(
12
+ textureBindGroupLayout.$.texture,
13
+ textureBindGroupLayout.$.sampler,
14
+ texcoord
15
+ );
16
+
17
+ return color;
18
+ });
@@ -5,6 +5,7 @@ import {
5
5
  textureBindGroupLayout,
6
6
  colorMaskBindGroupLayout,
7
7
  } from '../bindGroupLayouts';
8
+ import { rgbToHSV } from '../tgpuUtils';
8
9
 
9
10
  const colorMaskFragment = tgpu['~unstable'].fragmentFn({
10
11
  in: { uv: d.vec2f },
@@ -15,6 +16,18 @@ const colorMaskFragment = tgpu['~unstable'].fragmentFn({
15
16
  const mask = colorMaskBindGroupLayout.$.mask;
16
17
  const maskedColor = mask.baseColor;
17
18
  const rgbToleranceRange = mask.rgbToleranceRange;
19
+ const useHSV = mask.useHSV;
20
+
21
+ const hueToleranceRange = mask.hueToleranceRange;
22
+ const hueUpper = hueToleranceRange.upper;
23
+ const hueLower = hueToleranceRange.lower;
24
+
25
+ const brightnessTolerance = mask.brightnessTolerance;
26
+ const saturationTolerance = mask.saturationTolerance;
27
+ const lowSaturationThreshold = mask.lowSaturationThreshold;
28
+ const lowBrightnessThreshold = mask.lowBrightnessThreshold;
29
+
30
+ const colorMaskDebug = mask.debugMode;
18
31
 
19
32
  let color = std.textureSample(
20
33
  textureBindGroupLayout.$.texture,
@@ -26,10 +39,48 @@ const colorMaskFragment = tgpu['~unstable'].fragmentFn({
26
39
  const maskedColorUpper = std.add(maskedColor, rgbToleranceRange.upper);
27
40
  const upperCheck = std.all(std.le(color.xyz, maskedColorUpper));
28
41
  const lowerCheck = std.all(std.ge(color.xyz, maskedColorLower));
29
- if (upperCheck && lowerCheck) {
30
- return d.vec4f(color.xyz, 0.0);
31
- }
32
- return d.vec4f(color.xyz, color.w);
42
+ const rgbCheck = upperCheck && lowerCheck;
43
+
44
+ const maskedHSV = rgbToHSV(maskedColor);
45
+ const colorHSV = rgbToHSV(color.xyz);
46
+
47
+ let hueDiff = std.sub(colorHSV.x, maskedHSV.x);
48
+ hueDiff = std.select(hueDiff, std.sub(hueDiff, 1.0), hueDiff > d.f32(0.5));
49
+ hueDiff = std.select(hueDiff, std.add(hueDiff, 1.0), hueDiff < d.f32(-0.5));
50
+ const lowerHueCheck = hueDiff >= -hueLower;
51
+ const upperHueCheck = hueDiff <= hueUpper;
52
+ let hueCheck = lowerHueCheck && upperHueCheck;
53
+
54
+ const saturationDiff = std.abs(std.sub(colorHSV.y, maskedHSV.y));
55
+ const saturationCheck = saturationDiff <= saturationTolerance;
56
+
57
+ const brightnessDiff = std.abs(std.sub(colorHSV.z, maskedHSV.z));
58
+ const brightnessCheck = brightnessDiff <= brightnessTolerance;
59
+
60
+ const pixelIsGray = colorHSV.y < lowSaturationThreshold;
61
+ const targetIsGray = maskedHSV.y < lowSaturationThreshold;
62
+
63
+ const pixelIsBlack = colorHSV.z < lowBrightnessThreshold;
64
+ const targetIsBlack = maskedHSV.z < lowBrightnessThreshold;
65
+
66
+ //hue is unstable when either color is gray or black (low saturation or low brightness)
67
+ const hueIsUnstable =
68
+ pixelIsGray || targetIsGray || pixelIsBlack || targetIsBlack;
69
+
70
+ hueCheck = std.select(hueCheck, d.bool(true), hueIsUnstable);
71
+
72
+ const hsvCheck = hueCheck && saturationCheck && brightnessCheck;
73
+ const maskCheck = std.select(rgbCheck, hsvCheck, useHSV === d.u32(1));
74
+
75
+ color = std.select(color, d.vec4f(color.xyz, 0.0), maskCheck);
76
+
77
+ //debug - shows masked areas coloring them red
78
+ color = std.select(
79
+ color,
80
+ d.vec4f(1.0, 0.0, 0.0, 0.0),
81
+ maskCheck && colorMaskDebug === d.u32(1)
82
+ );
83
+ return color;
33
84
  });
34
85
 
35
86
  export default colorMaskFragment;
@@ -95,8 +95,8 @@ export const newGlareFragment = tgpu['~unstable'].fragmentFn({
95
95
  const glareIntensity = opts.glareIntensity; // [0..∞): bigger → wider/stronger area
96
96
  const glowPower = opts.glowPower; // (0..∞): curve shaping; bigger → softer/wider glow
97
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
98
+ const hueShiftAngleMin = opts.hueShiftAngleMin; // degrees
99
+ const hueShiftAngleMax = opts.hueShiftAngleMax; // degrees
100
100
  const lightIntensity = opts.lightIntensity / 1.3; // [0..∞): brightness boost of the glare/bloom
101
101
 
102
102
  let color = std.textureSample(
@@ -137,7 +137,5 @@ export const newGlareFragment = tgpu['~unstable'].fragmentFn({
137
137
 
138
138
  const outRGB = std.clamp(finalRGB, d.vec3f(0.0), d.vec3f(1.0));
139
139
 
140
- // if (maskedGlow > 0.6) return d.vec4f(0.0, 0.0, 0.0, 0.0);
141
-
142
140
  return d.vec4f(outRGB, color.w);
143
141
  });
@@ -27,9 +27,15 @@ export const holoFragment = tgpu['~unstable'].fragmentFn({
27
27
 
28
28
  const band = std.add(0.2 * waveX * uv.x, 2 * waveY * uv.y);
29
29
 
30
- const hueAngle = std.mul(std.abs(band), (10 * Math.PI * rot.x) / 3);
30
+ //TODO: fix holo
31
+ const hueAngle =
32
+ d.f32(180) * std.mul(std.abs(band), (10 * Math.PI * rot.x) / 3);
31
33
  const rainbowColor = hueShift(d.vec3f(1.0, 1.0, 1.0), hueAngle);
32
34
  const finalColor = std.mul(rainbowColor, 1.0);
33
35
 
36
+ // console.log('\ncurrentColor = (', rainbowColor.xyz, ')');
37
+ // console.log('hueAngle = ', hueAngle);
38
+ // console.clear();
39
+
34
40
  return d.vec4f(finalColor, 0.9 * textureColor.w);
35
41
  });
@@ -1,19 +1,20 @@
1
1
  import { Asset } from 'expo-asset';
2
+ import { debug } from '../../config/debugMode';
2
3
 
3
4
  const getBitmapFromURI = async (uri: string): Promise<ImageBitmap> => {
4
5
  if (uriToBitmapMap.has(uri)) return uriToBitmapMap.get(uri)!;
5
- console.log('bitmap not found in cache, fetching from URI');
6
+ if (debug) console.log('bitmap not found in cache, fetching from URI');
6
7
 
7
8
  const ast = Asset.fromURI(uri);
8
9
  await ast.downloadAsync();
9
10
  const fileURI = ast.localUri || ast.uri;
10
11
 
11
- console.log('fetch completed, creating ImageBitmap');
12
+ if (debug) console.log('fetch completed, creating ImageBitmap');
12
13
  const response = await fetch(fileURI);
13
14
  const blob = await response.blob();
14
15
  const imageBitmap = await createImageBitmap(blob);
15
16
 
16
- console.log('bitmap size: ', imageBitmap);
17
+ if (debug) console.log('bitmap size: ', imageBitmap);
17
18
  uriToBitmapMap.set(uri, imageBitmap);
18
19
  return imageBitmap;
19
20
  };
@@ -1,4 +1,5 @@
1
1
  import type { TgpuRoot, TgpuBuffer, ValidateBufferSchema } from 'typegpu';
2
+ import { debug } from '../../config/debugMode';
2
3
 
3
4
  export type BufferUsageType = 'uniform' | 'storage' | 'vertex';
4
5
 
@@ -49,7 +50,15 @@ export class TypedBufferMap<
49
50
 
50
51
  const { schema, usage } = entry;
51
52
  if (this.buffers[key]) {
52
- console.warn(`Buffer "${String(key)}" already exists. Skipping...`);
53
+ if (debug) console.warn(`Buffer "${String(key)}" already exists.`);
54
+
55
+ if (initValues) {
56
+ (this.buffers[key] as TgpuBuffer<any>).write(initValues);
57
+ if (debug)
58
+ console.log(
59
+ `Buffer "${String(key)}" updated with new initial values.`
60
+ );
61
+ }
53
62
  return this.buffers[key]!;
54
63
  }
55
64
 
@@ -7,8 +7,8 @@ export const createTexture = async (
7
7
  width: number;
8
8
  height: number;
9
9
  }
10
- //TODO: check why the error message screams about 'texture_2d' and 'texture_multisampled_2d'
11
- ): Promise<TgpuTexture> => {
10
+ //TODO: change any to the texture types (make a type that includes a union of all texture formats that are used)
11
+ ): Promise<TgpuTexture<any>> => {
12
12
  const texture = root['~unstable'].createTexture({
13
13
  size: [size.width, size.height, 1],
14
14
  format: 'rgba8unorm',
@@ -20,7 +20,7 @@ export const createTexture = async (
20
20
  export const loadTexture = async (
21
21
  root: TgpuRoot,
22
22
  imageBitmap: ImageBitmap,
23
- texture: TgpuTexture
23
+ texture: TgpuTexture<any>
24
24
  ) => {
25
25
  root.device.queue.copyExternalImageToTexture(
26
26
  { source: imageBitmap },
@@ -6,60 +6,72 @@ export const hueShift = tgpu.fn(
6
6
  [d.vec3f, d.f32],
7
7
  d.vec3f
8
8
  )((rgb, angle) => {
9
- const yiqY = std.add(
10
- std.mul(rgb.x, 0.299),
11
- std.add(std.mul(rgb.y, 0.587), std.mul(rgb.z, 0.114))
12
- );
13
- const yiqI = std.add(
14
- std.mul(rgb.x, 0.596),
15
- std.sub(std.mul(rgb.y, -0.274), std.mul(rgb.z, 0.322))
9
+ const hsv = rgbToHSV(rgb);
10
+ const shiftedH = std.fract(std.add(hsv.x, angle / 360.0));
11
+ const shiftedRGB = hsvToRGB(d.vec3f(shiftedH, hsv.y, hsv.z));
12
+ return shiftedRGB;
13
+ });
14
+
15
+ export const rgbToHSV = tgpu.fn(
16
+ [d.vec3f],
17
+ d.vec3f
18
+ )((rgb) => {
19
+ const K = d.vec4f(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
20
+ const p = std.mix(
21
+ d.vec4f(rgb.z, rgb.y, K.w, K.z),
22
+ d.vec4f(rgb.y, rgb.z, K.x, K.y),
23
+ std.step(rgb.z, rgb.y)
16
24
  );
17
- const yiqQ = std.add(
18
- std.mul(rgb.x, 0.211),
19
- std.sub(std.mul(rgb.y, -0.523), std.mul(rgb.z, 0.311))
25
+ const q = std.mix(
26
+ d.vec4f(p.x, p.y, p.w, rgb.x),
27
+ d.vec4f(rgb.x, p.y, p.z, p.x),
28
+ std.step(p.x, rgb.x)
20
29
  );
21
30
 
22
- // Rotate hue
23
- const cosA = std.cos(angle);
24
- const sinA = std.sin(angle);
25
- const i = std.sub(std.mul(yiqI, cosA), std.mul(yiqQ, sinA));
26
- const q = std.add(std.mul(yiqI, sinA), std.mul(yiqQ, cosA));
31
+ const v = std.max(q.x, q.y);
32
+ const d_val = std.sub(v, std.min(q.y, q.w));
33
+ const epsilon = d.f32(1.0e-10);
27
34
 
28
- // Convert back to RGB
29
- const r = std.add(std.add(yiqY, std.mul(i, 0.956)), std.mul(q, 0.621));
30
- const g = std.add(std.add(yiqY, std.mul(i, -0.272)), std.mul(q, -0.647));
31
- const b = std.add(std.add(yiqY, std.mul(i, -1.105)), std.mul(q, 1.702));
35
+ const h_temp = std.add(
36
+ q.z,
37
+ std.div(std.sub(q.w, q.y), std.add(std.mul(6.0, d_val), epsilon))
38
+ );
39
+ const h = std.fract(h_temp);
40
+ const s = std.div(d_val, std.add(v, epsilon));
32
41
 
33
- return d.vec3f(r, g, b);
42
+ return d.vec3f(h, s, v);
34
43
  });
35
44
 
36
- export const rgbToHSV = tgpu.fn(
45
+ export const hsvToRGB = tgpu.fn(
37
46
  [d.vec3f],
38
47
  d.vec3f
39
- )((rgb) => {
40
- const cMax = std.max(std.max(rgb.x, rgb.y), rgb.z);
41
- const cMin = std.min(std.min(rgb.x, rgb.y), rgb.z);
42
- const delta = std.sub(cMax, cMin);
43
-
44
- const hueDeltaZero = d.f32(0.0);
45
- const hueRmax = d.f32(60.0) * fmod((rgb.y - rgb.z) / delta, d.f32(6.0));
46
- const hueGmax = d.f32(60.0) * ((rgb.z - rgb.x) / delta + d.f32(2.0));
47
- const hueBmax = d.f32(60.0) * ((rgb.x - rgb.y) / delta + d.f32(4.0));
48
-
49
- let hue = std.select(
50
- hueDeltaZero,
51
- hueRmax,
52
- cMax === rgb.x && delta !== d.f32(0.0)
53
- );
54
- hue = std.select(hue, hueGmax, cMax === rgb.y && delta !== d.f32(0.0));
55
- hue = std.select(hue, hueBmax, cMax === rgb.z && delta !== d.f32(0.0));
56
- hue = std.select(hue, d.f32(0.0), delta === d.f32(0.0));
48
+ )((hsv) => {
49
+ const h = hsv.x;
50
+ const s = hsv.y;
51
+ const v = hsv.z;
52
+
53
+ // Multiply by 6.0 to convert [0,1] hue range to [0,6] sector range
54
+ const h2 = h * d.f32(6.0);
57
55
 
58
- hue = std.mod(hue, d.f32(360.0));
59
- const saturation = std.select(delta / cMax, d.f32(0.0), cMax === d.f32(0.0));
60
- const value = cMax;
56
+ const i = std.floor(h2);
57
+ const f = h2 - i;
61
58
 
62
- return d.vec3f(hue, saturation, value);
59
+ const p = v * (d.f32(1) - s);
60
+ const q = v * (d.f32(1) - s * f);
61
+ const t = v * (d.f32(1) - s * (d.f32(1) - f));
62
+
63
+ const i1 = d.f32(i === 1);
64
+ const i2 = d.f32(i === 2);
65
+ const i3 = d.f32(i === 3);
66
+ const i4 = d.f32(i === 4);
67
+ const i5 = d.f32(i === 5);
68
+ const i0 = d.f32(d.u32(i5 + i1 + i2 + i3 + i4) === d.u32(0)); //doesnt work, clamps on 300
69
+
70
+ const r = i0 * v + i1 * q + i2 * p + i3 * p + i4 * t + i5 * v;
71
+ const g = i0 * t + i1 * v + i2 * v + i3 * q + i4 * p + i5 * p;
72
+ const b = i0 * p + i1 * p + i2 * t + i3 * v + i4 * v + i5 * q;
73
+
74
+ return d.vec3f(r, g, b);
63
75
  });
64
76
 
65
77
  export const fmod = tgpu.fn(
@@ -10,6 +10,7 @@ import type {
10
10
  } from './types';
11
11
  import { div } from 'typegpu/std';
12
12
  import { WAVE_CALLBACKS } from '../enums/waveCallback';
13
+ import { colorMaskDebug } from '../config/debugMode';
13
14
 
14
15
  export const createGlareOptions = (
15
16
  options: Partial<GlareOptions>
@@ -51,16 +52,40 @@ export const mapToF32 = <T extends Record<string, number>>(
51
52
  export const createColorMask = (
52
53
  colorMask: DeepPartiallyOptional<ColorMask, 'baseColor'>
53
54
  ): ColorMask => {
54
- const { baseColor, rgbToleranceRange } = colorMask;
55
+ const {
56
+ baseColor,
57
+ rgbToleranceRange,
58
+ useHSV,
59
+ hueToleranceRange,
60
+ brightnessTolerance,
61
+ saturationTolerance,
62
+ lowBrightnessThreshold,
63
+ lowSaturationThreshold,
64
+ } = colorMask;
55
65
  const baseTolerance = {
56
66
  upper: [20, 20, 20] as vec3,
57
67
  lower: [20, 20, 20] as vec3,
58
68
  };
69
+ const baseHueTolerance = {
70
+ upper: 20,
71
+ lower: 20,
72
+ };
59
73
  const tolerance = { ...baseTolerance, ...rgbToleranceRange };
74
+ const hueTolerance = { ...baseHueTolerance, ...hueToleranceRange };
60
75
 
76
+ // TODO: add radian and degree angle handling
77
+ // '123deg' <- interpret as a numeric angle value
78
+ // 2 <- interpret as a radian value
61
79
  const mask: ColorMask = {
62
80
  baseColor: baseColor,
63
81
  rgbToleranceRange: tolerance,
82
+ useHSV: useHSV!!,
83
+ hueToleranceRange: hueTolerance,
84
+ brightnessTolerance: brightnessTolerance ?? 1.0,
85
+ saturationTolerance: saturationTolerance ?? 1.0,
86
+ lowBrightnessThreshold: lowBrightnessThreshold ?? 0.0,
87
+ lowSaturationThreshold: lowSaturationThreshold ?? 0.0,
88
+ debugMode: colorMaskDebug,
64
89
  };
65
90
 
66
91
  return mask;
@@ -73,6 +98,16 @@ export const colorMaskToTyped = (colorMask: ColorMask) => {
73
98
  upper: div(numberArrToTyped(colorMask.rgbToleranceRange.upper), 255),
74
99
  lower: div(numberArrToTyped(colorMask.rgbToleranceRange.lower), 255),
75
100
  },
101
+ useHSV: d.u32(colorMask.useHSV ? 1 : 0),
102
+ hueToleranceRange: {
103
+ lower: div(f32(colorMask.hueToleranceRange.lower), 360),
104
+ upper: div(f32(colorMask.hueToleranceRange.upper), 360),
105
+ },
106
+ brightnessTolerance: f32(colorMask.brightnessTolerance),
107
+ saturationTolerance: f32(colorMask.saturationTolerance),
108
+ lowSaturationThreshold: f32(colorMask.lowSaturationThreshold),
109
+ lowBrightnessThreshold: f32(colorMask.lowBrightnessThreshold),
110
+ debugMode: d.u32(colorMask.debugMode ? d.u32(1) : d.u32(0)),
76
111
  };
77
112
  return result;
78
113
  };
@@ -116,7 +151,6 @@ export const createReverseHoloDetectionChannelFlags = (
116
151
  };
117
152
  }
118
153
 
119
- console.log('createReverseHoloDetectionChannelFlags:', channelFlags);
120
154
  return channelFlags;
121
155
  };
122
156
 
@@ -21,10 +21,17 @@ export type GlareOptions = {
21
21
 
22
22
  export type ColorMask = {
23
23
  baseColor: vec3;
24
+ useHSV?: boolean;
25
+ hueToleranceRange: { upper: number; lower: number };
26
+ brightnessTolerance?: number;
27
+ lowBrightnessThreshold?: number;
28
+ saturationTolerance?: number;
29
+ lowSaturationThreshold?: number;
24
30
  rgbToleranceRange: {
25
31
  upper: vec3;
26
32
  lower: vec3;
27
33
  };
34
+ debugMode?: boolean;
28
35
  };
29
36
 
30
37
  export type ReverseHoloDetectionChannelFlags = {
@@ -129,4 +129,8 @@ export function degToRad(deg: number): number {
129
129
  return (deg * Math.PI) / 180;
130
130
  }
131
131
 
132
+ export function createV3d(x: number, y: number, z: number): V3d {
133
+ return { x: x, y: y, z: z };
134
+ }
135
+
132
136
  export const zeroV3d = { x: 0, y: 0, z: 0 };