/*
===========================================================================
Copyright (C) 2024 Gian 'myT' Schellenbaum

This file is part of Challenge Quake 3 (CNQ3).

Challenge Quake 3 is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.

Challenge Quake 3 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Challenge Quake 3. If not, see <https://www.gnu.org/licenses/>.
===========================================================================
*/
// accumulation depth of field: debug overlay


#include "common.hlsli"
#include "fullscreen.hlsli"
#include "dof.hlsli"


cbuffer RootConstants
{
	matrix mvp; // displaced view, to project to CS
	matrix invMvp; // main view, to unproject to WS
	uint colorTextureIndex;
	uint depthTextureIndex;
	uint debugMode; // 1: colorized coc, 2: constant intensity far field
	int tcScale;
	float focusDist;
	float linearDepthA; // main view, to unproject to WS
	float linearDepthB;
	float maxNearCocCS;
	float maxFarCocCS;
};

float4 ps(VOut input) : SV_Target
{
	Texture2D colorTexture = ResourceDescriptorHeap[colorTextureIndex];
	Texture2D<float> depthTexture = ResourceDescriptorHeap[depthTextureIndex];

	int3 tcColor = int3(input.position.xy, 0);
	int3 tcDepth = int3(input.position.xy / tcScale, 0);
	float3 color = colorTexture.Load(tcColor).rgb;
	float depthZW = depthTexture.Load(tcDepth);
	float depth = LinearDepth(depthZW, linearDepthA, linearDepthB);
	bool nearField = depth < focusDist;
	float4 result;
	if(debugMode == 1)
	{
		float quadPosXCS = input.texCoords.x * 2.0 - 1.0;
		float quadPosYCS = (1.0 - input.texCoords.y) * 2.0 - 1.0;
		float4 positionWS = mul(invMvp, float4(quadPosXCS, quadPosYCS, depthZW, 1));
		float4 positionCS = mul(mvp, float4(positionWS.xyz / positionWS.w, 1));
		float coc = distance(positionCS.xy / positionCS.w, float2(quadPosXCS, quadPosYCS));
		result = DOF_DebugCoc(color, nearField, saturate(coc / maxNearCocCS), saturate(coc / maxFarCocCS));
	}
	else if(debugMode == 2)
	{
		result = DOF_DebugFocusPlane(color, nearField);
	}
	else
	{
		result = float4(color, 1);
	}

	return result;
}
