rabidus-test/Assets/PolyFew/BatchFewShader/Includes/BatchFewStandardInput.cginc

411 lines
13 KiB
HLSL

// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
// 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_INPUT_INCLUDED
#define UNITY_STANDARD_INPUT_INCLUDED
#include "UnityCG.cginc"
#include "Includes/BatchFewStandardConfig.cginc"
#include "UnityPBSLighting.cginc" // TBD: remove
#include "Includes/BatchFewStandardUtils.cginc"
//---------------------------------------
// Directional lightmaps & Parallax require tangent space too
#if (_NORMALMAP || DIRLIGHTMAP_COMBINED || defined(_PARALLAXMAP) || defined(_POM))
#define _TANGENT_TO_WORLD 1
#endif
#if (_DETAIL_MULX2 || _DETAIL_MUL || _DETAIL_ADD || _DETAIL_LERP)
#define _DETAIL 1
#endif
//---------------------------------------
half _Cutoff;
UNITY_DECLARE_TEX2DARRAY(_MainTex);
float4 _MainTex_ST;
sampler2D _AttrImg;
float4 _AttrImg_TexelSize;
UNITY_DECLARE_TEX2DARRAY(_DetailAlbedoMap);
float4 _DetailAlbedoMap_ST;
UNITY_DECLARE_TEX2DARRAY(_BumpMap);
UNITY_DECLARE_TEX2DARRAY(_DetailMask);
UNITY_DECLARE_TEX2DARRAY(_DetailNormalMap);
UNITY_DECLARE_TEX2DARRAY(_SpecGlossMap);
UNITY_DECLARE_TEX2DARRAY(_MetallicGlossMap);
UNITY_DECLARE_TEX2DARRAY(_OcclusionMap);
UNITY_DECLARE_TEX2DARRAY(_ParallaxMap);
half _Parallax;
half _UVSec;
UNITY_DECLARE_TEX2DARRAY(_EmissionMap);
sampler2D _DetailAlbedoSingle;
sampler2D _DetailNormalSingle;
//-------------------------------------------------------------------------------------
// Input functions
struct VertexInput
{
float4 vertex : POSITION;
half4 color : COLOR;
half3 normal : NORMAL;
float4 uv0 : TEXCOORD0;
float2 uv1 : TEXCOORD1;
#if defined(DYNAMICLIGHTMAP_ON) || defined(UNITY_PASS_META)
float2 uv2 : TEXCOORD2;
#endif
#ifdef _TANGENT_TO_WORLD
half4 tangent : TANGENT;
#endif
UNITY_VERTEX_INPUT_INSTANCE_ID
};
float4 SampleAttrImg(float prop, float index)
{
return tex2Dlod(_AttrImg, float4((prop + 0.5) * _AttrImg_TexelSize.x, (index + 0.5) * _AttrImg_TexelSize.y, 0, 0));
}
float4 TexCoords(VertexInput v)
{
float4 uvScaleOffset = SampleAttrImg(0, v.color.r * 255);
float4 texcoord;
texcoord.z = v.color.a * 255;
texcoord.w = v.color.r * 255;
texcoord.xy = v.uv0.xy * (uvScaleOffset.xy+1) + uvScaleOffset.zw;
return texcoord;
}
half DetailMask(float3 uv)
{
return UNITY_SAMPLE_TEX2DARRAY(_DetailMask, uv).a;
}
half3 Albedo(float4 texcoords, half4 attribs)
{
half3 albedo = UNITY_SAMPLE_TEX2DARRAY (_MainTex, texcoords.xyz).rgb * SampleAttrImg(2, texcoords.w).rgb;
#if _DETAIL
#if (SHADER_TARGET < 30)
// SM20: instruction count limitation
// SM20: no detail mask
half mask = 1;
#else
half mask = DetailMask(texcoords);
#endif
//float4 uvmod = SampleAttrImg(5, texcoords.w);
texcoords.xy = texcoords.xy * SampleAttrImg(5, texcoords.w).xy + SampleAttrImg(5, texcoords.w).zw;
half3 detailAlbedo = UNITY_SAMPLE_TEX2DARRAY (_DetailAlbedoMap, texcoords.xyz).rgb;
#if _DETAIL_MULX2
albedo *= LerpWhiteTo (detailAlbedo * unity_ColorSpaceDouble.rgb, mask);
#elif _DETAIL_MUL
albedo *= LerpWhiteTo (detailAlbedo, mask);
#elif _DETAIL_ADD
albedo += detailAlbedo * mask;
#elif _DETAIL_LERP
albedo = lerp (albedo, detailAlbedo, mask);
#endif
#elif _DETAIL_SINGLE
#if (SHADER_TARGET < 30)
// SM20: instruction count limitation
// SM20: no detail mask
half mask = 1;
#else
half mask = DetailMask(texcoords);
#endif
//float4 uvmod = SampleAttrImg(5, texcoords.w);
texcoords.xy = texcoords.xy * SampleAttrImg(5, texcoords.w).xy + SampleAttrImg(5, texcoords.w).zw;
half3 detailAlbedo = tex2D (_DetailAlbedoSingle, texcoords.xy).rgb;
albedo *= LerpWhiteTo (detailAlbedo * unity_ColorSpaceDouble.rgb, mask);
#endif
return albedo;
}
half Alpha(float4 uv)
{
return UNITY_SAMPLE_TEX2DARRAY(_MainTex, uv.xyz).a;
}
half Occlusion(float4 uv, half4 attribs)
{
return UNITY_SAMPLE_TEX2DARRAY(_OcclusionMap, uv.xyz).g * attribs.y;
}
half4 SpecularGloss(float4 uv, half4 attribs)
{
half4 sg = attribs.wwzz;
#ifdef _SPECGLOSSMAP
#if defined(_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A)
sg.rgb = UNITY_SAMPLE_TEX2DARRAY(_SpecGlossMap, uv.xyz).rgb;
sg.a = UNITY_SAMPLE_TEX2DARRAY(_MainTex, uv.xyz).a * attribs.z;
#else
sg = UNITY_SAMPLE_TEX2DARRAY(_SpecGlossMap, uv.xyz);
#endif
sg.a *= SampleAttrImg(4, uv.w).a;
#else
sg.rgb = SampleAttrImg(4, uv.w).rgb;
#ifdef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
sg.a = UNITY_SAMPLE_TEX2DARRAY(_MainTex, uv.xyz).a * attribs.z;
#else
sg.a = SampleAttrImg(1, uv.w).b;
#endif
#endif
return sg;
}
half2 MetallicGloss(float4 uv, half4 attribs)
{
half2 mg = attribs.wz;
#ifdef _METALLICGLOSSMAP
#ifdef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
mg.r = UNITY_SAMPLE_TEX2DARRAY(_MetallicGlossMap, uv.xyz).r;
mg.g = UNITY_SAMPLE_TEX2DARRAY(_MainTex, uv.xyz).a * attribs.z;
#else
mg = UNITY_SAMPLE_TEX2DARRAY(_MetallicGlossMap, uv.xyz).ra;
mg.g *= attribs.z;
#endif
#else
mg.r = attribs.w;
#ifdef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
mg.g = UNITY_SAMPLE_TEX2DARRAY(_MainTex, uv.xyz).a;
#else
mg.g = attribs.z;
#endif
#endif
return mg;
}
half3 Emission(float4 uv)
{
#if _EMISSION
return UNITY_SAMPLE_TEX2DARRAY(_EmissionMap, uv.xyz).rgb;
#endif
#if _EMISSION_COLOR
return SampleAttrImg(3, uv.w).xyz;
#endif
return half3(0,0,0);
}
#ifdef _NORMALMAP
half3 NormalInTangentSpace(float4 texcoords, half4 attribs)
{
half3 normalTangent = UnpackScaleNormal(UNITY_SAMPLE_TEX2DARRAY (_BumpMap, texcoords.xyz), attribs.r);
#if _DETAIL && defined(UNITY_ENABLE_DETAIL_NORMALMAP)
half mask = DetailMask(texcoords);
texcoords.xy = texcoords.xy * SampleAttrImg(5, texcoords.w).xy + SampleAttrImg(5, texcoords.w).zw;
half3 detailNormalTangent = UnpackScaleNormal(UNITY_SAMPLE_TEX2DARRAY (_DetailNormalMap, texcoords.xyz), SampleAttrImg(6, texcoords.w).r);
#if _DETAIL_LERP
normalTangent = lerp(
normalTangent,
detailNormalTangent,
mask);
#else
normalTangent = lerp(
normalTangent,
BlendNormals(normalTangent, detailNormalTangent),
mask);
#endif
#endif
#if _DETAIL_SINGLE && defined(UNITY_ENABLE_DETAIL_NORMALMAP)
half mask = DetailMask(texcoords);
//float uvmod = SampleAttrImg(5, texcoords.w);
texcoords.xy = texcoords.xy * SampleAttrImg(5, texcoords.w).xy + SampleAttrImg(5, texcoords.w).zw;
half3 detailNormalTangent = UnpackScaleNormal(tex2D (_DetailNormalSingle, texcoords.xy), SampleAttrImg(6, texcoords.w).r);
#if _DETAIL_LERP
normalTangent = lerp(
normalTangent,
detailNormalTangent,
mask);
#else
normalTangent = lerp(
normalTangent,
BlendNormals(normalTangent, detailNormalTangent),
mask);
#endif
#endif
return normalTangent;
}
#endif
#if (UNITY_VERSION >= 201810 && (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))) || (UNITY_VERSION < 201810 && (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL)))
#define BACTHFEW_SAMPLE_TEX2D_GRAD(tex,coord,dx,dy) tex.SampleGrad (sampler##tex,coord,dx,dy)
#elif defined(SHADER_API_D3D9)
#define BACTHFEW_SAMPLE_TEX2D_GRAD(tex,coord,dx,dy) half4(0,1,0,0)
#elif defined(UNITY_COMPILER_HLSL2GLSL) || defined(SHADER_TARGET_SURFACE_ANALYSIS)
#define BACTHFEW_SAMPLE_TEX2D_GRAD(tex,coord,dx,dy) texCUBEgrad (tex,coord,float3(dx.x,dx.y,0),float3(dy.x,dy.y,0))
#elif defined(SHADER_API_GLES)
#define BACTHFEW_SAMPLE_TEX2D_GRAD(tex,coord,dx,dy) half4(1,1,0,0)
#elif defined(SHADER_API_D3D11_9X)
#define BACTHFEW_SAMPLE_TEX2D_GRAD(tex,coord,dx,dy) half4(0,1,1,0)
#else
#define BACTHFEW_SAMPLE_TEX2D_GRAD(tex,coord,dx,dy) half4(0,0,1,0)
#endif
#if (UNITY_VERSION >= 201810 && (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))) || (UNITY_VERSION < 201810 && (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL)))
#define BATCHFEW_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)
#define BATCHFEW_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)
#else
#define BATCHFEW_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)
#define BATCHFEW_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)
#endif
float ComputeMipLevel(float2 uv, float2 textureSize)
{
uv *= textureSize;
float2 dx_vtc = ddx(uv);
float2 dy_vtc = ddy(uv);
float delta_max_sqr = max(dot(dx_vtc, dx_vtc), dot(dy_vtc, dy_vtc));
return 0.5 * log2(delta_max_sqr);
}
int _ParallaxSteps;
float4 _ParallaxMap_TexelSize;
inline float2 POM( float2 uvs,
float3 normalWorld, float3 viewWorld, float3 viewDirTan,
float parallax, float texIndex)
{
float curvFix = 1.0;
float2 curv = float2(0, 0);
float refPlane = 0;
float3 result = 0;
int stepIndex = 0;
//int numSteps = ( int )lerp( maxSamples, minSamples, dot( normalWorld, viewWorld ) );
int numSteps = _ParallaxSteps; // artifacts when using variable step slope above
float layerHeight = 1.0 / numSteps;
float2 plane = parallax * ( viewDirTan.xy / viewDirTan.z );
uvs += refPlane * plane;
float2 deltaTex = -plane * layerHeight;
float2 prevTexOffset = 0;
float prevRayZ = 1.0f;
float prevHeight = 0.0f;
float2 currTexOffset = deltaTex;
float currRayZ = 1.0f - layerHeight;
float currHeight = 0.0f;
float intersection = 0;
float2 finalTexOffset = 0;
float mipLevel = ComputeMipLevel(uvs, _ParallaxMap_TexelSize.zw);
while ( stepIndex < numSteps + 1 )
{
result.z = dot( curv, currTexOffset * currTexOffset );
currHeight = BATCHFEW_SAMPLE_TEX2D_LOD(_ParallaxMap, float3(uvs + currTexOffset, texIndex), mipLevel ).r * ( 1 - result.z );
if ( currHeight > currRayZ )
{
stepIndex = numSteps + 1;
}
else
{
stepIndex++;
prevTexOffset = currTexOffset;
prevRayZ = currRayZ;
prevHeight = currHeight;
currTexOffset += deltaTex;
currRayZ -= layerHeight * ( 1 - result.z ) * (1+curvFix);
}
}
int sectionSteps = 10;
int sectionIndex = 0;
float newZ = 0;
float newHeight = 0;
while ( sectionIndex < sectionSteps )
{
intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );
finalTexOffset = prevTexOffset + intersection * deltaTex;
newZ = prevRayZ - intersection * layerHeight;
newHeight = BATCHFEW_SAMPLE_TEX2D_LOD(_ParallaxMap, float3(uvs + finalTexOffset, texIndex), mipLevel ).r * ( 1 - result.z );
if ( newHeight > newZ )
{
currTexOffset = finalTexOffset;
currHeight = newHeight;
currRayZ = newZ;
deltaTex = intersection * deltaTex;
layerHeight = intersection * layerHeight;
}
else
{
prevTexOffset = finalTexOffset;
prevHeight = newHeight;
prevRayZ = newZ;
deltaTex = ( 1 - intersection ) * deltaTex;
layerHeight = ( 1 - intersection ) * layerHeight;
}
sectionIndex++;
}
#ifdef UNITY_PASS_SHADOWCASTER
if ( unity_LightShadowBias.z == 0.0 )
{
#endif
if ( result.z > 1 )
clip( -1 );
#ifdef UNITY_PASS_SHADOWCASTER
}
#endif
return uvs + finalTexOffset;
}
float4 Parallax (float4 texcoords, half3 i_viewDirForParallax, float3 i_eyeVec, float4 tangentToWorld[3])
{
#if defined(_PARALLAXMAP)
half h = UNITY_SAMPLE_TEX2DARRAY (_ParallaxMap, texcoords.xyz).g;
float2 offset = ParallaxOffset1Step (h, SampleAttrImg(6, texcoords.w).b, i_viewDirForParallax);
return float4(texcoords.xy + offset, texcoords.zw);
#endif
#if defined(_POM)
float parallax = SampleAttrImg(6, texcoords.w).b;
half3 normal = (0,0,1);
half3 worldNormal = half3(dot(tangentToWorld[0], normal), dot(tangentToWorld[1],normal), dot(tangentToWorld[2],normal));
float2 offset = POM(texcoords.xy, worldNormal, i_eyeVec, i_viewDirForParallax, parallax, texcoords.z);
return float4(offset, texcoords.zw);
#endif
return texcoords;
}
#endif // UNITY_STANDARD_INPUT_INCLUDED