191 lines
6.6 KiB
HLSL
191 lines
6.6 KiB
HLSL
// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
|
|
// This code in no way belongs to BrainFailProductions. I have just made a small change to make
|
|
// it work with texture arrays
|
|
|
|
#ifndef UNITY_STANDARD_SHADOW_INCLUDED
|
|
#define UNITY_STANDARD_SHADOW_INCLUDED
|
|
|
|
|
|
#include "UnityCG.cginc"
|
|
#include "Includes/BatchFewStandardConfig.cginc"
|
|
#include "Includes/BatchFewStandardUtils.cginc"
|
|
|
|
#if (defined(_ALPHABLEND_ON) || defined(_ALPHAPREMULTIPLY_ON)) && defined(UNITY_USE_DITHER_MASK_FOR_ALPHABLENDED_SHADOWS)
|
|
#define UNITY_STANDARD_USE_DITHER_MASK 1
|
|
#endif
|
|
|
|
// Need to output UVs in shadow caster, since we need to sample texture and do clip/dithering based on it
|
|
#if defined(_ALPHATEST_ON) || defined(_ALPHABLEND_ON) || defined(_ALPHAPREMULTIPLY_ON)
|
|
#define UNITY_STANDARD_USE_SHADOW_UVS 1
|
|
#endif
|
|
|
|
// Has a non-empty shadow caster output struct (it's an error to have empty structs on some platforms...)
|
|
#if !defined(V2F_SHADOW_CASTER_NOPOS_IS_EMPTY) || defined(UNITY_STANDARD_USE_SHADOW_UVS)
|
|
#define UNITY_STANDARD_USE_SHADOW_OUTPUT_STRUCT 1
|
|
#endif
|
|
|
|
#ifdef UNITY_STEREO_INSTANCING_ENABLED
|
|
#define UNITY_STANDARD_USE_STEREO_SHADOW_OUTPUT_STRUCT 1
|
|
#endif
|
|
|
|
|
|
half _Cutoff;
|
|
UNITY_DECLARE_TEX2DARRAY(_MainTex);
|
|
float4 _MainTex_ST;
|
|
#ifdef UNITY_STANDARD_USE_DITHER_MASK
|
|
sampler3D _DitherMaskLOD;
|
|
#endif
|
|
|
|
// Handle PremultipliedAlpha from Fade or Transparent shading mode
|
|
#ifdef _SPECGLOSSMAP
|
|
UNITY_DECLARE_TEX2DARRAY(_SpecGlossMap);
|
|
#endif
|
|
#ifdef _METALLICGLOSSMAP
|
|
UNITY_DECLARE_TEX2DARRAY(_MetallicGlossMap);
|
|
#endif
|
|
|
|
#if defined(UNITY_STANDARD_USE_SHADOW_UVS) && (defined(_PARALLAXMAP) || defined(_POM))
|
|
UNITY_DECLARE_TEX2DARRAY(_ParallaxMap);
|
|
#endif
|
|
|
|
half MetallicSetup_ShadowGetOneMinusReflectivity(half3 uv)
|
|
{
|
|
half metallicity = 0;
|
|
#ifdef _METALLICGLOSSMAP
|
|
metallicity = UNITY_SAMPLE_TEX2DARRAY(_MetallicGlossMap, uv).r;
|
|
#endif
|
|
return OneMinusReflectivityFromMetallic(metallicity);
|
|
}
|
|
|
|
half SpecularSetup_ShadowGetOneMinusReflectivity(half3 uv)
|
|
{
|
|
half3 specColor = half3(0,0,0);
|
|
#ifdef _SPECGLOSSMAP
|
|
specColor = UNITY_SAMPLE_TEX2DARRAY(_SpecGlossMap, uv).rgb;
|
|
#endif
|
|
return (1 - SpecularStrength(specColor));
|
|
}
|
|
|
|
// SHADOW_ONEMINUSREFLECTIVITY(): workaround to get one minus reflectivity based on UNITY_SETUP_BRDF_INPUT
|
|
#define SHADOW_JOIN2(a, b) a##b
|
|
#define SHADOW_JOIN(a, b) SHADOW_JOIN2(a,b)
|
|
#define SHADOW_ONEMINUSREFLECTIVITY SHADOW_JOIN(UNITY_SETUP_BRDF_INPUT, _ShadowGetOneMinusReflectivity)
|
|
|
|
struct VertexInput
|
|
{
|
|
float4 vertex : POSITION;
|
|
float3 normal : NORMAL;
|
|
float4 uv0 : TEXCOORD0;
|
|
float4 color : COLOR;
|
|
#if defined(UNITY_STANDARD_USE_SHADOW_UVS) && (defined(_PARALLAXMAP) || defined(_POM))
|
|
half4 tangent : TANGENT;
|
|
#endif
|
|
UNITY_VERTEX_INPUT_INSTANCE_ID
|
|
};
|
|
|
|
#ifdef UNITY_STANDARD_USE_SHADOW_OUTPUT_STRUCT
|
|
struct VertexOutputShadowCaster
|
|
{
|
|
V2F_SHADOW_CASTER_NOPOS
|
|
#if defined(UNITY_STANDARD_USE_SHADOW_UVS)
|
|
float4 tex : TEXCOORD1;
|
|
|
|
#if (defined(_PARALLAXMAP) || defined(_POM))
|
|
half4 tangentToWorldAndParallax[3]: TEXCOORD2; // [3x3:tangentToWorld | 1x3:viewDirForParallax]
|
|
#endif
|
|
#endif
|
|
};
|
|
#endif
|
|
|
|
#ifdef UNITY_STANDARD_USE_STEREO_SHADOW_OUTPUT_STRUCT
|
|
struct VertexOutputStereoShadowCaster
|
|
{
|
|
UNITY_VERTEX_OUTPUT_STEREO
|
|
};
|
|
#endif
|
|
|
|
// We have to do these dances of outputting SV_POSITION separately from the vertex shader,
|
|
// and inputting VPOS in the pixel shader, since they both map to "POSITION" semantic on
|
|
// some platforms, and then things don't go well.
|
|
|
|
|
|
void vertShadowCaster (VertexInput v,
|
|
#ifdef UNITY_STANDARD_USE_SHADOW_OUTPUT_STRUCT
|
|
out VertexOutputShadowCaster o,
|
|
#endif
|
|
#ifdef UNITY_STANDARD_USE_STEREO_SHADOW_OUTPUT_STRUCT
|
|
out VertexOutputStereoShadowCaster os,
|
|
#endif
|
|
out float4 opos : SV_POSITION)
|
|
{
|
|
UNITY_SETUP_INSTANCE_ID(v);
|
|
#ifdef UNITY_STANDARD_USE_STEREO_SHADOW_OUTPUT_STRUCT
|
|
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(os);
|
|
#endif
|
|
TRANSFER_SHADOW_CASTER_NOPOS(o,opos)
|
|
#if defined(UNITY_STANDARD_USE_SHADOW_UVS)
|
|
o.tex.xy = TRANSFORM_TEX(v.uv0.xy * (v.uv0.zw+1), _MainTex);
|
|
o.tex.z = v.color.a * 255;
|
|
o.tex.w = v.color.r * 255;
|
|
|
|
#if (defined(_PARALLAXMAP) || defined(_POM))
|
|
TANGENT_SPACE_ROTATION;
|
|
half3 viewDirForParallax = mul (rotation, ObjSpaceViewDir(v.vertex));
|
|
o.tangentToWorldAndParallax[0].w = viewDirForParallax.x;
|
|
o.tangentToWorldAndParallax[1].w = viewDirForParallax.y;
|
|
o.tangentToWorldAndParallax[2].w = viewDirForParallax.z;
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
sampler2D _AttrImg;
|
|
float4 _AttrImg_TexelSize;
|
|
float4 SampleAttrImg(float prop, float index)
|
|
{
|
|
return tex2Dlod(_AttrImg, float4(prop * _AttrImg_TexelSize.x, index * _AttrImg_TexelSize.y, 0, 0));
|
|
}
|
|
|
|
half4 fragShadowCaster (
|
|
#ifdef UNITY_STANDARD_USE_SHADOW_OUTPUT_STRUCT
|
|
VertexOutputShadowCaster i
|
|
#endif
|
|
#ifdef UNITY_STANDARD_USE_DITHER_MASK
|
|
, UNITY_VPOS_TYPE vpos : VPOS
|
|
#endif
|
|
) : SV_Target
|
|
{
|
|
#if defined(UNITY_STANDARD_USE_SHADOW_UVS)
|
|
#if (defined(_PARALLAXMAP) || defined(_POM)) && (SHADER_TARGET >= 30)
|
|
//On d3d9 parallax can also be disabled on the fwd pass when too many sampler are used. See EXCEEDS_D3D9_SM3_MAX_SAMPLER_COUNT. Ideally we should account for that here as well.
|
|
half3 viewDirForParallax = normalize( half3(i.tangentToWorldAndParallax[0].w,i.tangentToWorldAndParallax[1].w,i.tangentToWorldAndParallax[2].w) );
|
|
fixed h = UNITY_SAMPLE_TEX2DARRAY (_ParallaxMap, i.tex).g;
|
|
half2 offset = ParallaxOffset1Step (h, SampleAttrImg(6, i.tex.w).b, viewDirForParallax);
|
|
i.tex.xy += offset;
|
|
#endif
|
|
|
|
half alpha = UNITY_SAMPLE_TEX2DARRAY(_MainTex, i.tex).a;
|
|
#if defined(_ALPHATEST_ON)
|
|
clip (alpha - _Cutoff);
|
|
#endif
|
|
#if defined(_ALPHABLEND_ON) || defined(_ALPHAPREMULTIPLY_ON)
|
|
#if defined(_ALPHAPREMULTIPLY_ON)
|
|
half outModifiedAlpha;
|
|
PreMultiplyAlpha(half3(0, 0, 0), alpha, SHADOW_ONEMINUSREFLECTIVITY(i.tex), outModifiedAlpha);
|
|
alpha = outModifiedAlpha;
|
|
#endif
|
|
#if defined(UNITY_STANDARD_USE_DITHER_MASK)
|
|
// Use dither mask for alpha blended shadows, based on pixel position xy
|
|
// and alpha level. Our dither texture is 4x4x16.
|
|
half alphaRef = tex3D(_DitherMaskLOD, float3(vpos.xy*0.25,alpha*0.9375)).a;
|
|
clip (alphaRef - 0.01);
|
|
#else
|
|
clip (alpha - _Cutoff);
|
|
#endif
|
|
#endif
|
|
#endif // #if defined(UNITY_STANDARD_USE_SHADOW_UVS)
|
|
|
|
SHADOW_CASTER_FRAGMENT(i)
|
|
}
|
|
|
|
#endif // UNITY_STANDARD_SHADOW_INCLUDED
|