Skip to content

Crash translating hull shader outputs #32

@davidrogers-unity

Description

@davidrogers-unity

I've encountered problem with translating hull shaders. GetOutputSignatureFromRegister in AddUserOutput returns a null reference. It appears that there is trouble when join phases have a lot of dcl_output instructions. After 8-10 instructions the register numbers get out of whack and the output signature cannot be retrieved.

Here is source to reproduce the issue, compiled with this command.
fxc.exe /Od /Gec /T hs_5_0 /Fo test.o /E HS_PNTriangles test.hlsl

#line 10 ""
#ifdef DUMMY_PREPROCESSOR_TO_WORK_AROUND_HLSL_COMPILER_LINE_HANDLING
#endif

#line 1 "HLSLSupport.cginc"
#ifndef HLSL_SUPPORT_INCLUDED
#define HLSL_SUPPORT_INCLUDED


#if defined(SHADER_API_D3D11) || defined(SHADER_API_XBOX360) || defined(SHADER_API_D3D11_9X) || defined(VAR_COMPILER_HLSLCC) || defined(SHADER_API_D3D9)
#define VAR_COMPILER_HLSL
#elif defined(SHADER_TARGET_GLSL)
#define VAR_COMPILER_HLSL2GLSL
#else
#define VAR_COMPILER_CG
#endif

#if !defined(SV_Target)
#   if defined(SHADER_API_PSSL)
#       define SV_Target S_TARGET_OUTPUT
#   elif !defined(SHADER_API_XBOXONE)
#       define SV_Target COLOR
#   endif
#endif


#if !defined(SV_Target0)
#   if defined(SHADER_API_PSSL)
#       define SV_Target0 S_TARGET_OUTPUT0
#   elif !defined(SHADER_API_XBOXONE)
#       define SV_Target0 COLOR0
#   endif
#endif


#if !defined(SV_Target1)
#   if defined(SHADER_API_PSSL)
#       define SV_Target1 S_TARGET_OUTPUT1
#   elif !defined(SHADER_API_XBOXONE)
#       define SV_Target1 COLOR1
#   endif
#endif

#if !defined(SV_Target2)
#   if defined(SHADER_API_PSSL)
#       define SV_Target2 S_TARGET_OUTPUT2
#   elif !defined(SHADER_API_XBOXONE)
#       define SV_Target2 COLOR2
#   endif
#endif

#if !defined(SV_Target3)
#   if defined(SHADER_API_PSSL)
#       define SV_Target3 S_TARGET_OUTPUT3
#   elif !defined(SHADER_API_XBOXONE)
#       define SV_Target3 COLOR3
#   endif
#endif



#if !defined(SV_Depth)
#   if defined(SHADER_API_PSSL)
#       define SV_Depth S_DEPTH_OUTPUT
#   elif !defined(SHADER_API_XBOXONE)
#       define SV_Depth DEPTH
#   endif
#endif

#if defined(SHADER_API_PSSL)
// compute shader defines
#define StructuredBuffer RegularBuffer
#define SV_VertexID S_VERTEX_ID

#endif 

#if defined(VAR_COMPILER_HLSL)
#pragma warning (disable : 3205) // conversion of larger type to smaller
#pragma warning (disable : 3568) // unknown pragma ignored
#endif

#if !defined(SHADER_TARGET_GLSL) && !defined(SHADER_API_PSSL)
#define fixed half
#define fixed2 half2
#define fixed3 half3
#define fixed4 half4
#define fixed4x4 half4x4
#define fixed3x3 half3x3
#define fixed2x2 half2x2
#define sampler2D_half sampler2D
#define sampler2D_float sampler2D
#define samplerCUBE_half samplerCUBE
#define samplerCUBE_float samplerCUBE
#endif

#if defined(SHADER_API_PSSL)
#define uniform
#define half float
#define half2 float2
#define half3 float3
#define half4 float4
#define half2x2 float2x2
#define half3x3 float3x3
#define half4x4 float4x4
#define fixed float
#define fixed2 float2
#define fixed3 float3
#define fixed4 float4
#define fixed4x4 half4x4
#define fixed3x3 half3x3
#define fixed2x2 half2x2
#define samplerCUBE_half samplerCUBE
#define samplerCUBE_float samplerCUBE

#define CBUFFER_START(name) ConstantBuffer name {
#define CBUFFER_END };
#elif !defined(VAR_COMPILER_HLSLCC) && (defined(SHADER_API_D3D11) || defined(SHADER_API_D3D11_9X))
#define CBUFFER_START(name) cbuffer name {
#define CBUFFER_END };
#else
#define CBUFFER_START(name)
#define CBUFFER_END
#endif

#if defined(SHADOWS_NATIVE) && defined(SHADER_API_PSSL)
    // PSSL
    #define VAR_DECLARE_SHADOWMAP(tex)      Texture2D tex; SamplerComparisonState sampler##tex
    #define VAR_SAMPLE_SHADOW(tex,coord)        tex.SampleCmpLOD0(sampler##tex,(coord).xy,(coord).z)
    #define VAR_SAMPLE_SHADOW_PROJ(tex,coord)   tex.SampleCmpLOD0(sampler##tex,(coord).xy/(coord).w,(coord).z/(coord).w)
#elif defined(SHADOWS_NATIVE) && (defined(SHADER_API_D3D11) || defined(SHADER_API_D3D11_9X) || defined(VAR_COMPILER_HLSLCC))
    // DX11 syntax for shadow maps
    #define VAR_DECLARE_SHADOWMAP(tex) Texture2D tex; SamplerComparisonState sampler##tex
    #define VAR_SAMPLE_SHADOW(tex,coord) tex.SampleCmpLevelZero (sampler##tex,(coord).xy,(coord).z)
    #define VAR_SAMPLE_SHADOW_PROJ(tex,coord) tex.SampleCmpLevelZero (sampler##tex,(coord).xy/(coord).w,(coord).z/(coord).w)
#elif defined(SHADOWS_NATIVE) && defined(SHADER_TARGET_GLSL)
    // hlsl2glsl syntax for shadow maps
    #define VAR_DECLARE_SHADOWMAP(tex) sampler2DShadow tex
    #define VAR_SAMPLE_SHADOW(tex,coord) shadow2D (tex,(coord).xyz)
    #define VAR_SAMPLE_SHADOW_PROJ(tex,coord) shadow2Dproj (tex,coord)
#elif defined(SHADOWS_NATIVE) && defined(SHADER_API_PSP2) && !defined(SHADER_API_PSM)
    #define VAR_DECLARE_SHADOWMAP(tex) sampler2D tex
    #define VAR_SAMPLE_SHADOW(tex,coord) f1tex2D<float>(tex, (coord).xyz)
    #define VAR_SAMPLE_SHADOW_PROJ(tex,coord) f1tex2Dproj<float>(tex, coord)
#elif defined(SHADOWS_NATIVE) && defined(SHADER_API_D3D9)
    // Native shadow maps hack on D3D9: look just like regular
    // texture sample. Have to always do a projected sample
    // so that HLSL compiler doesn't try to be too smart and mess up swizzles
    // (thinking that Z is unused).
    #define VAR_DECLARE_SHADOWMAP(tex) sampler2D tex
    #define VAR_SAMPLE_SHADOW(tex,coord) tex2Dproj (tex,float4((coord).xyz,1)).r
    #define VAR_SAMPLE_SHADOW_PROJ(tex,coord) tex2Dproj (tex,coord).r
#else
    // Fallback for other platforms: look just like a regular texture sample.
    #define VAR_DECLARE_SHADOWMAP(tex) sampler2D tex
    #define VAR_SAMPLE_SHADOW(tex,coord) tex2D (tex,(coord).xyz).r
    #define VAR_SAMPLE_SHADOW_PROJ(tex,coord) tex2Dproj (tex,coord).r
#endif



// Macros to declare textures and samplers, possibly separately. For platforms
// that have separate samplers & textures (like DX11), and we'd want to conserve
// the samplers.
//  - VAR_DECLARE_TEX2D_NOSAMPLER declares a texture, without a sampler.
//  - VAR_SAMPLE_TEX2D_SAMPLER samples a texture, using sampler from another texture.
//      That another texture must also be actually used in the current shader, otherwise
//      the correct sampler will not be set.
#if defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(VAR_COMPILER_HLSLCC)
#define VAR_DECLARE_TEX2D(tex) Texture2D tex; SamplerState sampler##tex
#define VAR_DECLARE_TEX2D_NOSAMPLER(tex) Texture2D tex
#define VAR_SAMPLE_TEX2D(tex,coord) tex.Sample (sampler##tex,coord)
#define VAR_SAMPLE_TEX2D_SAMPLER(tex,samplertex,coord) tex.Sample (sampler##samplertex,coord)
#else
#define VAR_DECLARE_TEX2D(tex) sampler2D tex
#define VAR_DECLARE_TEX2D_NOSAMPLER(tex) sampler2D tex
#define VAR_SAMPLE_TEX2D(tex,coord) tex2D (tex,coord)
#define VAR_SAMPLE_TEX2D_SAMPLER(tex,samplertex,coord) tex2D (tex,coord)
#endif



#define samplerRECT sampler2D
#define texRECT tex2D
#define texRECTlod tex2Dlod
#define texRECTbias tex2Dbias
#define texRECTproj tex2Dproj

#if defined(SHADER_API_PSSL)
#define VPOS            S_POSITION
#elif defined(VAR_COMPILER_CG)
// Cg seems to use WPOS instead of VPOS semantic?
#define VPOS WPOS
// Cg does not have tex2Dgrad and friends, but has tex2D overload that
// can take the derivatives
#define tex2Dgrad tex2D
#define texCUBEgrad texCUBE
#define tex3Dgrad tex3D
#endif


#if defined(SHADER_API_PSSL)

struct sampler1D {
    Texture1D       t;
    SamplerState    s;
};
struct sampler2D {
    Texture2D       t;
    SamplerState    s;
};
struct sampler2D_float {
    Texture2D       t;
    SamplerState    s;
};
struct sampler3D {
    Texture3D       t;
    SamplerState    s;
};
struct samplerCUBE {
    TextureCube     t;
    SamplerState    s;
};

float4 tex1D(sampler1D x, float v)              { return x.t.Sample(x.s, v); }
float4 tex2D(sampler2D x, float2 v)             { return x.t.Sample(x.s, v); }
float4 tex2D(sampler2D_float x, float2 v)       { return x.t.Sample(x.s, v); }
float4 tex3D(sampler3D x, float3 v)             { return x.t.Sample(x.s, v); }
float4 texCUBE(samplerCUBE x, float3 v)         { return x.t.Sample(x.s, v); }

float4 tex1Dbias(sampler1D x, in float4 t)      { return x.t.SampleBias(x.s, t.x, t.w); }
float4 tex2Dbias(sampler2D x, in float4 t)      { return x.t.SampleBias(x.s, t.xy, t.w); }
float4 tex2Dbias(sampler2D_float x, in float4 t)        { return x.t.SampleBias(x.s, t.xy, t.w); }
float4 tex3Dbias(sampler3D x, in float4 t)      { return x.t.SampleBias(x.s, t.xyz, t.w); }
float4 texCUBEbias(samplerCUBE x, in float4 t)  { return x.t.SampleBias(x.s, t.xyz, t.w); }

float4 tex1Dlod(sampler1D x, in float4 t)       { return x.t.SampleLOD(x.s, t.x, t.w); }
float4 tex2Dlod(sampler2D x, in float4 t)       { return x.t.SampleLOD(x.s, t.xy, t.w); }
float4 tex2Dlod(sampler2D_float x, in float4 t)     { return x.t.SampleLOD(x.s, t.xy, t.w); }
float4 tex3Dlod(sampler3D x, in float4 t)       { return x.t.SampleLOD(x.s, t.xyz, t.w); }
float4 texCUBElod(samplerCUBE x, in float4 t)   { return x.t.SampleLOD(x.s, t.xyz, t.w); }

float4 tex1Dgrad(sampler1D x, float t, float dx, float dy)          { return x.t.SampleGradient(x.s, t, dx, dy); }
float4 tex2Dgrad(sampler2D x, float2 t, float2 dx, float2 dy)       { return x.t.SampleGradient(x.s, t, dx, dy); }
float4 tex2Dgrad(sampler2D_float x, float2 t, float2 dx, float2 dy)     { return x.t.SampleGradient(x.s, t, dx, dy); }
float4 tex3Dgrad(sampler3D x, float3 t, float3 dx, float3 dy)       { return x.t.SampleGradient(x.s, t, dx, dy); }
float4 texCUBEgrad(samplerCUBE x, float3 t, float3 dx, float3 dy)   { return x.t.SampleGradient(x.s, t, dx, dy); }

float4 tex1Dproj(sampler1D s, in float2 t)      { return tex1D(s, t.x / t.y); }
float4 tex1Dproj(sampler1D s, in float4 t)      { return tex1D(s, t.x / t.w); }
float4 tex2Dproj(sampler2D s, in float3 t)      { return tex2D(s, t.xy / t.z); }
float4 tex2Dproj(sampler2D_float s, in float3 t)        { return tex2D(s, t.xy / t.z); }
float4 tex2Dproj(sampler2D s, in float4 t)      { return tex2D(s, t.xy / t.w); }
float4 tex3Dproj(sampler3D s, in float4 t)      { return tex3D(s, t.xyz / t.w); }
float4 texCUBEproj(samplerCUBE s, in float4 t)  { return texCUBE(s, t.xyz / t.w); }

#elif defined(SHADER_API_XBOX360)

float4 tex2Dproj(in sampler2D s, in float4 t) 
{ 
    float2 ti=t.xy / t.w;
    return tex2D( s, ti);
}

float4 tex2Dproj(in sampler2D s, in float3 t) 
{ 
    float2 ti=t.xy / t.z;
    return tex2D( s, ti);
}


#endif

#if defined(VAR_COMPILER_HLSL) || defined (SHADER_TARGET_GLSL)
#define FOGC FOG
#endif

// Use VFACE pixel shader input semantic in your shaders to get front-facing scalar value.
#if defined(VAR_COMPILER_CG)
#define VFACE FACE
#endif
#if defined(VAR_COMPILER_HLSL2GLSL)
#define FACE VFACE
#endif

#if defined(SHADER_API_PSSL)
#define SV_POSITION S_POSITION
#elif !defined(SHADER_API_D3D11) && !defined(SHADER_API_D3D11_9X)
#define SV_POSITION POSITION
#endif


#if (defined(SHADER_API_D3D9) || defined(SHADER_API_XBOX360) || defined(SHADER_API_PS3) || defined(SHADER_API_D3D11) || defined(SHADER_API_D3D11_9X) || defined(SHADER_API_PSP2) || defined(SHADER_API_PSSL)) && !defined(VAR_COMPILER_HLSLCC)
#define VAR_ATTEN_CHANNEL r
#else
#define VAR_ATTEN_CHANNEL a
#endif

#if defined(SHADER_API_D3D9) || defined(SHADER_API_XBOX360) || defined(SHADER_API_PSP2)
#define VAR_HALF_TEXEL_OFFSET
#endif

#if (defined(SHADER_API_D3D9) || defined(SHADER_API_XBOX360) || defined(SHADER_API_PS3) || defined(SHADER_API_D3D11) || defined(SHADER_API_D3D11_9X) || defined(SHADER_API_PSP2) || defined(SHADER_API_PSSL)) && !defined(VAR_COMPILER_HLSLCC)
#define VAR_UV_STARTS_AT_TOP 1
#endif

#if (defined(SHADER_API_D3D9) || defined(SHADER_API_XBOX360) || defined(SHADER_API_PS3) || defined(SHADER_API_D3D11) || defined(SHADER_API_D3D11_9X)) && !defined(VAR_COMPILER_HLSLCC)
#define VAR_NEAR_CLIP_VALUE (0.0)
#else
#define VAR_NEAR_CLIP_VALUE (-1.0)
#endif


#if defined(SHADER_API_D3D9)
#define VAR_MIGHT_NOT_HAVE_DEPTH_TEXTURE
#endif


#if (defined(SHADER_API_OPENGL) && !defined(SHADER_TARGET_GLSL)) || defined(SHADER_API_PSP2)
#define VAR_BUGGY_TEX2DPROJ4
#define VAR_PROJ_COORD(a) (a).xyw
#else
#define VAR_PROJ_COORD(a) a
#endif


// Platforms which do not use cascaded/screenspace shadow maps: more or less "mobile" platforms
#if defined(SHADER_API_GLES) || defined(SHADER_API_GLES3) || defined(SHADER_API_GLES31) || defined(SHADER_API_METAL) || defined(SHADER_API_D3D11_9X)
#define VAR_NO_SCREENSPACE_SHADOWS
#endif

// Platforms which do not use RGBM lightmap compression, or DXT5nm normal map compression
#if defined(SHADER_API_GLES) || defined(SHADER_API_GLES3) || defined(SHADER_API_GLES31) || defined(SHADER_API_METAL)
#define VAR_NO_RGBM
#define VAR_NO_DXT5nm
#endif

// Platforms which can support "framebuffer fetch" on some devices
#if defined(SHADER_API_GLES) || defined(SHADER_API_GLES3) || defined(SHADER_API_GLES31)
#define VAR_FRAMEBUFFER_FETCH_AVAILABLE
#endif


// On most platforms, use floating point render targets to store depth of point
// light shadowmaps. However, on some others they either have issues, or aren't widely
// supported; in which case fallback to encoding depth into RGBA channels.
// Make sure this define matches GraphicsCaps.useRGBAForPointShadows.
#if defined(SHADER_API_GLES) || defined(SHADER_API_PSP2) || defined(SHADER_API_XBOX360) || defined(SHADER_API_PS3)
#define VAR_USE_RGBA_FOR_POINT_SHADOWS
#endif


#if defined(VAR_COMPILER_HLSL) || defined(VAR_COMPILER_HLSLCC)
#define VAR_INITIALIZE_OUTPUT(type,name) name = (type)0;
#else
#define VAR_INITIALIZE_OUTPUT(type,name)
#endif

#if defined(SHADER_API_D3D11) || defined(VAR_COMPILER_HLSLCC)
#define VAR_CAN_COMPILE_TESSELLATION 1
#   define VAR_domain                   domain
#   define VAR_partitioning         partitioning
#   define VAR_outputtopology           outputtopology
#   define VAR_patchconstantfunc        patchconstantfunc
#   define VAR_outputcontrolpoints  outputcontrolpoints
#elif defined(SHADER_API_PSSL)
#   define VAR_CAN_COMPILE_TESSELLATION 1

#   define SV_OutputControlPointID      S_OUTPUT_CONTROL_POINT_ID
#   define SV_TessFactor                S_EDGE_TESS_FACTOR
#   define SV_InsideTessFactor          S_INSIDE_TESS_FACTOR
#   define SV_DomainLocation            S_DOMAIN_LOCATION

#   define VAR_domain                   DOMAIN_PATCH_TYPE
#   define VAR_partitioning         PARTITIONING_TYPE
#   define VAR_outputtopology           OUTPUT_TOPOLOGY_TYPE
#   define VAR_patchconstantfunc        PATCH_CONSTANT_FUNC
#   define VAR_outputcontrolpoints  OUTPUT_CONTROL_POINTS

#   define  domain                      DOMAIN_PATCH_TYPE
#   define  partitioning                PARTITIONING_TYPE
#   define  outputtopology              OUTPUT_TOPOLOGY_TYPE
#   define  patchconstantfunc           PATCH_CONSTANT_FUNC
#   define  outputcontrolpoints         OUTPUT_CONTROL_POINTS

#   define  maxtessfactor               MAX_TESS_FACTOR
#   define  instance                    INSTANCE
#   define  numthreads                  NUM_THREADS
#   define  patchsize                   PATCH_SIZE
#   define  maxvertexcount              MAX_VERTEX_COUNT            
#   define  earlydepthstencil           FORCE_EARLY_DEPTH_STENCIL

#   define  GroupMemoryBarrierWithGroupSync ThreadGroupMemoryBarrierSync

// geometry shader
#   define TriangleStream               TriangleBuffer              
#   define PointStream                  PointBuffer                 
#   define LineStream                   LineBuffer                  
#   define triangle                 Triangle                    
#   define point                        Point                       
#   define line                     Line                        
#   define triangleadj                  AdjacentTriangle            
#   define lineadj                      AdjacentLine

// multimedia operations
#define msad4                       msad

#endif

// Not really needed anymore, but did ship in My 4.0; with D3D11_9X remapping them to .r channel.
// Now that's not used.
#define VAR_SAMPLE_1CHANNEL(x,y) tex2D(x,y).a
#define VAR_ALPHA_CHANNEL a


#endif

#line 13 ""

#line 1 "MyShaderVariables.cginc"
#ifndef VAR_SHADER_VARIABLES_INCLUDED
#define VAR_SHADER_VARIABLES_INCLUDED

#line 1 "HLSLSupport.cginc"
#ifndef HLSL_SUPPORT_INCLUDED
#define HLSL_SUPPORT_INCLUDED


#if defined(SHADER_API_D3D11) || defined(SHADER_API_XBOX360) || defined(SHADER_API_D3D11_9X) || defined(VAR_COMPILER_HLSLCC) || defined(SHADER_API_D3D9)
#define VAR_COMPILER_HLSL
#elif defined(SHADER_TARGET_GLSL)
#define VAR_COMPILER_HLSL2GLSL
#else
#define VAR_COMPILER_CG
#endif

#if !defined(SV_Target)
#   if defined(SHADER_API_PSSL)
#       define SV_Target S_TARGET_OUTPUT
#   elif !defined(SHADER_API_XBOXONE)
#       define SV_Target COLOR
#   endif
#endif


#if !defined(SV_Target0)
#   if defined(SHADER_API_PSSL)
#       define SV_Target0 S_TARGET_OUTPUT0
#   elif !defined(SHADER_API_XBOXONE)
#       define SV_Target0 COLOR0
#   endif
#endif


#if !defined(SV_Target1)
#   if defined(SHADER_API_PSSL)
#       define SV_Target1 S_TARGET_OUTPUT1
#   elif !defined(SHADER_API_XBOXONE)
#       define SV_Target1 COLOR1
#   endif
#endif

#if !defined(SV_Target2)
#   if defined(SHADER_API_PSSL)
#       define SV_Target2 S_TARGET_OUTPUT2
#   elif !defined(SHADER_API_XBOXONE)
#       define SV_Target2 COLOR2
#   endif
#endif

#if !defined(SV_Target3)
#   if defined(SHADER_API_PSSL)
#       define SV_Target3 S_TARGET_OUTPUT3
#   elif !defined(SHADER_API_XBOXONE)
#       define SV_Target3 COLOR3
#   endif
#endif



#if !defined(SV_Depth)
#   if defined(SHADER_API_PSSL)
#       define SV_Depth S_DEPTH_OUTPUT
#   elif !defined(SHADER_API_XBOXONE)
#       define SV_Depth DEPTH
#   endif
#endif

#if defined(SHADER_API_PSSL)
// compute shader defines
#define StructuredBuffer RegularBuffer
#define SV_VertexID S_VERTEX_ID

#endif 

#if defined(VAR_COMPILER_HLSL)
#pragma warning (disable : 3205) // conversion of larger type to smaller
#pragma warning (disable : 3568) // unknown pragma ignored
#endif

#if !defined(SHADER_TARGET_GLSL) && !defined(SHADER_API_PSSL)
#define fixed half
#define fixed2 half2
#define fixed3 half3
#define fixed4 half4
#define fixed4x4 half4x4
#define fixed3x3 half3x3
#define fixed2x2 half2x2
#define sampler2D_half sampler2D
#define sampler2D_float sampler2D
#define samplerCUBE_half samplerCUBE
#define samplerCUBE_float samplerCUBE
#endif

#if defined(SHADER_API_PSSL)
#define uniform
#define half float
#define half2 float2
#define half3 float3
#define half4 float4
#define half2x2 float2x2
#define half3x3 float3x3
#define half4x4 float4x4
#define fixed float
#define fixed2 float2
#define fixed3 float3
#define fixed4 float4
#define fixed4x4 half4x4
#define fixed3x3 half3x3
#define fixed2x2 half2x2
#define samplerCUBE_half samplerCUBE
#define samplerCUBE_float samplerCUBE

#define CBUFFER_START(name) ConstantBuffer name {
#define CBUFFER_END };
#elif !defined(VAR_COMPILER_HLSLCC) && (defined(SHADER_API_D3D11) || defined(SHADER_API_D3D11_9X))
#define CBUFFER_START(name) cbuffer name {
#define CBUFFER_END };
#else
#define CBUFFER_START(name)
#define CBUFFER_END
#endif

#if defined(SHADOWS_NATIVE) && defined(SHADER_API_PSSL)
    // PSSL
    #define VAR_DECLARE_SHADOWMAP(tex)      Texture2D tex; SamplerComparisonState sampler##tex
    #define VAR_SAMPLE_SHADOW(tex,coord)        tex.SampleCmpLOD0(sampler##tex,(coord).xy,(coord).z)
    #define VAR_SAMPLE_SHADOW_PROJ(tex,coord)   tex.SampleCmpLOD0(sampler##tex,(coord).xy/(coord).w,(coord).z/(coord).w)
#elif defined(SHADOWS_NATIVE) && (defined(SHADER_API_D3D11) || defined(SHADER_API_D3D11_9X) || defined(VAR_COMPILER_HLSLCC))
    // DX11 syntax for shadow maps
    #define VAR_DECLARE_SHADOWMAP(tex) Texture2D tex; SamplerComparisonState sampler##tex
    #define VAR_SAMPLE_SHADOW(tex,coord) tex.SampleCmpLevelZero (sampler##tex,(coord).xy,(coord).z)
    #define VAR_SAMPLE_SHADOW_PROJ(tex,coord) tex.SampleCmpLevelZero (sampler##tex,(coord).xy/(coord).w,(coord).z/(coord).w)
#elif defined(SHADOWS_NATIVE) && defined(SHADER_TARGET_GLSL)
    // hlsl2glsl syntax for shadow maps
    #define VAR_DECLARE_SHADOWMAP(tex) sampler2DShadow tex
    #define VAR_SAMPLE_SHADOW(tex,coord) shadow2D (tex,(coord).xyz)
    #define VAR_SAMPLE_SHADOW_PROJ(tex,coord) shadow2Dproj (tex,coord)
#elif defined(SHADOWS_NATIVE) && defined(SHADER_API_PSP2) && !defined(SHADER_API_PSM)
    #define VAR_DECLARE_SHADOWMAP(tex) sampler2D tex
    #define VAR_SAMPLE_SHADOW(tex,coord) f1tex2D<float>(tex, (coord).xyz)
    #define VAR_SAMPLE_SHADOW_PROJ(tex,coord) f1tex2Dproj<float>(tex, coord)
#elif defined(SHADOWS_NATIVE) && defined(SHADER_API_D3D9)
    // Native shadow maps hack on D3D9: look just like regular
    // texture sample. Have to always do a projected sample
    // so that HLSL compiler doesn't try to be too smart and mess up swizzles
    // (thinking that Z is unused).
    #define VAR_DECLARE_SHADOWMAP(tex) sampler2D tex
    #define VAR_SAMPLE_SHADOW(tex,coord) tex2Dproj (tex,float4((coord).xyz,1)).r
    #define VAR_SAMPLE_SHADOW_PROJ(tex,coord) tex2Dproj (tex,coord).r
#else
    // Fallback for other platforms: look just like a regular texture sample.
    #define VAR_DECLARE_SHADOWMAP(tex) sampler2D tex
    #define VAR_SAMPLE_SHADOW(tex,coord) tex2D (tex,(coord).xyz).r
    #define VAR_SAMPLE_SHADOW_PROJ(tex,coord) tex2Dproj (tex,coord).r
#endif



// Macros to declare textures and samplers, possibly separately. For platforms
// that have separate samplers & textures (like DX11), and we'd want to conserve
// the samplers.
//  - VAR_DECLARE_TEX2D_NOSAMPLER declares a texture, without a sampler.
//  - VAR_SAMPLE_TEX2D_SAMPLER samples a texture, using sampler from another texture.
//      That another texture must also be actually used in the current shader, otherwise
//      the correct sampler will not be set.
#if defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(VAR_COMPILER_HLSLCC)
#define VAR_DECLARE_TEX2D(tex) Texture2D tex; SamplerState sampler##tex
#define VAR_DECLARE_TEX2D_NOSAMPLER(tex) Texture2D tex
#define VAR_SAMPLE_TEX2D(tex,coord) tex.Sample (sampler##tex,coord)
#define VAR_SAMPLE_TEX2D_SAMPLER(tex,samplertex,coord) tex.Sample (sampler##samplertex,coord)
#else
#define VAR_DECLARE_TEX2D(tex) sampler2D tex
#define VAR_DECLARE_TEX2D_NOSAMPLER(tex) sampler2D tex
#define VAR_SAMPLE_TEX2D(tex,coord) tex2D (tex,coord)
#define VAR_SAMPLE_TEX2D_SAMPLER(tex,samplertex,coord) tex2D (tex,coord)
#endif



#define samplerRECT sampler2D
#define texRECT tex2D
#define texRECTlod tex2Dlod
#define texRECTbias tex2Dbias
#define texRECTproj tex2Dproj

#if defined(SHADER_API_PSSL)
#define VPOS            S_POSITION
#elif defined(VAR_COMPILER_CG)
// Cg seems to use WPOS instead of VPOS semantic?
#define VPOS WPOS
// Cg does not have tex2Dgrad and friends, but has tex2D overload that
// can take the derivatives
#define tex2Dgrad tex2D
#define texCUBEgrad texCUBE
#define tex3Dgrad tex3D
#endif


#if defined(SHADER_API_PSSL)

struct sampler1D {
    Texture1D       t;
    SamplerState    s;
};
struct sampler2D {
    Texture2D       t;
    SamplerState    s;
};
struct sampler2D_float {
    Texture2D       t;
    SamplerState    s;
};
struct sampler3D {
    Texture3D       t;
    SamplerState    s;
};
struct samplerCUBE {
    TextureCube     t;
    SamplerState    s;
};

float4 tex1D(sampler1D x, float v)              { return x.t.Sample(x.s, v); }
float4 tex2D(sampler2D x, float2 v)             { return x.t.Sample(x.s, v); }
float4 tex2D(sampler2D_float x, float2 v)       { return x.t.Sample(x.s, v); }
float4 tex3D(sampler3D x, float3 v)             { return x.t.Sample(x.s, v); }
float4 texCUBE(samplerCUBE x, float3 v)         { return x.t.Sample(x.s, v); }

float4 tex1Dbias(sampler1D x, in float4 t)      { return x.t.SampleBias(x.s, t.x, t.w); }
float4 tex2Dbias(sampler2D x, in float4 t)      { return x.t.SampleBias(x.s, t.xy, t.w); }
float4 tex2Dbias(sampler2D_float x, in float4 t)        { return x.t.SampleBias(x.s, t.xy, t.w); }
float4 tex3Dbias(sampler3D x, in float4 t)      { return x.t.SampleBias(x.s, t.xyz, t.w); }
float4 texCUBEbias(samplerCUBE x, in float4 t)  { return x.t.SampleBias(x.s, t.xyz, t.w); }

float4 tex1Dlod(sampler1D x, in float4 t)       { return x.t.SampleLOD(x.s, t.x, t.w); }
float4 tex2Dlod(sampler2D x, in float4 t)       { return x.t.SampleLOD(x.s, t.xy, t.w); }
float4 tex2Dlod(sampler2D_float x, in float4 t)     { return x.t.SampleLOD(x.s, t.xy, t.w); }
float4 tex3Dlod(sampler3D x, in float4 t)       { return x.t.SampleLOD(x.s, t.xyz, t.w); }
float4 texCUBElod(samplerCUBE x, in float4 t)   { return x.t.SampleLOD(x.s, t.xyz, t.w); }

float4 tex1Dgrad(sampler1D x, float t, float dx, float dy)          { return x.t.SampleGradient(x.s, t, dx, dy); }
float4 tex2Dgrad(sampler2D x, float2 t, float2 dx, float2 dy)       { return x.t.SampleGradient(x.s, t, dx, dy); }
float4 tex2Dgrad(sampler2D_float x, float2 t, float2 dx, float2 dy)     { return x.t.SampleGradient(x.s, t, dx, dy); }
float4 tex3Dgrad(sampler3D x, float3 t, float3 dx, float3 dy)       { return x.t.SampleGradient(x.s, t, dx, dy); }
float4 texCUBEgrad(samplerCUBE x, float3 t, float3 dx, float3 dy)   { return x.t.SampleGradient(x.s, t, dx, dy); }

float4 tex1Dproj(sampler1D s, in float2 t)      { return tex1D(s, t.x / t.y); }
float4 tex1Dproj(sampler1D s, in float4 t)      { return tex1D(s, t.x / t.w); }
float4 tex2Dproj(sampler2D s, in float3 t)      { return tex2D(s, t.xy / t.z); }
float4 tex2Dproj(sampler2D_float s, in float3 t)        { return tex2D(s, t.xy / t.z); }
float4 tex2Dproj(sampler2D s, in float4 t)      { return tex2D(s, t.xy / t.w); }
float4 tex3Dproj(sampler3D s, in float4 t)      { return tex3D(s, t.xyz / t.w); }
float4 texCUBEproj(samplerCUBE s, in float4 t)  { return texCUBE(s, t.xyz / t.w); }

#elif defined(SHADER_API_XBOX360)

float4 tex2Dproj(in sampler2D s, in float4 t) 
{ 
    float2 ti=t.xy / t.w;
    return tex2D( s, ti);
}

float4 tex2Dproj(in sampler2D s, in float3 t) 
{ 
    float2 ti=t.xy / t.z;
    return tex2D( s, ti);
}


#endif

#if defined(VAR_COMPILER_HLSL) || defined (SHADER_TARGET_GLSL)
#define FOGC FOG
#endif

// Use VFACE pixel shader input semantic in your shaders to get front-facing scalar value.
#if defined(VAR_COMPILER_CG)
#define VFACE FACE
#endif
#if defined(VAR_COMPILER_HLSL2GLSL)
#define FACE VFACE
#endif

#if defined(SHADER_API_PSSL)
#define SV_POSITION S_POSITION
#elif !defined(SHADER_API_D3D11) && !defined(SHADER_API_D3D11_9X)
#define SV_POSITION POSITION
#endif


#if (defined(SHADER_API_D3D9) || defined(SHADER_API_XBOX360) || defined(SHADER_API_PS3) || defined(SHADER_API_D3D11) || defined(SHADER_API_D3D11_9X) || defined(SHADER_API_PSP2) || defined(SHADER_API_PSSL)) && !defined(VAR_COMPILER_HLSLCC)
#define VAR_ATTEN_CHANNEL r
#else
#define VAR_ATTEN_CHANNEL a
#endif

#if defined(SHADER_API_D3D9) || defined(SHADER_API_XBOX360) || defined(SHADER_API_PSP2)
#define VAR_HALF_TEXEL_OFFSET
#endif

#if (defined(SHADER_API_D3D9) || defined(SHADER_API_XBOX360) || defined(SHADER_API_PS3) || defined(SHADER_API_D3D11) || defined(SHADER_API_D3D11_9X) || defined(SHADER_API_PSP2) || defined(SHADER_API_PSSL)) && !defined(VAR_COMPILER_HLSLCC)
#define VAR_UV_STARTS_AT_TOP 1
#endif

#if (defined(SHADER_API_D3D9) || defined(SHADER_API_XBOX360) || defined(SHADER_API_PS3) || defined(SHADER_API_D3D11) || defined(SHADER_API_D3D11_9X)) && !defined(VAR_COMPILER_HLSLCC)
#define VAR_NEAR_CLIP_VALUE (0.0)
#else
#define VAR_NEAR_CLIP_VALUE (-1.0)
#endif


#if defined(SHADER_API_D3D9)
#define VAR_MIGHT_NOT_HAVE_DEPTH_TEXTURE
#endif


#if (defined(SHADER_API_OPENGL) && !defined(SHADER_TARGET_GLSL)) || defined(SHADER_API_PSP2)
#define VAR_BUGGY_TEX2DPROJ4
#define VAR_PROJ_COORD(a) (a).xyw
#else
#define VAR_PROJ_COORD(a) a
#endif


// Platforms which do not use cascaded/screenspace shadow maps: more or less "mobile" platforms
#if defined(SHADER_API_GLES) || defined(SHADER_API_GLES3) || defined(SHADER_API_GLES31) || defined(SHADER_API_METAL) || defined(SHADER_API_D3D11_9X)
#define VAR_NO_SCREENSPACE_SHADOWS
#endif

// Platforms which do not use RGBM lightmap compression, or DXT5nm normal map compression
#if defined(SHADER_API_GLES) || defined(SHADER_API_GLES3) || defined(SHADER_API_GLES31) || defined(SHADER_API_METAL)
#define VAR_NO_RGBM
#define VAR_NO_DXT5nm
#endif

// Platforms which can support "framebuffer fetch" on some devices
#if defined(SHADER_API_GLES) || defined(SHADER_API_GLES3) || defined(SHADER_API_GLES31)
#define VAR_FRAMEBUFFER_FETCH_AVAILABLE
#endif


// On most platforms, use floating point render targets to store depth of point
// light shadowmaps. However, on some others they either have issues, or aren't widely
// supported; in which case fallback to encoding depth into RGBA channels.
// Make sure this define matches GraphicsCaps.useRGBAForPointShadows.
#if defined(SHADER_API_GLES) || defined(SHADER_API_PSP2) || defined(SHADER_API_XBOX360) || defined(SHADER_API_PS3)
#define VAR_USE_RGBA_FOR_POINT_SHADOWS
#endif


#if defined(VAR_COMPILER_HLSL) || defined(VAR_COMPILER_HLSLCC)
#define VAR_INITIALIZE_OUTPUT(type,name) name = (type)0;
#else
#define VAR_INITIALIZE_OUTPUT(type,name)
#endif

#if defined(SHADER_API_D3D11) || defined(VAR_COMPILER_HLSLCC)
#define VAR_CAN_COMPILE_TESSELLATION 1
#   define VAR_domain                   domain
#   define VAR_partitioning         partitioning
#   define VAR_outputtopology           outputtopology
#   define VAR_patchconstantfunc        patchconstantfunc
#   define VAR_outputcontrolpoints  outputcontrolpoints
#elif defined(SHADER_API_PSSL)
#   define VAR_CAN_COMPILE_TESSELLATION 1

#   define SV_OutputControlPointID      S_OUTPUT_CONTROL_POINT_ID
#   define SV_TessFactor                S_EDGE_TESS_FACTOR
#   define SV_InsideTessFactor          S_INSIDE_TESS_FACTOR
#   define SV_DomainLocation            S_DOMAIN_LOCATION

#   define VAR_domain                   DOMAIN_PATCH_TYPE
#   define VAR_partitioning         PARTITIONING_TYPE
#   define VAR_outputtopology           OUTPUT_TOPOLOGY_TYPE
#   define VAR_patchconstantfunc        PATCH_CONSTANT_FUNC
#   define VAR_outputcontrolpoints  OUTPUT_CONTROL_POINTS

#   define  domain                      DOMAIN_PATCH_TYPE
#   define  partitioning                PARTITIONING_TYPE
#   define  outputtopology              OUTPUT_TOPOLOGY_TYPE
#   define  patchconstantfunc           PATCH_CONSTANT_FUNC
#   define  outputcontrolpoints         OUTPUT_CONTROL_POINTS

#   define  maxtessfactor               MAX_TESS_FACTOR
#   define  instance                    INSTANCE
#   define  numthreads                  NUM_THREADS
#   define  patchsize                   PATCH_SIZE
#   define  maxvertexcount              MAX_VERTEX_COUNT            
#   define  earlydepthstencil           FORCE_EARLY_DEPTH_STENCIL

#   define  GroupMemoryBarrierWithGroupSync ThreadGroupMemoryBarrierSync

// geometry shader
#   define TriangleStream               TriangleBuffer              
#   define PointStream                  PointBuffer                 
#   define LineStream                   LineBuffer                  
#   define triangle                 Triangle                    
#   define point                        Point                       
#   define line                     Line                        
#   define triangleadj                  AdjacentTriangle            
#   define lineadj                      AdjacentLine

// multimedia operations
#define msad4                       msad

#endif

// Not really needed anymore, but did ship in My 4.0; with D3D11_9X remapping them to .r channel.
// Now that's not used.
#define VAR_SAMPLE_1CHANNEL(x,y) tex2D(x,y).a
#define VAR_ALPHA_CHANNEL a


#endif

#line 4 "MyShaderVariables.cginc"


#if defined (DIRECTIONAL_COOKIE) || defined (DIRECTIONAL)
#define USING_DIRECTIONAL_LIGHT
#endif



// ----------------------------------------------------------------------------

CBUFFER_START(MyPerCamera)
    // Time values from My
    uniform float4 _Time;
    uniform float4 _SinTime;
    uniform float4 _CosTime;
    uniform float4 var_DeltaTime; // dt, 1/dt, smoothdt, 1/smoothdt

    uniform float3 _WorldSpaceCameraPos;

    // x = 1 or -1 (-1 if projection is flipped)
    // y = near plane
    // z = far plane
    // w = 1/far plane
    uniform float4 _ProjectionParams;

    // x = width
    // y = height
    // z = 1 + 1.0/width
    // w = 1 + 1.0/height
    uniform float4 _ScreenParams;

    uniform float4 _ZBufferParams;

    // x = orthographic camera's width
    // y = orthographic camera's height
    // z = unused
    // w = 1.0 if camera is ortho, 0.0 if perspective
    uniform float4 var_OrthoParams;
CBUFFER_END


CBUFFER_START(MyPerCameraRare)
    uniform float4 var_CameraWorldClipPlanes[6];

    // Projection matrices of the camera. Note that this might be different from projection matrix
    // that is set right now, e.g. while rendering shadows the matrices below are still the projection
    // of original camera.
    uniform float4x4 var_CameraProjection;
    uniform float4x4 var_CameraInvProjection;
CBUFFER_END



// ----------------------------------------------------------------------------

CBUFFER_START(MyLighting)

    #ifdef USING_DIRECTIONAL_LIGHT
    uniform half4 _WorldSpaceLightPos0;
    #else
    uniform float4 _WorldSpaceLightPos0;
    #endif

    uniform float4 _LightPositionRange; // xyz = pos, w = 1/range

    float4 var_4LightPosX0;
    float4 var_4LightPosY0;
    float4 var_4LightPosZ0;
    half4 var_4LightAtten0;

    half4 var_LightColor[8];
    float4 var_LightPosition[8];
    // x = -1
    // y = 1
    // z = quadratic attenuation
    // w = range^2
    half4 var_LightAtten[8];
    float4 var_SpotDirection[8];

    // SH lighting environment
    half4 var_SHAr;
    half4 var_SHAg;
    half4 var_SHAb;
    half4 var_SHBr;
    half4 var_SHBg;
    half4 var_SHBb;
    half4 var_SHC;
CBUFFER_END

CBUFFER_START(MyLightingOld)
    half3 var_LightColor0, var_LightColor1, var_LightColor2, var_LightColor3; // keeping those only for any existing shaders; remove in 4.0
CBUFFER_END


// ----------------------------------------------------------------------------

CBUFFER_START(MyShadows)
    float4 var_ShadowSplitSpheres[4];
    float4 var_ShadowSplitSqRadii;
    float4 var_LightShadowBias;
    float4 _LightSplitsNear;
    float4 _LightSplitsFar;
    float4x4 var_World2Shadow[4];
    half4 _LightShadowData;
    float4 var_ShadowFadeCenterAndType;
CBUFFER_END

#define _World2Shadow var_World2Shadow[0]
#define _World2Shadow1 var_World2Shadow[1]
#define _World2Shadow2 var_World2Shadow[2]
#define _World2Shadow3 var_World2Shadow[3]


// ----------------------------------------------------------------------------

CBUFFER_START(MyPerDraw)
    float4x4 glstate_matrix_mvp;
    float4x4 glstate_matrix_modelview0;
    float4x4 glstate_matrix_invtrans_modelview0;
    #define VAR_MATRIX_MVP glstate_matrix_mvp
    #define VAR_MATRIX_MV glstate_matrix_modelview0
    #define VAR_MATRIX_IT_MV glstate_matrix_invtrans_modelview0

    uniform float4x4 _Object2World;
    uniform float4x4 _World2Object;
    uniform float4 var_LODFade; // x is the fade value ranging within [0,1]. y is x quantized into 16 levels
CBUFFER_END




CBUFFER_START(MyPerDrawRare)
    float4x4 glstate_matrix_transpose_modelview0;
    #define VAR_MATRIX_T_MV glstate_matrix_transpose_modelview0
CBUFFER_END



// ----------------------------------------------------------------------------

CBUFFER_START(MyPerFrame)

    float4x4 glstate_matrix_projection;
    float4   glstate_lightmodel_ambient;
    #define VAR_MATRIX_P glstate_matrix_projection
    #define VAR_LIGHTMODEL_AMBIENT glstate_lightmodel_ambient

    float4x4 var_MatrixV;
    float4x4 var_MatrixVP;
    #define VAR_MATRIX_V var_MatrixV
    #define VAR_MATRIX_VP var_MatrixVP

    fixed4 var_AmbientSky;
    fixed4 var_AmbientGround;

CBUFFER_END


// ----------------------------------------------------------------------------

CBUFFER_START(MyFog)
    uniform fixed4 var_FogColor;
    // x = density / sqrt(ln(2)), useful for Exp2 mode
    // y = density / ln(2), useful for Exp mode
    // z = -1/(end-start), useful for Linear mode
    // w = end/(end-start), useful for Linear mode
    uniform float4 var_FogParams;
CBUFFER_END


// ----------------------------------------------------------------------------
//  Deprecated

// There used to be fixed function-like texture matrices, defined as VAR_MATRIX_TEXTUREn. These are gone now; and are just defined to identity.
#define VAR_MATRIX_TEXTURE0 float4x4(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1)
#define VAR_MATRIX_TEXTURE1 float4x4(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1)
#define VAR_MATRIX_TEXTURE2 float4x4(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1)
#define VAR_MATRIX_TEXTURE3 float4x4(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1)


#endif

#line 14 ""

#line 10 ""
#ifdef DUMMY_PREPROCESSOR_TO_WORK_AROUND_HLSL_COMPILER_LINE_HANDLING
#endif

// #pragma target 5.0

//// #pragma vertex VS_RenderScene
//// #pragma fragment PS_RenderSceneTextured

// #pragma vertex VS_RenderSceneWithTessellation
// #pragma fragment PS_RenderSceneTextured
// #pragma hull HS_PNTriangles
// #pragma domain DS_PNTriangles

#line 1 "MyCG.cginc"
#ifndef VAR_CG_INCLUDED
#define VAR_CG_INCLUDED

#line 1 "MyShaderVariables.cginc"
#ifndef VAR_SHADER_VARIABLES_INCLUDED
#define VAR_SHADER_VARIABLES_INCLUDED

#line 1 "HLSLSupport.cginc"
#ifndef HLSL_SUPPORT_INCLUDED
#define HLSL_SUPPORT_INCLUDED


#if defined(SHADER_API_D3D11) || defined(SHADER_API_XBOX360) || defined(SHADER_API_D3D11_9X) || defined(VAR_COMPILER_HLSLCC) || defined(SHADER_API_D3D9)
#define VAR_COMPILER_HLSL
#elif defined(SHADER_TARGET_GLSL)
#define VAR_COMPILER_HLSL2GLSL
#else
#define VAR_COMPILER_CG
#endif

#if !defined(SV_Target)
#   if defined(SHADER_API_PSSL)
#       define SV_Target S_TARGET_OUTPUT
#   elif !defined(SHADER_API_XBOXONE)
#       define SV_Target COLOR
#   endif
#endif


#if !defined(SV_Target0)
#   if defined(SHADER_API_PSSL)
#       define SV_Target0 S_TARGET_OUTPUT0
#   elif !defined(SHADER_API_XBOXONE)
#       define SV_Target0 COLOR0
#   endif
#endif


#if !defined(SV_Target1)
#   if defined(SHADER_API_PSSL)
#       define SV_Target1 S_TARGET_OUTPUT1
#   elif !defined(SHADER_API_XBOXONE)
#       define SV_Target1 COLOR1
#   endif
#endif

#if !defined(SV_Target2)
#   if defined(SHADER_API_PSSL)
#       define SV_Target2 S_TARGET_OUTPUT2
#   elif !defined(SHADER_API_XBOXONE)
#       define SV_Target2 COLOR2
#   endif
#endif

#if !defined(SV_Target3)
#   if defined(SHADER_API_PSSL)
#       define SV_Target3 S_TARGET_OUTPUT3
#   elif !defined(SHADER_API_XBOXONE)
#       define SV_Target3 COLOR3
#   endif
#endif



#if !defined(SV_Depth)
#   if defined(SHADER_API_PSSL)
#       define SV_Depth S_DEPTH_OUTPUT
#   elif !defined(SHADER_API_XBOXONE)
#       define SV_Depth DEPTH
#   endif
#endif

#if defined(SHADER_API_PSSL)
// compute shader defines
#define StructuredBuffer RegularBuffer
#define SV_VertexID S_VERTEX_ID

#endif 

#if defined(VAR_COMPILER_HLSL)
#pragma warning (disable : 3205) // conversion of larger type to smaller
#pragma warning (disable : 3568) // unknown pragma ignored
#endif

#if !defined(SHADER_TARGET_GLSL) && !defined(SHADER_API_PSSL)
#define fixed half
#define fixed2 half2
#define fixed3 half3
#define fixed4 half4
#define fixed4x4 half4x4
#define fixed3x3 half3x3
#define fixed2x2 half2x2
#define sampler2D_half sampler2D
#define sampler2D_float sampler2D
#define samplerCUBE_half samplerCUBE
#define samplerCUBE_float samplerCUBE
#endif

#if defined(SHADER_API_PSSL)
#define uniform
#define half float
#define half2 float2
#define half3 float3
#define half4 float4
#define half2x2 float2x2
#define half3x3 float3x3
#define half4x4 float4x4
#define fixed float
#define fixed2 float2
#define fixed3 float3
#define fixed4 float4
#define fixed4x4 half4x4
#define fixed3x3 half3x3
#define fixed2x2 half2x2
#define samplerCUBE_half samplerCUBE
#define samplerCUBE_float samplerCUBE

#define CBUFFER_START(name) ConstantBuffer name {
#define CBUFFER_END };
#elif !defined(VAR_COMPILER_HLSLCC) && (defined(SHADER_API_D3D11) || defined(SHADER_API_D3D11_9X))
#define CBUFFER_START(name) cbuffer name {
#define CBUFFER_END };
#else
#define CBUFFER_START(name)
#define CBUFFER_END
#endif

#if defined(SHADOWS_NATIVE) && defined(SHADER_API_PSSL)
    // PSSL
    #define VAR_DECLARE_SHADOWMAP(tex)      Texture2D tex; SamplerComparisonState sampler##tex
    #define VAR_SAMPLE_SHADOW(tex,coord)        tex.SampleCmpLOD0(sampler##tex,(coord).xy,(coord).z)
    #define VAR_SAMPLE_SHADOW_PROJ(tex,coord)   tex.SampleCmpLOD0(sampler##tex,(coord).xy/(coord).w,(coord).z/(coord).w)
#elif defined(SHADOWS_NATIVE) && (defined(SHADER_API_D3D11) || defined(SHADER_API_D3D11_9X) || defined(VAR_COMPILER_HLSLCC))
    // DX11 syntax for shadow maps
    #define VAR_DECLARE_SHADOWMAP(tex) Texture2D tex; SamplerComparisonState sampler##tex
    #define VAR_SAMPLE_SHADOW(tex,coord) tex.SampleCmpLevelZero (sampler##tex,(coord).xy,(coord).z)
    #define VAR_SAMPLE_SHADOW_PROJ(tex,coord) tex.SampleCmpLevelZero (sampler##tex,(coord).xy/(coord).w,(coord).z/(coord).w)
#elif defined(SHADOWS_NATIVE) && defined(SHADER_TARGET_GLSL)
    // hlsl2glsl syntax for shadow maps
    #define VAR_DECLARE_SHADOWMAP(tex) sampler2DShadow tex
    #define VAR_SAMPLE_SHADOW(tex,coord) shadow2D (tex,(coord).xyz)
    #define VAR_SAMPLE_SHADOW_PROJ(tex,coord) shadow2Dproj (tex,coord)
#elif defined(SHADOWS_NATIVE) && defined(SHADER_API_PSP2) && !defined(SHADER_API_PSM)
    #define VAR_DECLARE_SHADOWMAP(tex) sampler2D tex
    #define VAR_SAMPLE_SHADOW(tex,coord) f1tex2D<float>(tex, (coord).xyz)
    #define VAR_SAMPLE_SHADOW_PROJ(tex,coord) f1tex2Dproj<float>(tex, coord)
#elif defined(SHADOWS_NATIVE) && defined(SHADER_API_D3D9)
    // Native shadow maps hack on D3D9: look just like regular
    // texture sample. Have to always do a projected sample
    // so that HLSL compiler doesn't try to be too smart and mess up swizzles
    // (thinking that Z is unused).
    #define VAR_DECLARE_SHADOWMAP(tex) sampler2D tex
    #define VAR_SAMPLE_SHADOW(tex,coord) tex2Dproj (tex,float4((coord).xyz,1)).r
    #define VAR_SAMPLE_SHADOW_PROJ(tex,coord) tex2Dproj (tex,coord).r
#else
    // Fallback for other platforms: look just like a regular texture sample.
    #define VAR_DECLARE_SHADOWMAP(tex) sampler2D tex
    #define VAR_SAMPLE_SHADOW(tex,coord) tex2D (tex,(coord).xyz).r
    #define VAR_SAMPLE_SHADOW_PROJ(tex,coord) tex2Dproj (tex,coord).r
#endif



// Macros to declare textures and samplers, possibly separately. For platforms
// that have separate samplers & textures (like DX11), and we'd want to conserve
// the samplers.
//  - VAR_DECLARE_TEX2D_NOSAMPLER declares a texture, without a sampler.
//  - VAR_SAMPLE_TEX2D_SAMPLER samples a texture, using sampler from another texture.
//      That another texture must also be actually used in the current shader, otherwise
//      the correct sampler will not be set.
#if defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(VAR_COMPILER_HLSLCC)
#define VAR_DECLARE_TEX2D(tex) Texture2D tex; SamplerState sampler##tex
#define VAR_DECLARE_TEX2D_NOSAMPLER(tex) Texture2D tex
#define VAR_SAMPLE_TEX2D(tex,coord) tex.Sample (sampler##tex,coord)
#define VAR_SAMPLE_TEX2D_SAMPLER(tex,samplertex,coord) tex.Sample (sampler##samplertex,coord)
#else
#define VAR_DECLARE_TEX2D(tex) sampler2D tex
#define VAR_DECLARE_TEX2D_NOSAMPLER(tex) sampler2D tex
#define VAR_SAMPLE_TEX2D(tex,coord) tex2D (tex,coord)
#define VAR_SAMPLE_TEX2D_SAMPLER(tex,samplertex,coord) tex2D (tex,coord)
#endif



#define samplerRECT sampler2D
#define texRECT tex2D
#define texRECTlod tex2Dlod
#define texRECTbias tex2Dbias
#define texRECTproj tex2Dproj

#if defined(SHADER_API_PSSL)
#define VPOS            S_POSITION
#elif defined(VAR_COMPILER_CG)
// Cg seems to use WPOS instead of VPOS semantic?
#define VPOS WPOS
// Cg does not have tex2Dgrad and friends, but has tex2D overload that
// can take the derivatives
#define tex2Dgrad tex2D
#define texCUBEgrad texCUBE
#define tex3Dgrad tex3D
#endif


#if defined(SHADER_API_PSSL)

struct sampler1D {
    Texture1D       t;
    SamplerState    s;
};
struct sampler2D {
    Texture2D       t;
    SamplerState    s;
};
struct sampler2D_float {
    Texture2D       t;
    SamplerState    s;
};
struct sampler3D {
    Texture3D       t;
    SamplerState    s;
};
struct samplerCUBE {
    TextureCube     t;
    SamplerState    s;
};

float4 tex1D(sampler1D x, float v)              { return x.t.Sample(x.s, v); }
float4 tex2D(sampler2D x, float2 v)             { return x.t.Sample(x.s, v); }
float4 tex2D(sampler2D_float x, float2 v)       { return x.t.Sample(x.s, v); }
float4 tex3D(sampler3D x, float3 v)             { return x.t.Sample(x.s, v); }
float4 texCUBE(samplerCUBE x, float3 v)         { return x.t.Sample(x.s, v); }

float4 tex1Dbias(sampler1D x, in float4 t)      { return x.t.SampleBias(x.s, t.x, t.w); }
float4 tex2Dbias(sampler2D x, in float4 t)      { return x.t.SampleBias(x.s, t.xy, t.w); }
float4 tex2Dbias(sampler2D_float x, in float4 t)        { return x.t.SampleBias(x.s, t.xy, t.w); }
float4 tex3Dbias(sampler3D x, in float4 t)      { return x.t.SampleBias(x.s, t.xyz, t.w); }
float4 texCUBEbias(samplerCUBE x, in float4 t)  { return x.t.SampleBias(x.s, t.xyz, t.w); }

float4 tex1Dlod(sampler1D x, in float4 t)       { return x.t.SampleLOD(x.s, t.x, t.w); }
float4 tex2Dlod(sampler2D x, in float4 t)       { return x.t.SampleLOD(x.s, t.xy, t.w); }
float4 tex2Dlod(sampler2D_float x, in float4 t)     { return x.t.SampleLOD(x.s, t.xy, t.w); }
float4 tex3Dlod(sampler3D x, in float4 t)       { return x.t.SampleLOD(x.s, t.xyz, t.w); }
float4 texCUBElod(samplerCUBE x, in float4 t)   { return x.t.SampleLOD(x.s, t.xyz, t.w); }

float4 tex1Dgrad(sampler1D x, float t, float dx, float dy)          { return x.t.SampleGradient(x.s, t, dx, dy); }
float4 tex2Dgrad(sampler2D x, float2 t, float2 dx, float2 dy)       { return x.t.SampleGradient(x.s, t, dx, dy); }
float4 tex2Dgrad(sampler2D_float x, float2 t, float2 dx, float2 dy)     { return x.t.SampleGradient(x.s, t, dx, dy); }
float4 tex3Dgrad(sampler3D x, float3 t, float3 dx, float3 dy)       { return x.t.SampleGradient(x.s, t, dx, dy); }
float4 texCUBEgrad(samplerCUBE x, float3 t, float3 dx, float3 dy)   { return x.t.SampleGradient(x.s, t, dx, dy); }

float4 tex1Dproj(sampler1D s, in float2 t)      { return tex1D(s, t.x / t.y); }
float4 tex1Dproj(sampler1D s, in float4 t)      { return tex1D(s, t.x / t.w); }
float4 tex2Dproj(sampler2D s, in float3 t)      { return tex2D(s, t.xy / t.z); }
float4 tex2Dproj(sampler2D_float s, in float3 t)        { return tex2D(s, t.xy / t.z); }
float4 tex2Dproj(sampler2D s, in float4 t)      { return tex2D(s, t.xy / t.w); }
float4 tex3Dproj(sampler3D s, in float4 t)      { return tex3D(s, t.xyz / t.w); }
float4 texCUBEproj(samplerCUBE s, in float4 t)  { return texCUBE(s, t.xyz / t.w); }

#elif defined(SHADER_API_XBOX360)

float4 tex2Dproj(in sampler2D s, in float4 t) 
{ 
    float2 ti=t.xy / t.w;
    return tex2D( s, ti);
}

float4 tex2Dproj(in sampler2D s, in float3 t) 
{ 
    float2 ti=t.xy / t.z;
    return tex2D( s, ti);
}


#endif

#if defined(VAR_COMPILER_HLSL) || defined (SHADER_TARGET_GLSL)
#define FOGC FOG
#endif

// Use VFACE pixel shader input semantic in your shaders to get front-facing scalar value.
#if defined(VAR_COMPILER_CG)
#define VFACE FACE
#endif
#if defined(VAR_COMPILER_HLSL2GLSL)
#define FACE VFACE
#endif

#if defined(SHADER_API_PSSL)
#define SV_POSITION S_POSITION
#elif !defined(SHADER_API_D3D11) && !defined(SHADER_API_D3D11_9X)
#define SV_POSITION POSITION
#endif


#if (defined(SHADER_API_D3D9) || defined(SHADER_API_XBOX360) || defined(SHADER_API_PS3) || defined(SHADER_API_D3D11) || defined(SHADER_API_D3D11_9X) || defined(SHADER_API_PSP2) || defined(SHADER_API_PSSL)) && !defined(VAR_COMPILER_HLSLCC)
#define VAR_ATTEN_CHANNEL r
#else
#define VAR_ATTEN_CHANNEL a
#endif

#if defined(SHADER_API_D3D9) || defined(SHADER_API_XBOX360) || defined(SHADER_API_PSP2)
#define VAR_HALF_TEXEL_OFFSET
#endif

#if (defined(SHADER_API_D3D9) || defined(SHADER_API_XBOX360) || defined(SHADER_API_PS3) || defined(SHADER_API_D3D11) || defined(SHADER_API_D3D11_9X) || defined(SHADER_API_PSP2) || defined(SHADER_API_PSSL)) && !defined(VAR_COMPILER_HLSLCC)
#define VAR_UV_STARTS_AT_TOP 1
#endif

#if (defined(SHADER_API_D3D9) || defined(SHADER_API_XBOX360) || defined(SHADER_API_PS3) || defined(SHADER_API_D3D11) || defined(SHADER_API_D3D11_9X)) && !defined(VAR_COMPILER_HLSLCC)
#define VAR_NEAR_CLIP_VALUE (0.0)
#else
#define VAR_NEAR_CLIP_VALUE (-1.0)
#endif


#if defined(SHADER_API_D3D9)
#define VAR_MIGHT_NOT_HAVE_DEPTH_TEXTURE
#endif


#if (defined(SHADER_API_OPENGL) && !defined(SHADER_TARGET_GLSL)) || defined(SHADER_API_PSP2)
#define VAR_BUGGY_TEX2DPROJ4
#define VAR_PROJ_COORD(a) (a).xyw
#else
#define VAR_PROJ_COORD(a) a
#endif


// Platforms which do not use cascaded/screenspace shadow maps: more or less "mobile" platforms
#if defined(SHADER_API_GLES) || defined(SHADER_API_GLES3) || defined(SHADER_API_GLES31) || defined(SHADER_API_METAL) || defined(SHADER_API_D3D11_9X)
#define VAR_NO_SCREENSPACE_SHADOWS
#endif

// Platforms which do not use RGBM lightmap compression, or DXT5nm normal map compression
#if defined(SHADER_API_GLES) || defined(SHADER_API_GLES3) || defined(SHADER_API_GLES31) || defined(SHADER_API_METAL)
#define VAR_NO_RGBM
#define VAR_NO_DXT5nm
#endif

// Platforms which can support "framebuffer fetch" on some devices
#if defined(SHADER_API_GLES) || defined(SHADER_API_GLES3) || defined(SHADER_API_GLES31)
#define VAR_FRAMEBUFFER_FETCH_AVAILABLE
#endif


// On most platforms, use floating point render targets to store depth of point
// light shadowmaps. However, on some others they either have issues, or aren't widely
// supported; in which case fallback to encoding depth into RGBA channels.
// Make sure this define matches GraphicsCaps.useRGBAForPointShadows.
#if defined(SHADER_API_GLES) || defined(SHADER_API_PSP2) || defined(SHADER_API_XBOX360) || defined(SHADER_API_PS3)
#define VAR_USE_RGBA_FOR_POINT_SHADOWS
#endif


#if defined(VAR_COMPILER_HLSL) || defined(VAR_COMPILER_HLSLCC)
#define VAR_INITIALIZE_OUTPUT(type,name) name = (type)0;
#else
#define VAR_INITIALIZE_OUTPUT(type,name)
#endif

#if defined(SHADER_API_D3D11) || defined(VAR_COMPILER_HLSLCC)
#define VAR_CAN_COMPILE_TESSELLATION 1
#   define VAR_domain                   domain
#   define VAR_partitioning         partitioning
#   define VAR_outputtopology           outputtopology
#   define VAR_patchconstantfunc        patchconstantfunc
#   define VAR_outputcontrolpoints  outputcontrolpoints
#elif defined(SHADER_API_PSSL)
#   define VAR_CAN_COMPILE_TESSELLATION 1

#   define SV_OutputControlPointID      S_OUTPUT_CONTROL_POINT_ID
#   define SV_TessFactor                S_EDGE_TESS_FACTOR
#   define SV_InsideTessFactor          S_INSIDE_TESS_FACTOR
#   define SV_DomainLocation            S_DOMAIN_LOCATION

#   define VAR_domain                   DOMAIN_PATCH_TYPE
#   define VAR_partitioning         PARTITIONING_TYPE
#   define VAR_outputtopology           OUTPUT_TOPOLOGY_TYPE
#   define VAR_patchconstantfunc        PATCH_CONSTANT_FUNC
#   define VAR_outputcontrolpoints  OUTPUT_CONTROL_POINTS

#   define  domain                      DOMAIN_PATCH_TYPE
#   define  partitioning                PARTITIONING_TYPE
#   define  outputtopology              OUTPUT_TOPOLOGY_TYPE
#   define  patchconstantfunc           PATCH_CONSTANT_FUNC
#   define  outputcontrolpoints         OUTPUT_CONTROL_POINTS

#   define  maxtessfactor               MAX_TESS_FACTOR
#   define  instance                    INSTANCE
#   define  numthreads                  NUM_THREADS
#   define  patchsize                   PATCH_SIZE
#   define  maxvertexcount              MAX_VERTEX_COUNT            
#   define  earlydepthstencil           FORCE_EARLY_DEPTH_STENCIL

#   define  GroupMemoryBarrierWithGroupSync ThreadGroupMemoryBarrierSync

// geometry shader
#   define TriangleStream               TriangleBuffer              
#   define PointStream                  PointBuffer                 
#   define LineStream                   LineBuffer                  
#   define triangle                 Triangle                    
#   define point                        Point                       
#   define line                     Line                        
#   define triangleadj                  AdjacentTriangle            
#   define lineadj                      AdjacentLine

// multimedia operations
#define msad4                       msad

#endif

#define VAR_SAMPLE_1CHANNEL(x,y) tex2D(x,y).a
#define VAR_ALPHA_CHANNEL a


#endif

#line 4 "MyShaderVariables.cginc"


#if defined (DIRECTIONAL_COOKIE) || defined (DIRECTIONAL)
#define USING_DIRECTIONAL_LIGHT
#endif



// ----------------------------------------------------------------------------

CBUFFER_START(MyPerCamera)
    uniform float4 _Time;
    uniform float4 _SinTime;
    uniform float4 _CosTime;
    uniform float4 var_DeltaTime; // dt, 1/dt, smoothdt, 1/smoothdt

    uniform float3 _WorldSpaceCameraPos;

    // x = 1 or -1 (-1 if projection is flipped)
    // y = near plane
    // z = far plane
    // w = 1/far plane
    uniform float4 _ProjectionParams;

    // x = width
    // y = height
    // z = 1 + 1.0/width
    // w = 1 + 1.0/height
    uniform float4 _ScreenParams;

    uniform float4 _ZBufferParams;

    // x = orthographic camera's width
    // y = orthographic camera's height
    // z = unused
    // w = 1.0 if camera is ortho, 0.0 if perspective
    uniform float4 var_OrthoParams;
CBUFFER_END


CBUFFER_START(MyPerCameraRare)
    uniform float4 var_CameraWorldClipPlanes[6];

    // Projection matrices of the camera. Note that this might be different from projection matrix
    // that is set right now, e.g. while rendering shadows the matrices below are still the projection
    // of original camera.
    uniform float4x4 var_CameraProjection;
    uniform float4x4 var_CameraInvProjection;
CBUFFER_END



// ----------------------------------------------------------------------------

CBUFFER_START(MyLighting)

    #ifdef USING_DIRECTIONAL_LIGHT
    uniform half4 _WorldSpaceLightPos0;
    #else
    uniform float4 _WorldSpaceLightPos0;
    #endif

    uniform float4 _LightPositionRange; // xyz = pos, w = 1/range

    float4 var_4LightPosX0;
    float4 var_4LightPosY0;
    float4 var_4LightPosZ0;
    half4 var_4LightAtten0;

    half4 var_LightColor[8];
    float4 var_LightPosition[8];
    // x = -1
    // y = 1
    // z = quadratic attenuation
    // w = range^2
    half4 var_LightAtten[8];
    float4 var_SpotDirection[8];

    // SH lighting environment
    half4 var_SHAr;
    half4 var_SHAg;
    half4 var_SHAb;
    half4 var_SHBr;
    half4 var_SHBg;
    half4 var_SHBb;
    half4 var_SHC;
CBUFFER_END

CBUFFER_START(MyLightingOld)
    half3 var_LightColor0, var_LightColor1, var_LightColor2, var_LightColor3; // keeping those only for any existing shaders; remove in 4.0
CBUFFER_END


// ----------------------------------------------------------------------------

CBUFFER_START(MyShadows)
    float4 var_ShadowSplitSpheres[4];
    float4 var_ShadowSplitSqRadii;
    float4 var_LightShadowBias;
    float4 _LightSplitsNear;
    float4 _LightSplitsFar;
    float4x4 var_World2Shadow[4];
    half4 _LightShadowData;
    float4 var_ShadowFadeCenterAndType;
CBUFFER_END

#define _World2Shadow var_World2Shadow[0]
#define _World2Shadow1 var_World2Shadow[1]
#define _World2Shadow2 var_World2Shadow[2]
#define _World2Shadow3 var_World2Shadow[3]


// ----------------------------------------------------------------------------

CBUFFER_START(MyPerDraw)
    float4x4 glstate_matrix_mvp;
    float4x4 glstate_matrix_modelview0;
    float4x4 glstate_matrix_invtrans_modelview0;
    #define VAR_MATRIX_MVP glstate_matrix_mvp
    #define VAR_MATRIX_MV glstate_matrix_modelview0
    #define VAR_MATRIX_IT_MV glstate_matrix_invtrans_modelview0

    uniform float4x4 _Object2World;
    uniform float4x4 _World2Object;
    uniform float4 var_LODFade; // x is the fade value ranging within [0,1]. y is x quantized into 16 levels
CBUFFER_END




CBUFFER_START(MyPerDrawRare)
    float4x4 glstate_matrix_transpose_modelview0;
    #define VAR_MATRIX_T_MV glstate_matrix_transpose_modelview0
CBUFFER_END



// ----------------------------------------------------------------------------

CBUFFER_START(MyPerFrame)

    float4x4 glstate_matrix_projection;
    float4   glstate_lightmodel_ambient;
    #define VAR_MATRIX_P glstate_matrix_projection
    #define VAR_LIGHTMODEL_AMBIENT glstate_lightmodel_ambient

    float4x4 var_MatrixV;
    float4x4 var_MatrixVP;
    #define VAR_MATRIX_V var_MatrixV
    #define VAR_MATRIX_VP var_MatrixVP

    fixed4 var_AmbientSky;
    fixed4 var_AmbientGround;

CBUFFER_END


// ----------------------------------------------------------------------------

CBUFFER_START(MyFog)
    uniform fixed4 var_FogColor;
    // x = density / sqrt(ln(2)), useful for Exp2 mode
    // y = density / ln(2), useful for Exp mode
    // z = -1/(end-start), useful for Linear mode
    // w = end/(end-start), useful for Linear mode
    uniform float4 var_FogParams;
CBUFFER_END


// ----------------------------------------------------------------------------
//  Deprecated

// There used to be fixed function-like texture matrices, defined as VAR_MATRIX_TEXTUREn. These are gone now; and are just defined to identity.
#define VAR_MATRIX_TEXTURE0 float4x4(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1)
#define VAR_MATRIX_TEXTURE1 float4x4(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1)
#define VAR_MATRIX_TEXTURE2 float4x4(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1)
#define VAR_MATRIX_TEXTURE3 float4x4(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1)


#endif

#line 4 "MyCG.cginc"



// Deprecated! Use SAMPLE_DEPTH_TEXTURE & SAMPLE_DEPTH_TEXTURE_PROJ instead!
#if defined(SHADER_API_PS3)
#   define VAR_SAMPLE_DEPTH(value) (dot((value).wxy, float3(0.996093809371817670572857294849, 0.0038909914428586627756752238080039, 1.5199185323666651467481343000015e-5)))
#elif defined(SHADER_API_PSP2)
#   define VAR_SAMPLE_DEPTH(value) (value).r
#else
#   define VAR_SAMPLE_DEPTH(value) (value).r
#endif


#if defined(SHADER_API_PS3)
#   define SAMPLE_DEPTH_TEXTURE(sampler, uv) (dot((tex2D(sampler, uv)).wxy, float3(0.996093809371817670572857294849, 0.0038909914428586627756752238080039, 1.5199185323666651467481343000015e-5)))
#elif defined(SHADER_API_PSP2) && !defined(SHADER_API_PSM)
#   define SAMPLE_DEPTH_TEXTURE(sampler, uv) (f1tex2D<float>(sampler, uv))
#else
#   define SAMPLE_DEPTH_TEXTURE(sampler, uv) (tex2D(sampler, uv).r)
#endif

#if defined(SHADER_API_PS3)
#   define SAMPLE_DEPTH_TEXTURE_PROJ(sampler, uv) (dot((tex2Dproj(sampler, uv)).wxy, float3(0.996093809371817670572857294849, 0.0038909914428586627756752238080039, 1.5199185323666651467481343000015e-5)))
#elif defined(SHADER_API_PSP2) && !defined(SHADER_API_PSM)
#   define SAMPLE_DEPTH_TEXTURE_PROJ(sampler, uv) (f1tex2Dproj<float>(sampler, uv))
#else
#   define SAMPLE_DEPTH_TEXTURE_PROJ(sampler, uv) (tex2Dproj(sampler, uv).r)
#endif

#if defined(SHADER_API_PSP2) && !defined(SHADER_API_PSM)
#define SAMPLE_DEPTH_TEXTURE_LOD(sampler, uv) (tex2Dlod<float>(sampler, uv))
#else
#define SAMPLE_DEPTH_TEXTURE_LOD(sampler, uv) (tex2Dlod(sampler, uv).r)
#endif

uniform fixed4 var_ColorSpaceGrey;
uniform fixed4 var_ColorSpaceDouble;

// -------------------------------------------------------------------
//  helper functions and macros used in many standard shaders


#if defined (DIRECTIONAL) || defined (DIRECTIONAL_COOKIE) || defined (POINT) || defined (SPOT) || defined (POINT_NOATT) || defined (POINT_COOKIE)
#define USING_LIGHT_MULTI_COMPILE
#endif

#define SCALED_NORMAL v.normal

struct appdata_base {
    float4 vertex : POSITION;
    float3 normal : NORMAL;
    float4 texcoord : TEXCOORD0;
};

struct appdata_tan {
    float4 vertex : POSITION;
    float4 tangent : TANGENT;
    float3 normal : NORMAL;
    float4 texcoord : TEXCOORD0;
};

struct appdata_full {
    float4 vertex : POSITION;
    float4 tangent : TANGENT;
    float3 normal : NORMAL;
    float4 texcoord : TEXCOORD0;
    float4 texcoord1 : TEXCOORD1;
    float4 texcoord2 : TEXCOORD2;
    float4 texcoord3 : TEXCOORD3;
#if defined(SHADER_API_XBOX360)
    half4 texcoord4 : TEXCOORD4;
    half4 texcoord5 : TEXCOORD5;
#endif
    fixed4 color : COLOR;
};

// Transforms direction from object to world space
inline float3 MyObjectToWorldDir( in float3 dir )
{
    return normalize(mul((float3x3)_Object2World, dir));
}

// Transforms direction from world to object space
inline float3 MyWorldToObjectDir( in float3 dir )
{
    return normalize(mul((float3x3)_World2Object, dir));
}

// Transforms normal from object to world space
inline float3 MyObjectToWorldNorm( in float3 norm )
{
    // Multiply by transposed inverse matrix, actually using transpose() generates badly optimized code
    return normalize(_World2Object[0].xyz * norm.x + _World2Object[1].xyz * norm.y + _World2Object[2].xyz * norm.z);
}

// Computes world space light direction, from world space position
inline float3 MyWorldSpaceLightDir( in float3 worldPos )
{
    #ifndef USING_LIGHT_MULTI_COMPILE
        return _WorldSpaceLightPos0.xyz - worldPos * _WorldSpaceLightPos0.w;
    #else
        #ifndef USING_DIRECTIONAL_LIGHT
        return _WorldSpaceLightPos0.xyz - worldPos;
        #else
        return _WorldSpaceLightPos0.xyz;
        #endif
    #endif
}

// Computes world space light direction, from object space position
// *Legacy* Please use MyWorldSpaceLightDir instead
inline float3 WorldSpaceLightDir( in float4 localPos )
{
    float3 worldPos = mul(_Object2World, localPos).xyz;
    return MyWorldSpaceLightDir(worldPos);
}

// Computes object space light direction
inline float3 ObjSpaceLightDir( in float4 v )
{
    float3 objSpaceLightPos = mul(_World2Object, _WorldSpaceLightPos0).xyz;
    #ifndef USING_LIGHT_MULTI_COMPILE
        return objSpaceLightPos.xyz - v.xyz * _WorldSpaceLightPos0.w;
    #else
        #ifndef USING_DIRECTIONAL_LIGHT
        return objSpaceLightPos.xyz - v.xyz;
        #else
        return objSpaceLightPos.xyz;
        #endif
    #endif
}

// Computes world space view direction, from object space position
inline float3 MyWorldSpaceViewDir( in float3 worldPos )
{
    return _WorldSpaceCameraPos.xyz - worldPos;
}

// Computes world space view direction, from object space position
// *Legacy* Please use MyWorldSpaceViewDir instead
inline float3 WorldSpaceViewDir( in float4 localPos )
{
    float3 worldPos = mul(_Object2World, localPos).xyz;
    return MyWorldSpaceViewDir(worldPos);
}

// Computes object space view direction
inline float3 ObjSpaceViewDir( in float4 v )
{
    float3 objSpaceCameraPos = mul(_World2Object, float4(_WorldSpaceCameraPos.xyz, 1)).xyz;
    return objSpaceCameraPos - v.xyz;
}

// Declares 3x3 matrix 'rotation', filled with tangent space basis
#define TANGENT_SPACE_ROTATION \
    float3 binormal = cross( normalize(v.normal), normalize(v.tangent.xyz) ) * v.tangent.w; \
    float3x3 rotation = float3x3( v.tangent.xyz, binormal, v.normal )




float3 Shade4PointLights (
    float4 lightPosX, float4 lightPosY, float4 lightPosZ,
    float3 lightColor0, float3 lightColor1, float3 lightColor2, float3 lightColor3,
    float4 lightAttenSq,
    float3 pos, float3 normal)
{
    // to light vectors
    float4 toLightX = lightPosX - pos.x;
    float4 toLightY = lightPosY - pos.y;
    float4 toLightZ = lightPosZ - pos.z;
    // squared lengths
    float4 lengthSq = 0;
    lengthSq += toLightX * toLightX;
    lengthSq += toLightY * toLightY;
    lengthSq += toLightZ * toLightZ;
    // NdotL
    float4 ndotl = 0;
    ndotl += toLightX * normal.x;
    ndotl += toLightY * normal.y;
    ndotl += toLightZ * normal.z;
    // correct NdotL
    float4 corr = rsqrt(lengthSq);
    ndotl = max (float4(0,0,0,0), ndotl * corr);
    // attenuation
    float4 atten = 1.0 / (1.0 + lengthSq * lightAttenSq);
    float4 diff = ndotl * atten;
    // final color
    float3 col = 0;
    col += lightColor0 * diff.x;
    col += lightColor1 * diff.y;
    col += lightColor2 * diff.z;
    col += lightColor3 * diff.w;
    return col;
}


float3 ShadeVertexLights (float4 vertex, float3 normal)
{
    float3 viewpos = mul (VAR_MATRIX_MV, vertex).xyz;
    float3 viewN = normalize (mul ((float3x3)VAR_MATRIX_IT_MV, normal));
    float3 lightColor = VAR_LIGHTMODEL_AMBIENT.xyz;
    for (int i = 0; i < 4; i++) {
        float3 toLight = var_LightPosition[i].xyz - viewpos.xyz * var_LightPosition[i].w;
        float lengthSq = dot(toLight, toLight);
        float atten = 1.0 / (1.0 + lengthSq * var_LightAtten[i].z);
        float diff = max (0, dot (viewN, normalize(toLight)));
        lightColor += var_LightColor[i].rgb * (diff * atten);
    }
    return lightColor;
}


// normal should be normalized, w=1.0
half3 ShadeSH9 (half4 normal)
{
    half3 x1, x2, x3;

    // Linear + constant polynomial terms
    x1.r = dot(var_SHAr,normal);
    x1.g = dot(var_SHAg,normal);
    x1.b = dot(var_SHAb,normal);

    // 4 of the quadratic polynomials
    half4 vB = normal.xyzz * normal.yzzx;
    x2.r = dot(var_SHBr,vB);
    x2.g = dot(var_SHBg,vB);
    x2.b = dot(var_SHBb,vB);

    // Final quadratic polynomial
    float vC = normal.x*normal.x - normal.y*normal.y;
    x3 = var_SHC.rgb * vC;
    return x1 + x2 + x3;
} 


// Transforms 2D UV by scale/bias property
#define TRANSFORM_TEX(tex,name) (tex.xy * name##_ST.xy + name##_ST.zw)

// Deprecated. Used to transform 4D UV by a fixed function texture matrix. Now just returns the passed UV.
#define TRANSFORM_UV(idx) v.texcoord.xy



struct v2f_vertex_lit {
    float2 uv   : TEXCOORD0;
    fixed4 diff : COLOR0;
    fixed4 spec : COLOR1;
};  

inline fixed4 VertexLight( v2f_vertex_lit i, sampler2D mainTex )
{
    fixed4 texcol = tex2D( mainTex, i.uv );
    fixed4 c;
    c.xyz = ( texcol.xyz * i.diff.xyz + i.spec.xyz * texcol.a ) * 2;
    c.w = texcol.w * i.diff.w;
    return c;
}


// Calculates UV offset for parallax bump mapping
inline float2 ParallaxOffset( half h, half height, half3 viewDir )
{
    h = h * height - height/2.0;
    float3 v = normalize(viewDir);
    v.z += 0.42;
    return h * (v.xy / v.z);
}


// Converts color to luminance (grayscale)
inline fixed Luminance( fixed3 c )
{
    return dot( c, fixed3(0.22, 0.707, 0.071) );
}

// Decodes HDR textures
// handles dLDR, RGBM formats
inline half3 DecodeHDR (half4 data, half4 decodeInstructions)
{
    // GLES2.0 support only Gamma mode, we can skip exponent
    // SM2.0 might be used in combination with SM3.0, so we can NOT skip exponent
    #if (defined(SHADER_API_GLES) && defined(SHADER_API_MOBILE))
        return (decodeInstructions.x * data.a) * data.rgb;
    #else
        return (decodeInstructions.x * pow(data.a, decodeInstructions.y)) * data.rgb;
    #endif
}

// Decodes lightmaps:
// - doubleLDR encoded on GLES
// - RGBM encoded with range [0;8] on other platforms using surface shaders
inline fixed3 DecodeLightmap( fixed4 color )
{
#if defined(VAR_NO_RGBM)
    return 2.0 * color.rgb;
#else
    // potentially faster to do the scalar multiplication
    // in parenthesis for scalar GPUs
    return (8.0 * color.a) * color.rgb;
#endif
}

// Decode LRB lightmaps, range [0;16]:
// - alpha: the low 8 bits of the 16-bit luminance value
// - red:   the high 8 bits of the 16-bit luminance value
// - green: scaled red
// - blue:  scaled blue
inline half3 DecodeLightmapLRB( fixed4 value )
{   
    half3 color         = half3 (value.g, 1.0f - value.g - value.b, value.b);
    half intensity      = (value.r + value.a / 256.0f) * 16.0f;
    half3 irradiance    = color * intensity;

    return irradiance;
}


// Helpers used in image effects. Most image effects use the same
// minimal vertex shader (vert_img).

struct appdata_img {
    float4 vertex : POSITION;
    half2 texcoord : TEXCOORD0;
};
struct v2f_img {
    float4 pos : SV_POSITION;
    half2 uv : TEXCOORD0;
};

float2 MultiplyUV (float4x4 mat, float2 inUV) {
    float4 temp = float4 (inUV.x, inUV.y, 0, 0);
    temp = mul (mat, temp);
    return temp.xy;
}

v2f_img vert_img( appdata_img v )
{
    v2f_img o;
    o.pos = mul (VAR_MATRIX_MVP, v.vertex);
    o.uv = v.texcoord;
    return o;
}


// Encoding/decoding [0..1) floats into 8 bit/channel RGBA. Note that 1.0 will not be encoded properly.
inline float4 EncodeFloatRGBA( float v )
{
    float4 kEncodeMul = float4(1.0, 255.0, 65025.0, 16581375.0);
    float kEncodeBit = 1.0/255.0;
    float4 enc = kEncodeMul * v;
    enc = frac (enc);
    enc -= enc.yzww * kEncodeBit;
    return enc;
}
inline float DecodeFloatRGBA( float4 enc )
{
    float4 kDecodeDot = float4(1.0, 1/255.0, 1/65025.0, 1/16581375.0);
    return dot( enc, kDecodeDot );
}

// Encoding/decoding [0..1) floats into 8 bit/channel RG. Note that 1.0 will not be encoded properly.
inline float2 EncodeFloatRG( float v )
{
    float2 kEncodeMul = float2(1.0, 255.0);
    float kEncodeBit = 1.0/255.0;
    float2 enc = kEncodeMul * v;
    enc = frac (enc);
    enc.x -= enc.y * kEncodeBit;
    return enc;
}
inline float DecodeFloatRG( float2 enc )
{
    float2 kDecodeDot = float2(1.0, 1/255.0);
    return dot( enc, kDecodeDot );
}


// Encoding/decoding view space normals into 2D 0..1 vector
inline float2 EncodeViewNormalStereo( float3 n )
{
    float kScale = 1.7777;
    float2 enc;
    enc = n.xy / (n.z+1);
    enc /= kScale;
    enc = enc*0.5+0.5;
    return enc;
}
inline float3 DecodeViewNormalStereo( float4 enc4 )
{
    float kScale = 1.7777;
    float3 nn = enc4.xyz*float3(2*kScale,2*kScale,0) + float3(-kScale,-kScale,1);
    float g = 2.0 / dot(nn.xyz,nn.xyz);
    float3 n;
    n.xy = g*nn.xy;
    n.z = g-1;
    return n;
}

inline float4 EncodeDepthNormal( float depth, float3 normal )
{
    float4 enc;
    enc.xy = EncodeViewNormalStereo (normal);
    enc.zw = EncodeFloatRG (depth);
    return enc;
}

inline void DecodeDepthNormal( float4 enc, out float depth, out float3 normal )
{
    depth = DecodeFloatRG (enc.zw);
    normal = DecodeViewNormalStereo (enc);
}

inline fixed3 UnpackNormalDXT5nm (fixed4 packednormal)
{
    fixed3 normal;
    normal.xy = packednormal.wy * 2 - 1;
    normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));
    return normal;
}

inline fixed3 UnpackNormal(fixed4 packednormal)
{
#if defined(VAR_NO_DXT5nm)
    return packednormal.xyz * 2 - 1;
#else
    return UnpackNormalDXT5nm(packednormal);
#endif
}


// Z buffer to linear 0..1 depth (0 at eye, 1 at far plane)
inline float Linear01Depth( float z )
{
    return 1.0 / (_ZBufferParams.x * z + _ZBufferParams.y);
}
// Z buffer to linear depth
inline float LinearEyeDepth( float z )
{
    return 1.0 / (_ZBufferParams.z * z + _ZBufferParams.w);
}


// Depth render texture helpers
#if defined(VAR_MIGHT_NOT_HAVE_DEPTH_TEXTURE)
    #define VAR_TRANSFER_DEPTH(oo) oo = o.pos.zw
    #define VAR_OUTPUT_DEPTH(i) return i.x/i.y
#else
    #define VAR_TRANSFER_DEPTH(oo) 
    #define VAR_OUTPUT_DEPTH(i) return 0
#endif
#define DECODE_EYEDEPTH(i) LinearEyeDepth(i)
#define COMPUTE_EYEDEPTH(o) o = -mul( VAR_MATRIX_MV, v.vertex ).z
#define COMPUTE_DEPTH_01 -(mul( VAR_MATRIX_MV, v.vertex ).z * _ProjectionParams.w)
#define COMPUTE_VIEW_NORMAL normalize(mul((float3x3)VAR_MATRIX_IT_MV, v.normal))


// Projected screen position helpers
#define V2F_SCREEN_TYPE float4
inline float4 ComputeScreenPos (float4 pos) {
    float4 o = pos * 0.5f;
    #if defined(VAR_HALF_TEXEL_OFFSET)
    o.xy = float2(o.x, o.y*_ProjectionParams.x) + o.w * _ScreenParams.zw;
    #else
    o.xy = float2(o.x, o.y*_ProjectionParams.x) + o.w;
    #endif

    o.zw = pos.zw;
    return o;
}

inline float4 ComputeGrabScreenPos (float4 pos) {
    #if VAR_UV_STARTS_AT_TOP
    float scale = -1.0;
    #else
    float scale = 1.0;
    #endif
    float4 o = pos * 0.5f;
    o.xy = float2(o.x, o.y*scale) + o.w;
    o.zw = pos.zw;
    return o;
}

// snaps post-transformed position to screen pixels
inline float4 MyPixelSnap (float4 pos)
{
    float2 hpc = _ScreenParams.xy * 0.5f;
    #ifdef VAR_HALF_TEXEL_OFFSET
    float2 hpcO = float2(-0.5f, 0.5f);
    #else
    float2 hpcO = float2(0,0);
    #endif  
    float2 pixelPos = round ((pos.xy / pos.w) * hpc);
    pos.xy = (pixelPos + hpcO) / hpc * pos.w;
    return pos;
}

inline float2 TransformViewToProjection (float2 v) {
    return mul((float2x2)VAR_MATRIX_P, v);
}

inline float3 TransformViewToProjection (float3 v) {
    return mul((float3x3)VAR_MATRIX_P, v);
}

// Shadow caster pass helpers

float4 MyEncodeCubeShadowDepth (float z)
{
    #ifdef VAR_USE_RGBA_FOR_POINT_SHADOWS
    return EncodeFloatRGBA (min(z, 0.999));
    #else
    return z;
    #endif
}

float MyDecodeCubeShadowDepth (float4 vals)
{
    #ifdef VAR_USE_RGBA_FOR_POINT_SHADOWS
    return DecodeFloatRGBA (vals);
    #else
    return vals.r;
    #endif
}


#ifdef SHADOWS_CUBE
    #define V2F_SHADOW_CASTER float4 pos : SV_POSITION; float3 vec : TEXCOORD0
    #define TRANSFER_SHADOW_CASTER(o) o.vec = mul( _Object2World, v.vertex ).xyz - _LightPositionRange.xyz; o.pos = mul(VAR_MATRIX_MVP, v.vertex);
    #define SHADOW_CASTER_FRAGMENT(i) return MyEncodeCubeShadowDepth (length(i.vec) * _LightPositionRange.w);
#else
    #if defined(VAR_MIGHT_NOT_HAVE_DEPTH_TEXTURE)
    #define V2F_SHADOW_CASTER float4 pos : SV_POSITION; float4 hpos : TEXCOORD0
    #define TRANSFER_SHADOW_CASTER(o) \
        o.pos = mul(VAR_MATRIX_MVP, v.vertex); \
        o.pos.z += saturate(var_LightShadowBias.x/o.pos.w); \
        float clamped = max(o.pos.z, o.pos.w*VAR_NEAR_CLIP_VALUE); \
        o.pos.z = lerp(o.pos.z, clamped, var_LightShadowBias.y); \
        o.hpos = o.pos;
    #else
    #define V2F_SHADOW_CASTER float4 pos : SV_POSITION
    #define TRANSFER_SHADOW_CASTER(o) \
        o.pos = mul(VAR_MATRIX_MVP, v.vertex); \
        o.pos.z += saturate(var_LightShadowBias.x/o.pos.w); \
        float clamped = max(o.pos.z, o.pos.w*VAR_NEAR_CLIP_VALUE); \
        o.pos.z = lerp(o.pos.z, clamped, var_LightShadowBias.y);
    #endif
    #define SHADOW_CASTER_FRAGMENT(i) VAR_OUTPUT_DEPTH(i.hpos.zw);
#endif


// ------------------------------------------------------------------
//  Fog helpers
//
//  multi_compile_fog Will compile fog variants.
//  VAR_FOG_COORDS(texcoordindex) Declares the fog data interpolator.
//  VAR_TRANSFER_FOG(outputStruct,clipspacePos) Outputs fog data from the vertex shader.
//  VAR_APPLY_FOG(fogData,col) Applies fog to color "col". Automatically applies black fog when in forward-additive pass.
//  Can also use VAR_APPLY_FOG_COLOR to supply your own fog color.

// In case someone by accident tries to compile fog code in one of the g-buffer or shadow passes:
// treat it as fog is off.
#if defined(VAR_PASS_PREPASSBASE) || defined(VAR_PASS_DEFERRED) || defined(VAR_PASS_SHADOWCASTER)
#undef FOG_LINEAR
#undef FOG_EXP
#undef FOG_EXP2
#endif

#if defined(FOG_LINEAR) || defined(FOG_EXP) || defined(FOG_EXP2)
#define VAR_FOG_COORDS(idx) float fogCoord : TEXCOORD##idx;
#define VAR_TRANSFER_FOG(o,outpos) o.fogCoord = (outpos).z
#else
#define VAR_FOG_COORDS(idx)
#define VAR_TRANSFER_FOG(o,outpos)
#endif

#define VAR_FOG_LERP_COLOR(col,fogCol,fogFac) col.rgb = lerp((fogCol).rgb, (col).rgb, saturate(fogFac))


#if defined(FOG_LINEAR)
    // factor = (end-z)/(end-start) = z * (-1/(end-start)) + (end/(end-start))
    #define VAR_APPLY_FOG_COLOR(coord,col,fogCol) float fogFac = (coord) * var_FogParams.z + var_FogParams.w; VAR_FOG_LERP_COLOR(col,fogCol,fogFac)
#elif defined(FOG_EXP)
    // factor = exp(-density*z)
    #define VAR_APPLY_FOG_COLOR(coord,col,fogCol) float fogFac = var_FogParams.y * (coord); fogFac = exp2(-fogFac); VAR_FOG_LERP_COLOR(col,fogCol,fogFac)
#elif defined(FOG_EXP2)
    // factor = exp(-(density*z)^2)
    #define VAR_APPLY_FOG_COLOR(coord,col,fogCol) float fogFac = var_FogParams.x * (coord); fogFac = exp2(-fogFac*fogFac); VAR_FOG_LERP_COLOR(col,fogCol,fogFac)
#else
    #define VAR_APPLY_FOG_COLOR(coord,col,fogCol)
#endif

#ifdef VAR_PASS_FORWARDADD
    #define VAR_APPLY_FOG(coord,col) VAR_APPLY_FOG_COLOR(coord,col,fixed4(0,0,0,0))
#else
    #define VAR_APPLY_FOG(coord,col) VAR_APPLY_FOG_COLOR(coord,col,var_FogColor)
#endif


// ------------------------------------------------------------------
//  Deprecated things: these aren't used; kept here
//  just so that various existing shaders still compile, more or less.


// Note: deprecated shadow collector pass helpers
#ifdef SHADOW_COLLECTOR_PASS

#if !defined(SHADOWMAPSAMPLER_DEFINED)
VAR_DECLARE_SHADOWMAP(_ShadowMapTexture);
#endif

// Note: deprecated
#define V2F_SHADOW_COLLECTOR float4 pos : SV_POSITION; float3 _ShadowCoord0 : TEXCOORD0; float3 _ShadowCoord1 : TEXCOORD1; float3 _ShadowCoord2 : TEXCOORD2; float3 _ShadowCoord3 : TEXCOORD3; float4 _WorldPosViewZ : TEXCOORD4
#define TRANSFER_SHADOW_COLLECTOR(o)    \
    o.pos = mul(VAR_MATRIX_MVP, v.vertex); \
    float4 wpos = mul(_Object2World, v.vertex); \
    o._WorldPosViewZ.xyz = wpos; \
    o._WorldPosViewZ.w = -mul( VAR_MATRIX_MV, v.vertex ).z; \
    o._ShadowCoord0 = mul(var_World2Shadow[0], wpos).xyz; \
    o._ShadowCoord1 = mul(var_World2Shadow[1], wpos).xyz; \
    o._ShadowCoord2 = mul(var_World2Shadow[2], wpos).xyz; \
    o._ShadowCoord3 = mul(var_World2Shadow[3], wpos).xyz;

// Note: deprecated
#if defined (SHADOWS_NATIVE)
    #define SAMPLE_SHADOW_COLLECTOR_SHADOW(coord) \
    half shadow = VAR_SAMPLE_SHADOW(_ShadowMapTexture,coord); \
    shadow = _LightShadowData.r + shadow * (1-_LightShadowData.r);
#else
    #define SAMPLE_SHADOW_COLLECTOR_SHADOW(coord) \
    float shadow = SAMPLE_DEPTH_TEXTURE(_ShadowMapTexture, coord.xy ) < coord.z ? _LightShadowData.r : 1.0;
#endif

// Note: deprecated
#define COMPUTE_SHADOW_COLLECTOR_SHADOW(i, weights, shadowFade) \
    float4 coord = float4(i._ShadowCoord0 * weights[0] + i._ShadowCoord1 * weights[1] + i._ShadowCoord2 * weights[2] + i._ShadowCoord3 * weights[3], 1); \
    SAMPLE_SHADOW_COLLECTOR_SHADOW(coord) \
    float4 res; \
    res.x = saturate(shadow + shadowFade); \
    res.y = 1.0; \
    res.zw = EncodeFloatRG (1 - i._WorldPosViewZ.w * _ProjectionParams.w); \
    return res; 

// Note: deprecated
#if defined (SHADOWS_SPLIT_SPHERES)
#define SHADOW_COLLECTOR_FRAGMENT(i) \
    float3 fromCenter0 = i._WorldPosViewZ.xyz - var_ShadowSplitSpheres[0].xyz; \
    float3 fromCenter1 = i._WorldPosViewZ.xyz - var_ShadowSplitSpheres[1].xyz; \
    float3 fromCenter2 = i._WorldPosViewZ.xyz - var_ShadowSplitSpheres[2].xyz; \
    float3 fromCenter3 = i._WorldPosViewZ.xyz - var_ShadowSplitSpheres[3].xyz; \
    float4 distances2 = float4(dot(fromCenter0,fromCenter0), dot(fromCenter1,fromCenter1), dot(fromCenter2,fromCenter2), dot(fromCenter3,fromCenter3)); \
    float4 cascadeWeights = float4(distances2 < var_ShadowSplitSqRadii); \
    cascadeWeights.yzw = saturate(cascadeWeights.yzw - cascadeWeights.xyz); \
    float sphereDist = distance(i._WorldPosViewZ.xyz, var_ShadowFadeCenterAndType.xyz); \
    float shadowFade = saturate(sphereDist * _LightShadowData.z + _LightShadowData.w); \
    COMPUTE_SHADOW_COLLECTOR_SHADOW(i, cascadeWeights, shadowFade)
#else
#define SHADOW_COLLECTOR_FRAGMENT(i) \
    float4 viewZ = i._WorldPosViewZ.w; \
    float4 zNear = float4( viewZ >= _LightSplitsNear ); \
    float4 zFar = float4( viewZ < _LightSplitsFar ); \
    float4 cascadeWeights = zNear * zFar; \
    float shadowFade = saturate(i._WorldPosViewZ.w * _LightShadowData.z + _LightShadowData.w); \
    COMPUTE_SHADOW_COLLECTOR_SHADOW(i, cascadeWeights, shadowFade)
#endif

#endif // #ifdef SHADOW_COLLECTOR_PASS


#endif // VAR_CG_INCLUDED

#line 23 ""


float _TessEdge;
float _Displacement;


//=================================================================================================================================
// Buffers, Textures and Samplers
//=================================================================================================================================

Texture2D _MainTex;
SamplerState    sampler_MainTex;
Texture2D _DispTex;
SamplerState    sampler_DispTex;

//=================================================================================================================================
// Shader structures
//=================================================================================================================================


struct VS_RenderSceneInput
{
    float3 vertex : POSITION;
    float3 normal : NORMAL;
    float2 texcoord : TEXCOORD0;
};

struct HS_Input
{
    float4 f4Position   : POS;
    float3 f3Normal     : NORMAL;
    float2 f2TexCoord   : TEXCOORD;
};

struct HS_ConstantOutput
{
    // Tess factor for the FF HW block
    float fTessFactor[3]    : SV_TessFactor;
    float fInsideTessFactor : SV_InsideTessFactor;

    // Geometry cubic generated control points
    float3 f3B210    : POS3;
    float3 f3B120    : POS4;
    float3 f3B021    : POS5;
    float3 f3B012    : POS6;
    float3 f3B102    : POS7;
    float3 f3B201    : POS8;
    float3 f3B111    : CENTER;

    // Normal quadratic generated control points
    float3 f3N110    : NORMAL3;
    float3 f3N011    : NORMAL4;
    float3 f3N101    : NORMAL5;
};

struct HS_ControlPointOutput
{
    float3    f3Position    : POS;
    float3    f3Normal      : NORMAL;
    float2    f2TexCoord    : TEXCOORD;
};

struct DS_Output
{
    float4 f4Position   : SV_Position;
    float2 f2TexCoord   : TEXCOORD0;
    float4 f4Diffuse    : COLOR0;
};

struct PS_RenderSceneInput
{
    float4 f4Position   : SV_Position;
    float2 f2TexCoord   : TEXCOORD0;
    float4 f4Diffuse    : COLOR0;
};

struct PS_RenderOutput
{
    float4 f4Color      : SV_Target0;
};

PS_RenderSceneInput VS_RenderScene( VS_RenderSceneInput I )
{
    PS_RenderSceneInput O;

    O.f4Position = mul (VAR_MATRIX_MVP, float4(I.vertex, 1.0f));
    float3 viewN = mul ((float3x3)VAR_MATRIX_IT_MV, I.normal);

    // Calc diffuse color
    O.f4Diffuse.rgb = var_LightColor[0].rgb * max(0, dot(viewN, var_LightPosition[0].xyz)) + VAR_LIGHTMODEL_AMBIENT.rgb;
    O.f4Diffuse.a = 1.0f;

    // Pass through texture coords
    O.f2TexCoord = I.texcoord;

    return O;
}


HS_Input VS_RenderSceneWithTessellation( VS_RenderSceneInput I )
{
    HS_Input O;

    // To view space
    O.f4Position = mul(VAR_MATRIX_MV, float4(I.vertex,1.0f));
    O.f3Normal = mul ((float3x3)VAR_MATRIX_IT_MV, I.normal);

    O.f2TexCoord = I.texcoord;

    return O;
}


//=================================================================================================================================
// This hull shader passes the tessellation factors through to the HW tessellator,
// and the 10 (geometry), 6 (normal) control points of the PN-triangular patch to the domain shader
//=================================================================================================================================
HS_ConstantOutput HS_PNTrianglesConstant( InputPatch<HS_Input, 3> I )
{
    HS_ConstantOutput O = (HS_ConstantOutput)0;

    // Simply output the tessellation factors from constant space
    // for use by the FF tessellation unit
    O.fTessFactor[0] = O.fTessFactor[1] = O.fTessFactor[2] = _TessEdge;
    O.fInsideTessFactor = _TessEdge;

    // Assign Positions
    float3 f3B003 = I[0].f4Position.xyz;
    float3 f3B030 = I[1].f4Position.xyz;
    float3 f3B300 = I[2].f4Position.xyz;
    // And Normals
    float3 f3N002 = I[0].f3Normal;
    float3 f3N020 = I[1].f3Normal;
    float3 f3N200 = I[2].f3Normal;

    // Compute the cubic geometry control points
    // Edge control points
    O.f3B210 = ( ( 2.0f * f3B003 ) + f3B030 - ( dot( ( f3B030 - f3B003 ), f3N002 ) * f3N002 ) ) / 3.0f;
    O.f3B120 = ( ( 2.0f * f3B030 ) + f3B003 - ( dot( ( f3B003 - f3B030 ), f3N020 ) * f3N020 ) ) / 3.0f;
    O.f3B021 = ( ( 2.0f * f3B030 ) + f3B300 - ( dot( ( f3B300 - f3B030 ), f3N020 ) * f3N020 ) ) / 3.0f;
    O.f3B012 = ( ( 2.0f * f3B300 ) + f3B030 - ( dot( ( f3B030 - f3B300 ), f3N200 ) * f3N200 ) ) / 3.0f;
    O.f3B102 = ( ( 2.0f * f3B300 ) + f3B003 - ( dot( ( f3B003 - f3B300 ), f3N200 ) * f3N200 ) ) / 3.0f;
    O.f3B201 = ( ( 2.0f * f3B003 ) + f3B300 - ( dot( ( f3B300 - f3B003 ), f3N002 ) * f3N002 ) ) / 3.0f;
    // Center control point
    float3 f3E = ( O.f3B210 + O.f3B120 + O.f3B021 + O.f3B012 + O.f3B102 + O.f3B201 ) / 6.0f;
    float3 f3V = ( f3B003 + f3B030 + f3B300 ) / 3.0f;
    O.f3B111 = f3E + ( ( f3E - f3V ) / 2.0f );

    // Compute the quadratic normal control points
    float fV12 = 2.0f * dot( f3B030 - f3B003, f3N002 + f3N020 ) / dot( f3B030 - f3B003, f3B030 - f3B003 );
    O.f3N110 = normalize( f3N002 + f3N020 - fV12 * ( f3B030 - f3B003 ) );
    float fV23 = 2.0f * dot( f3B300 - f3B030, f3N020 + f3N200 ) / dot( f3B300 - f3B030, f3B300 - f3B030 );
    O.f3N011 = normalize( f3N020 + f3N200 - fV23 * ( f3B300 - f3B030 ) );
    float fV31 = 2.0f * dot( f3B003 - f3B300, f3N200 + f3N002 ) / dot( f3B003 - f3B300, f3B003 - f3B300 );
    O.f3N101 = normalize( f3N200 + f3N002 - fV31 * ( f3B003 - f3B300 ) );

    return O;
}

[domain("tri")]
[partitioning("fractional_odd")]
[outputtopology("triangle_cw")]
[patchconstantfunc("HS_PNTrianglesConstant")]
[outputcontrolpoints(3)]
HS_ControlPointOutput HS_PNTriangles( InputPatch<HS_Input, 3> I, uint uCPID : SV_OutputControlPointID )
{
    HS_ControlPointOutput O = (HS_ControlPointOutput)0;

    // Just pass through inputs = fast pass through mode triggered
    O.f3Position = I[uCPID].f4Position.xyz;
    O.f3Normal = I[uCPID].f3Normal;
    O.f2TexCoord = I[uCPID].f2TexCoord;

    return O;
}


//=================================================================================================================================
// This domain shader applies contol point weighting to the barycentric coords produced by the FF tessellator
//=================================================================================================================================
[domain("tri")]
DS_Output DS_PNTriangles( HS_ConstantOutput HSConstantData, const OutputPatch<HS_ControlPointOutput, 3> I, float3 f3BarycentricCoords : SV_DomainLocation )
{
    DS_Output O = (DS_Output)0;

    // The barycentric coordinates
    float fU = f3BarycentricCoords.x;
    float fV = f3BarycentricCoords.y;
    float fW = f3BarycentricCoords.z;

    // Precompute squares and squares * 3
    float fUU = fU * fU;
    float fVV = fV * fV;
    float fWW = fW * fW;
    float fUU3 = fUU * 3.0f;
    float fVV3 = fVV * 3.0f;
    float fWW3 = fWW * 3.0f;

    // Compute position from cubic control points and barycentric coords
    float3 f3Position = I[0].f3Position * fWW * fW +
                        I[1].f3Position * fUU * fU +
                        I[2].f3Position * fVV * fV +
                        HSConstantData.f3B210 * fWW3 * fU +
                        HSConstantData.f3B120 * fW * fUU3 +
                        HSConstantData.f3B201 * fWW3 * fV +
                        HSConstantData.f3B021 * fUU3 * fV +
                        HSConstantData.f3B102 * fW * fVV3 +
                        HSConstantData.f3B012 * fU * fVV3 +
                        HSConstantData.f3B111 * 6.0f * fW * fU * fV;

    // Compute normal from quadratic control points and barycentric coords
    float3 f3Normal =   I[0].f3Normal * fWW +
                        I[1].f3Normal * fUU +
                        I[2].f3Normal * fVV +
                        HSConstantData.f3N110 * fW * fU +
                        HSConstantData.f3N011 * fU * fV +
                        HSConstantData.f3N101 * fW * fV;

    // Normalize the interpolated normal
    f3Normal = normalize( f3Normal );

    // Linearly interpolate the texture coords
    O.f2TexCoord = I[0].f2TexCoord * fW + I[1].f2TexCoord * fU + I[2].f2TexCoord * fV;

    // Displacement map!
    float disp = _DispTex.SampleLevel (sampler_DispTex, O.f2TexCoord, 0).r * _Displacement;
    f3Position += f3Normal * disp;

    // Calc diffuse color
    O.f4Diffuse.rgb = var_LightColor[0].rgb * max( 0, dot( f3Normal, var_LightPosition[0].xyz ) ) + VAR_LIGHTMODEL_AMBIENT.rgb;
    O.f4Diffuse.a = 1.0f;

    // Transform position with projection matrix
    O.f4Position = mul (VAR_MATRIX_P, float4(f3Position.xyz,1.0));

    return O;
}


PS_RenderOutput PS_RenderSceneTextured( PS_RenderSceneInput I )
{
    PS_RenderOutput O;

    O.f4Color = _MainTex.Sample( sampler_MainTex, I.f2TexCoord ).r * I.f4Diffuse;

    return O;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions