@quenty/depthoffield 11.19.0 → 11.19.1-canary.545.2374fb2.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/CHANGELOG.md +11 -0
- package/package.json +17 -17
- package/src/Client/DepthOfFieldEffect.lua +123 -57
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,17 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [11.19.1-canary.545.2374fb2.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/depthoffield@11.19.0...@quenty/depthoffield@11.19.1-canary.545.2374fb2.0) (2025-04-05)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* Add types to packages ([2374fb2](https://github.com/Quenty/NevermoreEngine/commit/2374fb2b043cfbe0e9b507b3316eec46a4e353a0))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
6
17
|
# [11.19.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/depthoffield@11.18.2...@quenty/depthoffield@11.19.0) (2025-04-02)
|
|
7
18
|
|
|
8
19
|
**Note:** Version bump only for package @quenty/depthoffield
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quenty/depthoffield",
|
|
3
|
-
"version": "11.19.0",
|
|
3
|
+
"version": "11.19.1-canary.545.2374fb2.0",
|
|
4
4
|
"description": "Depth of field service to allow multiple systems to write depth of field",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Roblox",
|
|
@@ -25,24 +25,24 @@
|
|
|
25
25
|
"Quenty"
|
|
26
26
|
],
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@quenty/acceltween": "
|
|
29
|
-
"@quenty/attributeutils": "
|
|
30
|
-
"@quenty/baseobject": "
|
|
31
|
-
"@quenty/basicpane": "
|
|
32
|
-
"@quenty/blend": "
|
|
33
|
-
"@quenty/brio": "
|
|
34
|
-
"@quenty/instanceutils": "
|
|
35
|
-
"@quenty/loader": "
|
|
36
|
-
"@quenty/maid": "
|
|
37
|
-
"@quenty/math": "
|
|
38
|
-
"@quenty/rx": "
|
|
39
|
-
"@quenty/signal": "
|
|
40
|
-
"@quenty/steputils": "
|
|
41
|
-
"@quenty/transitionmodel": "
|
|
42
|
-
"@quenty/valueobject": "
|
|
28
|
+
"@quenty/acceltween": "2.5.1-canary.545.2374fb2.0",
|
|
29
|
+
"@quenty/attributeutils": "14.17.1-canary.545.2374fb2.0",
|
|
30
|
+
"@quenty/baseobject": "10.8.1-canary.545.2374fb2.0",
|
|
31
|
+
"@quenty/basicpane": "13.17.1-canary.545.2374fb2.0",
|
|
32
|
+
"@quenty/blend": "12.18.1-canary.545.2374fb2.0",
|
|
33
|
+
"@quenty/brio": "14.17.1-canary.545.2374fb2.0",
|
|
34
|
+
"@quenty/instanceutils": "13.17.1-canary.545.2374fb2.0",
|
|
35
|
+
"@quenty/loader": "10.8.1-canary.545.2374fb2.0",
|
|
36
|
+
"@quenty/maid": "3.4.1-canary.545.2374fb2.0",
|
|
37
|
+
"@quenty/math": "2.7.2-canary.545.2374fb2.0",
|
|
38
|
+
"@quenty/rx": "13.17.1-canary.545.2374fb2.0",
|
|
39
|
+
"@quenty/signal": "7.10.1-canary.545.2374fb2.0",
|
|
40
|
+
"@quenty/steputils": "3.5.4-canary.545.2374fb2.0",
|
|
41
|
+
"@quenty/transitionmodel": "7.19.1-canary.545.2374fb2.0",
|
|
42
|
+
"@quenty/valueobject": "13.17.1-canary.545.2374fb2.0"
|
|
43
43
|
},
|
|
44
44
|
"publishConfig": {
|
|
45
45
|
"access": "public"
|
|
46
46
|
},
|
|
47
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "2374fb2b043cfbe0e9b507b3316eec46a4e353a0"
|
|
48
48
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
--!strict
|
|
1
2
|
--[=[
|
|
2
3
|
Handles interpolation of depth of field, which is tricky due to how Roblox implemented the shader
|
|
3
4
|
and how it interacts with other depth of field effects.
|
|
@@ -22,12 +23,25 @@ local SpringTransitionModel = require("SpringTransitionModel")
|
|
|
22
23
|
local TransitionModel = require("TransitionModel")
|
|
23
24
|
local ValueObject = require("ValueObject")
|
|
24
25
|
local RxAttributeUtils = require("RxAttributeUtils")
|
|
26
|
+
local _Brio = require("Brio")
|
|
25
27
|
|
|
26
28
|
local DepthOfFieldEffect = setmetatable({}, TransitionModel)
|
|
27
29
|
DepthOfFieldEffect.ClassName = "DepthOfFieldEffect"
|
|
28
30
|
DepthOfFieldEffect.__index = DepthOfFieldEffect
|
|
29
31
|
|
|
30
|
-
|
|
32
|
+
export type DepthOfFieldEffect = typeof(setmetatable(
|
|
33
|
+
{} :: {
|
|
34
|
+
_depthOfField: Instance,
|
|
35
|
+
_focusDistanceSpring: SpringObject.SpringObject<number>,
|
|
36
|
+
_inFocusRadiusSpring: SpringObject.SpringObject<number>,
|
|
37
|
+
_nearIntensitySpring: SpringObject.SpringObject<number>,
|
|
38
|
+
_farIntensitySpring: SpringObject.SpringObject<number>,
|
|
39
|
+
_percentVisibleModel: SpringTransitionModel.SpringTransitionModel<number>,
|
|
40
|
+
},
|
|
41
|
+
DepthOfFieldEffect
|
|
42
|
+
))
|
|
43
|
+
|
|
44
|
+
function DepthOfFieldEffect.new(): DepthOfFieldEffect
|
|
31
45
|
local self = setmetatable(TransitionModel.new(), DepthOfFieldEffect)
|
|
32
46
|
|
|
33
47
|
self._focusDistanceSpring = self._maid:Add(SpringObject.new(40, 30))
|
|
@@ -58,7 +72,7 @@ function DepthOfFieldEffect.new()
|
|
|
58
72
|
return self
|
|
59
73
|
end
|
|
60
74
|
|
|
61
|
-
function DepthOfFieldEffect:SetShowSpeed(speed)
|
|
75
|
+
function DepthOfFieldEffect:SetShowSpeed(speed: number)
|
|
62
76
|
self._percentVisibleModel:SetSpeed(speed)
|
|
63
77
|
end
|
|
64
78
|
|
|
@@ -67,7 +81,7 @@ end
|
|
|
67
81
|
@param focusDistanceTarget number
|
|
68
82
|
@param doNotAnimate boolean
|
|
69
83
|
]=]
|
|
70
|
-
function DepthOfFieldEffect:SetFocusDistanceTarget(focusDistanceTarget, doNotAnimate)
|
|
84
|
+
function DepthOfFieldEffect:SetFocusDistanceTarget(focusDistanceTarget: number, doNotAnimate: boolean?)
|
|
71
85
|
assert(type(focusDistanceTarget) == "number", "Bad focusDistanceTarget")
|
|
72
86
|
|
|
73
87
|
self._focusDistanceSpring:SetTarget(focusDistanceTarget, doNotAnimate)
|
|
@@ -78,7 +92,7 @@ end
|
|
|
78
92
|
@param inFocusRadiusTarget number
|
|
79
93
|
@param doNotAnimate boolean
|
|
80
94
|
]=]
|
|
81
|
-
function DepthOfFieldEffect:SetInFocusRadiusTarget(inFocusRadiusTarget, doNotAnimate)
|
|
95
|
+
function DepthOfFieldEffect:SetInFocusRadiusTarget(inFocusRadiusTarget: number, doNotAnimate: boolean?)
|
|
82
96
|
assert(type(inFocusRadiusTarget) == "number", "Bad inFocusRadiusTarget")
|
|
83
97
|
|
|
84
98
|
self._inFocusRadiusSpring:SetTarget(inFocusRadiusTarget, doNotAnimate)
|
|
@@ -89,7 +103,7 @@ end
|
|
|
89
103
|
@param nearIntensityTarget number
|
|
90
104
|
@param doNotAnimate boolean
|
|
91
105
|
]=]
|
|
92
|
-
function DepthOfFieldEffect:SetNearIntensityTarget(nearIntensityTarget, doNotAnimate)
|
|
106
|
+
function DepthOfFieldEffect:SetNearIntensityTarget(nearIntensityTarget: number, doNotAnimate: boolean?)
|
|
93
107
|
assert(type(nearIntensityTarget) == "number", "Bad nearIntensityTarget")
|
|
94
108
|
|
|
95
109
|
self._nearIntensitySpring:SetTarget(nearIntensityTarget, doNotAnimate)
|
|
@@ -100,7 +114,7 @@ end
|
|
|
100
114
|
@param farIntensityTarget number
|
|
101
115
|
@param doNotAnimate boolean
|
|
102
116
|
]=]
|
|
103
|
-
function DepthOfFieldEffect:SetFarIntensityTarget(farIntensityTarget, doNotAnimate)
|
|
117
|
+
function DepthOfFieldEffect:SetFarIntensityTarget(farIntensityTarget: number, doNotAnimate: boolean?)
|
|
104
118
|
assert(type(farIntensityTarget) == "number", "Bad farIntensityTarget")
|
|
105
119
|
|
|
106
120
|
self._farIntensitySpring:SetTarget(farIntensityTarget, doNotAnimate)
|
|
@@ -110,7 +124,7 @@ end
|
|
|
110
124
|
Retrieves the distance target
|
|
111
125
|
@return number
|
|
112
126
|
]=]
|
|
113
|
-
function DepthOfFieldEffect:GetFocusDistanceTarget()
|
|
127
|
+
function DepthOfFieldEffect:GetFocusDistanceTarget(): number
|
|
114
128
|
return self._focusDistanceSpring.Target
|
|
115
129
|
end
|
|
116
130
|
|
|
@@ -118,7 +132,7 @@ end
|
|
|
118
132
|
Retrieves the radius target
|
|
119
133
|
@return number
|
|
120
134
|
]=]
|
|
121
|
-
function DepthOfFieldEffect:GetInFocusRadiusTarget()
|
|
135
|
+
function DepthOfFieldEffect:GetInFocusRadiusTarget(): number
|
|
122
136
|
return self._inFocusRadiusSpring.Target
|
|
123
137
|
end
|
|
124
138
|
|
|
@@ -126,7 +140,7 @@ end
|
|
|
126
140
|
Retrieve the near intensity target
|
|
127
141
|
@return number
|
|
128
142
|
]=]
|
|
129
|
-
function DepthOfFieldEffect:GetNearIntensityTarget()
|
|
143
|
+
function DepthOfFieldEffect:GetNearIntensityTarget(): number
|
|
130
144
|
return self._nearIntensitySpring.Target
|
|
131
145
|
end
|
|
132
146
|
|
|
@@ -134,7 +148,7 @@ end
|
|
|
134
148
|
Retrieve the far intensity target
|
|
135
149
|
@return number
|
|
136
150
|
]=]
|
|
137
|
-
function DepthOfFieldEffect:GetFarIntensityTarget()
|
|
151
|
+
function DepthOfFieldEffect:GetFarIntensityTarget(): number
|
|
138
152
|
return self._farIntensitySpring.Target
|
|
139
153
|
end
|
|
140
154
|
|
|
@@ -143,11 +157,11 @@ function DepthOfFieldEffect:_render()
|
|
|
143
157
|
-- state towards zero. The only issue is `InFocusRadius` must be rendered at target of 500 to fade "out" the effect
|
|
144
158
|
-- if other
|
|
145
159
|
|
|
146
|
-
return Blend.New
|
|
147
|
-
Name = "DepthOfField"
|
|
160
|
+
return Blend.New("DepthOfFieldEffect")({
|
|
161
|
+
Name = "DepthOfField",
|
|
148
162
|
Enabled = Blend.Computed(self._percentVisibleModel, function(visible)
|
|
149
163
|
return visible > 0
|
|
150
|
-
end)
|
|
164
|
+
end),
|
|
151
165
|
FocusDistance = Blend.Computed(
|
|
152
166
|
self._percentVisibleModel,
|
|
153
167
|
self._focusDistanceSpring,
|
|
@@ -161,7 +175,8 @@ function DepthOfFieldEffect:_render()
|
|
|
161
175
|
end
|
|
162
176
|
|
|
163
177
|
return Math.map(percentVisible, 0, 1, externalFocusDistance, focusDistance)
|
|
164
|
-
end
|
|
178
|
+
end
|
|
179
|
+
),
|
|
165
180
|
InFocusRadius = Blend.Computed(
|
|
166
181
|
self._percentVisibleModel,
|
|
167
182
|
self._inFocusRadiusSpring,
|
|
@@ -179,32 +194,77 @@ function DepthOfFieldEffect:_render()
|
|
|
179
194
|
end
|
|
180
195
|
|
|
181
196
|
return Math.map(percentVisible, 0, 1, externalInFocusRadius, inFocusRadius)
|
|
182
|
-
end
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
197
|
+
end
|
|
198
|
+
),
|
|
199
|
+
NearIntensity = Blend.Computed(
|
|
200
|
+
self._percentVisibleModel,
|
|
201
|
+
self._nearIntensitySpring,
|
|
202
|
+
function(percentVisible, intensity)
|
|
203
|
+
return Math.map(percentVisible, 0, 1, 0, intensity)
|
|
204
|
+
end
|
|
205
|
+
),
|
|
206
|
+
FarIntensity = Blend.Computed(
|
|
207
|
+
self._percentVisibleModel,
|
|
208
|
+
self._farIntensitySpring,
|
|
209
|
+
function(percentVisible, intensity)
|
|
210
|
+
return Math.map(percentVisible, 0, 1, 0, intensity)
|
|
211
|
+
end
|
|
212
|
+
),
|
|
189
213
|
[Blend.Instance] = function(gui)
|
|
190
214
|
self._depthOfField = gui
|
|
191
215
|
|
|
192
216
|
-- Setup attributes so multiple tweening depth off fields with this system isn't sad
|
|
193
|
-
self._maid:GiveTask(
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
217
|
+
self._maid:GiveTask(
|
|
218
|
+
Blend.Computed(
|
|
219
|
+
self._percentVisibleModel,
|
|
220
|
+
self._inFocusRadiusSpring,
|
|
221
|
+
function(percentVisible, inFocusRadius)
|
|
222
|
+
return Math.map(percentVisible, 0, 1, 0, inFocusRadius)
|
|
223
|
+
end
|
|
224
|
+
)
|
|
225
|
+
:Subscribe(function(targetDepthOfFieldRadius)
|
|
226
|
+
self._depthOfField:SetAttribute(
|
|
227
|
+
"DepthOfFieldEffect_TargetInFocusRadius",
|
|
228
|
+
targetDepthOfFieldRadius
|
|
229
|
+
)
|
|
230
|
+
end)
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
self._maid:GiveTask(
|
|
234
|
+
Blend.Computed(
|
|
235
|
+
self._percentVisibleModel,
|
|
236
|
+
self._focusDistanceSpring,
|
|
237
|
+
function(percentVisible, focusDistance)
|
|
238
|
+
return Math.map(percentVisible, 0, 1, 0, focusDistance)
|
|
239
|
+
end
|
|
240
|
+
)
|
|
241
|
+
:Subscribe(function(targetDepthOfFieldRadius)
|
|
242
|
+
self._depthOfField:SetAttribute(
|
|
243
|
+
"DepthOfFieldEffect_TargetFocusDistance",
|
|
244
|
+
targetDepthOfFieldRadius
|
|
245
|
+
)
|
|
246
|
+
end)
|
|
247
|
+
)
|
|
248
|
+
end,
|
|
249
|
+
})
|
|
206
250
|
end
|
|
207
251
|
|
|
252
|
+
type OutputState = {
|
|
253
|
+
enabled: boolean?,
|
|
254
|
+
inFocusRadius: number?,
|
|
255
|
+
focusDistance: number?,
|
|
256
|
+
externalCount: number?,
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
type DepthOfFieldState = {
|
|
260
|
+
inFocusRadius: number,
|
|
261
|
+
focusDistance: number,
|
|
262
|
+
targetInFocusRadius: number,
|
|
263
|
+
targetFocusDistance: number,
|
|
264
|
+
enabled: boolean,
|
|
265
|
+
depthOfField: DepthOfFieldEffect?,
|
|
266
|
+
}
|
|
267
|
+
|
|
208
268
|
function DepthOfFieldEffect:_observeRenderedDepthOfFieldState()
|
|
209
269
|
if self._observeOtherStates then
|
|
210
270
|
return self._observeOtherStates
|
|
@@ -213,25 +273,25 @@ function DepthOfFieldEffect:_observeRenderedDepthOfFieldState()
|
|
|
213
273
|
self._observeOtherStates = Observable.new(function(sub)
|
|
214
274
|
local topMaid = Maid.new()
|
|
215
275
|
|
|
216
|
-
local result = topMaid:Add(ValueObject.new(nil))
|
|
276
|
+
local result: ValueObject.ValueObject<OutputState?> = topMaid:Add(ValueObject.new(nil))
|
|
217
277
|
|
|
218
|
-
local latestStates = {}
|
|
278
|
+
local latestStates: { [Maid.Maid]: DepthOfFieldState } = {}
|
|
219
279
|
|
|
220
280
|
local function update()
|
|
221
281
|
local output = {
|
|
222
|
-
inFocusRadius = 0
|
|
223
|
-
focusDistance = 0
|
|
224
|
-
externalCount = 0
|
|
282
|
+
inFocusRadius = 0,
|
|
283
|
+
focusDistance = 0,
|
|
284
|
+
externalCount = 0,
|
|
225
285
|
}
|
|
226
286
|
|
|
227
|
-
for _, state in
|
|
287
|
+
for _, state in latestStates do
|
|
228
288
|
if state.depthOfField == self._depthOfField then
|
|
229
289
|
continue
|
|
230
290
|
end
|
|
231
291
|
|
|
232
292
|
if state.enabled then
|
|
233
293
|
output.externalCount += 1
|
|
234
|
-
local inFocusRadius
|
|
294
|
+
local inFocusRadius: number
|
|
235
295
|
if state.targetInFocusRadius then
|
|
236
296
|
inFocusRadius = state.targetInFocusRadius
|
|
237
297
|
else
|
|
@@ -264,16 +324,22 @@ function DepthOfFieldEffect:_observeRenderedDepthOfFieldState()
|
|
|
264
324
|
|
|
265
325
|
local maid, depthOfField = brio:ToMaidAndValue()
|
|
266
326
|
maid:GiveTask(Rx.combineLatest({
|
|
267
|
-
depthOfField = depthOfField
|
|
268
|
-
|
|
269
|
-
inFocusRadius = RxInstanceUtils.observeProperty(depthOfField, "InFocusRadius")
|
|
270
|
-
targetInFocusRadius = RxAttributeUtils.observeAttribute(
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
327
|
+
depthOfField = depthOfField,
|
|
328
|
+
|
|
329
|
+
inFocusRadius = RxInstanceUtils.observeProperty(depthOfField, "InFocusRadius"),
|
|
330
|
+
targetInFocusRadius = RxAttributeUtils.observeAttribute(
|
|
331
|
+
depthOfField,
|
|
332
|
+
"DepthOfFieldEffect_TargetInFocusRadius"
|
|
333
|
+
),
|
|
334
|
+
|
|
335
|
+
focusDistance = RxInstanceUtils.observeProperty(depthOfField, "FocusDistance"),
|
|
336
|
+
targetFocusDistance = RxAttributeUtils.observeAttribute(
|
|
337
|
+
depthOfField,
|
|
338
|
+
"DepthOfFieldEffect_TargetFocusDistance"
|
|
339
|
+
),
|
|
340
|
+
|
|
341
|
+
enabled = RxInstanceUtils.observeProperty(depthOfField, "Enabled"),
|
|
342
|
+
}):Subscribe(function(state: any)
|
|
277
343
|
if state.depthOfField == self._depthOfField then
|
|
278
344
|
latestStates[maid] = nil
|
|
279
345
|
else
|
|
@@ -292,23 +358,23 @@ function DepthOfFieldEffect:_observeRenderedDepthOfFieldState()
|
|
|
292
358
|
|
|
293
359
|
return topMaid
|
|
294
360
|
end):Pipe({
|
|
295
|
-
Rx.cache()
|
|
361
|
+
Rx.cache() :: any,
|
|
296
362
|
})
|
|
297
363
|
|
|
298
364
|
return self._observeOtherStates
|
|
299
365
|
end
|
|
300
366
|
|
|
301
|
-
function DepthOfFieldEffect:_observeAllDepthOfFieldBrio()
|
|
367
|
+
function DepthOfFieldEffect:_observeAllDepthOfFieldBrio(): Observable.Observable<_Brio.Brio<DepthOfFieldEffect>>
|
|
302
368
|
return Rx.merge({
|
|
303
|
-
RxInstanceUtils.observeChildrenOfClassBrio(Lighting, "DepthOfFieldEffect")
|
|
369
|
+
RxInstanceUtils.observeChildrenOfClassBrio(Lighting, "DepthOfFieldEffect") :: any,
|
|
304
370
|
RxInstanceUtils.observePropertyBrio(Workspace, "CurrentCamera", function(camera)
|
|
305
371
|
return camera ~= nil
|
|
306
372
|
end):Pipe({
|
|
307
373
|
RxBrioUtils.flatMapBrio(function(currentCamera)
|
|
308
374
|
return RxInstanceUtils.observeChildrenOfClassBrio(currentCamera, "DepthOfFieldEffect")
|
|
309
|
-
end)
|
|
310
|
-
})
|
|
311
|
-
})
|
|
375
|
+
end),
|
|
376
|
+
}) :: any,
|
|
377
|
+
}) :: any
|
|
312
378
|
end
|
|
313
379
|
|
|
314
380
|
return DepthOfFieldEffect
|