//    Koko-aio shader is meant to be an all-in one crt shader.
//    It can be configured with many parameters, so that can be
//    scaled to run on even on modest gpus while still developed to
//    run with heavier presets on at least Haswell+ iGpus.
//    It is not meant to simulate the internal behaviour of CRT displays,
//    but to give users the parameters to make their monitors to look similar.
//    Several presets are included.

//    Actually it provides emulation for:
//        scanlines, screenlines, RGB vertical masks, horizontal slot masks,
//        glowing, haloing, blooming, gamma and SATURATION correction,pixel_outi        
//        black frame insertions, interlace emulation, antialiasing.

//    External code by:
//    * Nvidia (FXAA)



    
// Bezel texture contains the following infomations:
//   - The red channel represents the luminance information
//   - The green channel represents the highlights
//   - The alpha channel in the inner frame represents the part of the bezel that will be filled by the game content
//   - The blue channel represents the part of the bezel that will be filled by the game reflection.


                textures = "monitor_body_curved;monitor_body_straight;bg_under;bg_over;backdrop;sideshade"
                
            monitor_body_curved = "textures/monitor_body_curved.png"
     monitor_body_curved_linear = "true"
  // Does this work?
  monitor_body_curved_wrap_mode = "clamp_to_edge"
     monitor_body_curved_mipmap = "true"

            monitor_body_straight = "textures/monitor_body_straight.png"
     monitor_body_straight_linear = "true"
  // Does this work?
  monitor_body_straight_wrap_mode = "clamp_to_edge"
     monitor_body_straight_mipmap = "true"
     
                bg_under = "textures/background_under.png"
         bg_under_linear = "true"
      bg_under_wrap_mode = "mirrored_repeat"
         bg_under_mipmap = "false"
         
                 bg_over = "textures/background_over.png"
          bg_over_linear = "true"
       bg_over_wrap_mode = "mirrored_repeat"
          bg_over_mipmap = "false"

                backdrop = "textures/backdrop.jpg"
         backdrop_linear = "true"
      backdrop_wrap_mode = "clamp_to_border"
         backdrop_mipmap = "false"
         
                sideshade = "textures/side_shade-helper.png"
         sideshade_linear = "true"
      sideshade_wrap_mode = "mirrored_repeat"
         sideshade_mipmap = "false"


shaders = 17


// The very first pass emulates:
// Ntsc color artifacting
// Color tools
// Ghosting
// Phosphor persistance
// Geometry override shifting (so it needs clamp_to _border)
// It generates mipmaps to be used by several passes afterwards
// Also, it carries a series of debug patterns that need to be activated by modifying 
// some #defines in the pass itself

// ASMDEBUG GLSL27
           shader0 = shaders-ng/colortools_and_ntsc_pass.slang
            alias0 = "colortools_and_ntsc_pass"
       scale_type0 = source
            scale0 = 1.0
            
// (**Note 0)
// Watch out for filter_linear0 and wrap_mode0
// In retroarch, metadatas such as the followings, usually applies to the
// previous pass (Original, in this case).
// However it seems that those metadatas are applied to the feedback of the pass itself.
// Now, since we need to compare colortools_and_ntsc_pass and colortools_and_ntsc_passFeedback
// for Deltarender purposes, it is important that they share the same filtering and wrap mode:

// colortools_and_ntsc_pass wrap_mode and filter_linear_mode 
//      are set by upscale_pass (the next one)
// colortools_and_ntsc_passFeedback wrap_mode and filter_linear_mode 
//      are set by colortools_and_ntsc_pass (the this pass)

// Hence, we have to set colortools_and_ntsc_pass and next pass (upscale_pass) with the same filter and wrap_mode

// high precision needed by phosphor persistance and values > 1.0 needed by color pushes
float_framebuffer0 = "true"
    filter_linear0 = "true"
        wrap_mode0 = "mirrored_repeat"



        
// This pass emulates the flickering observed on crts when the input signal is interlaced
// and there is high brightness difference between adiacent scanlines.
// It also emulates the RF noise.

// Also, it upscales the input signal to 2X and optionally applies an edge smoothing algorithm.
// Koko-aio will then work internally at 2X, which is needed by several following filters.
// However, if the input signal is already at sufficient resolution, there is no need to scale to 2x
// and it is possible to gain performance by turning the scale to 1x.

// A special note for P-UAE core (Commodore Amiga), is needed, because it outputs by default to
// 720 pixel width and about 280p; this means that for P-UAE you can use scale_x1 = 1.0
// and only scale_y1 = 2.0 is needed.
// As an alternative option you can configure P-UAE to always output to low resolution for x and y
// But this way you loose the emulation for hires content (not much games uses it anyway).
        
// ASMDEBUG: GLSL30
           shader1 = shaders-ng/fxaa.slang
            alias1 = "upscale_pass"
       scale_type1 = source
            scale1 = 2.0
     mipmap_input1 = "true"
        // This *has* to be mirrored repeat so that avglum mipmap sampling that samplese from previous
        // pass will not pick black.
        wrap_mode1 = "mirrored_repeat"
// this has to be float framebuffer, because colortools may push values over 1.0.
// simple test is to push brightness and see the difference.
float_framebuffer1 = "true"
    filter_linear1 = "true"
        

// This pass emulates NTSC/PAL composite color bleeding and deconvergence
// deconvergence should really be applied in th final pass, but it is too heavy there.
// This pass also applies the input gamma needed for glow pass.
        
// ASMDEBUG: GLSL33
           shader2 = shaders-ng/shift_and_bleed.slang
            alias2 = "shift_and_bleed_pass"
    filter_linear2 = true
            scale2 = 1.0
       scale_type2 = source
// As per fxaa pass, this has to be float framebuffer too, because colortools may push values over 1.0.
// simple test is to push brightness and see the difference.
        wrap_mode2 = "mirrored_repeat"
// this has to be true to just to keep the precision needed by linearization
float_framebuffer2 = true
        
        
// Blur and/or glows and/or sharpens the image as requested 
// This passes aims to simulate the signal input power.
        
// ASMDEBUG: GLSL36
           shader3 = shaders-ng/in_glow_x.slang
            alias3 = "in_glow_pass_x"
    filter_linear3 = true
            scale3 = 1.0
       scale_type3 = source    
// This needs to be signed because of WarpedGlow, so float_framebuffer.
float_framebuffer3 = true
        wrap_mode3 = "clamp_to_edge"
     
// ASMDEBUG: GLSL39
           shader4 = shaders-ng/in_glow_y.slang
            alias4 = "in_glow_pass"
    filter_linear4 = true
            scale4 = 1.0
       scale_type4 = source    
// This needs to be signed because of WarpedGlow, so float_framebuffer.
float_framebuffer4 = true
        wrap_mode4 = "clamp_to_border"
            
          
        
// This essentially is the same as glowing by a code point of view.
// But the result of this pass will be added (+) to the input signal
// in the final pass.
        
// ASMDEBUG: GLSL42
           shader5 = shaders-ng/halo_pre_gamma.slang
            alias5 = "halo_pre_gamma_pass"
    filter_linear5 = true
            scale5 = 1.0
       scale_type5 = source
// float_framebuffer here is needed to avoid visible bandings
// (check flycast:D.O.A. intro.)
// *and* because the alpha carries the fps estimation.
float_framebuffer5 = true
        // This has to be clamp_to_border in order for the glow pass to return a black frame
        // around it, which is needed so that when using geometry override and zooming out the content,
        // it will have black surrounding.
        wrap_mode5 = "clamp_to_border"
        
// ASMDEBUG: GLSL45
           shader6 = shaders-ng/halo.slang
            alias6 = "halo_pass"
    filter_linear6 = true
            scale6 = 1.0
       scale_type6 = source
// float_framebuffer here is needed to avoid visible bandings
// check flycast:D.O.A. intro.
float_framebuffer6 = true
        wrap_mode6 = "clamp_to_border"



// Get the average luminance needed by ambilight here.
//   The rgb channels of the following pass contains luminance info
//   Used by the bezel code to light up the bezel corners.
//   The alpha channel contains the sum/3.0 of rgb channels
//   used to detect scene changes.

// This pass computes the average luminance of the image
// by grabbing a mipmap from colortools_and_ntsc_pass.
// It stores at:
// alpha@coords 0.25,0.25 at reduced sampling to aid ambient light scene change detection
// alpha@coords 0.75,0.75 temporally smoother for use with bloom exposure and dynamic zoom
// rgb: it puts a small mipmap from colortools_and_ntsc_pass used to light-up the bezel highlights.
// alpha@other coords: simple continuous sampling used to modulate bezel highlights strength.
        
// ASMDEBUG: GLSL48
               shader7 = shaders-ng/avglum_pass.slang
                alias7 = "avglum_pass"
        filter_linear7 = true
           scale_type7 = source
                scale7 = 0.5
            wrap_mode7 = "clamp_to_border"
// temporal mixing needs high precision.
    float_framebuffer7 = "true"
         
         
// The following passes emulates soft bezel reflections.
    
// ASMDEBUG: GLSL51
               shader8 = shaders-ng/reflection_blur_pre.slang
                alias8 = "reflected_blurred_pass_pre"
        filter_linear8 = true
           scale_type8 = source
                scale8 = 1.0
            wrap_mode8 = "clamp_to_border"

// ASMDEBUG: GLSL54          
               shader9 = shaders-ng/reflection_blur.slang
                alias9 = "reflected_blurred_pass"
        filter_linear9 = true
           scale_type9 = source
                scale9 = 1.0
// float_framebuffer9 is an output metadata and is needed
// because reflection_blur can output negative values
// due to shades.
    float_framebuffer9 = true
            wrap_mode9 = "mirrored_repeat"

// In the following passes we emulate bloom effect.
// Since the radius has to be high, we sample first_pass
// and then do other blur passes at reduced size to keep it fast.
// Every blur pass samples radially around the center and offsets
// the starting point in every subsequent pass.
            
// ASMDEBUG: GLSL57
               shader10 = shaders-ng/bloom_pass_1.slang
                alias10 = "bloom_pass_1"
        filter_linear10 = true
           scale_type10 = source
                scale10 = 1.0
            wrap_mode10 = "mirrored_repeat"
    
// ASMDEBUG: GLSL60
               shader11 = shaders-ng/bloom_pass_2.slang
                alias11 = "bloom_pass_2"
        filter_linear11 = true
           scale_type11 = source
                scale11 = 0.5
            wrap_mode11 = "clamp_to_edge"
            
// ASMDEBUG: GLSL63
               shader12 = shaders-ng/bloom_pass_3.slang
                alias12 = "bloom_pass_3"
        filter_linear12 = true
           scale_type12 = source
                scale12 = 1.0
            wrap_mode12 = "clamp_to_edge"

// ASMDEBUG: GLSL66
               shader13 = shaders-ng/bloom_pass_4.slang
                alias13 = "bloom_pass_final"
        filter_linear13 = true
           scale_type13 = source
                scale13 = 1.0
            wrap_mode13 = "mirrored_repeat"
// Here float framebuffer is needed because we need high resolution feedback
// for time fades
    float_framebuffer13 = "true"



// Use mipmaps from colortools_and_ntsc_pass to light virtual leds under the virtual monitor 
// and temporally smooth led lights.
// Extra logic makes it possible to lower the led reaction time when a scene change is detected.
// this is achieved through average luminance sampling from avglum_pass
// ASMDEBUG: GLSL69
               shader14 = shaders-ng/ambi_temporal_pass.slang
                alias14 = "ambi_temporal_pass"
        filter_linear14 = true
           scale_type14 = absolute
              scale_x14 = 96
              scale_y14 = 64
            wrap_mode14 = "clamp_to_border"
// temporal mix needs higher precision:
    float_framebuffer14 = true
    
// This is a small helper pass i can use to store values and things
// that don't need high resolution like noise and vignette.
// ASMDEBUG: GLSL72
           shader15 = shaders-ng/helper_pass.slang
            alias15 = "helper_pass"
       scale_type15 = absolute
// Helper pass needs float framebuffer so that the noise over spot
// and vignette does a (much) better job in debanding.
float_framebuffer15 = true
            scale15 = 128
    filter_linear15 = true    
        wrap_mode15 = "mirrored_repeat"
    

// This pass pass will do everything needed to happen at screen coordinates:
// * The composition of the previous passes with the bloomed image, 
// * vignette and spot light
// * Scanlines
// * Phosphors masks 
// * Black frame insertions
// * Bezel
// * Background images
// ASMDEBUG: GLSL75
           shader16 = shaders-ng/final_pass.slang
            alias16 = "final_pass"
    filter_linear16 = true
       scale_type16 = viewport
            scale16 = 1.0
        //This needs to be clamp_to_edge or displacing vignette would dark screen borders
        wrap_mode16 = "clamp_to_edge" 

        

