#ifndef X2M_LWRP_COMMON_INCLUDED
#define X2M_LWRP_COMMON_INCLUDED

#include "../../Common/Template Shader/Transforms.hlsl"

// ����
#define X2M_PI 3.14159265359
#define X2M_DEG2RAD(deg) (0.0174532925199433f*(deg))
// ����
#define X2M_TEXTURE_DEPTH        _CameraDepthTexture
#define X2M_SAMPLER_DEPTH        sampler##X2M_TEXTURE_DEPTH

#define X2M_TEXTURE_DEPTH_NORMAL _CameraDepthNormalsTexture
#define X2M_SAMPLER_DEPTH_NORMAL sampler##X2M_TEXTURE_DEPTH_NORMAL

#define X2M_TEXTURE_BACKGROUND   _CameraOpaqueTexture
#define X2M_SAMPLER_BACKGROUND   sampler##X2M_TEXTURE_BACKGROUND

// ����
#define X2M_TEX2D_PARAM(_Tex) TEXTURE2D_PARAM(_Tex, sampler##_Tex)
#define X2M_TEX2D_ARGS(_Tex)  TEXTURE2D_ARGS(_Tex, sampler##_Tex)
// ����
#define X2M_DECLARE_TEX2D(_Tex)       TEXTURE2D(_Tex); SAMPLER(sampler##_Tex);
#define X2M_DECLARE_TEX2D_FLOAT(_Tex) TEXTURE2D_FLOAT(_Tex); SAMPLER(sampler##_Tex);
#define X2M_DECLARE_TEX2D_SHADOW(_Tex) TEXTURE2D_SHADOW(_Tex); SAMPLER_CMP(sampler##_Tex);

#define X2M_DECLARE_TEX2D_DEPTH        X2M_DECLARE_TEX2D_FLOAT(X2M_TEXTURE_DEPTH);
#define X2M_DECLARE_TEX2D_BACKGROUND   X2M_DECLARE_TEX2D(X2M_TEXTURE_BACKGROUND);
#define X2M_DECLARE_TEX2D_DEPTH_NORMAL X2M_DECLARE_TEX2D(X2M_TEXTURE_DEPTH_NORMAL);
// ����
#define X2M_SAMPLE_TEX2D(_Tex, uv)        SAMPLE_TEXTURE2D(_Tex, sampler##_Tex, uv)
#define X2M_SAMPLE_TEX2D_FLOAT(_Tex, uv)  SAMPLE_TEXTURE2D(_Tex, sampler##_Tex, uv).r
#define X2M_SAMPLE_TEX2D_LOD(_Tex, uv)    SAMPLE_TEXTURE2D_LOD(_Tex, sampler##_Tex, uv.xy,uv.w) /*xy: uv, w:lod*/
#define X2M_SAMPLE_TEX2D_PROJ(_Tex, uv)   SAMPLE_TEXTURE2D(_Tex, sampler##_Tex, uv.xy/uv.w)
#define X2M_SAMPLE_TEX2D_SHADOW(_Tex, uv) SAMPLE_TEXTURE2D_SHADOW(_Tex,sampler##_Tex,uv)

//����
#define X2M_LOAD_TEX2D(_Tex, index2)          LOAD_TEXTURE2D(_Tex, index2)    
#define X2M_LOAD_TEX2D_LOD(_Tex, index2,lod)  LOAD_TEXTURE2D_LOD(_Tex, index2, lod)  

#define X2M_LOAD_TEX2DUV(_Tex, uv)            LOAD_TEXTURE2D(_Tex, uv * _Tex##_TexelSize.zw)   
#define X2M_LOAD_TEX2DUV_LOD(_Tex, uv,lod)    LOAD_TEXTURE2D_LOD(_Tex, uv * _Tex##_TexelSize.zw,lod)   
#define X2M_LOAD_TEX2DUV_PROJ(_Tex,uv)        X2M_LOAD_TEX2DUV(_Tex,(uv.xy/uv.w))


#define X2M_SAMPLE_TEX2D_DEPTH(uv)          SAMPLE_DEPTH_TEXTURE(X2M_TEXTURE_DEPTH,X2M_SAMPLER_DEPTH, uv) //����SAMPLE_DEPTH_TEXTURE(TEXTURE2D_ARGS(X2M_TEXTURE_DEPTH), uv) GLES���벻��
#define X2M_SAMPLE_TEX2D_DEPTH_NORMAL(uv)   X2M_SAMPLE_TEX2D(X2M_TEXTURE_DEPTH_NORMAL, uv)
#define X2M_SAMPLE_TEX2D_BACKGROUND(uv)     X2M_SAMPLE_TEX2D(X2M_TEXTURE_BACKGROUND, uv)

#define X2M_SAMPLE_TEX2DPROJ_DEPTH(screenpos)        X2M_SAMPLE_TEX2D_DEPTH(screenpos.xy / screenpos.w)
#define X2M_SAMPLE_TEX2DPROJ_DEPTH_NORMAL(screenpos) X2M_SAMPLE_TEX2D_PROJ(X2M_TEXTURE_DEPTH_NORMAL,screenpos)
#define X2M_SAMPLE_TEX2DPROJ_BACKGROUND(screenpos)   X2M_SAMPLE_TEX2D_PROJ(X2M_TEXTURE_BACKGROUND,  screenpos)

// һЩ����
#define X2M_LINEAR_EYE_DEPTH(screenpos)                        LinearEyeDepth(screenpos.z / screenpos.w, _ZBufferParams)

#define X2M_LINEAR_EYE_DEPTH_FROM_NONLINEAR_DEPTH(nonlinear)   LinearEyeDepth(nonlinear, _ZBufferParams)
#define X2M_LINEAR_EYE_DEPTH_FROM_DEPTH_TEXTURE(screenpos)     LinearEyeDepth(X2M_SAMPLE_TEX2DPROJ_DEPTH(screenpos), _ZBufferParams)

#define X2M_LINEAR_EYE_DEPTH01_FROM_NONLINEAR_DEPTH(nonlinear) Linear01Depth (nonlinear, _ZBufferParams)
#define X2M_LINEAR_EYE_DEPTH01_FROM_DEPTH_TEXTURE(screenpos)   Linear01Depth (X2M_SAMPLE_TEX2DPROJ_DEPTH(screenpos), _ZBufferParams)

// Transforms normal from object to world space
inline float3 UnityObjectToWorldNormal(in float3 norm)
{
	/*
	#ifdef UNITY_ASSUME_UNIFORM_SCALING
	return UnityObjectToWorldDir(norm);
	#else*/
	// mul(IT_M, norm) => mul(norm, I_M) => {dot(norm, I_M.col0), dot(norm, I_M.col1), dot(norm, I_M.col2)}
	return normalize(mul(norm, (float3x3)unity_WorldToObject));
	/*#endif*/
}

//float3 TransformObjectToWorld(float4 positionOS)
//{
//	return TransformObjectToWorld(positionOS.xyz);
//}
float3 TransformObjectToView(float3 positionOS)
{
	return UnityObjectToViewPos(positionOS);
}
float3 TransformObjectToView(float4 positionOS)
{
	return UnityObjectToViewPos(positionOS);
}
float4 TransformObjectToClip(float3 positionOS)
{
	return TransformObjectToHClip(positionOS);
}
float4 TransformObjectToClip(float4 positionOS)
{
	return TransformObjectToHClip(positionOS.xyz);
}
float3 TransformViewToWorld(float4 positionVS)
{
	return mul(unity_CameraToWorld, positionVS).xyz;
}
float3 TransformViewToWorld(float3 positionVS)
{
	return TransformViewToWorld(float4(positionVS, 1.0f)).xyz;
}

#endif //X2M_LWRP_COMMON_INCLUDED