Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Blurry pixels?
#1
Hey, still getting familiar with Tilengine(and C in general) and I noticed that with the CRT effect turned off my artwork is pretty blurry looking, so my question is: 

Is there a way to turn off this blur effect in the engine? 

I did a quick search and I see that someone asked about this last year, and Marc had said it wasn't a feature then, but was it added since then? If so, what do I need to do to fix this?

Thank you for your time and support.

Nevermind, I've found the answer. Adding CWF_NEAREST to TLN_CreateWindow is what I needed. This option wasn't listed in the documentation on the website, but I found it by looking through the update notes. Loving this engine so far! Keep up the great work! This is fantastic.
Reply
#2
Thanks for your appreciation! I'm glad you're enjoying it  Smile

There is an additional element that contributes to blurriness, but it's hardcoded inside the CRT effect and can't be disabled. There is a 1-pixel wide horizontal blur that blends together any two adjacent pixels. This is needed to emulate the horizontal smear produced by legacy RF transmission. This defect was exploited by many graphics designers, specially for the sega genesis, where alternation color on vertical line strips were used to get more colors and fake 50% transparency. Without this blurring, if you load this kind of artwork in tilengine, you'll see the ugly alternating lines instead of the expected mixed color.

However this RF blurring effect should be selectable. Other systems with better color support, hardware blending or cleaner signal (SNES, arcade boards) didn't exploited (or shown at all) this behavior, introducing an artificial excessive blurring in your artwork. I'm learning/playing with shaders, my intention is to rewrite the effect, taking advantage of GPU acceleration with a better effect using less resources, as the current implementation uses CPU.
Reply
#3
(11-15-2019, 02:46 AM)megamarc Wrote: I'm learning/playing with shaders, my intention is to rewrite the effect, taking advantage of GPU acceleration with a better effect using less resources, as the current implementation uses CPU.

That would be interesting to see. 

One more question if you don't mind, (completely different topic) I was wondering if Tilengine could be used to do an effect like the one found in this video at 16 minute mark: https://www.youtube.com/watch?v=Rnr1q12Hs0I with the reflective surface that moves up and down?
Reply
#4
Sure you can do this effect! This is a raster effect trick, setting the lines in resverse order and changing the palette

<- Here start normal drawing of frame, numbers are scanlines of the background layer in normal order:
1
2
3
4
5
6
7
8
<- reflection surface: change palette to a red-tinted variant and start drawing in reverse order:
7
6
5
4
3
Reply
#5
(11-15-2019, 07:42 AM)megamarc Wrote: Sure you can do this effect! This is a raster effect trick, setting the lines in resverse order and changing the palette

<- Here start normal drawing of frame, numbers are scanlines of the background layer in normal order:
1
2
3
4
5
6
7
8
<- reflection surface: change palette to a red-tinted variant and start drawing in reverse order:
7
6
5
4
3

If it's not too much to ask, could you point me in the right direction of setting this up? Is there a example/guide I could look at to see how the scanline coding in C works exactly? Would I use something like TLN_SetLayerAffineTransform to reverse the drawing, or is there another function/method to use for such an effect?

 Thank you very much for all the help. Cheers!
Reply
#6
Hi,
Here attached is a little example on how to do this effect in C. It just loads a background tilemap, creates a blue tinted palette from the original one, and sets up the raster effect for reflection. There are comments inside. It scrolls right automatically, but you can control the height of the reflection surface with up/down arrow keys. Let me know if it fits your needs!

Code:
#include "Tilengine.h"

static TLN_Palette palette;
static TLN_Palette water;
static int limit = 180;
static int x = 0;

/* raster callback for the reflection effect */
static void reflection_raster(int line)
{
    /* top of frame: restore palette and vertical position */
    if (line == 0)
    {
        TLN_SetLayerPalette(0, palette);
        TLN_SetLayerPosition(0, x, 0);
    }
    
    /* surface line: set waterish palette */
    else if (line == limit)
        TLN_SetLayerPalette(0, water);
    
    /* below-surface line: calculate distance and set */
    else if (line > limit)
        TLN_SetLayerPosition(0, x, -(line - limit)*2);
}

/* create a blueish palette of the source */
static TLN_Palette create_water_palette(TLN_Palette source)
{
    typedef struct
    {
        uint8_t b,g,r,x;
    }
    Color;

    int c;
    TLN_Palette water = TLN_ClonePalette(source);

    for(c = 0; c<256; c++)
    {
        Color* color = (Color*)TLN_GetPaletteData(water, c);
        int mix = (color->r + color->g + color->b) / 3;
        color->r = 0;
        color->g = mix/2;
        color->b = mix;
    }
    return water;
}

void main(void)
{
    int frame = 0;
    TLN_Tilemap background;

    TLN_Init (400,240,1,0,20);
    TLN_SetLoadPath ("assets");
    background = TLN_LoadTilemap ("rolo.tmx", NULL);
    TLN_SetLayer (0, NULL, background);
    TLN_SetRasterCallback(reflection_raster);
    TLN_SetBGColorFromTilemap(background);
    
    palette = TLN_GetLayerPalette(0);
    water = create_water_palette(palette);

    TLN_CreateWindow (NULL, 0);
    while (TLN_ProcessWindow())
    {
        /* use arrow keys to displace surface line */
        if (TLN_GetInput(INPUT_UP) && limit > 120)
            limit -= 1;
        else if (TLN_GetInput(INPUT_DOWN))
            limit += 1;
        
        TLN_DrawFrame (frame);
        frame += 1;
        x += 2;
    }
    TLN_Deinit ();
}


Attached Files Thumbnail(s)
   

.zip   reflection.zip (Size: 8.73 KB / Downloads: 4)
Reply
#7
(11-15-2019, 07:49 PM)megamarc Wrote: Hi,
Here attached is a little example on how to do this effect in C. It just loads a background tilemap, creates a blue tinted palette from the original one, and sets up the raster effect for reflection. There are comments inside. It scrolls right automatically, but you can control the height of the reflection surface with up/down arrow keys. Let me know if it fits your needs!

Code:
#include "Tilengine.h"

static TLN_Palette palette;
static TLN_Palette water;
static int limit = 180;
static int x = 0;

/* raster callback for the reflection effect */
static void reflection_raster(int line)
{
    /* top of frame: restore palette and vertical position */
    if (line == 0)
    {
        TLN_SetLayerPalette(0, palette);
        TLN_SetLayerPosition(0, x, 0);
    }
    
    /* surface line: set waterish palette */
    else if (line == limit)
        TLN_SetLayerPalette(0, water);
    
    /* below-surface line: calculate distance and set */
    else if (line > limit)
        TLN_SetLayerPosition(0, x, -(line - limit)*2);
}

/* create a blueish palette of the source */
static TLN_Palette create_water_palette(TLN_Palette source)
{
    typedef struct
    {
        uint8_t b,g,r,x;
    }
    Color;

    int c;
    TLN_Palette water = TLN_ClonePalette(source);

    for(c = 0; c<256; c++)
    {
        Color* color = (Color*)TLN_GetPaletteData(water, c);
        int mix = (color->r + color->g + color->b) / 3;
        color->r = 0;
        color->g = mix/2;
        color->b = mix;
    }
    return water;
}

void main(void)
{
    int frame = 0;
    TLN_Tilemap background;

    TLN_Init (400,240,1,0,20);
    TLN_SetLoadPath ("assets");
    background = TLN_LoadTilemap ("rolo.tmx", NULL);
    TLN_SetLayer (0, NULL, background);
    TLN_SetRasterCallback(reflection_raster);
    TLN_SetBGColorFromTilemap(background);
    
    palette = TLN_GetLayerPalette(0);
    water = create_water_palette(palette);

    TLN_CreateWindow (NULL, 0);
    while (TLN_ProcessWindow())
    {
        /* use arrow keys to displace surface line */
        if (TLN_GetInput(INPUT_UP) && limit > 120)
            limit -= 1;
        else if (TLN_GetInput(INPUT_DOWN))
            limit += 1;
        
        TLN_DrawFrame (frame);
        frame += 1;
        x += 2;
    }
    TLN_Deinit ();
}

Fantastic! Thank you so much! This is exactly what I needed. I really appreciate it.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)