/**
 *                    ____      ____  _               _
 *                   |  _ \ ___/ ___|| |__   __ _  __| | ___
 *                   | |_) / _ \___ \| '_ \ / _` |/ _` |/ _ \
 *                   |  _ '  __/___) | | | | (_| | (_| |  __/
 *                   |_| \_\___|____/|_| |_|\__,_|\__,_|\___|
 *                                  by Crosire
 *
 * =============================================================================
 *   This is an example shader demonstrating the ReShade FX shading language.
 * =============================================================================
 *
 * Macros:
 * -------
 * 
 * __RESHADE__
 *      > Version of the injector.
 * __VENDOR__
 *      > Vendor id.
 * __DEVICE__
 *      > Device id.
 * __RENDERER__
 *      > Renderer version in format 0x[Type][Major][Minor][Revision]. Examples:
 *           0x09300 is Direct3D9 SM3
 *           0x0A100 is Direct3D10.1
 *           0x0B000 is Direct3D11.0
 *           0x14300 is OpenGL 4.3
 * __APPLICATION__
 *      > Hash of the application executable name.
 *
 * __DATE_YEAR__
 *      > Current year.
 * __DATE_MONTH__
 *      > Current month.
 * __DATE_DAY__
 *      > Current day in month.
 *
 * BUFFER_WIDTH
 *      > Screen width.
 * BUFFER_HEIGHT
 *      > Screen height.
 * BUFFER_RCP_WIDTH
 *      > Reciprocal screen width.
 * BUFFER_RCP_HEIGHT
 *      > Reciprocal screen height.
 *
 * Pragmas:
 * --------
 * 
 * #pragma message "Hello World!"
 *      > Displays  the string  "Hello World!" in  the  center of  the  game  on
 *        startup. Multiple of these can be chained and will be added together.
 * #pragma reshade showfps
 *      > Shows a framerate counter in the top right corner.
 * #pragma reshade showclock
 *      > Shows a clock with the current local time in the top right corner.
 * #pragma reshade showstatistics
 *      > Shows some detailed drawing statistics about the current frame.
 * #pragma reshade showtogglemessage
 *      > Notifies when switching a technique on or off with its toggle key.
 * #pragma reshade skipoptimization
 *      > Forces the internal compilers to skip the optimization step.
 * #pragma reshade screenshot_format bmp
 *      > Sets the screenshot file format to BMP.
 * #pragma reshade screenshot_format png
 *      > Sets the screenshot file format to PNG.
 */

/**
 * Textures:
 * ---------
 *
 * Textures are multidimensional data containers usually used to store images.
 *
 * Annotations:
 * ~~~~~~~~~~~~
 *
 * texture imageTex < source = "path/to/image.bmp"; > { ... };
 *      > Opens image from  the patch specified, resizes  it to the texture size
 *        and loads it into the texture.
 *
 * Semantics:
 * ~~~~~~~~~~
 *
 * texture texColor : COLOR;
 *      > Recieves the backbuffer contents.
 * texture texDepth : DEPTH;
 *      > Recieves the game's depth information.
 *
 * These special textures are readonly. Do not attempt to render into them.
 */

// Semantics on textures are used to request special textures.

texture texColorBuffer : COLOR; // or SV_Target
texture texDepthBuffer : DEPTH; // or SV_Depth

// Textures declared are created at runtime with the parameters specified in the
// body.

texture texTarget
{
	// The texture dimensions (default: 1x1).
	Width = BUFFER_WIDTH / 2;
	Height = BUFFER_HEIGHT / 2;
	
	// The amount of mipmaps including the base level (default: 1).
	MipLevels = 1;
	
	// The internal texture format (default: RGBA8).
	// Available formats:
	//   R8, R16, R16F, R32F
	//   RG8, RG16, RG16F, RG32F
	//   RGBA8, RGBA16, RGBA16F, RGBA32F
	// Available compressed formats (readonly):
	//   DXT1 or BC1, DXT3 or BC2, DXT5 or BC3
	//   LATC1 or BC4, LATC2 or BC5
	Format = RGBA8;

	// The default value is used if an option is missing here.
};

/**
 * Samplers:
 * ---------
 *
 * Samplers  are the  bridge  between  textures and  shaders. They  define how a
 * texture is sampled.  Multiple  samplers  can refer to the same texture  using
 * different options.
 */

sampler samplerColor
{
	// The texture to be used for sampling.
	Texture = texColorBuffer;
	
	// The method used for resolving  texture coordinates which  are outside
	// of bounds.
	// Available values: CLAMP, MIRROR, WRAP or REPEAT, BORDER
	AddressU = CLAMP;
	AddressV = CLAMP;
	AddressW = CLAMP;
	
	// The minification, magnification and minification mipmap filter types.
	// Available values: POINT, LINEAR, ANISOTROPIC
	MinFilter = LINEAR;
	MagFilter = LINEAR;
	MipFilter = LINEAR;
	
	// An offset applied to the calculated mipmap level (default: 0).
	MipLODBias = 0.0f;
	
	// The maxmimum mipmap levels accessible.
	MinLOD = 0.0f;
	MaxLOD = 1000.0f;
	
	// The maximum anisotropy used when anisotropic filtering is enabled.
	MaxAnisotropy = 1;
	
	// Enable or disable converting  to linear colors when sampling from the
	// texture.
	SRGBTexture = false;

	// Missing options are again set to the defaults shown here.
};
sampler samplerDepth
{
	Texture = texDepthBuffer;
};
sampler samplerTarget
{
	Texture = texTarget;
};

/**
 * Uniforms:
 * ---------
 *
 * Uniform variables can be used to retrieve values from ReShade.
 *
 * Annotations:
 * ~~~~~~~~~~~~
 *
 * uniform float frametime < source = "frametime"; >;
 *      > Time in milliseconds it took for the last frame to complete.
 * uniform int framecount < source = "framecount"; >;
 *      > Total amount of frames since the game started.
 * uniform float4 date < source = "date"; >;
 *      > float4(year, month (1 - 12), day of month (1 - 31), time in seconds)
 * uniform float timer < source = "timer"; >;
 *      > Timer counting time in milliseconds since game start.
 * uniform float timeleft < source = "timeleft"; >;
 *      > Time in milliseconds that is left  until the current technique timeout
 *        is reached.
 * uniform float2 pingpong < source = "pingpong"; min = 0; max = 9; step = 1; >;
 *      > Counter  that counts  up and down between min  and max using  step  as
 *        increase value.  The second  component is either +1 or -1 depending on
 *        the direction it currently goes.
 * uniform int random < source = "random"; min = 0; max = 10; >;
 *      > Gets a new random value between min and max every pass.
 * uniform bool keydown < source = "key"; keycode = 0x20; toggle = false; >;
 *      > True if specified  keycode (in this case the spacebar) is  pressed and
 *        false otherwise. If  toggle is true the value stays true until the key
 *        is pressed a second time.
 */

// Initializers are used for the initial value when providied.

uniform float4 UniformSingleValue = float4(0.0f, 0.0f, 0.0f, 0.0f);

// It is recommended  to use  constants instead of uniforms if  the value is not
// changing.

static const float4 ConstantSingleValue = float4(0.0f, 0.0f, 0.0f, 0.0f);

// If a source annotation is added it can be used to request special values.
// The following recieves a high precision timer for example:

uniform float timer < source = "timer"; >;

/**
 * Structs:
 * --------
 *
 * Structs are user defined data types that can be used for custom variables.
 */
 
struct MyStruct
{
	int MyField1, MyField2;
	float MyField3;
};

/**
 * Namespaces:
 * -----------
 *
 * Namespaces  are  used  to group  functions and variables  together. They  are
 * especially useful to avoid name clashing.
 */

/**
 * Functions:
 * ----------
 *
 * Parameter Qualifiers:
 * ~~~~~~~~~~~~~~~~~~~~~
 * 
 * in
 *      > Declares an input parameter. Default and implicit if none is used.
 *        Functions expect these to be filled with a value.
 * out
 *      > Declares an output parameter. The value is  filled in the function and
 *        can be used in the caller again.
 * inout
 *      > Declares a parameter that provides input and also expects output.
 *
 * Intrinsics:
 * ~~~~~~~~~~~
 *
 * abs
 * acos
 * all
 * any
 * asfloat
 * asin
 * asint
 * asuint
 * atan
 * atan2
 * ceil
 * clamp
 * cos
 * cosh
 * cross
 * ddx
 * ddy
 * degrees
 * determinant
 * distance
 * dot
 * exp
 * exp2,
 * faceforward
 * floor
 * frac
 * frexp
 * fwidth
 * ldexp
 * length
 * lerp
 * log
 * log10,
 * log2
 * mad
 * max
 * min
 * modf
 * mul
 * normalize
 * pow
 * radians
 * rcp
 * reflect
 * refract
 * round
 * rsqrt
 * saturate
 * sign
 * sin
 * sincos
 * sinh
 * smoothstep
 * sqrt
 * step
 * tan
 * tanh
 * tex2D
 * tex2Dgrad
 * tex2Dlod
 * tex2Dproj
 * transpose
 * trunc
 *
 * In addition to these standard intrinsics, ReShade has a few additional ones:
 *
 * float4 tex2Dfetch(sampler2D s, int2 coords)
 *     > Fetches a value from the texture directly without any sampling.
 * float4 tex2Dgather(sampler2D s, float2 coords, int comp)
 *     > Gathers  the  specified  component of the  four neighboring pixels  and
 *       returns the result.
 * float4 tex2Dgatheroffset(sampler2D s, float2 coords, int2 offset, int comp)
 * float4 tex2Dlodoffset(sampler2D s, float4 coords, int2 offset)
 * float4 tex2Doffset(sampler2D s, float2 coords, int2 offset)
 *     > Offsets the texture coordinates before sampling.
 * int2 tex2Dsize(sampler2D s, int lod)
 *     > Gets the texture dimensions.
 *
 * Statements:
 * ~~~~~~~~~~~
 *
 * if ([condition]) { [statement...] } [else { [statement...] }]
 *      > Statements after if are only executed  if condition is true, otherwise
 *        the ones after else are executed (if it exists).
 * switch ([expression]) { [case [constant]/default]: [statement...] }
 *      > Selects the case matching the switch expression or default if non does
 *        and it exists.
 * for ([declaration]; [condition]; [iteration]) { [statement...] }
 *      > Runs the statements in the body as long as the condition is true.  The
 *        iteration expression is executed after each run.
 * while ([condition]) { [statement...] }
 *      > Runs the statements in the body as long as the condition is true.
 * do { [statement...] } while ([condition]);
 *      > Similar to a normal while loop with the difference that the statements
 *        are executed at least once.
 *
 * break;
 *      > Breaks out  of the current loop or switch  statement and jumps  to the
 *        statement after.
 * continue;
 *      > Jumps directly  to the  next loop iteration ignoring any  left code in
 *        the current one.
 * return [expression];
 *      > Jumps out of the current function, optionally providing a value to the
 *        caller.
 * discard;
 *      > Abort rendering  of the current pixel and step out of the shader.  Can
 *        be used in pixel shaders only.
 */

namespace MyNamespace
{
	float4 DoNothing(
		float4 color)
	{
		return color;
	}
}

// Semantics  are  used to tell the  runtime which arguments to connect  between
// shader stages. They are ignored on non-entry-point functions (those  not used
// in any pass below). Semantics starting with  "SV_" are system value semantics
// and serve a special meaning.
// The following vertex shader demonstrates how to generate a simple  fullscreen
// triangle with the three vertices provided by ReShade (http://redd.it/2j17wk):

void ExampleVS(
	in uint id : SV_VertexID,
	out float4 position : SV_Position,
	out float2 texcoord : TEXCOORD0)
{
	texcoord.x = (id == 2) ? 2.0 : 0.0;
	texcoord.y = (id == 1) ? 2.0 : 0.0;
	position = float4(texcoord * float2(2, -2) + float2(-1, 1), 0, 1);
}

// The following pixel shader simply returns the color of the games output again
// without modifying it:

void ExamplePS0(
	in float4 pos : SV_Position,
	in float2 texcoord : TEXCOORD0,
	out float4 color : SV_Target)
{
	// Most known shader intrinsics and a bunch of new ones are available.
	// Here "tex2D" is used to sample from the frame color texture using the
	// "samplerColor" sampler from above:
	color = tex2D(samplerColor, texcoord);
	
	// You can declare  local variables and use them in the scope they  were
	// declared.
	bool myBool = false;
	int myInt = 0;
	uint myUint = 0u;
	float myFloat = 0.0f;
	
	// You can call functions  declared above. The "::" operator  is used to
	// access variables or functions inside namespaces.
	color = MyNamespace::DoNothing(color);
}

// The following pixel shader takes the output of the previous pass and adds the
// depthbuffer content to the right screen side.

float4 ExamplePS1(
	in float4 pos : SV_Position,
	in float2 texcoord : TEXCOORD0) : SV_Target
{
	// Here color information is  sampled with "samplerTarget" and thus from
	// "texTarget", which was set as rendertarget  in the previous pass (see
	// the technique definition below) and now contains its output.
	// In this case it  is the game output, but downsampled  to half because
	// the texture is only half of the screen size.
	
	float4 color = tex2D(samplerTarget, texcoord);
	
	// Only execute the following code when on the right half of the screen.
	
	if (texcoord.x > 0.5f)
	{
		// Sample from the game depthbuffer  using "samplerDepth", which
		// samples from "texDepth" texture.
		
		float depth = tex2D(samplerDepth, texcoord).r;
		
		// Linearize the depth values to better visualize them.
		
		depth = 2.0 / (-99.0 * depth + 101.0);
		
		// Return that value.
		
		color.rgb = depth.rrr;
	}
	
	return color;
}

/**
 * Techniques:
 * -----------
 *
 * An effect file can have  multiple techniques, each representing a full render
 * pipeline, which is executed to apply post-processing effects.
 * ReShade executes all enabled techniques in the order they were defined in the
 * effect file.
 *
 * Annotations:
 * ~~~~~~~~~~~~
 *
 * technique tech1 < enabled = true; > { ... }
 *      > Enable (or disable if false) this technique by default.
 * technique tech2 < timeout = 1000; > { ... }
 *      > Auto-toggle this technique off 1000 milliseconds after it was enabled.
 * technique tech3 < toggle = 0x20; > { ... }
 *      > Toggle this technique when the specified keycode is pressed.
 * technique tech3 < toggleTime = 100; > { ... }
 *      > Toggle this technique at the specified time (seconds after midnight).
 *
 */

technique Example < enabled = true; >
{
	// A technique is made up of one or more passes which contain info about
	// which renderstates to set and what shaders to execute.  They are run
	// sequentially starting with the top most declared. A name is optional.

	pass p0
	{
		// Each pass can set renderstates. The  default value is used if
		// one is not specified in the pass body.
		
		// The following  two accept function names declared above which
		// are used as entry points for the shader.
		// Please note that all parameters must have an associated
		// semantic so the runtime can match them between shader stages.
		
		VertexShader = ExampleVS;
		PixelShader = ExamplePS0;
		
		// RenderTarget0 to RenderTarget7  allow you to  set one or more
		// rendertargets for rendering to textures.
		// Set  them to a  texture name declared above in order to write
		// the color output (SV_Target0 to RenderTarget0, SV_Target1  to
		// RenderTarget1, ...) to this texture in this pass.
		// If  multiple  rendertargets are used, the dimensions  of them
		// has to match each other.
		// If no rendertargets are set here, RenderTarget0 points to the
		// backbuffer.
		// Be aware that  you can  only read OR  write a  texture at the
		// same time, so  don't sample from it while it's still bound as
		// render target here.
		// RenderTarget and RenderTarget0 are aliases.
		
		RenderTarget = texTarget;
		
		// The following renderstates  set various other  parameters for
		// rendering.
		
		// The mask applied to the color  output before it is written to
		// the rendertarget.

		RenderTargetWriteMask = 0xF; // or ColorWriteEnable
		
		// Enable or disable gamma correction applied to the output.

		SRGBWriteEnable = FALSE;
		
		// Enable or disable the depth and stencil tests.
		// The depthstencil is cleared at the start of a technique.
		
		DepthEnable = FALSE; // or ZEnable
		StencilEnable = FALSE;
		
		// Enable or  disable  writing to the  internal depthbuffer  for
		// depth testing.

		DepthWriteMask = FALSE; // or ZWriteEnable
		
		// The function used for depth testing.
		// Available values:
		//   NEVER, ALWAYS
		//   EQUAL, NEQUAL or NOTEQUAL
		//   LESS, GREATER, LEQUAL or LESSEQUAL, GEQUAL or GREATEREQUAL

		DepthFunc = ALWAYS; // or ZFunc
		
		// The masks applied before reading from/writing to the stencil.
		// Available values:
		//   0-255

		StencilReadMask = 0xFF; // or StencilMask
		StencilWriteMask = 0xFF;
		
		// The reference value used with the stencil function.

		StencilRef = 0;
		
		// The function used for stencil testing.
		// Available values:
		//   NEVER, ALWAYS
		//   EQUAL, NEQUAL or NOTEQUAL
		//   LESS, GREATER, LEQUAL or LESSEQUAL, GEQUAL or GREATEREQUAL

		StencilFunc = ALWAYS;
		
		// The operation  to  perform  on  the stencil  buffer when  the
		// stencil  test passed/failed or stencil passed  but depth test
		// failed.
		// Available values:
		//   KEEP, ZERO, REPLACE, INCR, INCRSAT, DECR, DECRSAT, INVERT

		StencilPassOp = KEEP; // or StencilPass
		StencilFailOp = KEEP; // or StencilFail
		StencilDepthFailOp = KEEP; // or StencilZFail
	}
	pass p1
	{
		VertexShader = ExampleVS;
		PixelShader = ExamplePS1;
	}
}
