#ifndef VOLUMETRIC_FOG_FOR_OBJECT
#define VOLUMETRIC_FOG_FOR_OBJECT

TEXTURE2D(_g_volumetric_fog_texture);			SAMPLER(sampler_g_volumetric_fog_texture);
uniform half USE_VOLUMETRIC_FOG;

static const half _volumetric_fog_texture3d_width = 32;;
static const half _volumetric_fog_texture3d_height = 32;;
static const half _volumetric_fog_texture3d_inv_height = 1.0 / 32.0;;
static const half _volumetric_fog_texture3d_depth = 16;;
static const float _volumetric_fog_texture2d_width = _volumetric_fog_texture3d_width * _volumetric_fog_texture3d_height;;
static const half _volumetric_fog_texture2d_height = _volumetric_fog_texture3d_depth;;
static const float _volumetric_fog_texture2d_half_pixel = 0.5 / _volumetric_fog_texture2d_width;;
static const half _volumetric_fog_texture3d_inv_depth = 1.0 / _volumetric_fog_texture3d_depth;;

static const half _volumetric_fog_depth_range = 128.0; //< Depth range R
static const half _volumetric_fog_curve_power = 2.0;
static const half _volumetric_fog_inv_curve_power = 1.0 / _volumetric_fog_curve_power; //< Inv . power ( 1 . 0 / C)

float4 VolumetricFog_GetFogCoord(float4 ndc, float zInCamera)
{
	float4 ret = float4(ndc.xy, 
#if UNITY_UV_STARTS_AT_TOP
		zInCamera * _ProjectionParams.x, 
#else
		// ?????
		-zInCamera * _ProjectionParams.x,
#endif
		ndc.w);
	return ret;
}

// [0, 1]
float VolumetricFog_GetLookupDepth(float inViewSpaceDepth)
{
	return clamp(pow((inViewSpaceDepth / _volumetric_fog_depth_range), _volumetric_fog_inv_curve_power), 0, 1);
	
	/*int a = clamp(pow((inViewSpaceDepth / _volumetric_fog_depth_range), _volumetric_fog_inv_curve_power), 0, 1) * 16;
	int b = a + 1;
	
	int c = pow((float)a / 16.0, 2.0) * 128;
	int d = pow((float)b / 16.0, 2.0) * 128;

	float f = (float)(inViewSpaceDepth - c) / (float)(d - c);

	float g = clamp(pow(((float)c / _volumetric_fog_depth_range), _volumetric_fog_inv_curve_power), 0, 1);

	return g + f * 1.0 / 16.0;*/

	/*float a = clamp(pow((inViewSpaceDepth / _volumetric_fog_depth_range), _volumetric_fog_inv_curve_power), 0, 1);
	float b = fmod(a, 1.0 / 16.0);
	float a2 = a - b;
	float b2 = a2 + 1.0 / 16.0;
	float a3 =a2 * 128;
	float b3 =b2 * 128;
	float c = inViewSpaceDepth - a3;
	c /= (b3 - a3);
	c *= 1.0 / 16.0;
	return a2 + c;*/


	//return clamp(inViewSpaceDepth / 128, 0, 1);

}

// screenPos.xy is screen pos [0, 1], screenPos.z is the distance from camera
half3 VolumetricFog_GetFog(half3 pixelColorWithoutFog, float4 screenPos)
{
	//float2 uv = float2(
	//	//(screenPos.x * _volumetric_fog_texture3d_width + screenPos.y * _volumetric_fog_texture3d_height * _volumetric_fog_texture3d_width) / _volumetric_fog_texture2d_width;
	//	screenPos.x * _volumetric_fog_texture3d_inv_height + screenPos.y,
	//	VolumetricFog_GetLookupDepth(screenPos.z)
	//	);
	//
	//// Read volumetric in - scattering and transmittance
	//half4 scatteringInformation = SAMPLE_TEXTURE2D(_g_volumetric_fog_texture, sampler_g_volumetric_fog_texture, uv);

	screenPos.xy /= screenPos.w;

	float t = fmod(screenPos.y, _volumetric_fog_texture3d_inv_height);
	float y = screenPos.y - t;
	t *= _volumetric_fog_texture3d_height;

	float2 uv0 = float2(
		//(clamp((int)(screenPos.x * _volumetric_fog_texture3d_width), 1, _volumetric_fog_texture3d_width - 1) + (int)(screenPos.y * _volumetric_fog_texture3d_height) * _volumetric_fog_texture3d_width) / _volumetric_fog_texture2d_width,
		clamp(screenPos.x * _volumetric_fog_texture3d_inv_height, _volumetric_fog_texture2d_half_pixel, _volumetric_fog_texture3d_inv_height - _volumetric_fog_texture2d_half_pixel) + y,
		VolumetricFog_GetLookupDepth(screenPos.z)
		);



	float2 uv1 = uv0 + float2(_volumetric_fog_texture3d_inv_height, 0);


	//// Read volumetric in - scattering and transmittance
	half4 scatteringInformation0 = SAMPLE_TEXTURE2D(_g_volumetric_fog_texture, sampler_g_volumetric_fog_texture, uv0);

	half4 scatteringInformation1 = 0;
	if (uv1.x >= 0 && uv1.x <= 1 && uv1.y >= 0 && uv1.y <= 1)
		scatteringInformation1 = SAMPLE_TEXTURE2D(_g_volumetric_fog_texture, sampler_g_volumetric_fog_texture, uv1);


	half4 scatteringInformation = scatteringInformation0 * (1.0 - t) + scatteringInformation1 * t;
	float3 inScattering = scatteringInformation.rgb;
	float transmittance = scatteringInformation.a;
	// Apply to lit pixel

    float3 finalPixelColor = lerp(pixelColorWithoutFog, pixelColorWithoutFog * transmittance + inScattering, USE_VOLUMETRIC_FOG);
	
	return finalPixelColor;
	
}



#endif // VOLUMETRIC_FOG_FOR_OBJECT