cbuffer ConstantBufferWorld : register( b0 )
{
	matrix WorldViewProj : WORLDVIEWPROJ;
	matrix WorldView : WORLDVIEW;
	matrix Proj : PROJ;
	float2 ClipPlane;	// [Front, Back] (will align 16 bytes)
	float3 LightDir;	// (will align 16 bytes)
	float3 ViewDir;		// (will align 16 bytes)
	float3 CameraPos;		// (will align 16 bytes)
	int2 Resolution;
	float PointSize;
	float LineWidth;
	matrix ShadowMapProj;
	int OITRenderMode;
	float BackLineAlpha;
	int AlphaBlendMode; // 0.disable 1.enable 2.OIT
	int ColorSpace; // 0.SRGB 1.Linear
	float4 BackFaceColor;
	float3 NormalMapFlip; // (will align 16 bytes)
}

cbuffer ConstantBufferClipPlane : register( b3 )
{
	int ArbClipPlaneNum;
	float4 ArbClipPlane[4];// Arbitrary clip plane
}

bool IsArbClipped(float3 WorldPos)
{
	for(int i=0; i<ArbClipPlaneNum; i++){
		if(any(ArbClipPlane[i].xyz)){
			if(dot(WorldPos.xyz, ArbClipPlane[i].xyz) + ArbClipPlane[i].w < 0)
				return true;
		}
	}
	return false;
}


#ifndef SRGB_LINEAR_COLOR_SPACE
#define SRGB_LINEAR_COLOR_SPACE 1
#endif

float SRGBtoLINEAR(float c)
{
#if SRGB_LINEAR_COLOR_SPACE
    return (c < 0.04045) ? c*0.0773993808 : pow(abs(c*0.9478672986+0.0521327014), 2.4);
#else
	return pow(c, 2.2);
#endif
}

float3 SRGBtoLINEAR(float3 srgbIn)
{
#if SRGB_LINEAR_COLOR_SPACE
	return float3(
		SRGBtoLINEAR(srgbIn.x),
		SRGBtoLINEAR(srgbIn.y),
		SRGBtoLINEAR(srgbIn.z));
#else
	return pow(abs(srgbIn),2.2);
#endif
}

float4 SRGBtoLINEAR(float4 srgbIn)
{
	float3 linOut = SRGBtoLINEAR(srgbIn.xyz);
	return float4(linOut,srgbIn.w);
}

float3 SRGBtoLINEAR(float3 srgbIn, bool is_srgb)
{
	if(is_srgb)
		return SRGBtoLINEAR(srgbIn);
	else
		return srgbIn;
}

float4 SRGBtoLINEAR(float4 srgbIn, bool is_srgb)
{
	if(is_srgb){
		float3 linOut = SRGBtoLINEAR(srgbIn.xyz);
		return float4(linOut,srgbIn.w);
	}else{
		return srgbIn;
	}
}


float LINEARtoSRGB(float c)
{
#if SRGB_LINEAR_COLOR_SPACE
    return (c < 0.0031308) ? c * 12.92 : 1.055 * pow(abs(c), 0.41666) - 0.055;
#else
	return pow(abs(c),1.0/2.2);
#endif
}

float3 LINEARtoSRGB(float3 srgbIn)
{
#if SRGB_LINEAR_COLOR_SPACE
	return float3(
		LINEARtoSRGB(srgbIn.x),
		LINEARtoSRGB(srgbIn.y),
		LINEARtoSRGB(srgbIn.z));
#else
	return pow(abs(srgbIn),1.0/2.2);
#endif
}

float4 LINEARtoSRGB(float4 srgbIn)
{
	float3 linOut = LINEARtoSRGB(srgbIn.xyz);
	return float4(linOut,srgbIn.w);
}

float3 LINEARtoSRGB(float3 srgbIn, bool is_srgb)
{
	if(is_srgb)
		return LINEARtoSRGB(srgbIn.xyz);
	else
		return srgbIn;
}

float4 LINEARtoSRGB(float4 srgbIn, bool is_srgb)
{
	if(is_srgb){
		float3 linOut = LINEARtoSRGB(srgbIn.xyz);
		return float4(linOut,srgbIn.w);
	}else{
		return srgbIn;
	}
}

