4098 lines
180 KiB
GLSL
4098 lines
180 KiB
GLSL
// Made with Amplify Shader Editor v1.9.2.1
|
|
// Available at the Unity Asset Store - http://u3d.as/y3X
|
|
Shader "Impostors/Custom/Colored Barrels"
|
|
{
|
|
Properties
|
|
{
|
|
[HideInInspector] _EmissionColor("Emission Color", Color) = (1,1,1,1)
|
|
[HideInInspector] _AlphaCutoff("Alpha Cutoff ", Range(0, 1)) = 0.5
|
|
_Albedo("Impostor Albedo & Alpha", 2D) = "white" {}
|
|
_Normals("Impostor Normal & Depth", 2D) = "white" {}
|
|
[NoScaleOffset]_Mask("Mask", 2D) = "white" {}
|
|
_AI_Clip("Impostor Clip", Range( 0 , 1)) = 0.5
|
|
[HideInInspector]_AI_DepthSize("Impostor Depth Size", Float) = 0
|
|
_AI_ShadowBias("Impostor Shadow Bias", Range( 0 , 2)) = 0.25
|
|
_AI_ShadowView("Impostor Shadow View", Range( 0 , 1)) = 1
|
|
[HideInInspector]_AI_FramesY("Impostor Frames Y", Float) = 0
|
|
[HideInInspector]_AI_FramesX("Impostor Frames X", Float) = 0
|
|
[HideInInspector]_AI_Frames("Impostor Frames", Float) = 0
|
|
[HideInInspector]_AI_ImpostorSize("Impostor Size", Float) = 0
|
|
_AI_TextureBias("Impostor Texture Bias", Float) = -1
|
|
[HideInInspector]_AI_Offset("Impostor Offset", Vector) = (0,0,0,0)
|
|
[HideInInspector]_AI_SizeOffset("Impostor Size Offset", Vector) = (0,0,0,0)
|
|
_AI_Parallax("Impostor Parallax", Range( 0 , 1)) = 1
|
|
|
|
}
|
|
|
|
SubShader
|
|
{
|
|
LOD 0
|
|
|
|
|
|
Tags { "RenderPipeline"="HDRenderPipeline" "RenderType"="Opaque" "Queue"="Geometry" "ImpostorType"="Octahedron" }
|
|
|
|
Cull Back
|
|
Blend One Zero
|
|
ZTest LEqual
|
|
ZWrite On
|
|
ZClip [_ZClip]
|
|
|
|
HLSLINCLUDE
|
|
#pragma target 4.5
|
|
#pragma exclude_renderers glcore gles gles3 ps5
|
|
#pragma multi_compile_instancing
|
|
#pragma instancing_options renderinglayer
|
|
#pragma multi_compile _ DOTS_INSTANCING_ON
|
|
#pragma multi_compile _ LOD_FADE_CROSSFADE
|
|
#define AI_RENDERPIPELINE
|
|
|
|
struct GlobalSurfaceDescription
|
|
{
|
|
float3 Albedo;
|
|
float3 Normal;
|
|
float3 BentNormal;
|
|
float3 Specular;
|
|
float CoatMask;
|
|
float Metallic;
|
|
float3 Emission;
|
|
float Smoothness;
|
|
float Occlusion;
|
|
float Alpha;
|
|
float AlphaClipThreshold;
|
|
float SpecularAAScreenSpaceVariance;
|
|
float SpecularAAThreshold;
|
|
float SpecularOcclusion;
|
|
//Refraction
|
|
float RefractionIndex;
|
|
float3 RefractionColor;
|
|
float RefractionDistance;
|
|
//SSS/Translucent
|
|
float Thickness;
|
|
float SubsurfaceMask;
|
|
float DiffusionProfile;
|
|
//Anisotropy
|
|
float Anisotropy;
|
|
float3 Tangent;
|
|
//Iridescent
|
|
float IridescenceMask;
|
|
float IridescenceThickness;
|
|
};
|
|
|
|
struct SurfaceOutput
|
|
{
|
|
half3 Albedo;
|
|
half3 Specular;
|
|
half Metallic;
|
|
float3 Normal;
|
|
half3 Emission;
|
|
half Smoothness;
|
|
half Occlusion;
|
|
half Alpha;
|
|
};
|
|
|
|
struct AlphaSurfaceDescription
|
|
{
|
|
float Alpha;
|
|
float AlphaClipThreshold;
|
|
};
|
|
|
|
struct SmoothSurfaceDescription
|
|
{
|
|
float Smoothness;
|
|
float Alpha;
|
|
float AlphaClipThreshold;
|
|
};
|
|
|
|
struct DistortionSurfaceDescription
|
|
{
|
|
float Alpha;
|
|
float2 Distortion;
|
|
float DistortionBlur;
|
|
float AlphaClipThreshold;
|
|
};
|
|
ENDHLSL
|
|
|
|
|
|
Pass
|
|
{
|
|
|
|
Name "GBuffer"
|
|
Tags { "LightMode"="GBuffer" }
|
|
|
|
Stencil
|
|
{
|
|
Ref 10
|
|
WriteMask 14
|
|
Comp Always
|
|
Pass Replace
|
|
}
|
|
|
|
|
|
ColorMask [_LightLayersMaskBuffer4] 4
|
|
ColorMask [_LightLayersMaskBuffer5] 5
|
|
|
|
HLSLPROGRAM
|
|
|
|
#define _DECALS 1
|
|
#define _MATERIAL_FEATURE_SPECULAR_COLOR 1
|
|
#define _ENERGY_CONSERVING_SPECULAR 1
|
|
#define _AMBIENT_OCCLUSION 1
|
|
#define ASE_SRP_VERSION 120112
|
|
#ifdef UNITY_COLORSPACE_GAMMA//AI_SRP
|
|
#define unity_ColorSpaceDielectricSpec half4(0.220916301, 0.220916301, 0.220916301, 1.0 - 0.220916301)//AI_SRP
|
|
#else//AI_SRP
|
|
#define unity_ColorSpaceDielectricSpec half4(0.04, 0.04, 0.04, 1.0 - 0.04) //AI_SRP
|
|
#endif//AI_SRP
|
|
|
|
|
|
#pragma vertex Vert
|
|
#pragma fragment Frag
|
|
|
|
#if defined(_MATERIAL_FEATURE_SUBSURFACE_SCATTERING) && !defined(_SURFACE_TYPE_TRANSPARENT)
|
|
#define OUTPUT_SPLIT_LIGHTING
|
|
#endif
|
|
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
|
|
//#if defined( ASE_SRP_VERSION ) && ASE_SRP_VERSION < 60900
|
|
//#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Wind.hlsl"
|
|
//#endif
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/NormalSurfaceGradient.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/FragInputs.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl"
|
|
|
|
#define SHADERPASS SHADERPASS_GBUFFER
|
|
//#pragma multi_compile _ LIGHTMAP_ON
|
|
//#pragma multi_compile _ DIRLIGHTMAP_COMBINED
|
|
//#pragma multi_compile _ DYNAMICLIGHTMAP_ON
|
|
//#pragma multi_compile _ SHADOWS_SHADOWMASK
|
|
//#pragma multi_compile DECALS_OFF DECALS_3RT DECALS_4RT
|
|
#pragma multi_compile _ LIGHT_LAYERS
|
|
|
|
#define VARYINGS_NEED_POSITION_WS
|
|
#define VARYINGS_NEED_TANGENT_TO_WORLD
|
|
#define VARYINGS_NEED_TEXCOORD1
|
|
#define VARYINGS_NEED_TEXCOORD2
|
|
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinUtilities.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialUtilities.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalUtilities.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDecalData.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphFunctions.hlsl"
|
|
|
|
//#if defined( ASE_SRP_VERSION ) && ASE_SRP_VERSION < 60900
|
|
//#define T2W(var, index) var.worldToTangent[index]
|
|
//#else
|
|
#define T2W(var, index) var.tangentToWorld[index]
|
|
//#endif
|
|
|
|
#define ai_ObjectToWorld GetObjectToWorldMatrix()
|
|
#define ai_WorldToObject GetWorldToObjectMatrix()
|
|
#define AI_INV_TWO_PI INV_TWO_PI
|
|
#define AI_PI PI
|
|
#define AI_INV_PI INV_PI
|
|
|
|
|
|
struct AttributesMesh
|
|
{
|
|
float4 vertex : POSITION;
|
|
float3 normal : NORMAL;
|
|
float4 tangent : TANGENT;
|
|
float4 texcoord : TEXCOORD0;
|
|
float4 uv1 : TEXCOORD1;
|
|
float4 uv2 : TEXCOORD2;
|
|
|
|
UNITY_VERTEX_INPUT_INSTANCE_ID
|
|
|
|
};
|
|
|
|
struct PackedVaryingsMeshToPS
|
|
{
|
|
float4 positionCS : SV_Position;
|
|
float3 interp00 : TEXCOORD0;
|
|
float3 interp01 : TEXCOORD1;
|
|
float4 interp02 : TEXCOORD2;
|
|
float4 interp03 : TEXCOORD3;
|
|
float4 interp04 : TEXCOORD4;
|
|
float4 UVsFrame117 : TEXCOORD5;
|
|
float4 UVsFrame217 : TEXCOORD6;
|
|
float4 UVsFrame317 : TEXCOORD7;
|
|
float4 octaframe17 : TEXCOORD8;
|
|
float4 viewPos17 : TEXCOORD9;
|
|
UNITY_VERTEX_INPUT_INSTANCE_ID
|
|
UNITY_VERTEX_OUTPUT_STEREO
|
|
};
|
|
|
|
sampler2D _Albedo;
|
|
sampler2D _Normals;
|
|
sampler2D _Mask;
|
|
SAMPLER(sampler_Mask);
|
|
float4x4 unity_CameraProjection;
|
|
float4x4 unity_CameraInvProjection;
|
|
float4x4 unity_WorldToCamera;
|
|
float4x4 unity_CameraToWorld;
|
|
CBUFFER_START( UnityPerMaterial )
|
|
float4 _AI_SizeOffset;
|
|
float3 _AI_Offset;
|
|
float _AI_Frames;
|
|
float _AI_FramesX;
|
|
float _AI_FramesY;
|
|
float _AI_ImpostorSize;
|
|
float _AI_Parallax;
|
|
float _AI_TextureBias;
|
|
float _AI_DepthSize;
|
|
float _AI_ShadowBias;
|
|
float _AI_ShadowView;
|
|
float _AI_Clip;
|
|
CBUFFER_END
|
|
|
|
|
|
float2 VectortoOctahedron( float3 N )
|
|
{
|
|
N /= dot( 1.0, abs( N ) );
|
|
if( N.z <= 0 )
|
|
{
|
|
N.xy = ( 1 - abs( N.yx ) ) * ( N.xy >= 0 ? 1.0 : -1.0 );
|
|
}
|
|
return N.xy;
|
|
}
|
|
|
|
float3 OctahedronToVector( float2 Oct )
|
|
{
|
|
float3 N = float3( Oct, 1.0 - dot( 1.0, abs( Oct ) ) );
|
|
if(N.z< 0 )
|
|
{
|
|
N.xy = ( 1 - abs( N.yx) ) * (N.xy >= 0 ? 1.0 : -1.0 );
|
|
}
|
|
return normalize( N);
|
|
}
|
|
|
|
inline void RayPlaneIntersectionUV( float3 normal, float3 rayPosition, float3 rayDirection, inout float2 uvs, inout float3 localNormal )
|
|
{
|
|
float lDotN = dot( rayDirection, normal );
|
|
float p0l0DotN = dot( -rayPosition, normal );
|
|
float t = p0l0DotN / lDotN;
|
|
float3 p = rayDirection * t + rayPosition;
|
|
float3 upVector = float3( 0, 1, 0 );
|
|
float3 tangent = normalize( cross( upVector, normal ) + float3( -0.001, 0, 0 ) );
|
|
float3 bitangent = cross( tangent, normal );
|
|
float frameX = dot( p, tangent );
|
|
float frameZ = dot( p, bitangent );
|
|
uvs = -float2( frameX, frameZ );
|
|
if( t <= 0.0 )
|
|
uvs = 0;
|
|
float3x3 worldToLocal = float3x3( tangent, bitangent, normal );
|
|
localNormal = normalize( mul( worldToLocal, rayDirection ) );
|
|
}
|
|
|
|
inline void OctaImpostorVertex( inout float4 vertex, inout float3 normal, inout float4 uvsFrame1, inout float4 uvsFrame2, inout float4 uvsFrame3, inout float4 octaFrame, inout float4 viewPos )
|
|
{
|
|
float2 uvOffset = _AI_SizeOffset.zw;
|
|
float parallax = -_AI_Parallax;
|
|
float UVscale = _AI_ImpostorSize;
|
|
float framesXY = _AI_Frames;
|
|
float prevFrame = framesXY - 1;
|
|
float3 fractions = 1.0 / float3( framesXY, prevFrame, UVscale );
|
|
float fractionsFrame = fractions.x;
|
|
float fractionsPrevFrame = fractions.y;
|
|
float fractionsUVscale = fractions.z;
|
|
float3 worldOrigin = 0;
|
|
float4 perspective = float4( 0, 0, 0, 1 );
|
|
if( UNITY_MATRIX_P[ 3 ][ 3 ] == 1 )
|
|
{
|
|
perspective = float4( 0, 0, 5000, 0 );
|
|
worldOrigin = ai_ObjectToWorld._m03_m13_m23;
|
|
}
|
|
float3 worldCameraPos = worldOrigin + mul( UNITY_MATRIX_I_V, perspective ).xyz;
|
|
float3 objectCameraPosition = mul( ai_WorldToObject, float4( worldCameraPos, 1 ) ).xyz - _AI_Offset.xyz;
|
|
float3 objectCameraDirection = normalize( objectCameraPosition );
|
|
float3 upVector = float3( 0,1,0 );
|
|
float3 objectHorizontalVector = normalize( cross( objectCameraDirection, upVector ) );
|
|
float3 objectVerticalVector = cross( objectHorizontalVector, objectCameraDirection );
|
|
float2 uvExpansion = vertex.xy;
|
|
float3 billboard = objectHorizontalVector * uvExpansion.x + objectVerticalVector * uvExpansion.y;
|
|
float3 localDir = billboard - objectCameraPosition;
|
|
float2 frameOcta = VectortoOctahedron( objectCameraDirection.xzy ) * 0.5 + 0.5;
|
|
float2 prevOctaFrame = frameOcta * prevFrame;
|
|
float2 baseOctaFrame = floor( prevOctaFrame );
|
|
float2 fractionOctaFrame = ( baseOctaFrame * fractionsFrame );
|
|
float2 octaFrame1 = ( baseOctaFrame * fractionsPrevFrame ) * 2.0 - 1.0;
|
|
float3 octa1WorldY = OctahedronToVector( octaFrame1 ).xzy;
|
|
float3 octa1LocalY;
|
|
float2 uvFrame1;
|
|
RayPlaneIntersectionUV( octa1WorldY, objectCameraPosition, localDir, /*inout*/ uvFrame1, /*inout*/ octa1LocalY );
|
|
float2 uvParallax1 = octa1LocalY.xy * fractionsFrame * parallax;
|
|
uvFrame1 = ( uvFrame1 * fractionsUVscale + 0.5 ) * fractionsFrame + fractionOctaFrame;
|
|
uvsFrame1 = float4( uvParallax1, uvFrame1) - float4( 0, 0, uvOffset );
|
|
float2 fractPrevOctaFrame = frac( prevOctaFrame );
|
|
float2 cornerDifference = lerp( float2( 0,1 ) , float2( 1,0 ) , saturate( ceil( ( fractPrevOctaFrame.x - fractPrevOctaFrame.y ) ) ));
|
|
float2 octaFrame2 = ( ( baseOctaFrame + cornerDifference ) * fractionsPrevFrame ) * 2.0 - 1.0;
|
|
float3 octa2WorldY = OctahedronToVector( octaFrame2 ).xzy;
|
|
float3 octa2LocalY;
|
|
float2 uvFrame2;
|
|
RayPlaneIntersectionUV( octa2WorldY, objectCameraPosition, localDir, /*inout*/ uvFrame2, /*inout*/ octa2LocalY );
|
|
float2 uvParallax2 = octa2LocalY.xy * fractionsFrame * parallax;
|
|
uvFrame2 = ( uvFrame2 * fractionsUVscale + 0.5 ) * fractionsFrame + ( ( cornerDifference * fractionsFrame ) + fractionOctaFrame );
|
|
uvsFrame2 = float4( uvParallax2, uvFrame2) - float4( 0, 0, uvOffset );
|
|
float2 octaFrame3 = ( ( baseOctaFrame + 1 ) * fractionsPrevFrame ) * 2.0 - 1.0;
|
|
float3 octa3WorldY = OctahedronToVector( octaFrame3 ).xzy;
|
|
float3 octa3LocalY;
|
|
float2 uvFrame3;
|
|
RayPlaneIntersectionUV( octa3WorldY, objectCameraPosition, localDir, /*inout*/ uvFrame3, /*inout*/ octa3LocalY );
|
|
float2 uvParallax3 = octa3LocalY.xy * fractionsFrame * parallax;
|
|
uvFrame3 = ( uvFrame3 * fractionsUVscale + 0.5 ) * fractionsFrame + ( fractionOctaFrame + fractionsFrame );
|
|
uvsFrame3 = float4( uvParallax3, uvFrame3) - float4( 0, 0, uvOffset );
|
|
octaFrame = 0;
|
|
octaFrame.xy = prevOctaFrame;
|
|
vertex.xyz = billboard + _AI_Offset.xyz;
|
|
normal.xyz = objectCameraDirection;
|
|
viewPos = 0;
|
|
viewPos.xyz = TransformWorldToView( TransformObjectToWorld( vertex.xyz ) );
|
|
}
|
|
|
|
inline void OctaImpostorFragment( inout SurfaceOutput o, out float4 clipPos, out float3 worldPos, float4 uvsFrame1, float4 uvsFrame2, float4 uvsFrame3, float4 octaFrame, float4 interpViewPos, out float4 output0 )
|
|
{
|
|
float depthBias = -1.0;
|
|
float textureBias = _AI_TextureBias;
|
|
float2 fraction = frac( octaFrame.xy );
|
|
float2 invFraction = 1 - fraction;
|
|
float3 weights;
|
|
weights.x = min( invFraction.x, invFraction.y );
|
|
weights.y = abs( fraction.x - fraction.y );
|
|
weights.z = min( fraction.x, fraction.y );
|
|
float4 parallaxSample1 = tex2Dbias( _Normals, float4(uvsFrame1.zw, 0, depthBias) );
|
|
float2 parallax1 = ( ( 0.5 - parallaxSample1.a ) * uvsFrame1.xy ) + uvsFrame1.zw;
|
|
float4 parallaxSample2 = tex2Dbias( _Normals, float4(uvsFrame2.zw, 0, depthBias) );
|
|
float2 parallax2 = ( ( 0.5 - parallaxSample2.a ) * uvsFrame2.xy ) + uvsFrame2.zw;
|
|
float4 parallaxSample3 = tex2Dbias( _Normals, float4(uvsFrame3.zw, 0, depthBias) );
|
|
float2 parallax3 = ( ( 0.5 - parallaxSample3.a ) * uvsFrame3.xy ) + uvsFrame3.zw;
|
|
float4 albedo1 = tex2Dbias( _Albedo, float4(parallax1, 0, textureBias) );
|
|
float4 albedo2 = tex2Dbias( _Albedo, float4(parallax2, 0, textureBias) );
|
|
float4 albedo3 = tex2Dbias( _Albedo, float4(parallax3, 0, textureBias) );
|
|
float4 blendedAlbedo = albedo1 * weights.x + albedo2 * weights.y + albedo3 * weights.z;
|
|
o.Alpha = ( blendedAlbedo.a - _AI_Clip );
|
|
clip( o.Alpha );
|
|
o.Albedo = blendedAlbedo.rgb;
|
|
#if defined(AI_HD_RENDERPIPELINE)
|
|
float4 feat1 = _Features.SampleLevel( SamplerState_Point_Repeat, parallax1, 0);
|
|
o.Diffusion = feat1.rgb;
|
|
o.Features = feat1.a;
|
|
float4 test1 = _Specular.SampleLevel( SamplerState_Point_Repeat, parallax1, 0);
|
|
o.MetalTangent = test1.b;
|
|
#endif
|
|
float4 normals1 = tex2Dbias( _Normals, float4(parallax1, 0, textureBias) );
|
|
float4 normals2 = tex2Dbias( _Normals, float4(parallax2, 0, textureBias) );
|
|
float4 normals3 = tex2Dbias( _Normals, float4(parallax3, 0, textureBias) );
|
|
float4 blendedNormal = normals1 * weights.x + normals2 * weights.y + normals3 * weights.z;
|
|
float4 output0a = tex2Dbias( _Mask, float4(parallax1, 0, textureBias) );
|
|
float4 output0b = tex2Dbias( _Mask, float4(parallax2, 0, textureBias) );
|
|
float4 output0c = tex2Dbias( _Mask, float4(parallax3, 0, textureBias) );
|
|
output0 = output0a * weights.x + output0b * weights.y + output0c * weights.z;
|
|
float3 localNormal = blendedNormal.rgb * 2.0 - 1.0;
|
|
float3 worldNormal = normalize( mul( (float3x3)ai_ObjectToWorld, localNormal ) );
|
|
o.Normal = worldNormal;
|
|
float3 viewPos = interpViewPos.xyz;
|
|
#if ( defined(SHADERPASS) && (defined(SHADERPASS_DEPTHNORMALSONLY) && SHADERPASS == SHADERPASS_DEPTHNORMALSONLY) ) || defined(UNITY_PASS_SHADOWCASTER)
|
|
float depthOffset = ( ( parallaxSample1.a * weights.x + parallaxSample2.a * weights.y + parallaxSample3.a * weights.z ) - 0.5001 /** 2.0 - 1.0*/ ) /** 0.5*/ * _AI_DepthSize * length( ai_ObjectToWorld[ 2 ].xyz );
|
|
#else
|
|
float depthOffset = ( ( parallaxSample1.a * weights.x + parallaxSample2.a * weights.y + parallaxSample3.a * weights.z ) - 0.5 /** 2.0 - 1.0*/ ) /** 0.5*/ * _AI_DepthSize * length( ai_ObjectToWorld[ 2 ].xyz );
|
|
#endif
|
|
#if ( defined(SHADERPASS) && ((defined(SHADERPASS_SHADOWS) && SHADERPASS == SHADERPASS_SHADOWS) || (defined(SHADERPASS_SHADOWCASTER) && SHADERPASS == SHADERPASS_SHADOWCASTER)) ) || defined(UNITY_PASS_SHADOWCASTER)
|
|
viewPos.z += depthOffset * _AI_ShadowView;
|
|
viewPos.z += -_AI_ShadowBias;
|
|
#else
|
|
viewPos.z += depthOffset;
|
|
#endif
|
|
worldPos = mul( UNITY_MATRIX_I_V, float4( viewPos.xyz, 1 ) ).xyz;
|
|
clipPos = mul( UNITY_MATRIX_P, float4( viewPos, 1 ) );
|
|
#if defined(UNITY_PASS_SHADOWCASTER) && !defined(SHADERPASS)
|
|
#if UNITY_REVERSED_Z
|
|
clipPos.z = min( clipPos.z, clipPos.w * UNITY_NEAR_CLIP_VALUE );
|
|
#else
|
|
clipPos.z = max( clipPos.z, clipPos.w * UNITY_NEAR_CLIP_VALUE );
|
|
#endif
|
|
#endif
|
|
clipPos.xyz /= clipPos.w;
|
|
if( UNITY_NEAR_CLIP_VALUE < 0 )
|
|
clipPos = clipPos * 0.5 + 0.5;
|
|
}
|
|
|
|
float3 HSVToRGB( float3 c )
|
|
{
|
|
float4 K = float4( 1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0 );
|
|
float3 p = abs( frac( c.xxx + K.xyz ) * 6.0 - K.www );
|
|
return c.z * lerp( K.xxx, saturate( p - K.xxx ), c.y );
|
|
}
|
|
|
|
|
|
void BuildSurfaceData(FragInputs fragInputs, inout GlobalSurfaceDescription surfaceDescription, float3 V, out SurfaceData surfaceData, out float3 bentNormalWS)
|
|
{
|
|
ZERO_INITIALIZE(SurfaceData, surfaceData);
|
|
|
|
surfaceData.baseColor = surfaceDescription.Albedo;
|
|
surfaceData.perceptualSmoothness = surfaceDescription.Smoothness;
|
|
#ifdef _SPECULAR_OCCLUSION_CUSTOM
|
|
surfaceData.specularOcclusion = surfaceDescription.SpecularOcclusion;
|
|
#endif
|
|
surfaceData.ambientOcclusion = surfaceDescription.Occlusion;
|
|
surfaceData.metallic = surfaceDescription.Metallic;
|
|
surfaceData.coatMask = surfaceDescription.CoatMask;
|
|
|
|
#if defined( _MATERIAL_FEATURE_SUBSURFACE_SCATTERING ) || defined( _MATERIAL_FEATURE_TRANSMISSION )
|
|
surfaceData.diffusionProfileHash = asuint(surfaceDescription.DiffusionProfile);
|
|
#endif
|
|
|
|
#ifdef _MATERIAL_FEATURE_IRIDESCENCE
|
|
surfaceData.iridescenceMask = surfaceDescription.IridescenceMask;
|
|
surfaceData.iridescenceThickness = surfaceDescription.IridescenceThickness;
|
|
#endif
|
|
|
|
surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD;
|
|
#ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING;
|
|
#endif
|
|
#ifdef _MATERIAL_FEATURE_TRANSMISSION
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION;
|
|
#endif
|
|
#ifdef _MATERIAL_FEATURE_ANISOTROPY
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_ANISOTROPY;
|
|
#endif
|
|
|
|
#ifdef ASE_LIT_CLEAR_COAT
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_CLEAR_COAT;
|
|
#endif
|
|
|
|
#ifdef _MATERIAL_FEATURE_IRIDESCENCE
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_IRIDESCENCE;
|
|
#endif
|
|
#ifdef _MATERIAL_FEATURE_SPECULAR_COLOR
|
|
surfaceData.specularColor = surfaceDescription.Specular;
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR;
|
|
#endif
|
|
|
|
#if defined (_MATERIAL_FEATURE_SPECULAR_COLOR) && defined (_ENERGY_CONSERVING_SPECULAR)
|
|
surfaceData.baseColor *= (1.0 - Max3(surfaceData.specularColor.r, surfaceData.specularColor.g, surfaceData.specularColor.b));
|
|
#endif
|
|
|
|
GetNormalWS( fragInputs, float3( 0.0, 0.0, 1.0 ), surfaceData.normalWS, float3( 1.0, 1.0, 1.0 ) );
|
|
|
|
bentNormalWS = surfaceData.normalWS;
|
|
|
|
#ifdef ASE_BENT_NORMAL
|
|
GetNormalWS(fragInputs, surfaceDescription.BentNormal, bentNormalWS, float3( 1, 1, 1 ) );
|
|
#endif
|
|
|
|
surfaceData.geomNormalWS = T2W(fragInputs, 2);
|
|
|
|
#if defined(_HAS_REFRACTION) || defined(_MATERIAL_FEATURE_TRANSMISSION)
|
|
surfaceData.thickness = surfaceDescription.Thickness;
|
|
#endif
|
|
|
|
#ifdef _HAS_REFRACTION
|
|
if (_EnableSSRefraction)
|
|
{
|
|
surfaceData.ior = surfaceDescription.RefractionIndex;
|
|
surfaceData.transmittanceColor = surfaceDescription.RefractionColor;
|
|
surfaceData.atDistance = surfaceDescription.RefractionDistance;
|
|
|
|
surfaceData.transmittanceMask = (1.0 - surfaceDescription.Alpha);
|
|
surfaceDescription.Alpha = 1.0;
|
|
}
|
|
else
|
|
{
|
|
surfaceData.ior = 1.0;
|
|
surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);
|
|
surfaceData.atDistance = 1.0;
|
|
surfaceData.transmittanceMask = 0.0;
|
|
surfaceDescription.Alpha = 1.0;
|
|
}
|
|
#else
|
|
surfaceData.ior = 1.0;
|
|
surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);
|
|
surfaceData.atDistance = 1.0;
|
|
surfaceData.transmittanceMask = 0.0;
|
|
#endif
|
|
|
|
#if defined(_HAS_REFRACTION) || defined(_MATERIAL_FEATURE_TRANSMISSION)
|
|
surfaceData.thickness = surfaceDescription.Thickness;
|
|
#endif
|
|
|
|
#ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING
|
|
surfaceData.subsurfaceMask = surfaceDescription.SubsurfaceMask;
|
|
#endif
|
|
|
|
#if defined( _MATERIAL_FEATURE_SUBSURFACE_SCATTERING ) || defined( _MATERIAL_FEATURE_TRANSMISSION )
|
|
surfaceData.diffusionProfileHash = asuint(surfaceDescription.DiffusionProfile);
|
|
#endif
|
|
|
|
surfaceData.tangentWS = normalize(T2W(fragInputs, 0).xyz); // The tangent is not normalize in worldToTangent for mikkt. TODO: Check if it expected that we normalize with Morten. Tag: SURFACE_GRADIENT
|
|
#ifdef _MATERIAL_FEATURE_ANISOTROPY
|
|
surfaceData.anisotropy = surfaceDescription.Anisotropy;
|
|
surfaceData.tangentWS = TransformTangentToWorld(surfaceDescription.Tangent, fragInputs.worldToTangent);
|
|
#endif
|
|
surfaceData.tangentWS = Orthonormalize(surfaceData.tangentWS, surfaceData.normalWS);
|
|
|
|
#if defined(_SPECULAR_OCCLUSION_CUSTOM)
|
|
#elif defined(_SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL)
|
|
surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO(V, bentNormalWS, surfaceData.normalWS, surfaceData.ambientOcclusion, PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness));
|
|
#elif defined(_AMBIENT_OCCLUSION) && defined(_SPECULAR_OCCLUSION_FROM_AO)
|
|
surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(dot(surfaceData.normalWS, V)), surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness));
|
|
#else
|
|
surfaceData.specularOcclusion = 1.0;
|
|
#endif
|
|
#ifdef _ENABLE_GEOMETRIC_SPECULAR_AA
|
|
surfaceData.perceptualSmoothness = GeometricNormalFiltering(surfaceData.perceptualSmoothness, T2W(fragInputs, 2), surfaceDescription.SpecularAAScreenSpaceVariance, surfaceDescription.SpecularAAThreshold);
|
|
#endif
|
|
}
|
|
|
|
void GetSurfaceAndBuiltinData(GlobalSurfaceDescription surfaceDescription, FragInputs fragInputs, float3 V, inout PositionInputs posInput, out SurfaceData surfaceData, out BuiltinData builtinData)
|
|
{
|
|
//#ifdef LOD_FADE_CROSSFADE
|
|
// uint3 fadeMaskSeed = asuint((int3)(V * _ScreenSize.xyx));
|
|
// LODDitheringTransition(fadeMaskSeed, unity_LODFade.x);
|
|
//#endif
|
|
|
|
#ifdef _ALPHATEST_ON
|
|
DoAlphaTest(surfaceDescription.Alpha, surfaceDescription.AlphaClipThreshold);
|
|
#endif
|
|
|
|
float3 bentNormalWS;
|
|
BuildSurfaceData(fragInputs, surfaceDescription, V, surfaceData, bentNormalWS);
|
|
|
|
#if HAVE_DECALS
|
|
if( _EnableDecals )
|
|
{
|
|
DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, surfaceDescription.Alpha);
|
|
ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData);
|
|
}
|
|
#endif
|
|
|
|
//#if defined( ASE_SRP_VERSION ) && ASE_SRP_VERSION <= 50702
|
|
//InitBuiltinData( surfaceDescription.Alpha, bentNormalWS, -T2W(fragInputs, 2), fragInputs.positionRWS, fragInputs.texCoord1, fragInputs.texCoord2, builtinData );
|
|
//#else
|
|
InitBuiltinData( posInput, surfaceDescription.Alpha, bentNormalWS, -T2W(fragInputs, 2), fragInputs.texCoord1, fragInputs.texCoord2, builtinData );
|
|
//#endif
|
|
|
|
builtinData.emissiveColor = surfaceDescription.Emission;
|
|
|
|
builtinData.depthOffset = 0.0;
|
|
|
|
#if (SHADERPASS == SHADERPASS_DISTORTION)
|
|
builtinData.distortion = surfaceDescription.Distortion;
|
|
builtinData.distortionBlur = surfaceDescription.DistortionBlur;
|
|
#else
|
|
builtinData.distortion = float2(0.0, 0.0);
|
|
builtinData.distortionBlur = 0.0;
|
|
#endif
|
|
|
|
PostInitBuiltinData(V, posInput, surfaceData, builtinData);
|
|
}
|
|
|
|
PackedVaryingsMeshToPS Vert(AttributesMesh inputMesh )
|
|
{
|
|
PackedVaryingsMeshToPS outputPackedVaryingsMeshToPS;
|
|
|
|
UNITY_SETUP_INSTANCE_ID( inputMesh );
|
|
UNITY_TRANSFER_INSTANCE_ID( inputMesh, outputPackedVaryingsMeshToPS );
|
|
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO( outputPackedVaryingsMeshToPS );
|
|
|
|
OctaImpostorVertex( inputMesh.vertex, inputMesh.normal, outputPackedVaryingsMeshToPS.UVsFrame117, outputPackedVaryingsMeshToPS.UVsFrame217, outputPackedVaryingsMeshToPS.UVsFrame317, outputPackedVaryingsMeshToPS.octaframe17, outputPackedVaryingsMeshToPS.viewPos17 );
|
|
|
|
inputMesh.vertex.xyz += float3( 0, 0, 0 ) ;
|
|
|
|
float3 positionRWS = TransformObjectToWorld(inputMesh.vertex.xyz );
|
|
float3 normalWS = TransformObjectToWorldNormal(inputMesh.normal );
|
|
float4 tangentWS = float4(TransformObjectToWorldDir(inputMesh.tangent.xyz), inputMesh.tangent.w);
|
|
|
|
outputPackedVaryingsMeshToPS.positionCS = TransformWorldToHClip(positionRWS);
|
|
outputPackedVaryingsMeshToPS.interp00.xyz = positionRWS;
|
|
outputPackedVaryingsMeshToPS.interp01.xyz = normalWS;
|
|
outputPackedVaryingsMeshToPS.interp02.xyzw = tangentWS;
|
|
outputPackedVaryingsMeshToPS.interp03.xyzw = inputMesh.uv1;
|
|
outputPackedVaryingsMeshToPS.interp04.xyzw = inputMesh.uv2;
|
|
|
|
return outputPackedVaryingsMeshToPS;
|
|
}
|
|
|
|
void Frag( PackedVaryingsMeshToPS packedInput, OUTPUT_GBUFFER(outGBuffer), out float outputDepth : SV_Depth )
|
|
{
|
|
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX( packedInput );
|
|
UNITY_SETUP_INSTANCE_ID( packedInput );
|
|
|
|
#ifdef LOD_FADE_CROSSFADE
|
|
float3 VC = GetWorldSpaceNormalizeViewDir(packedInput.interp00.xyz);
|
|
LODDitheringTransition(ComputeFadeMaskSeed(VC, packedInput.positionCS.xy), unity_LODFade.x);
|
|
#endif
|
|
|
|
FragInputs input;
|
|
|
|
ZERO_INITIALIZE( FragInputs, input );
|
|
GlobalSurfaceDescription surfaceDescription = (GlobalSurfaceDescription)0;
|
|
SurfaceOutput o = (SurfaceOutput)0;
|
|
|
|
o.Normal = float3( 0, 0, 1 );
|
|
float4 clipPos = 0;
|
|
float3 worldPos = 0;
|
|
|
|
float4 output0 = 0;
|
|
OctaImpostorFragment( o, clipPos, worldPos, packedInput.UVsFrame117, packedInput.UVsFrame217, packedInput.UVsFrame317, packedInput.octaframe17, packedInput.viewPos17, output0 );
|
|
float4 break38 = output0;
|
|
float3 objToWorld67 = GetAbsolutePositionWS(mul( GetObjectToWorldMatrix(), float4( float3( 0,0,0 ), 1 ) ).xyz);
|
|
float3 hsvTorgb33 = HSVToRGB( float3(abs( sin( ( objToWorld67.x + objToWorld67.z ) ) ),1.0,1.0) );
|
|
float3 lerpResult36 = lerp( o.Albedo , ( break38.w * hsvTorgb33 ) , break38.w);
|
|
|
|
float3 temp_cast_0 = (break38.x).xxx;
|
|
|
|
|
|
surfaceDescription.Albedo = lerpResult36;
|
|
o.Normal = o.Normal;
|
|
surfaceDescription.BentNormal = float3( 0, 0, 1 );
|
|
surfaceDescription.CoatMask = 0;
|
|
surfaceDescription.Metallic = 0;
|
|
|
|
#ifdef _MATERIAL_FEATURE_SPECULAR_COLOR
|
|
surfaceDescription.Specular = temp_cast_0;
|
|
#endif
|
|
|
|
surfaceDescription.Emission = 0;
|
|
surfaceDescription.Smoothness = break38.y;
|
|
surfaceDescription.Occlusion = break38.z;
|
|
surfaceDescription.Alpha = o.Alpha;
|
|
|
|
#ifdef _ALPHATEST_ON
|
|
surfaceDescription.AlphaClipThreshold = 0;
|
|
#endif
|
|
|
|
#ifdef _ENABLE_GEOMETRIC_SPECULAR_AA
|
|
surfaceDescription.SpecularAAScreenSpaceVariance = 0;
|
|
surfaceDescription.SpecularAAThreshold = 0;
|
|
#endif
|
|
|
|
#ifdef _SPECULAR_OCCLUSION_CUSTOM
|
|
surfaceDescription.SpecularOcclusion = 0;
|
|
#endif
|
|
|
|
#if defined(_HAS_REFRACTION) || defined(_MATERIAL_FEATURE_TRANSMISSION)
|
|
surfaceDescription.Thickness = 0;
|
|
#endif
|
|
|
|
#ifdef _HAS_REFRACTION
|
|
surfaceDescription.RefractionIndex = 1;
|
|
surfaceDescription.RefractionColor = float3(1,1,1);
|
|
surfaceDescription.RefractionDistance = 0;
|
|
#endif
|
|
|
|
#ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING
|
|
surfaceDescription.SubsurfaceMask = 1;
|
|
#endif
|
|
|
|
#if defined( _MATERIAL_FEATURE_SUBSURFACE_SCATTERING ) || defined( _MATERIAL_FEATURE_TRANSMISSION )
|
|
surfaceDescription.DiffusionProfile = 0;
|
|
#endif
|
|
|
|
#ifdef _MATERIAL_FEATURE_ANISOTROPY
|
|
surfaceDescription.Anisotropy = 1;
|
|
surfaceDescription.Tangent = float3(1,0,0);
|
|
#endif
|
|
|
|
#ifdef _MATERIAL_FEATURE_IRIDESCENCE
|
|
surfaceDescription.IridescenceMask = 0;
|
|
surfaceDescription.IridescenceThickness = 0;
|
|
#endif
|
|
|
|
float4 bakedGI = float4( 0, 0, 0, 0 );
|
|
|
|
packedInput.positionCS.zw = clipPos.zw;
|
|
float3 positionRWS = worldPos;
|
|
float3 normalWS = o.Normal;
|
|
float4 tangentWS = packedInput.interp02.xyzw;
|
|
|
|
input.positionSS = packedInput.positionCS;
|
|
input.positionRWS = positionRWS;
|
|
//#if defined( ASE_SRP_VERSION ) && ASE_SRP_VERSION < 60900
|
|
//input.worldToTangent = BuildWorldToTangent( tangentWS, normalWS );
|
|
//#else
|
|
input.tangentToWorld = BuildTangentToWorld( tangentWS, normalWS );
|
|
//#endif
|
|
input.texCoord1 = packedInput.interp03.xyzw;
|
|
input.texCoord2 = packedInput.interp04.xyzw;
|
|
|
|
PositionInputs posInput = GetPositionInput( input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS );
|
|
SurfaceData surfaceData;
|
|
BuiltinData builtinData;
|
|
|
|
float3 normalizedWorldViewDir = GetWorldSpaceNormalizeViewDir( input.positionRWS );
|
|
|
|
GetSurfaceAndBuiltinData(surfaceDescription,input, normalizedWorldViewDir, posInput, surfaceData, builtinData);
|
|
|
|
#ifdef CUSTOM_BAKED_GI
|
|
BSDFData bsdfData = ConvertSurfaceDataToBSDFData( posInput.positionSS, surfaceData );
|
|
half4 decodeInstructions = half4( LIGHTMAP_HDR_MULTIPLIER, LIGHTMAP_HDR_EXPONENT, 0.0h, 0.0h );
|
|
builtinData.bakeDiffuseLighting = UnpackLightmapRGBM( bakedGI, decodeInstructions ) * EMISSIVE_RGBM_SCALE * bsdfData.diffuseColor;
|
|
#endif
|
|
|
|
ENCODE_INTO_GBUFFER(surfaceData, builtinData, posInput.positionSS, outGBuffer);
|
|
|
|
outputDepth = posInput.deviceDepth;
|
|
}
|
|
|
|
ENDHLSL
|
|
}
|
|
|
|
|
|
Pass
|
|
{
|
|
|
|
Name "SceneSelectionPass"
|
|
Tags { "LightMode"="SceneSelectionPass" }
|
|
ColorMask 0
|
|
|
|
HLSLPROGRAM
|
|
#define _DECALS 1
|
|
#define _MATERIAL_FEATURE_SPECULAR_COLOR 1
|
|
#define _ENERGY_CONSERVING_SPECULAR 1
|
|
#define _AMBIENT_OCCLUSION 1
|
|
#define ASE_SRP_VERSION 120112
|
|
#ifdef UNITY_COLORSPACE_GAMMA//AI_SRP
|
|
#define unity_ColorSpaceDielectricSpec half4(0.220916301, 0.220916301, 0.220916301, 1.0 - 0.220916301)//AI_SRP
|
|
#else//AI_SRP
|
|
#define unity_ColorSpaceDielectricSpec half4(0.04, 0.04, 0.04, 1.0 - 0.04) //AI_SRP
|
|
#endif//AI_SRP
|
|
|
|
#pragma vertex Vert
|
|
#pragma fragment Frag
|
|
|
|
#if defined(_MATERIAL_FEATURE_SUBSURFACE_SCATTERING) && !defined(_SURFACE_TYPE_TRANSPARENT)
|
|
#define OUTPUT_SPLIT_LIGHTING
|
|
#endif
|
|
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
|
|
//#if defined( ASE_SRP_VERSION ) && ASE_SRP_VERSION < 60900
|
|
//#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Wind.hlsl"
|
|
//#endif
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/NormalSurfaceGradient.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/FragInputs.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl"
|
|
|
|
|
|
#define SHADERPASS SHADERPASS_DEPTH_ONLY
|
|
#define SCENESELECTIONPASS
|
|
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinUtilities.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialUtilities.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalUtilities.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDecalData.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphFunctions.hlsl"
|
|
|
|
//#if defined( ASE_SRP_VERSION ) && ASE_SRP_VERSION < 60900
|
|
//#define T2W(var, index) var.worldToTangent[index]
|
|
//#else
|
|
#define T2W(var, index) var.tangentToWorld[index]
|
|
//#endif
|
|
|
|
int _ObjectId;
|
|
int _PassValue;
|
|
|
|
#define ai_ObjectToWorld GetObjectToWorldMatrix()
|
|
#define ai_WorldToObject GetWorldToObjectMatrix()
|
|
#define AI_INV_TWO_PI INV_TWO_PI
|
|
#define AI_PI PI
|
|
#define AI_INV_PI INV_PI
|
|
|
|
|
|
struct AttributesMesh
|
|
{
|
|
float4 vertex : POSITION;
|
|
float3 normal : NORMAL;
|
|
float4 texcoord : TEXCOORD0;
|
|
UNITY_VERTEX_INPUT_INSTANCE_ID
|
|
|
|
};
|
|
|
|
struct PackedVaryingsMeshToPS
|
|
{
|
|
float4 positionCS : SV_Position;
|
|
UNITY_VERTEX_INPUT_INSTANCE_ID
|
|
float4 UVsFrame117 : TEXCOORD0;
|
|
float4 UVsFrame217 : TEXCOORD1;
|
|
float4 UVsFrame317 : TEXCOORD2;
|
|
float4 octaframe17 : TEXCOORD3;
|
|
float4 viewPos17 : TEXCOORD4;
|
|
};
|
|
|
|
sampler2D _Albedo;
|
|
sampler2D _Normals;
|
|
sampler2D _Mask;
|
|
SAMPLER(sampler_Mask);
|
|
CBUFFER_START( UnityPerMaterial )
|
|
float4 _AI_SizeOffset;
|
|
float3 _AI_Offset;
|
|
float _AI_Frames;
|
|
float _AI_FramesX;
|
|
float _AI_FramesY;
|
|
float _AI_ImpostorSize;
|
|
float _AI_Parallax;
|
|
float _AI_TextureBias;
|
|
float _AI_DepthSize;
|
|
float _AI_ShadowBias;
|
|
float _AI_ShadowView;
|
|
float _AI_Clip;
|
|
CBUFFER_END
|
|
|
|
|
|
float2 VectortoOctahedron( float3 N )
|
|
{
|
|
N /= dot( 1.0, abs( N ) );
|
|
if( N.z <= 0 )
|
|
{
|
|
N.xy = ( 1 - abs( N.yx ) ) * ( N.xy >= 0 ? 1.0 : -1.0 );
|
|
}
|
|
return N.xy;
|
|
}
|
|
|
|
float3 OctahedronToVector( float2 Oct )
|
|
{
|
|
float3 N = float3( Oct, 1.0 - dot( 1.0, abs( Oct ) ) );
|
|
if(N.z< 0 )
|
|
{
|
|
N.xy = ( 1 - abs( N.yx) ) * (N.xy >= 0 ? 1.0 : -1.0 );
|
|
}
|
|
return normalize( N);
|
|
}
|
|
|
|
inline void RayPlaneIntersectionUV( float3 normal, float3 rayPosition, float3 rayDirection, inout float2 uvs, inout float3 localNormal )
|
|
{
|
|
float lDotN = dot( rayDirection, normal );
|
|
float p0l0DotN = dot( -rayPosition, normal );
|
|
float t = p0l0DotN / lDotN;
|
|
float3 p = rayDirection * t + rayPosition;
|
|
float3 upVector = float3( 0, 1, 0 );
|
|
float3 tangent = normalize( cross( upVector, normal ) + float3( -0.001, 0, 0 ) );
|
|
float3 bitangent = cross( tangent, normal );
|
|
float frameX = dot( p, tangent );
|
|
float frameZ = dot( p, bitangent );
|
|
uvs = -float2( frameX, frameZ );
|
|
if( t <= 0.0 )
|
|
uvs = 0;
|
|
float3x3 worldToLocal = float3x3( tangent, bitangent, normal );
|
|
localNormal = normalize( mul( worldToLocal, rayDirection ) );
|
|
}
|
|
|
|
inline void OctaImpostorVertex( inout float4 vertex, inout float3 normal, inout float4 uvsFrame1, inout float4 uvsFrame2, inout float4 uvsFrame3, inout float4 octaFrame, inout float4 viewPos )
|
|
{
|
|
float2 uvOffset = _AI_SizeOffset.zw;
|
|
float parallax = -_AI_Parallax;
|
|
float UVscale = _AI_ImpostorSize;
|
|
float framesXY = _AI_Frames;
|
|
float prevFrame = framesXY - 1;
|
|
float3 fractions = 1.0 / float3( framesXY, prevFrame, UVscale );
|
|
float fractionsFrame = fractions.x;
|
|
float fractionsPrevFrame = fractions.y;
|
|
float fractionsUVscale = fractions.z;
|
|
float3 worldOrigin = 0;
|
|
float4 perspective = float4( 0, 0, 0, 1 );
|
|
if( UNITY_MATRIX_P[ 3 ][ 3 ] == 1 )
|
|
{
|
|
perspective = float4( 0, 0, 5000, 0 );
|
|
worldOrigin = ai_ObjectToWorld._m03_m13_m23;
|
|
}
|
|
float3 worldCameraPos = worldOrigin + mul( UNITY_MATRIX_I_V, perspective ).xyz;
|
|
float3 objectCameraPosition = mul( ai_WorldToObject, float4( worldCameraPos, 1 ) ).xyz - _AI_Offset.xyz;
|
|
float3 objectCameraDirection = normalize( objectCameraPosition );
|
|
float3 upVector = float3( 0,1,0 );
|
|
float3 objectHorizontalVector = normalize( cross( objectCameraDirection, upVector ) );
|
|
float3 objectVerticalVector = cross( objectHorizontalVector, objectCameraDirection );
|
|
float2 uvExpansion = vertex.xy;
|
|
float3 billboard = objectHorizontalVector * uvExpansion.x + objectVerticalVector * uvExpansion.y;
|
|
float3 localDir = billboard - objectCameraPosition;
|
|
float2 frameOcta = VectortoOctahedron( objectCameraDirection.xzy ) * 0.5 + 0.5;
|
|
float2 prevOctaFrame = frameOcta * prevFrame;
|
|
float2 baseOctaFrame = floor( prevOctaFrame );
|
|
float2 fractionOctaFrame = ( baseOctaFrame * fractionsFrame );
|
|
float2 octaFrame1 = ( baseOctaFrame * fractionsPrevFrame ) * 2.0 - 1.0;
|
|
float3 octa1WorldY = OctahedronToVector( octaFrame1 ).xzy;
|
|
float3 octa1LocalY;
|
|
float2 uvFrame1;
|
|
RayPlaneIntersectionUV( octa1WorldY, objectCameraPosition, localDir, /*inout*/ uvFrame1, /*inout*/ octa1LocalY );
|
|
float2 uvParallax1 = octa1LocalY.xy * fractionsFrame * parallax;
|
|
uvFrame1 = ( uvFrame1 * fractionsUVscale + 0.5 ) * fractionsFrame + fractionOctaFrame;
|
|
uvsFrame1 = float4( uvParallax1, uvFrame1) - float4( 0, 0, uvOffset );
|
|
float2 fractPrevOctaFrame = frac( prevOctaFrame );
|
|
float2 cornerDifference = lerp( float2( 0,1 ) , float2( 1,0 ) , saturate( ceil( ( fractPrevOctaFrame.x - fractPrevOctaFrame.y ) ) ));
|
|
float2 octaFrame2 = ( ( baseOctaFrame + cornerDifference ) * fractionsPrevFrame ) * 2.0 - 1.0;
|
|
float3 octa2WorldY = OctahedronToVector( octaFrame2 ).xzy;
|
|
float3 octa2LocalY;
|
|
float2 uvFrame2;
|
|
RayPlaneIntersectionUV( octa2WorldY, objectCameraPosition, localDir, /*inout*/ uvFrame2, /*inout*/ octa2LocalY );
|
|
float2 uvParallax2 = octa2LocalY.xy * fractionsFrame * parallax;
|
|
uvFrame2 = ( uvFrame2 * fractionsUVscale + 0.5 ) * fractionsFrame + ( ( cornerDifference * fractionsFrame ) + fractionOctaFrame );
|
|
uvsFrame2 = float4( uvParallax2, uvFrame2) - float4( 0, 0, uvOffset );
|
|
float2 octaFrame3 = ( ( baseOctaFrame + 1 ) * fractionsPrevFrame ) * 2.0 - 1.0;
|
|
float3 octa3WorldY = OctahedronToVector( octaFrame3 ).xzy;
|
|
float3 octa3LocalY;
|
|
float2 uvFrame3;
|
|
RayPlaneIntersectionUV( octa3WorldY, objectCameraPosition, localDir, /*inout*/ uvFrame3, /*inout*/ octa3LocalY );
|
|
float2 uvParallax3 = octa3LocalY.xy * fractionsFrame * parallax;
|
|
uvFrame3 = ( uvFrame3 * fractionsUVscale + 0.5 ) * fractionsFrame + ( fractionOctaFrame + fractionsFrame );
|
|
uvsFrame3 = float4( uvParallax3, uvFrame3) - float4( 0, 0, uvOffset );
|
|
octaFrame = 0;
|
|
octaFrame.xy = prevOctaFrame;
|
|
vertex.xyz = billboard + _AI_Offset.xyz;
|
|
normal.xyz = objectCameraDirection;
|
|
viewPos = 0;
|
|
viewPos.xyz = TransformWorldToView( TransformObjectToWorld( vertex.xyz ) );
|
|
}
|
|
|
|
inline void OctaImpostorFragment( inout SurfaceOutput o, out float4 clipPos, out float3 worldPos, float4 uvsFrame1, float4 uvsFrame2, float4 uvsFrame3, float4 octaFrame, float4 interpViewPos, out float4 output0 )
|
|
{
|
|
float depthBias = -1.0;
|
|
float textureBias = _AI_TextureBias;
|
|
float2 fraction = frac( octaFrame.xy );
|
|
float2 invFraction = 1 - fraction;
|
|
float3 weights;
|
|
weights.x = min( invFraction.x, invFraction.y );
|
|
weights.y = abs( fraction.x - fraction.y );
|
|
weights.z = min( fraction.x, fraction.y );
|
|
float4 parallaxSample1 = tex2Dbias( _Normals, float4(uvsFrame1.zw, 0, depthBias) );
|
|
float2 parallax1 = ( ( 0.5 - parallaxSample1.a ) * uvsFrame1.xy ) + uvsFrame1.zw;
|
|
float4 parallaxSample2 = tex2Dbias( _Normals, float4(uvsFrame2.zw, 0, depthBias) );
|
|
float2 parallax2 = ( ( 0.5 - parallaxSample2.a ) * uvsFrame2.xy ) + uvsFrame2.zw;
|
|
float4 parallaxSample3 = tex2Dbias( _Normals, float4(uvsFrame3.zw, 0, depthBias) );
|
|
float2 parallax3 = ( ( 0.5 - parallaxSample3.a ) * uvsFrame3.xy ) + uvsFrame3.zw;
|
|
float4 albedo1 = tex2Dbias( _Albedo, float4(parallax1, 0, textureBias) );
|
|
float4 albedo2 = tex2Dbias( _Albedo, float4(parallax2, 0, textureBias) );
|
|
float4 albedo3 = tex2Dbias( _Albedo, float4(parallax3, 0, textureBias) );
|
|
float4 blendedAlbedo = albedo1 * weights.x + albedo2 * weights.y + albedo3 * weights.z;
|
|
o.Alpha = ( blendedAlbedo.a - _AI_Clip );
|
|
clip( o.Alpha );
|
|
o.Albedo = blendedAlbedo.rgb;
|
|
#if defined(AI_HD_RENDERPIPELINE)
|
|
float4 feat1 = _Features.SampleLevel( SamplerState_Point_Repeat, parallax1, 0);
|
|
o.Diffusion = feat1.rgb;
|
|
o.Features = feat1.a;
|
|
float4 test1 = _Specular.SampleLevel( SamplerState_Point_Repeat, parallax1, 0);
|
|
o.MetalTangent = test1.b;
|
|
#endif
|
|
float4 normals1 = tex2Dbias( _Normals, float4(parallax1, 0, textureBias) );
|
|
float4 normals2 = tex2Dbias( _Normals, float4(parallax2, 0, textureBias) );
|
|
float4 normals3 = tex2Dbias( _Normals, float4(parallax3, 0, textureBias) );
|
|
float4 blendedNormal = normals1 * weights.x + normals2 * weights.y + normals3 * weights.z;
|
|
float4 output0a = tex2Dbias( _Mask, float4(parallax1, 0, textureBias) );
|
|
float4 output0b = tex2Dbias( _Mask, float4(parallax2, 0, textureBias) );
|
|
float4 output0c = tex2Dbias( _Mask, float4(parallax3, 0, textureBias) );
|
|
output0 = output0a * weights.x + output0b * weights.y + output0c * weights.z;
|
|
float3 localNormal = blendedNormal.rgb * 2.0 - 1.0;
|
|
float3 worldNormal = normalize( mul( (float3x3)ai_ObjectToWorld, localNormal ) );
|
|
o.Normal = worldNormal;
|
|
float3 viewPos = interpViewPos.xyz;
|
|
#if ( defined(SHADERPASS) && (defined(SHADERPASS_DEPTHNORMALSONLY) && SHADERPASS == SHADERPASS_DEPTHNORMALSONLY) ) || defined(UNITY_PASS_SHADOWCASTER)
|
|
float depthOffset = ( ( parallaxSample1.a * weights.x + parallaxSample2.a * weights.y + parallaxSample3.a * weights.z ) - 0.5001 /** 2.0 - 1.0*/ ) /** 0.5*/ * _AI_DepthSize * length( ai_ObjectToWorld[ 2 ].xyz );
|
|
#else
|
|
float depthOffset = ( ( parallaxSample1.a * weights.x + parallaxSample2.a * weights.y + parallaxSample3.a * weights.z ) - 0.5 /** 2.0 - 1.0*/ ) /** 0.5*/ * _AI_DepthSize * length( ai_ObjectToWorld[ 2 ].xyz );
|
|
#endif
|
|
#if ( defined(SHADERPASS) && ((defined(SHADERPASS_SHADOWS) && SHADERPASS == SHADERPASS_SHADOWS) || (defined(SHADERPASS_SHADOWCASTER) && SHADERPASS == SHADERPASS_SHADOWCASTER)) ) || defined(UNITY_PASS_SHADOWCASTER)
|
|
viewPos.z += depthOffset * _AI_ShadowView;
|
|
viewPos.z += -_AI_ShadowBias;
|
|
#else
|
|
viewPos.z += depthOffset;
|
|
#endif
|
|
worldPos = mul( UNITY_MATRIX_I_V, float4( viewPos.xyz, 1 ) ).xyz;
|
|
clipPos = mul( UNITY_MATRIX_P, float4( viewPos, 1 ) );
|
|
#if defined(UNITY_PASS_SHADOWCASTER) && !defined(SHADERPASS)
|
|
#if UNITY_REVERSED_Z
|
|
clipPos.z = min( clipPos.z, clipPos.w * UNITY_NEAR_CLIP_VALUE );
|
|
#else
|
|
clipPos.z = max( clipPos.z, clipPos.w * UNITY_NEAR_CLIP_VALUE );
|
|
#endif
|
|
#endif
|
|
clipPos.xyz /= clipPos.w;
|
|
if( UNITY_NEAR_CLIP_VALUE < 0 )
|
|
clipPos = clipPos * 0.5 + 0.5;
|
|
}
|
|
|
|
|
|
void BuildSurfaceData(FragInputs fragInputs, inout AlphaSurfaceDescription surfaceDescription, float3 V, out SurfaceData surfaceData, out float3 bentNormalWS)
|
|
{
|
|
ZERO_INITIALIZE(SurfaceData, surfaceData);
|
|
|
|
surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD;
|
|
#ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING;
|
|
#endif
|
|
#ifdef _MATERIAL_FEATURE_TRANSMISSION
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION;
|
|
#endif
|
|
#ifdef _MATERIAL_FEATURE_ANISOTROPY
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_ANISOTROPY;
|
|
#endif
|
|
|
|
#ifdef _MATERIAL_FEATURE_IRIDESCENCE
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_IRIDESCENCE;
|
|
#endif
|
|
#ifdef _MATERIAL_FEATURE_SPECULAR_COLOR
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR;
|
|
#endif
|
|
|
|
#if defined (_MATERIAL_FEATURE_SPECULAR_COLOR) && defined (_ENERGY_CONSERVING_SPECULAR)
|
|
surfaceData.baseColor *= (1.0 - Max3(surfaceData.specularColor.r, surfaceData.specularColor.g, surfaceData.specularColor.b));
|
|
#endif
|
|
|
|
GetNormalWS( fragInputs, float3( 0.0f, 0.0f, 1.0f ), surfaceData.normalWS, float3( 1.0, 1.0, 1.0 ) );
|
|
|
|
bentNormalWS = surfaceData.normalWS;
|
|
|
|
#ifdef _HAS_REFRACTION
|
|
if (_EnableSSRefraction)
|
|
{
|
|
|
|
surfaceData.transmittanceMask = (1.0 - surfaceDescription.Alpha);
|
|
surfaceDescription.Alpha = 1.0;
|
|
}
|
|
else
|
|
{
|
|
surfaceData.ior = 1.0;
|
|
surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);
|
|
surfaceData.atDistance = 1.0;
|
|
surfaceData.transmittanceMask = 0.0;
|
|
surfaceDescription.Alpha = 1.0;
|
|
}
|
|
#else
|
|
surfaceData.ior = 1.0;
|
|
surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);
|
|
surfaceData.atDistance = 1.0;
|
|
surfaceData.transmittanceMask = 0.0;
|
|
#endif
|
|
|
|
surfaceData.tangentWS = normalize(T2W(fragInputs, 0).xyz); // The tangent is not normalize in worldToTangent for mikkt. TODO: Check if it expected that we normalize with Morten. Tag: SURFACE_GRADIENT
|
|
surfaceData.tangentWS = Orthonormalize(surfaceData.tangentWS, surfaceData.normalWS);
|
|
|
|
#if defined(_SPECULAR_OCCLUSION_CUSTOM)
|
|
#elif defined(_SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL)
|
|
surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO(V, bentNormalWS, surfaceData.normalWS, surfaceData.ambientOcclusion, PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness));
|
|
#elif defined(_AMBIENT_OCCLUSION) && defined(_SPECULAR_OCCLUSION_FROM_AO)
|
|
surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(dot(surfaceData.normalWS, V)), surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness));
|
|
#else
|
|
surfaceData.specularOcclusion = 1.0;
|
|
#endif
|
|
#ifdef _ENABLE_GEOMETRIC_SPECULAR_AA
|
|
surfaceData.perceptualSmoothness = GeometricNormalFiltering(surfaceData.perceptualSmoothness, T2W(fragInputs, 2), surfaceDescription.SpecularAAScreenSpaceVariance, surfaceDescription.SpecularAAThreshold);
|
|
#endif
|
|
}
|
|
|
|
void GetSurfaceAndBuiltinData(AlphaSurfaceDescription surfaceDescription, FragInputs fragInputs, float3 V, inout PositionInputs posInput, out SurfaceData surfaceData, out BuiltinData builtinData)
|
|
{
|
|
//#ifdef LOD_FADE_CROSSFADE
|
|
// uint3 fadeMaskSeed = asuint((int3)(V * _ScreenSize.xyx));
|
|
// LODDitheringTransition(fadeMaskSeed, unity_LODFade.x);
|
|
//#endif
|
|
|
|
#ifdef _ALPHATEST_ON
|
|
DoAlphaTest ( surfaceDescription.Alpha, surfaceDescription.AlphaClipThreshold );
|
|
#endif
|
|
|
|
float3 bentNormalWS;
|
|
BuildSurfaceData(fragInputs, surfaceDescription, V, surfaceData, bentNormalWS);
|
|
|
|
#if HAVE_DECALS
|
|
if( _EnableDecals )
|
|
{
|
|
DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, surfaceDescription.Alpha);
|
|
ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData);
|
|
}
|
|
#endif
|
|
|
|
//#if defined( ASE_SRP_VERSION ) && ASE_SRP_VERSION <= 50702
|
|
//InitBuiltinData( surfaceDescription.Alpha, bentNormalWS, -T2W(fragInputs, 2), fragInputs.positionRWS, fragInputs.texCoord1, fragInputs.texCoord2, builtinData );
|
|
//#else
|
|
InitBuiltinData( posInput, surfaceDescription.Alpha, bentNormalWS, -T2W(fragInputs, 2), fragInputs.texCoord1, fragInputs.texCoord2, builtinData );
|
|
//#endif
|
|
|
|
builtinData.depthOffset = 0.0;
|
|
|
|
#if (SHADERPASS == SHADERPASS_DISTORTION)
|
|
builtinData.distortion = surfaceDescription.Distortion;
|
|
builtinData.distortionBlur = surfaceDescription.DistortionBlur;
|
|
#else
|
|
builtinData.distortion = float2(0.0, 0.0);
|
|
builtinData.distortionBlur = 0.0;
|
|
#endif
|
|
|
|
PostInitBuiltinData(V, posInput, surfaceData, builtinData);
|
|
}
|
|
|
|
PackedVaryingsMeshToPS Vert(AttributesMesh inputMesh )
|
|
{
|
|
UNITY_SETUP_INSTANCE_ID( inputMesh );
|
|
PackedVaryingsMeshToPS outputPackedVaryingsMeshToPS;
|
|
UNITY_TRANSFER_INSTANCE_ID( inputMesh, outputPackedVaryingsMeshToPS );
|
|
|
|
OctaImpostorVertex( inputMesh.vertex, inputMesh.normal, outputPackedVaryingsMeshToPS.UVsFrame117, outputPackedVaryingsMeshToPS.UVsFrame217, outputPackedVaryingsMeshToPS.UVsFrame317, outputPackedVaryingsMeshToPS.octaframe17, outputPackedVaryingsMeshToPS.viewPos17 );
|
|
|
|
inputMesh.vertex.xyz += float3( 0, 0, 0 ) ;
|
|
|
|
float3 positionRWS = TransformObjectToWorld(inputMesh.vertex.xyz );
|
|
outputPackedVaryingsMeshToPS.positionCS = TransformWorldToHClip(positionRWS);
|
|
return outputPackedVaryingsMeshToPS;
|
|
}
|
|
|
|
void Frag( PackedVaryingsMeshToPS packedInput
|
|
#ifdef WRITE_NORMAL_BUFFER
|
|
, out float4 outNormalBuffer : SV_Target0
|
|
#ifdef WRITE_MSAA_DEPTH
|
|
, out float1 depthColor : SV_Target1
|
|
#endif
|
|
#elif defined(SCENESELECTIONPASS)
|
|
, out float4 outColor : SV_Target0
|
|
#endif
|
|
, out float outputDepth : SV_Depth
|
|
|
|
)
|
|
{
|
|
UNITY_SETUP_INSTANCE_ID( packedInput );
|
|
|
|
//#ifdef LOD_FADE_CROSSFADE
|
|
//float3 VC = GetWorldSpaceNormalizeViewDir(packedInput.interp00.xyz);
|
|
//LODDitheringTransition(ComputeFadeMaskSeed(VC, packedInput.positionCS.xy), unity_LODFade.x);
|
|
//#endif
|
|
|
|
FragInputs input;
|
|
ZERO_INITIALIZE(FragInputs, input);
|
|
AlphaSurfaceDescription surfaceDescription = (AlphaSurfaceDescription)0;
|
|
SurfaceOutput o = (SurfaceOutput)0;
|
|
|
|
o.Normal = float3( 0, 0, 1 );
|
|
float4 clipPos = 0;
|
|
float3 worldPos = 0;
|
|
float4 output0 = 0;
|
|
OctaImpostorFragment( o, clipPos, worldPos, packedInput.UVsFrame117, packedInput.UVsFrame217, packedInput.UVsFrame317, packedInput.octaframe17, packedInput.viewPos17, output0 );
|
|
|
|
surfaceDescription.Alpha = o.Alpha;
|
|
|
|
#ifdef _ALPHATEST_ON
|
|
surfaceDescription.AlphaClipThreshold = 0;
|
|
#endif
|
|
|
|
packedInput.positionCS.zw = clipPos.zw;
|
|
float3 positionRWS = worldPos;
|
|
|
|
//#if defined( ASE_SRP_VERSION ) && ASE_SRP_VERSION < 60900
|
|
//input.worldToTangent = k_identity3x3;
|
|
//#else
|
|
input.tangentToWorld = k_identity3x3;
|
|
//#endif
|
|
|
|
input.positionSS = packedInput.positionCS;
|
|
input.positionRWS = positionRWS;
|
|
PositionInputs posInput = GetPositionInput( input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS );
|
|
|
|
float3 normalizedWorldViewDir = GetWorldSpaceNormalizeViewDir( input.positionRWS );
|
|
|
|
SurfaceData surfaceData;
|
|
BuiltinData builtinData;
|
|
|
|
GetSurfaceAndBuiltinData(surfaceDescription,input, normalizedWorldViewDir, posInput, surfaceData, builtinData);
|
|
|
|
outputDepth = posInput.deviceDepth;
|
|
|
|
#ifdef WRITE_NORMAL_BUFFER
|
|
EncodeIntoNormalBuffer(ConvertSurfaceDataToNormalData(surfaceData), posInput.positionSS, outNormalBuffer);
|
|
#ifdef WRITE_MSAA_DEPTH
|
|
depthColor = packedInput.positionCS.z;
|
|
#endif
|
|
#elif defined(SCENESELECTIONPASS)
|
|
outColor = float4(_ObjectId, _PassValue, 1.0, 1.0);
|
|
#endif
|
|
}
|
|
|
|
ENDHLSL
|
|
}
|
|
|
|
|
|
Pass
|
|
{
|
|
|
|
Name "META"
|
|
Tags { "LightMode"="Meta" }
|
|
Cull Off
|
|
|
|
HLSLPROGRAM
|
|
|
|
#define _DECALS 1
|
|
#define _MATERIAL_FEATURE_SPECULAR_COLOR 1
|
|
#define _ENERGY_CONSERVING_SPECULAR 1
|
|
#define _AMBIENT_OCCLUSION 1
|
|
#define ASE_SRP_VERSION 120112
|
|
#ifdef UNITY_COLORSPACE_GAMMA//AI_SRP
|
|
#define unity_ColorSpaceDielectricSpec half4(0.220916301, 0.220916301, 0.220916301, 1.0 - 0.220916301)//AI_SRP
|
|
#else//AI_SRP
|
|
#define unity_ColorSpaceDielectricSpec half4(0.04, 0.04, 0.04, 1.0 - 0.04) //AI_SRP
|
|
#endif//AI_SRP
|
|
|
|
|
|
#pragma vertex Vert
|
|
#pragma fragment Frag
|
|
|
|
#if defined(_MATERIAL_FEATURE_SUBSURFACE_SCATTERING) && !defined(_SURFACE_TYPE_TRANSPARENT)
|
|
#define OUTPUT_SPLIT_LIGHTING
|
|
#endif
|
|
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
|
|
//#if defined( ASE_SRP_VERSION ) && ASE_SRP_VERSION < 60900
|
|
//#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Wind.hlsl"
|
|
//#endif
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/NormalSurfaceGradient.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/FragInputs.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl"
|
|
|
|
#define SHADERPASS SHADERPASS_LIGHT_TRANSPORT
|
|
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinUtilities.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialUtilities.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalUtilities.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDecalData.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphFunctions.hlsl"
|
|
|
|
//#if defined( ASE_SRP_VERSION ) && ASE_SRP_VERSION < 60900
|
|
//#define T2W(var, index) var.worldToTangent[index]
|
|
//#else
|
|
#define T2W(var, index) var.tangentToWorld[index]
|
|
//#endif
|
|
|
|
#define ai_ObjectToWorld GetObjectToWorldMatrix()
|
|
#define ai_WorldToObject GetWorldToObjectMatrix()
|
|
#define AI_INV_TWO_PI INV_TWO_PI
|
|
#define AI_PI PI
|
|
#define AI_INV_PI INV_PI
|
|
|
|
|
|
struct AttributesMesh
|
|
{
|
|
float4 vertex : POSITION;
|
|
float3 normal : NORMAL;
|
|
float4 tangent : TANGENT;
|
|
float4 texcoord : TEXCOORD0;
|
|
float4 uv1 : TEXCOORD1;
|
|
float4 uv2 : TEXCOORD2;
|
|
float4 color : COLOR;
|
|
UNITY_VERTEX_INPUT_INSTANCE_ID
|
|
|
|
};
|
|
|
|
struct PackedVaryingsMeshToPS
|
|
{
|
|
float4 positionCS : SV_Position;
|
|
UNITY_VERTEX_INPUT_INSTANCE_ID
|
|
float4 UVsFrame117 : TEXCOORD0;
|
|
float4 UVsFrame217 : TEXCOORD1;
|
|
float4 UVsFrame317 : TEXCOORD2;
|
|
float4 octaframe17 : TEXCOORD3;
|
|
float4 viewPos17 : TEXCOORD4;
|
|
};
|
|
|
|
sampler2D _Albedo;
|
|
sampler2D _Normals;
|
|
sampler2D _Mask;
|
|
SAMPLER(sampler_Mask);
|
|
float4x4 unity_CameraProjection;
|
|
float4x4 unity_CameraInvProjection;
|
|
float4x4 unity_WorldToCamera;
|
|
float4x4 unity_CameraToWorld;
|
|
CBUFFER_START( UnityPerMaterial )
|
|
float4 _AI_SizeOffset;
|
|
float3 _AI_Offset;
|
|
float _AI_Frames;
|
|
float _AI_FramesX;
|
|
float _AI_FramesY;
|
|
float _AI_ImpostorSize;
|
|
float _AI_Parallax;
|
|
float _AI_TextureBias;
|
|
float _AI_DepthSize;
|
|
float _AI_ShadowBias;
|
|
float _AI_ShadowView;
|
|
float _AI_Clip;
|
|
CBUFFER_END
|
|
|
|
|
|
float2 VectortoOctahedron( float3 N )
|
|
{
|
|
N /= dot( 1.0, abs( N ) );
|
|
if( N.z <= 0 )
|
|
{
|
|
N.xy = ( 1 - abs( N.yx ) ) * ( N.xy >= 0 ? 1.0 : -1.0 );
|
|
}
|
|
return N.xy;
|
|
}
|
|
|
|
float3 OctahedronToVector( float2 Oct )
|
|
{
|
|
float3 N = float3( Oct, 1.0 - dot( 1.0, abs( Oct ) ) );
|
|
if(N.z< 0 )
|
|
{
|
|
N.xy = ( 1 - abs( N.yx) ) * (N.xy >= 0 ? 1.0 : -1.0 );
|
|
}
|
|
return normalize( N);
|
|
}
|
|
|
|
inline void RayPlaneIntersectionUV( float3 normal, float3 rayPosition, float3 rayDirection, inout float2 uvs, inout float3 localNormal )
|
|
{
|
|
float lDotN = dot( rayDirection, normal );
|
|
float p0l0DotN = dot( -rayPosition, normal );
|
|
float t = p0l0DotN / lDotN;
|
|
float3 p = rayDirection * t + rayPosition;
|
|
float3 upVector = float3( 0, 1, 0 );
|
|
float3 tangent = normalize( cross( upVector, normal ) + float3( -0.001, 0, 0 ) );
|
|
float3 bitangent = cross( tangent, normal );
|
|
float frameX = dot( p, tangent );
|
|
float frameZ = dot( p, bitangent );
|
|
uvs = -float2( frameX, frameZ );
|
|
if( t <= 0.0 )
|
|
uvs = 0;
|
|
float3x3 worldToLocal = float3x3( tangent, bitangent, normal );
|
|
localNormal = normalize( mul( worldToLocal, rayDirection ) );
|
|
}
|
|
|
|
inline void OctaImpostorVertex( inout float4 vertex, inout float3 normal, inout float4 uvsFrame1, inout float4 uvsFrame2, inout float4 uvsFrame3, inout float4 octaFrame, inout float4 viewPos )
|
|
{
|
|
float2 uvOffset = _AI_SizeOffset.zw;
|
|
float parallax = -_AI_Parallax;
|
|
float UVscale = _AI_ImpostorSize;
|
|
float framesXY = _AI_Frames;
|
|
float prevFrame = framesXY - 1;
|
|
float3 fractions = 1.0 / float3( framesXY, prevFrame, UVscale );
|
|
float fractionsFrame = fractions.x;
|
|
float fractionsPrevFrame = fractions.y;
|
|
float fractionsUVscale = fractions.z;
|
|
float3 worldOrigin = 0;
|
|
float4 perspective = float4( 0, 0, 0, 1 );
|
|
if( UNITY_MATRIX_P[ 3 ][ 3 ] == 1 )
|
|
{
|
|
perspective = float4( 0, 0, 5000, 0 );
|
|
worldOrigin = ai_ObjectToWorld._m03_m13_m23;
|
|
}
|
|
float3 worldCameraPos = worldOrigin + mul( UNITY_MATRIX_I_V, perspective ).xyz;
|
|
float3 objectCameraPosition = mul( ai_WorldToObject, float4( worldCameraPos, 1 ) ).xyz - _AI_Offset.xyz;
|
|
float3 objectCameraDirection = normalize( objectCameraPosition );
|
|
float3 upVector = float3( 0,1,0 );
|
|
float3 objectHorizontalVector = normalize( cross( objectCameraDirection, upVector ) );
|
|
float3 objectVerticalVector = cross( objectHorizontalVector, objectCameraDirection );
|
|
float2 uvExpansion = vertex.xy;
|
|
float3 billboard = objectHorizontalVector * uvExpansion.x + objectVerticalVector * uvExpansion.y;
|
|
float3 localDir = billboard - objectCameraPosition;
|
|
float2 frameOcta = VectortoOctahedron( objectCameraDirection.xzy ) * 0.5 + 0.5;
|
|
float2 prevOctaFrame = frameOcta * prevFrame;
|
|
float2 baseOctaFrame = floor( prevOctaFrame );
|
|
float2 fractionOctaFrame = ( baseOctaFrame * fractionsFrame );
|
|
float2 octaFrame1 = ( baseOctaFrame * fractionsPrevFrame ) * 2.0 - 1.0;
|
|
float3 octa1WorldY = OctahedronToVector( octaFrame1 ).xzy;
|
|
float3 octa1LocalY;
|
|
float2 uvFrame1;
|
|
RayPlaneIntersectionUV( octa1WorldY, objectCameraPosition, localDir, /*inout*/ uvFrame1, /*inout*/ octa1LocalY );
|
|
float2 uvParallax1 = octa1LocalY.xy * fractionsFrame * parallax;
|
|
uvFrame1 = ( uvFrame1 * fractionsUVscale + 0.5 ) * fractionsFrame + fractionOctaFrame;
|
|
uvsFrame1 = float4( uvParallax1, uvFrame1) - float4( 0, 0, uvOffset );
|
|
float2 fractPrevOctaFrame = frac( prevOctaFrame );
|
|
float2 cornerDifference = lerp( float2( 0,1 ) , float2( 1,0 ) , saturate( ceil( ( fractPrevOctaFrame.x - fractPrevOctaFrame.y ) ) ));
|
|
float2 octaFrame2 = ( ( baseOctaFrame + cornerDifference ) * fractionsPrevFrame ) * 2.0 - 1.0;
|
|
float3 octa2WorldY = OctahedronToVector( octaFrame2 ).xzy;
|
|
float3 octa2LocalY;
|
|
float2 uvFrame2;
|
|
RayPlaneIntersectionUV( octa2WorldY, objectCameraPosition, localDir, /*inout*/ uvFrame2, /*inout*/ octa2LocalY );
|
|
float2 uvParallax2 = octa2LocalY.xy * fractionsFrame * parallax;
|
|
uvFrame2 = ( uvFrame2 * fractionsUVscale + 0.5 ) * fractionsFrame + ( ( cornerDifference * fractionsFrame ) + fractionOctaFrame );
|
|
uvsFrame2 = float4( uvParallax2, uvFrame2) - float4( 0, 0, uvOffset );
|
|
float2 octaFrame3 = ( ( baseOctaFrame + 1 ) * fractionsPrevFrame ) * 2.0 - 1.0;
|
|
float3 octa3WorldY = OctahedronToVector( octaFrame3 ).xzy;
|
|
float3 octa3LocalY;
|
|
float2 uvFrame3;
|
|
RayPlaneIntersectionUV( octa3WorldY, objectCameraPosition, localDir, /*inout*/ uvFrame3, /*inout*/ octa3LocalY );
|
|
float2 uvParallax3 = octa3LocalY.xy * fractionsFrame * parallax;
|
|
uvFrame3 = ( uvFrame3 * fractionsUVscale + 0.5 ) * fractionsFrame + ( fractionOctaFrame + fractionsFrame );
|
|
uvsFrame3 = float4( uvParallax3, uvFrame3) - float4( 0, 0, uvOffset );
|
|
octaFrame = 0;
|
|
octaFrame.xy = prevOctaFrame;
|
|
vertex.xyz = billboard + _AI_Offset.xyz;
|
|
normal.xyz = objectCameraDirection;
|
|
viewPos = 0;
|
|
viewPos.xyz = TransformWorldToView( TransformObjectToWorld( vertex.xyz ) );
|
|
}
|
|
|
|
inline void OctaImpostorFragment( inout SurfaceOutput o, out float4 clipPos, out float3 worldPos, float4 uvsFrame1, float4 uvsFrame2, float4 uvsFrame3, float4 octaFrame, float4 interpViewPos, out float4 output0 )
|
|
{
|
|
float depthBias = -1.0;
|
|
float textureBias = _AI_TextureBias;
|
|
float2 fraction = frac( octaFrame.xy );
|
|
float2 invFraction = 1 - fraction;
|
|
float3 weights;
|
|
weights.x = min( invFraction.x, invFraction.y );
|
|
weights.y = abs( fraction.x - fraction.y );
|
|
weights.z = min( fraction.x, fraction.y );
|
|
float4 parallaxSample1 = tex2Dbias( _Normals, float4(uvsFrame1.zw, 0, depthBias) );
|
|
float2 parallax1 = ( ( 0.5 - parallaxSample1.a ) * uvsFrame1.xy ) + uvsFrame1.zw;
|
|
float4 parallaxSample2 = tex2Dbias( _Normals, float4(uvsFrame2.zw, 0, depthBias) );
|
|
float2 parallax2 = ( ( 0.5 - parallaxSample2.a ) * uvsFrame2.xy ) + uvsFrame2.zw;
|
|
float4 parallaxSample3 = tex2Dbias( _Normals, float4(uvsFrame3.zw, 0, depthBias) );
|
|
float2 parallax3 = ( ( 0.5 - parallaxSample3.a ) * uvsFrame3.xy ) + uvsFrame3.zw;
|
|
float4 albedo1 = tex2Dbias( _Albedo, float4(parallax1, 0, textureBias) );
|
|
float4 albedo2 = tex2Dbias( _Albedo, float4(parallax2, 0, textureBias) );
|
|
float4 albedo3 = tex2Dbias( _Albedo, float4(parallax3, 0, textureBias) );
|
|
float4 blendedAlbedo = albedo1 * weights.x + albedo2 * weights.y + albedo3 * weights.z;
|
|
o.Alpha = ( blendedAlbedo.a - _AI_Clip );
|
|
clip( o.Alpha );
|
|
o.Albedo = blendedAlbedo.rgb;
|
|
#if defined(AI_HD_RENDERPIPELINE)
|
|
float4 feat1 = _Features.SampleLevel( SamplerState_Point_Repeat, parallax1, 0);
|
|
o.Diffusion = feat1.rgb;
|
|
o.Features = feat1.a;
|
|
float4 test1 = _Specular.SampleLevel( SamplerState_Point_Repeat, parallax1, 0);
|
|
o.MetalTangent = test1.b;
|
|
#endif
|
|
float4 normals1 = tex2Dbias( _Normals, float4(parallax1, 0, textureBias) );
|
|
float4 normals2 = tex2Dbias( _Normals, float4(parallax2, 0, textureBias) );
|
|
float4 normals3 = tex2Dbias( _Normals, float4(parallax3, 0, textureBias) );
|
|
float4 blendedNormal = normals1 * weights.x + normals2 * weights.y + normals3 * weights.z;
|
|
float4 output0a = tex2Dbias( _Mask, float4(parallax1, 0, textureBias) );
|
|
float4 output0b = tex2Dbias( _Mask, float4(parallax2, 0, textureBias) );
|
|
float4 output0c = tex2Dbias( _Mask, float4(parallax3, 0, textureBias) );
|
|
output0 = output0a * weights.x + output0b * weights.y + output0c * weights.z;
|
|
float3 localNormal = blendedNormal.rgb * 2.0 - 1.0;
|
|
float3 worldNormal = normalize( mul( (float3x3)ai_ObjectToWorld, localNormal ) );
|
|
o.Normal = worldNormal;
|
|
float3 viewPos = interpViewPos.xyz;
|
|
#if ( defined(SHADERPASS) && (defined(SHADERPASS_DEPTHNORMALSONLY) && SHADERPASS == SHADERPASS_DEPTHNORMALSONLY) ) || defined(UNITY_PASS_SHADOWCASTER)
|
|
float depthOffset = ( ( parallaxSample1.a * weights.x + parallaxSample2.a * weights.y + parallaxSample3.a * weights.z ) - 0.5001 /** 2.0 - 1.0*/ ) /** 0.5*/ * _AI_DepthSize * length( ai_ObjectToWorld[ 2 ].xyz );
|
|
#else
|
|
float depthOffset = ( ( parallaxSample1.a * weights.x + parallaxSample2.a * weights.y + parallaxSample3.a * weights.z ) - 0.5 /** 2.0 - 1.0*/ ) /** 0.5*/ * _AI_DepthSize * length( ai_ObjectToWorld[ 2 ].xyz );
|
|
#endif
|
|
#if ( defined(SHADERPASS) && ((defined(SHADERPASS_SHADOWS) && SHADERPASS == SHADERPASS_SHADOWS) || (defined(SHADERPASS_SHADOWCASTER) && SHADERPASS == SHADERPASS_SHADOWCASTER)) ) || defined(UNITY_PASS_SHADOWCASTER)
|
|
viewPos.z += depthOffset * _AI_ShadowView;
|
|
viewPos.z += -_AI_ShadowBias;
|
|
#else
|
|
viewPos.z += depthOffset;
|
|
#endif
|
|
worldPos = mul( UNITY_MATRIX_I_V, float4( viewPos.xyz, 1 ) ).xyz;
|
|
clipPos = mul( UNITY_MATRIX_P, float4( viewPos, 1 ) );
|
|
#if defined(UNITY_PASS_SHADOWCASTER) && !defined(SHADERPASS)
|
|
#if UNITY_REVERSED_Z
|
|
clipPos.z = min( clipPos.z, clipPos.w * UNITY_NEAR_CLIP_VALUE );
|
|
#else
|
|
clipPos.z = max( clipPos.z, clipPos.w * UNITY_NEAR_CLIP_VALUE );
|
|
#endif
|
|
#endif
|
|
clipPos.xyz /= clipPos.w;
|
|
if( UNITY_NEAR_CLIP_VALUE < 0 )
|
|
clipPos = clipPos * 0.5 + 0.5;
|
|
}
|
|
|
|
float3 HSVToRGB( float3 c )
|
|
{
|
|
float4 K = float4( 1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0 );
|
|
float3 p = abs( frac( c.xxx + K.xyz ) * 6.0 - K.www );
|
|
return c.z * lerp( K.xxx, saturate( p - K.xxx ), c.y );
|
|
}
|
|
|
|
|
|
void BuildSurfaceData( FragInputs fragInputs, inout GlobalSurfaceDescription surfaceDescription, float3 V, out SurfaceData surfaceData, out float3 bentNormalWS )
|
|
{
|
|
ZERO_INITIALIZE( SurfaceData, surfaceData );
|
|
surfaceData.baseColor = surfaceDescription.Albedo;
|
|
surfaceData.perceptualSmoothness = surfaceDescription.Smoothness;
|
|
#ifdef _SPECULAR_OCCLUSION_CUSTOM
|
|
surfaceData.specularOcclusion = surfaceDescription.SpecularOcclusion;
|
|
#endif
|
|
surfaceData.ambientOcclusion = surfaceDescription.Occlusion;
|
|
surfaceData.metallic = surfaceDescription.Metallic;
|
|
surfaceData.coatMask = surfaceDescription.CoatMask;
|
|
|
|
#ifdef _MATERIAL_FEATURE_IRIDESCENCE
|
|
surfaceData.iridescenceMask = surfaceDescription.IridescenceMask;
|
|
surfaceData.iridescenceThickness = surfaceDescription.IridescenceThickness;
|
|
#endif
|
|
surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD;
|
|
#ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING;
|
|
#endif
|
|
#ifdef _MATERIAL_FEATURE_TRANSMISSION
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION;
|
|
#endif
|
|
#ifdef _MATERIAL_FEATURE_ANISOTROPY
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_ANISOTROPY;
|
|
#endif
|
|
|
|
#ifdef ASE_LIT_CLEAR_COAT
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_CLEAR_COAT;
|
|
#endif
|
|
|
|
#ifdef _MATERIAL_FEATURE_IRIDESCENCE
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_IRIDESCENCE;
|
|
#endif
|
|
#ifdef _MATERIAL_FEATURE_SPECULAR_COLOR
|
|
surfaceData.specularColor = surfaceDescription.Specular;
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR;
|
|
#endif
|
|
|
|
#if defined (_MATERIAL_FEATURE_SPECULAR_COLOR) && defined (_ENERGY_CONSERVING_SPECULAR)
|
|
surfaceData.baseColor *= ( 1.0 - Max3( surfaceData.specularColor.r, surfaceData.specularColor.g, surfaceData.specularColor.b ) );
|
|
#endif
|
|
//float3 normalTS = float3( 0.0f, 0.0f, 1.0f );
|
|
//normalTS = surfaceDescription.Normal;
|
|
GetNormalWS( fragInputs, float3( 0.0, 0.0, 1.0 ), surfaceData.normalWS, float3( 1.0, 1.0, 1.0 ) );
|
|
bentNormalWS = surfaceData.normalWS;
|
|
|
|
#ifdef ASE_BENT_NORMAL
|
|
GetNormalWS( fragInputs, surfaceDescription.BentNormal, bentNormalWS, float4( 1, 1, -1, 0 ) );
|
|
#endif
|
|
|
|
surfaceData.geomNormalWS = T2W(fragInputs, 2);
|
|
|
|
#ifdef _HAS_REFRACTION
|
|
if( _EnableSSRefraction )
|
|
{
|
|
surfaceData.ior = surfaceDescription.RefractionIndex;
|
|
surfaceData.transmittanceColor = surfaceDescription.RefractionColor;
|
|
surfaceData.atDistance = surfaceDescription.RefractionDistance;
|
|
|
|
surfaceData.transmittanceMask = ( 1.0 - surfaceDescription.Alpha );
|
|
surfaceDescription.Alpha = 1.0;
|
|
}
|
|
else
|
|
{
|
|
surfaceData.ior = 1.0;
|
|
surfaceData.transmittanceColor = float3( 1.0, 1.0, 1.0 );
|
|
surfaceData.atDistance = 1.0;
|
|
surfaceData.transmittanceMask = 0.0;
|
|
surfaceDescription.Alpha = 1.0;
|
|
}
|
|
#else
|
|
surfaceData.ior = 1.0;
|
|
surfaceData.transmittanceColor = float3( 1.0, 1.0, 1.0 );
|
|
surfaceData.atDistance = 1.0;
|
|
surfaceData.transmittanceMask = 0.0;
|
|
#endif
|
|
|
|
#if defined(_HAS_REFRACTION) || defined(_MATERIAL_FEATURE_TRANSMISSION)
|
|
surfaceData.thickness = surfaceDescription.Thickness;
|
|
#endif
|
|
|
|
#ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING
|
|
surfaceData.subsurfaceMask = surfaceDescription.SubsurfaceMask;
|
|
#endif
|
|
|
|
#if defined( _MATERIAL_FEATURE_SUBSURFACE_SCATTERING ) || defined( _MATERIAL_FEATURE_TRANSMISSION )
|
|
surfaceData.diffusionProfileHash = asuint(surfaceDescription.DiffusionProfile);
|
|
#endif
|
|
|
|
surfaceData.tangentWS = normalize( T2W(fragInputs, 0).xyz ); // The tangent is not normalize in worldToTangent for mikkt. TODO: Check if it expected that we normalize with Morten. Tag: SURFACE_GRADIENT
|
|
#ifdef _MATERIAL_FEATURE_ANISOTROPY
|
|
surfaceData.anisotropy = surfaceDescription.Anisotropy;
|
|
surfaceData.tangentWS = TransformTangentToWorld( surfaceDescription.Tangent, fragInputs.worldToTangent );
|
|
#endif
|
|
surfaceData.tangentWS = Orthonormalize( surfaceData.tangentWS, surfaceData.normalWS );
|
|
#if defined(_SPECULAR_OCCLUSION_CUSTOM)
|
|
#elif defined(_SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL)
|
|
surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO( V, bentNormalWS, surfaceData.normalWS, surfaceData.ambientOcclusion, PerceptualSmoothnessToPerceptualRoughness( surfaceData.perceptualSmoothness ) );
|
|
#elif defined(_AMBIENT_OCCLUSION) && defined(_SPECULAR_OCCLUSION_FROM_AO)
|
|
surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion( ClampNdotV( dot( surfaceData.normalWS, V ) ), surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness( surfaceData.perceptualSmoothness ) );
|
|
#else
|
|
surfaceData.specularOcclusion = 1.0;
|
|
#endif
|
|
#ifdef _ENABLE_GEOMETRIC_SPECULAR_AA
|
|
surfaceData.perceptualSmoothness = GeometricNormalFiltering( surfaceData.perceptualSmoothness, T2W(fragInputs, 2), surfaceDescription.SpecularAAScreenSpaceVariance, surfaceDescription.SpecularAAThreshold );
|
|
#endif
|
|
|
|
}
|
|
|
|
void GetSurfaceAndBuiltinData( GlobalSurfaceDescription surfaceDescription,FragInputs fragInputs, float3 V, inout PositionInputs posInput, out SurfaceData surfaceData, out BuiltinData builtinData )
|
|
{
|
|
//#ifdef LOD_FADE_CROSSFADE
|
|
// uint3 fadeMaskSeed = asuint( ( int3 )( V * _ScreenSize.xyx ) ); // Quantize V to _ScreenSize values
|
|
// LODDitheringTransition( fadeMaskSeed, unity_LODFade.x );
|
|
//#endif
|
|
|
|
#ifdef _ALPHATEST_ON
|
|
DoAlphaTest( surfaceDescription.Alpha, surfaceDescription.AlphaClipThreshold );
|
|
#endif
|
|
|
|
float3 bentNormalWS;
|
|
BuildSurfaceData( fragInputs, surfaceDescription, V, surfaceData, bentNormalWS );
|
|
|
|
#if HAVE_DECALS
|
|
if( _EnableDecals )
|
|
{
|
|
DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, surfaceDescription.Alpha);
|
|
ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData);
|
|
}
|
|
#endif
|
|
|
|
//#if defined( ASE_SRP_VERSION ) && ASE_SRP_VERSION <= 50702
|
|
//InitBuiltinData( surfaceDescription.Alpha, bentNormalWS, -T2W(fragInputs, 2), fragInputs.positionRWS, fragInputs.texCoord1, fragInputs.texCoord2, builtinData );
|
|
//#else
|
|
InitBuiltinData( posInput, surfaceDescription.Alpha, bentNormalWS, -T2W(fragInputs, 2), fragInputs.texCoord1, fragInputs.texCoord2, builtinData );
|
|
//#endif
|
|
|
|
builtinData.emissiveColor = surfaceDescription.Emission;
|
|
|
|
builtinData.depthOffset = 0.0;
|
|
|
|
#if (SHADERPASS == SHADERPASS_DISTORTION)
|
|
builtinData.distortion = surfaceDescription.Distortion;
|
|
builtinData.distortionBlur = surfaceDescription.DistortionBlur;
|
|
#else
|
|
builtinData.distortion = float2( 0.0, 0.0 );
|
|
builtinData.distortionBlur = 0.0;
|
|
#endif
|
|
|
|
PostInitBuiltinData( V, posInput, surfaceData, builtinData );
|
|
}
|
|
|
|
CBUFFER_START( UnityMetaPass )
|
|
bool4 unity_MetaVertexControl;
|
|
bool4 unity_MetaFragmentControl;
|
|
CBUFFER_END
|
|
|
|
float unity_OneOverOutputBoost;
|
|
float unity_MaxOutputValue;
|
|
|
|
PackedVaryingsMeshToPS Vert( AttributesMesh inputMesh )
|
|
{
|
|
UNITY_SETUP_INSTANCE_ID( inputMesh );
|
|
PackedVaryingsMeshToPS outputPackedVaryingsMeshToPS;
|
|
UNITY_TRANSFER_INSTANCE_ID( inputMesh, outputPackedVaryingsMeshToPS );
|
|
|
|
OctaImpostorVertex( inputMesh.vertex, inputMesh.normal, outputPackedVaryingsMeshToPS.UVsFrame117, outputPackedVaryingsMeshToPS.UVsFrame217, outputPackedVaryingsMeshToPS.UVsFrame317, outputPackedVaryingsMeshToPS.octaframe17, outputPackedVaryingsMeshToPS.viewPos17 );
|
|
|
|
inputMesh.vertex.xyz += float3( 0, 0, 0 ) ;
|
|
|
|
float2 uv = float2( 0.0, 0.0 );
|
|
if( unity_MetaVertexControl.x )
|
|
{
|
|
uv = inputMesh.uv1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
|
|
}
|
|
else if( unity_MetaVertexControl.y )
|
|
{
|
|
uv = inputMesh.uv2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;
|
|
}
|
|
|
|
outputPackedVaryingsMeshToPS.positionCS = float4( uv * 2.0 - 1.0, inputMesh.vertex.z > 0 ? 1.0e-4 : 0.0, 1.0 );
|
|
return outputPackedVaryingsMeshToPS;
|
|
}
|
|
|
|
float4 Frag( PackedVaryingsMeshToPS packedInput ) : SV_Target
|
|
{
|
|
UNITY_SETUP_INSTANCE_ID( packedInput );
|
|
|
|
//#ifdef LOD_FADE_CROSSFADE
|
|
//float3 VC = GetWorldSpaceNormalizeViewDir(packedInput.interp00.xyz);
|
|
//LODDitheringTransition(ComputeFadeMaskSeed(VC, packedInput.positionCS.xy), unity_LODFade.x);
|
|
//#endif
|
|
|
|
FragInputs input;
|
|
ZERO_INITIALIZE( FragInputs, input );
|
|
GlobalSurfaceDescription surfaceDescription = (GlobalSurfaceDescription)0;
|
|
SurfaceOutput o = (SurfaceOutput)0;
|
|
|
|
o.Normal = float3( 0, 0, 1 );
|
|
float4 clipPos = 0;
|
|
float3 worldPos = 0;
|
|
|
|
float4 output0 = 0;
|
|
OctaImpostorFragment( o, clipPos, worldPos, packedInput.UVsFrame117, packedInput.UVsFrame217, packedInput.UVsFrame317, packedInput.octaframe17, packedInput.viewPos17, output0 );
|
|
float4 break38 = output0;
|
|
float3 objToWorld67 = GetAbsolutePositionWS(mul( GetObjectToWorldMatrix(), float4( float3( 0,0,0 ), 1 ) ).xyz);
|
|
float3 hsvTorgb33 = HSVToRGB( float3(abs( sin( ( objToWorld67.x + objToWorld67.z ) ) ),1.0,1.0) );
|
|
float3 lerpResult36 = lerp( o.Albedo , ( break38.w * hsvTorgb33 ) , break38.w);
|
|
|
|
float3 temp_cast_0 = (break38.x).xxx;
|
|
|
|
|
|
surfaceDescription.Albedo = lerpResult36;
|
|
o.Normal = o.Normal;
|
|
surfaceDescription.BentNormal = float3( 0, 0, 1 );
|
|
surfaceDescription.CoatMask = 0;
|
|
surfaceDescription.Metallic = 0;
|
|
|
|
#ifdef _MATERIAL_FEATURE_SPECULAR_COLOR
|
|
surfaceDescription.Specular = temp_cast_0;
|
|
#endif
|
|
|
|
surfaceDescription.Emission = 0;
|
|
surfaceDescription.Smoothness = break38.y;
|
|
surfaceDescription.Occlusion = break38.z;
|
|
surfaceDescription.Alpha = o.Alpha;
|
|
|
|
#ifdef _ALPHATEST_ON
|
|
surfaceDescription.AlphaClipThreshold = 0;
|
|
#endif
|
|
|
|
#ifdef _ENABLE_GEOMETRIC_SPECULAR_AA
|
|
surfaceDescription.SpecularAAScreenSpaceVariance = 0;
|
|
surfaceDescription.SpecularAAThreshold = 0;
|
|
#endif
|
|
|
|
#ifdef _SPECULAR_OCCLUSION_CUSTOM
|
|
surfaceDescription.SpecularOcclusion = 0;
|
|
#endif
|
|
|
|
#if defined(_HAS_REFRACTION) || defined(_MATERIAL_FEATURE_TRANSMISSION)
|
|
surfaceDescription.Thickness = 0;
|
|
#endif
|
|
|
|
#ifdef _HAS_REFRACTION
|
|
surfaceDescription.RefractionIndex = 1;
|
|
surfaceDescription.RefractionColor = float3( 1,1,1 );
|
|
surfaceDescription.RefractionDistance = 0;
|
|
#endif
|
|
|
|
#ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING
|
|
surfaceDescription.SubsurfaceMask = 1;
|
|
#endif
|
|
|
|
#if defined( _MATERIAL_FEATURE_SUBSURFACE_SCATTERING ) || defined( _MATERIAL_FEATURE_TRANSMISSION )
|
|
surfaceDescription.DiffusionProfile = 0;
|
|
#endif
|
|
|
|
#ifdef _MATERIAL_FEATURE_ANISOTROPY
|
|
surfaceDescription.Anisotropy = 1;
|
|
surfaceDescription.Tangent = float3( 1,0,0 );
|
|
#endif
|
|
|
|
#ifdef _MATERIAL_FEATURE_IRIDESCENCE
|
|
surfaceDescription.IridescenceMask = 0;
|
|
surfaceDescription.IridescenceThickness = 0;
|
|
#endif
|
|
|
|
packedInput.positionCS.zw = clipPos.zw;
|
|
float3 positionRWS = worldPos;
|
|
|
|
input.positionSS = packedInput.positionCS;
|
|
input.positionRWS = positionRWS;
|
|
//#if defined( ASE_SRP_VERSION ) && ASE_SRP_VERSION < 60900
|
|
//input.worldToTangent = k_identity3x3;
|
|
//#else
|
|
input.tangentToWorld = k_identity3x3;
|
|
//#endif
|
|
|
|
PositionInputs posInput = GetPositionInput( input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS );
|
|
|
|
SurfaceData surfaceData;
|
|
BuiltinData builtinData;
|
|
|
|
float3 normalizedWorldViewDir = GetWorldSpaceNormalizeViewDir( input.positionRWS );
|
|
|
|
GetSurfaceAndBuiltinData( surfaceDescription,input, normalizedWorldViewDir, posInput, surfaceData, builtinData );
|
|
|
|
BSDFData bsdfData = ConvertSurfaceDataToBSDFData( input.positionSS.xy, surfaceData );
|
|
LightTransportData lightTransportData = GetLightTransportData( surfaceData, builtinData, bsdfData );
|
|
|
|
float4 res = float4( 0.0, 0.0, 0.0, 1.0 );
|
|
if( unity_MetaFragmentControl.x )
|
|
{
|
|
res.rgb = clamp( pow( abs( lightTransportData.diffuseColor ), saturate( unity_OneOverOutputBoost ) ), 0, unity_MaxOutputValue );
|
|
}
|
|
|
|
if( unity_MetaFragmentControl.y )
|
|
{
|
|
res.rgb = lightTransportData.emissiveColor;
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
ENDHLSL
|
|
}
|
|
|
|
|
|
Pass
|
|
{
|
|
|
|
Name "ShadowCaster"
|
|
Tags { "LightMode"="ShadowCaster" }
|
|
ColorMask 0
|
|
|
|
HLSLPROGRAM
|
|
#define _DECALS 1
|
|
#define _MATERIAL_FEATURE_SPECULAR_COLOR 1
|
|
#define _ENERGY_CONSERVING_SPECULAR 1
|
|
#define _AMBIENT_OCCLUSION 1
|
|
#define ASE_SRP_VERSION 120112
|
|
#ifdef UNITY_COLORSPACE_GAMMA//AI_SRP
|
|
#define unity_ColorSpaceDielectricSpec half4(0.220916301, 0.220916301, 0.220916301, 1.0 - 0.220916301)//AI_SRP
|
|
#else//AI_SRP
|
|
#define unity_ColorSpaceDielectricSpec half4(0.04, 0.04, 0.04, 1.0 - 0.04) //AI_SRP
|
|
#endif//AI_SRP
|
|
|
|
#pragma vertex Vert
|
|
#pragma fragment Frag
|
|
|
|
#if defined(_MATERIAL_FEATURE_SUBSURFACE_SCATTERING) && !defined(_SURFACE_TYPE_TRANSPARENT)
|
|
#define OUTPUT_SPLIT_LIGHTING
|
|
#endif
|
|
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
|
|
//#if defined( ASE_SRP_VERSION ) && ASE_SRP_VERSION < 60900
|
|
//#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Wind.hlsl"
|
|
//#endif
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/NormalSurfaceGradient.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/FragInputs.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl"
|
|
|
|
#define SHADERPASS SHADERPASS_SHADOWS
|
|
#define USE_LEGACY_UNITY_MATRIX_VARIABLES
|
|
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
|
|
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinUtilities.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialUtilities.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalUtilities.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDecalData.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphFunctions.hlsl"
|
|
|
|
//#if defined( ASE_SRP_VERSION ) && ASE_SRP_VERSION < 60900
|
|
//#define T2W(var, index) var.worldToTangent[index]
|
|
//#else
|
|
#define T2W(var, index) var.tangentToWorld[index]
|
|
//#endif
|
|
|
|
#define ai_ObjectToWorld GetObjectToWorldMatrix()
|
|
#define ai_WorldToObject GetWorldToObjectMatrix()
|
|
#define AI_INV_TWO_PI INV_TWO_PI
|
|
#define AI_PI PI
|
|
#define AI_INV_PI INV_PI
|
|
|
|
|
|
struct AttributesMesh
|
|
{
|
|
float4 vertex : POSITION;
|
|
float3 normal : NORMAL;
|
|
float4 texcoord : TEXCOORD0;
|
|
|
|
UNITY_VERTEX_INPUT_INSTANCE_ID
|
|
};
|
|
|
|
struct PackedVaryingsMeshToPS
|
|
{
|
|
float4 positionCS : SV_Position;
|
|
float3 interp00 : TEXCOORD10;
|
|
float4 UVsFrame117 : TEXCOORD0;
|
|
float4 UVsFrame217 : TEXCOORD1;
|
|
float4 UVsFrame317 : TEXCOORD2;
|
|
float4 octaframe17 : TEXCOORD3;
|
|
float4 viewPos17 : TEXCOORD4;
|
|
UNITY_VERTEX_INPUT_INSTANCE_ID
|
|
UNITY_VERTEX_OUTPUT_STEREO
|
|
};
|
|
|
|
sampler2D _Albedo;
|
|
sampler2D _Normals;
|
|
sampler2D _Mask;
|
|
SAMPLER(sampler_Mask);
|
|
CBUFFER_START( UnityPerMaterial )
|
|
float4 _AI_SizeOffset;
|
|
float3 _AI_Offset;
|
|
float _AI_Frames;
|
|
float _AI_FramesX;
|
|
float _AI_FramesY;
|
|
float _AI_ImpostorSize;
|
|
float _AI_Parallax;
|
|
float _AI_TextureBias;
|
|
float _AI_DepthSize;
|
|
float _AI_ShadowBias;
|
|
float _AI_ShadowView;
|
|
float _AI_Clip;
|
|
CBUFFER_END
|
|
|
|
|
|
float2 VectortoOctahedron( float3 N )
|
|
{
|
|
N /= dot( 1.0, abs( N ) );
|
|
if( N.z <= 0 )
|
|
{
|
|
N.xy = ( 1 - abs( N.yx ) ) * ( N.xy >= 0 ? 1.0 : -1.0 );
|
|
}
|
|
return N.xy;
|
|
}
|
|
|
|
float3 OctahedronToVector( float2 Oct )
|
|
{
|
|
float3 N = float3( Oct, 1.0 - dot( 1.0, abs( Oct ) ) );
|
|
if(N.z< 0 )
|
|
{
|
|
N.xy = ( 1 - abs( N.yx) ) * (N.xy >= 0 ? 1.0 : -1.0 );
|
|
}
|
|
return normalize( N);
|
|
}
|
|
|
|
inline void RayPlaneIntersectionUV( float3 normal, float3 rayPosition, float3 rayDirection, inout float2 uvs, inout float3 localNormal )
|
|
{
|
|
float lDotN = dot( rayDirection, normal );
|
|
float p0l0DotN = dot( -rayPosition, normal );
|
|
float t = p0l0DotN / lDotN;
|
|
float3 p = rayDirection * t + rayPosition;
|
|
float3 upVector = float3( 0, 1, 0 );
|
|
float3 tangent = normalize( cross( upVector, normal ) + float3( -0.001, 0, 0 ) );
|
|
float3 bitangent = cross( tangent, normal );
|
|
float frameX = dot( p, tangent );
|
|
float frameZ = dot( p, bitangent );
|
|
uvs = -float2( frameX, frameZ );
|
|
if( t <= 0.0 )
|
|
uvs = 0;
|
|
float3x3 worldToLocal = float3x3( tangent, bitangent, normal );
|
|
localNormal = normalize( mul( worldToLocal, rayDirection ) );
|
|
}
|
|
|
|
inline void OctaImpostorVertex( inout float4 vertex, inout float3 normal, inout float4 uvsFrame1, inout float4 uvsFrame2, inout float4 uvsFrame3, inout float4 octaFrame, inout float4 viewPos )
|
|
{
|
|
float2 uvOffset = _AI_SizeOffset.zw;
|
|
float parallax = -_AI_Parallax;
|
|
float UVscale = _AI_ImpostorSize;
|
|
float framesXY = _AI_Frames;
|
|
float prevFrame = framesXY - 1;
|
|
float3 fractions = 1.0 / float3( framesXY, prevFrame, UVscale );
|
|
float fractionsFrame = fractions.x;
|
|
float fractionsPrevFrame = fractions.y;
|
|
float fractionsUVscale = fractions.z;
|
|
float3 worldOrigin = 0;
|
|
float4 perspective = float4( 0, 0, 0, 1 );
|
|
if( UNITY_MATRIX_P[ 3 ][ 3 ] == 1 )
|
|
{
|
|
perspective = float4( 0, 0, 5000, 0 );
|
|
worldOrigin = ai_ObjectToWorld._m03_m13_m23;
|
|
}
|
|
float3 worldCameraPos = worldOrigin + mul( UNITY_MATRIX_I_V, perspective ).xyz;
|
|
float3 objectCameraPosition = mul( ai_WorldToObject, float4( worldCameraPos, 1 ) ).xyz - _AI_Offset.xyz;
|
|
float3 objectCameraDirection = normalize( objectCameraPosition );
|
|
float3 upVector = float3( 0,1,0 );
|
|
float3 objectHorizontalVector = normalize( cross( objectCameraDirection, upVector ) );
|
|
float3 objectVerticalVector = cross( objectHorizontalVector, objectCameraDirection );
|
|
float2 uvExpansion = vertex.xy;
|
|
float3 billboard = objectHorizontalVector * uvExpansion.x + objectVerticalVector * uvExpansion.y;
|
|
float3 localDir = billboard - objectCameraPosition;
|
|
float2 frameOcta = VectortoOctahedron( objectCameraDirection.xzy ) * 0.5 + 0.5;
|
|
float2 prevOctaFrame = frameOcta * prevFrame;
|
|
float2 baseOctaFrame = floor( prevOctaFrame );
|
|
float2 fractionOctaFrame = ( baseOctaFrame * fractionsFrame );
|
|
float2 octaFrame1 = ( baseOctaFrame * fractionsPrevFrame ) * 2.0 - 1.0;
|
|
float3 octa1WorldY = OctahedronToVector( octaFrame1 ).xzy;
|
|
float3 octa1LocalY;
|
|
float2 uvFrame1;
|
|
RayPlaneIntersectionUV( octa1WorldY, objectCameraPosition, localDir, /*inout*/ uvFrame1, /*inout*/ octa1LocalY );
|
|
float2 uvParallax1 = octa1LocalY.xy * fractionsFrame * parallax;
|
|
uvFrame1 = ( uvFrame1 * fractionsUVscale + 0.5 ) * fractionsFrame + fractionOctaFrame;
|
|
uvsFrame1 = float4( uvParallax1, uvFrame1) - float4( 0, 0, uvOffset );
|
|
float2 fractPrevOctaFrame = frac( prevOctaFrame );
|
|
float2 cornerDifference = lerp( float2( 0,1 ) , float2( 1,0 ) , saturate( ceil( ( fractPrevOctaFrame.x - fractPrevOctaFrame.y ) ) ));
|
|
float2 octaFrame2 = ( ( baseOctaFrame + cornerDifference ) * fractionsPrevFrame ) * 2.0 - 1.0;
|
|
float3 octa2WorldY = OctahedronToVector( octaFrame2 ).xzy;
|
|
float3 octa2LocalY;
|
|
float2 uvFrame2;
|
|
RayPlaneIntersectionUV( octa2WorldY, objectCameraPosition, localDir, /*inout*/ uvFrame2, /*inout*/ octa2LocalY );
|
|
float2 uvParallax2 = octa2LocalY.xy * fractionsFrame * parallax;
|
|
uvFrame2 = ( uvFrame2 * fractionsUVscale + 0.5 ) * fractionsFrame + ( ( cornerDifference * fractionsFrame ) + fractionOctaFrame );
|
|
uvsFrame2 = float4( uvParallax2, uvFrame2) - float4( 0, 0, uvOffset );
|
|
float2 octaFrame3 = ( ( baseOctaFrame + 1 ) * fractionsPrevFrame ) * 2.0 - 1.0;
|
|
float3 octa3WorldY = OctahedronToVector( octaFrame3 ).xzy;
|
|
float3 octa3LocalY;
|
|
float2 uvFrame3;
|
|
RayPlaneIntersectionUV( octa3WorldY, objectCameraPosition, localDir, /*inout*/ uvFrame3, /*inout*/ octa3LocalY );
|
|
float2 uvParallax3 = octa3LocalY.xy * fractionsFrame * parallax;
|
|
uvFrame3 = ( uvFrame3 * fractionsUVscale + 0.5 ) * fractionsFrame + ( fractionOctaFrame + fractionsFrame );
|
|
uvsFrame3 = float4( uvParallax3, uvFrame3) - float4( 0, 0, uvOffset );
|
|
octaFrame = 0;
|
|
octaFrame.xy = prevOctaFrame;
|
|
vertex.xyz = billboard + _AI_Offset.xyz;
|
|
normal.xyz = objectCameraDirection;
|
|
viewPos = 0;
|
|
viewPos.xyz = TransformWorldToView( TransformObjectToWorld( vertex.xyz ) );
|
|
}
|
|
|
|
inline void OctaImpostorFragment( inout SurfaceOutput o, out float4 clipPos, out float3 worldPos, float4 uvsFrame1, float4 uvsFrame2, float4 uvsFrame3, float4 octaFrame, float4 interpViewPos, out float4 output0 )
|
|
{
|
|
float depthBias = -1.0;
|
|
float textureBias = _AI_TextureBias;
|
|
float2 fraction = frac( octaFrame.xy );
|
|
float2 invFraction = 1 - fraction;
|
|
float3 weights;
|
|
weights.x = min( invFraction.x, invFraction.y );
|
|
weights.y = abs( fraction.x - fraction.y );
|
|
weights.z = min( fraction.x, fraction.y );
|
|
float4 parallaxSample1 = tex2Dbias( _Normals, float4(uvsFrame1.zw, 0, depthBias) );
|
|
float2 parallax1 = ( ( 0.5 - parallaxSample1.a ) * uvsFrame1.xy ) + uvsFrame1.zw;
|
|
float4 parallaxSample2 = tex2Dbias( _Normals, float4(uvsFrame2.zw, 0, depthBias) );
|
|
float2 parallax2 = ( ( 0.5 - parallaxSample2.a ) * uvsFrame2.xy ) + uvsFrame2.zw;
|
|
float4 parallaxSample3 = tex2Dbias( _Normals, float4(uvsFrame3.zw, 0, depthBias) );
|
|
float2 parallax3 = ( ( 0.5 - parallaxSample3.a ) * uvsFrame3.xy ) + uvsFrame3.zw;
|
|
float4 albedo1 = tex2Dbias( _Albedo, float4(parallax1, 0, textureBias) );
|
|
float4 albedo2 = tex2Dbias( _Albedo, float4(parallax2, 0, textureBias) );
|
|
float4 albedo3 = tex2Dbias( _Albedo, float4(parallax3, 0, textureBias) );
|
|
float4 blendedAlbedo = albedo1 * weights.x + albedo2 * weights.y + albedo3 * weights.z;
|
|
o.Alpha = ( blendedAlbedo.a - _AI_Clip );
|
|
clip( o.Alpha );
|
|
o.Albedo = blendedAlbedo.rgb;
|
|
#if defined(AI_HD_RENDERPIPELINE)
|
|
float4 feat1 = _Features.SampleLevel( SamplerState_Point_Repeat, parallax1, 0);
|
|
o.Diffusion = feat1.rgb;
|
|
o.Features = feat1.a;
|
|
float4 test1 = _Specular.SampleLevel( SamplerState_Point_Repeat, parallax1, 0);
|
|
o.MetalTangent = test1.b;
|
|
#endif
|
|
float4 normals1 = tex2Dbias( _Normals, float4(parallax1, 0, textureBias) );
|
|
float4 normals2 = tex2Dbias( _Normals, float4(parallax2, 0, textureBias) );
|
|
float4 normals3 = tex2Dbias( _Normals, float4(parallax3, 0, textureBias) );
|
|
float4 blendedNormal = normals1 * weights.x + normals2 * weights.y + normals3 * weights.z;
|
|
float4 output0a = tex2Dbias( _Mask, float4(parallax1, 0, textureBias) );
|
|
float4 output0b = tex2Dbias( _Mask, float4(parallax2, 0, textureBias) );
|
|
float4 output0c = tex2Dbias( _Mask, float4(parallax3, 0, textureBias) );
|
|
output0 = output0a * weights.x + output0b * weights.y + output0c * weights.z;
|
|
float3 localNormal = blendedNormal.rgb * 2.0 - 1.0;
|
|
float3 worldNormal = normalize( mul( (float3x3)ai_ObjectToWorld, localNormal ) );
|
|
o.Normal = worldNormal;
|
|
float3 viewPos = interpViewPos.xyz;
|
|
#if ( defined(SHADERPASS) && (defined(SHADERPASS_DEPTHNORMALSONLY) && SHADERPASS == SHADERPASS_DEPTHNORMALSONLY) ) || defined(UNITY_PASS_SHADOWCASTER)
|
|
float depthOffset = ( ( parallaxSample1.a * weights.x + parallaxSample2.a * weights.y + parallaxSample3.a * weights.z ) - 0.5001 /** 2.0 - 1.0*/ ) /** 0.5*/ * _AI_DepthSize * length( ai_ObjectToWorld[ 2 ].xyz );
|
|
#else
|
|
float depthOffset = ( ( parallaxSample1.a * weights.x + parallaxSample2.a * weights.y + parallaxSample3.a * weights.z ) - 0.5 /** 2.0 - 1.0*/ ) /** 0.5*/ * _AI_DepthSize * length( ai_ObjectToWorld[ 2 ].xyz );
|
|
#endif
|
|
#if ( defined(SHADERPASS) && ((defined(SHADERPASS_SHADOWS) && SHADERPASS == SHADERPASS_SHADOWS) || (defined(SHADERPASS_SHADOWCASTER) && SHADERPASS == SHADERPASS_SHADOWCASTER)) ) || defined(UNITY_PASS_SHADOWCASTER)
|
|
viewPos.z += depthOffset * _AI_ShadowView;
|
|
viewPos.z += -_AI_ShadowBias;
|
|
#else
|
|
viewPos.z += depthOffset;
|
|
#endif
|
|
worldPos = mul( UNITY_MATRIX_I_V, float4( viewPos.xyz, 1 ) ).xyz;
|
|
clipPos = mul( UNITY_MATRIX_P, float4( viewPos, 1 ) );
|
|
#if defined(UNITY_PASS_SHADOWCASTER) && !defined(SHADERPASS)
|
|
#if UNITY_REVERSED_Z
|
|
clipPos.z = min( clipPos.z, clipPos.w * UNITY_NEAR_CLIP_VALUE );
|
|
#else
|
|
clipPos.z = max( clipPos.z, clipPos.w * UNITY_NEAR_CLIP_VALUE );
|
|
#endif
|
|
#endif
|
|
clipPos.xyz /= clipPos.w;
|
|
if( UNITY_NEAR_CLIP_VALUE < 0 )
|
|
clipPos = clipPos * 0.5 + 0.5;
|
|
}
|
|
|
|
|
|
void BuildSurfaceData(FragInputs fragInputs, inout AlphaSurfaceDescription surfaceDescription, float3 V, out SurfaceData surfaceData, out float3 bentNormalWS)
|
|
{
|
|
ZERO_INITIALIZE(SurfaceData, surfaceData);
|
|
|
|
surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD;
|
|
#ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING;
|
|
#endif
|
|
#ifdef _MATERIAL_FEATURE_TRANSMISSION
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION;
|
|
#endif
|
|
#ifdef _MATERIAL_FEATURE_ANISOTROPY
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_ANISOTROPY;
|
|
#endif
|
|
|
|
#ifdef _MATERIAL_FEATURE_IRIDESCENCE
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_IRIDESCENCE;
|
|
#endif
|
|
#ifdef _MATERIAL_FEATURE_SPECULAR_COLOR
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR;
|
|
#endif
|
|
|
|
#if defined (_MATERIAL_FEATURE_SPECULAR_COLOR) && defined (_ENERGY_CONSERVING_SPECULAR)
|
|
surfaceData.baseColor *= (1.0 - Max3(surfaceData.specularColor.r, surfaceData.specularColor.g, surfaceData.specularColor.b));
|
|
#endif
|
|
|
|
GetNormalWS( fragInputs, float3( 0.0, 0.0, 1.0 ), surfaceData.normalWS, float3( 1.0, 1.0, 1.0 ) );
|
|
bentNormalWS = surfaceData.normalWS;
|
|
|
|
surfaceData.geomNormalWS = T2W(fragInputs, 2);
|
|
|
|
#ifdef _HAS_REFRACTION
|
|
if (_EnableSSRefraction)
|
|
{
|
|
|
|
surfaceData.transmittanceMask = (1.0 - surfaceDescription.Alpha);
|
|
surfaceDescription.Alpha = 1.0;
|
|
}
|
|
else
|
|
{
|
|
surfaceData.ior = 1.0;
|
|
surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);
|
|
surfaceData.atDistance = 1.0;
|
|
surfaceData.transmittanceMask = 0.0;
|
|
surfaceDescription.Alpha = 1.0;
|
|
}
|
|
#else
|
|
surfaceData.ior = 1.0;
|
|
surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);
|
|
surfaceData.atDistance = 1.0;
|
|
surfaceData.transmittanceMask = 0.0;
|
|
#endif
|
|
|
|
surfaceData.tangentWS = normalize(T2W(fragInputs, 0).xyz); // The tangent is not normalize in worldToTangent for mikkt. TODO: Check if it expected that we normalize with Morten. Tag: SURFACE_GRADIENT
|
|
surfaceData.tangentWS = Orthonormalize(surfaceData.tangentWS, surfaceData.normalWS);
|
|
|
|
#if defined(_SPECULAR_OCCLUSION_CUSTOM)
|
|
#elif defined(_SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL)
|
|
surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO(V, bentNormalWS, surfaceData.normalWS, surfaceData.ambientOcclusion, PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness));
|
|
#elif defined(_AMBIENT_OCCLUSION) && defined(_SPECULAR_OCCLUSION_FROM_AO)
|
|
surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(dot(surfaceData.normalWS, V)), surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness));
|
|
#else
|
|
surfaceData.specularOcclusion = 1.0;
|
|
#endif
|
|
#ifdef _ENABLE_GEOMETRIC_SPECULAR_AA
|
|
surfaceData.perceptualSmoothness = GeometricNormalFiltering(surfaceData.perceptualSmoothness, T2W(fragInputs, 2), surfaceDescription.SpecularAAScreenSpaceVariance, surfaceDescription.SpecularAAThreshold);
|
|
#endif
|
|
}
|
|
|
|
void GetSurfaceAndBuiltinData(AlphaSurfaceDescription surfaceDescription, FragInputs fragInputs, float3 V, inout PositionInputs posInput, out SurfaceData surfaceData, out BuiltinData builtinData)
|
|
{
|
|
//#ifdef LOD_FADE_CROSSFADE
|
|
// uint3 fadeMaskSeed = asuint((int3)(V * _ScreenSize.xyx));
|
|
// LODDitheringTransition(fadeMaskSeed, unity_LODFade.x);
|
|
//#endif
|
|
|
|
#ifdef _ALPHATEST_ON
|
|
DoAlphaTest ( surfaceDescription.Alpha, surfaceDescription.AlphaClipThreshold );
|
|
#endif
|
|
float3 bentNormalWS;
|
|
BuildSurfaceData(fragInputs, surfaceDescription, V, surfaceData, bentNormalWS);
|
|
|
|
#if HAVE_DECALS
|
|
if( _EnableDecals )
|
|
{
|
|
DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, surfaceDescription.Alpha);
|
|
ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData);
|
|
}
|
|
#endif
|
|
|
|
#if defined( ASE_SRP_VERSION ) && ASE_SRP_VERSION <= 50702
|
|
InitBuiltinData( surfaceDescription.Alpha, bentNormalWS, -T2W(fragInputs, 2), fragInputs.positionRWS, fragInputs.texCoord1, fragInputs.texCoord2, builtinData );
|
|
#else
|
|
InitBuiltinData( posInput, surfaceDescription.Alpha, bentNormalWS, -T2W(fragInputs, 2), fragInputs.texCoord1, fragInputs.texCoord2, builtinData );
|
|
#endif
|
|
|
|
builtinData.depthOffset = 0.0;
|
|
|
|
#if (SHADERPASS == SHADERPASS_DISTORTION)
|
|
builtinData.distortion = surfaceDescription.Distortion;
|
|
builtinData.distortionBlur = surfaceDescription.DistortionBlur;
|
|
#else
|
|
builtinData.distortion = float2(0.0, 0.0);
|
|
builtinData.distortionBlur = 0.0;
|
|
#endif
|
|
|
|
PostInitBuiltinData(V, posInput, surfaceData, builtinData);
|
|
}
|
|
|
|
PackedVaryingsMeshToPS Vert(AttributesMesh inputMesh )
|
|
{
|
|
PackedVaryingsMeshToPS outputPackedVaryingsMeshToPS;
|
|
|
|
UNITY_SETUP_INSTANCE_ID( inputMesh );
|
|
UNITY_TRANSFER_INSTANCE_ID( inputMesh, outputPackedVaryingsMeshToPS );
|
|
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(outputPackedVaryingsMeshToPS);
|
|
|
|
OctaImpostorVertex( inputMesh.vertex, inputMesh.normal, outputPackedVaryingsMeshToPS.UVsFrame117, outputPackedVaryingsMeshToPS.UVsFrame217, outputPackedVaryingsMeshToPS.UVsFrame317, outputPackedVaryingsMeshToPS.octaframe17, outputPackedVaryingsMeshToPS.viewPos17 );
|
|
|
|
inputMesh.vertex.xyz += float3( 0, 0, 0 ) ;
|
|
|
|
float3 positionRWS = TransformObjectToWorld(inputMesh.vertex.xyz);
|
|
outputPackedVaryingsMeshToPS.positionCS = TransformWorldToHClip(positionRWS);
|
|
outputPackedVaryingsMeshToPS.interp00.xyz = positionRWS;
|
|
return outputPackedVaryingsMeshToPS;
|
|
}
|
|
|
|
void Frag( PackedVaryingsMeshToPS packedInput
|
|
#ifdef WRITE_NORMAL_BUFFER
|
|
, out float4 outNormalBuffer : SV_Target0
|
|
#ifdef WRITE_MSAA_DEPTH
|
|
, out float1 depthColor : SV_Target1
|
|
#endif
|
|
#endif
|
|
, out float outputDepth : SV_Depth
|
|
|
|
)
|
|
{
|
|
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX( packedInput );
|
|
UNITY_SETUP_INSTANCE_ID( packedInput );
|
|
|
|
#ifdef LOD_FADE_CROSSFADE
|
|
float3 VC = GetWorldSpaceNormalizeViewDir(packedInput.interp00.xyz);
|
|
LODDitheringTransition(ComputeFadeMaskSeed(VC, packedInput.positionCS.xy), unity_LODFade.x);
|
|
#endif
|
|
|
|
FragInputs input;
|
|
|
|
ZERO_INITIALIZE(FragInputs, input);
|
|
AlphaSurfaceDescription surfaceDescription = (AlphaSurfaceDescription)0;
|
|
SurfaceOutput o = (SurfaceOutput)0;
|
|
|
|
o.Normal = float3( 0, 0, 1 );
|
|
float4 clipPos = 0;
|
|
float3 worldPos = 0;
|
|
|
|
float4 output0 = 0;
|
|
OctaImpostorFragment( o, clipPos, worldPos, packedInput.UVsFrame117, packedInput.UVsFrame217, packedInput.UVsFrame317, packedInput.octaframe17, packedInput.viewPos17, output0 );
|
|
|
|
|
|
surfaceDescription.Alpha = o.Alpha;
|
|
|
|
#ifdef _ALPHATEST_ON
|
|
surfaceDescription.AlphaClipThreshold = 0;
|
|
#endif
|
|
|
|
packedInput.positionCS.zw = clipPos.zw;
|
|
float3 positionRWS = worldPos;
|
|
|
|
input.positionSS = packedInput.positionCS;
|
|
input.positionRWS = positionRWS;
|
|
//#if defined( ASE_SRP_VERSION ) && ASE_SRP_VERSION < 60900
|
|
//input.worldToTangent = k_identity3x3;
|
|
//#else
|
|
input.tangentToWorld = k_identity3x3;
|
|
//#endif
|
|
|
|
PositionInputs posInput = GetPositionInput( input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS );
|
|
|
|
SurfaceData surfaceData;
|
|
BuiltinData builtinData;
|
|
|
|
float3 normalizedWorldViewDir = GetWorldSpaceNormalizeViewDir( input.positionRWS );
|
|
|
|
GetSurfaceAndBuiltinData(surfaceDescription, input, normalizedWorldViewDir, posInput, surfaceData, builtinData);
|
|
|
|
outputDepth = posInput.deviceDepth;
|
|
|
|
#ifdef WRITE_NORMAL_BUFFER
|
|
EncodeIntoNormalBuffer(ConvertSurfaceDataToNormalData(surfaceData), posInput.positionSS, outNormalBuffer);
|
|
#ifdef WRITE_MSAA_DEPTH
|
|
depthColor = packedInput.positionCS.z;
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
ENDHLSL
|
|
}
|
|
|
|
|
|
Pass
|
|
{
|
|
|
|
Name "DepthOnly"
|
|
Tags { "LightMode"="DepthOnly" }
|
|
|
|
HLSLPROGRAM
|
|
#define _DECALS 1
|
|
#define _MATERIAL_FEATURE_SPECULAR_COLOR 1
|
|
#define _ENERGY_CONSERVING_SPECULAR 1
|
|
#define _AMBIENT_OCCLUSION 1
|
|
#define ASE_SRP_VERSION 120112
|
|
#ifdef UNITY_COLORSPACE_GAMMA//AI_SRP
|
|
#define unity_ColorSpaceDielectricSpec half4(0.220916301, 0.220916301, 0.220916301, 1.0 - 0.220916301)//AI_SRP
|
|
#else//AI_SRP
|
|
#define unity_ColorSpaceDielectricSpec half4(0.04, 0.04, 0.04, 1.0 - 0.04) //AI_SRP
|
|
#endif//AI_SRP
|
|
|
|
#pragma vertex Vert
|
|
#pragma fragment Frag
|
|
|
|
#if defined(_MATERIAL_FEATURE_SUBSURFACE_SCATTERING) && !defined(_SURFACE_TYPE_TRANSPARENT)
|
|
#define OUTPUT_SPLIT_LIGHTING
|
|
#endif
|
|
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
|
|
//#if defined( ASE_SRP_VERSION ) && ASE_SRP_VERSION < 60900
|
|
//#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Wind.hlsl"
|
|
//#endif
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/NormalSurfaceGradient.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/FragInputs.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl"
|
|
|
|
#define SHADERPASS SHADERPASS_DEPTH_ONLY
|
|
#pragma multi_compile _ WRITE_NORMAL_BUFFER
|
|
#pragma multi_compile _ WRITE_MSAA_DEPTH
|
|
|
|
#define VARYINGS_NEED_POSITION_WS
|
|
#define VARYINGS_NEED_TANGENT_TO_WORLD
|
|
#define VARYINGS_NEED_TEXCOORD0
|
|
#define VARYINGS_NEED_TEXCOORD1
|
|
#define VARYINGS_NEED_TEXCOORD2
|
|
#define VARYINGS_NEED_TEXCOORD3
|
|
#define VARYINGS_NEED_COLOR
|
|
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinUtilities.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialUtilities.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalUtilities.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDecalData.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphFunctions.hlsl"
|
|
|
|
//#if defined( ASE_SRP_VERSION ) && ASE_SRP_VERSION < 60900
|
|
//#define T2W(var, index) var.worldToTangent[index]
|
|
//#else
|
|
#define T2W(var, index) var.tangentToWorld[index]
|
|
//#endif
|
|
|
|
#define ai_ObjectToWorld GetObjectToWorldMatrix()
|
|
#define ai_WorldToObject GetWorldToObjectMatrix()
|
|
#define AI_INV_TWO_PI INV_TWO_PI
|
|
#define AI_PI PI
|
|
#define AI_INV_PI INV_PI
|
|
|
|
|
|
struct AttributesMesh
|
|
{
|
|
float4 vertex : POSITION;
|
|
float3 normal : NORMAL;
|
|
float4 tangent : TANGENT;
|
|
float4 texcoord : TEXCOORD0;
|
|
float4 uv1 : TEXCOORD1;
|
|
float4 uv2 : TEXCOORD2;
|
|
float4 uv3 : TEXCOORD3;
|
|
float4 color : COLOR;
|
|
|
|
UNITY_VERTEX_INPUT_INSTANCE_ID
|
|
};
|
|
|
|
struct PackedVaryingsMeshToPS
|
|
{
|
|
float4 positionCS : SV_Position;
|
|
float3 interp00 : TEXCOORD0;
|
|
float3 interp01 : TEXCOORD1;
|
|
float4 interp02 : TEXCOORD2;
|
|
float4 interp03 : TEXCOORD3;
|
|
float4 interp04 : TEXCOORD4;
|
|
float4 interp05 : TEXCOORD5;
|
|
float4 interp06 : TEXCOORD6;
|
|
float4 interp07 : TEXCOORD7;
|
|
float4 UVsFrame117 : TEXCOORD8;
|
|
float4 UVsFrame217 : TEXCOORD9;
|
|
float4 UVsFrame317 : TEXCOORD10;
|
|
float4 octaframe17 : TEXCOORD11;
|
|
float4 viewPos17 : TEXCOORD12;
|
|
UNITY_VERTEX_INPUT_INSTANCE_ID
|
|
UNITY_VERTEX_OUTPUT_STEREO
|
|
};
|
|
|
|
sampler2D _Albedo;
|
|
sampler2D _Normals;
|
|
sampler2D _Mask;
|
|
SAMPLER(sampler_Mask);
|
|
CBUFFER_START( UnityPerMaterial )
|
|
float4 _AI_SizeOffset;
|
|
float3 _AI_Offset;
|
|
float _AI_Frames;
|
|
float _AI_FramesX;
|
|
float _AI_FramesY;
|
|
float _AI_ImpostorSize;
|
|
float _AI_Parallax;
|
|
float _AI_TextureBias;
|
|
float _AI_DepthSize;
|
|
float _AI_ShadowBias;
|
|
float _AI_ShadowView;
|
|
float _AI_Clip;
|
|
CBUFFER_END
|
|
|
|
|
|
float2 VectortoOctahedron( float3 N )
|
|
{
|
|
N /= dot( 1.0, abs( N ) );
|
|
if( N.z <= 0 )
|
|
{
|
|
N.xy = ( 1 - abs( N.yx ) ) * ( N.xy >= 0 ? 1.0 : -1.0 );
|
|
}
|
|
return N.xy;
|
|
}
|
|
|
|
float3 OctahedronToVector( float2 Oct )
|
|
{
|
|
float3 N = float3( Oct, 1.0 - dot( 1.0, abs( Oct ) ) );
|
|
if(N.z< 0 )
|
|
{
|
|
N.xy = ( 1 - abs( N.yx) ) * (N.xy >= 0 ? 1.0 : -1.0 );
|
|
}
|
|
return normalize( N);
|
|
}
|
|
|
|
inline void RayPlaneIntersectionUV( float3 normal, float3 rayPosition, float3 rayDirection, inout float2 uvs, inout float3 localNormal )
|
|
{
|
|
float lDotN = dot( rayDirection, normal );
|
|
float p0l0DotN = dot( -rayPosition, normal );
|
|
float t = p0l0DotN / lDotN;
|
|
float3 p = rayDirection * t + rayPosition;
|
|
float3 upVector = float3( 0, 1, 0 );
|
|
float3 tangent = normalize( cross( upVector, normal ) + float3( -0.001, 0, 0 ) );
|
|
float3 bitangent = cross( tangent, normal );
|
|
float frameX = dot( p, tangent );
|
|
float frameZ = dot( p, bitangent );
|
|
uvs = -float2( frameX, frameZ );
|
|
if( t <= 0.0 )
|
|
uvs = 0;
|
|
float3x3 worldToLocal = float3x3( tangent, bitangent, normal );
|
|
localNormal = normalize( mul( worldToLocal, rayDirection ) );
|
|
}
|
|
|
|
inline void OctaImpostorVertex( inout float4 vertex, inout float3 normal, inout float4 uvsFrame1, inout float4 uvsFrame2, inout float4 uvsFrame3, inout float4 octaFrame, inout float4 viewPos )
|
|
{
|
|
float2 uvOffset = _AI_SizeOffset.zw;
|
|
float parallax = -_AI_Parallax;
|
|
float UVscale = _AI_ImpostorSize;
|
|
float framesXY = _AI_Frames;
|
|
float prevFrame = framesXY - 1;
|
|
float3 fractions = 1.0 / float3( framesXY, prevFrame, UVscale );
|
|
float fractionsFrame = fractions.x;
|
|
float fractionsPrevFrame = fractions.y;
|
|
float fractionsUVscale = fractions.z;
|
|
float3 worldOrigin = 0;
|
|
float4 perspective = float4( 0, 0, 0, 1 );
|
|
if( UNITY_MATRIX_P[ 3 ][ 3 ] == 1 )
|
|
{
|
|
perspective = float4( 0, 0, 5000, 0 );
|
|
worldOrigin = ai_ObjectToWorld._m03_m13_m23;
|
|
}
|
|
float3 worldCameraPos = worldOrigin + mul( UNITY_MATRIX_I_V, perspective ).xyz;
|
|
float3 objectCameraPosition = mul( ai_WorldToObject, float4( worldCameraPos, 1 ) ).xyz - _AI_Offset.xyz;
|
|
float3 objectCameraDirection = normalize( objectCameraPosition );
|
|
float3 upVector = float3( 0,1,0 );
|
|
float3 objectHorizontalVector = normalize( cross( objectCameraDirection, upVector ) );
|
|
float3 objectVerticalVector = cross( objectHorizontalVector, objectCameraDirection );
|
|
float2 uvExpansion = vertex.xy;
|
|
float3 billboard = objectHorizontalVector * uvExpansion.x + objectVerticalVector * uvExpansion.y;
|
|
float3 localDir = billboard - objectCameraPosition;
|
|
float2 frameOcta = VectortoOctahedron( objectCameraDirection.xzy ) * 0.5 + 0.5;
|
|
float2 prevOctaFrame = frameOcta * prevFrame;
|
|
float2 baseOctaFrame = floor( prevOctaFrame );
|
|
float2 fractionOctaFrame = ( baseOctaFrame * fractionsFrame );
|
|
float2 octaFrame1 = ( baseOctaFrame * fractionsPrevFrame ) * 2.0 - 1.0;
|
|
float3 octa1WorldY = OctahedronToVector( octaFrame1 ).xzy;
|
|
float3 octa1LocalY;
|
|
float2 uvFrame1;
|
|
RayPlaneIntersectionUV( octa1WorldY, objectCameraPosition, localDir, /*inout*/ uvFrame1, /*inout*/ octa1LocalY );
|
|
float2 uvParallax1 = octa1LocalY.xy * fractionsFrame * parallax;
|
|
uvFrame1 = ( uvFrame1 * fractionsUVscale + 0.5 ) * fractionsFrame + fractionOctaFrame;
|
|
uvsFrame1 = float4( uvParallax1, uvFrame1) - float4( 0, 0, uvOffset );
|
|
float2 fractPrevOctaFrame = frac( prevOctaFrame );
|
|
float2 cornerDifference = lerp( float2( 0,1 ) , float2( 1,0 ) , saturate( ceil( ( fractPrevOctaFrame.x - fractPrevOctaFrame.y ) ) ));
|
|
float2 octaFrame2 = ( ( baseOctaFrame + cornerDifference ) * fractionsPrevFrame ) * 2.0 - 1.0;
|
|
float3 octa2WorldY = OctahedronToVector( octaFrame2 ).xzy;
|
|
float3 octa2LocalY;
|
|
float2 uvFrame2;
|
|
RayPlaneIntersectionUV( octa2WorldY, objectCameraPosition, localDir, /*inout*/ uvFrame2, /*inout*/ octa2LocalY );
|
|
float2 uvParallax2 = octa2LocalY.xy * fractionsFrame * parallax;
|
|
uvFrame2 = ( uvFrame2 * fractionsUVscale + 0.5 ) * fractionsFrame + ( ( cornerDifference * fractionsFrame ) + fractionOctaFrame );
|
|
uvsFrame2 = float4( uvParallax2, uvFrame2) - float4( 0, 0, uvOffset );
|
|
float2 octaFrame3 = ( ( baseOctaFrame + 1 ) * fractionsPrevFrame ) * 2.0 - 1.0;
|
|
float3 octa3WorldY = OctahedronToVector( octaFrame3 ).xzy;
|
|
float3 octa3LocalY;
|
|
float2 uvFrame3;
|
|
RayPlaneIntersectionUV( octa3WorldY, objectCameraPosition, localDir, /*inout*/ uvFrame3, /*inout*/ octa3LocalY );
|
|
float2 uvParallax3 = octa3LocalY.xy * fractionsFrame * parallax;
|
|
uvFrame3 = ( uvFrame3 * fractionsUVscale + 0.5 ) * fractionsFrame + ( fractionOctaFrame + fractionsFrame );
|
|
uvsFrame3 = float4( uvParallax3, uvFrame3) - float4( 0, 0, uvOffset );
|
|
octaFrame = 0;
|
|
octaFrame.xy = prevOctaFrame;
|
|
vertex.xyz = billboard + _AI_Offset.xyz;
|
|
normal.xyz = objectCameraDirection;
|
|
viewPos = 0;
|
|
viewPos.xyz = TransformWorldToView( TransformObjectToWorld( vertex.xyz ) );
|
|
}
|
|
|
|
inline void OctaImpostorFragment( inout SurfaceOutput o, out float4 clipPos, out float3 worldPos, float4 uvsFrame1, float4 uvsFrame2, float4 uvsFrame3, float4 octaFrame, float4 interpViewPos, out float4 output0 )
|
|
{
|
|
float depthBias = -1.0;
|
|
float textureBias = _AI_TextureBias;
|
|
float2 fraction = frac( octaFrame.xy );
|
|
float2 invFraction = 1 - fraction;
|
|
float3 weights;
|
|
weights.x = min( invFraction.x, invFraction.y );
|
|
weights.y = abs( fraction.x - fraction.y );
|
|
weights.z = min( fraction.x, fraction.y );
|
|
float4 parallaxSample1 = tex2Dbias( _Normals, float4(uvsFrame1.zw, 0, depthBias) );
|
|
float2 parallax1 = ( ( 0.5 - parallaxSample1.a ) * uvsFrame1.xy ) + uvsFrame1.zw;
|
|
float4 parallaxSample2 = tex2Dbias( _Normals, float4(uvsFrame2.zw, 0, depthBias) );
|
|
float2 parallax2 = ( ( 0.5 - parallaxSample2.a ) * uvsFrame2.xy ) + uvsFrame2.zw;
|
|
float4 parallaxSample3 = tex2Dbias( _Normals, float4(uvsFrame3.zw, 0, depthBias) );
|
|
float2 parallax3 = ( ( 0.5 - parallaxSample3.a ) * uvsFrame3.xy ) + uvsFrame3.zw;
|
|
float4 albedo1 = tex2Dbias( _Albedo, float4(parallax1, 0, textureBias) );
|
|
float4 albedo2 = tex2Dbias( _Albedo, float4(parallax2, 0, textureBias) );
|
|
float4 albedo3 = tex2Dbias( _Albedo, float4(parallax3, 0, textureBias) );
|
|
float4 blendedAlbedo = albedo1 * weights.x + albedo2 * weights.y + albedo3 * weights.z;
|
|
o.Alpha = ( blendedAlbedo.a - _AI_Clip );
|
|
clip( o.Alpha );
|
|
o.Albedo = blendedAlbedo.rgb;
|
|
#if defined(AI_HD_RENDERPIPELINE)
|
|
float4 feat1 = _Features.SampleLevel( SamplerState_Point_Repeat, parallax1, 0);
|
|
o.Diffusion = feat1.rgb;
|
|
o.Features = feat1.a;
|
|
float4 test1 = _Specular.SampleLevel( SamplerState_Point_Repeat, parallax1, 0);
|
|
o.MetalTangent = test1.b;
|
|
#endif
|
|
float4 normals1 = tex2Dbias( _Normals, float4(parallax1, 0, textureBias) );
|
|
float4 normals2 = tex2Dbias( _Normals, float4(parallax2, 0, textureBias) );
|
|
float4 normals3 = tex2Dbias( _Normals, float4(parallax3, 0, textureBias) );
|
|
float4 blendedNormal = normals1 * weights.x + normals2 * weights.y + normals3 * weights.z;
|
|
float4 output0a = tex2Dbias( _Mask, float4(parallax1, 0, textureBias) );
|
|
float4 output0b = tex2Dbias( _Mask, float4(parallax2, 0, textureBias) );
|
|
float4 output0c = tex2Dbias( _Mask, float4(parallax3, 0, textureBias) );
|
|
output0 = output0a * weights.x + output0b * weights.y + output0c * weights.z;
|
|
float3 localNormal = blendedNormal.rgb * 2.0 - 1.0;
|
|
float3 worldNormal = normalize( mul( (float3x3)ai_ObjectToWorld, localNormal ) );
|
|
o.Normal = worldNormal;
|
|
float3 viewPos = interpViewPos.xyz;
|
|
#if ( defined(SHADERPASS) && (defined(SHADERPASS_DEPTHNORMALSONLY) && SHADERPASS == SHADERPASS_DEPTHNORMALSONLY) ) || defined(UNITY_PASS_SHADOWCASTER)
|
|
float depthOffset = ( ( parallaxSample1.a * weights.x + parallaxSample2.a * weights.y + parallaxSample3.a * weights.z ) - 0.5001 /** 2.0 - 1.0*/ ) /** 0.5*/ * _AI_DepthSize * length( ai_ObjectToWorld[ 2 ].xyz );
|
|
#else
|
|
float depthOffset = ( ( parallaxSample1.a * weights.x + parallaxSample2.a * weights.y + parallaxSample3.a * weights.z ) - 0.5 /** 2.0 - 1.0*/ ) /** 0.5*/ * _AI_DepthSize * length( ai_ObjectToWorld[ 2 ].xyz );
|
|
#endif
|
|
#if ( defined(SHADERPASS) && ((defined(SHADERPASS_SHADOWS) && SHADERPASS == SHADERPASS_SHADOWS) || (defined(SHADERPASS_SHADOWCASTER) && SHADERPASS == SHADERPASS_SHADOWCASTER)) ) || defined(UNITY_PASS_SHADOWCASTER)
|
|
viewPos.z += depthOffset * _AI_ShadowView;
|
|
viewPos.z += -_AI_ShadowBias;
|
|
#else
|
|
viewPos.z += depthOffset;
|
|
#endif
|
|
worldPos = mul( UNITY_MATRIX_I_V, float4( viewPos.xyz, 1 ) ).xyz;
|
|
clipPos = mul( UNITY_MATRIX_P, float4( viewPos, 1 ) );
|
|
#if defined(UNITY_PASS_SHADOWCASTER) && !defined(SHADERPASS)
|
|
#if UNITY_REVERSED_Z
|
|
clipPos.z = min( clipPos.z, clipPos.w * UNITY_NEAR_CLIP_VALUE );
|
|
#else
|
|
clipPos.z = max( clipPos.z, clipPos.w * UNITY_NEAR_CLIP_VALUE );
|
|
#endif
|
|
#endif
|
|
clipPos.xyz /= clipPos.w;
|
|
if( UNITY_NEAR_CLIP_VALUE < 0 )
|
|
clipPos = clipPos * 0.5 + 0.5;
|
|
}
|
|
|
|
|
|
void BuildSurfaceData(FragInputs fragInputs, inout SmoothSurfaceDescription surfaceDescription, float3 V, out SurfaceData surfaceData, out float3 bentNormalWS)
|
|
{
|
|
ZERO_INITIALIZE(SurfaceData, surfaceData);
|
|
surfaceData.perceptualSmoothness = surfaceDescription.Smoothness;
|
|
|
|
surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD;
|
|
#ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING;
|
|
#endif
|
|
#ifdef _MATERIAL_FEATURE_TRANSMISSION
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION;
|
|
#endif
|
|
#ifdef _MATERIAL_FEATURE_ANISOTROPY
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_ANISOTROPY;
|
|
#endif
|
|
|
|
#ifdef _MATERIAL_FEATURE_IRIDESCENCE
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_IRIDESCENCE;
|
|
#endif
|
|
#ifdef _MATERIAL_FEATURE_SPECULAR_COLOR
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR;
|
|
#endif
|
|
|
|
#if defined (_MATERIAL_FEATURE_SPECULAR_COLOR) && defined (_ENERGY_CONSERVING_SPECULAR)
|
|
surfaceData.baseColor *= (1.0 - Max3(surfaceData.specularColor.r, surfaceData.specularColor.g, surfaceData.specularColor.b));
|
|
#endif
|
|
|
|
GetNormalWS( fragInputs, float3( 0.0, 0.0, 1.0 ), surfaceData.normalWS, float3( 1.0, 1.0, 1.0 ) );
|
|
bentNormalWS = surfaceData.normalWS;
|
|
|
|
surfaceData.geomNormalWS = T2W(fragInputs, 2);
|
|
|
|
#ifdef _HAS_REFRACTION
|
|
surfaceData.transmittanceMask = 1.0 - surfaceDescription.Alpha;
|
|
surfaceDescription.Alpha = 1.0;
|
|
#endif
|
|
|
|
surfaceData.tangentWS = normalize(T2W(fragInputs, 0).xyz); // The tangent is not normalize in worldToTangent for mikkt. TODO: Check if it expected that we normalize with Morten. Tag: SURFACE_GRADIENT
|
|
surfaceData.tangentWS = Orthonormalize(surfaceData.tangentWS, surfaceData.normalWS);
|
|
|
|
#if defined(_SPECULAR_OCCLUSION_CUSTOM)
|
|
#elif defined(_SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL)
|
|
surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO(V, bentNormalWS, surfaceData.normalWS, surfaceData.ambientOcclusion, PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness));
|
|
#elif defined(_AMBIENT_OCCLUSION) && defined(_SPECULAR_OCCLUSION_FROM_AO)
|
|
surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(dot(surfaceData.normalWS, V)), surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness));
|
|
#else
|
|
surfaceData.specularOcclusion = 1.0;
|
|
#endif
|
|
#ifdef _ENABLE_GEOMETRIC_SPECULAR_AA
|
|
surfaceData.perceptualSmoothness = GeometricNormalFiltering(surfaceData.perceptualSmoothness, T2W(fragInputs, 2), surfaceDescription.SpecularAAScreenSpaceVariance, surfaceDescription.SpecularAAThreshold);
|
|
#endif
|
|
}
|
|
|
|
void GetSurfaceAndBuiltinData(SmoothSurfaceDescription surfaceDescription, FragInputs fragInputs, float3 V, inout PositionInputs posInput, out SurfaceData surfaceData, out BuiltinData builtinData)
|
|
{
|
|
//#ifdef LOD_FADE_CROSSFADE
|
|
// uint3 fadeMaskSeed = asuint((int3)(V * _ScreenSize.xyx));
|
|
// LODDitheringTransition(fadeMaskSeed, unity_LODFade.x);
|
|
//#endif
|
|
|
|
#ifdef _ALPHATEST_ON
|
|
DoAlphaTest ( surfaceDescription.Alpha, surfaceDescription.AlphaClipThreshold );
|
|
#endif
|
|
|
|
float3 bentNormalWS;
|
|
BuildSurfaceData(fragInputs, surfaceDescription, V, surfaceData, bentNormalWS);
|
|
|
|
#if HAVE_DECALS
|
|
if( _EnableDecals )
|
|
{
|
|
DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, surfaceDescription.Alpha);
|
|
ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData);
|
|
}
|
|
#endif
|
|
|
|
#if defined( ASE_SRP_VERSION ) && ASE_SRP_VERSION <= 50702
|
|
InitBuiltinData( surfaceDescription.Alpha, bentNormalWS, -T2W(fragInputs, 2), fragInputs.positionRWS, fragInputs.texCoord1, fragInputs.texCoord2, builtinData );
|
|
#else
|
|
InitBuiltinData( posInput, surfaceDescription.Alpha, bentNormalWS, -T2W(fragInputs, 2), fragInputs.texCoord1, fragInputs.texCoord2, builtinData );
|
|
#endif
|
|
|
|
builtinData.depthOffset = 0.0;
|
|
|
|
#if (SHADERPASS == SHADERPASS_DISTORTION)
|
|
builtinData.distortion = surfaceDescription.Distortion;
|
|
builtinData.distortionBlur = surfaceDescription.DistortionBlur;
|
|
#else
|
|
builtinData.distortion = float2(0.0, 0.0);
|
|
builtinData.distortionBlur = 0.0;
|
|
#endif
|
|
|
|
PostInitBuiltinData(V, posInput, surfaceData, builtinData);
|
|
}
|
|
|
|
PackedVaryingsMeshToPS Vert(AttributesMesh inputMesh )
|
|
{
|
|
PackedVaryingsMeshToPS outputPackedVaryingsMeshToPS;
|
|
|
|
UNITY_SETUP_INSTANCE_ID( inputMesh );
|
|
UNITY_TRANSFER_INSTANCE_ID( inputMesh, outputPackedVaryingsMeshToPS );
|
|
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO( outputPackedVaryingsMeshToPS );
|
|
|
|
OctaImpostorVertex( inputMesh.vertex, inputMesh.normal, outputPackedVaryingsMeshToPS.UVsFrame117, outputPackedVaryingsMeshToPS.UVsFrame217, outputPackedVaryingsMeshToPS.UVsFrame317, outputPackedVaryingsMeshToPS.octaframe17, outputPackedVaryingsMeshToPS.viewPos17 );
|
|
|
|
inputMesh.vertex.xyz += float3( 0, 0, 0 ) ;
|
|
|
|
float3 positionRWS = TransformObjectToWorld( inputMesh.vertex.xyz );
|
|
float3 normalWS = TransformObjectToWorldNormal(inputMesh.normal);
|
|
float4 tangentWS = float4(TransformObjectToWorldDir(inputMesh.tangent.xyz), inputMesh.tangent.w);
|
|
|
|
outputPackedVaryingsMeshToPS.positionCS = TransformWorldToHClip(positionRWS);
|
|
outputPackedVaryingsMeshToPS.interp00.xyz = positionRWS;
|
|
outputPackedVaryingsMeshToPS.interp01.xyz = normalWS;
|
|
outputPackedVaryingsMeshToPS.interp02.xyzw = tangentWS;
|
|
outputPackedVaryingsMeshToPS.interp03.xyzw = inputMesh.texcoord;
|
|
outputPackedVaryingsMeshToPS.interp04.xyzw = inputMesh.uv1;
|
|
outputPackedVaryingsMeshToPS.interp05.xyzw = inputMesh.uv2;
|
|
outputPackedVaryingsMeshToPS.interp06.xyzw = inputMesh.uv3;
|
|
outputPackedVaryingsMeshToPS.interp07.xyzw = inputMesh.color;
|
|
|
|
return outputPackedVaryingsMeshToPS;
|
|
}
|
|
|
|
void Frag( PackedVaryingsMeshToPS packedInput
|
|
#ifdef WRITE_NORMAL_BUFFER
|
|
, out float4 outNormalBuffer : SV_Target0
|
|
#ifdef WRITE_MSAA_DEPTH
|
|
, out float1 depthColor : SV_Target1
|
|
#endif
|
|
#endif
|
|
, out float outputDepth : SV_Depth
|
|
|
|
)
|
|
{
|
|
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX( packedInput );
|
|
UNITY_SETUP_INSTANCE_ID( packedInput );
|
|
|
|
#ifdef LOD_FADE_CROSSFADE
|
|
float3 VC = GetWorldSpaceNormalizeViewDir(packedInput.interp00.xyz);
|
|
LODDitheringTransition(ComputeFadeMaskSeed(VC, packedInput.positionCS.xy), unity_LODFade.x);
|
|
#endif
|
|
|
|
FragInputs input;
|
|
|
|
ZERO_INITIALIZE(FragInputs, input);
|
|
SmoothSurfaceDescription surfaceDescription = (SmoothSurfaceDescription)0;
|
|
SurfaceOutput o = (SurfaceOutput)0;
|
|
|
|
o.Normal = float3( 0, 0, 1 );
|
|
float4 clipPos = 0;
|
|
float3 worldPos = 0;
|
|
|
|
float4 output0 = 0;
|
|
OctaImpostorFragment( o, clipPos, worldPos, packedInput.UVsFrame117, packedInput.UVsFrame217, packedInput.UVsFrame317, packedInput.octaframe17, packedInput.viewPos17, output0 );
|
|
float4 break38 = output0;
|
|
|
|
surfaceDescription.Smoothness = break38.y;
|
|
surfaceDescription.Alpha = o.Alpha;
|
|
|
|
#ifdef _ALPHATEST_ON
|
|
surfaceDescription.AlphaClipThreshold = 0;
|
|
#endif
|
|
|
|
packedInput.positionCS.zw = clipPos.zw;
|
|
float3 positionRWS = worldPos;
|
|
float3 normalWS = o.Normal;
|
|
float4 tangentWS = packedInput.interp02.xyzw;
|
|
float4 texCoord0 = packedInput.interp03.xyzw;
|
|
float4 texCoord1 = packedInput.interp04.xyzw;
|
|
float4 texCoord2 = packedInput.interp05.xyzw;
|
|
float4 texCoord3 = packedInput.interp06.xyzw;
|
|
float4 vertexColor = packedInput.interp07.xyzw;
|
|
|
|
input.positionSS = packedInput.positionCS;
|
|
input.positionRWS = positionRWS;
|
|
//#if defined( ASE_SRP_VERSION ) && ASE_SRP_VERSION < 60900
|
|
//input.worldToTangent = BuildWorldToTangent( tangentWS, normalWS );
|
|
//#else
|
|
input.tangentToWorld = BuildTangentToWorld( tangentWS, normalWS );
|
|
//#endif
|
|
input.texCoord0 = texCoord0;
|
|
input.texCoord1 = texCoord1;
|
|
input.texCoord2 = texCoord2;
|
|
input.texCoord3 = texCoord3;
|
|
input.color = vertexColor;
|
|
|
|
PositionInputs posInput = GetPositionInput( input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS );
|
|
|
|
float3 normalizedWorldViewDir = GetWorldSpaceNormalizeViewDir( input.positionRWS );
|
|
|
|
SurfaceData surfaceData;
|
|
BuiltinData builtinData;
|
|
|
|
GetSurfaceAndBuiltinData(surfaceDescription, input, normalizedWorldViewDir, posInput, surfaceData, builtinData);
|
|
|
|
outputDepth = posInput.deviceDepth;
|
|
|
|
#ifdef WRITE_NORMAL_BUFFER
|
|
EncodeIntoNormalBuffer(ConvertSurfaceDataToNormalData(surfaceData), posInput.positionSS, outNormalBuffer);
|
|
#ifdef WRITE_MSAA_DEPTH
|
|
depthColor = packedInput.positionCS.z;
|
|
#endif
|
|
#endif
|
|
}
|
|
ENDHLSL
|
|
}
|
|
|
|
|
|
Pass
|
|
{
|
|
|
|
Name "Motion Vectors"
|
|
Tags { "LightMode"="MotionVectors" }
|
|
Stencil
|
|
{
|
|
Ref 40
|
|
WriteMask 40
|
|
Comp Always
|
|
Pass Replace
|
|
}
|
|
|
|
|
|
HLSLPROGRAM
|
|
#define _DECALS 1
|
|
#define _MATERIAL_FEATURE_SPECULAR_COLOR 1
|
|
#define _ENERGY_CONSERVING_SPECULAR 1
|
|
#define _AMBIENT_OCCLUSION 1
|
|
#define ASE_SRP_VERSION 120112
|
|
#ifdef UNITY_COLORSPACE_GAMMA//AI_SRP
|
|
#define unity_ColorSpaceDielectricSpec half4(0.220916301, 0.220916301, 0.220916301, 1.0 - 0.220916301)//AI_SRP
|
|
#else//AI_SRP
|
|
#define unity_ColorSpaceDielectricSpec half4(0.04, 0.04, 0.04, 1.0 - 0.04) //AI_SRP
|
|
#endif//AI_SRP
|
|
|
|
#pragma vertex Vert
|
|
#pragma fragment Frag
|
|
|
|
#if defined(_MATERIAL_FEATURE_SUBSURFACE_SCATTERING) && !defined(_SURFACE_TYPE_TRANSPARENT)
|
|
#define OUTPUT_SPLIT_LIGHTING
|
|
#endif
|
|
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
|
|
//#if defined( ASE_SRP_VERSION ) && ASE_SRP_VERSION < 60900
|
|
//#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Wind.hlsl"
|
|
//#endif
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/NormalSurfaceGradient.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/FragInputs.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl"
|
|
|
|
#define SHADERPASS SHADERPASS_VELOCITY
|
|
#pragma multi_compile _ WRITE_NORMAL_BUFFER
|
|
#pragma multi_compile _ WRITE_MSAA_DEPTH
|
|
|
|
#define VARYINGS_NEED_POSITION_WS
|
|
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinUtilities.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialUtilities.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalUtilities.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDecalData.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphFunctions.hlsl"
|
|
|
|
//#if defined( ASE_SRP_VERSION ) && ASE_SRP_VERSION < 60900
|
|
//#define T2W(var, index) var.worldToTangent[index]
|
|
//#else
|
|
#define T2W(var, index) var.tangentToWorld[index]
|
|
//#endif
|
|
|
|
#define ai_ObjectToWorld GetObjectToWorldMatrix()
|
|
#define ai_WorldToObject GetWorldToObjectMatrix()
|
|
#define AI_INV_TWO_PI INV_TWO_PI
|
|
#define AI_PI PI
|
|
#define AI_INV_PI INV_PI
|
|
|
|
|
|
struct AttributesMesh
|
|
{
|
|
float4 vertex : POSITION;
|
|
float3 normal : NORMAL;
|
|
float4 texcoord : TEXCOORD0;
|
|
|
|
UNITY_VERTEX_INPUT_INSTANCE_ID
|
|
};
|
|
|
|
struct VaryingsMeshToPS
|
|
{
|
|
float4 positionCS : SV_Position;
|
|
float3 positionRWS;
|
|
UNITY_VERTEX_INPUT_INSTANCE_ID
|
|
UNITY_VERTEX_OUTPUT_STEREO
|
|
};
|
|
|
|
struct AttributesPass
|
|
{
|
|
float3 previousPositionOS : TEXCOORD4;
|
|
};
|
|
|
|
struct VaryingsPassToPS
|
|
{
|
|
float4 positionCS;
|
|
float4 previousPositionCS;
|
|
};
|
|
|
|
#define VARYINGS_NEED_PASS
|
|
struct VaryingsToPS
|
|
{
|
|
VaryingsMeshToPS vmesh;
|
|
VaryingsPassToPS vpass;
|
|
};
|
|
|
|
struct PackedVaryingsToPS
|
|
{
|
|
float4 vmeshPositionCS : SV_Position;
|
|
float3 vmeshInterp00 : TEXCOORD0;
|
|
float3 vpassInterpolators0 : TEXCOORD1;
|
|
float3 vpassInterpolators1 : TEXCOORD2;
|
|
float4 UVsFrame117 : TEXCOORD3;
|
|
float4 UVsFrame217 : TEXCOORD4;
|
|
float4 UVsFrame317 : TEXCOORD5;
|
|
float4 octaframe17 : TEXCOORD6;
|
|
float4 viewPos17 : TEXCOORD7;
|
|
UNITY_VERTEX_INPUT_INSTANCE_ID
|
|
UNITY_VERTEX_OUTPUT_STEREO
|
|
};
|
|
|
|
sampler2D _Albedo;
|
|
sampler2D _Normals;
|
|
sampler2D _Mask;
|
|
SAMPLER(sampler_Mask);
|
|
CBUFFER_START( UnityPerMaterial )
|
|
float4 _AI_SizeOffset;
|
|
float3 _AI_Offset;
|
|
float _AI_Frames;
|
|
float _AI_FramesX;
|
|
float _AI_FramesY;
|
|
float _AI_ImpostorSize;
|
|
float _AI_Parallax;
|
|
float _AI_TextureBias;
|
|
float _AI_DepthSize;
|
|
float _AI_ShadowBias;
|
|
float _AI_ShadowView;
|
|
float _AI_Clip;
|
|
CBUFFER_END
|
|
|
|
|
|
float2 VectortoOctahedron( float3 N )
|
|
{
|
|
N /= dot( 1.0, abs( N ) );
|
|
if( N.z <= 0 )
|
|
{
|
|
N.xy = ( 1 - abs( N.yx ) ) * ( N.xy >= 0 ? 1.0 : -1.0 );
|
|
}
|
|
return N.xy;
|
|
}
|
|
|
|
float3 OctahedronToVector( float2 Oct )
|
|
{
|
|
float3 N = float3( Oct, 1.0 - dot( 1.0, abs( Oct ) ) );
|
|
if(N.z< 0 )
|
|
{
|
|
N.xy = ( 1 - abs( N.yx) ) * (N.xy >= 0 ? 1.0 : -1.0 );
|
|
}
|
|
return normalize( N);
|
|
}
|
|
|
|
inline void RayPlaneIntersectionUV( float3 normal, float3 rayPosition, float3 rayDirection, inout float2 uvs, inout float3 localNormal )
|
|
{
|
|
float lDotN = dot( rayDirection, normal );
|
|
float p0l0DotN = dot( -rayPosition, normal );
|
|
float t = p0l0DotN / lDotN;
|
|
float3 p = rayDirection * t + rayPosition;
|
|
float3 upVector = float3( 0, 1, 0 );
|
|
float3 tangent = normalize( cross( upVector, normal ) + float3( -0.001, 0, 0 ) );
|
|
float3 bitangent = cross( tangent, normal );
|
|
float frameX = dot( p, tangent );
|
|
float frameZ = dot( p, bitangent );
|
|
uvs = -float2( frameX, frameZ );
|
|
if( t <= 0.0 )
|
|
uvs = 0;
|
|
float3x3 worldToLocal = float3x3( tangent, bitangent, normal );
|
|
localNormal = normalize( mul( worldToLocal, rayDirection ) );
|
|
}
|
|
|
|
inline void OctaImpostorVertex( inout float4 vertex, inout float3 normal, inout float4 uvsFrame1, inout float4 uvsFrame2, inout float4 uvsFrame3, inout float4 octaFrame, inout float4 viewPos )
|
|
{
|
|
float2 uvOffset = _AI_SizeOffset.zw;
|
|
float parallax = -_AI_Parallax;
|
|
float UVscale = _AI_ImpostorSize;
|
|
float framesXY = _AI_Frames;
|
|
float prevFrame = framesXY - 1;
|
|
float3 fractions = 1.0 / float3( framesXY, prevFrame, UVscale );
|
|
float fractionsFrame = fractions.x;
|
|
float fractionsPrevFrame = fractions.y;
|
|
float fractionsUVscale = fractions.z;
|
|
float3 worldOrigin = 0;
|
|
float4 perspective = float4( 0, 0, 0, 1 );
|
|
if( UNITY_MATRIX_P[ 3 ][ 3 ] == 1 )
|
|
{
|
|
perspective = float4( 0, 0, 5000, 0 );
|
|
worldOrigin = ai_ObjectToWorld._m03_m13_m23;
|
|
}
|
|
float3 worldCameraPos = worldOrigin + mul( UNITY_MATRIX_I_V, perspective ).xyz;
|
|
float3 objectCameraPosition = mul( ai_WorldToObject, float4( worldCameraPos, 1 ) ).xyz - _AI_Offset.xyz;
|
|
float3 objectCameraDirection = normalize( objectCameraPosition );
|
|
float3 upVector = float3( 0,1,0 );
|
|
float3 objectHorizontalVector = normalize( cross( objectCameraDirection, upVector ) );
|
|
float3 objectVerticalVector = cross( objectHorizontalVector, objectCameraDirection );
|
|
float2 uvExpansion = vertex.xy;
|
|
float3 billboard = objectHorizontalVector * uvExpansion.x + objectVerticalVector * uvExpansion.y;
|
|
float3 localDir = billboard - objectCameraPosition;
|
|
float2 frameOcta = VectortoOctahedron( objectCameraDirection.xzy ) * 0.5 + 0.5;
|
|
float2 prevOctaFrame = frameOcta * prevFrame;
|
|
float2 baseOctaFrame = floor( prevOctaFrame );
|
|
float2 fractionOctaFrame = ( baseOctaFrame * fractionsFrame );
|
|
float2 octaFrame1 = ( baseOctaFrame * fractionsPrevFrame ) * 2.0 - 1.0;
|
|
float3 octa1WorldY = OctahedronToVector( octaFrame1 ).xzy;
|
|
float3 octa1LocalY;
|
|
float2 uvFrame1;
|
|
RayPlaneIntersectionUV( octa1WorldY, objectCameraPosition, localDir, /*inout*/ uvFrame1, /*inout*/ octa1LocalY );
|
|
float2 uvParallax1 = octa1LocalY.xy * fractionsFrame * parallax;
|
|
uvFrame1 = ( uvFrame1 * fractionsUVscale + 0.5 ) * fractionsFrame + fractionOctaFrame;
|
|
uvsFrame1 = float4( uvParallax1, uvFrame1) - float4( 0, 0, uvOffset );
|
|
float2 fractPrevOctaFrame = frac( prevOctaFrame );
|
|
float2 cornerDifference = lerp( float2( 0,1 ) , float2( 1,0 ) , saturate( ceil( ( fractPrevOctaFrame.x - fractPrevOctaFrame.y ) ) ));
|
|
float2 octaFrame2 = ( ( baseOctaFrame + cornerDifference ) * fractionsPrevFrame ) * 2.0 - 1.0;
|
|
float3 octa2WorldY = OctahedronToVector( octaFrame2 ).xzy;
|
|
float3 octa2LocalY;
|
|
float2 uvFrame2;
|
|
RayPlaneIntersectionUV( octa2WorldY, objectCameraPosition, localDir, /*inout*/ uvFrame2, /*inout*/ octa2LocalY );
|
|
float2 uvParallax2 = octa2LocalY.xy * fractionsFrame * parallax;
|
|
uvFrame2 = ( uvFrame2 * fractionsUVscale + 0.5 ) * fractionsFrame + ( ( cornerDifference * fractionsFrame ) + fractionOctaFrame );
|
|
uvsFrame2 = float4( uvParallax2, uvFrame2) - float4( 0, 0, uvOffset );
|
|
float2 octaFrame3 = ( ( baseOctaFrame + 1 ) * fractionsPrevFrame ) * 2.0 - 1.0;
|
|
float3 octa3WorldY = OctahedronToVector( octaFrame3 ).xzy;
|
|
float3 octa3LocalY;
|
|
float2 uvFrame3;
|
|
RayPlaneIntersectionUV( octa3WorldY, objectCameraPosition, localDir, /*inout*/ uvFrame3, /*inout*/ octa3LocalY );
|
|
float2 uvParallax3 = octa3LocalY.xy * fractionsFrame * parallax;
|
|
uvFrame3 = ( uvFrame3 * fractionsUVscale + 0.5 ) * fractionsFrame + ( fractionOctaFrame + fractionsFrame );
|
|
uvsFrame3 = float4( uvParallax3, uvFrame3) - float4( 0, 0, uvOffset );
|
|
octaFrame = 0;
|
|
octaFrame.xy = prevOctaFrame;
|
|
vertex.xyz = billboard + _AI_Offset.xyz;
|
|
normal.xyz = objectCameraDirection;
|
|
viewPos = 0;
|
|
viewPos.xyz = TransformWorldToView( TransformObjectToWorld( vertex.xyz ) );
|
|
}
|
|
|
|
inline void OctaImpostorFragment( inout SurfaceOutput o, out float4 clipPos, out float3 worldPos, float4 uvsFrame1, float4 uvsFrame2, float4 uvsFrame3, float4 octaFrame, float4 interpViewPos, out float4 output0 )
|
|
{
|
|
float depthBias = -1.0;
|
|
float textureBias = _AI_TextureBias;
|
|
float2 fraction = frac( octaFrame.xy );
|
|
float2 invFraction = 1 - fraction;
|
|
float3 weights;
|
|
weights.x = min( invFraction.x, invFraction.y );
|
|
weights.y = abs( fraction.x - fraction.y );
|
|
weights.z = min( fraction.x, fraction.y );
|
|
float4 parallaxSample1 = tex2Dbias( _Normals, float4(uvsFrame1.zw, 0, depthBias) );
|
|
float2 parallax1 = ( ( 0.5 - parallaxSample1.a ) * uvsFrame1.xy ) + uvsFrame1.zw;
|
|
float4 parallaxSample2 = tex2Dbias( _Normals, float4(uvsFrame2.zw, 0, depthBias) );
|
|
float2 parallax2 = ( ( 0.5 - parallaxSample2.a ) * uvsFrame2.xy ) + uvsFrame2.zw;
|
|
float4 parallaxSample3 = tex2Dbias( _Normals, float4(uvsFrame3.zw, 0, depthBias) );
|
|
float2 parallax3 = ( ( 0.5 - parallaxSample3.a ) * uvsFrame3.xy ) + uvsFrame3.zw;
|
|
float4 albedo1 = tex2Dbias( _Albedo, float4(parallax1, 0, textureBias) );
|
|
float4 albedo2 = tex2Dbias( _Albedo, float4(parallax2, 0, textureBias) );
|
|
float4 albedo3 = tex2Dbias( _Albedo, float4(parallax3, 0, textureBias) );
|
|
float4 blendedAlbedo = albedo1 * weights.x + albedo2 * weights.y + albedo3 * weights.z;
|
|
o.Alpha = ( blendedAlbedo.a - _AI_Clip );
|
|
clip( o.Alpha );
|
|
o.Albedo = blendedAlbedo.rgb;
|
|
#if defined(AI_HD_RENDERPIPELINE)
|
|
float4 feat1 = _Features.SampleLevel( SamplerState_Point_Repeat, parallax1, 0);
|
|
o.Diffusion = feat1.rgb;
|
|
o.Features = feat1.a;
|
|
float4 test1 = _Specular.SampleLevel( SamplerState_Point_Repeat, parallax1, 0);
|
|
o.MetalTangent = test1.b;
|
|
#endif
|
|
float4 normals1 = tex2Dbias( _Normals, float4(parallax1, 0, textureBias) );
|
|
float4 normals2 = tex2Dbias( _Normals, float4(parallax2, 0, textureBias) );
|
|
float4 normals3 = tex2Dbias( _Normals, float4(parallax3, 0, textureBias) );
|
|
float4 blendedNormal = normals1 * weights.x + normals2 * weights.y + normals3 * weights.z;
|
|
float4 output0a = tex2Dbias( _Mask, float4(parallax1, 0, textureBias) );
|
|
float4 output0b = tex2Dbias( _Mask, float4(parallax2, 0, textureBias) );
|
|
float4 output0c = tex2Dbias( _Mask, float4(parallax3, 0, textureBias) );
|
|
output0 = output0a * weights.x + output0b * weights.y + output0c * weights.z;
|
|
float3 localNormal = blendedNormal.rgb * 2.0 - 1.0;
|
|
float3 worldNormal = normalize( mul( (float3x3)ai_ObjectToWorld, localNormal ) );
|
|
o.Normal = worldNormal;
|
|
float3 viewPos = interpViewPos.xyz;
|
|
#if ( defined(SHADERPASS) && (defined(SHADERPASS_DEPTHNORMALSONLY) && SHADERPASS == SHADERPASS_DEPTHNORMALSONLY) ) || defined(UNITY_PASS_SHADOWCASTER)
|
|
float depthOffset = ( ( parallaxSample1.a * weights.x + parallaxSample2.a * weights.y + parallaxSample3.a * weights.z ) - 0.5001 /** 2.0 - 1.0*/ ) /** 0.5*/ * _AI_DepthSize * length( ai_ObjectToWorld[ 2 ].xyz );
|
|
#else
|
|
float depthOffset = ( ( parallaxSample1.a * weights.x + parallaxSample2.a * weights.y + parallaxSample3.a * weights.z ) - 0.5 /** 2.0 - 1.0*/ ) /** 0.5*/ * _AI_DepthSize * length( ai_ObjectToWorld[ 2 ].xyz );
|
|
#endif
|
|
#if ( defined(SHADERPASS) && ((defined(SHADERPASS_SHADOWS) && SHADERPASS == SHADERPASS_SHADOWS) || (defined(SHADERPASS_SHADOWCASTER) && SHADERPASS == SHADERPASS_SHADOWCASTER)) ) || defined(UNITY_PASS_SHADOWCASTER)
|
|
viewPos.z += depthOffset * _AI_ShadowView;
|
|
viewPos.z += -_AI_ShadowBias;
|
|
#else
|
|
viewPos.z += depthOffset;
|
|
#endif
|
|
worldPos = mul( UNITY_MATRIX_I_V, float4( viewPos.xyz, 1 ) ).xyz;
|
|
clipPos = mul( UNITY_MATRIX_P, float4( viewPos, 1 ) );
|
|
#if defined(UNITY_PASS_SHADOWCASTER) && !defined(SHADERPASS)
|
|
#if UNITY_REVERSED_Z
|
|
clipPos.z = min( clipPos.z, clipPos.w * UNITY_NEAR_CLIP_VALUE );
|
|
#else
|
|
clipPos.z = max( clipPos.z, clipPos.w * UNITY_NEAR_CLIP_VALUE );
|
|
#endif
|
|
#endif
|
|
clipPos.xyz /= clipPos.w;
|
|
if( UNITY_NEAR_CLIP_VALUE < 0 )
|
|
clipPos = clipPos * 0.5 + 0.5;
|
|
}
|
|
|
|
|
|
void BuildSurfaceData(FragInputs fragInputs, inout SmoothSurfaceDescription surfaceDescription, float3 V, out SurfaceData surfaceData, out float3 bentNormalWS)
|
|
{
|
|
ZERO_INITIALIZE(SurfaceData, surfaceData);
|
|
|
|
surfaceData.perceptualSmoothness = surfaceDescription.Smoothness;
|
|
|
|
surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD;
|
|
#ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING;
|
|
#endif
|
|
#ifdef _MATERIAL_FEATURE_TRANSMISSION
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION;
|
|
#endif
|
|
#ifdef _MATERIAL_FEATURE_ANISOTROPY
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_ANISOTROPY;
|
|
#endif
|
|
|
|
#ifdef _MATERIAL_FEATURE_IRIDESCENCE
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_IRIDESCENCE;
|
|
#endif
|
|
#ifdef _MATERIAL_FEATURE_SPECULAR_COLOR
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR;
|
|
#endif
|
|
|
|
#if defined (_MATERIAL_FEATURE_SPECULAR_COLOR) && defined (_ENERGY_CONSERVING_SPECULAR)
|
|
surfaceData.baseColor *= (1.0 - Max3(surfaceData.specularColor.r, surfaceData.specularColor.g, surfaceData.specularColor.b));
|
|
#endif
|
|
|
|
GetNormalWS( fragInputs, float3( 0.0, 0.0, 1.0 ), surfaceData.normalWS, float3( 1.0, 1.0, 1.0 ) );
|
|
bentNormalWS = surfaceData.normalWS;
|
|
|
|
surfaceData.geomNormalWS = T2W(fragInputs, 2);
|
|
|
|
#ifdef _HAS_REFRACTION
|
|
if (_EnableSSRefraction)
|
|
{
|
|
|
|
surfaceData.transmittanceMask = (1.0 - surfaceDescription.Alpha);
|
|
surfaceDescription.Alpha = 1.0;
|
|
}
|
|
else
|
|
{
|
|
surfaceData.ior = 1.0;
|
|
surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);
|
|
surfaceData.atDistance = 1.0;
|
|
surfaceData.transmittanceMask = 0.0;
|
|
surfaceDescription.Alpha = 1.0;
|
|
}
|
|
#else
|
|
surfaceData.ior = 1.0;
|
|
surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);
|
|
surfaceData.atDistance = 1.0;
|
|
surfaceData.transmittanceMask = 0.0;
|
|
#endif
|
|
|
|
surfaceData.tangentWS = normalize(T2W(fragInputs, 0).xyz); // The tangent is not normalize in worldToTangent for mikkt. TODO: Check if it expected that we normalize with Morten. Tag: SURFACE_GRADIENT
|
|
surfaceData.tangentWS = Orthonormalize(surfaceData.tangentWS, surfaceData.normalWS);
|
|
|
|
#if defined(_SPECULAR_OCCLUSION_CUSTOM)
|
|
#elif defined(_SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL)
|
|
surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO(V, bentNormalWS, surfaceData.normalWS, surfaceData.ambientOcclusion, PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness));
|
|
#elif defined(_AMBIENT_OCCLUSION) && defined(_SPECULAR_OCCLUSION_FROM_AO)
|
|
surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(dot(surfaceData.normalWS, V)), surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness));
|
|
#else
|
|
surfaceData.specularOcclusion = 1.0;
|
|
#endif
|
|
#ifdef _ENABLE_GEOMETRIC_SPECULAR_AA
|
|
surfaceData.perceptualSmoothness = GeometricNormalFiltering(surfaceData.perceptualSmoothness, T2W(fragInputs, 2), surfaceDescription.SpecularAAScreenSpaceVariance, surfaceDescription.SpecularAAThreshold);
|
|
#endif
|
|
}
|
|
|
|
void GetSurfaceAndBuiltinData( SmoothSurfaceDescription surfaceDescription, FragInputs fragInputs, float3 V, inout PositionInputs posInput, out SurfaceData surfaceData, out BuiltinData builtinData)
|
|
{
|
|
//#ifdef LOD_FADE_CROSSFADE
|
|
// uint3 fadeMaskSeed = asuint((int3)(V * _ScreenSize.xyx));
|
|
// LODDitheringTransition(fadeMaskSeed, unity_LODFade.x);
|
|
//#endif
|
|
|
|
#ifdef _ALPHATEST_ON
|
|
DoAlphaTest ( surfaceDescription.Alpha, surfaceDescription.AlphaClipThreshold );
|
|
#endif
|
|
float3 bentNormalWS;
|
|
BuildSurfaceData(fragInputs, surfaceDescription, V, surfaceData, bentNormalWS);
|
|
|
|
#if HAVE_DECALS
|
|
if( _EnableDecals )
|
|
{
|
|
DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, surfaceDescription.Alpha);
|
|
ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData);
|
|
}
|
|
#endif
|
|
|
|
#if defined( ASE_SRP_VERSION ) && ASE_SRP_VERSION <= 50702
|
|
InitBuiltinData( surfaceDescription.Alpha, bentNormalWS, -T2W(fragInputs, 2), fragInputs.positionRWS, fragInputs.texCoord1, fragInputs.texCoord2, builtinData );
|
|
#else
|
|
InitBuiltinData( posInput, surfaceDescription.Alpha, bentNormalWS, -T2W(fragInputs, 2), fragInputs.texCoord1, fragInputs.texCoord2, builtinData );
|
|
#endif
|
|
|
|
builtinData.depthOffset = 0.0;
|
|
|
|
#if (SHADERPASS == SHADERPASS_DISTORTION)
|
|
builtinData.distortion = surfaceDescription.Distortion;
|
|
builtinData.distortionBlur = surfaceDescription.DistortionBlur;
|
|
#else
|
|
builtinData.distortion = float2(0.0, 0.0);
|
|
builtinData.distortionBlur = 0.0;
|
|
#endif
|
|
|
|
PostInitBuiltinData(V, posInput, surfaceData, builtinData);
|
|
}
|
|
|
|
VaryingsPassToPS UnpackVaryingsPassToPS(PackedVaryingsToPS input)
|
|
{
|
|
VaryingsPassToPS output;
|
|
output.positionCS = float4(input.vpassInterpolators0.xy, 0.0, input.vpassInterpolators0.z);
|
|
output.previousPositionCS = float4(input.vpassInterpolators1.xy, 0.0, input.vpassInterpolators1.z);
|
|
|
|
return output;
|
|
}
|
|
|
|
#if UNITY_VERSION < 201930
|
|
float3 TransformPreviousObjectToWorldNormal(float3 normalOS)
|
|
{
|
|
#ifdef UNITY_ASSUME_UNIFORM_SCALING
|
|
return normalize(mul((float3x3)unity_MatrixPreviousM, normalOS));
|
|
#else
|
|
return normalize(mul(normalOS, (float3x3)unity_MatrixPreviousMI));
|
|
#endif
|
|
}
|
|
|
|
float3 TransformPreviousObjectToWorld(float3 positionOS)
|
|
{
|
|
float4x4 previousModelMatrix = ApplyCameraTranslationToMatrix(unity_MatrixPreviousM);
|
|
return mul(previousModelMatrix, float4(positionOS, 1.0)).xyz;
|
|
}
|
|
#endif
|
|
|
|
void VelocityPositionZBias(VaryingsToPS input)
|
|
{
|
|
#if defined(UNITY_REVERSED_Z)
|
|
input.vmesh.positionCS.z -= unity_MotionVectorsParams.z * input.vmesh.positionCS.w;
|
|
#else
|
|
input.vmesh.positionCS.z += unity_MotionVectorsParams.z * input.vmesh.positionCS.w;
|
|
#endif
|
|
}
|
|
|
|
PackedVaryingsToPS Vert(AttributesMesh inputMesh, AttributesPass inputPass )
|
|
{
|
|
PackedVaryingsToPS outputPackedVaryingsToPS;
|
|
VaryingsToPS varyingsType;
|
|
VaryingsMeshToPS outputVaryingsMeshToPS;
|
|
|
|
ZERO_INITIALIZE( PackedVaryingsToPS, outputPackedVaryingsToPS );
|
|
UNITY_SETUP_INSTANCE_ID(inputMesh);
|
|
UNITY_TRANSFER_INSTANCE_ID(inputMesh, outputVaryingsMeshToPS);
|
|
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(outputPackedVaryingsMeshToPS);
|
|
|
|
OctaImpostorVertex( inputMesh.vertex, inputMesh.normal, outputPackedVaryingsToPS.UVsFrame117, outputPackedVaryingsToPS.UVsFrame217, outputPackedVaryingsToPS.UVsFrame317, outputPackedVaryingsToPS.octaframe17, outputPackedVaryingsToPS.viewPos17 );
|
|
|
|
inputMesh.vertex.xyz += float3( 0, 0, 0 ) ;
|
|
|
|
float3 positionRWS = TransformObjectToWorld( inputMesh.vertex.xyz );
|
|
|
|
outputVaryingsMeshToPS.positionRWS = positionRWS;
|
|
outputVaryingsMeshToPS.positionCS = TransformWorldToHClip(positionRWS);
|
|
|
|
varyingsType.vmesh = outputVaryingsMeshToPS;
|
|
|
|
VelocityPositionZBias(varyingsType);
|
|
varyingsType.vpass.positionCS = mul(_NonJitteredViewProjMatrix, float4(varyingsType.vmesh.positionRWS, 1.0));
|
|
|
|
bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;
|
|
if (forceNoMotion)
|
|
{
|
|
varyingsType.vpass.previousPositionCS = float4(0.0, 0.0, 0.0, 1.0);
|
|
}
|
|
else
|
|
{
|
|
bool hasDeformation = unity_MotionVectorsParams.x > 0.0; // Skin or morph target
|
|
float3 previousPositionRWS = TransformPreviousObjectToWorld(hasDeformation ? inputPass.previousPositionOS : inputMesh.vertex.xyz );
|
|
varyingsType.vpass.previousPositionCS = mul(_PrevViewProjMatrix, float4(previousPositionRWS, 1.0));
|
|
}
|
|
|
|
outputPackedVaryingsToPS.vmeshPositionCS = varyingsType.vmesh.positionCS;
|
|
outputPackedVaryingsToPS.vmeshInterp00.xyz = varyingsType.vmesh.positionRWS;
|
|
outputPackedVaryingsToPS.vpassInterpolators0 = float3(varyingsType.vpass.positionCS.xyw);
|
|
outputPackedVaryingsToPS.vpassInterpolators1 = float3(varyingsType.vpass.previousPositionCS.xyw);
|
|
return outputPackedVaryingsToPS;
|
|
}
|
|
|
|
void Frag( PackedVaryingsToPS packedInput
|
|
, out float4 outVelocity : SV_Target0
|
|
#ifdef WRITE_NORMAL_BUFFER
|
|
, out float4 outNormalBuffer : SV_Target1
|
|
#ifdef WRITE_MSAA_DEPTH
|
|
, out float1 depthColor : SV_Target2
|
|
#endif
|
|
#endif
|
|
, out float outputDepth : SV_Depth
|
|
|
|
)
|
|
{
|
|
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX( packedInput );
|
|
UNITY_SETUP_INSTANCE_ID( packedInput );
|
|
|
|
#ifdef LOD_FADE_CROSSFADE
|
|
float3 VC = GetWorldSpaceNormalizeViewDir(packedInput.vmeshInterp00.xyz);
|
|
LODDitheringTransition(ComputeFadeMaskSeed(VC, packedInput.vmeshPositionCS.xy), unity_LODFade.x);
|
|
#endif
|
|
|
|
FragInputs input;
|
|
|
|
ZERO_INITIALIZE(FragInputs, input);
|
|
SmoothSurfaceDescription surfaceDescription = (SmoothSurfaceDescription)0;
|
|
SurfaceOutput o = (SurfaceOutput)0;
|
|
|
|
o.Normal = float3( 0, 0, 1 );
|
|
float4 clipPos = 0;
|
|
float3 worldPos = 0;
|
|
|
|
float4 output0 = 0;
|
|
OctaImpostorFragment( o, clipPos, worldPos, packedInput.UVsFrame117, packedInput.UVsFrame217, packedInput.UVsFrame317, packedInput.octaframe17, packedInput.viewPos17, output0 );
|
|
float4 break38 = output0;
|
|
|
|
surfaceDescription.Smoothness = break38.y;
|
|
surfaceDescription.Alpha = o.Alpha;
|
|
|
|
#ifdef _ALPHATEST_ON
|
|
surfaceDescription.AlphaClipThreshold = 0;
|
|
#endif
|
|
|
|
packedInput.vmeshPositionCS.zw = clipPos.zw;
|
|
float3 positionRWS = worldPos;
|
|
float3 normalWS = o.Normal;
|
|
|
|
//#if defined( ASE_SRP_VERSION ) && ASE_SRP_VERSION < 60900
|
|
//input.worldToTangent = k_identity3x3;
|
|
//#else
|
|
input.tangentToWorld = k_identity3x3;
|
|
//#endif
|
|
input.positionSS = packedInput.vmeshPositionCS;
|
|
input.positionRWS = positionRWS;
|
|
|
|
PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS);
|
|
|
|
float3 normalizedWorldViewDir = GetWorldSpaceNormalizeViewDir( input.positionRWS );
|
|
|
|
SurfaceData surfaceData;
|
|
BuiltinData builtinData;
|
|
|
|
GetSurfaceAndBuiltinData(surfaceDescription, input, normalizedWorldViewDir, posInput, surfaceData, builtinData);
|
|
|
|
VaryingsPassToPS inputPass = UnpackVaryingsPassToPS(packedInput);
|
|
//#if defined( ASE_SRP_VERSION ) && ASE_SRP_VERSION <= 50702
|
|
//float2 velocity = CalculateVelocity(inputPass.positionCS, inputPass.previousPositionCS);
|
|
//EncodeVelocity(velocity * 0.5, outVelocity);
|
|
//#else
|
|
float2 velocity = CalculateMotionVector( inputPass.positionCS, inputPass.previousPositionCS );
|
|
EncodeMotionVector( velocity * 0.5, outVelocity );
|
|
//#endif
|
|
|
|
bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;
|
|
if (forceNoMotion)
|
|
outVelocity = float4(0.0, 0.0, 0.0, 0.0);
|
|
|
|
#ifdef WRITE_NORMAL_BUFFER
|
|
EncodeIntoNormalBuffer(ConvertSurfaceDataToNormalData(surfaceData), posInput.positionSS, outNormalBuffer);
|
|
|
|
#ifdef WRITE_MSAA_DEPTH
|
|
depthColor = packedInput.vmeshPositionCS.z;
|
|
#endif
|
|
#endif
|
|
|
|
outputDepth = posInput.deviceDepth;
|
|
}
|
|
|
|
ENDHLSL
|
|
}
|
|
|
|
|
|
Pass
|
|
{
|
|
|
|
Name "Forward"
|
|
Tags { "LightMode"="Forward" }
|
|
Stencil
|
|
{
|
|
Ref 10
|
|
WriteMask 14
|
|
Comp Always
|
|
Pass Replace
|
|
}
|
|
|
|
|
|
ColorMask [_ColorMaskTransparentVelOne] 1
|
|
ColorMask [_ColorMaskTransparentVelTwo] 2
|
|
|
|
HLSLPROGRAM
|
|
|
|
#define _DECALS 1
|
|
#define _MATERIAL_FEATURE_SPECULAR_COLOR 1
|
|
#define _ENERGY_CONSERVING_SPECULAR 1
|
|
#define _AMBIENT_OCCLUSION 1
|
|
#define ASE_SRP_VERSION 120112
|
|
#ifdef UNITY_COLORSPACE_GAMMA//AI_SRP
|
|
#define unity_ColorSpaceDielectricSpec half4(0.220916301, 0.220916301, 0.220916301, 1.0 - 0.220916301)//AI_SRP
|
|
#else//AI_SRP
|
|
#define unity_ColorSpaceDielectricSpec half4(0.04, 0.04, 0.04, 1.0 - 0.04) //AI_SRP
|
|
#endif//AI_SRP
|
|
|
|
|
|
#pragma vertex Vert
|
|
#pragma fragment Frag
|
|
|
|
#if defined(_MATERIAL_FEATURE_SUBSURFACE_SCATTERING) && !defined(_SURFACE_TYPE_TRANSPARENT)
|
|
#define OUTPUT_SPLIT_LIGHTING
|
|
#endif
|
|
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
|
|
//#if defined( ASE_SRP_VERSION ) && ASE_SRP_VERSION < 60900
|
|
//#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Wind.hlsl"
|
|
//#endif
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/NormalSurfaceGradient.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/FragInputs.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl"
|
|
|
|
#define SHADERPASS SHADERPASS_FORWARD
|
|
//#pragma multi_compile _ LIGHTMAP_ON
|
|
//#pragma multi_compile _ DIRLIGHTMAP_COMBINED
|
|
//#pragma multi_compile _ DYNAMICLIGHTMAP_ON
|
|
//#pragma multi_compile _ SHADOWS_SHADOWMASK
|
|
//#pragma multi_compile DECALS_OFF DECALS_3RT DECALS_4RT
|
|
#define LIGHTLOOP_TILE_PASS
|
|
#pragma multi_compile USE_FPTL_LIGHTLIST USE_CLUSTERED_LIGHTLIST
|
|
#pragma multi_compile SHADOW_LOW SHADOW_MEDIUM SHADOW_HIGH
|
|
|
|
#define VARYINGS_NEED_POSITION_WS
|
|
#define VARYINGS_NEED_TANGENT_TO_WORLD
|
|
#define VARYINGS_NEED_TEXCOORD1
|
|
#define VARYINGS_NEED_TEXCOORD2
|
|
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Lighting.hlsl"
|
|
|
|
#define HAS_LIGHTLOOP
|
|
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoopDef.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoop.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinUtilities.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialUtilities.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalUtilities.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDecalData.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphFunctions.hlsl"
|
|
|
|
//#if defined( ASE_SRP_VERSION ) && ASE_SRP_VERSION < 60900
|
|
//#define T2W(var, index) var.worldToTangent[index]
|
|
//#else
|
|
#define T2W(var, index) var.tangentToWorld[index]
|
|
//#endif
|
|
|
|
#define ai_ObjectToWorld GetObjectToWorldMatrix()
|
|
#define ai_WorldToObject GetWorldToObjectMatrix()
|
|
#define AI_INV_TWO_PI INV_TWO_PI
|
|
#define AI_PI PI
|
|
#define AI_INV_PI INV_PI
|
|
|
|
|
|
struct AttributesMesh
|
|
{
|
|
float4 vertex : POSITION;
|
|
float3 normal : NORMAL;
|
|
float4 tangent : TANGENT;
|
|
float4 texcoord : TEXCOORD0;
|
|
float4 uv1 : TEXCOORD1;
|
|
float4 uv2 : TEXCOORD2;
|
|
|
|
UNITY_VERTEX_INPUT_INSTANCE_ID
|
|
};
|
|
|
|
struct PackedVaryingsMeshToPS
|
|
{
|
|
float4 positionCS : SV_Position;
|
|
float3 interp00 : TEXCOORD0;
|
|
float3 interp01 : TEXCOORD1;
|
|
float4 interp02 : TEXCOORD2;
|
|
float4 interp03 : TEXCOORD3;
|
|
float4 interp04 : TEXCOORD4;
|
|
float4 interp05 : TEXCOORD5;
|
|
float4 UVsFrame117 : TEXCOORD6;
|
|
float4 UVsFrame217 : TEXCOORD7;
|
|
float4 UVsFrame317 : TEXCOORD8;
|
|
float4 octaframe17 : TEXCOORD9;
|
|
float4 viewPos17 : TEXCOORD10;
|
|
UNITY_VERTEX_INPUT_INSTANCE_ID
|
|
UNITY_VERTEX_OUTPUT_STEREO
|
|
};
|
|
|
|
sampler2D _Albedo;
|
|
sampler2D _Normals;
|
|
sampler2D _Mask;
|
|
SAMPLER(sampler_Mask);
|
|
float4x4 unity_CameraProjection;
|
|
float4x4 unity_CameraInvProjection;
|
|
float4x4 unity_WorldToCamera;
|
|
float4x4 unity_CameraToWorld;
|
|
CBUFFER_START( UnityPerMaterial )
|
|
float4 _AI_SizeOffset;
|
|
float3 _AI_Offset;
|
|
float _AI_Frames;
|
|
float _AI_FramesX;
|
|
float _AI_FramesY;
|
|
float _AI_ImpostorSize;
|
|
float _AI_Parallax;
|
|
float _AI_TextureBias;
|
|
float _AI_DepthSize;
|
|
float _AI_ShadowBias;
|
|
float _AI_ShadowView;
|
|
float _AI_Clip;
|
|
CBUFFER_END
|
|
|
|
|
|
float2 VectortoOctahedron( float3 N )
|
|
{
|
|
N /= dot( 1.0, abs( N ) );
|
|
if( N.z <= 0 )
|
|
{
|
|
N.xy = ( 1 - abs( N.yx ) ) * ( N.xy >= 0 ? 1.0 : -1.0 );
|
|
}
|
|
return N.xy;
|
|
}
|
|
|
|
float3 OctahedronToVector( float2 Oct )
|
|
{
|
|
float3 N = float3( Oct, 1.0 - dot( 1.0, abs( Oct ) ) );
|
|
if(N.z< 0 )
|
|
{
|
|
N.xy = ( 1 - abs( N.yx) ) * (N.xy >= 0 ? 1.0 : -1.0 );
|
|
}
|
|
return normalize( N);
|
|
}
|
|
|
|
inline void RayPlaneIntersectionUV( float3 normal, float3 rayPosition, float3 rayDirection, inout float2 uvs, inout float3 localNormal )
|
|
{
|
|
float lDotN = dot( rayDirection, normal );
|
|
float p0l0DotN = dot( -rayPosition, normal );
|
|
float t = p0l0DotN / lDotN;
|
|
float3 p = rayDirection * t + rayPosition;
|
|
float3 upVector = float3( 0, 1, 0 );
|
|
float3 tangent = normalize( cross( upVector, normal ) + float3( -0.001, 0, 0 ) );
|
|
float3 bitangent = cross( tangent, normal );
|
|
float frameX = dot( p, tangent );
|
|
float frameZ = dot( p, bitangent );
|
|
uvs = -float2( frameX, frameZ );
|
|
if( t <= 0.0 )
|
|
uvs = 0;
|
|
float3x3 worldToLocal = float3x3( tangent, bitangent, normal );
|
|
localNormal = normalize( mul( worldToLocal, rayDirection ) );
|
|
}
|
|
|
|
inline void OctaImpostorVertex( inout float4 vertex, inout float3 normal, inout float4 uvsFrame1, inout float4 uvsFrame2, inout float4 uvsFrame3, inout float4 octaFrame, inout float4 viewPos )
|
|
{
|
|
float2 uvOffset = _AI_SizeOffset.zw;
|
|
float parallax = -_AI_Parallax;
|
|
float UVscale = _AI_ImpostorSize;
|
|
float framesXY = _AI_Frames;
|
|
float prevFrame = framesXY - 1;
|
|
float3 fractions = 1.0 / float3( framesXY, prevFrame, UVscale );
|
|
float fractionsFrame = fractions.x;
|
|
float fractionsPrevFrame = fractions.y;
|
|
float fractionsUVscale = fractions.z;
|
|
float3 worldOrigin = 0;
|
|
float4 perspective = float4( 0, 0, 0, 1 );
|
|
if( UNITY_MATRIX_P[ 3 ][ 3 ] == 1 )
|
|
{
|
|
perspective = float4( 0, 0, 5000, 0 );
|
|
worldOrigin = ai_ObjectToWorld._m03_m13_m23;
|
|
}
|
|
float3 worldCameraPos = worldOrigin + mul( UNITY_MATRIX_I_V, perspective ).xyz;
|
|
float3 objectCameraPosition = mul( ai_WorldToObject, float4( worldCameraPos, 1 ) ).xyz - _AI_Offset.xyz;
|
|
float3 objectCameraDirection = normalize( objectCameraPosition );
|
|
float3 upVector = float3( 0,1,0 );
|
|
float3 objectHorizontalVector = normalize( cross( objectCameraDirection, upVector ) );
|
|
float3 objectVerticalVector = cross( objectHorizontalVector, objectCameraDirection );
|
|
float2 uvExpansion = vertex.xy;
|
|
float3 billboard = objectHorizontalVector * uvExpansion.x + objectVerticalVector * uvExpansion.y;
|
|
float3 localDir = billboard - objectCameraPosition;
|
|
float2 frameOcta = VectortoOctahedron( objectCameraDirection.xzy ) * 0.5 + 0.5;
|
|
float2 prevOctaFrame = frameOcta * prevFrame;
|
|
float2 baseOctaFrame = floor( prevOctaFrame );
|
|
float2 fractionOctaFrame = ( baseOctaFrame * fractionsFrame );
|
|
float2 octaFrame1 = ( baseOctaFrame * fractionsPrevFrame ) * 2.0 - 1.0;
|
|
float3 octa1WorldY = OctahedronToVector( octaFrame1 ).xzy;
|
|
float3 octa1LocalY;
|
|
float2 uvFrame1;
|
|
RayPlaneIntersectionUV( octa1WorldY, objectCameraPosition, localDir, /*inout*/ uvFrame1, /*inout*/ octa1LocalY );
|
|
float2 uvParallax1 = octa1LocalY.xy * fractionsFrame * parallax;
|
|
uvFrame1 = ( uvFrame1 * fractionsUVscale + 0.5 ) * fractionsFrame + fractionOctaFrame;
|
|
uvsFrame1 = float4( uvParallax1, uvFrame1) - float4( 0, 0, uvOffset );
|
|
float2 fractPrevOctaFrame = frac( prevOctaFrame );
|
|
float2 cornerDifference = lerp( float2( 0,1 ) , float2( 1,0 ) , saturate( ceil( ( fractPrevOctaFrame.x - fractPrevOctaFrame.y ) ) ));
|
|
float2 octaFrame2 = ( ( baseOctaFrame + cornerDifference ) * fractionsPrevFrame ) * 2.0 - 1.0;
|
|
float3 octa2WorldY = OctahedronToVector( octaFrame2 ).xzy;
|
|
float3 octa2LocalY;
|
|
float2 uvFrame2;
|
|
RayPlaneIntersectionUV( octa2WorldY, objectCameraPosition, localDir, /*inout*/ uvFrame2, /*inout*/ octa2LocalY );
|
|
float2 uvParallax2 = octa2LocalY.xy * fractionsFrame * parallax;
|
|
uvFrame2 = ( uvFrame2 * fractionsUVscale + 0.5 ) * fractionsFrame + ( ( cornerDifference * fractionsFrame ) + fractionOctaFrame );
|
|
uvsFrame2 = float4( uvParallax2, uvFrame2) - float4( 0, 0, uvOffset );
|
|
float2 octaFrame3 = ( ( baseOctaFrame + 1 ) * fractionsPrevFrame ) * 2.0 - 1.0;
|
|
float3 octa3WorldY = OctahedronToVector( octaFrame3 ).xzy;
|
|
float3 octa3LocalY;
|
|
float2 uvFrame3;
|
|
RayPlaneIntersectionUV( octa3WorldY, objectCameraPosition, localDir, /*inout*/ uvFrame3, /*inout*/ octa3LocalY );
|
|
float2 uvParallax3 = octa3LocalY.xy * fractionsFrame * parallax;
|
|
uvFrame3 = ( uvFrame3 * fractionsUVscale + 0.5 ) * fractionsFrame + ( fractionOctaFrame + fractionsFrame );
|
|
uvsFrame3 = float4( uvParallax3, uvFrame3) - float4( 0, 0, uvOffset );
|
|
octaFrame = 0;
|
|
octaFrame.xy = prevOctaFrame;
|
|
vertex.xyz = billboard + _AI_Offset.xyz;
|
|
normal.xyz = objectCameraDirection;
|
|
viewPos = 0;
|
|
viewPos.xyz = TransformWorldToView( TransformObjectToWorld( vertex.xyz ) );
|
|
}
|
|
|
|
inline void OctaImpostorFragment( inout SurfaceOutput o, out float4 clipPos, out float3 worldPos, float4 uvsFrame1, float4 uvsFrame2, float4 uvsFrame3, float4 octaFrame, float4 interpViewPos, out float4 output0 )
|
|
{
|
|
float depthBias = -1.0;
|
|
float textureBias = _AI_TextureBias;
|
|
float2 fraction = frac( octaFrame.xy );
|
|
float2 invFraction = 1 - fraction;
|
|
float3 weights;
|
|
weights.x = min( invFraction.x, invFraction.y );
|
|
weights.y = abs( fraction.x - fraction.y );
|
|
weights.z = min( fraction.x, fraction.y );
|
|
float4 parallaxSample1 = tex2Dbias( _Normals, float4(uvsFrame1.zw, 0, depthBias) );
|
|
float2 parallax1 = ( ( 0.5 - parallaxSample1.a ) * uvsFrame1.xy ) + uvsFrame1.zw;
|
|
float4 parallaxSample2 = tex2Dbias( _Normals, float4(uvsFrame2.zw, 0, depthBias) );
|
|
float2 parallax2 = ( ( 0.5 - parallaxSample2.a ) * uvsFrame2.xy ) + uvsFrame2.zw;
|
|
float4 parallaxSample3 = tex2Dbias( _Normals, float4(uvsFrame3.zw, 0, depthBias) );
|
|
float2 parallax3 = ( ( 0.5 - parallaxSample3.a ) * uvsFrame3.xy ) + uvsFrame3.zw;
|
|
float4 albedo1 = tex2Dbias( _Albedo, float4(parallax1, 0, textureBias) );
|
|
float4 albedo2 = tex2Dbias( _Albedo, float4(parallax2, 0, textureBias) );
|
|
float4 albedo3 = tex2Dbias( _Albedo, float4(parallax3, 0, textureBias) );
|
|
float4 blendedAlbedo = albedo1 * weights.x + albedo2 * weights.y + albedo3 * weights.z;
|
|
o.Alpha = ( blendedAlbedo.a - _AI_Clip );
|
|
clip( o.Alpha );
|
|
o.Albedo = blendedAlbedo.rgb;
|
|
#if defined(AI_HD_RENDERPIPELINE)
|
|
float4 feat1 = _Features.SampleLevel( SamplerState_Point_Repeat, parallax1, 0);
|
|
o.Diffusion = feat1.rgb;
|
|
o.Features = feat1.a;
|
|
float4 test1 = _Specular.SampleLevel( SamplerState_Point_Repeat, parallax1, 0);
|
|
o.MetalTangent = test1.b;
|
|
#endif
|
|
float4 normals1 = tex2Dbias( _Normals, float4(parallax1, 0, textureBias) );
|
|
float4 normals2 = tex2Dbias( _Normals, float4(parallax2, 0, textureBias) );
|
|
float4 normals3 = tex2Dbias( _Normals, float4(parallax3, 0, textureBias) );
|
|
float4 blendedNormal = normals1 * weights.x + normals2 * weights.y + normals3 * weights.z;
|
|
float4 output0a = tex2Dbias( _Mask, float4(parallax1, 0, textureBias) );
|
|
float4 output0b = tex2Dbias( _Mask, float4(parallax2, 0, textureBias) );
|
|
float4 output0c = tex2Dbias( _Mask, float4(parallax3, 0, textureBias) );
|
|
output0 = output0a * weights.x + output0b * weights.y + output0c * weights.z;
|
|
float3 localNormal = blendedNormal.rgb * 2.0 - 1.0;
|
|
float3 worldNormal = normalize( mul( (float3x3)ai_ObjectToWorld, localNormal ) );
|
|
o.Normal = worldNormal;
|
|
float3 viewPos = interpViewPos.xyz;
|
|
#if ( defined(SHADERPASS) && (defined(SHADERPASS_DEPTHNORMALSONLY) && SHADERPASS == SHADERPASS_DEPTHNORMALSONLY) ) || defined(UNITY_PASS_SHADOWCASTER)
|
|
float depthOffset = ( ( parallaxSample1.a * weights.x + parallaxSample2.a * weights.y + parallaxSample3.a * weights.z ) - 0.5001 /** 2.0 - 1.0*/ ) /** 0.5*/ * _AI_DepthSize * length( ai_ObjectToWorld[ 2 ].xyz );
|
|
#else
|
|
float depthOffset = ( ( parallaxSample1.a * weights.x + parallaxSample2.a * weights.y + parallaxSample3.a * weights.z ) - 0.5 /** 2.0 - 1.0*/ ) /** 0.5*/ * _AI_DepthSize * length( ai_ObjectToWorld[ 2 ].xyz );
|
|
#endif
|
|
#if ( defined(SHADERPASS) && ((defined(SHADERPASS_SHADOWS) && SHADERPASS == SHADERPASS_SHADOWS) || (defined(SHADERPASS_SHADOWCASTER) && SHADERPASS == SHADERPASS_SHADOWCASTER)) ) || defined(UNITY_PASS_SHADOWCASTER)
|
|
viewPos.z += depthOffset * _AI_ShadowView;
|
|
viewPos.z += -_AI_ShadowBias;
|
|
#else
|
|
viewPos.z += depthOffset;
|
|
#endif
|
|
worldPos = mul( UNITY_MATRIX_I_V, float4( viewPos.xyz, 1 ) ).xyz;
|
|
clipPos = mul( UNITY_MATRIX_P, float4( viewPos, 1 ) );
|
|
#if defined(UNITY_PASS_SHADOWCASTER) && !defined(SHADERPASS)
|
|
#if UNITY_REVERSED_Z
|
|
clipPos.z = min( clipPos.z, clipPos.w * UNITY_NEAR_CLIP_VALUE );
|
|
#else
|
|
clipPos.z = max( clipPos.z, clipPos.w * UNITY_NEAR_CLIP_VALUE );
|
|
#endif
|
|
#endif
|
|
clipPos.xyz /= clipPos.w;
|
|
if( UNITY_NEAR_CLIP_VALUE < 0 )
|
|
clipPos = clipPos * 0.5 + 0.5;
|
|
}
|
|
|
|
float3 HSVToRGB( float3 c )
|
|
{
|
|
float4 K = float4( 1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0 );
|
|
float3 p = abs( frac( c.xxx + K.xyz ) * 6.0 - K.www );
|
|
return c.z * lerp( K.xxx, saturate( p - K.xxx ), c.y );
|
|
}
|
|
|
|
|
|
void BuildSurfaceData(FragInputs fragInputs, inout GlobalSurfaceDescription surfaceDescription, float3 V, PositionInputs posInput, out SurfaceData surfaceData, out float3 bentNormalWS)
|
|
{
|
|
ZERO_INITIALIZE(SurfaceData, surfaceData);
|
|
surfaceData.baseColor = surfaceDescription.Albedo;
|
|
surfaceData.perceptualSmoothness = surfaceDescription.Smoothness;
|
|
surfaceData.ambientOcclusion = surfaceDescription.Occlusion;
|
|
surfaceData.specularColor = surfaceDescription.Specular;
|
|
surfaceData.coatMask = surfaceDescription.CoatMask;
|
|
|
|
#ifdef _HAS_REFRACTION
|
|
if (_EnableSSRefraction)
|
|
{
|
|
surfaceData.ior = surfaceDescription.RefractionIndex;
|
|
surfaceData.transmittanceColor = surfaceDescription.RefractionColor;
|
|
surfaceData.atDistance = surfaceDescription.RefractionDistance;
|
|
|
|
surfaceData.transmittanceMask = (1.0 - surfaceDescription.Alpha);
|
|
surfaceDescription.Alpha = 1.0;
|
|
}
|
|
else
|
|
{
|
|
surfaceData.ior = 1.0;
|
|
surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);
|
|
surfaceData.atDistance = 1.0;
|
|
surfaceData.transmittanceMask = 0.0;
|
|
surfaceDescription.Alpha = 1.0;
|
|
}
|
|
#else
|
|
surfaceData.ior = 1.0;
|
|
surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);
|
|
surfaceData.atDistance = 1.0;
|
|
surfaceData.transmittanceMask = 0.0;
|
|
#endif
|
|
|
|
#ifdef _MATERIAL_FEATURE_IRIDESCENCE
|
|
surfaceData.iridescenceMask = surfaceDescription.IridescenceMask;
|
|
surfaceData.iridescenceThickness = surfaceDescription.IridescenceThickness;
|
|
#endif
|
|
|
|
surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD;
|
|
#ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING;
|
|
#endif
|
|
#ifdef _MATERIAL_FEATURE_TRANSMISSION
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION;
|
|
#endif
|
|
#ifdef _MATERIAL_FEATURE_ANISOTROPY
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_ANISOTROPY;
|
|
#endif
|
|
#ifdef ASE_LIT_CLEAR_COAT
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_CLEAR_COAT;
|
|
#endif
|
|
#ifdef _MATERIAL_FEATURE_IRIDESCENCE
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_IRIDESCENCE;
|
|
#endif
|
|
#ifdef _MATERIAL_FEATURE_SPECULAR_COLOR
|
|
surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR;
|
|
#endif
|
|
|
|
#if defined (_MATERIAL_FEATURE_SPECULAR_COLOR) && defined (_ENERGY_CONSERVING_SPECULAR)
|
|
surfaceData.baseColor *= (1.0 - Max3(surfaceData.specularColor.r, surfaceData.specularColor.g, surfaceData.specularColor.b));
|
|
#endif
|
|
|
|
GetNormalWS( fragInputs, float3( 0.0, 0.0, 1.0 ), surfaceData.normalWS, float3( 1.0, 1.0, 1.0 ) );
|
|
|
|
bentNormalWS = surfaceData.normalWS;
|
|
|
|
#ifdef ASE_BENT_NORMAL
|
|
GetNormalWS(fragInputs, surfaceDescription.BentNormal, bentNormalWS, float3( 1, 1, 1 ) );
|
|
#endif
|
|
|
|
surfaceData.geomNormalWS = T2W(fragInputs, 2);
|
|
|
|
#if defined(_HAS_REFRACTION) || defined(_MATERIAL_FEATURE_TRANSMISSION)
|
|
surfaceData.thickness = surfaceDescription.Thickness;
|
|
#endif
|
|
|
|
#ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING
|
|
surfaceData.subsurfaceMask = surfaceDescription.SubsurfaceMask;
|
|
#endif
|
|
|
|
#if defined( _MATERIAL_FEATURE_SUBSURFACE_SCATTERING ) || defined( _MATERIAL_FEATURE_TRANSMISSION )
|
|
surfaceData.diffusionProfileHash = asuint(surfaceDescription.DiffusionProfile);
|
|
#endif
|
|
|
|
surfaceData.tangentWS = normalize( T2W(fragInputs, 0).xyz );
|
|
#ifdef _MATERIAL_FEATURE_ANISOTROPY
|
|
surfaceData.anisotropy = surfaceDescription.Anisotropy;
|
|
surfaceData.tangentWS = TransformTangentToWorld(surfaceDescription.Tangent, fragInputs.worldToTangent);
|
|
#endif
|
|
surfaceData.tangentWS = Orthonormalize(surfaceData.tangentWS, surfaceData.normalWS);
|
|
|
|
#if defined(_SPECULAR_OCCLUSION_CUSTOM)
|
|
surfaceData.specularOcclusion = surfaceDescription.SpecularOcclusion;
|
|
#elif defined(_SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL)
|
|
surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO(V, bentNormalWS, surfaceData.normalWS, surfaceData.ambientOcclusion, PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness));
|
|
#elif defined(_AMBIENT_OCCLUSION) && defined(_SPECULAR_OCCLUSION_FROM_AO)
|
|
surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(dot(surfaceData.normalWS, V)), surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness));
|
|
#else
|
|
surfaceData.specularOcclusion = 1.0;
|
|
#endif
|
|
|
|
#ifdef _ENABLE_GEOMETRIC_SPECULAR_AA
|
|
surfaceData.perceptualSmoothness = GeometricNormalFiltering(surfaceData.perceptualSmoothness, T2W(fragInputs, 2), surfaceDescription.SpecularAAScreenSpaceVariance, surfaceDescription.SpecularAAThreshold);
|
|
#endif
|
|
}
|
|
|
|
void GetSurfaceAndBuiltinData(GlobalSurfaceDescription surfaceDescription,FragInputs fragInputs, float3 V, inout PositionInputs posInput, out SurfaceData surfaceData, out BuiltinData builtinData)
|
|
{
|
|
//#ifdef LOD_FADE_CROSSFADE
|
|
// uint3 fadeMaskSeed = asuint((int3)(V * _ScreenSize.xyx));
|
|
// LODDitheringTransition(fadeMaskSeed, unity_LODFade.x);
|
|
//#endif
|
|
|
|
#ifdef _ALPHATEST_ON
|
|
DoAlphaTest(surfaceDescription.Alpha, surfaceDescription.AlphaClipThreshold);
|
|
#endif
|
|
|
|
float3 bentNormalWS;
|
|
BuildSurfaceData(fragInputs, surfaceDescription, V, posInput, surfaceData, bentNormalWS);
|
|
|
|
#if HAVE_DECALS
|
|
if( _EnableDecals )
|
|
{
|
|
DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, surfaceDescription.Alpha);
|
|
ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData);
|
|
}
|
|
#endif
|
|
|
|
#if defined( ASE_SRP_VERSION ) && ASE_SRP_VERSION <= 50702
|
|
InitBuiltinData( surfaceDescription.Alpha, bentNormalWS, -T2W(fragInputs, 2), fragInputs.positionRWS, fragInputs.texCoord1, fragInputs.texCoord2, builtinData );
|
|
#else
|
|
InitBuiltinData( posInput, surfaceDescription.Alpha, bentNormalWS, -T2W(fragInputs, 2), fragInputs.texCoord1, fragInputs.texCoord2, builtinData );
|
|
#endif
|
|
|
|
builtinData.emissiveColor = surfaceDescription.Emission;
|
|
|
|
builtinData.depthOffset = 0.0;
|
|
|
|
#if (SHADERPASS == SHADERPASS_DISTORTION)
|
|
builtinData.distortion = surfaceDescription.Distortion;
|
|
builtinData.distortionBlur = surfaceDescription.DistortionBlur;
|
|
#else
|
|
builtinData.distortion = float2(0.0, 0.0);
|
|
builtinData.distortionBlur = 0.0;
|
|
#endif
|
|
|
|
PostInitBuiltinData(V, posInput, surfaceData, builtinData);
|
|
}
|
|
|
|
PackedVaryingsMeshToPS Vert(AttributesMesh inputMesh )
|
|
{
|
|
PackedVaryingsMeshToPS outputPackedVaryingsMeshToPS;
|
|
|
|
UNITY_SETUP_INSTANCE_ID( inputMesh );
|
|
UNITY_TRANSFER_INSTANCE_ID( inputMesh, outputPackedVaryingsMeshToPS );
|
|
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO( outputPackedVaryingsMeshToPS );
|
|
|
|
OctaImpostorVertex( inputMesh.vertex, inputMesh.normal, outputPackedVaryingsMeshToPS.UVsFrame117, outputPackedVaryingsMeshToPS.UVsFrame217, outputPackedVaryingsMeshToPS.UVsFrame317, outputPackedVaryingsMeshToPS.octaframe17, outputPackedVaryingsMeshToPS.viewPos17 );
|
|
|
|
inputMesh.vertex.xyz += float3( 0, 0, 0 ) ;
|
|
|
|
float3 positionRWS = TransformObjectToWorld(inputMesh.vertex.xyz );
|
|
float3 normalWS = TransformObjectToWorldNormal(inputMesh.normal);
|
|
float4 tangentWS = float4(TransformObjectToWorldDir(inputMesh.tangent.xyz), inputMesh.tangent.w);
|
|
|
|
outputPackedVaryingsMeshToPS.positionCS = TransformWorldToHClip(positionRWS);
|
|
outputPackedVaryingsMeshToPS.interp00.xyz = positionRWS;
|
|
outputPackedVaryingsMeshToPS.interp01.xyz = normalWS;
|
|
outputPackedVaryingsMeshToPS.interp02.xyzw = tangentWS;
|
|
outputPackedVaryingsMeshToPS.interp03.xyzw = inputMesh.texcoord;
|
|
outputPackedVaryingsMeshToPS.interp04.xyzw = inputMesh.uv1;
|
|
outputPackedVaryingsMeshToPS.interp05.xyzw = inputMesh.uv2;
|
|
return outputPackedVaryingsMeshToPS;
|
|
}
|
|
|
|
void Frag(PackedVaryingsMeshToPS packedInput,
|
|
#ifdef OUTPUT_SPLIT_LIGHTING
|
|
out float4 outColor : SV_Target0,
|
|
out float4 outDiffuseLighting : SV_Target1,
|
|
OUTPUT_SSSBUFFER(outSSSBuffer)
|
|
#else
|
|
out float4 outColor : SV_Target0
|
|
#endif
|
|
, out float outputDepth : SV_Depth
|
|
|
|
)
|
|
{
|
|
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(packedInput);
|
|
UNITY_SETUP_INSTANCE_ID( packedInput );
|
|
|
|
#ifdef LOD_FADE_CROSSFADE
|
|
float3 VC = GetWorldSpaceNormalizeViewDir(packedInput.interp00.xyz);
|
|
LODDitheringTransition(ComputeFadeMaskSeed(VC, packedInput.positionCS.xy), unity_LODFade.x);
|
|
#endif
|
|
|
|
FragInputs input;
|
|
|
|
ZERO_INITIALIZE(FragInputs, input);
|
|
GlobalSurfaceDescription surfaceDescription = (GlobalSurfaceDescription)0;
|
|
SurfaceOutput o = (SurfaceOutput)0;
|
|
|
|
o.Normal = packedInput.interp01.xyz; //float3( 0, 0, 1 );
|
|
float4 clipPos = packedInput.positionCS; //0;
|
|
float3 worldPos = packedInput.interp00.xyz; //0;
|
|
|
|
float4 output0 = 0;
|
|
OctaImpostorFragment( o, clipPos, worldPos, packedInput.UVsFrame117, packedInput.UVsFrame217, packedInput.UVsFrame317, packedInput.octaframe17, packedInput.viewPos17, output0 );
|
|
float4 break38 = output0;
|
|
float3 objToWorld67 = GetAbsolutePositionWS(mul( GetObjectToWorldMatrix(), float4( float3( 0,0,0 ), 1 ) ).xyz);
|
|
float3 hsvTorgb33 = HSVToRGB( float3(abs( sin( ( objToWorld67.x + objToWorld67.z ) ) ),1.0,1.0) );
|
|
float3 lerpResult36 = lerp( o.Albedo , ( break38.w * hsvTorgb33 ) , break38.w);
|
|
|
|
float3 temp_cast_0 = (break38.x).xxx;
|
|
|
|
surfaceDescription.Albedo = lerpResult36;
|
|
o.Normal = o.Normal;
|
|
surfaceDescription.BentNormal = float3( 0, 0, 1 );
|
|
surfaceDescription.CoatMask = 0;
|
|
surfaceDescription.Metallic = 0;
|
|
|
|
#ifdef _MATERIAL_FEATURE_SPECULAR_COLOR
|
|
surfaceDescription.Specular = temp_cast_0;
|
|
#endif
|
|
|
|
surfaceDescription.Emission = 0;
|
|
surfaceDescription.Smoothness = break38.y;
|
|
surfaceDescription.Occlusion = break38.z;
|
|
surfaceDescription.Alpha = o.Alpha;
|
|
|
|
#ifdef _ALPHATEST_ON
|
|
surfaceDescription.AlphaClipThreshold = 0;
|
|
#endif
|
|
|
|
#ifdef _ENABLE_GEOMETRIC_SPECULAR_AA
|
|
surfaceDescription.SpecularAAScreenSpaceVariance = 0;
|
|
surfaceDescription.SpecularAAThreshold = 0;
|
|
#endif
|
|
|
|
#ifdef _SPECULAR_OCCLUSION_CUSTOM
|
|
surfaceDescription.SpecularOcclusion = 0;
|
|
#endif
|
|
|
|
#if defined(_HAS_REFRACTION) || defined(_MATERIAL_FEATURE_TRANSMISSION)
|
|
surfaceDescription.Thickness = 1;
|
|
#endif
|
|
|
|
#ifdef _HAS_REFRACTION
|
|
surfaceDescription.RefractionIndex = 1;
|
|
surfaceDescription.RefractionColor = float3(1,1,1);
|
|
surfaceDescription.RefractionDistance = 0;
|
|
#endif
|
|
|
|
#ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING
|
|
surfaceDescription.SubsurfaceMask = 1;
|
|
#endif
|
|
|
|
#if defined( _MATERIAL_FEATURE_SUBSURFACE_SCATTERING ) || defined( _MATERIAL_FEATURE_TRANSMISSION )
|
|
surfaceDescription.DiffusionProfile = 0;
|
|
#endif
|
|
|
|
#ifdef _MATERIAL_FEATURE_ANISOTROPY
|
|
surfaceDescription.Anisotropy = 1;
|
|
surfaceDescription.Tangent = float3(1,0,0);
|
|
#endif
|
|
|
|
#ifdef _MATERIAL_FEATURE_IRIDESCENCE
|
|
surfaceDescription.IridescenceMask = 0;
|
|
surfaceDescription.IridescenceThickness = 0;
|
|
#endif
|
|
|
|
float4 bakedGI = float4( 0, 0, 0, 0 );
|
|
|
|
packedInput.positionCS.zw = clipPos.zw;
|
|
float3 positionRWS = worldPos;
|
|
float3 normalWS = o.Normal;
|
|
float4 tangentWS = packedInput.interp02.xyzw;
|
|
|
|
input.positionSS = packedInput.positionCS;
|
|
input.positionRWS = positionRWS;
|
|
//#if defined( ASE_SRP_VERSION ) && ASE_SRP_VERSION < 60900
|
|
//input.worldToTangent = BuildWorldToTangent( tangentWS, normalWS );
|
|
//#else
|
|
input.tangentToWorld = BuildTangentToWorld( tangentWS, normalWS );
|
|
//#endif
|
|
input.texCoord0 = packedInput.interp03.xyzw;
|
|
input.texCoord1 = packedInput.interp04.xyzw;
|
|
input.texCoord2 = packedInput.interp05.xyzw;
|
|
|
|
uint2 tileIndex = uint2( input.positionSS.xy ) / GetTileSize();
|
|
//#if defined( ASE_SRP_VERSION ) && ASE_SRP_VERSION < 60900
|
|
//#if defined(UNITY_SINGLE_PASS_STEREO)
|
|
// tileIndex.x -= unity_StereoEyeIndex * _NumTileClusteredX;
|
|
//#endif
|
|
//PositionInputs posInput = GetPositionInput_Stereo( input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS.xyz, tileIndex, unity_StereoEyeIndex );
|
|
//#else
|
|
PositionInputs posInput = GetPositionInput( input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS.xyz, tileIndex );
|
|
//#endif
|
|
float3 normalizedWorldViewDir = GetWorldSpaceNormalizeViewDir( input.positionRWS );
|
|
|
|
SurfaceData surfaceData;
|
|
BuiltinData builtinData;
|
|
|
|
GetSurfaceAndBuiltinData( surfaceDescription, input, normalizedWorldViewDir, posInput, surfaceData, builtinData);
|
|
BSDFData bsdfData = ConvertSurfaceDataToBSDFData(input.positionSS.xy, surfaceData);
|
|
PreLightData preLightData = GetPreLightData(normalizedWorldViewDir, posInput, bsdfData);
|
|
|
|
#ifdef CUSTOM_BAKED_GI
|
|
half4 decodeInstructions = half4( LIGHTMAP_HDR_MULTIPLIER, LIGHTMAP_HDR_EXPONENT, 0.0h, 0.0h );
|
|
builtinData.bakeDiffuseLighting = UnpackLightmapRGBM( bakedGI, decodeInstructions ) * EMISSIVE_RGBM_SCALE * bsdfData.diffuseColor;
|
|
#endif
|
|
|
|
outColor = float4(0.0, 0.0, 0.0, 0.0);
|
|
#ifdef _SURFACE_TYPE_TRANSPARENT
|
|
uint featureFlags = LIGHT_FEATURE_MASK_FLAGS_TRANSPARENT;
|
|
#else
|
|
uint featureFlags = LIGHT_FEATURE_MASK_FLAGS_OPAQUE;
|
|
#endif
|
|
//float3 diffuseLighting;
|
|
//float3 specularLighting;
|
|
|
|
//LightLoop(normalizedWorldViewDir, posInput, preLightData, bsdfData, builtinData, featureFlags, diffuseLighting, specularLighting);
|
|
LightLoopOutput lightLoopOutput;
|
|
LightLoop(normalizedWorldViewDir, posInput, preLightData, bsdfData, builtinData, featureFlags, lightLoopOutput);
|
|
|
|
// Alias
|
|
float3 diffuseLighting = lightLoopOutput.diffuseLighting;
|
|
float3 specularLighting = lightLoopOutput.specularLighting;
|
|
|
|
diffuseLighting *= GetCurrentExposureMultiplier();
|
|
specularLighting *= GetCurrentExposureMultiplier();
|
|
|
|
#ifdef OUTPUT_SPLIT_LIGHTING
|
|
if (_EnableSubsurfaceScattering != 0 && ShouldOutputSplitLighting(bsdfData))
|
|
{
|
|
outColor = float4(specularLighting, 1.0);
|
|
outDiffuseLighting = float4(TagLightingForSSS(diffuseLighting), 1.0);
|
|
}
|
|
else
|
|
{
|
|
outColor = float4(diffuseLighting + specularLighting, 1.0);
|
|
outDiffuseLighting = 0;
|
|
}
|
|
ENCODE_INTO_SSSBUFFER(surfaceData, posInput.positionSS, outSSSBuffer);
|
|
#else
|
|
outColor = ApplyBlendMode(diffuseLighting, specularLighting, builtinData.opacity);
|
|
outColor = EvaluateAtmosphericScattering(posInput, normalizedWorldViewDir, outColor);
|
|
#endif
|
|
|
|
outputDepth = posInput.deviceDepth;
|
|
}
|
|
ENDHLSL
|
|
}
|
|
|
|
}
|
|
Fallback "Hidden/InternalErrorShader"
|
|
|
|
CustomEditor "ASEMaterialInspector"
|
|
}
|
|
/*ASEBEGIN
|
|
Version=19201
|
|
Node;AmplifyShaderEditor.TransformPositionNode;67;-1424,448;Inherit;False;Object;World;False;Fast;True;1;0;FLOAT3;0,0,0;False;4;FLOAT3;0;FLOAT;1;FLOAT;2;FLOAT;3
|
|
Node;AmplifyShaderEditor.SimpleAddOpNode;37;-1184,480;Inherit;False;2;2;0;FLOAT;0;False;1;FLOAT;0;False;1;FLOAT;0
|
|
Node;AmplifyShaderEditor.SinOpNode;28;-1040,480;Inherit;False;1;0;FLOAT;0;False;1;FLOAT;0
|
|
Node;AmplifyShaderEditor.AbsOpNode;31;-896,480;Inherit;False;1;0;FLOAT;0;False;1;FLOAT;0
|
|
Node;AmplifyShaderEditor.HSVToRGBNode;33;-720,464;Float;False;3;0;FLOAT;0;False;1;FLOAT;0;False;2;FLOAT;0;False;4;FLOAT3;0;FLOAT;1;FLOAT;2;FLOAT;3
|
|
Node;AmplifyShaderEditor.SimpleMultiplyOpNode;34;-448,432;Inherit;False;2;2;0;FLOAT;0;False;1;FLOAT3;0,0,0;False;1;FLOAT3;0
|
|
Node;AmplifyShaderEditor.LerpOp;36;-240,336;Inherit;False;3;0;FLOAT3;0,0,0;False;1;FLOAT3;0,0,0;False;2;FLOAT;0;False;1;FLOAT3;0
|
|
Node;AmplifyShaderEditor.BreakToComponentsNode;38;-812.5283,238.2642;Inherit;False;FLOAT4;1;0;FLOAT4;0,0,0,0;False;16;FLOAT;0;FLOAT;1;FLOAT;2;FLOAT;3;FLOAT;4;FLOAT;5;FLOAT;6;FLOAT;7;FLOAT;8;FLOAT;9;FLOAT;10;FLOAT;11;FLOAT;12;FLOAT;13;FLOAT;14;FLOAT;15
|
|
Node;AmplifyShaderEditor.TemplateMultiPassMasterNode;68;5,0;Float;False;True;-1;2;ASEMaterialInspector;0;16;Impostors/Custom/Colored Barrels;87e83e0e165df8c42a86552d2fc010f1;True;GBuffer;0;0;GBuffer;26;False;True;1;1;False;;0;False;;0;1;False;;0;False;;False;False;False;False;False;False;False;False;False;False;False;False;True;0;False;;False;False;False;False;False;False;False;False;False;False;False;True;1;False;;True;3;False;;False;True;4;RenderPipeline=HDRenderPipeline;RenderType=Opaque=RenderType;Queue=Geometry=Queue=0;ImpostorType=Octahedron;True;5;True;8;d3d11;metal;vulkan;xboxone;xboxseries;playstation;ps4;switch;0;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;True;True;True;True;True;0;True;_LightLayersMaskBuffer4;False;False;False;False;False;False;False;True;True;10;False;;255;False;;14;False;;7;False;;3;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;False;False;False;False;True;1;LightMode=GBuffer;False;False;0;Hidden/InternalErrorShader;0;0;Standard;16;Material Type,InvertActionOnDeselection;4;638261905476077953;Energy Conserving Specular,InvertActionOnDeselection;1;638261905502503163; Transmission,InvertActionOnDeselection;0;0;Surface Type;0;0;Alpha Cutoff;0;0;Receive Decals;1;0;Receives SSR;1;0;Specular AA;0;0;Specular Occlusion Mode;0;0;Distortion;0;0;Distortion Mode;0;0;Distortion Depth Test;0;0;Blend Preserves Specular;1;0;Fog;1;0;Draw Before Refraction;0;0;Refraction Model;0;0;0;8;True;True;True;True;True;True;False;True;False;;False;0
|
|
Node;AmplifyShaderEditor.TemplateMultiPassMasterNode;69;5,0;Float;False;False;-1;2;ASEMaterialInspector;0;1;New Amplify Shader;87e83e0e165df8c42a86552d2fc010f1;True;SceneSelectionPass;0;1;SceneSelectionPass;0;False;True;1;1;False;;0;False;;0;1;False;;0;False;;False;False;False;False;False;False;False;False;False;False;False;False;True;0;False;;False;False;False;False;False;False;False;False;False;False;False;True;1;False;;True;3;False;;False;True;3;RenderPipeline=HDRenderPipeline;RenderType=Opaque=RenderType;Queue=Geometry=Queue=0;True;5;True;8;d3d11;metal;vulkan;xboxone;xboxseries;playstation;ps4;switch;0;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;True;False;False;False;False;0;False;;False;False;False;False;False;False;False;False;False;False;False;False;True;1;LightMode=SceneSelectionPass;False;False;0;Hidden/InternalErrorShader;0;0;Standard;0;False;0
|
|
Node;AmplifyShaderEditor.TemplateMultiPassMasterNode;70;5,0;Float;False;False;-1;2;ASEMaterialInspector;0;1;New Amplify Shader;87e83e0e165df8c42a86552d2fc010f1;True;META;0;2;META;0;False;True;1;1;False;;0;False;;0;1;False;;0;False;;False;False;False;False;False;False;False;False;False;False;False;False;True;0;False;;False;False;False;False;False;False;False;False;False;False;False;True;1;False;;True;3;False;;False;True;3;RenderPipeline=HDRenderPipeline;RenderType=Opaque=RenderType;Queue=Geometry=Queue=0;True;5;True;8;d3d11;metal;vulkan;xboxone;xboxseries;playstation;ps4;switch;0;False;False;False;False;False;False;False;False;False;False;False;False;False;False;True;2;False;;False;False;False;False;False;False;False;False;False;False;False;False;False;False;True;1;LightMode=Meta;False;False;0;Hidden/InternalErrorShader;0;0;Standard;0;False;0
|
|
Node;AmplifyShaderEditor.TemplateMultiPassMasterNode;71;5,0;Float;False;False;-1;2;ASEMaterialInspector;0;1;New Amplify Shader;87e83e0e165df8c42a86552d2fc010f1;True;ShadowCaster;0;3;ShadowCaster;0;False;True;1;1;False;;0;False;;0;1;False;;0;False;;False;False;False;False;False;False;False;False;False;False;False;False;True;0;False;;False;False;False;False;False;False;False;False;False;False;False;True;1;False;;True;3;False;;False;True;3;RenderPipeline=HDRenderPipeline;RenderType=Opaque=RenderType;Queue=Geometry=Queue=0;True;5;True;8;d3d11;metal;vulkan;xboxone;xboxseries;playstation;ps4;switch;0;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;True;False;False;False;False;0;False;;False;False;False;False;False;False;False;False;False;False;False;False;True;1;LightMode=ShadowCaster;False;False;0;Hidden/InternalErrorShader;0;0;Standard;0;False;0
|
|
Node;AmplifyShaderEditor.TemplateMultiPassMasterNode;72;5,0;Float;False;False;-1;2;ASEMaterialInspector;0;1;New Amplify Shader;87e83e0e165df8c42a86552d2fc010f1;True;DepthOnly;0;4;DepthOnly;0;False;True;1;1;False;;0;False;;0;1;False;;0;False;;False;False;False;False;False;False;False;False;False;False;False;False;True;0;False;;False;False;False;False;False;False;False;False;False;False;False;True;1;False;;True;3;False;;False;True;3;RenderPipeline=HDRenderPipeline;RenderType=Opaque=RenderType;Queue=Geometry=Queue=0;True;5;True;8;d3d11;metal;vulkan;xboxone;xboxseries;playstation;ps4;switch;0;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;True;1;LightMode=DepthOnly;False;False;0;Hidden/InternalErrorShader;0;0;Standard;0;False;0
|
|
Node;AmplifyShaderEditor.TemplateMultiPassMasterNode;73;5,0;Float;False;False;-1;2;ASEMaterialInspector;0;1;New Amplify Shader;87e83e0e165df8c42a86552d2fc010f1;True;Motion Vectors;0;5;Motion Vectors;0;False;True;1;1;False;;0;False;;0;1;False;;0;False;;False;False;False;False;False;False;False;False;False;False;False;False;True;0;False;;False;False;False;False;False;False;False;False;False;False;False;True;1;False;;True;3;False;;False;True;3;RenderPipeline=HDRenderPipeline;RenderType=Opaque=RenderType;Queue=Geometry=Queue=0;True;5;True;8;d3d11;metal;vulkan;xboxone;xboxseries;playstation;ps4;switch;0;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;True;True;40;False;;255;False;;40;False;;7;False;;3;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;False;False;False;False;True;1;LightMode=MotionVectors;False;False;0;Hidden/InternalErrorShader;0;0;Standard;0;False;0
|
|
Node;AmplifyShaderEditor.TemplateMultiPassMasterNode;74;5,0;Float;False;False;-1;2;ASEMaterialInspector;0;1;New Amplify Shader;87e83e0e165df8c42a86552d2fc010f1;True;Distortion;0;6;Distortion;2;False;True;1;1;False;;0;False;;0;1;False;;0;False;;False;False;False;False;False;False;False;False;False;False;False;False;True;0;False;;False;False;False;False;False;False;False;False;False;False;False;True;1;False;;True;3;False;;False;True;3;RenderPipeline=HDRenderPipeline;RenderType=Opaque=RenderType;Queue=Geometry=Queue=0;True;5;True;8;d3d11;metal;vulkan;xboxone;xboxseries;playstation;ps4;switch;0;False;True;4;1;False;;1;False;;4;1;False;;1;False;;True;1;False;;5;False;;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;True;3;False;;False;True;1;LightMode=DistortionVectors;False;False;0;Hidden/InternalErrorShader;0;0;Standard;0;False;0
|
|
Node;AmplifyShaderEditor.TemplateMultiPassMasterNode;75;5,0;Float;False;False;-1;2;ASEMaterialInspector;0;1;New Amplify Shader;87e83e0e165df8c42a86552d2fc010f1;True;Forward;0;7;Forward;0;False;True;1;1;False;;0;False;;0;1;False;;0;False;;False;False;False;False;False;False;False;False;False;False;False;False;True;0;False;;False;False;False;False;False;False;False;False;False;False;False;True;1;False;;True;3;False;;False;True;3;RenderPipeline=HDRenderPipeline;RenderType=Opaque=RenderType;Queue=Geometry=Queue=0;True;5;True;8;d3d11;metal;vulkan;xboxone;xboxseries;playstation;ps4;switch;0;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;True;True;True;True;True;0;True;_ColorMaskTransparentVelOne;False;True;True;True;True;True;0;True;_ColorMaskTransparentVelTwo;False;False;False;True;True;10;False;;255;False;;14;False;;7;False;;3;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;False;False;False;False;True;1;LightMode=Forward;False;False;0;Hidden/InternalErrorShader;0;0;Standard;0;False;0
|
|
Node;AmplifyShaderEditor.RangedFloatNode;30;-914.8141,548.5341;Float;False;Constant;_Float1;Float 1;10;0;Create;True;0;0;0;False;0;False;1;0;0;0;0;1;FLOAT;0
|
|
Node;AmplifyShaderEditor.RangedFloatNode;29;-917.941,616.0258;Float;False;Constant;_Float0;Float 0;4;0;Create;True;0;0;0;False;0;False;1;0;0;0;0;1;FLOAT;0
|
|
Node;AmplifyShaderEditor.TexturePropertyNode;25;-1367.822,-11.22142;Float;True;Property;_Mask;Mask;4;1;[NoScaleOffset];Create;True;0;0;0;False;0;False;None;None;False;white;Auto;Texture2D;-1;0;2;SAMPLER2D;0;SAMPLERSTATE;1
|
|
Node;AmplifyShaderEditor.AmplifyImpostorNode;17;-1095.646,-11.5097;Inherit;False;9901;Octahedron;False;False;False;12;11;10;13;17;15;16;14;0;1;2;3;7;8;9;5;6;1;Specular;False;9;0;SAMPLER2D;sampler017;False;1;SAMPLER2D;;False;2;SAMPLER2D;;False;3;SAMPLER2D;;False;4;SAMPLER2D;;False;5;SAMPLER2D;;False;6;SAMPLER2D;;False;7;SAMPLER2D;;False;8;SAMPLERSTATE;;False;17;FLOAT4;8;FLOAT4;9;FLOAT4;10;FLOAT4;11;FLOAT4;12;FLOAT4;13;FLOAT4;14;FLOAT4;15;FLOAT3;0;FLOAT3;1;FLOAT3;2;FLOAT3;3;FLOAT;4;FLOAT;5;FLOAT;6;FLOAT3;7;FLOAT3;16
|
|
WireConnection;37;0;67;1
|
|
WireConnection;37;1;67;3
|
|
WireConnection;28;0;37;0
|
|
WireConnection;31;0;28;0
|
|
WireConnection;33;0;31;0
|
|
WireConnection;33;1;30;0
|
|
WireConnection;33;2;29;0
|
|
WireConnection;34;0;38;3
|
|
WireConnection;34;1;33;0
|
|
WireConnection;36;0;17;0
|
|
WireConnection;36;1;34;0
|
|
WireConnection;36;2;38;3
|
|
WireConnection;38;0;17;8
|
|
WireConnection;68;0;36;0
|
|
WireConnection;68;1;17;1
|
|
WireConnection;68;5;38;0
|
|
WireConnection;68;7;38;1
|
|
WireConnection;68;8;38;2
|
|
WireConnection;68;9;17;6
|
|
WireConnection;17;0;25;0
|
|
ASEEND*/
|
|
//CHKSM=CE7B5BE7B642E35289B4BC5B32E38ADCE8E62CD2 |