Page 2 of 2

Re: How to efficiently play an animation/video of 500 frames?

Posted: Fri Aug 06, 2021 4:30 pm
by ecoste
To some of the disgruntled posters: yes it's a hentai game.

Thanks for all of the suggestions to use green as a bootleg alpha channel. This is what I did:

Code: Select all

// Convert all images to have a green background instead of transparent. This works by creating a green flag image and overlaying the input frame on top.
ffmpeg.exe -start_number 1000 -i mika_%04d.png -filter_complex "color=0x00FF00,format=rgb24[c];[c][0]scale2ref[c][i];[c][i]overlay=format=auto:shortest=1,setsar=1" out_%04d.png

// Convert the images into a video.
ffmpeg -framerate 50 -i out_%4d.png -c:v libtheora -pix_fmt yuv420p -vb 20M out.ogg
Then the shader (thanks pgimeno)

Code: Select all

vec3 key = vec3(0.,1.,0.);
float threshold = 0.5;

vec4 effect(vec4 pxColor, Image tex, vec2 texture_coords, vec2 screen_coords) {
    vec4 videoColor = VideoTexel(texture_coords);
    if (length(videoColor.rgb - key) < threshold) videoColor.a = 0.0;
    return videoColor;
}
Unfortunately, even with the very high threshold there is a slight green outline that is visible:
0.5 thershold green outline
0.5 thershold green outline
d67b1f9c1e82a54d3b8696475fa3e4ce.png (615.42 KiB) Viewed 3542 times
If I increase the threshold to 0.8, the green outline is almost gone but then some parts of the characters start becoming transparent like the eyes.

I'll try to play around some more with the shader to see if this can be improved, although I've never touched shaders before really.
I don't know how well this would work, if at all, but how about using two ogv files - one with the RGB info, and one with just the alpha (stored in one of the RGB channels) and then using a shader to combine everything when drawing.
This might work, although it might be hard to get the mask lined up with the video and it might get choppy. Although, don't know until you try. I might try after playing around some more with the shader.
black background instead of green, also can see some artifacts especially around the head
black background instead of green, also can see some artifacts especially around the head
bbdd13b4593311d83ee25f5e2cbd625c.png (609.85 KiB) Viewed 3541 times

Re: How to efficiently play an animation/video of 500 frames?

Posted: Fri Aug 06, 2021 4:35 pm
by GVovkiv
ecoste wrote: Fri Aug 06, 2021 4:30 pm To some of the disgruntled posters: yes it's a hentai game.
When and where and how much

Re: How to efficiently play an animation/video of 500 frames?

Posted: Fri Aug 06, 2021 7:12 pm
by Gunroar:Cannon()
ecoste wrote: Fri Aug 06, 2021 4:30 pm To some of the disgruntled posters: yes it's a hentai game.
Okay, that explains it :| ... Not that disgrunted...but...anyway..we're all here to learn love (2d that is)!
GVovkiv wrote: Fri Aug 06, 2021 4:35 pm When and where and how much
:rofl: :rofl:

Re: How to efficiently play an animation/video of 500 frames?

Posted: Fri Aug 06, 2021 7:46 pm
by GVovkiv
Gunroar:Cannon() wrote: Fri Aug 06, 2021 7:12 pm
ecoste wrote: Fri Aug 06, 2021 4:30 pm To some of the disgruntled posters: yes it's a hentai game.
Okay, that explains it :| ... Not that disgrunted...but...anyway..we're all here to learn love (2d that is)!
GVovkiv wrote: Fri Aug 06, 2021 4:35 pm When and where and how much
:rofl: :rofl:
Seriously, where
I already want buy it, if it will be good

Re: How to efficiently play an animation/video of 500 frames?

Posted: Fri Aug 06, 2021 11:10 pm
by pgimeno
Have you tried with black?
Black could be an option as a key colour, judging by the sample image, and that's great because bleeding effects might be reduced.
Making it progressive instead of hard alpha would help. Let's see...

The first RGBs in your image are R=19, G=18 and B=38. There isn't any pixel with R < 19, G < 18 or B < 38. Dividing by 255 and taking the length from (0,0,0) gives me 0.17458689638864366, so let's start the ramp there. You'll have to experiment a bit with the range.

Code: Select all

float base = 0.174;
float range = 0.03;

vec4 effect(vec4 pxColor, Image tex, vec2 texture_coords, vec2 screen_coords) {
    vec4 videoColor = VideoTexel(texture_coords);
    float len = length(videoColor.rgb);
    videoColor.a = (len - base) / range;
    return videoColor;
}

Re: How to efficiently play an animation/video of 500 frames?

Posted: Sat Aug 07, 2021 3:22 pm
by Xii
<useless suggestion>

Re: How to efficiently play an animation/video of 500 frames?

Posted: Sat Aug 07, 2021 4:22 pm
by pgimeno
That won't work I'm afraid. There's a lot of white, and white has green. If I replace the green channel with the alpha channel, I get the attached.

Re: How to efficiently play an animation/video of 500 frames?

Posted: Sat Aug 07, 2021 7:09 pm
by Xii
Dang you're right.

Re: How to efficiently play an animation/video of 500 frames?

Posted: Sun Aug 08, 2021 12:30 am
by ecoste
pgimeno wrote: Fri Aug 06, 2021 11:10 pm Have you tried with black?
Black could be an option as a key colour, judging by the sample image, and that's great because bleeding effects might be reduced.
Making it progressive instead of hard alpha would help. Let's see...

The first RGBs in your image are R=19, G=18 and B=38. There isn't any pixel with R < 19, G < 18 or B < 38. Dividing by 255 and taking the length from (0,0,0) gives me 0.17458689638864366, so let's start the ramp there. You'll have to experiment a bit with the range.

Code: Select all

float base = 0.174;
float range = 0.03;

vec4 effect(vec4 pxColor, Image tex, vec2 texture_coords, vec2 screen_coords) {
    vec4 videoColor = VideoTexel(texture_coords);
    float len = length(videoColor.rgb);
    videoColor.a = (len - base) / range;
    return videoColor;
}
Using solid black color as an 'alpha' with progressive alpha

I did try black before, it worked the best but still had slight artifacting. Here is black with the progressive alpha code.

Code: Select all

float base = 0.015;

vec4 effect(vec4 pxColor, Image tex, vec2 texture_coords, vec2 screen_coords) {
    vec4 videoColor = VideoTexel(texture_coords);
    float len = length(videoColor.rgb);
    videoColor.a = 1 - ((base - len) * (1.0 / base));
    return videoColor;
}
and it worked the best. There was still slight artifacting with some tuning, but not too much. Here's the result:
bbdd13b4593311d83ee25f5e2cbd625c.png
bbdd13b4593311d83ee25f5e2cbd625c.png (609.85 KiB) Viewed 3417 times
One can improve this probably by taking into account neighboring pixel values and doing some fancy math but I'm not an expert on this and it would take me forever to do.

Using a second video as a mask
This works, but it has the same exact artifacting problems as if you're just replacing the alpha with another color. This is expected I guess since your'e doing the same thing essentially.

A middle-ground solution that I will use from now on is DXT5 DDS images

I converted all of the PNGs to DXT5 DDS.

Code: Select all

magick mogrify -format dds -path out/ -define dds:compression=dx5 mika_*.png
And then loaded them all using

Code: Select all

love.graphics.newImage(love.image.newCompressedData(fileName))
The loading time went down from like a minute to a couple of seconds which is fine. The RAM usage went down from 4GB to 1GB which is also perfectly fine. There is no noticeable quality loss and no artifacting problems on the outside of the image. I can also control the speed etc. which you don't get with a video.

Thanks everyone.

edit: Another solution is to have PNGs as only a black and white mask, convert them to DXT5 and use them as a mask with a shader with a video. This would probably yield the best RAM/loading time results, but for now I don't need it.