2021-12-15 16:29:44 +03:00

157 lines
5.4 KiB
HLSL

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