723 lines
28 KiB
GLSL
723 lines
28 KiB
GLSL
/*
|
|
Filamented texture blending sample.
|
|
This is designed to be used as-is in existing projects, but
|
|
experienced users may wish to modify how the shader functions.
|
|
*/
|
|
Shader "Silent/Filamented Extras/Texture Blending Filamented"
|
|
{
|
|
Properties
|
|
{
|
|
[CheckDFGTexture]
|
|
[BlendModeSelector(_SrcBlend, _DstBlend, _CustomRenderQueue, _ZWrite, _AtoCmode)] _Mode ("__mode", Float) = 0.0
|
|
|
|
[HeaderEx(Base Settings)]
|
|
[Enum(UV0,0,UV1,1,UV2,2,UV3,3)] _UVSec ("UV for Splat Map", Float) = 0
|
|
[SetKeyword(_SPLATMAP)]_MainTex("Splat Map (Optional) and Texture Scale", 2D) = "black" {}
|
|
[ToggleUI]_WeightFromDirection("World-Space XYZ to Vertex Colour RGB", Float) = 0
|
|
|
|
[HeaderEx(Base Color)]
|
|
[ScaleOffset][SingleLine(_ColorA)]_MainTexA ("Albedo (RGB)", 2D) = "white" {}
|
|
[HideInInspector]_ColorA("Color", Color) = (1,1,1,1)
|
|
[SingleLine(_BumpScaleA)][Normal]_BumpMapA ("Normal Map (XYZ)", 2D) = "bump" {}
|
|
[HideInInspector]_BumpScaleA("Normal Scale", Float) = 1
|
|
[SingleLine(_PropertiesA)]_MaskMapA ("Mask (MOES)", 2D) = "green" {}
|
|
[HideInInspector]_PropertiesA("MOES Scale", Vector) = (0.0, 0.0, 0.0, 1.0)
|
|
|
|
[HeaderEx(Vertex Color R)]
|
|
[ScaleOffset][SingleLine(_ColorR)]_MainTexR ("Albedo (RGB)", 2D) = "white" {}
|
|
[HideInInspector]_ColorR("Color", Color) = (1,1,1,1)
|
|
[SingleLine(_BumpScaleR)][Normal]_BumpMapR ("Normal Map (XYZ)", 2D) = "bump" {}
|
|
[HideInInspector]_BumpScaleR("Normal Scale", Float) = 1
|
|
[SingleLine(_PropertiesR)]_MaskMapR ("Mask (MOES)", 2D) = "green" {}
|
|
[HideInInspector]_PropertiesR("MOES Scale", Vector) = (0.0, 0.0, 0.0, 1.0)
|
|
|
|
[HeaderEx(Vertex Color G)]
|
|
[ScaleOffset][SingleLine(_ColorG)]_MainTexG ("Albedo (RGB)", 2D) = "white" {}
|
|
[HideInInspector]_ColorG("Color", Color) = (1,1,1,1)
|
|
[SingleLine(_BumpScaleG)][Normal]_BumpMapG ("Normal Map (XYZ)", 2D) = "bump" {}
|
|
[HideInInspector]_BumpScaleG("Normal Scale", Float) = 1
|
|
[SingleLine(_PropertiesG)]_MaskMapG ("Mask (MOES)", 2D) = "green" {}
|
|
[HideInInspector]_PropertiesG("MOES Scale", Vector) = (0.0, 0.0, 0.0, 1.0)
|
|
|
|
[HeaderEx(Vertex Color B)]
|
|
[ScaleOffset][SingleLine(_ColorB)]_MainTexB ("Albedo (RGB)", 2D) = "white" {}
|
|
[HideInInspector]_ColorB("Color", Color) = (1,1,1,1)
|
|
[SingleLine(_BumpScaleB)][Normal]_BumpMapB ("Normal Map (XYZ)", 2D) = "bump" {}
|
|
[HideInInspector]_BumpScaleB("Normal Scale", Float) = 1
|
|
[SingleLine(_PropertiesB)]_MaskMapB ("Mask (MOES)", 2D) = "green" {}
|
|
[HideInInspector]_PropertiesB("MOES Scale", Vector) = (0.0, 0.0, 0.0, 1.0)
|
|
|
|
[HeaderEx(Texture Blending Settings)]
|
|
[ScaleOffset][SingleLine]_BlendMask ("Texture Blending Offset (R)", 2D) = "grey" {}
|
|
_MaskStr("Blending Mask Power (per-channel)", Vector) = (1.0, 1.0, 1.0, 1.0)
|
|
[Toggle(_DEBUG_VIEWWEIGHTS)]_DebugViewBlendingWeights("Debug View for Blend Weights", Float ) = 0.0
|
|
|
|
[Space]
|
|
[HeaderEx(Sampling Settings)]
|
|
[Toggle(_STOCHASTIC)]_UseStochastic("Stochastic Sampling", Float) = 0.0
|
|
[Space]
|
|
[Toggle(_TRIPLANAR)]_UseTriplanar("Triplanar Sampling", Float) = 0.0
|
|
[IfDef(_TRIPLANAR)]_UVTransform0("Triplanar UV Transform X", Vector) = (1, 0, 0, 0)
|
|
[IfDef(_TRIPLANAR)]_UVTransform1("Triplanar UV Transform Y", Vector) = (0, 1, 0, 0)
|
|
[IfDef(_TRIPLANAR)]_UVTransform2("Triplanar UV Transform Z", Vector) = (0, 0, 1, 0)
|
|
|
|
[HeaderEx(Filamented Settings)]
|
|
[Toggle(_LIGHTMAPSPECULAR)]_LightmapSpecular("Lightmap Specular", Range(0, 1)) = 1
|
|
_LightmapSpecularMaxSmoothness("Lightmap Specular Max Smoothness", Range(0, 1)) = 1
|
|
_ExposureOcclusion("Lightmap Occlusion Sensitivity", Range(0, 1)) = 0.2
|
|
|
|
[Space]
|
|
[KeywordEnum(None, SH, RNM, MonoSH)] _Bakery ("Bakery Mode", Int) = 0
|
|
[HideInInspector]_RNM0("RNM0", 2D) = "black" {}
|
|
[HideInInspector]_RNM1("RNM1", 2D) = "black" {}
|
|
[HideInInspector]_RNM2("RNM2", 2D) = "black" {}
|
|
[Toggle(_LTCGI)] _LTCGI ("LTCGI", Int) = 0
|
|
[Toggle(_VRCLV)] _VRCLV ("VRC Light Volumes", Int) = 0
|
|
[IfDef(_VRCLV)] _VRCLVSurfaceBias("Light Volume Surface Bias", Range(0, 0.5)) = 0.05
|
|
[Space]
|
|
[Enum(UnityEngine.Rendering.CullMode)]_CullMode("Cull Mode", Int) = 2
|
|
|
|
[NonModifiableTextureData][HideInInspector] _DFG("DFG", 2D) = "white" {}
|
|
// Blending state
|
|
[HideInInspector] _SrcBlend ("__src", Float) = 1.0
|
|
[HideInInspector] _DstBlend ("__dst", Float) = 0.0
|
|
[HideInInspector] _CustomRenderQueue ("__rq", Float) = 1.0
|
|
[HideInInspector] _ZWrite ("__zw", Float) = 1.0
|
|
[HideInInspector] _AtoCmode("__atoc", Float) = 0
|
|
}
|
|
|
|
CustomEditor "Silent.FilamentedExtras.Unity.FilamentedExtrasInspector"
|
|
|
|
CGINCLUDE
|
|
// First, setup what Filamented does.
|
|
// Filamented's behaviour is decided by the shading model and what material properties are defined.
|
|
// These are listed in FilamentMaterialInputs.
|
|
// You can set up and use anything in the initMaterials function.
|
|
|
|
// SHADING_MODEL_SPECULAR_GLOSSINESS
|
|
// If this is not defined, the material will default to metallic/roughness workflow.
|
|
|
|
#define MATERIAL_HAS_NORMAL
|
|
// If this is not defined, normal maps won't be enabled.
|
|
|
|
#define MATERIAL_HAS_AMBIENT_OCCLUSION
|
|
// If this is not defined, occlusion won't be taken into account
|
|
|
|
#define MATERIAL_HAS_EMISSIVE
|
|
// If this is not defined, emission won't be taken into account
|
|
|
|
// MATERIAL_HAS_ANISOTROPY
|
|
// If this is set, the material will support anisotropy.
|
|
|
|
// MATERIAL_HAS_CLEAR_COAT
|
|
// If this is set, the material will support clear coat.
|
|
|
|
#define HAS_ATTRIBUTE_COLOR
|
|
// If this is not defined, vertex colour will not be available.
|
|
|
|
#define HAS_ATTRIBUTE_UV2
|
|
#define HAS_ATTRIBUTE_UV3
|
|
// If this is not defined, secondary UVs will not be available.
|
|
|
|
#define USE_DFG_LUT
|
|
// Whether to use the lookup texture for specular reflection calculation.
|
|
// Requires a shader property _DFG to be present and filled.
|
|
ENDCG
|
|
|
|
CGINCLUDE
|
|
// UNITY_SHADER_NO_UPGRADE
|
|
#ifndef UNITY_PASS_SHADOWCASTER
|
|
|
|
// Include common files. These will include the other files as needed.
|
|
#include "Packages/s-ilent.filamented/Filamented/UnityLightingCommon.cginc"
|
|
#include "Packages/s-ilent.filamented/Filamented/UnityStandardInput.cginc"
|
|
#include "Packages/s-ilent.filamented/Filamented/UnityStandardConfig.cginc"
|
|
#include "Packages/s-ilent.filamented/Filamented/UnityStandardCore.cginc"
|
|
#include "Packages/s-ilent.filamented/Filamented/SharedSamplingLib.hlsl"
|
|
// Note: Unfortunately, Input is still needed due to some interdependancies with other Unity files.
|
|
// This means that some properties will always be defined, even if they aren't used.
|
|
// In practise, this won't affect the final compilation, but it means you'll need to watch out for the names
|
|
// of some common parameters.
|
|
|
|
TEXTURE2D(_MainTexR); TEXTURE2D(_MainTexG); TEXTURE2D(_MainTexB); TEXTURE2D(_MainTexA);
|
|
TEXTURE2D(_BumpMapR); TEXTURE2D(_BumpMapG); TEXTURE2D(_BumpMapB); TEXTURE2D(_BumpMapA);
|
|
TEXTURE2D(_MaskMapR); TEXTURE2D(_MaskMapG); TEXTURE2D(_MaskMapB); TEXTURE2D(_MaskMapA);
|
|
|
|
SAMPLER(sampler_MainTexR);
|
|
SAMPLER(sampler_BumpMapR);
|
|
SAMPLER(sampler_MaskMapR);
|
|
|
|
float4 _MainTexR_ST; float4 _MainTexG_ST; float4 _MainTexB_ST; float4 _MainTexA_ST;
|
|
|
|
float4 _ColorR; float4 _ColorG; float4 _ColorB; float4 _ColorA;
|
|
float _BumpScaleR; float _BumpScaleG; float _BumpScaleB; float _BumpScaleA;
|
|
|
|
float4 _PropertiesR; float4 _PropertiesG; float4 _PropertiesB; float4 _PropertiesA;
|
|
|
|
uniform half4 _UVTransform0;
|
|
uniform half4 _UVTransform1;
|
|
uniform half4 _UVTransform2;
|
|
|
|
TEXTURE2D(_BlendMask); SAMPLER(sampler_BlendMask);
|
|
float4 _BlendMask_ST;
|
|
float4 _MaskStr;
|
|
|
|
half _WeightFromDirection;
|
|
|
|
VertexOutputForwardBase vertBase (VertexInput v)
|
|
{
|
|
VertexOutputForwardBase o;
|
|
o = vertForwardBase(v);
|
|
o.tex.zw = TRANSFORM_TEX(((_UVSec == 0) ? v.uv0 : v.uv1), _MainTex);
|
|
#if defined(HAS_ATTRIBUTE_UV2)
|
|
o.tex.zw = TRANSFORM_TEX(((_UVSec == 2) ? v.uv2 : o.tex.zw), _MainTex);
|
|
#endif
|
|
#if defined(HAS_ATTRIBUTE_UV3)
|
|
o.tex.zw = TRANSFORM_TEX(((_UVSec == 3) ? v.uv3 : o.tex.zw), _MainTex);
|
|
#endif
|
|
return o;
|
|
}
|
|
|
|
VertexOutputForwardAdd vertAdd (VertexInput v)
|
|
{
|
|
VertexOutputForwardAdd o;
|
|
o = vertForwardAdd(v);
|
|
o.tex.zw = TRANSFORM_TEX(((_UVSec == 0) ? v.uv0 : v.uv1), _MainTex);
|
|
#if defined(HAS_ATTRIBUTE_UV2)
|
|
o.tex.zw = TRANSFORM_TEX(((_UVSec == 2) ? v.uv2 : o.tex.zw), _MainTex);
|
|
#endif
|
|
#if defined(HAS_ATTRIBUTE_UV3)
|
|
o.tex.zw = TRANSFORM_TEX(((_UVSec == 3) ? v.uv3 : o.tex.zw), _MainTex);
|
|
#endif
|
|
return o;
|
|
}
|
|
|
|
|
|
//hash for randomness
|
|
float2 hash2D2D(float2 s)
|
|
{
|
|
//magic numbers
|
|
return frac(sin(fmod(float2(dot(s, float2(127.1, 311.7)), dot(s, float2(269.5, 183.3))), 3.14159)) * 43758.5453);
|
|
}
|
|
|
|
//stochastic sampling
|
|
float4 tex2DStochastic(TEXTURE2D_PARAM(tex, smp), float2 UV)
|
|
{
|
|
//triangle vertices and blend weights
|
|
//BW_vx[0...2].xyz = triangle verts
|
|
//BW_vx[3].xy = blend weights (z is unused)
|
|
float4x3 BW_vx;
|
|
|
|
//uv transformed into triangular grid space with UV scaled by approximation of 2*sqrt(3)
|
|
float2 skewUV = mul(float2x2 (1.0, 0.0, -0.57735027, 1.15470054), UV * 3.464);
|
|
|
|
//vertex IDs and barycentric coords
|
|
float2 vxID = float2 (floor(skewUV));
|
|
float3 barry = float3 (frac(skewUV), 0);
|
|
barry.z = 1.0 - barry.x - barry.y;
|
|
|
|
BW_vx = ((barry.z > 0) ?
|
|
float4x3(float3(vxID, 0), float3(vxID + float2(0, 1), 0), float3(vxID + float2(1, 0), 0), barry.zyx) :
|
|
float4x3(float3(vxID + float2 (1, 1), 0), float3(vxID + float2 (1, 0), 0), float3(vxID + float2 (0, 1), 0), float3(-barry.z, 1.0 - barry.y, 1.0 - barry.x)));
|
|
|
|
//calculate derivatives to avoid triangular grid artifacts
|
|
float2 dx = ddx(UV);
|
|
float2 dy = ddy(UV);
|
|
|
|
//blend samples with calculated weights
|
|
return mul(SAMPLE_TEXTURE2D_GRAD(tex, smp, UV + hash2D2D(BW_vx[0].xy), dx, dy), BW_vx[3].x) +
|
|
mul(SAMPLE_TEXTURE2D_GRAD(tex, smp, UV + hash2D2D(BW_vx[1].xy), dx, dy), BW_vx[3].y) +
|
|
mul(SAMPLE_TEXTURE2D_GRAD(tex, smp, UV + hash2D2D(BW_vx[2].xy), dx, dy), BW_vx[3].z);
|
|
}
|
|
|
|
// Typical triplanar mapping -- has less visual artifacts than biplanar.
|
|
// Artifacts stand out because this is a material shader for things like
|
|
// terrain which cover a large portion of the screen.
|
|
float4 boxmap( TEXTURE2D_PARAM(tex, smp), float3 p, float3 n, float k )
|
|
{
|
|
// grab coord derivatives for texturing
|
|
float3 dpdx = ddx(p);
|
|
float3 dpdy = ddy(p);
|
|
|
|
float3 m = pow( abs(n), k );
|
|
|
|
// project+fetch
|
|
float4 x = 0.0;
|
|
if (m.x > 0) x = SAMPLE_TEXTURE2D_GRAD( tex, smp, p.zy, dpdx.zy, dpdy.zy );
|
|
float4 y = 0.0;
|
|
if (m.y > 0) y = SAMPLE_TEXTURE2D_GRAD( tex, smp, p.zx, dpdx.zx, dpdy.zx );
|
|
float4 z = 0.0;
|
|
if (m.z > 0) z = SAMPLE_TEXTURE2D_GRAD( tex, smp, p.xy, dpdx.xy, dpdy.xy );
|
|
|
|
// and blend
|
|
return (x*m.x + y*m.y + z*m.z) / (m.x + m.y + m.z);
|
|
}
|
|
|
|
float4 tex2DStochasticBoxmap(TEXTURE2D_PARAM(tex, smp), float3 p, float3 n, float k)
|
|
{
|
|
// Stochastic sampling
|
|
float4x3 BW_vx;
|
|
float3 m = pow( abs(n), k );
|
|
float2 skewUV = mul(float2x2 (1.0, 0.0, -0.57735027, 1.15470054), (p.xy * m.x + p.yz * m.y + p.zx * m.z) * 3.464);
|
|
float2 vxID = float2 (floor(skewUV));
|
|
float3 barry = float3 (frac(skewUV), 0);
|
|
barry.z = 1.0 - barry.x - barry.y;
|
|
|
|
BW_vx = ((barry.z > 0) ?
|
|
float4x3(float3(vxID, 0), float3(vxID + float2(0, 1), 0), float3(vxID + float2(1, 0), 0), barry.zyx) :
|
|
float4x3(float3(vxID + float2 (1, 1), 0), float3(vxID + float2 (1, 0), 0), float3(vxID + float2 (0, 1), 0), float3(-barry.z, 1.0 - barry.y, 1.0 - barry.x)));
|
|
|
|
// Box mapping
|
|
float3 dpdx = ddx(p);
|
|
float3 dpdy = ddy(p);
|
|
|
|
// Blend samples with calculated weights
|
|
return ((m.x > 0 ? mul(SAMPLE_TEXTURE2D_GRAD(tex, smp, p.zy + hash2D2D(BW_vx[0].xy), dpdx.zy, dpdy.zy), BW_vx[3].x) : 0) +
|
|
(m.y > 0 ? mul(SAMPLE_TEXTURE2D_GRAD(tex, smp, p.zx + hash2D2D(BW_vx[1].xy), dpdx.zx, dpdy.zx), BW_vx[3].y) : 0) +
|
|
(m.z > 0 ? mul(SAMPLE_TEXTURE2D_GRAD(tex, smp, p.xy + hash2D2D(BW_vx[2].xy), dpdx.xy, dpdy.xy), BW_vx[3].z) : 0)) / (m.x + m.y + m.z);
|
|
}
|
|
|
|
|
|
float3 RNMBlendUnpacked(float3 n1, float3 n2)
|
|
{
|
|
n1 += float3( 0, 0, 1);
|
|
n2 *= float3(-1, -1, 1);
|
|
return n1*dot(n1, n2)/n1.z - n2;
|
|
}
|
|
|
|
float3 PDNormalBlend(float3 n1, float3 n2, float alpha)
|
|
{
|
|
float2 pd1 = n1.xy / n1.z;
|
|
float2 pd2 = n2.xy / n2.z;
|
|
float2 pd_interpolated = lerp(pd1, pd2, alpha);
|
|
return normalize(float3(pd_interpolated, 1.0));
|
|
}
|
|
|
|
void addLayer(float weight, float2 uv, float4 uv_ST,
|
|
TEXTURE2D_PARAM(tex_A, smp_A), inout float4 albedoAlpha, float4 tint,
|
|
TEXTURE2D_PARAM(tex_N, smp_N), inout float3 normal, float scale,
|
|
TEXTURE2D_PARAM(tex_M, smp_M), inout float4 props,
|
|
inout float4 maskProps)
|
|
{
|
|
if (weight > 0)
|
|
{
|
|
uv = uv * uv_ST.xy + uv_ST.zw;
|
|
|
|
#if defined(_STOCHASTIC)
|
|
float4 thisBasemap = tex2DStochastic(tex_A, smp_A, uv);
|
|
float3 thisNormal = UnpackScaleNormal(tex2DStochastic(tex_N, smp_N, uv), weight * scale);
|
|
float4 thisProps = tex2DStochastic(tex_M, smp_M, uv);
|
|
#else
|
|
float4 thisBasemap = SAMPLE_TEXTURE2D(tex_A, smp_A, uv);
|
|
float3 thisNormal = UnpackScaleNormal(SAMPLE_TEXTURE2D(tex_N, smp_N, uv), weight * scale);
|
|
float4 thisProps = SAMPLE_TEXTURE2D(tex_M, smp_M, uv);
|
|
#endif
|
|
|
|
thisBasemap *= tint;
|
|
|
|
thisProps.rba *= maskProps.rba; // metallic, emission, smoothness
|
|
thisProps.g = lerp(1, thisProps.g, maskProps.g); // occlusion
|
|
|
|
#if 0
|
|
albedoAlpha = albedoAlpha + thisBasemap * weight;
|
|
normal = RNMBlendUnpacked(thisNormal, normal);
|
|
props = props + thisProps * weight;
|
|
#else
|
|
albedoAlpha = lerp(albedoAlpha, thisBasemap, weight);
|
|
normal = lerp(normal, thisNormal, weight);
|
|
props = lerp(props, thisProps, weight);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
void addLayerTriplanar(float weight, float3 p, float3 n, float4 uv_ST,
|
|
TEXTURE2D_PARAM(tex_A, smp_A), inout float4 albedoAlpha, float4 tint,
|
|
TEXTURE2D_PARAM(tex_N, smp_N), inout float3 normal, float scale,
|
|
TEXTURE2D_PARAM(tex_M, smp_M), inout float4 props,
|
|
inout float4 maskProps)
|
|
{
|
|
const float tightness = 6.0;
|
|
if (weight > 0.01)
|
|
{
|
|
p = p * uv_ST.xyx + uv_ST.zwz;
|
|
|
|
#if defined(_STOCHASTIC)
|
|
float4 thisBasemap = tex2DStochasticBoxmap(TEXTURE2D_ARGS(tex_A, smp_A), p, n, tightness);
|
|
float3 thisNormal = UnpackScaleNormal(tex2DStochasticBoxmap(TEXTURE2D_ARGS(tex_N, smp_N), p, n, tightness), weight * scale);
|
|
float4 thisProps = tex2DStochasticBoxmap(TEXTURE2D_ARGS(tex_M, smp_M), p, n, tightness);
|
|
#else
|
|
float4 thisBasemap = boxmap(TEXTURE2D_ARGS(tex_A, smp_A), p, n, tightness);
|
|
float3 thisNormal = UnpackScaleNormal(boxmap(TEXTURE2D_ARGS(tex_N, smp_N), p, n, tightness), weight * scale);
|
|
float4 thisProps = boxmap(TEXTURE2D_ARGS(tex_M, smp_M), p, n, tightness);
|
|
#endif
|
|
|
|
thisBasemap *= tint;
|
|
|
|
thisProps.rba *= maskProps.rba; // metallic, emission, smoothness
|
|
thisProps.g = lerp(1, thisProps.g, maskProps.g); // occlusion
|
|
|
|
#if 0
|
|
albedoAlpha = albedoAlpha + thisBasemap * weight;
|
|
normal = RNMBlendUnpacked(thisNormal, normal);
|
|
props = props + thisProps * weight;
|
|
#else
|
|
albedoAlpha = lerp(albedoAlpha, thisBasemap, weight);
|
|
normal = lerp(normal, thisNormal, weight);
|
|
props = lerp(props, thisProps, weight);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
// The material function itself! You can alter the code below to add extra properties.
|
|
inline MaterialInputs BlendedMaterialSetup (inout float4 i_tex, float4 tangentToWorld[3],
|
|
float3 i_posWorld, float4 i_color)
|
|
{
|
|
// Blend weights in vertex colours
|
|
fixed3 weights = i_color;
|
|
#if defined(_SPLATMAP)
|
|
// Blend weights in splat map
|
|
weights = tex2D (_MainTex, i_tex.zw);
|
|
#endif
|
|
|
|
float3x3 tangentToWorldOnly = float3x3(tangentToWorld[0].xyz, tangentToWorld[1].xyz, tangentToWorld[2].xyz);
|
|
float3 worldNormalT = mul ( float3( 0, 0, 1 ), tangentToWorldOnly );
|
|
float3 worldPosT = float3(
|
|
dot(float4(i_posWorld.xyz, 1), _UVTransform0),
|
|
dot(float4(i_posWorld.xyz, 1), _UVTransform1),
|
|
dot(float4(i_posWorld.xyz, 1), _UVTransform2)
|
|
);
|
|
|
|
if (_WeightFromDirection)
|
|
{
|
|
weights = (abs(worldNormalT));
|
|
}
|
|
|
|
#if defined(_TRIPLANAR)
|
|
float4 blendMod = boxmap(TEXTURE2D_ARGS(_BlendMask, sampler_BlendMask),
|
|
worldPosT * _BlendMask_ST.xyx + _BlendMask_ST.zwz, worldNormalT, 1.0).r;
|
|
#else
|
|
float4 blendMod = SAMPLE_TEXTURE2D(_BlendMask, sampler_BlendMask,
|
|
i_tex.xy * _BlendMask_ST.xy + _BlendMask_ST.zw).r;
|
|
#endif
|
|
|
|
weights = saturate( pow(((blendMod*weights)*4) + (weights*2), _MaskStr) );
|
|
|
|
float baseLayerWeight = 1.0 - saturate(dot(weights, 1.0));
|
|
|
|
#if defined(_DEBUG_VIEWWEIGHTS)
|
|
MaterialInputs debugView = (MaterialInputs)0;
|
|
initMaterial(debugView);
|
|
debugView.baseColor = 0.0;
|
|
debugView.emissive = float4(weights, 1.0);
|
|
debugView.emissive.a = 1.0;
|
|
return debugView;
|
|
#endif
|
|
|
|
float4 c = 0;
|
|
float3 n = float3(0.0, 0.0, 1.0);
|
|
float4 m = 0;
|
|
|
|
#if defined(_TRIPLANAR)
|
|
addLayerTriplanar(baseLayerWeight, worldPosT, worldNormalT, _MainTexA_ST,
|
|
TEXTURE2D_ARGS(_MainTexA, sampler_MainTexR), c, _ColorA,
|
|
TEXTURE2D_ARGS(_BumpMapA, sampler_BumpMapR), n, _BumpScaleA,
|
|
TEXTURE2D_ARGS(_MaskMapA, sampler_MaskMapR), m,
|
|
_PropertiesA);
|
|
addLayerTriplanar(weights.r, worldPosT, worldNormalT, _MainTexR_ST,
|
|
TEXTURE2D_ARGS(_MainTexR, sampler_MainTexR), c, _ColorR,
|
|
TEXTURE2D_ARGS(_BumpMapR, sampler_BumpMapR), n, _BumpScaleR,
|
|
TEXTURE2D_ARGS(_MaskMapR, sampler_MaskMapR), m,
|
|
_PropertiesR);
|
|
addLayerTriplanar(weights.g, worldPosT, worldNormalT, _MainTexG_ST,
|
|
TEXTURE2D_ARGS(_MainTexG, sampler_MainTexR), c, _ColorG,
|
|
TEXTURE2D_ARGS(_BumpMapG, sampler_BumpMapR), n, _BumpScaleG,
|
|
TEXTURE2D_ARGS(_MaskMapG, sampler_MaskMapR), m,
|
|
_PropertiesG);
|
|
addLayerTriplanar(weights.b, worldPosT, worldNormalT, _MainTexB_ST,
|
|
TEXTURE2D_ARGS(_MainTexB, sampler_MainTexR), c, _ColorB,
|
|
TEXTURE2D_ARGS(_BumpMapB, sampler_BumpMapR), n, _BumpScaleB,
|
|
TEXTURE2D_ARGS(_MaskMapB, sampler_MaskMapR), m,
|
|
_PropertiesB);
|
|
#else
|
|
addLayer(baseLayerWeight, i_tex.xy, _MainTexA_ST,
|
|
TEXTURE2D_ARGS(_MainTexA, sampler_MainTexR), c, _ColorA,
|
|
TEXTURE2D_ARGS(_BumpMapA, sampler_BumpMapR), n, _BumpScaleA,
|
|
TEXTURE2D_ARGS(_MaskMapA, sampler_MaskMapR), m,
|
|
_PropertiesA);
|
|
addLayer(weights.r, i_tex.xy, _MainTexR_ST,
|
|
TEXTURE2D_ARGS(_MainTexR, sampler_MainTexR), c, _ColorR,
|
|
TEXTURE2D_ARGS(_BumpMapR, sampler_BumpMapR), n, _BumpScaleR,
|
|
TEXTURE2D_ARGS(_MaskMapR, sampler_MaskMapR), m,
|
|
_PropertiesR);
|
|
addLayer(weights.g, i_tex.xy, _MainTexG_ST,
|
|
TEXTURE2D_ARGS(_MainTexG, sampler_MainTexR), c, _ColorG,
|
|
TEXTURE2D_ARGS(_BumpMapG, sampler_BumpMapR), n, _BumpScaleG,
|
|
TEXTURE2D_ARGS(_MaskMapG, sampler_MaskMapR), m,
|
|
_PropertiesG);
|
|
addLayer(weights.b, i_tex.xy, _MainTexB_ST,
|
|
TEXTURE2D_ARGS(_MainTexB, sampler_MainTexR), c, _ColorB,
|
|
TEXTURE2D_ARGS(_BumpMapB, sampler_BumpMapR), n, _BumpScaleB,
|
|
TEXTURE2D_ARGS(_MaskMapB, sampler_MaskMapR), m,
|
|
_PropertiesB);
|
|
#endif
|
|
|
|
half metallic = m.x;
|
|
half occlusion = m.y;
|
|
half emissionMask = m.z;
|
|
half smoothness = m.w;
|
|
|
|
MaterialInputs material = (MaterialInputs)0;
|
|
initMaterial(material);
|
|
material.baseColor = c;
|
|
material.metallic = metallic;
|
|
material.roughness = computeRoughnessFromGlossiness(smoothness);
|
|
material.normal = n;
|
|
material.emissive.rgb = c.rgb * emissionMask;
|
|
material.emissive.a = 1.0;
|
|
material.ambientOcclusion = occlusion;
|
|
return material;
|
|
}
|
|
|
|
half4 fragForwardBaseTemplate (VertexOutputForwardBase i)
|
|
{
|
|
UNITY_APPLY_DITHER_CROSSFADE(i.pos.xy);
|
|
|
|
UNITY_SETUP_INSTANCE_ID(i);
|
|
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
|
|
|
|
ShadingParams shading = (ShadingParams)0;
|
|
// Initialize shading with expected parameters
|
|
computeShadingParamsForwardBase(shading, i);
|
|
|
|
UNITY_LIGHT_ATTENUATION(atten, i, shading.position);
|
|
|
|
#if defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON)
|
|
GetBakedAttenuation(atten, i.ambientOrLightmapUV.xy, shading.position);
|
|
#endif
|
|
|
|
// Your material setup goes here.
|
|
MaterialInputs material =
|
|
BlendedMaterialSetup(i.tex, i.tangentToWorldAndPackedData, IN_WORLDPOS(i), i.color);
|
|
|
|
prepareMaterial(shading, material);
|
|
|
|
#if (defined(_NORMALMAP) && defined(NORMALMAP_SHADOW))
|
|
float noise = noiseR2(i.pos.xy);
|
|
float nmShade = NormalTangentShadow (i.tex, i.lightDirTS, noise);
|
|
shading.attenuation = min(shading.attenuation, max(1-nmShade, 0));
|
|
#endif
|
|
|
|
float4 c = evaluateMaterial (shading, material);
|
|
|
|
UNITY_EXTRACT_FOG_FROM_EYE_VEC(i);
|
|
UNITY_APPLY_FOG(_unity_fogCoord, c.rgb);
|
|
return c;
|
|
}
|
|
|
|
half4 fragForwardAddTemplate (VertexOutputForwardAdd i)
|
|
{
|
|
UNITY_APPLY_DITHER_CROSSFADE(i.pos.xy);
|
|
|
|
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
|
|
|
|
ShadingParams shading = (ShadingParams)0;
|
|
// Initialize shading with expected parameters
|
|
computeShadingParamsForwardAdd(shading, i);
|
|
|
|
UNITY_LIGHT_ATTENUATION(atten, i, shading.position);
|
|
|
|
// Your material setup goes here.
|
|
MaterialInputs material =
|
|
BlendedMaterialSetup(i.tex,i.tangentToWorldAndLightDir, IN_WORLDPOS_FWDADD(i), i.color);
|
|
|
|
prepareMaterial(shading, material);
|
|
|
|
#if (defined(_NORMALMAP) && defined(NORMALMAP_SHADOW))
|
|
float noise = noiseR2(i.pos.xy);
|
|
float nmShade = NormalTangentShadow (i.tex, i.lightDirTS, noise);
|
|
shading.attenuation = min(shading.attenuation, max(1-nmShade, 0));
|
|
#endif
|
|
|
|
float4 c = evaluateMaterial (shading, material);
|
|
|
|
UNITY_EXTRACT_FOG_FROM_EYE_VEC(i);
|
|
UNITY_APPLY_FOG_COLOR(_unity_fogCoord, c.rgb, half4(0,0,0,0)); // fog towards black in additive pass
|
|
return c;
|
|
}
|
|
|
|
half4 fragBase (VertexOutputForwardBase i) : SV_Target { return fragForwardBaseTemplate(i); }
|
|
half4 fragAdd (VertexOutputForwardAdd i) : SV_Target { return fragForwardAddTemplate(i); }
|
|
#endif
|
|
|
|
ENDCG
|
|
|
|
SubShader
|
|
{
|
|
Tags { "RenderType"="Opaque" "PerformanceChecks"="False" "LTCGI" = "_LTCGI" }
|
|
LOD 300
|
|
|
|
// ------------------------------------------------------------------
|
|
// Base forward pass (directional light, emission, lightmaps, ...)
|
|
Pass
|
|
{
|
|
Name "FORWARD"
|
|
Tags { "LightMode" = "ForwardBase" }
|
|
|
|
Cull [_CullMode]
|
|
AlphaToMask [_AtoCmode]
|
|
Blend [_SrcBlend] [_DstBlend]
|
|
ZWrite [_ZWrite]
|
|
|
|
CGPROGRAM
|
|
#pragma target 5.0
|
|
|
|
// -------------------------------------
|
|
|
|
#pragma shader_feature_local _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
|
|
#pragma shader_feature_local _SPECULARHIGHLIGHTS_OFF
|
|
#pragma shader_feature_local _GLOSSYREFLECTIONS_OFF
|
|
#pragma shader_feature_local _LIGHTMAPSPECULAR
|
|
|
|
#pragma shader_feature_local _ _BAKERY_RNM _BAKERY_SH _BAKERY_MONOSH
|
|
#pragma shader_feature_local _LTCGI
|
|
#pragma shader_feature_local _VRCLV
|
|
#pragma shader_feature_local _SPLATMAP
|
|
#pragma shader_feature_local _TRIPLANAR
|
|
#pragma shader_feature_local _STOCHASTIC
|
|
|
|
#pragma shader_feature_local _DEBUG_VIEWWEIGHTS
|
|
|
|
#pragma multi_compile_fwdbase
|
|
#pragma multi_compile_fog
|
|
#pragma multi_compile_instancing
|
|
// Uncomment the following line to enable dithering LOD crossfade. Note: there are more in the file to uncomment for other passes.
|
|
//#pragma multi_compile _ LOD_FADE_CROSSFADE
|
|
|
|
#pragma vertex vertBase
|
|
#pragma fragment fragBase
|
|
|
|
ENDCG
|
|
}
|
|
// ------------------------------------------------------------------
|
|
// Additive forward pass (one light per pass)
|
|
Pass
|
|
{
|
|
Name "FORWARD_DELTA"
|
|
Tags { "LightMode" = "ForwardAdd" }
|
|
Blend One One
|
|
Fog { Color (0,0,0,0) } // in additive pass fog should be black
|
|
ZWrite Off
|
|
ZTest Equal
|
|
Cull [_CullMode]
|
|
AlphaToMask [_AtoCmode]
|
|
//Blend One [_DstBlend]
|
|
//ZWrite [_ZWrite]
|
|
|
|
CGPROGRAM
|
|
#pragma target 5.0
|
|
|
|
// -------------------------------------
|
|
|
|
|
|
#pragma shader_feature_local _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
|
|
#pragma shader_feature_local _SPECULARHIGHLIGHTS_OFF
|
|
#pragma shader_feature_local _SPLATMAP
|
|
#pragma shader_feature_local _TRIPLANAR
|
|
#pragma shader_feature_local _STOCHASTIC
|
|
|
|
#pragma multi_compile_fwdadd_fullshadows
|
|
#pragma multi_compile_fog
|
|
// Uncomment the following line to enable dithering LOD crossfade. Note: there are more in the file to uncomment for other passes.
|
|
//#pragma multi_compile _ LOD_FADE_CROSSFADE
|
|
|
|
#pragma vertex vertAdd
|
|
#pragma fragment fragAdd
|
|
|
|
ENDCG
|
|
}
|
|
|
|
// ------------------------------------------------------------------
|
|
// Shadow rendering pass
|
|
Pass {
|
|
Name "ShadowCaster"
|
|
Tags { "LightMode" = "ShadowCaster" }
|
|
|
|
ZWrite On ZTest LEqual
|
|
Cull [_CullMode]
|
|
AlphaToMask Off
|
|
|
|
CGPROGRAM
|
|
#pragma target 5.0
|
|
|
|
// -------------------------------------
|
|
|
|
#ifndef UNITY_PASS_SHADOWCASTER
|
|
#define UNITY_PASS_SHADOWCASTER
|
|
#endif
|
|
|
|
#pragma shader_feature_local _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
|
|
#pragma multi_compile_shadowcaster
|
|
#pragma multi_compile_instancing
|
|
// Uncomment the following line to enable dithering LOD crossfade. Note: there are more in the file to uncomment for other passes.
|
|
//#pragma multi_compile _ LOD_FADE_CROSSFADE
|
|
|
|
#pragma vertex vertShadowCaster
|
|
#pragma fragment fragShadowCaster
|
|
|
|
#include "Packages/s-ilent.filamented/Filamented/UnityStandardShadow.cginc"
|
|
|
|
ENDCG
|
|
}
|
|
|
|
Pass
|
|
{
|
|
Name "META"
|
|
Tags {"LightMode"="Meta"}
|
|
Cull Off
|
|
AlphaToMask Off
|
|
CGPROGRAM
|
|
|
|
#define REQUIRE_META_WORLDPOS
|
|
|
|
#include "Packages/s-ilent.filamented/Filamented/UnityStandardMeta.cginc"
|
|
|
|
#define META_PASS
|
|
|
|
float4 frag_meta2 (v2f_meta i): SV_Target
|
|
{
|
|
MaterialInputs material = SETUP_BRDF_INPUT (i.uv);
|
|
float4 dummy[3]; dummy[0] = 1; dummy[1] = 0; dummy[2] = 0;
|
|
material = BlendedMaterialSetup(i.uv, dummy, i.worldPos, i.color);
|
|
|
|
PixelParams pixel = (PixelParams)0;
|
|
getCommonPixelParams(material, pixel);
|
|
|
|
UnityMetaInput o;
|
|
UNITY_INITIALIZE_OUTPUT(UnityMetaInput, o);
|
|
|
|
#ifdef EDITOR_VISUALIZATION
|
|
o.Albedo = pixel.diffuseColor;
|
|
o.VizUV = i.vizUV;
|
|
o.LightCoord = i.lightCoord;
|
|
#else
|
|
o.Albedo = UnityLightmappingAlbedo (pixel.diffuseColor, pixel.f0, 1-pixel.perceptualRoughness);
|
|
#endif
|
|
o.SpecularColor = pixel.f0;
|
|
o.Emission = material.emissive;
|
|
|
|
return UnityMetaFragment(o);
|
|
}
|
|
|
|
#pragma vertex vert_meta
|
|
#pragma fragment frag_meta2
|
|
#pragma shader_feature _EMISSION
|
|
#pragma shader_feature _METALLICGLOSSMAP
|
|
#pragma shader_feature ___ _DETAIL_MULX2
|
|
ENDCG
|
|
}
|
|
|
|
}
|
|
|
|
FallBack "VertexLit"
|
|
}
|