/***************************************************************************
 *                         Zanoza Modeler v3.3.x                           *
 *     This is unpublished proprietary source code of Zanoza Software.     *
 *      The copyright notice does not evidence any actual or intended      *
 *                    publication of such source code.                     *
 *                                                                         *
 *                 Copyright (c) 2002-2024 Zanoza Software.                *
 *                                                                         *
 *                        All rights reserved.                             *
 ***************************************************************************
 *--------------------------------------------------------------------------
 * @author:   Oleg M.
 *--------------------------------------------------------------------------
 * @purpose:  ZModeler 3.3.x Pure (no parameters) screen-space textured shader
 *--------------------------------------------------------------------------
 * @history: 17.02.2023. Created
 * @Description:
   Shader for default rendering (with no materials). Used to draw 
   general-purpose geometry in viewports like wireframe, primitives,
   on-screen grid and other elements with flexible vertices format.
   This version of shader includes light-specific computations 
   and expects vertices to be shipped with normals.
<[[
UserName = "Light-shaded Wireframe/solid"
Version  = 2.0.1
Options  = PURE
Engine = 11
]]>
*/

#pragma pack_matrix( row_major ) 

struct VS_INPUT
{
    float4 vPosition        : SV_POSITION;
    float4 vNormal          : NORMAL;
    float4 vTangent         : TANGENT;
    float4 vColorDif        : COLOR0;
    float4 vDeformPosition  : TEXCOORD5;
    float4 vDeformNormal    : COLOR2;
    uint4  vBones0          : BLENDINDICES0;
    uint4  vBones1          : BLENDINDICES1;
    float4 vWeights0        : BLENDWEIGHT0;
    float4 vWeights1        : BLENDWEIGHT1;
};

struct VS_OUTPUT
{
    float4  vPosition : SV_POSITION;
    float4  vDiffuse  : COLOR;
};

#include "zmCommonBuffers.inl"
#include "zmCommonRoutines.inl"

#ifdef GEOMETRY_SHADER
//
// point expand to bilboard quad geometry shader:
[maxvertexcount(4)]
void pointGS(point VS_OUTPUT ptIn[1], inout TriangleStream<VS_OUTPUT> tristream)
{
  VS_OUTPUT gout;
  [unroll]
  for (int i = 0; i < 4; i++)
  {
    gout = ptIn[0];
    float2 vOffset2D = (float2(i&1, i>>1)*2 - 1)*g_geomLevels.x;
    vOffset2D = vOffset2D*g_viewport.zw;
    gout.vPosition.xy += vOffset2D*gout.vPosition.w;
    tristream.Append(gout);
  }
}

#endif //GEOMETRY_SHADER

#ifdef VERTEX_SHADER
VS_OUTPUT mainVS(in VS_INPUT v)
{
  VS_OUTPUT output;
  //transform to screen:
  float4 vNorm    = v.vNormal;
  float4 vTangent = v.vTangent;
  float4 vViewer  = (float4)0;

  output.vPosition = transformInput(v, output.vPosition, vNorm, vTangent, vViewer);

  //
  // basic diffuse blend (per-vertex and material)
  float4 vertColor = (any(v.vColorDif.rgb) ? v.vColorDif : 1);
  float4 color = lerp(1, g_colors[1], g_colorBlend.y) * 
                 lerp(1, vertColor, g_colorBlend.x);

  //dim on diffuse light (respect emissive):
  float3 normal = normalize(vNorm.xyz);
  color.rgb = (g_colors[0].rgb + 0.2*v.vColorDif.rgb + 0.2*g_ambientLight.rgb)*g_ambientLight.rgb +
              color.rgb*saturate(saturate(dot(-g_lightDir.xyz, normal)) + g_colorBlend.z + g_colors[3].w);

  //
  // add global emissive:
  color.rgb += g_colors[3].rgb*g_colors[3].w;

  //
  // desaturate on back-facing: color level:
  vViewer.w = step(0, dot(vViewer.xyz, vNorm.xyz));
  color.rgb = lerp(dot(color.rgb, float3(0.3, 0.59, 0.11)), color.rgb, 
                          saturate(g_faders.x + vViewer.w));
  color.a = g_colors[1].a*lerp(1, vertColor.a, g_colorBlend.a)*
			saturate(g_faders.y + vViewer.w);//fade on back-facing;

  output.vDiffuse = color;
  return output;
}
#endif //VERTEX_SHADER

float4 mainPS(in VS_OUTPUT v) : SV_TARGET
{
  return v.vDiffuse;
}
