Back to Home

ESO Lua File v101044

libraries/zo_visualeffects/zo_flickereffect.lua

[◄ back to folders ]
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
134
135
136
137
138
139
140
141
142
143
144
--[[
-- Apply a flicker effect to the specified Texture control that simulates the
-- "random" dimming and brightening that is characteristic of a wax candle.
local SPEED_MULTIPLIER = 1.0 -- Flicker speed multiplier (ex: 0.5x, 1.0x or 2.0x speed)
local ALPHA_STRENGTH = 0.5 -- Maximum percentage reduction of the texture alpha (fading)
local COLOR_STRENGTH = 0.25 -- Maximum percentage reduction of the texture color (dimming)
FLICKER_EFFECT:RegisterControl(myTextureControl, SPEED_MULTIPLIER, ALPHA_STRENGTH, COLOR_STRENGTH)
]]
local VALID_CONTROL_TYPES =
{
    [CT_TEXTURE] = true
}
local VERTICES =
{
    VERTEX_POINTS_TOPLEFT,
    VERTEX_POINTS_TOPRIGHT,
    VERTEX_POINTS_BOTTOMLEFT,
    VERTEX_POINTS_BOTTOMRIGHT,
}
local NUM_VERTICES = #VERTICES
local CONTROL_POINTS =
{
    {
        offset = 0.0,
        coefficient = ZO_PI * 0.7,
    },
    {
        offset = ZO_HALF_PI,
        coefficient = ZO_PI,
    },
    {
        offset = ZO_PI,
        coefficient = ZO_PI,
    },
    {
        offset = ZO_HALF_PI * 3,
        coefficient = ZO_PI * 1.2,
    },
}
local NUM_CONTROL_POINTS = #CONTROL_POINTS
ZO_FlickerEffect = ZO_BaseVisualEffect:Subclass()
function ZO_FlickerEffect:Initialize(...)
    ZO_BaseVisualEffect.Initialize(self, ...)
    self.controlPoints = {}
    self.vertexInterpolants = {}
end
-- These are the optional arguments that can be passed to RegisterControl.
function ZO_FlickerEffect:CreateParameterTable(control, speedMultiplier, alphaFlickerStrength, colorFlickerStrength, maxGaussianBlurFactor, baseColor)
    local parameterTable = {}
    parameterTable.speedMultiplier = zo_clamp(speedMultiplier or 0.5, 0, 1)
    parameterTable.minAlphaCoefficient = zo_clamp(1 - (alphaFlickerStrength or 0.5), 0, 1)
    parameterTable.maxAlphaCoefficient = 1
    parameterTable.minColorCoefficient = zo_clamp(1 - (colorFlickerStrength or 0.5), 0, 1)
    parameterTable.maxColorCoefficient = 1
    parameterTable.maxGaussianBlurFactor = maxGaussianBlurFactor or 0
    parameterTable.baseColor = baseColor
    return parameterTable
end
function ZO_FlickerEffect:GetEffectName()
    return "ZO_FlickerEffect"
end
function ZO_FlickerEffect:GetValidControlTypes()
    return VALID_CONTROL_TYPES
end
function ZO_FlickerEffect:OnUpdate(frameTimeMs)
    local frameTimeS = frameTimeMs * 0.001
    -- Calculate the Fourier series control points to be combined using varied sets of coefficients
    -- and normalize the resulting sine values from [-1, 1] to [0, 1]; repeat for the upper bound speed.
    local numControlPoints = NUM_CONTROL_POINTS
    local controlPoints = self.controlPoints
    for controlPointIndex, controlPointInfo in ipairs(CONTROL_POINTS) do
        local offset = controlPointInfo.offset
        local coefficient = controlPointInfo.coefficient * frameTimeS
        controlPoints[controlPointIndex] = zo_sin(offset + coefficient) * 0.5 + 0.5
        controlPoints[controlPointIndex + numControlPoints] = zo_sin(offset * 2 + coefficient * 2) * 0.5 + 0.5
    end
    -- Apply the effect to all registered controls in the order in which they were
    -- registered (for animation consistency); repeat for the upper bound speed.
    local vertexInterpolants = self.vertexInterpolants
    for controlIndex, control in ipairs(self.controls) do
        local parameters = self.controlParameters[control]
        local baseR, baseG, baseB, baseA = parameters.baseColor:UnpackRGBA()
        -- Premultiply the vertex interpolants to match the requested flicker "speed."
        for vertexIndex, vertexPoint in ipairs(VERTICES) do
            vertexInterpolants[vertexIndex] = zo_lerp(controlPoints[vertexIndex], controlPoints[vertexIndex + numControlPoints], parameters.speedMultiplier)
        end
        -- Apply the vertex interpolants, interpreted as color and/or alpha coefficients,
        -- to the vertices of this registered control.
        local vertexInterpolantIndexOffset = controlIndex * 3
        local vertexInterpolantSum = 0
        for vertexIndex, vertexPoint in ipairs(VERTICES) do
            local vertexInterpolantIndex = ((vertexIndex + vertexInterpolantIndexOffset) % numControlPoints) + 1
            local vertexInterpolant = vertexInterpolants[vertexInterpolantIndex]
            vertexInterpolantSum = vertexInterpolantSum + vertexInterpolant
            local alphaCoefficient = zo_lerp(parameters.minAlphaCoefficient, parameters.maxAlphaCoefficient, vertexInterpolant)
            local colorCoefficient = zo_lerp(parameters.minColorCoefficient, parameters.maxColorCoefficient, vertexInterpolant)
            local r, g, b, a = baseR * colorCoefficient, baseG * colorCoefficient, baseB * colorCoefficient, baseA * alphaCoefficient
            control:SetVertexColors(vertexPoint, r, g, b, a)
        end
        if parameters.maxGaussianBlurFactor > 0 then
            -- Scale the control's Gaussian blur factor in proportion to the average "brightness."
            local averageVertexInterpolant = vertexInterpolantSum / NUM_VERTICES
            local kernelSize = control:GetGaussianBlur()
            local blurFactor = zo_lerp(0, parameters.maxGaussianBlurFactor, ZO_EaseInQuartic(averageVertexInterpolant))
            control:SetGaussianBlur(kernelSize, blurFactor)
        end
    end
end
-- Effect Specific Methods
function ZO_FlickerEffect:SetControlBaseColor(control, baseColor)
    local parameters = self:GetControlParameters(control)
    if parameters then
        parameters.baseColor = baseColor
    end
end
function ZO_FlickerEffect:SetAlphaAndColorFlickerStrength(control, alphaFlickerStrength, colorFlickerStrength)
    local parameters = self:GetControlParameters(control)
    if parameters then
        parameters.alphaFlickerStrength = alphaFlickerStrength
        parameters.colorFlickerStrength = colorFlickerStrength
    end
end
FLICKER_EFFECT = ZO_FlickerEffect:New()