James-Jones / HLSLCrossCompiler

Other
468 stars 81 forks source link

Crash translating hull shader outputs #32

Open davidrogers-unity opened 10 years ago

davidrogers-unity commented 10 years ago

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;
}
James-Jones commented 10 years ago

Output signature 3 registers (0-2)

Patch Constant signature 10 registers (0-9)

There is an access to o3 but the compiler is only looking at output signatures so it will return NULL since there is no o3 there. It appears that join phase output registers are from the patch constant signature.

So the fix involves decoding the PCSG fourcc chunk and look for output registers there for certain phases.

davidrogers-unity commented 10 years ago

Is this something that you'd be able to take a look at(if you have the time) or I can. But I've had trouble finding documentation regarding the formats. Do you have anything that describes the format of PCSG chunks?

James-Jones commented 10 years ago

I have pushed changes to decode PCSG. It is the same as output signatures.

James-Jones commented 10 years ago

OK I have done a quick change to use the patch constants. The shader compiles but I have not looked into its correctness.

davidrogers-unity commented 10 years ago

Things are looking much better thanks to you.

Here is another, similar crash. First there is the requirement to increase the number of max fork phases but that's an easy fix.

#line 8 ""
#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_GLES3PLUS) || 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_GLES3PLUS) || 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_GLES3PLUS)
#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_GLES3PLUS) || 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 11 ""

#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_GLES3PLUS) || 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_GLES3PLUS) || 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_GLES3PLUS)
#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_GLES3PLUS) || 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 12 ""

#line 8 ""
#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_GLES3PLUS) || 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_GLES3PLUS) || 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_GLES3PLUS)
#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_GLES3PLUS) || 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 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 21 ""

float _TessEdge;
float _TessInside;

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

Texture2D _MainTex;
SamplerState    sampler_MainTex;

//=================================================================================================================================
// 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;

    // 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;
    //O.f4Diffuse.rgb = f3BarycentricCoords;

    // 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 ) * I.f4Diffuse;

    return O;
}