////////////////////////////////////////////////////// // MK Toon ShadowCaster Program // // // // Created by Michael Kremmel // // www.michaelkremmel.de // // Copyright © 2021 All rights reserved. // ////////////////////////////////////////////////////// #ifndef MK_TOON_SHADOWCASTER #define MK_TOON_SHADOWCASTER #include "../Core.hlsl" #if defined(MK_URP) #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl" #elif defined(MK_LWRP) #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl" #include "Packages/com.unity.render-pipelines.lightweight/ShaderLibrary/Shadows.hlsl" #endif #include "../Surface.hlsl" #include "Data.hlsl" //This should be excluded from the CBuffer uniform float3 _LightDirection; ///////////////////////////////////////////////////////////////////////////////////////////// // VERTEX SHADER ///////////////////////////////////////////////////////////////////////////////////////////// void ShadowCasterVert ( VertexInputShadowCaster VERTEX_INPUT, out VertexOutputShadowCaster vertexOutput ,out float4 svPositionClip : SV_POSITION ) { UNITY_SETUP_INSTANCE_ID(VERTEX_INPUT); INITIALIZE_STRUCT(VertexOutputShadowCaster, vertexOutput); UNITY_TRANSFER_INSTANCE_ID(VERTEX_INPUT, vertexOutput); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(vertexOutput); #ifdef MK_VERTEX_ANIMATION VERTEX_INPUT.vertex.xyz = VertexAnimation(PASS_VERTEX_ANIMATION_ARG(_VertexAnimationMap, PASS_VERTEX_ANIMATION_UV(VERTEX_INPUT.texcoord0.xy), _VertexAnimationIntensity, _VertexAnimationFrequency.xyz, VERTEX_INPUT.vertex.xyz, VERTEX_INPUT.normal)); #endif #if defined(MK_VERTCLR) || defined(MK_POLYBRUSH) vertexOutput.color = VERTEX_INPUT.color; #endif #if defined(MK_TCM) vertexOutput.uv = VERTEX_INPUT.texcoord0.xy * _AlbedoMap_ST.xy + _AlbedoMap_ST.zw; #endif #if defined(MK_URP) || defined(MK_LWRP) half3 normalWorld = ComputeNormalWorld(VERTEX_INPUT.normal); #endif #ifdef MK_PARALLAX half3 viewTangent = ComputeViewTangent(ComputeViewObject(VERTEX_INPUT.vertex.xyz), VERTEX_INPUT.normal, VERTEX_INPUT.tangent, cross(VERTEX_INPUT.normal, VERTEX_INPUT.tangent.xyz) * VERTEX_INPUT.tangent.w * unity_WorldTransformParams.w); #endif #if defined(MK_URP) float3 positionWorld = mul(MATRIX_M, float4(VERTEX_INPUT.vertex.xyz, 1.0)).xyz; svPositionClip = mul(MATRIX_VP, float4(ApplyShadowBias(positionWorld, normalWorld, _LightDirection), 1.0)); #if UNITY_REVERSED_Z svPositionClip.z = min(svPositionClip.z, svPositionClip.w * UNITY_NEAR_CLIP_VALUE); #else svPositionClip.z = max(svPositionClip.z, svPositionClip.w * UNITY_NEAR_CLIP_VALUE); #endif #elif defined(MK_LWRP) float3 positionWorld = mul(MATRIX_M, float4(VERTEX_INPUT.vertex.xyz, 1.0)).xyz; float invNdotL = 1.0 - saturate(dot(_LightDirection, normalWorld)); float scale = invNdotL * _ShadowBias.y; positionWorld = _LightDirection * _ShadowBias.xxx + positionWorld; positionWorld = normalWorld * scale.xxx + positionWorld; svPositionClip = mul(MATRIX_VP, float4(positionWorld, 1)); #if UNITY_REVERSED_Z svPositionClip.z = min(svPositionClip.z, svPositionClip.w * UNITY_NEAR_CLIP_VALUE); #else svPositionClip.z = max(svPositionClip.z, svPositionClip.w * UNITY_NEAR_CLIP_VALUE); #endif #else TRANSFER_SHADOW_CASTER_NOPOS(vertexOutput, svPositionClip) #endif } ///////////////////////////////////////////////////////////////////////////////////////////// // FRAGMENT SHADER ///////////////////////////////////////////////////////////////////////////////////////////// half4 ShadowCasterFrag ( VertexOutputShadowCaster vertexOutput #ifdef MK_LEGACY_RP #if UNITY_VERSION >= 20171 ,UNITY_POSITION(vpos) #else ,UNITY_VPOS_TYPE vpos : VPOS #endif #endif ) : SV_Target { UNITY_SETUP_INSTANCE_ID(vertexOutput); UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(vertexOutput); MKSurfaceData surfaceData = ComputeSurfaceData ( PASS_POSITION_WORLD_ARG(0) PASS_FOG_FACTOR_WORLD_ARG(0) PASS_BASE_UV_ARG(float4(vertexOutput.uv.xy, 0, 0)) PASS_LIGHTMAP_UV_ARG(0) PASS_VERTEX_COLOR_ARG(vertexOutput.color) PASS_NORMAL_WORLD_ARG(1) PASS_VERTEX_LIGHTING_ARG(0) PASS_TANGENT_WORLD_ARG(1) PASS_VIEW_TANGENT_ARG(vertexOutput.viewTangent) PASS_BITANGENT_WORLD_ARG(1) PASS_POSITION_CLIP_ARG(0) PASS_NULL_CLIP_ARG(0) PASS_FLIPBOOK_UV_ARG(0) ); Surface surface = InitSurface(surfaceData, PASS_TEXTURE_2D(_AlbedoMap, SAMPLER_REPEAT_MAIN), _AlbedoColor); #if defined(MK_URP) || defined(MK_LWRP) return 0; #else #ifdef MK_SURFACE_TYPE_TRANSPARENT #ifdef MK_TOON_DITHER_MASK /* #ifdef LOD_FADE_CROSSFADE #define _LOD_FADE_ON_ALPHA alpha *= unity_LODFade.y; #endif */ // dither mask alpha blending half alphaRef = tex3D(_DitherMaskLOD, float3(vpos.xy*0.25,surface.alpha*0.9375)).a; Clip0(alphaRef); #else Clip0(surface.alpha - 0.5); #endif /* //Disabled for now #ifdef LOD_FADE_CROSSFADE #ifdef _LOD_FADE_ON_ALPHA #undef _LOD_FADE_ON_ALPHA #else UnityApplyDitherCrossFade(vpos.xy); #endif #endif */ #endif SHADOW_CASTER_FRAGMENT(vertexOutput) #endif } #endif