Get it on Google Play


Wm뮤 :: AutomaticShadowDistance

블로그 이미지
가끔 그림그리거나 3D모델링하거나
취미로 로봇만드는
퇴직한 전자과 게임프로그래머
2020.3.48f1 , 2022.3.6f1 주로 사용
모카쨩
@Ahzkwid

Recent Comment

Archive


2024. 4. 18. 15:40 Unity/C#

 

 

 

https://ahzkwid.booth.pm/items/5632873

 

Automatic Shadow Distance - Wmup - BOOTH

ワールド用です DirectionalLightの影の長さをFPSに応じて自動的に変更するツールです。 動きがきれいじゃないので、キャラクターシャドウ専用に使用するのをお勧めします - Code - https://gist.githu

ahzkwid.booth.pm

여기서 다운 가능

 

 

 

 

 

using UdonSharp;
using UnityEngine;
using UnityEngine.UI;
using VRC.SDKBase;
using VRC.Udon;

[UdonBehaviourSyncMode(BehaviourSyncMode.None)]
public class AutomaticShadowDistance : UdonSharpBehaviour
{
    public Light directionalLight;
    public float frameCheckTimeCycle = 3f;
    int playerLayerIndex = 9;
    public Vector2 targetFps = new Vector2(30, 60);
    public Vector2 defaultShadowDistance = new Vector2(10, 80);
    public Vector2 playerShadowDistance = new Vector2(1,15);

    float tPre = 2;

    void UpdateShadowDistance(float t)
    {
        var defaultShadowDistanceMin = defaultShadowDistance.x;
        var defaultShadowDistanceMax = defaultShadowDistance.y;
        var playerShadowDistanceMin = playerShadowDistance.x;
        var playerShadowDistanceMax = playerShadowDistance.y;


        var targetDistanceDefault = Mathf.Lerp(defaultShadowDistanceMin, defaultShadowDistanceMax, t);
        var targetDistancePlayer = Mathf.Lerp(playerShadowDistanceMin, playerShadowDistanceMax, t);
        
        {
            //QualitySettings.shadowDistance = targetDistanceDefault;
        }
        {
            var ShadowCullDistances = new float[32];
            //ShadowCullDistances[0] = Mathf.Lerp(ShadowCullDistances[0], targetDistanceDefault, 0.1f);
            ShadowCullDistances[0] = targetDistanceDefault;
            ShadowCullDistances[11] = ShadowCullDistances[0];
            ShadowCullDistances[13] = ShadowCullDistances[0];
            ShadowCullDistances[14] = ShadowCullDistances[0];
            ShadowCullDistances[playerLayerIndex] = targetDistancePlayer;
            ShadowCullDistances[10] = ShadowCullDistances[playerLayerIndex];
            ShadowCullDistances[18] = ShadowCullDistances[playerLayerIndex];
            directionalLight.layerShadowCullDistances = ShadowCullDistances;

            //Camera.main.layerCullDistances = ShadowCullDistances;
        }
    }

    LightShadows shadowType = LightShadows.Soft;
    void Start()
    {
        //if (directionalLight==null)
        //{
        //    /*
        //    var lights = FindObjectsOfType<Light>();
        //    foreach (var light in lights)
        //    {
        //        if (light.type==LightType.Directional)
        //        {
        //            directionalLight = light;
        //        }
        //    }
        //    */
        //    /*
        //    var light= FindObjectOfType<Light>();
        //    if (light.type == LightType.Directional)
        //    {
        //        directionalLight = light;
        //    }
        //    */
        //}
        if (directionalLight.shadows != LightShadows.None)
        {
            shadowType = directionalLight.shadows;
        }

        UpdateShadowDistance(0);

        lastCheckTime = 0;
    }
    float lastCheckTime = 0;
    int frameCount = 0;

    public Toggle toggle;
    public Slider slider;
    public GameObject lockPanel;

    public bool alwaysUseShdow = true;
    bool CheckT(float t)
    {
        return ((Mathf.Abs(t - tPre) > 0.1f)
            || ((t == 0) && (tPre < 0.1f))
            || ((t == 1) && (tPre > 0.9f)));
    }
    void Update()
    {
        var useShadowOff = !alwaysUseShdow;

        var toggleManual = toggle;
        lockPanel.SetActive(toggleManual.isOn == false);



        var useShadowOffvalue = 0.1f;
        if (toggleManual.isOn)
        {
            if (slider.value > useShadowOffvalue)
            {
                var t = (slider.value - useShadowOffvalue) * (1f / (1f- useShadowOffvalue));
                if (CheckT(t))
                {
                    UpdateShadowDistance(t);
                    tPre = t;
                }
                if (useShadowOff)
                {
                    if (directionalLight.shadows == LightShadows.None)
                    {
                        directionalLight.shadows = shadowType;
                    }
                }
            }
            else
            {
                if (useShadowOff)
                {
                    if (directionalLight.shadows != LightShadows.None)
                    {
                        directionalLight.shadows = LightShadows.None;
                    }
                }
            }
        }
        else
        {


            frameCount++;

            if (Time.time - lastCheckTime >= frameCheckTimeCycle)
            {
                var fps = 0f;
                if (Time.deltaTime > 0)
                {
                    fps = 1f / Time.deltaTime;
                }
                if (frameCheckTimeCycle > 0.1f)
                {
                    fps = frameCount / frameCheckTimeCycle;
                }


                var min = targetFps.x;
                var max = targetFps.y;
                var t = (Mathf.Clamp(fps, min, max) - min) / (max - min);

                /*
                if ((Mathf.Abs(t - tPre) > 0.1f)
                    || ((t == 0) && (tPre < 0.1f))
                    || ((t == 1) && (tPre > 0.9f)))
                */
                if (CheckT(t))
                {

                    UpdateShadowDistance(t);
                    tPre = t;

                }


                if (Time.time > 10)
                {
                    if (useShadowOff)
                    {
                        if (directionalLight.shadows == LightShadows.None)
                        {
                            if (t > 0.8f)
                            {
                                directionalLight.shadows = shadowType;
                            }
                        }
                        else
                        {
                            if (fps < min / 2)
                            {
                                directionalLight.shadows = LightShadows.None;
                            }
                        }
                    }
                }
                if (directionalLight.shadows == LightShadows.None)
                {
                    slider.value = 0f;
                }
                else
                {
                    slider.value = useShadowOffvalue + t * (1f- useShadowOffvalue);
                }


                frameCount = 0;
                lastCheckTime = Time.time;
            }
        }
    }
}

'Unity > C#' 카테고리의 다른 글

c# Dictionary(딕셔너리) 관련  (0) 2024.03.19
자주 쓰는 DateTime 코드 모음  (0) 2023.12.19
Path 연산  (0) 2023.09.09
posted by 모카쨩

  • total
  • today
  • yesterday

Recent Post

저사양 유저용 블로그 진입