#ifndef LIL_MACRO_INCLUDED #define LIL_MACRO_INCLUDED //------------------------------------------------------------------------------------------------------------------------------ // Setting // The version of SRP is automatically determined, but an error may occur in a specific version. // In that case, define the version. // Example: HDRP 4.8.0 // #define LIL_SRP_VERSION_MAJOR 4 // #define LIL_SRP_VERSION_MINOR 8 // Transparent mode on subpass (Default : 0) // 0 : Cutout // 1 : Dither #define LIL_SUBPASS_TRANSPARENT_MODE 0 // Refraction blur #define LIL_REFRACTION_SAMPNUM 8 #define LIL_REFRACTION_GAUSDIST(i) exp(-(float)i*(float)i/(LIL_REFRACTION_SAMPNUM*LIL_REFRACTION_SAMPNUM/2.0)) // Antialias mode (Default : 1) // 0 : Off // 1 : On #define LIL_ANTIALIAS_MODE 1 // Light Probe Proxy Volumes (Default : 0) #define LIL_LPPV_MODE 0 // 0 : Off // 1 : On // Additional Lights Mode (Default : 3 or 4) // 0 : Off // 1 : In Vertex Shader // 2 : In Fragment Shader // 3 : Add to main light // 4 : Add to main light with direction // 5 : Add to main light with direction in Fragment Shader #if defined(LIL_BRP) #define LIL_ADDITIONAL_LIGHT_MODE 3 #define LIL_ADDITIONAL_LIGHT_STRENGTH _VertexLightStrength #elif defined(LIL_HDRP) #define LIL_ADDITIONAL_LIGHT_MODE 5 #define LIL_ADDITIONAL_LIGHT_STRENGTH 1 #elif defined(USE_CLUSTERED_LIGHTING) && USE_CLUSTERED_LIGHTING || defined(USE_FORWARD_PLUS) && USE_FORWARD_PLUS #define LIL_ADDITIONAL_LIGHT_MODE 5 #define LIL_ADDITIONAL_LIGHT_STRENGTH 1 #else #define LIL_ADDITIONAL_LIGHT_MODE 4 #define LIL_ADDITIONAL_LIGHT_STRENGTH 1 #endif // Near clip threshold for clipping canceller (Default : 0.1) #define LIL_NEARCLIP_THRESHOLD 0.1 //------------------------------------------------------------------------------------------------------------------------------ // Version #if !defined(LIL_SRP_VERSION_MAJOR) #if UNITY_VERSION < 201810 #define LIL_SRP_VERSION_MAJOR 0 #elif UNITY_VERSION < 201820 #define LIL_SRP_VERSION_MAJOR 1 #elif UNITY_VERSION < 201830 #define LIL_SRP_VERSION_MAJOR 2 #elif UNITY_VERSION < 201840 #define LIL_SRP_VERSION_MAJOR 3 #elif UNITY_VERSION < 201910 #define LIL_SRP_VERSION_MAJOR 4 #elif UNITY_VERSION < 201920 #define LIL_SRP_VERSION_MAJOR 5 #elif UNITY_VERSION < 201930 #define LIL_SRP_VERSION_MAJOR 6 #elif UNITY_VERSION < 201940 #define LIL_SRP_VERSION_MAJOR 7 #elif UNITY_VERSION < 202010 #define LIL_SRP_VERSION_MAJOR 8 #elif UNITY_VERSION < 202020 #define LIL_SRP_VERSION_MAJOR 9 #elif UNITY_VERSION < 202030 #define LIL_SRP_VERSION_MAJOR 10 #elif UNITY_VERSION < 202110 #define LIL_SRP_VERSION_MAJOR 11 #elif UNITY_VERSION < 202120 #define LIL_SRP_VERSION_MAJOR 12 #elif UNITY_VERSION < 202210 #define LIL_SRP_VERSION_MAJOR 13 #else #define LIL_SRP_VERSION_MAJOR 14 #endif #endif #if !defined(LIL_SRP_VERSION_MINOR) #define LIL_SRP_VERSION_MINOR 99 #endif #if !defined(LIL_SRP_VERSION_GREATER_EQUAL) #define LIL_SRP_VERSION_GREATER_EQUAL(major, minor) ((LIL_SRP_VERSION_MAJOR > major) || ((LIL_SRP_VERSION_MAJOR == major) && (LIL_SRP_VERSION_MINOR >= minor))) #define LIL_SRP_VERSION_LOWER(major, minor) ((LIL_SRP_VERSION_MAJOR < major) || ((LIL_SRP_VERSION_MAJOR == major) && (LIL_SRP_VERSION_MINOR < minor))) #define LIL_SRP_VERSION_EQUAL(major, minor) ((LIL_SRP_VERSION_MAJOR == major) && (LIL_SRP_VERSION_MINOR == minor)) #endif //------------------------------------------------------------------------------------------------------------------------------ // Replace Macro #define LIL_BRANCH #define LIL_VERTEX_INPUT_INSTANCE_ID UNITY_VERTEX_INPUT_INSTANCE_ID #define LIL_VERTEX_OUTPUT_STEREO UNITY_VERTEX_OUTPUT_STEREO #define LIL_SETUP_INSTANCE_ID(i) UNITY_SETUP_INSTANCE_ID(i) #define LIL_TRANSFER_INSTANCE_ID(i,o) UNITY_TRANSFER_INSTANCE_ID(i,o) #define LIL_INITIALIZE_VERTEX_OUTPUT_STEREO(o) UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o) #define LIL_TRANSFER_VERTEX_OUTPUT_STEREO(i,o) UNITY_TRANSFER_VERTEX_OUTPUT_STEREO(i,o) #define LIL_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i) UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i) // Gamma #if defined(UNITY_COLORSPACE_GAMMA) #define LIL_COLORSPACE_GAMMA float lilLuminance(float3 rgb) { return dot(rgb, float3(0.22, 0.707, 0.071)); } #else float lilLuminance(float3 rgb) { return dot(rgb, float3(0.0396819152, 0.458021790, 0.00609653955)); } #endif // Initialize struct #if defined(UNITY_INITIALIZE_OUTPUT) #define LIL_INITIALIZE_STRUCT(type,name) UNITY_INITIALIZE_OUTPUT(type,name) #else #define LIL_INITIALIZE_STRUCT(type,name) name = (type)0 #endif // Additional Light #if (!defined(LIL_PASS_FORWARDADD) && defined(UNITY_SHOULD_SAMPLE_SH)) || defined(_ADDITIONAL_LIGHTS) || defined(_ADDITIONAL_LIGHTS_VERTEX) || defined(LIL_HDRP) #define LIL_USE_ADDITIONALLIGHT #if LIL_ADDITIONAL_LIGHT_MODE == 1 #define LIL_USE_ADDITIONALLIGHT_VS #elif LIL_ADDITIONAL_LIGHT_MODE == 2 #define LIL_USE_ADDITIONALLIGHT_PS #elif LIL_ADDITIONAL_LIGHT_MODE == 3 #define LIL_USE_ADDITIONALLIGHT_MAIN #elif LIL_ADDITIONAL_LIGHT_MODE == 4 #define LIL_USE_ADDITIONALLIGHT_MAINDIR #elif LIL_ADDITIONAL_LIGHT_MODE == 5 #define LIL_USE_ADDITIONALLIGHT_MAINDIR_PS #endif #endif // Lightmap #if defined(LIGHTMAP_ON) #define LIL_USE_LIGHTMAP #endif #if defined(DYNAMICLIGHTMAP_ON) && !(defined(LIL_URP) && LIL_SRP_VERSION_LOWER(12, 0)) #define LIL_USE_DYNAMICLIGHTMAP #endif #if defined(DIRLIGHTMAP_COMBINED) #define LIL_USE_DIRLIGHTMAP #endif #if defined(SHADOWS_SHADOWMASK) #define LIL_LIGHTMODE_SHADOWMASK #endif #if defined(LIGHTMAP_SHADOW_MIXING) #define LIL_LIGHTMODE_SUBTRACTIVE #endif // DOTS instancing #if defined(UNITY_DOTS_INSTANCING_ENABLED) #define LIL_USE_DOTS_INSTANCING #endif // Conbine #if defined(SHADOWS_SCREEN) || defined(_MAIN_LIGHT_SHADOWS) || defined(_MAIN_LIGHT_SHADOWS_CASCADE) || defined(_MAIN_LIGHT_SHADOWS_SCREEN) || defined(SHADOW_LOW) || defined(SHADOW_MEDIUM) || defined(SHADOW_HIGH) #define LIL_USE_SHADOW #endif #if defined(LIL_USE_LIGHTMAP) || defined(LIL_USE_DYNAMICLIGHTMAP) || defined(LIL_USE_DIRLIGHTMAP) || defined(LIL_LIGHTMODE_SHADOWMASK) #define LIL_USE_LIGHTMAP_UV #endif // Directional Lightmap #undef LIL_USE_DIRLIGHTMAP // Light Probe Proxy Volumes #if (LIL_LPPV_MODE != 0) && UNITY_LIGHT_PROBE_PROXY_VOLUME #define LIL_USE_LPPV #endif //------------------------------------------------------------------------------------------------------------------------------ // Optimization Macro // tangentWS / bitangentWS / normalWS #if defined(LIL_FEATURE_NORMAL_1ST) || defined(LIL_FEATURE_NORMAL_2ND) || defined(LIL_FEATURE_ANISOTROPY) || defined(LIL_FEATURE_MatCapBumpMap) || defined(LIL_FEATURE_MatCap2ndBumpMap) || defined(LIL_FEATURE_EMISSION_1ST) || defined(LIL_FEATURE_EMISSION_2ND) || defined(LIL_FEATURE_PARALLAX) #define LIL_SHOULD_TBN #endif // tangentOS (vertex input) #if defined(LIL_SHOULD_TBN) || (defined(LIL_FEATURE_MAIN2ND) || defined(LIL_FEATURE_MAIN3RD)) && defined(LIL_FEATURE_DECAL) #define LIL_SHOULD_TANGENT #endif // normalOS (vertex input) #if defined(LIL_SHOULD_TANGENT) || defined(LIL_FEATURE_SHADOW) || defined(LIL_FEATURE_REFLECTION) || defined(LIL_FEATURE_MATCAP) || defined(LIL_FEATURE_MATCAP_2ND) || defined(LIL_FEATURE_RIMLIGHT) || defined(LIL_FEATURE_GLITTER) || defined(LIL_FEATURE_BACKLIGHT) || defined(LIL_FEATURE_AUDIOLINK) || defined(LIL_REFRACTION) || (defined(LIL_USE_LIGHTMAP) && defined(LIL_LIGHTMODE_SUBTRACTIVE)) || defined(LIL_HDRP) #define LIL_SHOULD_NORMAL #endif // positionOS #if (defined(LIL_FEATURE_MAIN2ND) || defined(LIL_FEATURE_MAIN3RD)) && defined(LIL_FEATURE_LAYER_DISSOLVE) || defined(LIL_FEATURE_GLITTER) || defined(LIL_FEATURE_DISSOLVE) || defined(LIL_FEATURE_AUDIOLINK) #define LIL_SHOULD_POSITION_OS #endif // positionWS #if defined(SHADOWS_SCREEN) || defined(LIL_PASS_FORWARDADD) || defined(LIL_FEATURE_MAIN2ND) || defined(LIL_FEATURE_MAIN3RD) || defined(LIL_FEATURE_ANISOTROPY) || defined(LIL_FEATURE_RECEIVE_SHADOW) || defined(LIL_FEATURE_REFLECTION) || defined(LIL_FEATURE_MATCAP) || defined(LIL_FEATURE_MATCAP_2ND) || defined(LIL_FEATURE_RIMLIGHT) || defined(LIL_FEATURE_GLITTER) || defined(LIL_FEATURE_BACKLIGHT) || defined(LIL_FEATURE_EMISSION_1ST) || defined(LIL_FEATURE_EMISSION_2ND) || defined(LIL_FEATURE_PARALLAX) || defined(LIL_FEATURE_DISTANCE_FADE) || defined(LIL_REFRACTION) || !defined(LIL_BRP) || defined(LIL_USE_LPPV) #define LIL_SHOULD_POSITION_WS #endif // uv1 #if defined(LIL_FEATURE_MATCAP) || defined(LIL_FEATURE_MATCAP_2ND) || defined(LIL_FEATURE_GLITTER) #define LIL_SHOULD_UV1 #endif //------------------------------------------------------------------------------------------------------------------------------ // Screen params #if defined(LIL_URP) #define LIL_SCREENPARAMS _ScaledScreenParams #else #define LIL_SCREENPARAMS _ScreenParams #endif //------------------------------------------------------------------------------------------------------------------------------ // API Macro #if defined(TEXTURE2D) #undef TEXTURE2D #endif #if defined(TEXTURE2D_FLOAT) #undef TEXTURE2D_FLOAT #endif #if defined(TEXTURE2D_ARRAY) #undef TEXTURE2D_ARRAY #endif #if defined(TEXTURE3D) #undef TEXTURE3D #endif #if defined(TEXTURECUBE) #undef TEXTURECUBE #endif #if defined(SAMPLER) #undef SAMPLER #endif #if defined(SHADER_API_D3D11_9X) #define LIL_NOPERSPECTIVE #define LIL_CENTROID #else #define LIL_NOPERSPECTIVE noperspective #define LIL_CENTROID centroid #endif #define LIL_VECTOR_INTERPOLATION #if defined(SHADER_API_D3D9) #undef LIL_ANTIALIAS_MODE #define LIL_ANTIALIAS_MODE 0 #endif #if defined(SHADER_API_D3D11_9X) #define LIL_VFACE(facing) #define LIL_COPY_VFACE(o) #undef LIL_USE_LIGHTMAP #elif defined(SHADER_API_GLCORE) || defined(SHADER_API_GLES) || defined(SHADER_API_D3D9) #define LIL_VFACE(facing) , float facing : VFACE #define LIL_COPY_VFACE(o) o = facing #else #define LIL_VFACE(facing) , bool isFrontFace : SV_IsFrontFace #define LIL_COPY_VFACE(o) o = isFrontFace ? 1 : -1 #endif #if defined(SHADER_API_MOBILE) || defined(SHADER_API_GLES) #define LIL_NOT_SUPPORT_VERTEXID #endif #if defined(SHADER_API_D3D9) || (defined(SHADER_TARGET_SURFACE_ANALYSIS) && defined(SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER)) || defined(SHADER_TARGET_SURFACE_ANALYSIS) #define LIL_SAMPLE_1D(tex,samp,uv) tex2D(tex,float2(uv,0.5)) #define LIL_SAMPLE_1D_LOD(tex,samp,uv,lod) tex2Dlod(tex,float4(uv,0.5,0,lod)) #define LIL_SAMPLE_2D(tex,samp,uv) tex2D(tex,uv) #define LIL_SAMPLE_2D_CS(tex,uv) tex2D(tex,uv/LIL_SCREENPARAMS.xy) #define LIL_SAMPLE_2D_ST(tex,samp,uv) tex2D(tex,uv*tex##_ST.xy+tex##_ST.zw) #define LIL_SAMPLE_2D_LOD(tex,samp,uv,lod) tex2Dlod(tex,float4(uv,0,lod)) #define LIL_SAMPLE_2D_BIAS(tex,samp,uv,bias) tex2Dbias(tex,float4(uv,0,bias)) #define LIL_SAMPLE_2D_GRAD(tex,samp,uv,dx,dy) tex2Dgrad(tex,uv,dx,dy) #define LIL_SAMPLE_2D_ARRAY(tex,samp,uv,index) tex2DArray(tex,float3(uv,index)) #define LIL_SAMPLE_2D_ARRAY_CS(tex,uv,index) tex2DArray(tex,float3(uv/LIL_SCREENPARAMS.xy,index)) #define LIL_SAMPLE_2D_ARRAY_LOD(tex,samp,uv,index,lod) tex2DArraylod(tex,float4(uv,index,lod)) #define LIL_SAMPLE_3D(tex,samp,uv) tex3D(tex,uv) #define LIL_SAMPLE_CUBE_LOD(tex,samp,uv,lod) texCUBElod(tex,float4(uv,0,lod)) #define TEXTURE2D(tex) sampler2D tex #define TEXTURE2D_FLOAT(tex) sampler2D tex #define TEXTURE2D_ARRAY(tex) sampler2DArray tex #define TEXTURE3D(tex) sampler3D tex #define TEXTURECUBE(tex) samplerCUBE tex #define SAMPLER(samp) #define LIL_SAMP_IN_FUNC(samp) #define LIL_SAMP_IN(samp) #define LIL_LWTEX bool IsEmpty(TEXTURECUBE(tex)) { return false; } bool IsEmpty(TEXTURE2D(tex)) { return false; } bool IsEmpty(TEXTURE2D_ARRAY(tex)) { return false; } bool IsScreenTex(TEXTURE2D(tex)) { return false; } bool IsScreenTex(TEXTURE2D_ARRAY(tex)) { return false; } float lilSampleDither(TEXTURE3D(tex), float2 positionCS, float alpha) { return tex3D(tex, float3(positionCS*0.25,alpha*0.9375)).a; } float2 lilGetWidthAndHeight(TEXTURE2D(tex)) { return float2(0, 0); } float2 lilGetWidthAndHeight(TEXTURE2D_ARRAY(tex)) { return float2(0, 0); } #else #define LIL_SAMPLE_1D(tex,samp,uv) tex.Sample(samp,uv) #define LIL_SAMPLE_1D_LOD(tex,samp,uv,lod) tex.SampleLevel(samp,uv,lod) #define LIL_SAMPLE_2D(tex,samp,uv) tex.Sample(samp,uv) #define LIL_SAMPLE_2D_CS(tex,uv) tex[uint2(uv)] #define LIL_SAMPLE_2D_ST(tex,samp,uv) tex.Sample(samp,uv*tex##_ST.xy+tex##_ST.zw) #define LIL_SAMPLE_2D_LOD(tex,samp,uv,lod) tex.SampleLevel(samp,uv,lod) #define LIL_SAMPLE_2D_BIAS(tex,samp,uv,bias) tex.SampleBias(samp,uv,bias) #define LIL_SAMPLE_2D_GRAD(tex,samp,uv,dx,dy) tex.SampleGrad(samp,uv,dx,dy) #define LIL_SAMPLE_2D_ARRAY(tex,samp,uv,index) tex.Sample(samp,float3(uv,index)) #define LIL_SAMPLE_2D_ARRAY_CS(tex,uv,index) tex[uint3(uv,index)] #define LIL_SAMPLE_2D_ARRAY_LOD(tex,samp,uv,index,lod) tex.SampleLevel(samp,float3(uv,index),lod) #define LIL_SAMPLE_3D(tex,samp,coord) tex.Sample(samp,coord) #define LIL_SAMPLE_CUBE_LOD(tex,samp,uv,lod) tex.SampleLevel(samp,uv,lod) #define TEXTURE2D(tex) Texture2D tex #define TEXTURE2D_FLOAT(tex) Texture2D tex #define TEXTURE2D_ARRAY(tex) Texture2DArray tex #define TEXTURE3D(tex) Texture3D tex #define TEXTURECUBE(tex) TextureCube tex #define SAMPLER(samp) SamplerState samp #define LIL_SAMP_IN_FUNC(samp) , SamplerState samp #define LIL_SAMP_IN(samp) , samp bool IsEmpty(TEXTURECUBE(tex)) { uint width, height, levels; tex.GetDimensions(0, width, height, levels); return width < 15; } bool IsEmpty(TEXTURE2D(tex)) { uint width, height; tex.GetDimensions(width, height); return width < 15; } bool IsEmpty(TEXTURE2D_ARRAY(tex)) { uint width, height, element; tex.GetDimensions(width, height, element); return width < 15; } bool IsScreenTex(TEXTURE2D(tex)) { uint width, height; tex.GetDimensions(width, height); return (abs(width - LIL_SCREENPARAMS.x) + abs(height - LIL_SCREENPARAMS.y)) < 1; } bool IsScreenTex(TEXTURE2D_ARRAY(tex)) { uint width, height, element; tex.GetDimensions(width, height, element); return (abs(width - LIL_SCREENPARAMS.x) + abs(height - LIL_SCREENPARAMS.y)) < 1; } float lilSampleDither(TEXTURE3D(tex), float2 positionCS, float alpha) { uint3 uv = uint3(positionCS, alpha*0.9375*16); uv.xy = uv.xy % 4; return tex[uv].a; } float2 lilGetWidthAndHeight(TEXTURE2D(tex)) { uint width, height; tex.GetDimensions(width, height); return float2(width, height); } float2 lilGetWidthAndHeight(TEXTURE2D_ARRAY(tex)) { uint width, height, element; tex.GetDimensions(width, height, element); return float2(width, height); } #endif #if defined(LIL_FEATURE_PARALLAX) && defined(LIL_FEATURE_POM) #define LIL_SAMPLE_2D_POM(tex,samp,uv,dx,dy) LIL_SAMPLE_2D_GRAD(tex,samp,uv,dx,dy) #else #define LIL_SAMPLE_2D_POM(tex,samp,uv,dx,dy) LIL_SAMPLE_2D(tex,samp,uv) #endif #if defined(UNITY_STEREO_INSTANCING_ENABLED) || defined(UNITY_STEREO_MULTIVIEW_ENABLED) #define TEXTURE2D_SCREEN(tex) TEXTURE2D_ARRAY(tex) #define LIL_SAMPLE_SCREEN(tex,samp,uv) LIL_SAMPLE_2D_ARRAY(tex,samp,uv,(float)unity_StereoEyeIndex) #define LIL_SAMPLE_SCREEN_LOD(tex,samp,uv,lod) LIL_SAMPLE_2D_ARRAY_LOD(tex,samp,uv,(float)unity_StereoEyeIndex,lod) #define LIL_SAMPLE_SCREEN_CS(tex,uv) LIL_SAMPLE_2D_ARRAY_CS(tex,uv,unity_StereoEyeIndex) #else #define TEXTURE2D_SCREEN(tex) TEXTURE2D(tex) #define LIL_SAMPLE_SCREEN(tex,samp,uv) LIL_SAMPLE_2D(tex,samp,uv) #define LIL_SAMPLE_SCREEN_LOD(tex,samp,uv,lod) LIL_SAMPLE_2D_LOD(tex,samp,uv,lod) #define LIL_SAMPLE_SCREEN_CS(tex,uv) LIL_SAMPLE_2D_CS(tex,uv) #endif //------------------------------------------------------------------------------------------------------------------------------ // Macro to absorb pipeline differences // Transform #if defined(LIL_BRP) #define LIL_MATRIX_M unity_ObjectToWorld #define LIL_MATRIX_I_M unity_WorldToObject #define LIL_MATRIX_V UNITY_MATRIX_V #define LIL_MATRIX_VP UNITY_MATRIX_VP #define LIL_MATRIX_P UNITY_MATRIX_P #define LIL_NEGATIVE_SCALE unity_WorldTransformParams.w float3 lilTransformOStoWS(float4 positionOS) { return mul(LIL_MATRIX_M, positionOS).xyz; } float3 lilTransformOStoWS(float3 positionOS) { return mul(LIL_MATRIX_M, float4(positionOS, 1.0)).xyz; } float3 lilTransformWStoOS(float3 positionWS) { return mul(LIL_MATRIX_I_M, float4(positionWS, 1.0)).xyz; } float3 lilTransformWStoVS(float3 positionWS) { return UnityWorldToViewPos(positionWS).xyz; } float4 lilTransformWStoCS(float3 positionWS) { return UnityWorldToClipPos(positionWS); } float4 lilTransformVStoCS(float3 positionVS) { return UnityViewToClipPos(positionVS); } float4 lilTransformCStoSS(float4 positionCS) { return ComputeGrabScreenPos(positionCS); } float4 lilTransformCStoSSFrag(float4 positionCS) { float4 positionSS = float4(positionCS.xyz * positionCS.w, positionCS.w); positionSS.xy = positionSS.xy / LIL_SCREENPARAMS.xy; return positionSS; } #else #if defined(SHADER_STAGE_RAY_TRACING) #define LIL_MATRIX_M ObjectToWorld3x4() #define LIL_MATRIX_I_M WorldToObject3x4() #else #define LIL_MATRIX_M GetObjectToWorldMatrix() #define LIL_MATRIX_I_M GetWorldToObjectMatrix() #endif #define LIL_MATRIX_V GetWorldToViewMatrix() #define LIL_MATRIX_VP GetWorldToHClipMatrix() #define LIL_MATRIX_P GetViewToHClipMatrix() #define LIL_NEGATIVE_SCALE GetOddNegativeScale() float3 lilTransformOStoWS(float4 positionOS) { return TransformObjectToWorld(positionOS.xyz).xyz; } float3 lilTransformOStoWS(float3 positionOS) { return mul(LIL_MATRIX_M, float4(positionOS, 1.0)).xyz; } float3 lilTransformWStoOS(float3 positionWS) { return TransformWorldToObject(positionWS).xyz; } float3 lilTransformWStoVS(float3 positionWS) { return TransformWorldToView(positionWS).xyz; } float4 lilTransformWStoCS(float3 positionWS) { return TransformWorldToHClip(positionWS); } float4 lilTransformVStoCS(float3 positionVS) { return TransformWViewToHClip(positionVS); } float4 lilTransformCStoSS(float4 positionCS) { float4 positionSS = positionCS * 0.5f; positionSS.xy = float2(positionSS.x, positionSS.y * _ProjectionParams.x) + positionSS.w; positionSS.zw = positionCS.zw; return positionSS; } float4 lilTransformCStoSSFrag(float4 positionCS) { float4 positionSS = float4(positionCS.xyz * positionCS.w, positionCS.w); positionSS.xy = positionSS.xy / LIL_SCREENPARAMS.xy; return positionSS; } #endif // Stereo #if defined(LIL_HDRP) #if LIL_SRP_VERSION_GREATER_EQUAL(7, 1) #define LIL_STEREO_MATRIX_V(i) _XRViewMatrix[i] #define LIL_STEREO_CAMERA_POS(i) _XRWorldSpaceCameraPos[i] #else #define LIL_STEREO_MATRIX_V(i) _XRViewConstants[i].viewMatrix #define LIL_STEREO_CAMERA_POS(i) _XRViewConstants[i].worldSpaceCameraPos #endif #else #define LIL_STEREO_MATRIX_V(i) unity_StereoMatrixV[i] #define LIL_STEREO_CAMERA_POS(i) unity_StereoWorldSpaceCameraPos[i] #endif float3 lilToAbsolutePositionWS(float3 positionRWS) { #if (SHADEROPTIONS_CAMERA_RELATIVE_RENDERING != 0) return positionRWS + _WorldSpaceCameraPos.xyz; #else return positionRWS; #endif } float3 lilToRelativePositionWS(float3 positionWS) { #if (SHADEROPTIONS_CAMERA_RELATIVE_RENDERING != 0) return positionWS - _WorldSpaceCameraPos.xyz; #else return positionWS; #endif } float3 lilTransformDirOStoWS(float3 directionOS, bool doNormalize) { if(doNormalize) return normalize(mul((float3x3)LIL_MATRIX_M, directionOS)); else return mul((float3x3)LIL_MATRIX_M, directionOS); } float3 lilTransformDirWStoOS(float3 directionWS, bool doNormalize) { if(doNormalize) return normalize(mul((float3x3)LIL_MATRIX_I_M, directionWS)); else return mul((float3x3)LIL_MATRIX_I_M, directionWS); } float3 lilTransformNormalOStoWS(float3 normalOS, bool doNormalize) { #ifdef UNITY_ASSUME_UNIFORM_SCALING return lilTransformDirOStoWS(normalOS, doNormalize); #else if(doNormalize) return normalize(mul(normalOS, (float3x3)LIL_MATRIX_I_M)); else return mul(normalOS, (float3x3)LIL_MATRIX_I_M); #endif } bool lilIsPerspective() { #if defined(LIL_HDRP) && defined(SHADERPASS) && (SHADERPASS == SHADERPASS_SHADOWS) return LIL_MATRIX_P._m33 == 0; #else return unity_OrthoParams.w == 0; #endif } float3 lilViewDirection(float3 positionWS) { return _WorldSpaceCameraPos.xyz - positionWS; } float3 lilHeadDirection(float3 positionWS) { #if defined(USING_STEREO_MATRICES) return (LIL_STEREO_CAMERA_POS(0).xyz + LIL_STEREO_CAMERA_POS(1).xyz) * 0.5 - positionWS; #else return lilViewDirection(positionWS); #endif } float3 lilCameraDirection() { #if defined(USING_STEREO_MATRICES) return normalize(LIL_STEREO_MATRIX_V(0)._m20_m21_m22 + LIL_STEREO_MATRIX_V(1)._m20_m21_m22); #else return LIL_MATRIX_V._m20_m21_m22; #endif } float3 lilCameraUp() { return LIL_MATRIX_V._m10_m11_m12; } float3 lilCameraRight() { #if defined(USING_STEREO_MATRICES) return cross(lilCameraDirection(), lilCameraUp()); #else return LIL_MATRIX_V._m00_m01_m02; #endif } float3 lilViewDirectionOS(float3 positionOS) { #if defined(LIL_HDRP) return lilTransformWStoOS(lilToRelativePositionWS(_WorldSpaceCameraPos.xyz)) - positionOS; #else return lilTransformWStoOS(_WorldSpaceCameraPos.xyz) - positionOS; #endif } float3 lilHeadDirectionOS(float3 positionOS) { #if defined(USING_STEREO_MATRICES) return lilTransformWStoOS((LIL_STEREO_CAMERA_POS(0).xyz + LIL_STEREO_CAMERA_POS(1).xyz) * 0.5) - positionOS; #else return lilViewDirectionOS(positionOS); #endif } float2 lilCStoGrabUV(float4 positionCS) { float2 uvScn = positionCS.xy / LIL_SCREENPARAMS.xy; #if defined(UNITY_SINGLE_PASS_STEREO) uvScn.xy = TransformStereoScreenSpaceTex(uvScn.xy, 1.0); #endif return uvScn; } float3 lilTransformDirWStoVSCenter(float3 directionWS, bool doNormalize) { #if defined(USING_STEREO_MATRICES) if(doNormalize) return normalize(mul((float3x3)LIL_STEREO_MATRIX_V(0), directionWS) + mul((float3x3)LIL_STEREO_MATRIX_V(1), directionWS)); else return mul((float3x3)LIL_STEREO_MATRIX_V(0), directionWS) + mul((float3x3)LIL_STEREO_MATRIX_V(1), directionWS); #else if(doNormalize) return normalize(mul((float3x3)LIL_MATRIX_V, directionWS)); else return mul((float3x3)LIL_MATRIX_V, directionWS); #endif } float3 lilTransformDirWStoVSCenter(float3 directionWS) { return lilTransformDirWStoVSCenter(directionWS, false); } float3 lilBlendVRParallax(float3 a, float3 b, float c) { #if defined(USING_STEREO_MATRICES) return lerp(a, b, c); #else return b; #endif } float lilLinearEyeDepth(float z) { //return LIL_MATRIX_P._m23 / (z - LIL_MATRIX_P._m22 / LIL_MATRIX_P._m32); return LIL_MATRIX_P._m23 / (z + LIL_MATRIX_P._m22); } float lilLinearEyeDepth(float z, float2 positionCS) { float2 pos = positionCS / LIL_SCREENPARAMS.xy * 2.0 - 1.0; #if UNITY_UV_STARTS_AT_TOP pos.y = -pos.y; #endif return LIL_MATRIX_P._m23 / (z + LIL_MATRIX_P._m22 - LIL_MATRIX_P._m20 / LIL_MATRIX_P._m00 * (pos.x +LIL_MATRIX_P._m02) - LIL_MATRIX_P._m21 / LIL_MATRIX_P._m11 * (pos.y +LIL_MATRIX_P._m12) ); } float2 lilCameraDepthTexel(float2 positionCS) { float2 uv = positionCS.xy; #if UNITY_UV_STARTS_AT_TOP if(_ProjectionParams.x > 0) uv.y = LIL_SCREENPARAMS.y - uv.y; #else if(_ProjectionParams.x < 0) uv.y = LIL_SCREENPARAMS.y - uv.y; #endif return uv; } float3 lilGetObjectPosition() { return lilTransformOStoWS(float3(0,0,0)); } /* // Built-in RP #define UnityWorldToViewPos(positionWS) lilTransformWStoVS(positionWS) #define UnityWorldToClipPos(positionWS) lilTransformWStoCS(positionWS) #define UnityViewToClipPos(positionVS) lilTransformVStoCS(positionVS) #define ComputeGrabScreenPos(positionCS) lilTransformCStoSS(positionCS) #define UnityWorldSpaceViewDir(positionWS) lilViewDirection(positionWS) #define UnityObjectToWorldDir(directionOS) lilTransformDirOStoWS(directionOS) #define UnityWorldToObjectDir(directionWS) lilTransformDirWStoOS(directionWS) #define UnityObjectToWorldNormal(normalOS) lilTransformNormalOStoWS(normalOS) #define UnityWorldSpaceViewDir(positionWS) lilViewDirection(positionWS) // SRP #define TransformObjectToWorld(positionOS) lilTransformOStoWS(positionOS) #define TransformWorldToObject(positionWS) lilTransformWStoOS(positionWS) #define TransformWorldToView(positionWS) lilTransformWStoVS(positionWS) #define TransformWorldToHClip(positionWS) lilTransformWStoCS(positionWS) #define TransformWViewToHClip(positionVS) lilTransformVStoCS(positionVS) #define TransformObjectToWorldDir(directionOS,doNormalize) lilTransformDirOStoWS(directionOS,doNormalize) #define TransformWorldToObjectDir(directionWS,doNormalize) lilTransformDirWStoOS(directionWS,doNormalize) #define TransformObjectToWorldNormal(normalOS,doNormalize) lilTransformNormalOStoWS(normalOS,doNormalize) #define GetAbsolutePositionWS(positionRWS) lilToAbsolutePositionWS(float3 positionRWS) */ // Lighting #if defined(LIL_BRP) // 2017 #ifndef EDITORVIZ_TEXTURE #undef EDITOR_VISUALIZATION #endif #ifndef UNITY_TRANSFER_LIGHTING #define UNITY_TRANSFER_LIGHTING(a,b) TRANSFER_SHADOW(a) #endif // HDRP Data uint lilGetRenderingLayer() { return 0; } #define LIL_GET_HDRPDATA(input,fd) #define LIL_HDRP_DEEXPOSURE(col) #define LIL_HDRP_INVDEEXPOSURE(col) // Main light #define LIL_MAINLIGHT_COLOR _LightColor0.rgb #define LIL_MAINLIGHT_DIRECTION _WorldSpaceLightPos0.xyz // Shadow #if defined(LIL_USE_SHADOW) && !defined(LIL_PASS_FORWARDADD) #define LIL_SHADOW_COORDS(idx) UNITY_SHADOW_COORDS(idx) #define LIL_TRANSFER_SHADOW(vi,uv,o) \ DummyStructure v; \ v.vertex = input.positionOS; \ BRPShadowCoords brpShadowCoords; \ LIL_INITIALIZE_STRUCT(BRPShadowCoords, brpShadowCoords); \ brpShadowCoords.pos = vi.positionCS; \ UNITY_TRANSFER_LIGHTING(brpShadowCoords, uv) \ o._ShadowCoord = brpShadowCoords._ShadowCoord #define LIL_LIGHT_ATTENUATION(atten,i) \ BRPShadowCoords brpShadowCoords; \ brpShadowCoords.pos = i.positionCS; \ brpShadowCoords._ShadowCoord = i._ShadowCoord; \ UNITY_LIGHT_ATTENUATION(attenuationOrig, brpShadowCoords, i.positionWS); \ atten = attenuationOrig #elif (UNITY_VERSION < 201820) && !defined(UNITY_HALF_PRECISION_FRAGMENT_SHADER_REGISTERS) || !defined(LIL_PASS_FORWARDADD) #define LIL_SHADOW_COORDS(idx) #define LIL_TRANSFER_SHADOW(vi,uv,o) #define LIL_LIGHT_ATTENUATION(atten,i) #else #if defined(POINT) #define LIL_CALC_LIGHT_COORDS(o,i) o._LightCoord = mul(unity_WorldToLight, float4(i.positionWS, 1.0)).xyz; #elif defined(SPOT) #define LIL_CALC_LIGHT_COORDS(o,i) o._LightCoord = mul(unity_WorldToLight, float4(i.positionWS, 1.0)); #elif defined(POINT_COOKIE) #define LIL_CALC_LIGHT_COORDS(o,i) o._LightCoord = mul(unity_WorldToLight, float4(i.positionWS, 1.0)).xyz; #elif defined(DIRECTIONAL_COOKIE) #define LIL_CALC_LIGHT_COORDS(o,i) o._LightCoord = mul(unity_WorldToLight, float4(i.positionWS, 1.0)).xy; #else #define LIL_CALC_LIGHT_COORDS(o,i) #endif #define LIL_SHADOW_COORDS(idx) UNITY_SHADOW_COORDS(idx) #if defined(SHADOWS_DEPTH) && defined(SPOT) || defined(SHADOWS_SCREEN) && defined(UNITY_NO_SCREENSPACE_SHADOWS) #define LIL_TRANSFER_SHADOW(vi,uv,o) o._ShadowCoord = mul(unity_WorldToShadow[0], float4(vi.positionWS.xyz, 1)); #elif defined(SHADOWS_CUBE) #define LIL_TRANSFER_SHADOW(vi,uv,o) o._ShadowCoord.xyz = fd.positionWS.xyz - _LightPositionRange.xyz; #elif defined(SHADOWS_SCREEN) #define LIL_TRANSFER_SHADOW(vi,uv,o) o._ShadowCoord = float4(vi.positionCS.xy / LIL_SCREENPARAMS.xy, 1, 1); #else #define LIL_TRANSFER_SHADOW(vi,uv,o) #endif #define LIL_LIGHT_ATTENUATION(atten,i) \ BRPShadowCoords brpShadowCoords; \ brpShadowCoords.pos = i.positionCS; \ LIL_CALC_LIGHT_COORDS(brpShadowCoords,i) \ LIL_TRANSFER_SHADOW(fd,fd.uv1,brpShadowCoords) \ UNITY_LIGHT_ATTENUATION(attenuationOrig, brpShadowCoords, i.positionWS); \ atten = attenuationOrig #endif struct BRPShadowCoords { float4 pos; LIL_SHADOW_COORDS(0) #if defined(DECLARE_LIGHT_COORDS) DECLARE_LIGHT_COORDS(1) #elif defined(POINT) unityShadowCoord3 _LightCoord : TEXCOORD1; #elif defined(SPOT) unityShadowCoord4 _LightCoord : TEXCOORD1; #elif defined(POINT_COOKIE) unityShadowCoord3 _LightCoord : TEXCOORD1; #elif defined(DIRECTIONAL_COOKIE) unityShadowCoord2 _LightCoord : TEXCOORD1; #endif }; struct DummyStructure { float4 vertex; }; // Shadow caster #define LIL_V2F_SHADOW_CASTER_OUTPUT V2F_SHADOW_CASTER_NOPOS float4 positionCS : SV_POSITION; #if defined(SHADOWS_CUBE) && !defined(SHADOWS_CUBE_IN_DEPTH_TEX) #define LIL_TRANSFER_SHADOW_CASTER(v,o) \ o.vec = mul(unity_ObjectToWorld, v.positionOS).xyz - _LightPositionRange.xyz; \ o.positionCS = UnityObjectToClipPos(v.positionOS) #else float4 lilClipSpaceShadowCasterPos(float4 positionOS, float3 normalOS, float bias) { #if defined(SHADOWS_DEPTH) if(LIL_MATRIX_P._m33 == 0.0) bias = 0; #endif float4 positionWS = mul(unity_ObjectToWorld, float4(positionOS.xyz, 1)); float3 L = normalize(UnityWorldSpaceLightDir(positionWS.xyz)); positionWS.xyz -= L * bias; if(unity_LightShadowBias.z != 0.0) { float3 normalWS = UnityObjectToWorldNormal(normalOS); float shadowCos = dot(normalWS, L); float shadowSine = sqrt(1-shadowCos*shadowCos); float normalBias = unity_LightShadowBias.z * shadowSine; positionWS.xyz -= normalWS * normalBias; } return mul(UNITY_MATRIX_VP, positionWS); } #define LIL_TRANSFER_SHADOW_CASTER(v,o) \ o.positionCS = lilClipSpaceShadowCasterPos(v.positionOS, v.normalOS, _lilShadowCasterBias); \ o.positionCS = UnityApplyLinearShadowBias(o.positionCS) #endif #define LIL_SHADOW_CASTER_FRAGMENT(i) SHADOW_CASTER_FRAGMENT(i) // Additional Light void lilGetAdditionalLights(float3 positionWS, float4 positionCS, float strength, inout float3 lightColor, inout float3 lightDirection) { #if defined(LIGHTPROBE_SH) && defined(VERTEXLIGHT_ON) float4 toLightX = unity_4LightPosX0 - positionWS.x; float4 toLightY = unity_4LightPosY0 - positionWS.y; float4 toLightZ = unity_4LightPosZ0 - positionWS.z; float4 lengthSq = toLightX * toLightX + 0.000001; lengthSq += toLightY * toLightY; lengthSq += toLightZ * toLightZ; //float4 atten = 1.0 / (1.0 + lengthSq * unity_4LightAtten0); float4 atten = saturate(saturate((25.0 - lengthSq * unity_4LightAtten0) * 0.111375) / (0.987725 + lengthSq * unity_4LightAtten0)) * strength; lightColor += unity_LightColor[0].rgb * atten.x; lightColor += unity_LightColor[1].rgb * atten.y; lightColor += unity_LightColor[2].rgb * atten.z; lightColor += unity_LightColor[3].rgb * atten.w; lightDirection += lilLuminance(unity_LightColor[0].rgb) * atten.x / sqrt(lengthSq.x) * float3(toLightX.x, toLightY.x, toLightZ.x); lightDirection += lilLuminance(unity_LightColor[1].rgb) * atten.y / sqrt(lengthSq.y) * float3(toLightX.y, toLightY.y, toLightZ.y); lightDirection += lilLuminance(unity_LightColor[2].rgb) * atten.z / sqrt(lengthSq.z) * float3(toLightX.z, toLightY.z, toLightZ.z); lightDirection += lilLuminance(unity_LightColor[3].rgb) * atten.w / sqrt(lengthSq.w) * float3(toLightX.w, toLightY.w, toLightZ.w); #endif } float3 lilGetAdditionalLights(float3 positionWS, float4 positionCS, float strength) { float3 lightColor = 0.0; float3 lightDirection = 0.0; lilGetAdditionalLights(positionWS, positionCS, strength, lightColor, lightDirection); return saturate(lightColor); } // Lightmap #define LIL_DECODE_LIGHTMAP(lm) DecodeLightmap(lm) #define LIL_DECODE_DYNAMICLIGHTMAP(lm) DecodeRealtimeLightmap(lm) // Environment reflection UnityGIInput lilSetupGIInput(float3 positionWS) { UnityGIInput data; LIL_INITIALIZE_STRUCT(UnityGIInput, data); data.worldPos = positionWS; data.probeHDR[0] = unity_SpecCube0_HDR; data.probeHDR[1] = unity_SpecCube1_HDR; #if defined(UNITY_SPECCUBE_BLENDING) || defined(UNITY_SPECCUBE_BOX_PROJECTION) data.boxMin[0] = unity_SpecCube0_BoxMin; #endif #ifdef UNITY_SPECCUBE_BOX_PROJECTION data.boxMax[0] = unity_SpecCube0_BoxMax; data.probePosition[0] = unity_SpecCube0_ProbePosition; data.boxMax[1] = unity_SpecCube1_BoxMax; data.boxMin[1] = unity_SpecCube1_BoxMin; data.probePosition[1] = unity_SpecCube1_ProbePosition; #endif return data; } Unity_GlossyEnvironmentData lilSetupGlossyEnvironmentData(float3 viewDirection, float3 normalDirection, float perceptualRoughness) { Unity_GlossyEnvironmentData glossIn; glossIn.roughness = perceptualRoughness; glossIn.reflUVW = reflect(-viewDirection,normalDirection); return glossIn; } float3 lilGetEnvReflection(float3 viewDirection, float3 normalDirection, float perceptualRoughness, float3 positionWS) { UnityGIInput data = lilSetupGIInput(positionWS); Unity_GlossyEnvironmentData glossIn = lilSetupGlossyEnvironmentData(viewDirection,normalDirection,perceptualRoughness); return UnityGI_IndirectSpecular(data, 1.0, glossIn); } #define LIL_GET_ENVIRONMENT_REFLECTION(viewDirection,normalDirection,perceptualRoughness,positionWS) \ ((IsEmpty(unity_SpecCube0) || unity_SpecCube0_HDR.x == 0 || _ReflectionCubeOverride) ? \ lilCustomReflection(_ReflectionCubeTex, _ReflectionCubeTex_HDR, viewDirection, normalDirection, perceptualRoughness) * _ReflectionCubeColor.rgb * lerp(1.0, fd.lightColor, _ReflectionCubeEnableLighting) : \ lilGetEnvReflection(viewDirection,normalDirection,perceptualRoughness,positionWS)) // Fog #if defined(LIL_PASS_FORWARDADD) #define LIL_FOG_COLOR float4(0,0,0,0) #else #define LIL_FOG_COLOR unity_FogColor #endif #if LIL_RENDER == 2 #define LIL_APPLY_FOG_BASE(col,fogCoord) UNITY_FOG_LERP_COLOR(col,LIL_FOG_COLOR*col.a,fogCoord) #define LIL_APPLY_FOG_COLOR_BASE(col,fogCoord,fogColor) UNITY_FOG_LERP_COLOR(col,fogColor*col.a,fogCoord) #else #define LIL_APPLY_FOG_BASE(col,fogCoord) UNITY_FOG_LERP_COLOR(col,LIL_FOG_COLOR,fogCoord) #define LIL_APPLY_FOG_COLOR_BASE(col,fogCoord,fogColor) UNITY_FOG_LERP_COLOR(col,fogColor,fogCoord) #endif float lilCalcFogFactor(float depth) { #if defined(FOG_LINEAR) || defined(FOG_EXP) || defined(FOG_EXP2) UNITY_CALC_FOG_FACTOR(depth); return unityFogFactor; #else return 1.0; #endif } // Meta #define MetaInput UnityMetaInput #define MetaFragment(input) UnityMetaFragment(input) #define MetaVertexPosition(pos,uv1,uv2,l,d) UnityMetaVertexPosition(pos,uv1,uv2,l,d) #elif defined(LIL_HDRP) #define LIGHT_SIMULATE_HQ // Support for old version #if LIL_SRP_VERSION_LOWER(4, 1) #define LIL_HDRP_IGNORE_LIGHTDIMMER float4 EvaluateAtmosphericScattering(PositionInputs posInput, float3 viewDirection, float4 col) { return EvaluateAtmosphericScattering(posInput, col); } #endif #if LIL_SRP_VERSION_LOWER(4, 2) float GetDirectionalShadowAttenuation(HDShadowContext shadowContext, float2 positionSS, float3 positionWS, float3 normalWS, int shadowIndex, float3 L) { return GetDirectionalShadowAttenuation(shadowContext, positionWS, normalWS, shadowIndex, L, positionSS); } #endif #if LIL_SRP_VERSION_LOWER(5, 3) float GetCurrentExposureMultiplier() { return 1.0; } #endif #if LIL_SRP_VERSION_LOWER(6, 6) float3 SampleCameraColor(float2 uv, float lod) { return LIL_SAMPLE_2D_LOD(_ColorPyramidTexture, s_trilinear_clamp_sampler, uv, lod).rgb; } #endif #if LIL_SRP_VERSION_LOWER(6, 8) float4 EvaluateLight_Directional(LightLoopContext lightLoopContext, PositionInputs posInput, DirectionalLightData light) { float4 color = float4(light.color, 1.0); #if LIL_SRP_VERSION_GREATER_EQUAL(4, 1) float cosZenithAngle = -light.forward.y; float fragmentHeight = posInput.positionWS.y; color.a = TransmittanceHeightFog(_HeightFogBaseExtinction, _HeightFogBaseHeight, _HeightFogExponents, cosZenithAngle, fragmentHeight); #endif if(light.cookieIndex >= 0) { float3 lightToSample = posInput.positionWS - light.positionRWS; float3 cookie = EvaluateCookie_Directional(lightLoopContext, light, lightToSample); color.rgb *= cookie; } return color; } void GetPunctualLightVectors(float3 positionWS, LightData light, out float3 L, out float4 distances) { float3 lightToSample; GetPunctualLightVectors(positionWS, light, L, lightToSample, distances); } #endif #if LIL_SRP_VERSION_LOWER(7, 1) float3 TransformPreviousObjectToWorld(float3 positionOS) { float4x4 previousModelMatrix = ApplyCameraTranslationToMatrix(unity_MatrixPreviousM); return mul(previousModelMatrix, float4(positionOS, 1.0)).xyz; } #endif #if LIL_SRP_VERSION_LOWER(11, 0) #define LIL_HDRP_DEEXPOSURE(col) #define LIL_HDRP_INVDEEXPOSURE(col) #else #define LIL_HDRP_DEEXPOSURE(col) col.rgb *= _DeExposureMultiplier #define LIL_HDRP_INVDEEXPOSURE(col) col.rgb /= _DeExposureMultiplier #endif float4 SampleEnv(LightLoopContext lightLoopContext, PositionInputs posInput, EnvLightData lightData, float3 reflUVW, float lod) { #if LIL_SRP_VERSION_GREATER_EQUAL(10, 1) float4 reflectionCol = SampleEnv(lightLoopContext, lightData.envIndex, reflUVW, lod * lightData.roughReflections, lightData.rangeCompressionFactorCompensation, posInput.positionNDC); #elif LIL_SRP_VERSION_GREATER_EQUAL(7, 1) float4 reflectionCol = SampleEnv(lightLoopContext, lightData.envIndex, reflUVW, lod, lightData.rangeCompressionFactorCompensation); #else float4 reflectionCol = SampleEnv(lightLoopContext, lightData.envIndex, reflUVW, lod); #endif LIL_HDRP_INVDEEXPOSURE(reflectionCol); return reflectionCol; } //------------------------------------------------------------------------------------------------------------------------------ // HDRP Data uint lilGetRenderingLayer() { #if defined(RENDERING_LIGHT_LAYERS_MASK) return _EnableLightLayers ? (asuint(unity_RenderingLayer.x) & RENDERING_LIGHT_LAYERS_MASK) >> RENDERING_LIGHT_LAYERS_MASK_SHIFT : DEFAULT_LIGHT_LAYERS; #else return _EnableLightLayers ? asuint(unity_RenderingLayer.x) : DEFAULT_LIGHT_LAYERS; #endif } struct lilNPRLightingData { float3 color; float3 direction; }; LightLoopContext lilInitLightLoopContext() { LightLoopContext lightLoopContext; lightLoopContext.shadowContext = InitShadowContext(); lightLoopContext.shadowValue = 1; lightLoopContext.sampleReflection = 0; lightLoopContext.contactShadow = 0; #if LIL_SRP_VERSION_GREATER_EQUAL(6, 7) real contactShadowFade; #endif #if LIL_SRP_VERSION_GREATER_EQUAL(12, 1) real splineVisibility; #endif #if defined(APPLY_FOG_ON_SKY_REFLECTIONS) lightLoopContext.positionWS = 0; #endif return lightLoopContext; } #define LIL_GET_HDRPDATA(input,fd) \ fd.renderingLayers = lilGetRenderingLayer(); \ fd.featureFlags = LIGHT_FEATURE_MASK_FLAGS_OPAQUE; \ fd.tileIndex = uint2(0,0); \ PositionInputs posInput = GetPositionInput(input.positionCS.xy, _ScreenSize.zw, input.positionCS.z, input.positionCS.w, input.positionWS, fd.tileIndex) //------------------------------------------------------------------------------------------------------------------------------ // Direction Light bool lilUseScreenSpaceShadow(int screenSpaceShadowIndex) { #if defined(SCREEN_SPACE_SHADOW_INDEX_MASK) && defined(INVALID_SCREEN_SPACE_SHADOW) return (screenSpaceShadowIndex & SCREEN_SPACE_SHADOW_INDEX_MASK) != INVALID_SCREEN_SPACE_SHADOW; #else return screenSpaceShadowIndex >= 0; #endif } float4 lilGetDirectionalLightColor(PositionInputs posInput, DirectionalLightData light) { LightLoopContext lightLoopContext = lilInitLightLoopContext(); return EvaluateLight_Directional(lightLoopContext, posInput, light); } lilNPRLightingData lilGetNPRDirectionalLight(PositionInputs posInput, DirectionalLightData light) { lilNPRLightingData lighting = (lilNPRLightingData)0; float3 L = -light.forward; #if !defined(LIL_HDRP_IGNORE_LIGHTDIMMER) if(light.lightDimmer > 0) #endif { float4 lightColor = lilGetDirectionalLightColor(posInput, light); lightColor.rgb *= lightColor.a; lighting.direction = L; lighting.color = lightColor.rgb; } return lighting; } void lilBlendlilNPRLightingData(inout lilNPRLightingData dst, lilNPRLightingData src) { dst.color += src.color; dst.direction += src.direction * Luminance(src.color); } float lilGetDirectionalShadow(PositionInputs posInput, float3 normalWS, uint featureFlags, float bias) { float attenuation = 1.0; if(featureFlags & LIGHTFEATUREFLAGS_DIRECTIONAL) { HDShadowContext shadowContext = InitShadowContext(); if(_DirectionalShadowIndex >= 0) { DirectionalLightData light = _DirectionalLightDatas[_DirectionalShadowIndex]; #if defined(SCREEN_SPACE_SHADOWS_ON) if(lilUseScreenSpaceShadow(light.screenSpaceShadowIndex)) { attenuation = GetScreenSpaceShadow(posInput, light.screenSpaceShadowIndex); } else #endif { float3 L = -light.forward; #if !defined(LIL_HDRP_IGNORE_LIGHTDIMMER) if((light.lightDimmer > 0) && (light.shadowDimmer > 0)) #endif { float3 positionWS = posInput.positionWS + L * bias; attenuation = GetDirectionalShadowAttenuation(shadowContext, posInput.positionSS, positionWS, normalWS, light.shadowIndex, L); } } } } return attenuation; } float lilGetDirectionalShadow(PositionInputs posInput, float3 normalWS, uint featureFlags) { return lilGetDirectionalShadow(posInput, normalWS, featureFlags, 0.0); } lilNPRLightingData lilGetDirectionalLightSum(PositionInputs posInput, uint renderingLayers, uint featureFlags) { lilNPRLightingData lightingData; lightingData.color = 0.0; lightingData.direction = 0.0; if(featureFlags & LIGHTFEATUREFLAGS_DIRECTIONAL) { for(uint i = 0; i < _DirectionalLightCount; ++i) { if((_DirectionalLightDatas[i].lightLayers & renderingLayers) != 0) { lilNPRLightingData lighting = lilGetNPRDirectionalLight(posInput, _DirectionalLightDatas[i]); lilBlendlilNPRLightingData(lightingData, lighting); } } } lightingData.direction = dot(lightingData.direction,lightingData.direction) < 0.000001 ? 0 : normalize(lightingData.direction); #ifdef LIGHT_SIMULATE_HQ lightingData.color = 0.0; if(featureFlags & LIGHTFEATUREFLAGS_DIRECTIONAL) { for(uint i = 0; i < _DirectionalLightCount; ++i) { if((_DirectionalLightDatas[i].lightLayers & renderingLayers) != 0) { lilNPRLightingData lighting = lilGetNPRDirectionalLight(posInput, _DirectionalLightDatas[i]); lightingData.color += lighting.color * saturate(dot(lightingData.direction, lighting.direction)); } } } #endif return lightingData; } void lilGetLightDirectionAndColor(out float3 lightDirection, out float3 lightColor, PositionInputs posInput) { uint renderingLayers = lilGetRenderingLayer(); uint featureFlags = LIGHT_FEATURE_MASK_FLAGS_OPAQUE; lilNPRLightingData lightingData = lilGetDirectionalLightSum(posInput, renderingLayers, featureFlags); lightDirection = lightingData.direction; lightColor = lightingData.color; } //------------------------------------------------------------------------------------------------------------------------------ // Punctual Light (Point / Spot) float4 EvaluateLight_Punctual(LightLoopContext lightLoopContext, float3 positionWS, LightData light, float3 L, float4 distances) { float4 color = float4(light.color, 1.0); color.a *= PunctualLightAttenuation(distances, light.rangeAttenuationScale, light.rangeAttenuationBias, light.angleScale, light.angleOffset); #if !defined(LIGHT_EVALUATION_NO_HEIGHT_FOG) && LIL_SRP_VERSION_GREATER_EQUAL(4, 1) float cosZenithAngle = L.y; float distToLight = (light.lightType == GPULIGHTTYPE_PROJECTOR_BOX) ? distances.w : distances.x; float fragmentHeight = positionWS.y; color.a *= TransmittanceHeightFog(_HeightFogBaseExtinction, _HeightFogBaseHeight, _HeightFogExponents, cosZenithAngle, fragmentHeight, distToLight); #endif #if LIL_SRP_VERSION_LOWER(7, 2) if(light.cookieIndex >= 0) #else if(light.cookieMode != COOKIEMODE_NONE) #endif { float3 lightToSample = positionWS - light.positionRWS; float4 cookie = EvaluateCookie_Punctual(lightLoopContext, light, lightToSample); color *= cookie; } return color; } lilNPRLightingData lilGetNPRPunctualLight(float3 positionWS, LightData light) { lilNPRLightingData lighting = (lilNPRLightingData)0; float3 L; float4 distances; GetPunctualLightVectors(positionWS, light, L, distances); #if !defined(LIL_HDRP_IGNORE_LIGHTDIMMER) if(light.lightDimmer > 0) #endif { LightLoopContext lightLoopContext; lightLoopContext.shadowContext = InitShadowContext(); lightLoopContext.shadowValue = 1; lightLoopContext.sampleReflection = 0; lightLoopContext.contactShadow = 0; float4 lightColor = EvaluateLight_Punctual(lightLoopContext, positionWS, light, L, distances); #if !defined(LIL_HDRP_IGNORE_LIGHTDIMMER) lightColor.a *= light.diffuseDimmer; #endif lightColor.rgb *= lightColor.a; lighting.direction = L; lighting.color = lightColor.rgb; } return lighting; } void lilGetPunctualLightColor(inout lilNPRLightingData dst, float3 positionWS, uint renderingLayers, uint featureFlags) { if(featureFlags & LIGHTFEATUREFLAGS_PUNCTUAL) { uint lightStart = 0; bool fastPath = false; #if SCALARIZE_LIGHT_LOOP uint lightStartLane0; fastPath = IsFastPath(lightStart, lightStartLane0); if(fastPath) lightStart = lightStartLane0; #endif uint lightListOffset = 0; while(lightListOffset < _PunctualLightCount) { uint v_lightIdx = FetchIndex(lightStart, lightListOffset); #if SCALARIZE_LIGHT_LOOP uint s_lightIdx = ScalarizeElementIndex(v_lightIdx, fastPath); #else uint s_lightIdx = v_lightIdx; #endif if(s_lightIdx == -1) break; LightData lightData = FetchLight(s_lightIdx, 0); if(s_lightIdx >= v_lightIdx) { lightListOffset++; if((lightData.lightLayers & renderingLayers) != 0) { lilNPRLightingData src = lilGetNPRPunctualLight(positionWS, lightData); lilBlendlilNPRLightingData(dst, src); } } } } } //------------------------------------------------------------------------------------------------------------------------------ // Area Light (Line / Rectangle) lilNPRLightingData lilGetLineLightColor(float3 positionWS, LightData lightData) { lilNPRLightingData lighting = (lilNPRLightingData)0; float3 unL = lightData.positionRWS - positionWS; float intensity = EllipsoidalDistanceAttenuation( unL, lightData.right, saturate(lightData.range / (lightData.range + 0.5 * lightData.size.x)), lightData.rangeAttenuationScale, lightData.rangeAttenuationBias); #if !defined(LIL_HDRP_IGNORE_LIGHTDIMMER) intensity *= lightData.diffuseDimmer; #endif lighting.color = lightData.color * intensity; float halfLength = 0.5 * lightData.size.x; //float3 nearestPoint = lightData.positionRWS - lightData.right * clamp(dot(unL, lightData.right), -halfLength, halfLength); float3 nearestPoint = lightData.positionRWS - lightData.right * clamp(dot(unL, lightData.right), -halfLength, halfLength) * 0.75; lighting.direction = normalize(nearestPoint - positionWS); return lighting; } lilNPRLightingData lilGetRectLightColor(float3 positionWS, LightData lightData) { lilNPRLightingData lighting = (lilNPRLightingData)0; float3 lightColor = 0.0; #if SHADEROPTIONS_BARN_DOOR RectangularLightApplyBarnDoor(lightData, positionWS); #endif float3 unL = lightData.positionRWS - positionWS; if(dot(lightData.forward, unL) < FLT_EPS) { float3x3 lightToWorld = float3x3(lightData.right, lightData.up, -lightData.forward); float3 unL2 = mul(unL, transpose(lightToWorld)); float halfWidth = lightData.size.x * 0.5; float halfHeight = lightData.size.y * 0.5; float3 invHalfDim = rcp(float3(lightData.range + halfWidth, lightData.range + halfHeight, lightData.range)); #ifdef ELLIPSOIDAL_ATTENUATION float intensity = EllipsoidalDistanceAttenuation(unL2, invHalfDim, lightData.rangeAttenuationScale, lightData.rangeAttenuationBias); #else float intensity = BoxDistanceAttenuation(unL2, invHalfDim, lightData.rangeAttenuationScale, lightData.rangeAttenuationBias); #endif #if !defined(LIL_HDRP_IGNORE_LIGHTDIMMER) intensity *= lightData.diffuseDimmer; #endif lighting.color = lightData.color * intensity; float2 halfLength = 0.5 * lightData.size.xy; float3 nearestPoint = lightData.positionRWS - lightData.right * clamp(dot(unL, lightData.right), -halfLength.x, halfLength.x) * 0.75 - lightData.up * clamp(dot(unL, lightData.up), -halfLength.y, halfLength.y) * 0.75; lighting.direction = normalize(nearestPoint - positionWS); } return lighting; } void lilGetAreaLightColor(inout lilNPRLightingData dst, float3 positionWS, uint renderingLayers, uint featureFlags) { #if SHADEROPTIONS_AREA_LIGHTS if(featureFlags & LIGHTFEATUREFLAGS_AREA) { if(_AreaLightCount > 0) { uint i = 0; uint last = _AreaLightCount - 1; LightData lightData = FetchLight(_PunctualLightCount, i); while(i <= last && lightData.lightType == GPULIGHTTYPE_TUBE) { lightData.lightType = GPULIGHTTYPE_TUBE; #if defined(COOKIEMODE_NONE) lightData.cookieMode = COOKIEMODE_NONE; #endif if((lightData.lightLayers & renderingLayers) != 0) { lilNPRLightingData lighting = lilGetLineLightColor(positionWS, lightData); lilBlendlilNPRLightingData(dst, lighting); } lightData = FetchLight(_PunctualLightCount, min(++i, last)); } while(i <= last) { lightData.lightType = GPULIGHTTYPE_RECTANGLE; if((lightData.lightLayers & renderingLayers) != 0) { lilNPRLightingData lighting = lilGetRectLightColor(positionWS, lightData); lilBlendlilNPRLightingData(dst, lighting); } lightData = FetchLight(_PunctualLightCount, min(++i, last)); } } } #endif } //------------------------------------------------------------------------------------------------------------------------------ // Reflection / Refraction float3 lilGetReflectionColor( LightLoopContext lightLoopContext, PositionInputs posInput, float3 reflUVW, float perceptualRoughness, float3 normalDirection, EnvLightData lightData, int influenceShapeType, inout float hierarchyWeight) { float weight = 1.0; EvaluateLight_EnvIntersection(posInput.positionWS, normalDirection, lightData, influenceShapeType, reflUVW, weight); float4 preLD = SampleEnv(lightLoopContext, posInput, lightData, reflUVW, PerceptualRoughnessToMipmapLevel(perceptualRoughness)); weight *= preLD.a; UpdateLightingHierarchyWeights(hierarchyWeight, weight); return preLD.rgb * weight * lightData.multiplier; } float3 lilGetReflectionSum(float3 viewDirection, float3 normalDirection, float perceptualRoughness, PositionInputs posInput, uint renderingLayers, uint featureFlags) { float3 reflUVW = reflect(-viewDirection, normalDirection); LightLoopContext lightLoopContext = lilInitLightLoopContext(); float3 specular = 0.0; if(featureFlags & (LIGHTFEATUREFLAGS_ENV | LIGHTFEATUREFLAGS_SKY)) { float reflectionHierarchyWeight = 0.0; uint envLightStart = 0; bool fastPath = false; #if SCALARIZE_LIGHT_LOOP uint envStartFirstLane; fastPath = IsFastPath(envLightStart, envStartFirstLane); #endif EnvLightData envLightData; if(_EnvLightCount > 0) envLightData = FetchEnvLight(envLightStart, 0); else envLightData = InitSkyEnvLightData(0); if(featureFlags & LIGHTFEATUREFLAGS_ENV) { lightLoopContext.sampleReflection = SINGLE_PASS_CONTEXT_SAMPLE_REFLECTION_PROBES; #if SCALARIZE_LIGHT_LOOP if(fastPath) envLightStart = envStartFirstLane; #endif uint v_envLightListOffset = 0; uint v_envLightIdx = envLightStart; while(v_envLightListOffset < _EnvLightCount) { v_envLightIdx = FetchIndex(envLightStart, v_envLightListOffset); #if SCALARIZE_LIGHT_LOOP uint s_envLightIdx = ScalarizeElementIndex(v_envLightIdx, fastPath); #else uint s_envLightIdx = v_envLightIdx; #endif if(s_envLightIdx == -1) break; EnvLightData s_envLightData = FetchEnvLight(s_envLightIdx, 0); if(s_envLightIdx >= v_envLightIdx) { v_envLightListOffset++; if((reflectionHierarchyWeight < 1.0) && ((s_envLightData.lightLayers & renderingLayers) != 0)) { specular += lilGetReflectionColor(lightLoopContext, posInput, reflUVW, perceptualRoughness, normalDirection, s_envLightData, s_envLightData.influenceShapeType, reflectionHierarchyWeight); } } } } if((featureFlags & LIGHTFEATUREFLAGS_SKY) && _EnvLightSkyEnabled) { lightLoopContext.sampleReflection = SINGLE_PASS_CONTEXT_SAMPLE_SKY; EnvLightData envLightSky = InitSkyEnvLightData(0); if(reflectionHierarchyWeight < 1.0) { specular += lilGetReflectionColor(lightLoopContext, posInput, reflUVW, perceptualRoughness, normalDirection, envLightSky, envLightSky.influenceShapeType, reflectionHierarchyWeight); } } } return specular * GetCurrentExposureMultiplier(); } // Main light #define LIL_MAINLIGHT_COLOR float3(1,1,1) #define LIL_MAINLIGHT_DIRECTION float3(0,1,0) // Shadow #define LIL_SHADOW_COORDS(idx) #define LIL_TRANSFER_SHADOW(vi,uv,o) #if defined(LIL_USE_SHADOW) #define LIL_LIGHT_ATTENUATION(atten,i) atten = lilGetDirectionalShadow(posInput, i.normalWS, fd.featureFlags, _lilShadowCasterBias) #else #define LIL_LIGHT_ATTENUATION(atten,i) #endif // Shadow caster #define LIL_V2F_SHADOW_CASTER_OUTPUT #define LIL_TRANSFER_SHADOW_CASTER(v,o) #define LIL_SHADOW_CASTER_FRAGMENT(i) // Additional Light void lilGetAdditionalLights(float3 positionWS, float4 positionCS, float strength, inout float3 lightColor, inout float3 lightDirection) { uint renderingLayers = lilGetRenderingLayer(); uint featureFlags = LIGHT_FEATURE_MASK_FLAGS_OPAQUE; lilNPRLightingData lighting; LIL_INITIALIZE_STRUCT(lilNPRLightingData, lighting); lilGetPunctualLightColor(lighting, positionWS, renderingLayers, featureFlags); lilGetAreaLightColor(lighting, positionWS, renderingLayers, featureFlags); lightColor += lighting.color * 0.75 * GetCurrentExposureMultiplier() * strength; lightDirection += lighting.direction * 0.75 * strength; } float3 lilGetAdditionalLights(float3 positionWS, float4 positionCS, float strength) { float3 lightColor = 0.0; float3 lightDirection = 0.0; lilGetAdditionalLights(positionWS, positionCS, strength, lightColor, lightDirection); return lightColor; } // Lightmap #define LIL_DECODE_LIGHTMAP(lm) DecodeLightmap(lm, float4(LIGHTMAP_HDR_MULTIPLIER,LIGHTMAP_HDR_EXPONENT,0.0,0.0)) #define LIL_DECODE_DYNAMICLIGHTMAP(lm) lm.rgb // Environment reflection #define LIL_GET_ENVIRONMENT_REFLECTION(viewDirection,normalDirection,perceptualRoughness,positionWS) \ (_ReflectionCubeOverride ? \ lilCustomReflection(_ReflectionCubeTex, _ReflectionCubeTex_HDR, viewDirection, normalDirection, perceptualRoughness) * _ReflectionCubeColor.rgb * lerp(1.0, fd.lightColor, _ReflectionCubeEnableLighting) : \ lilGetReflectionSum(viewDirection,normalDirection,perceptualRoughness,posInput,fd.renderingLayers,fd.featureFlags)) // Fog #define LIL_APPLY_FOG_BASE(col,fogCoord) col = EvaluateAtmosphericScattering(posInput, fd.V, col) #define LIL_APPLY_FOG_COLOR_BASE(col,fogCoord,fogColor) col = EvaluateAtmosphericScattering(posInput, fd.V, col) float lilCalcFogFactor(float depth) { return 0.0; } #else // Support for old version // HDRP Data #if LIL_SRP_VERSION_GREATER_EQUAL(14, 0) uint lilGetRenderingLayer() { return asuint(unity_RenderingLayer.x); } #elif LIL_SRP_VERSION_GREATER_EQUAL(12, 0) uint lilGetRenderingLayer() { #if defined(_LIGHT_LAYERS) return (asuint(unity_RenderingLayer.x) & RENDERING_LIGHT_LAYERS_MASK) >> RENDERING_LIGHT_LAYERS_MASK_SHIFT; #else return DEFAULT_LIGHT_LAYERS; #endif } #else uint lilGetRenderingLayer() { return 0; } #endif #define LIL_GET_HDRPDATA(input,fd) #define LIL_HDRP_DEEXPOSURE(col) #define LIL_HDRP_INVDEEXPOSURE(col) // Main light #if LIL_SRP_VERSION_GREATER_EQUAL(12, 0) && defined(_LIGHT_LAYERS) #define LIL_MAINLIGHT_COLOR ((_MainLightLayerMask & lilGetRenderingLayer()) != 0 ? _MainLightColor.rgb : 0.0) #else #define LIL_MAINLIGHT_COLOR _MainLightColor.rgb #endif #define LIL_MAINLIGHT_DIRECTION _MainLightPosition.xyz // Shadow float4 GetShadowCoord(float3 positionWS, float4 positionCS) { VertexPositionInputs vertexInput = (VertexPositionInputs)0; vertexInput.positionWS = positionWS; vertexInput.positionCS = positionCS; return GetShadowCoord(vertexInput); } #if defined(LIL_USE_SHADOW) #if defined(_MAIN_LIGHT_SHADOWS_SCREEN) #define LIL_SHADOW_COORDS(idx) float4 shadowCoord : TEXCOORD##idx; #define LIL_TRANSFER_SHADOW(vi,uv,o) o.shadowCoord = GetShadowCoord(vi.positionWS, vi.positionCS); #define LIL_LIGHT_ATTENUATION(atten,i) atten = MainLightRealtimeShadow(i.shadowCoord) #elif defined(_MAIN_LIGHT_SHADOWS_CASCADE) && !defined(_MAIN_LIGHT_SHADOWS) #define LIL_SHADOW_COORDS(idx) #define LIL_TRANSFER_SHADOW(vi,uv,o) #define LIL_LIGHT_ATTENUATION(atten,i) atten = MainLightRealtimeShadow(TransformWorldToShadowCoord(i.positionWS)) #else #define LIL_SHADOW_COORDS(idx) float4 shadowCoord : TEXCOORD##idx; #define LIL_TRANSFER_SHADOW(vi,uv,o) o.shadowCoord = GetShadowCoord(vi.positionWS, vi.positionCS); #define LIL_LIGHT_ATTENUATION(atten,i) atten = MainLightRealtimeShadow(i.shadowCoord) #endif #else #define LIL_SHADOW_COORDS(idx) #define LIL_TRANSFER_SHADOW(vi,uv,o) #define LIL_LIGHT_ATTENUATION(atten,i) #endif // Shadow caster float3 _LightDirection; float3 _LightPosition; float4 URPShadowPos(float4 positionOS, float3 normalOS, float bias) { float3 positionWS = TransformObjectToWorld(positionOS.xyz); float3 normalWS = TransformObjectToWorldNormal(normalOS); #if _CASTING_PUNCTUAL_LIGHT_SHADOW float3 lightDirectionWS = normalize(_LightPosition - positionWS); #else float3 lightDirectionWS = _LightDirection; #endif positionWS -= lightDirectionWS * bias; #if LIL_SRP_VERSION_GREATER_EQUAL(5, 1) float4 positionCS = TransformWorldToHClip(ApplyShadowBias(positionWS, normalWS, lightDirectionWS)); #else float4 positionCS = TransformWorldToHClip(positionWS); #endif #if UNITY_REVERSED_Z positionCS.z = min(positionCS.z, UNITY_NEAR_CLIP_VALUE); #else positionCS.z = max(positionCS.z, UNITY_NEAR_CLIP_VALUE); #endif return positionCS; } #define LIL_V2F_SHADOW_CASTER_OUTPUT float4 positionCS : SV_POSITION; #define LIL_TRANSFER_SHADOW_CASTER(v,o) o.positionCS = URPShadowPos(v.positionOS, v.normalOS, _lilShadowCasterBias) #define LIL_SHADOW_CASTER_FRAGMENT(i) return 0 // Additional Light void lilGetAdditionalLights(float3 positionWS, float4 positionCS, float strength, inout float3 lightColor, inout float3 lightDirection) { uint renderingLayers = lilGetRenderingLayer(); float3 objPositionWS = lilGetObjectPosition(); #if defined(_ADDITIONAL_LIGHTS) || defined(_ADDITIONAL_LIGHTS_VERTEX) uint lightsCount = GetAdditionalLightsCount(); #if defined(USE_FORWARD_PLUS) && USE_FORWARD_PLUS ClusteredLightLoop cll = ClusteredLightLoopInit(GetNormalizedScreenSpaceUV(positionCS), positionWS); while (ClusteredLightLoopNext(cll)) { uint lightIndex = ClusteredLightLoopGetLightIndex(cll); #elif defined(USE_CLUSTERED_LIGHTING) && USE_CLUSTERED_LIGHTING ClusteredLightLoop cll = ClusteredLightLoopInit(GetNormalizedScreenSpaceUV(positionCS), positionWS); while(ClusteredLightLoopNextWord(cll)) { while(ClusteredLightLoopNextLight(cll)) { uint lightIndex = ClusteredLightLoopGetLightIndex(cll); #elif defined(_USE_WEBGL1_LIGHTS) && _USE_WEBGL1_LIGHTS for(uint lightIndex = 0; lightIndex < _WEBGL1_MAX_LIGHTS; lightIndex++) { if(lightIndex >= lightsCount) break; #else for(uint lightIndex = 0; lightIndex < lightsCount; lightIndex++) { #endif Light light = GetAdditionalLight(lightIndex, positionWS); #if LIL_SRP_VERSION_GREATER_EQUAL(12, 0) && defined(_LIGHT_LAYERS) if((light.layerMask & renderingLayers) != 0) #endif { lightColor += light.color * light.distanceAttenuation * strength; lightDirection += dot(light.color, float3(1.0/3.0, 1.0/3.0, 1.0/3.0)) * light.distanceAttenuation * strength * light.direction; } } #if defined(USE_CLUSTERED_LIGHTING) && USE_CLUSTERED_LIGHTING } #endif #endif #if defined(_ADDITIONAL_LIGHTS) && (defined(USE_CLUSTERED_LIGHTING) && USE_CLUSTERED_LIGHTING || defined(USE_FORWARD_PLUS) && USE_FORWARD_PLUS) for(uint lightIndex = 0; lightIndex < min(_AdditionalLightsDirectionalCount, MAX_VISIBLE_LIGHTS); lightIndex++) { Light light = GetAdditionalLight(lightIndex, positionWS); #if LIL_SRP_VERSION_GREATER_EQUAL(12, 0) && defined(_LIGHT_LAYERS) if((light.layerMask & renderingLayers) != 0) #endif lightColor += light.color * light.distanceAttenuation * strength; lightDirection += dot(light.color, float3(1.0/3.0, 1.0/3.0, 1.0/3.0)) * light.distanceAttenuation * strength * light.direction; } #endif } float3 lilGetAdditionalLights(float3 positionWS, float4 positionCS, float strength) { float3 lightColor = 0.0; float3 lightDirection = 0.0; lilGetAdditionalLights(positionWS, positionCS, strength, lightColor, lightDirection); return lightColor; } // Lightmap #define LIL_DECODE_LIGHTMAP(lm) DecodeLightmap(lm, float4(LIGHTMAP_HDR_MULTIPLIER,LIGHTMAP_HDR_EXPONENT,0.0,0.0)) #define LIL_DECODE_DYNAMICLIGHTMAP(lm) lm.rgb // Environment reflection #define LIL_GET_ENVIRONMENT_REFLECTION(viewDirection,normalDirection,perceptualRoughness,positionWS) \ ((IsEmpty(unity_SpecCube0) || unity_SpecCube0_HDR.x == 0 || _ReflectionCubeOverride) ? \ lilCustomReflection(_ReflectionCubeTex, _ReflectionCubeTex_HDR, viewDirection, normalDirection, perceptualRoughness) * _ReflectionCubeColor.rgb * lerp(1.0, fd.lightColor, _ReflectionCubeEnableLighting) : \ GlossyEnvironmentReflection(reflect(-viewDirection,normalDirection), perceptualRoughness, 1.0)) // Fog #if LIL_RENDER == 2 #define LIL_APPLY_FOG_BASE(col,fogCoord) col.rgb = lerp(unity_FogColor.rgb*col.a,col.rgb,fogCoord) #define LIL_APPLY_FOG_COLOR_BASE(col,fogCoord,fogColor) col.rgb = lerp(fogColor.rgb*col.a,col.rgb,fogCoord) #else #define LIL_APPLY_FOG_BASE(col,fogCoord) col.rgb = lerp(unity_FogColor.rgb,col.rgb,fogCoord) #define LIL_APPLY_FOG_COLOR_BASE(col,fogCoord,fogColor) col.rgb = lerp(fogColor.rgb,col.rgb,fogCoord) #endif #if LIL_SRP_VERSION_GREATER_EQUAL(7, 1) float lilCalcFogFactor(float depth) { #if defined(FOG_LINEAR) || defined(FOG_EXP) || defined(FOG_EXP2) return ComputeFogIntensity(ComputeFogFactor(depth)); #else return 1.0; #endif } #else float lilCalcFogFactor(float depth) { #if defined(FOG_LINEAR) || defined(FOG_EXP) || defined(FOG_EXP2) float factor = ComputeFogFactor(depth); #if defined(FOG_EXP) return saturate(exp2(-factor)); #elif defined(FOG_EXP2) return saturate(exp2(-factor*factor)); #elif defined(FOG_LINEAR) return factor; #else return 0.0; #endif #else return 1.0; #endif } #endif #endif // Meta #if !defined(LIL_BRP) && (LIL_SRP_VERSION_LOWER(5, 14)) #define LIL_TRANSFER_METAPASS(input,output) \ output.positionCS = MetaVertexPosition(input.positionOS, input.uv1, input.uv2, unity_LightmapST) #else #define LIL_TRANSFER_METAPASS(input,output) \ output.positionCS = MetaVertexPosition(input.positionOS, input.uv1, input.uv2, unity_LightmapST, unity_DynamicLightmapST) #endif #if defined(LIL_HDRP) #define LIL_IS_MIRROR false #define LIL_LIGHTDIRECTION_ORIG lightDirection #else #define LIL_IS_MIRROR (dot(cross(LIL_MATRIX_V[0].xyz, LIL_MATRIX_V[1].xyz), LIL_MATRIX_V[2].xyz) > 0) #define LIL_LIGHTDIRECTION_ORIG LIL_MAINLIGHT_DIRECTION #endif //------------------------------------------------------------------------------------------------------------------------------ // Pi #define LIL_PI 3.14159265359f #define LIL_TWO_PI 6.28318530718f #define LIL_FOUR_PI 12.56637061436f #define LIL_INV_PI 0.31830988618f #define LIL_INV_TWO_PI 0.15915494309f #define LIL_INV_FOUR_PI 0.07957747155f #define LIL_HALF_PI 1.57079632679f #define LIL_INV_HALF_PI 0.636619772367f // Time #define LIL_TIME _Time.y #define LIL_INTER_TIME lilIntervalTime(_TimeInterval) // Interpolation for Tessellation #define LIL_TRI_INTERPOLATION(i,o,bary,type) o.type = bary.x * i[0].type + bary.y * i[1].type + bary.z * i[2].type // Specular dielectric #ifdef LIL_COLORSPACE_GAMMA #define LIL_DIELECTRIC_SPECULAR float4(0.220916301, 0.220916301, 0.220916301, 1.0 - 0.220916301) #else #define LIL_DIELECTRIC_SPECULAR float4(0.04, 0.04, 0.04, 1.0 - 0.04) #endif // Do not apply shadow #if (defined(LIL_LITE) || defined(LIL_FUR) || defined(LIL_GEM)) && !defined(LIL_PASS_FORWARDADD) #undef LIL_SHADOW_COORDS #undef LIL_TRANSFER_SHADOW #undef LIL_LIGHT_ATTENUATION #define LIL_SHADOW_COORDS(idx) #define LIL_TRANSFER_SHADOW(vi,uv,o) #define LIL_LIGHT_ATTENUATION(atten,i) #endif // Transform #define LIL_VERTEX_POSITION_INPUTS(positionOS,o) lilVertexPositionInputs o = lilGetVertexPositionInputs(positionOS.xyz) #define LIL_RE_VERTEX_POSITION_INPUTS(o) o = lilReGetVertexPositionInputs(o) #define LIL_VERTEX_NORMAL_INPUTS(normalOS,o) lilVertexNormalInputs o = lilGetVertexNormalInputs(normalOS) #define LIL_VERTEX_NORMAL_TANGENT_INPUTS(normalOS,tangentOS,o) lilVertexNormalInputs o = lilGetVertexNormalInputs(normalOS,tangentOS) // Lightmap #if defined(LIL_USE_DOTS_INSTANCING) #define LIL_SHADOWMAP_TEX unity_ShadowMasks #define LIL_SHADOWMAP_SAMP samplerunity_ShadowMasks #define LIL_LIGHTMAP_TEX unity_Lightmaps #define LIL_LIGHTMAP_SAMP samplerunity_Lightmaps #define LIL_LIGHTMAP_DIR_TEX unity_LightmapsInd #define LIL_SAMPLE_LIGHTMAP(tex,samp,uv) LIL_SAMPLE_2D_ARRAY(tex,samp,uv,unity_LightmapIndex.x) #else #define LIL_SHADOWMAP_TEX unity_ShadowMask #define LIL_SHADOWMAP_SAMP samplerunity_ShadowMask #define LIL_LIGHTMAP_TEX unity_Lightmap #define LIL_LIGHTMAP_SAMP samplerunity_Lightmap #define LIL_LIGHTMAP_DIR_TEX unity_LightmapInd #define LIL_SAMPLE_LIGHTMAP(tex,samp,uv) LIL_SAMPLE_2D(tex,samp,uv) #endif #define LIL_DYNAMICLIGHTMAP_TEX unity_DynamicLightmap #define LIL_DYNAMICLIGHTMAP_SAMP samplerunity_DynamicLightmap #define LIL_DYNAMICLIGHTMAP_DIR_TEX unity_DynamicDirectionality float3 lilGetLightMapColor(float2 uv1, float2 uv2) { float3 outCol = 0; #if defined(LIL_USE_LIGHTMAP) float2 lightmapUV = uv1 * unity_LightmapST.xy + unity_LightmapST.zw; float4 lightmap = LIL_SAMPLE_LIGHTMAP(LIL_LIGHTMAP_TEX, LIL_LIGHTMAP_SAMP, lightmapUV); outCol += LIL_DECODE_LIGHTMAP(lightmap); #endif #if defined(LIL_USE_DYNAMICLIGHTMAP) float2 dynlightmapUV = uv2 * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw; float4 dynlightmap = LIL_SAMPLE_2D(LIL_DYNAMICLIGHTMAP_TEX, LIL_DYNAMICLIGHTMAP_SAMP, dynlightmapUV); outCol += LIL_DECODE_DYNAMICLIGHTMAP(dynlightmap); #endif return outCol; } float3 lilGetLightMapDirection(float2 uv) { float3 lightmapDir = 0.0; #if defined(LIL_USE_LIGHTMAP) && defined(LIL_USE_DIRLIGHTMAP) float4 lightmapDirection = LIL_SAMPLE_LIGHTMAP(LIL_DIRLIGHTMAP_TEX, LIL_LIGHTMAP_SAMP, uv); lightmapDir = lightmapDirection.xyz * 2.0 - 1.0; #endif #if defined(LIL_USE_DYNAMICLIGHTMAP) && defined(LIL_USE_DIRLIGHTMAP) float4 lightmapDirection = LIL_SAMPLE_LIGHTMAP(LIL_DYNAMICLIGHTMAP_DIR_TEX, LIL_DYNAMICLIGHTMAP_SAMP, uv); lightmapDir = lightmapDirection.xyz * 2.0 - 1.0; #endif return lightmapDir; } // Main Light Coords #if defined(LIL_PASS_FORWARDADD) #define LIL_LIGHTCOLOR_COORDS(idx) #define LIL_LIGHTDIRECTION_COORDS(idx) #else #define LIL_LIGHTCOLOR_COORDS(idx) float3 lightColor : TEXCOORD##idx; #define LIL_LIGHTDIRECTION_COORDS(idx) float3 lightDirection : TEXCOORD##idx; #endif #if !defined(LIL_PASS_FORWARDADD) && (defined(LIL_FEATURE_SHADOW) || defined(LIL_LITE)) #define LIL_INDLIGHTCOLOR_COORDS(idx) float3 indLightColor : TEXCOORD##idx; #define LIL_GET_INDLIGHTCOLOR(i,o) o.indLightColor = i.indLightColor #else #define LIL_INDLIGHTCOLOR_COORDS(idx) #define LIL_GET_INDLIGHTCOLOR(i,o) #endif // Dir light & indir light #if defined(LIL_USE_LPPV) && (defined(LIL_FEATURE_SHADOW) || defined(LIL_LITE)) #define LIL_CALC_TWOLIGHT(i,o) lilGetLightColorDouble(i.positionWS, o.lightColor, o.indLightColor) #elif defined(LIL_FEATURE_SHADOW) || defined(LIL_LITE) #define LIL_CALC_TWOLIGHT(i,o) lilGetLightColorDouble(o.lightColor, o.indLightColor) #elif defined(LIL_USE_LPPV) #define LIL_CALC_TWOLIGHT(i,o) o.lightColor = lilGetLightColor(i.positionWS) #else #define LIL_CALC_TWOLIGHT(i,o) o.lightColor = lilGetLightColor() #endif // Main Light in VS (Color / Direction) struct lilLightData { float3 lightDirection; float3 lightColor; float3 indLightColor; }; // Main Light in VS #if defined(LIL_USE_ADDITIONALLIGHT_MAIN) #define LIL_APPLY_ADDITIONALLIGHT_TO_MAIN(i,o) \ float3 additionalLightDirection = 0.0; \ lilGetAdditionalLights(i.positionWS, i.positionCS/float4(i.positionCS.www,1.0)*float4(LIL_SCREENPARAMS.xy,1.0,1.0), LIL_ADDITIONAL_LIGHT_STRENGTH, o.lightColor, additionalLightDirection) #define LIL_CORRECT_LIGHTDIRECTION_PS(lightDirection) lightDirection = normalize(lightDirection) #elif defined(LIL_USE_ADDITIONALLIGHT_MAINDIR) #define LIL_APPLY_ADDITIONALLIGHT_TO_MAIN(i,o) \ lilGetAdditionalLights(i.positionWS, i.positionCS/float4(i.positionCS.www,1.0)*float4(LIL_SCREENPARAMS.xy,1.0,1.0), LIL_ADDITIONAL_LIGHT_STRENGTH, o.lightColor, o.lightDirection) #define LIL_CORRECT_LIGHTDIRECTION_PS(lightDirection) lightDirection = normalize(lightDirection) #elif defined(LIL_USE_ADDITIONALLIGHT_MAINDIR_PS) #define LIL_APPLY_ADDITIONALLIGHT_TO_MAIN(i,o) #define LIL_CORRECT_LIGHTDIRECTION_PS(lightDirection) lightDirection = normalize(lightDirection) #else #define LIL_APPLY_ADDITIONALLIGHT_TO_MAIN(i,o) #define LIL_CORRECT_LIGHTDIRECTION_PS(lightDirection) #endif #if defined(LIL_USE_LIGHTMAP) || defined(LIL_USE_ADDITIONALLIGHT_MAINDIR_PS) #define LIL_CORRECT_LIGHTCOLOR_VS(lightColor) #define LIL_CORRECT_LIGHTCOLOR_PS(lightColor) \ lightColor = clamp(lightColor, _LightMinLimit, _LightMaxLimit); \ lightColor = lerp(lightColor, lilGray(lightColor), _MonochromeLighting); \ lightColor = lerp(lightColor, 1.0, _AsUnlit) #else #define LIL_CORRECT_LIGHTCOLOR_VS(lightColor) \ lightColor = clamp(lightColor, _LightMinLimit, _LightMaxLimit); \ lightColor = lerp(lightColor, lilGray(lightColor), _MonochromeLighting); \ lightColor = lerp(lightColor, 1.0, _AsUnlit) #define LIL_CORRECT_LIGHTCOLOR_PS(lightColor) #endif #if defined(LIL_PASS_FORWARDADD) #define LIL_CALC_MAINLIGHT(i,o) #elif defined(LIL_HDRP) #define LIL_CALC_MAINLIGHT(i,o) \ lilLightData o; \ lilGetLightDirectionAndColor(o.lightDirection, o.lightColor, posInput); \ o.lightColor *= _lilDirectionalLightStrength; \ float3 lightDirectionCopy = o.lightDirection; \ o.lightDirection = o.lightDirection * Luminance(o.lightColor) + unity_SHAr.xyz * 0.333333 + unity_SHAg.xyz * 0.333333 + unity_SHAb.xyz * 0.333333; \ float3 lightDirectionSH = dot(o.lightDirection,o.lightDirection) < 0.000001 ? 0 : normalize(o.lightDirection); \ o.lightDirection += lilGetCustomLightDirection(_LightDirectionOverride); \ o.lightColor += lilShadeSH9(float4(lightDirectionSH * 0.666666, 1.0)); \ o.indLightColor = lilShadeSH9(float4(-lightDirectionSH * 0.666666, 1.0)); \ o.indLightColor = saturate(o.indLightColor / Luminance(o.lightColor)); \ o.lightColor = min(o.lightColor, _BeforeExposureLimit); \ o.lightColor *= GetCurrentExposureMultiplier(); \ LIL_APPLY_ADDITIONALLIGHT_TO_MAIN(i,o); \ LIL_CORRECT_LIGHTCOLOR_VS(o.lightColor) #elif defined(LIL_BRP) #define LIL_CALC_MAINLIGHT(i,o) \ OpenLitLightDatas lightDatas; \ ComputeLights(lightDatas, _LightDirectionOverride); \ lilLightData o; \ o.lightDirection = lightDatas.lightDirection; \ o.lightColor = lightDatas.directLight; \ o.indLightColor = lightDatas.indirectLight; \ LIL_APPLY_ADDITIONALLIGHT_TO_MAIN(i,o); \ LIL_CORRECT_LIGHTCOLOR_VS(o.lightColor) #else #define LIL_CALC_MAINLIGHT(i,o) \ lilLightData o; \ o.lightDirection = normalize(LIL_MAINLIGHT_DIRECTION * lilLuminance(LIL_MAINLIGHT_COLOR) + unity_SHAr.xyz * 0.333333 + unity_SHAg.xyz * 0.333333 + unity_SHAb.xyz * 0.333333); \ LIL_CALC_TWOLIGHT(i,o); \ o.lightDirection = lilGetFixedLightDirection(_LightDirectionOverride, false); \ LIL_APPLY_ADDITIONALLIGHT_TO_MAIN(i,o); \ LIL_CORRECT_LIGHTCOLOR_VS(o.lightColor) #endif // Main Light in PS (Color / Direction / Attenuation) #if defined(LIL_PASS_FORWARDADD) // Point Light & Spot Light (ForwardAdd) #define LIL_GET_MAINLIGHT(input,lc,ld,atten) \ ld = lilGetLightDirection(input.positionWS); \ lc = min(LIL_MAINLIGHT_COLOR * atten, _LightMaxLimit); \ lc = lerp(lc, lilGray(lc), _MonochromeLighting); \ lc = lerp(lc, 0.0, _AsUnlit) #elif defined(LIL_HDRP) && defined(LIL_USE_LIGHTMAP) // HDRP with lightmap #define LIL_GET_MAINLIGHT(input,lc,ld,atten) \ lc = input.lightColor; \ float3 lightmapColor = lilGetLightMapColor(fd.uv1,fd.uv2); \ lc += lightmapColor * GetCurrentExposureMultiplier(); \ LIL_CORRECT_LIGHTCOLOR_PS(lc); \ LIL_CORRECT_LIGHTDIRECTION_PS(ld) #elif defined(LIL_USE_LIGHTMAP) && defined(LIL_LIGHTMODE_SHADOWMASK) // Mixed Lightmap (Shadowmask) #define LIL_GET_MAINLIGHT(input,lc,ld,atten) \ lc = input.lightColor; \ float3 lightmapColor = lilGetLightMapColor(fd.uv1,fd.uv2); \ lc = max(lc, lightmapColor); \ LIL_CORRECT_LIGHTCOLOR_PS(lc); \ LIL_CORRECT_LIGHTDIRECTION_PS(ld); \ atten = min(atten, LIL_SAMPLE_LIGHTMAP(LIL_SHADOWMAP_TEX,LIL_LIGHTMAP_SAMP,fd.uv1).r) #elif defined(LIL_USE_LIGHTMAP) && defined(LIL_LIGHTMODE_SUBTRACTIVE) && defined(LIL_USE_DYNAMICLIGHTMAP) // Mixed Lightmap (Subtractive) // Use Lightmap as Shadowmask #undef LIL_USE_DYNAMICLIGHTMAP #define LIL_GET_MAINLIGHT(input,lc,ld,atten) \ lc = input.lightColor; \ float3 lightmapColor = lilGetLightMapColor(fd.uv1,fd.uv2); \ lc = max(lc, lightmapColor); \ LIL_CORRECT_LIGHTCOLOR_PS(lc); \ LIL_CORRECT_LIGHTDIRECTION_PS(ld); \ float3 lightmapShadowThreshold = LIL_MAINLIGHT_COLOR*0.5; \ float3 lightmapS = (lightmapColor - lightmapShadowThreshold) / (LIL_MAINLIGHT_COLOR - lightmapShadowThreshold); \ float lightmapAttenuation = saturate((lightmapS.r+lightmapS.g+lightmapS.b)/3.0); \ atten = min(atten, lightmapAttenuation) #elif defined(LIL_USE_LIGHTMAP) && defined(LIL_LIGHTMODE_SUBTRACTIVE) // Mixed Lightmap (Subtractive) // Use Lightmap as Shadowmask #define LIL_GET_MAINLIGHT(input,lc,ld,atten) \ lc = input.lightColor; \ float3 lightmapColor = lilGetLightMapColor(fd.uv1,fd.uv2); \ lc = max(lc, lightmapColor); \ LIL_CORRECT_LIGHTCOLOR_PS(lc); \ LIL_CORRECT_LIGHTDIRECTION_PS(ld); \ float3 lightmapS = (lightmapColor - lilShadeSH9(input.normalWS)) / LIL_MAINLIGHT_COLOR; \ float lightmapAttenuation = saturate((lightmapS.r+lightmapS.g+lightmapS.b)/3.0); \ atten = min(atten, lightmapAttenuation) #elif defined(LIL_USE_LIGHTMAP) && defined(LIL_USE_DIRLIGHTMAP) // Lightmap (Directional) #define LIL_GET_MAINLIGHT(input,lc,ld,atten) \ lc = input.lightColor; \ float3 lightmapColor = lilGetLightMapColor(fd.uv1,fd.uv2); \ float3 lightmapDirection = lilGetLightMapDirection(input.uv1); \ lc = saturate(lc + lightmapColor); \ LIL_CORRECT_LIGHTCOLOR_PS(lc); \ ld = normalize(ld + lightmapDirection * lilLuminance(lightmapColor)); \ LIL_CORRECT_LIGHTDIRECTION_PS(ld) #elif defined(LIL_USE_LIGHTMAP) && defined(LIL_USE_SHADOW) // Mixed Lightmap (Baked Indirect) with shadow #define LIL_GET_MAINLIGHT(input,lc,ld,atten) \ lc = LIL_MAINLIGHT_COLOR; \ float3 lightmapColor = lilGetLightMapColor(fd.uv1,fd.uv2); \ lc = saturate(lc + max(lightmapColor,lilGetSHToon())); \ LIL_CORRECT_LIGHTCOLOR_PS(lc); \ LIL_CORRECT_LIGHTDIRECTION_PS(ld) #elif defined(LIL_USE_LIGHTMAP) && defined(LIL_USE_DYNAMICLIGHTMAP) // Mixed Lightmap (Baked Indirect) or Lightmap (Non-Directional) #undef LIL_USE_DYNAMICLIGHTMAP #define LIL_GET_MAINLIGHT(input,lc,ld,atten) \ lc = input.lightColor; \ float3 lightmapColor = lilGetLightMapColor(fd.uv1,fd.uv2); \ lc = saturate(lc + lightmapColor); \ LIL_CORRECT_LIGHTCOLOR_PS(lc); \ LIL_CORRECT_LIGHTDIRECTION_PS(ld) #elif defined(LIL_USE_LIGHTMAP) // Mixed Lightmap (Baked Indirect) or Lightmap (Non-Directional) #define LIL_GET_MAINLIGHT(input,lc,ld,atten) \ lc = LIL_MAINLIGHT_COLOR; \ float3 lightmapColor = lilGetLightMapColor(fd.uv1,fd.uv2); \ lc = saturate(lc + lightmapColor); \ LIL_CORRECT_LIGHTCOLOR_PS(lc); \ LIL_CORRECT_LIGHTDIRECTION_PS(ld) #elif defined(LIL_USE_ADDITIONALLIGHT_MAINDIR_PS) // Realtime #define LIL_GET_MAINLIGHT(input,lc,ld,atten) \ lc = input.lightColor; \ lilGetAdditionalLights(input.positionWS, input.positionCS, LIL_ADDITIONAL_LIGHT_STRENGTH, lc, ld); \ LIL_CORRECT_LIGHTCOLOR_PS(lc); \ LIL_CORRECT_LIGHTDIRECTION_PS(ld) #elif defined(LIL_USE_ADDITIONALLIGHT_MAINDIR) // Realtime #define LIL_GET_MAINLIGHT(input,lc,ld,atten) \ lc = input.lightColor; \ LIL_CORRECT_LIGHTDIRECTION_PS(ld) #else // Realtime #define LIL_GET_MAINLIGHT(input,lc,ld,atten) \ lc = input.lightColor; \ LIL_CORRECT_LIGHTDIRECTION_PS(ld) #endif // Additional Light VS and Fog #if defined(LIL_USE_ADDITIONALLIGHT_VS) #define LIL_VERTEXLIGHT_FOG_TYPE float4 #define LIL_VERTEXLIGHT_FOG_COORDS(idx) float4 vlf : TEXCOORD##idx; #define LIL_TRANSFER_FOG(i,o) o.vlf.w = lilCalcFogFactor(i.positionCS.z) #define LIL_APPLY_FOG(col,i) LIL_APPLY_FOG_BASE(col,i.vlf.w) #define LIL_APPLY_FOG_COLOR(col,i,fogColor) LIL_APPLY_FOG_COLOR_BASE(col,i.vlf.w,fogColor) #elif defined(LIL_HDRP) #define LIL_VERTEXLIGHT_FOG_TYPE #define LIL_VERTEXLIGHT_FOG_COORDS(idx) #define LIL_TRANSFER_FOG(i,o) #define LIL_APPLY_FOG(col,i) LIL_APPLY_FOG_BASE(col,i.vlf) #define LIL_APPLY_FOG_COLOR(col,i,fogColor) LIL_APPLY_FOG_COLOR_BASE(col,i.vlf,fogColor) #else #define LIL_VERTEXLIGHT_FOG_TYPE float #define LIL_VERTEXLIGHT_FOG_COORDS(idx) float vlf : TEXCOORD##idx; #define LIL_TRANSFER_FOG(i,o) o.vlf = lilCalcFogFactor(i.positionCS.z) #define LIL_APPLY_FOG(col,i) LIL_APPLY_FOG_BASE(col,i.vlf) #define LIL_APPLY_FOG_COLOR(col,i,fogColor) LIL_APPLY_FOG_COLOR_BASE(col,i.vlf,fogColor) #endif #if defined(LIL_USE_ADDITIONALLIGHT_VS) && (defined(VERTEXLIGHT_ON) || !defined(LIL_BRP)) #define LIL_CALC_VERTEXLIGHT(i,o) \ o.vlf.rgb = lilGetAdditionalLights(i.positionWS, i.positionCS/float4(i.positionCS.www,1.0)*float4(LIL_SCREENPARAMS.xy,1.0,1.0), LIL_ADDITIONAL_LIGHT_STRENGTH); \ o.vlf.rgb = lerp(o.vlf.rgb, lilGray(o.vlf.rgb), _MonochromeLighting); \ o.vlf.rgb = lerp(o.vlf.rgb, 0.0, _AsUnlit) #elif defined(LIL_USE_ADDITIONALLIGHT_VS) #define LIL_CALC_VERTEXLIGHT(i,o) #elif defined(LIL_USE_ADDITIONALLIGHT_MAIN) #define LIL_CALC_VERTEXLIGHT(i,o) #else #define LIL_CALC_VERTEXLIGHT(i,o) #endif // Additional Light PS #if defined(LIL_USE_ADDITIONALLIGHT_PS) #define LIL_GET_ADDITIONALLIGHT(i,o) \ o = lilGetAdditionalLights(i.positionWS, i.positionCS, LIL_ADDITIONAL_LIGHT_STRENGTH); \ o = lerp(o, lilGray(o), _MonochromeLighting); \ o = lerp(o, 0.0, _AsUnlit) #elif defined(LIL_USE_ADDITIONALLIGHT_VS) #define LIL_GET_ADDITIONALLIGHT(i,o) \ o = i.vlf.rgb #elif defined(LIL_USE_ADDITIONALLIGHT_MAIN) #define LIL_GET_ADDITIONALLIGHT(i,o) \ o = 0 #else #define LIL_GET_ADDITIONALLIGHT(i,o) \ o = 0 #endif // Fragment Macro #define LIL_GET_LIGHTING_DATA(input,fd) \ LIL_GET_MAINLIGHT(input, fd.lightColor, fd.L, fd.attenuation); \ LIL_GET_ADDITIONALLIGHT(input, fd.addLightColor); \ fd.invLighting = saturate((1.0 - fd.lightColor) * sqrt(fd.lightColor)) #define LIL_GET_POSITION_WS_DATA(input,fd) \ fd.depth = length(lilHeadDirection(fd.positionWS)); \ fd.V = normalize(lilViewDirection(fd.positionWS)); \ fd.headV = normalize(lilHeadDirection(fd.positionWS)); \ fd.vl = dot(fd.V, fd.L); \ fd.hl = dot(fd.headV, fd.L); \ fd.uvPanorama = lilGetPanoramaUV(fd.V) #define LIL_GET_TBN_DATA(input,fd) \ float3 bitangentWS = cross(input.normalWS, input.tangentWS.xyz) * (input.tangentWS.w * LIL_NEGATIVE_SCALE); \ fd.TBN = float3x3(input.tangentWS.xyz, bitangentWS, input.normalWS) #define LIL_GET_PARALLAX_DATA(input,fd) \ fd.parallaxViewDirection = mul(fd.TBN, fd.V); \ fd.parallaxOffset = (fd.parallaxViewDirection.xy / (fd.parallaxViewDirection.z+0.5)) // Main Color & Emission #if defined(LIL_BAKER) #define LIL_GET_SUBTEX(tex,uv) lilGetSubTexWithoutAnimation(tex, tex##_ST, tex##Angle, uv, 1, tex##IsDecal, tex##IsLeftOnly, tex##IsRightOnly, tex##ShouldCopy, tex##ShouldFlipMirror, tex##ShouldFlipCopy, tex##IsMSDF, isRightHand LIL_SAMP_IN(sampler##tex)) #define LIL_GET_EMITEX(tex,uv) LIL_SAMPLE_2D(tex, sampler##tex, lilCalcUVWithoutAnimation(uv, tex##_ST, tex##_ScrollRotate)) #define LIL_GET_EMIMASK(tex,uv) LIL_SAMPLE_2D(tex, sampler_MainTex, lilCalcUVWithoutAnimation(uv, tex##_ST, tex##_ScrollRotate)) #elif defined(LIL_WITHOUT_ANIMATION) #define LIL_GET_SUBTEX(tex,uv) lilGetSubTexWithoutAnimation(tex, tex##_ST, tex##Angle, uv, 1, tex##IsDecal, tex##IsLeftOnly, tex##IsRightOnly, tex##ShouldCopy, tex##ShouldFlipMirror, tex##ShouldFlipCopy, tex##IsMSDF, fd.isRightHand LIL_SAMP_IN(sampler##tex)) #define LIL_GET_EMITEX(tex,uv) LIL_SAMPLE_2D(tex, sampler##tex, lilCalcUVWithoutAnimation(uv, tex##_ST, tex##_ScrollRotate)) #define LIL_GET_EMIMASK(tex,uv) LIL_SAMPLE_2D(tex, sampler_MainTex, lilCalcUVWithoutAnimation(uv, tex##_ST, tex##_ScrollRotate)) #else #define LIL_GET_SUBTEX(tex,uv) lilGetSubTex(tex, tex##_ST, tex##Angle, uv, fd.nv, tex##IsDecal, tex##IsLeftOnly, tex##IsRightOnly, tex##ShouldCopy, tex##ShouldFlipMirror, tex##ShouldFlipCopy, tex##IsMSDF, fd.isRightHand, tex##DecalAnimation, tex##DecalSubParam LIL_SAMP_IN(sampler##tex)) #define LIL_GET_EMITEX(tex,uv) LIL_SAMPLE_2D(tex, sampler##tex, lilCalcUV(uv, tex##_ST, tex##_ScrollRotate)) #define LIL_GET_EMIMASK(tex,uv) LIL_SAMPLE_2D(tex, sampler_MainTex, lilCalcUV(uv, tex##_ST, tex##_ScrollRotate)) #endif // Fallback #define UnpackNormalScale(normal,scale) lilUnpackNormalScale(normal,scale) #endif