Log in

View Full Version : CRT Phosphor Persistence (Afterglow or decay)


real.finder
3rd April 2026, 21:45
After I did crt_tv_interlace() (https://forum.doom9.org/showpost.php?p=2029962&postcount=74) I did try making the experience better and making the simulation closer to CRT, so I thought about Phosphor Persistence

and then I think https://github.com/libretro/slang-shaders/blob/f1b85fef8c82ae05bf24a2bda8eb2730b3b7023e/crt/crt-effects/phosphor-persistence.slangp is one of the best in this

so I did tried to port it to avs+ (I think non-plus is not possible unless the code is written differently while maintaining the same result)

function PhosphorPersistence(clip c, float "power", float "amplitude")
{
Assert (isrgb(c), "PhosphorPersistence: RGB only")
power = default(power, 1.8)
amplitude = default(amplitude, 0.04)
cscrn = c

# Get previous phosphor state (from previous frame execution)
phoFeed = cscrn.FeedbackInput()

cscrn = cscrn.RemoveAlphaPlane().expr("x 2.2 ^")
cphos = phoFeed.RemoveAlphaPlane().expr("x 2.2 ^")

t=expr(phoFeed.ExtractA(),phoFeed.ExtractB(),"255.0 x * y 255.0 * 4.0 / dup floor - 1024.0 * +") #255.0 x * y 255.0 * 4.0 / y 255.0 * 4.0 / floor - 1024.0 * +
cphos = expr(cphos,MergeRGB(t,t,t,PixelType(cscrn)),"x "+string(amplitude)+" y "+string(-power)+" ^ * *")
col = expr(cscrn, cphos, "x y + 1.0 2.2 / ^").AddAlphaPlane(1)



bscrn = expr(col.ExtractR(),col.ExtractG(),col.ExtractB(),"0.299 x 2.2 ^ * 0.587 y 2.2 ^ * + 0.114 z 2.2 ^ * +")
bphos = expr(phoFeed.ExtractR(),phoFeed.ExtractG(),phoFeed.ExtractB(),"0.299 x 2.2 ^ * 0.587 y 2.2 ^ * + 0.114 z 2.2 ^ * +")

t=expr(t,"x 1 +")

bphos = expr(bphos,t,"y 1023.0 > 0.0 x y "+string(-power)+" ^ * ?")

bscrnbphosmask=expr(bscrn, bphos,"x y >= 0.0 range_max ?")
screenrgba=MergeARGB(bscrn.expr("1 255.0 /"),col.ExtractR(), col.ExtractG(), col.ExtractB().expr("x 255.0 * 4.0 / floor 4.0 * 255.0 /"),PixelType(phoFeed))
phosphorrgba=MergeARGB(t.expr("x 256.0 / dup floor - 256.0 * 255.0 /"),phoFeed.ExtractR(), phoFeed.ExtractG(), phoFeed.ExtractB().expr(t,"x 255.0 * 4.0 / floor 4.0 * y 256.0 / floor +"),PixelType(phoFeed))
phosphorlast = mt_merge(screenrgba,phosphorrgba,bscrnbphosmask)
phosphorlast
phosphorFeedback = last.FeedbackOutput()
col
}

it need Feedback.dll https://forum.doom9.org/showthread.php?t=182910 plugin, also it need RGBAPS colour space

it kinda work but not usable, since it's not stable unless you start with frame 0 and also the output is buggy, so any help fixing it is so welcome :)

StainlessS
3rd April 2026, 23:32
Maybe, also post in new plugs etc.

real.finder
4th April 2026, 00:33
Maybe, also post in new plugs etc.

after it get fixed, it's not ready yet :) as I said "any help is so welcome"