// Copyright (c) Le Loc Tai . All rights reserved. Do not redistribute. using System.Diagnostics; using LeTai.Common; using LeTai.Paraform; using LeTai.Paraform.Scaffold; using UnityEngine; namespace LeTai.Asset.TranslucentImage { public partial class TranslucentImage { public ParaformConfig paraformConfig = ParaformConfig.DEFAULT; float etaCache = 1 / 1.5f; float previousScale = 0; private static float GetMaxRefractionOffset(float minDistance, float eta) { float k = 1.0f - eta * eta; float offset = Mathf.Sqrt(k) * minDistance / eta; return offset; } [Conditional("LETAI_PARAFORM")] private void PadRectForRefraction(ref Rect rect) { var offset = GetMaxRefractionOffset(paraformConfig.Elevation, etaCache); float padX; float padY; var minExtent = Mathf.Min(rect.width, rect.height) / 2f; var ringThickness = Mathf.Max(0, Mathf.Min(paraformConfig.RingThickness, minExtent)); if (ringThickness == 0 || ringThickness > minExtent) { padX = Mathf.Max(0, offset - rect.width); padY = Mathf.Max(0, offset - rect.height); } else { padX = Mathf.Max(0, offset - ringThickness); padY = Mathf.Max(0, offset - ringThickness); } rect.x -= padX / 2; rect.y -= padY / 2; rect.width += padX; rect.height += padY; } [Conditional("LETAI_PARAFORM")] private void CacheEta() { var etas = material.GetVector(ShaderID.REFRACTIVE_INDEX_RATIOS); etaCache = Mathf.Min(etas.x, Mathf.Min(etas.y, etas.z)); } [Conditional("LETAI_PARAFORM")] void SetParaformShaderGlobal() { if (!canvas) // trigger on undo return; Shader.SetGlobalFloat(ShaderID.G_CANVAS_SCALE_FACTOR, canvas.scaleFactor); } [Conditional("LETAI_PARAFORM")] void LateUpdate() { var localScale = rectTransform.localScale; // var scale = (localScale.x + localScale.y) / 2f; var scale = Mathf.Max(localScale.x, localScale.y); if (Mathf.Abs(scale - previousScale) > 1e-5f) { SetVerticesDirty(); previousScale = scale; } } [Conditional("LETAI_PARAFORM")] public static void CopyParaformMaterialPropertiesTo(Material src, Material dst) { MaterialUtils.CopyKeyword(src, dst, ShaderID.REFRACTION_MODE_OFF); MaterialUtils.CopyKeyword(src, dst, ShaderID.REFRACTION_MODE_ON); MaterialUtils.CopyKeyword(src, dst, ShaderID.REFRACTION_MODE_CHROMATIC); MaterialUtils.CopyKeyword(src, dst, ShaderID.USE_EDGE_GLINT); MaterialUtils.CopyFloat(src, dst, ShaderID.REFRACTIVE_INDEX_DUMMY); MaterialUtils.CopyFloat(src, dst, ShaderID.CHROMATIC_DISPERSION_DUMMY); MaterialUtils.CopyVector(src, dst, ShaderID.REFRACTIVE_INDEX_RATIOS); MaterialUtils.CopyVector(src, dst, ShaderID.EDGE_GLINT_DIRECTIONS); MaterialUtils.CopyFloat(src, dst, ShaderID.EDGE_GLINT1_STRENGTH); MaterialUtils.CopyFloat(src, dst, ShaderID.EDGE_GLINT2_STRENGTH); MaterialUtils.CopyFloat(src, dst, ShaderID.EDGE_GLINT_WRAP_RAW); MaterialUtils.CopyFloat(src, dst, ShaderID.EDGE_GLINT_SHARPNESS_RAW); } #if LETAI_PARAFORM public override bool IsRaycastLocationValid(Vector2 screenPoint, Camera eventCamera) { if (!RectTransformUtilityPatch.ScreenPointToLocalPointInRectangle(rectTransform, screenPoint, eventCamera, out var local)) return false; Rect rect = GetPixelAdjustedRect(); var padding = raycastPadding; rect.xMin += padding.x; rect.yMin += padding.y; rect.xMax -= padding.z; rect.yMax -= padding.w; if (!ParaformUtils.IsRaycastLocationValid(paraformConfig, rect, local)) return false; return base.IsRaycastLocationValid(screenPoint, eventCamera); } protected override void OnDidApplyAnimationProperties() { SetVerticesDirty(); base.OnDidApplyAnimationProperties(); } /// /// Convenience wrapper for . /// For better performance, use that instead and manage the material yourself. /// public void SetDispersionSlow(float dispersion) { ParaformMaterial.SetDispersion(materialForRendering, dispersion); } /// /// Convenience wrapper for . /// For better performance, use that instead and manage the material yourself. /// public void SetRefractiveIndexSlow(float refractiveIndex) { ParaformMaterial.SetRefractiveIndex(materialForRendering, refractiveIndex); } /// /// Convenience wrapper for . /// For better performance, use that instead and manage the material yourself. /// public void SetRefractiveIndexRatiosSlow(float refractiveIndex, float chromaticDispersion) { ParaformMaterial.SetRefractiveIndexRatios(materialForRendering, refractiveIndex, chromaticDispersion); } /// /// Convenience wrapper for . /// For better performance, use that instead and manage the material yourself. /// public void SetEdgeGlintWrap(float edgeGlintWrapNormalized) { ParaformMaterial.SetEdgeGlintWrap(materialForRendering, edgeGlintWrapNormalized); } /// /// Convenience wrapper for . /// For better performance, use that instead and manage the material yourself. /// public void SetEdgeGlintSharpness(float edgeGlintSharpnessNormalized) { ParaformMaterial.SetEdgeGlintSharpness(materialForRendering, edgeGlintSharpnessNormalized); } #endif } }