#ifndef _FILMGRAIN_FXH_
#define _FILMGRAIN_FXH_
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//  FilmGrain by martinsh
//      http://devlog-martinsh.blogspot.tw/2013/05/image-imperfections-and-film-grain-post.html
//
//  Impliment by kingeric1992                                 Nov.4.2017
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

#include "PerlinNoise.fxh"
static const float3 FilmGrain_rot = float3(1.425,3.892,5.835);

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

struct FilmGrainStruct {
    bool    State;
    float   Weight;
    float   Size, Freq, colWeight, lumWeight, Strength; 
//  texture2D blurtex; //use this for finetune intensity
};

float3 FilmGrain(float2 uv, float3 col, FilmGrainStruct IN)
{
    if(!IN.State) return col;
    float2 nPixels    = ScreenSize.x / IN.Size;
    float  timecoeff  = Timer.x*16777.216*IN.Freq;
           uv.y      *= ScreenSize.w; 
    float3 noise = { 
        PerlinNoise(float3(Rotate(uv, FilmGrain_rot.r) * nPixels, int(timecoeff) + 0.5)),
        PerlinNoise(float3(Rotate(uv, FilmGrain_rot.g) * nPixels, int(timecoeff) + 0.5)),
        PerlinNoise(float3(Rotate(uv, FilmGrain_rot.b) * nPixels, int(timecoeff) + 0.5))
    };
    noise.gb = lerp(noise.rr, noise.gb, IN.colWeight);
    
    //(use bloom tex instead)
    float sceneLumWeight = dot(col, LUM_COEFF) * IN.lumWeight;
          sceneLumWeight+= smoothstep( 0.2, 0.0, sceneLumWeight);
    noise *= 1.0 - pow(sceneLumWeight, 4.0);

    return col + noise * IN.Strength;
}

#endif //_FILMGRAIN_FXH_