Files
wnsrc/lua/postprocess/frame_blend.lua

225 lines
5.3 KiB
Lua
Raw Normal View History

2024-08-04 22:55:00 +03:00
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
--
-- The number of frames to blend
--
local pp_fb = CreateClientConVar( "pp_fb", "0", false, false )
--
-- The number of frames to blend
--
local pp_fb_frames = CreateClientConVar( "pp_fb_frames", "16", true, false )
--
-- The amount of time the shutter is open. If this is 0.5 then we will blend only
-- 50% of the frames. This is normally 0.5. Lowering it will make it more blurry.
--
local pp_fb_shutter = CreateClientConVar( "pp_fb_shutter", "0.5", true, false )
local FrameCurves = {}
local function FixupCurve( num )
local overflow = num
for k, v in pairs( FrameCurves[ num ] ) do
overflow = overflow - v
end
overflow = overflow * math.Rand( 0, 0.5 )
for i=0, num-1 do
FrameCurves[ num ][ i ] = FrameCurves[ num ][ i ] + ( overflow / num )
end
end
local function FrameCurve( f, num )
if ( FrameCurves[ num ] ) then
return FrameCurves[ num ][ f ]
end
local curve = {}
for i=0, num-1 do
local delta = ( i + 1 ) / num
curve[ i ] = math.sin( delta * math.pi )
end
FrameCurves[ num ] = curve
for i=0, 10 do
FixupCurve( num )
end
return 1.0
end
local texFB = GetRenderTargetEx( "_GMOD_FrameBlend", -1, -1, RT_SIZE_FULL_FRAME_BUFFER, MATERIAL_RT_DEPTH_NONE, 0, 0, IMAGE_FORMAT_DEFAULT )
local matFB = Material( "pp/frame_blend" )
local matFSB = Material( "pp/motionblur" )
local texMB0 = render.GetMoBlurTex0()
local texMB1 = render.GetMoBlurTex1()
local NumFramesTaken = 0
frame_blend = {}
frame_blend.IsActive = function()
return pp_fb:GetBool()
end
frame_blend.IsLastFrame = function()
if ( !frame_blend.IsActive() ) then return true end
local padding = math.floor( pp_fb_frames:GetInt() * pp_fb_shutter:GetFloat() * 0.5 )
return NumFramesTaken == ( pp_fb_frames:GetInt() - padding - 1 )
end
frame_blend.RenderableFrames = function()
local padding = math.floor( pp_fb_frames:GetInt() * pp_fb_shutter:GetFloat() * 0.5 ) * 2
return pp_fb_frames:GetInt() - padding
end
frame_blend.DrawPreview = function()
render.Clear( 0, 0, 0, 255, true, true )
matFSB:SetFloat( "$alpha", 1.0 )
matFSB:SetTexture( "$basetexture", texMB1 )
render.SetMaterial( matFSB )
render.DrawScreenQuad()
end
frame_blend.ShouldSkipFrame = function()
if ( pp_fb_shutter:GetFloat() <= 0 ) then return false end
if ( pp_fb_shutter:GetFloat() >= 1 ) then return false end
local padding = math.floor( pp_fb_frames:GetInt() * pp_fb_shutter:GetFloat() * 0.5 )
if ( NumFramesTaken < padding || NumFramesTaken >= pp_fb_frames:GetInt() - padding ) then
return true
end
return false
end
frame_blend.CompleteFrame = function()
matFSB:SetFloat( "$alpha", 1.0 )
matFSB:SetTexture( "$basetexture", texMB0 )
local OldRT = render.GetRenderTarget()
render.SetRenderTarget( texMB1 )
render.SetMaterial( matFSB )
render.DrawScreenQuad()
render.SetRenderTarget( OldRT )
render.SetRenderTarget( texMB0 )
render.Clear( 0, 0, 0, 255, true, true )
render.SetRenderTarget( OldRT )
end
frame_blend.AddFrame = function()
NumFramesTaken = NumFramesTaken + 1
if ( NumFramesTaken >= pp_fb_frames:GetInt() ) then
frame_blend.CompleteFrame()
NumFramesTaken = 0
end
end
frame_blend.BlendFrame = function()
local padding = math.floor( pp_fb_frames:GetInt() * pp_fb_shutter:GetFloat() * 0.5 )
local frames = pp_fb_frames:GetInt()
render.PushRenderTarget( texFB )
render.UpdateScreenEffectTexture()
render.PopRenderTarget()
local delta = ( NumFramesTaken - padding ) / ( frames - padding * 2 )
local curve = FrameCurve( NumFramesTaken - padding, frames-padding * 2 )
if ( !curve ) then return end
curve = ( 1 / ( NumFramesTaken - padding ) ) * curve
matFB:SetFloat( "$alpha", curve )
local OldRT = render.GetRenderTarget()
render.SetRenderTarget( texMB0 )
render.SetMaterial( matFB )
render.DrawScreenQuad()
render.SetRenderTarget( OldRT )
end
--
-- Don't use these hooks when rendering a demo
--
if ( engine.IsPlayingDemo() ) then return end
hook.Add( "PostRender", "RenderFrameBlend", function()
if ( !frame_blend.IsActive() ) then return end
if ( !frame_blend.ShouldSkipFrame() ) then
render.CopyRenderTargetToTexture( texFB )
frame_blend.BlendFrame()
end
frame_blend.AddFrame()
frame_blend.DrawPreview()
end )
list.Set( "PostProcess", "#frame_blend_pp", {
icon = "gui/postprocess/frame_blend.png",
convar = "pp_fb",
category = "#effects_pp",
cpanel = function( CPanel )
CPanel:AddControl( "Header", { Description = "#frame_blend_pp.desc" } )
CPanel:AddControl( "Header", { Description = "#frame_blend_pp.desc2" } )
CPanel:AddControl( "CheckBox", { Label = "#frame_blend_pp.enable", Command = "pp_fb" } )
local params = { Options = {}, CVars = {}, MenuButton = "1", Folder = "frame_blend" }
params.Options[ "#preset.default" ] = { pp_fb_frames = "16", pp_fb_shutter = "0.5" }
params.CVars = table.GetKeys( params.Options[ "#preset.default" ] )
CPanel:AddControl( "ComboBox", params )
CPanel:AddControl( "Slider", { Label = "#frame_blend_pp.frames", Command = "pp_fb_frames", Type = "Int", Min = "3", Max = "64" } )
CPanel:AddControl( "Slider", { Label = "#frame_blend_pp.shutter", Command = "pp_fb_shutter", Type = "Float", Min = "0", Max = "0.99" } )
end
} )