-
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathSampler.ts
133 lines (118 loc) · 3.72 KB
/
Sampler.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import { isRenderer, Renderer } from '../renderers/utils'
import { SamplerBinding } from '../bindings/SamplerBinding'
import { generateUUID, throwWarning } from '../../utils/utils'
import { GPUCurtains } from '../../curtains/GPUCurtains'
/** Options used to create a {@link Sampler} */
export interface SamplerOptions extends Partial<GPUSamplerDescriptor>, GPUSamplerBindingLayout {}
/**
* Parameters used to create a {@link Sampler}
*/
export interface SamplerParams extends SamplerOptions {
/** Name of the {@link Sampler} to use in the {@link SamplerBinding | binding} */
name: string
}
/**
* Used to create a {@link GPUSampler} and its associated {@link SamplerBinding}.
*
* @example
* ```javascript
* // set our main GPUCurtains instance
* const gpuCurtains = new GPUCurtains({
* container: '#canvas' // selector of our WebGPU canvas container
* })
*
* // set the GPU device
* // note this is asynchronous
* await gpuCurtains.setDevice()
*
* const mirrorSampler = new Sampler(gpuCurtains, {
* label: 'Mirror sampler',
* name: 'mirrorSampler',
* addressModeU: 'mirror-repeat',
* addressModeV: 'mirror-repeat',
* })
* ```
*/
export class Sampler {
/** The type of the {@link Sampler} */
type: string
/** The universal unique id of this {@link Sampler} */
readonly uuid: string
/** {@link Renderer} used by this {@link Sampler} */
renderer: Renderer
/** The label of the {@link Sampler}, used to create the {@link GPUSampler} for debugging purpose */
label: string
/** Name of the {@link Sampler} to use in the {@link SamplerBinding | binding} */
name: string
/** Options used to create this {@link Sampler} */
options: SamplerOptions
/** {@link GPUSampler} */
sampler: GPUSampler
/** {@link SamplerBinding | binding} to pass to a {@link core/bindGroups/TextureBindGroup.TextureBindGroup | bind group} */
binding: SamplerBinding
/**
* Sampler constructor
* @param renderer - {@link Renderer} object or {@link GPUCurtains} class object used to create this {@link Sampler}
* @param parameters - {@link SamplerParams | parameters} used to create this {@link Sampler}
*/
constructor(
renderer: GPUCurtains | Renderer,
{
label = 'Sampler',
name,
addressModeU = 'repeat',
addressModeV = 'repeat',
magFilter = 'linear',
minFilter = 'linear',
mipmapFilter = 'linear',
maxAnisotropy = 1,
type = 'filtering',
compare,
} = {} as SamplerParams
) {
this.type = 'Sampler'
this.uuid = generateUUID()
// we could pass our curtains object OR our curtains renderer object
renderer = (renderer && (renderer as GPUCurtains).renderer) || (renderer as Renderer)
isRenderer(renderer, label ? label + ' ' + this.type : this.type)
this.renderer = renderer
this.label = label
if (!name && !this.renderer.production) {
name = 'sampler' + this.renderer.samplers.length
throwWarning(
`Sampler: you are trying to create a sampler without the mandatory name parameter. A default name will be used instead: ${name}`
)
}
this.name = name
this.options = {
addressModeU,
addressModeV,
magFilter,
minFilter,
mipmapFilter,
maxAnisotropy,
type,
...(compare !== undefined && { compare }),
} as SamplerOptions
this.createSampler()
this.createBinding()
}
/**
* Set the {@link GPUSampler}
*/
createSampler() {
this.sampler = this.renderer.createSampler(this)
}
/**
* Set the {@link SamplerBinding | binding}
*/
createBinding() {
this.binding = new SamplerBinding({
label: this.label,
name: this.name,
bindingType: 'sampler',
sampler: this.sampler,
type: this.options.type,
})
}
}