react-native-shine 0.2.1 → 0.3.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.
- package/README.md +1 -1
- package/lib/module/components/Shine.js +269 -0
- package/lib/module/components/Shine.js.map +1 -0
- package/lib/module/components/ShineGroup.js +104 -0
- package/lib/module/components/ShineGroup.js.map +1 -0
- package/lib/module/enums/waveCallback.js +19 -0
- package/lib/module/enums/waveCallback.js.map +1 -0
- package/lib/module/hooks/useOrientation.js +16 -0
- package/lib/module/hooks/useOrientation.js.map +1 -0
- package/lib/module/index.js +5 -219
- package/lib/module/index.js.map +1 -1
- package/lib/module/shaders/bindGroupLayouts.js +40 -5
- package/lib/module/shaders/bindGroupLayouts.js.map +1 -1
- package/lib/module/shaders/bindGroupUtils.js +27 -12
- package/lib/module/shaders/bindGroupUtils.js.map +1 -1
- package/lib/module/shaders/fragmentShaders/colorMaskFragment.js +2 -2
- package/lib/module/shaders/fragmentShaders/colorMaskFragment.js.map +1 -1
- package/lib/module/shaders/fragmentShaders/glareFragment.js +114 -0
- package/lib/module/shaders/fragmentShaders/glareFragment.js.map +1 -0
- package/lib/module/shaders/fragmentShaders/holoFragment.js +33 -0
- package/lib/module/shaders/fragmentShaders/holoFragment.js.map +1 -0
- package/lib/module/shaders/fragmentShaders/maskFragment.js +20 -0
- package/lib/module/shaders/fragmentShaders/maskFragment.js.map +1 -0
- package/lib/module/shaders/fragmentShaders/reverseHoloFragment.js +46 -0
- package/lib/module/shaders/fragmentShaders/reverseHoloFragment.js.map +1 -0
- package/lib/module/shaders/pipelineSetups.js +82 -13
- package/lib/module/shaders/pipelineSetups.js.map +1 -1
- package/lib/module/shaders/{resourceManagement.js → resourceManagement/bitmaps.js} +2 -1
- package/lib/module/shaders/resourceManagement/bitmaps.js.map +1 -0
- package/lib/module/shaders/resourceManagement/bufferManager.js +46 -0
- package/lib/module/shaders/resourceManagement/bufferManager.js.map +1 -0
- package/lib/module/shaders/resourceManagement/textures.js +17 -0
- package/lib/module/shaders/resourceManagement/textures.js.map +1 -0
- package/lib/module/shaders/tgpuUtils.js +19 -1
- package/lib/module/shaders/tgpuUtils.js.map +1 -1
- package/lib/module/shaders/utils.js +0 -14
- package/lib/module/shaders/utils.js.map +1 -1
- package/lib/module/shaders/vertexShaders/mainRotationEffectVertex.js +47 -0
- package/lib/module/shaders/vertexShaders/mainRotationEffectVertex.js.map +1 -0
- package/lib/module/types/typeUtils.js +17 -5
- package/lib/module/types/typeUtils.js.map +1 -1
- package/lib/typescript/src/components/Shine.d.ts +17 -0
- package/lib/typescript/src/components/Shine.d.ts.map +1 -0
- package/lib/typescript/src/components/ShineGroup.d.ts +8 -0
- package/lib/typescript/src/components/ShineGroup.d.ts.map +1 -0
- package/lib/typescript/src/enums/waveCallback.d.ts +9 -0
- package/lib/typescript/src/enums/waveCallback.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useOrientation.d.ts +2 -0
- package/lib/typescript/src/hooks/useOrientation.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +6 -11
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/shaders/bindGroupLayouts.d.ts +44 -6
- package/lib/typescript/src/shaders/bindGroupLayouts.d.ts.map +1 -1
- package/lib/typescript/src/shaders/bindGroupUtils.d.ts +8 -8
- package/lib/typescript/src/shaders/bindGroupUtils.d.ts.map +1 -1
- package/lib/typescript/src/shaders/fragmentShaders/glareFragment.d.ts +8 -0
- package/lib/typescript/src/shaders/fragmentShaders/glareFragment.d.ts.map +1 -0
- package/lib/typescript/src/shaders/fragmentShaders/holoFragment.d.ts +5 -0
- package/lib/typescript/src/shaders/fragmentShaders/holoFragment.d.ts.map +1 -0
- package/lib/typescript/src/shaders/fragmentShaders/maskFragment.d.ts +6 -0
- package/lib/typescript/src/shaders/fragmentShaders/maskFragment.d.ts.map +1 -0
- package/lib/typescript/src/shaders/fragmentShaders/reverseHoloFragment.d.ts +5 -0
- package/lib/typescript/src/shaders/fragmentShaders/reverseHoloFragment.d.ts.map +1 -0
- package/lib/typescript/src/shaders/pipelineSetups.d.ts +9 -4
- package/lib/typescript/src/shaders/pipelineSetups.d.ts.map +1 -1
- package/lib/typescript/src/shaders/{resourceManagement.d.ts → resourceManagement/bitmaps.d.ts} +1 -1
- package/lib/typescript/src/shaders/resourceManagement/bitmaps.d.ts.map +1 -0
- package/lib/typescript/src/shaders/resourceManagement/bufferManager.d.ts +28 -0
- package/lib/typescript/src/shaders/resourceManagement/bufferManager.d.ts.map +1 -0
- package/lib/typescript/src/shaders/resourceManagement/textures.d.ts +7 -0
- package/lib/typescript/src/shaders/resourceManagement/textures.d.ts.map +1 -0
- package/lib/typescript/src/shaders/tgpuUtils.d.ts +5 -1
- package/lib/typescript/src/shaders/tgpuUtils.d.ts.map +1 -1
- package/lib/typescript/src/shaders/utils.d.ts +1 -7
- package/lib/typescript/src/shaders/utils.d.ts.map +1 -1
- package/lib/typescript/src/shaders/vertexShaders/mainRotationEffectVertex.d.ts +6 -0
- package/lib/typescript/src/shaders/vertexShaders/mainRotationEffectVertex.d.ts.map +1 -0
- package/lib/typescript/src/types/typeUtils.d.ts +3 -2
- package/lib/typescript/src/types/typeUtils.d.ts.map +1 -1
- package/lib/typescript/src/types/types.d.ts +7 -2
- package/lib/typescript/src/types/types.d.ts.map +1 -1
- package/package.json +5 -3
- package/scripts/install-peers.js +21 -0
- package/scripts/postinstall.js +18 -0
- package/src/components/Shine.tsx +480 -0
- package/src/components/ShineGroup.tsx +107 -0
- package/src/enums/waveCallback.ts +22 -0
- package/src/hooks/useOrientation.ts +20 -0
- package/src/index.tsx +6 -322
- package/src/shaders/bindGroupLayouts.ts +43 -6
- package/src/shaders/bindGroupUtils.ts +34 -19
- package/src/shaders/fragmentShaders/colorMaskFragment.ts +2 -2
- package/src/shaders/fragmentShaders/glareFragment.ts +142 -0
- package/src/shaders/fragmentShaders/holoFragment.ts +43 -0
- package/src/shaders/fragmentShaders/maskFragment.ts +31 -0
- package/src/shaders/fragmentShaders/reverseHoloFragment.ts +71 -0
- package/src/shaders/pipelineSetups.ts +161 -14
- package/src/shaders/{resourceManagement.ts → resourceManagement/bitmaps.ts} +1 -0
- package/src/shaders/resourceManagement/bufferManager.ts +82 -0
- package/src/shaders/resourceManagement/textures.ts +30 -0
- package/src/shaders/tgpuUtils.ts +36 -1
- package/src/shaders/utils.ts +0 -30
- package/src/shaders/vertexShaders/mainRotationEffectVertex.ts +76 -0
- package/src/types/typeUtils.ts +22 -8
- package/src/types/types.ts +8 -2
- package/lib/module/shaders/fragmentShaders/bloomFragment.js +0 -66
- package/lib/module/shaders/fragmentShaders/bloomFragment.js.map +0 -1
- package/lib/module/shaders/resourceManagement.js.map +0 -1
- package/lib/typescript/src/shaders/fragmentShaders/bloomFragment.d.ts +0 -6
- package/lib/typescript/src/shaders/fragmentShaders/bloomFragment.d.ts.map +0 -1
- package/lib/typescript/src/shaders/resourceManagement.d.ts.map +0 -1
- package/src/shaders/fragmentShaders/bloomFragment.ts +0 -83
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import tgpu from 'typegpu';
|
|
2
|
+
import * as d from 'typegpu/data';
|
|
3
|
+
import * as std from 'typegpu/std';
|
|
4
|
+
import {
|
|
5
|
+
rotationValuesBindGroupLayout,
|
|
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 centeredCoords = std.sub(std.mul(uv, 2.0), 1.0);
|
|
18
|
+
|
|
19
|
+
const textureColor = std.textureSample(
|
|
20
|
+
textureBindGroupLayout.$.texture,
|
|
21
|
+
textureBindGroupLayout.$.sampler,
|
|
22
|
+
texcoord
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
const rot = rotationValuesBindGroupLayout.$.vec;
|
|
26
|
+
const center = std.add(d.vec2f(0.0), d.vec2f(rot.x, rot.y));
|
|
27
|
+
|
|
28
|
+
const wave = waveCallbackSlot.$(rot.xy);
|
|
29
|
+
const waveX = wave.x;
|
|
30
|
+
const waveY = wave.y;
|
|
31
|
+
|
|
32
|
+
const band = std.add(waveX, waveY);
|
|
33
|
+
|
|
34
|
+
const dist = std.distance(centeredCoords, center);
|
|
35
|
+
const intensity = std.clamp(1.0 - dist, 0.0, 1.0);
|
|
36
|
+
const falloff = std.pow(std.exp(-dist), 1.0 / intensity);
|
|
37
|
+
|
|
38
|
+
const hueAngle = std.mul(std.abs(band), (10 * Math.PI * rot.x) / 3);
|
|
39
|
+
const rainbowColor = hueShift(d.vec3f(1.0, 1.0, 1.0), hueAngle);
|
|
40
|
+
const finalColor = std.mul(rainbowColor, falloff);
|
|
41
|
+
|
|
42
|
+
return d.vec4f(finalColor, 1 - falloff * dist * textureColor.w);
|
|
43
|
+
});
|
|
@@ -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
|
+
rotationValuesBindGroupLayout,
|
|
8
|
+
glareOptionsBindGroupLayout,
|
|
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 = rotationValuesBindGroupLayout.$.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 = glareOptionsBindGroupLayout.$.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,5 +1,19 @@
|
|
|
1
|
-
import type { TgpuRenderPipeline } from 'typegpu';
|
|
1
|
+
import type { TgpuRenderPipeline, TgpuRoot, TgpuTexture } from 'typegpu';
|
|
2
2
|
import type { BindGroupPair } from '../types/types';
|
|
3
|
+
import {
|
|
4
|
+
maskTextureBindGroupLayout,
|
|
5
|
+
textureBindGroupLayout,
|
|
6
|
+
} from './bindGroupLayouts';
|
|
7
|
+
import { createBindGroupPair, createBindGroupPairs } from '../types/typeUtils';
|
|
8
|
+
import mainVertex from './vertexShaders/mainVertex';
|
|
9
|
+
import maskFragment from './fragmentShaders/maskFragment';
|
|
10
|
+
import { reverseHoloFragment } from './fragmentShaders/reverseHoloFragment';
|
|
11
|
+
import { holoFragment } from './fragmentShaders/holoFragment';
|
|
12
|
+
import {
|
|
13
|
+
WAVE_CALLBACKS,
|
|
14
|
+
waveCallbackFn,
|
|
15
|
+
waveCallbackSlot,
|
|
16
|
+
} from '../enums/waveCallback';
|
|
3
17
|
|
|
4
18
|
export const attachBindGroups = (
|
|
5
19
|
pipeline: TgpuRenderPipeline,
|
|
@@ -12,23 +26,26 @@ export const attachBindGroups = (
|
|
|
12
26
|
return pipeline;
|
|
13
27
|
};
|
|
14
28
|
|
|
29
|
+
export const blend: GPUBlendState = {
|
|
30
|
+
color: {
|
|
31
|
+
srcFactor: 'one-minus-src-alpha',
|
|
32
|
+
dstFactor: 'src-alpha',
|
|
33
|
+
operation: 'add',
|
|
34
|
+
} satisfies GPUBlendComponent,
|
|
35
|
+
alpha: {
|
|
36
|
+
srcFactor: 'one-minus-src-alpha',
|
|
37
|
+
dstFactor: 'dst-alpha',
|
|
38
|
+
operation: 'add',
|
|
39
|
+
} satisfies GPUBlendComponent,
|
|
40
|
+
};
|
|
41
|
+
|
|
15
42
|
export const getDefaultTarget = (
|
|
16
|
-
presentationFormat: GPUTextureFormat
|
|
43
|
+
presentationFormat: GPUTextureFormat,
|
|
44
|
+
blendMode?: GPUBlendState
|
|
17
45
|
): GPUColorTargetState => {
|
|
18
46
|
return {
|
|
19
47
|
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
|
-
},
|
|
48
|
+
blend: blendMode,
|
|
32
49
|
};
|
|
33
50
|
};
|
|
34
51
|
|
|
@@ -42,3 +59,133 @@ export const attachBindGroupsToPass = (
|
|
|
42
59
|
|
|
43
60
|
return pass;
|
|
44
61
|
};
|
|
62
|
+
|
|
63
|
+
export const createMaskPipeline = (
|
|
64
|
+
root: TgpuRoot,
|
|
65
|
+
maskTexture: TgpuTexture | null,
|
|
66
|
+
BGP: BindGroupPair[],
|
|
67
|
+
sampler: GPUSampler,
|
|
68
|
+
presentationFormat: GPUTextureFormat
|
|
69
|
+
): TgpuRenderPipeline | null => {
|
|
70
|
+
if (!maskTexture) return null;
|
|
71
|
+
|
|
72
|
+
const maskTextureBindGroup = root.createBindGroup(
|
|
73
|
+
maskTextureBindGroupLayout,
|
|
74
|
+
{
|
|
75
|
+
texture: root.unwrap(maskTexture).createView(),
|
|
76
|
+
sampler,
|
|
77
|
+
}
|
|
78
|
+
);
|
|
79
|
+
const maskBGP: BindGroupPair[] = createBindGroupPairs(
|
|
80
|
+
[maskTextureBindGroupLayout],
|
|
81
|
+
[maskTextureBindGroup]
|
|
82
|
+
);
|
|
83
|
+
for (let i = 0; i < BGP.length; i++) {
|
|
84
|
+
maskBGP.push(BGP[i]!);
|
|
85
|
+
}
|
|
86
|
+
let maskPipeline = root['~unstable']
|
|
87
|
+
.withVertex(mainVertex, {})
|
|
88
|
+
.withFragment(maskFragment, getDefaultTarget(presentationFormat, blend))
|
|
89
|
+
.createPipeline();
|
|
90
|
+
maskPipeline = attachBindGroups(maskPipeline, maskBGP);
|
|
91
|
+
|
|
92
|
+
return maskPipeline;
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export const createReverseHoloPipeline = (
|
|
96
|
+
root: TgpuRoot,
|
|
97
|
+
texture: TgpuTexture | null,
|
|
98
|
+
BGP: BindGroupPair[],
|
|
99
|
+
sampler: GPUSampler,
|
|
100
|
+
presentationFormat: GPUTextureFormat
|
|
101
|
+
): TgpuRenderPipeline | null => {
|
|
102
|
+
if (!texture) return null;
|
|
103
|
+
|
|
104
|
+
const reverseHoloBindGroup = root.createBindGroup(
|
|
105
|
+
maskTextureBindGroupLayout,
|
|
106
|
+
{
|
|
107
|
+
texture: root.unwrap(texture).createView(),
|
|
108
|
+
sampler,
|
|
109
|
+
}
|
|
110
|
+
);
|
|
111
|
+
const reverseHoloBGP: BindGroupPair[] = BGP;
|
|
112
|
+
reverseHoloBGP.push(
|
|
113
|
+
createBindGroupPair(maskTextureBindGroupLayout, reverseHoloBindGroup)
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
let reverseHoloPipeline = root['~unstable']
|
|
117
|
+
.withVertex(mainVertex, {})
|
|
118
|
+
.withFragment(
|
|
119
|
+
reverseHoloFragment,
|
|
120
|
+
getDefaultTarget(presentationFormat, blend)
|
|
121
|
+
)
|
|
122
|
+
.createPipeline();
|
|
123
|
+
reverseHoloPipeline = attachBindGroups(reverseHoloPipeline, reverseHoloBGP);
|
|
124
|
+
|
|
125
|
+
return reverseHoloPipeline;
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
export const createRainbowHoloPipeline = (
|
|
129
|
+
root: TgpuRoot,
|
|
130
|
+
texture: TgpuTexture | null,
|
|
131
|
+
BGP: BindGroupPair[],
|
|
132
|
+
sampler: GPUSampler,
|
|
133
|
+
presentationFormat: GPUTextureFormat
|
|
134
|
+
): TgpuRenderPipeline | null => {
|
|
135
|
+
if (!texture) return null;
|
|
136
|
+
|
|
137
|
+
const imageTextureBindGroup = root.createBindGroup(textureBindGroupLayout, {
|
|
138
|
+
texture: root.unwrap(texture).createView(),
|
|
139
|
+
sampler,
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
const texBGP = createBindGroupPair(
|
|
143
|
+
textureBindGroupLayout,
|
|
144
|
+
imageTextureBindGroup
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
let rainbowHoloPipeline = root['~unstable']
|
|
148
|
+
.with(waveCallbackSlot, waveCallbackFn(WAVE_CALLBACKS.default))
|
|
149
|
+
.withVertex(mainVertex, {})
|
|
150
|
+
.withFragment(holoFragment, getDefaultTarget(presentationFormat, blend))
|
|
151
|
+
.createPipeline();
|
|
152
|
+
|
|
153
|
+
rainbowHoloPipeline = attachBindGroups(rainbowHoloPipeline, [...BGP, texBGP]);
|
|
154
|
+
return rainbowHoloPipeline;
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
export const pipelineRenderFunction = (
|
|
158
|
+
root: TgpuRoot,
|
|
159
|
+
pipelines: TgpuRenderPipeline[],
|
|
160
|
+
attachments: any[],
|
|
161
|
+
view: GPUTextureView,
|
|
162
|
+
isInSinglePass: boolean
|
|
163
|
+
) => {
|
|
164
|
+
if (isInSinglePass) {
|
|
165
|
+
root['~unstable'].beginRenderPass(
|
|
166
|
+
{
|
|
167
|
+
colorAttachments: [
|
|
168
|
+
{
|
|
169
|
+
view: view,
|
|
170
|
+
clearValue: [0, 0, 0, 0],
|
|
171
|
+
loadOp: 'clear',
|
|
172
|
+
storeOp: 'store',
|
|
173
|
+
},
|
|
174
|
+
],
|
|
175
|
+
},
|
|
176
|
+
(pass) => {
|
|
177
|
+
for (let i = 0; i < pipelines.length; i++) {
|
|
178
|
+
pass.setPipeline(pipelines[i]!);
|
|
179
|
+
pass.draw(6);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
);
|
|
183
|
+
root['~unstable'].flush();
|
|
184
|
+
} else {
|
|
185
|
+
for (let i = 0; i < pipelines.length; i++) {
|
|
186
|
+
const attachment = attachments[i];
|
|
187
|
+
if (!attachment) return;
|
|
188
|
+
pipelines[i]!.withColorAttachment(attachment).draw(6);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
};
|
|
@@ -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,30 @@
|
|
|
1
|
+
import { type TgpuRoot, type TgpuTexture } from 'typegpu';
|
|
2
|
+
|
|
3
|
+
export const createTexture = async (
|
|
4
|
+
root: TgpuRoot,
|
|
5
|
+
size: {
|
|
6
|
+
width: number;
|
|
7
|
+
height: number;
|
|
8
|
+
}
|
|
9
|
+
): Promise<TgpuTexture> => {
|
|
10
|
+
const texture = root['~unstable']
|
|
11
|
+
.createTexture({
|
|
12
|
+
size: [size.width, size.height],
|
|
13
|
+
format: 'rgba8unorm',
|
|
14
|
+
})
|
|
15
|
+
.$usage('sampled', 'render');
|
|
16
|
+
|
|
17
|
+
return texture;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const loadTexture = async (
|
|
21
|
+
root: TgpuRoot,
|
|
22
|
+
imageBitmap: ImageBitmap,
|
|
23
|
+
texture: TgpuTexture
|
|
24
|
+
) => {
|
|
25
|
+
root.device.queue.copyExternalImageToTexture(
|
|
26
|
+
{ source: imageBitmap },
|
|
27
|
+
{ texture: root.unwrap(texture) },
|
|
28
|
+
[imageBitmap.width, imageBitmap.height]
|
|
29
|
+
);
|
|
30
|
+
};
|
package/src/shaders/tgpuUtils.ts
CHANGED
|
@@ -33,7 +33,7 @@ export const hueShift = tgpu.fn(
|
|
|
33
33
|
return d.vec3f(r, g, b);
|
|
34
34
|
});
|
|
35
35
|
|
|
36
|
-
export const
|
|
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
|
+
});
|
package/src/shaders/utils.ts
CHANGED
|
@@ -1,36 +1,6 @@
|
|
|
1
|
-
import { type TgpuRoot, type TgpuTexture } from 'typegpu';
|
|
2
1
|
import type { quaternion, vec3 } from '../types/types';
|
|
3
2
|
import { Dimensions } from 'react-native';
|
|
4
3
|
|
|
5
|
-
export const createTexture = async (
|
|
6
|
-
root: TgpuRoot,
|
|
7
|
-
size: {
|
|
8
|
-
width: number;
|
|
9
|
-
height: number;
|
|
10
|
-
}
|
|
11
|
-
): Promise<TgpuTexture> => {
|
|
12
|
-
const texture = root['~unstable']
|
|
13
|
-
.createTexture({
|
|
14
|
-
size: [size.width, size.height],
|
|
15
|
-
format: 'rgba8unorm',
|
|
16
|
-
})
|
|
17
|
-
.$usage('sampled', 'render');
|
|
18
|
-
|
|
19
|
-
return texture;
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
export const loadTexture = async (
|
|
23
|
-
root: TgpuRoot,
|
|
24
|
-
imageBitmap: ImageBitmap,
|
|
25
|
-
texture: TgpuTexture
|
|
26
|
-
) => {
|
|
27
|
-
root.device.queue.copyExternalImageToTexture(
|
|
28
|
-
{ source: imageBitmap },
|
|
29
|
-
{ texture: root.unwrap(texture) },
|
|
30
|
-
[imageBitmap.width, imageBitmap.height]
|
|
31
|
-
);
|
|
32
|
-
};
|
|
33
|
-
|
|
34
4
|
export const rotateVectorByQuaternion = (
|
|
35
5
|
vec: vec3,
|
|
36
6
|
quaternion: quaternion
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import tgpu from 'typegpu';
|
|
2
|
+
import * as std from 'typegpu/std';
|
|
3
|
+
import * as d from 'typegpu/data';
|
|
4
|
+
import { rotationValuesBindGroupLayout } from '../bindGroupLayouts';
|
|
5
|
+
|
|
6
|
+
const mainRotationEffectVertex = tgpu['~unstable'].vertexFn({
|
|
7
|
+
in: { vertexIndex: d.builtin.vertexIndex },
|
|
8
|
+
out: { position: d.builtin.position, uv: d.vec2f },
|
|
9
|
+
})((input) => {
|
|
10
|
+
const rot = rotationValuesBindGroupLayout.$.vec;
|
|
11
|
+
|
|
12
|
+
// Maximum rotation angles in radians
|
|
13
|
+
const maxAngle = d.f32((25.0 * Math.PI) / 180.0);
|
|
14
|
+
const ax = d.f32(-rot.y * maxAngle); // rotateX depends on vertical touch
|
|
15
|
+
const ay = d.f32(-rot.x * 1.0); // rotateY depends on horizontal touch
|
|
16
|
+
|
|
17
|
+
const positions: d.v2f[] = [
|
|
18
|
+
d.vec2f(-1.0, -1.0),
|
|
19
|
+
d.vec2f(1.0, 1.0),
|
|
20
|
+
d.vec2f(1.0, -1.0),
|
|
21
|
+
d.vec2f(-1.0, -1.0),
|
|
22
|
+
d.vec2f(-1.0, 1.0),
|
|
23
|
+
d.vec2f(1.0, 1.0),
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
const uvs: d.v2f[] = [
|
|
27
|
+
d.vec2f(0.0, 0.0),
|
|
28
|
+
d.vec2f(1.0, 1.0),
|
|
29
|
+
d.vec2f(1.0, 0.0),
|
|
30
|
+
d.vec2f(0.0, 0.0),
|
|
31
|
+
d.vec2f(0.0, 1.0),
|
|
32
|
+
d.vec2f(1.0, 1.0),
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
const index = input.vertexIndex;
|
|
36
|
+
const pos = d.vec3f(positions[index] as d.v2f, 0.0);
|
|
37
|
+
|
|
38
|
+
const pivot = d.vec3f(rot.x, rot.y, 0.0);
|
|
39
|
+
|
|
40
|
+
const relative = std.sub(pos, pivot);
|
|
41
|
+
const cosX = std.cos(ax);
|
|
42
|
+
const sinX = std.sin(ax);
|
|
43
|
+
const rotatedX = d.vec3f(
|
|
44
|
+
relative.x,
|
|
45
|
+
cosX * relative.y - sinX * relative.z,
|
|
46
|
+
sinX * relative.y + cosX * relative.z
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
const cosY = std.cos(ay);
|
|
50
|
+
const sinY = std.sin(ay);
|
|
51
|
+
const rotatedXY = d.vec3f(
|
|
52
|
+
cosY * rotatedX.x + sinY * rotatedX.z,
|
|
53
|
+
rotatedX.y,
|
|
54
|
+
-sinY * rotatedX.x + cosY * rotatedX.z
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
const finalPos3D = std.add(rotatedXY, pivot);
|
|
58
|
+
const perspective = 100.0;
|
|
59
|
+
const zOffset = 2.5;
|
|
60
|
+
const z = finalPos3D.z + zOffset;
|
|
61
|
+
const persp = perspective / (perspective + z);
|
|
62
|
+
|
|
63
|
+
const finalPos = d.vec4f(
|
|
64
|
+
finalPos3D.x * persp,
|
|
65
|
+
finalPos3D.y * persp,
|
|
66
|
+
0.0,
|
|
67
|
+
1.0
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
return {
|
|
71
|
+
position: finalPos,
|
|
72
|
+
uv: uvs[index] as d.v2f,
|
|
73
|
+
};
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
export default mainRotationEffectVertex;
|
package/src/types/typeUtils.ts
CHANGED
|
@@ -1,36 +1,38 @@
|
|
|
1
1
|
import { f32, vec2f, vec3f, vec4f } from 'typegpu/data';
|
|
2
2
|
import type {
|
|
3
3
|
BindGroupPair,
|
|
4
|
-
|
|
4
|
+
GlareOptions,
|
|
5
5
|
ColorMask,
|
|
6
6
|
DeepPartiallyOptional,
|
|
7
7
|
vec3,
|
|
8
|
+
HoloOptions,
|
|
8
9
|
} from './types';
|
|
9
10
|
import { div } from 'typegpu/std';
|
|
10
11
|
import type { TgpuBindGroup, TgpuBindGroupLayout } from 'typegpu';
|
|
12
|
+
import { WAVE_CALLBACKS } from '../enums/waveCallback';
|
|
11
13
|
|
|
12
|
-
export const
|
|
13
|
-
options: Partial<
|
|
14
|
-
):
|
|
14
|
+
export const createGlareOptions = (
|
|
15
|
+
options: Partial<GlareOptions>
|
|
16
|
+
): GlareOptions => {
|
|
15
17
|
const {
|
|
16
18
|
glowPower,
|
|
17
19
|
hueShiftAngleMax,
|
|
18
20
|
hueShiftAngleMin,
|
|
19
21
|
hueBlendPower,
|
|
20
22
|
lightIntensity,
|
|
21
|
-
|
|
23
|
+
glareIntensity,
|
|
22
24
|
} = options;
|
|
23
25
|
|
|
24
|
-
const
|
|
26
|
+
const glareOp = {
|
|
25
27
|
glowPower: glowPower ?? 1.0,
|
|
26
28
|
hueShiftAngleMax: hueShiftAngleMax ?? 1.0,
|
|
27
29
|
hueShiftAngleMin: hueShiftAngleMin ?? 0.0,
|
|
28
30
|
hueBlendPower: hueBlendPower ?? 1.0,
|
|
29
31
|
lightIntensity: lightIntensity ?? 1.0,
|
|
30
|
-
|
|
32
|
+
glareIntensity: glareIntensity ?? 1.0,
|
|
31
33
|
};
|
|
32
34
|
|
|
33
|
-
return
|
|
35
|
+
return glareOp;
|
|
34
36
|
};
|
|
35
37
|
|
|
36
38
|
export const mapToF32 = <T extends Record<string, number>>(
|
|
@@ -75,6 +77,18 @@ export const colorMaskToTyped = (colorMask: ColorMask) => {
|
|
|
75
77
|
return result;
|
|
76
78
|
};
|
|
77
79
|
|
|
80
|
+
export const createHoloOptions = (
|
|
81
|
+
options: Partial<HoloOptions>
|
|
82
|
+
): HoloOptions => {
|
|
83
|
+
const { intensity, waveCallback } = options;
|
|
84
|
+
const holoOpt = {
|
|
85
|
+
intensity: intensity ?? 0.7,
|
|
86
|
+
waveCallback: waveCallback ?? WAVE_CALLBACKS.default,
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
return holoOpt;
|
|
90
|
+
};
|
|
91
|
+
|
|
78
92
|
export const numberArrToTyped = (vec: number[]) => {
|
|
79
93
|
let convFn: ((...args: number[]) => any) | null = null;
|
|
80
94
|
switch (vec.length) {
|