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