noradninja

Shader_LOD_Enumerator

Dec 30th, 2022 (edited)
131
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.99 KB | None | 0 0
  1. using UnityEngine;
  2. using UnityEngine.Rendering;
  3.  
  4. /* Please note- the Shader LOD only works with my custom Vita Standard shader. You can change the shader keywords
  5.  that are enabled/disabled to make it work with other shaders */
  6. public class Shader_LOD_Enumerator : MonoBehaviour
  7. {
  8.  
  9.     [SerializeField] GameObject player;
  10.     [SerializeField] int updateIntervalRate = 7;
  11.     [SerializeField] float[] LOD_distance = new float[3]; //set up 3 floats- LOD1, LOD2, cull
  12.     [SerializeField] bool enableShaderLOD = false;
  13.     [SerializeField] bool enableMeshLOD = false;
  14.     [SerializeField] MeshRenderer LOD0;
  15.     [SerializeField] MeshRenderer LOD1;
  16.     [SerializeField] MeshRenderer LOD2;
  17.     private GameObject TLD;
  18.    
  19.     private float distance;
  20.     private Vector3 thisPos;
  21.     private Vector3 playerPos;
  22.     private Renderer thisRenderer;
  23.     private Camera mainCam;
  24.     private bool LOD2Enabled = false;
  25.     private bool LOD1Enabled = false;
  26.     private bool LOD0Enabled = false;
  27.    
  28.     public static int tick = 0;
  29.  
  30.     private void Start()
  31.     {
  32.         thisRenderer = this.GetComponent<Renderer>();
  33.         mainCam = Camera.main;
  34.         if(!LOD0) Reset(); //check if populated, if not, populate
  35.     }
  36.     //TODO: write TickUpdate so its a subscriber fired event so we don't need this logic running on every object, cause that's fucking smart
  37.     private void Update()
  38.     {
  39.         // we only need to do *whatever* FPS/updateIntervalRate times a frame
  40.         if (tick != updateIntervalRate)
  41.             tick++;
  42.         else
  43.         {
  44.             TickUpdate();
  45.             tick = 0;
  46.         }
  47.     }
  48.     private void Reset() //automagically add PolyFew LOD's if LOD list is unpopulated
  49.     {
  50.         TLD = GetChildByName.getChildGameObject(gameObject, "(POLY FEW)_LODS-DON'T-DELETE-MANUALLY");
  51.         if (!mainCam)
  52.             mainCam = Camera.main;
  53.  
  54.         if (!LOD0)
  55.             LOD0 = this.GetComponent<MeshRenderer>();
  56.  
  57.         if (!LOD1)
  58.  
  59.             LOD1 = GetChildByName.getChildGameObject(TLD, "Level02").GetComponentInChildren<MeshRenderer>();
  60.  
  61.         if (!LOD2)
  62.             LOD2 = GetChildByName.getChildGameObject(TLD, "Level03").GetComponentInChildren<MeshRenderer>();
  63.  
  64.         SetLOD();
  65.  
  66.     }
  67.     //enable/disable mesh LOD's
  68.     private void SetLOD()
  69.     {
  70.         if (distance <= LOD_distance[0]) //first LOD
  71.         {
  72.             DisableAll();
  73.             EnableLOD0();
  74.         }
  75.         if (distance > LOD_distance[0] && distance <= LOD_distance[1]) //second LOD
  76.         {
  77.             DisableAll();
  78.             EnableLOD1();
  79.         }
  80.         if (distance > LOD_distance[1] && distance <= LOD_distance[2]) //third LOD
  81.         {
  82.             DisableAll();
  83.             EnableLOD2();
  84.         }
  85.         if (distance > LOD_distance[2]) //disable beyond 2x world chunk distance
  86.         {
  87.             DisableAll();
  88.         }
  89.     }
  90.  
  91.     private void SetShaderLOD()
  92.     {
  93.         if (distance == LOD_distance[0]) //first LOD
  94.         {
  95.             ShaderLOD1();
  96.         }
  97.         if (distance == LOD_distance[1]) //second LOD
  98.         {
  99.             ShaderLOD2();
  100.         }
  101.  
  102.         if (distance < LOD_distance[1] && distance > LOD_distance[0]) //transition back to second LOD
  103.         {
  104.             ShaderLODTransition();
  105.         }
  106.  
  107.         if (distance < LOD_distance[0]) //no LOD
  108.         {
  109.             ShadernoLOD();
  110.         }
  111.     }
  112.     //update mesh and shader LOD's based on tick value so we arent doing this every frame
  113.     private void TickUpdate()
  114.     {
  115.         thisPos = new Vector3(this.transform.position.x, 0f, this.transform.position.z);
  116.         playerPos = new Vector3(player.transform.position.x, 0f, player.transform.position.z);
  117.         distance = Vector3.Distance(playerPos, thisPos);//how far are we from the player
  118.  
  119.         if (enableShaderLOD) //check if we enabled this; if not skip to culling
  120.         {
  121.             SetShaderLOD();
  122.         }
  123.  
  124.         if (enableMeshLOD)
  125.         {
  126.             SetLOD();
  127.         }
  128.     }
  129.    
  130.     //methods for mesh LOD's
  131.     private void EnableLOD2()
  132.     {
  133.         LOD2.enabled = true;
  134.     }
  135.  
  136.     private void EnableLOD1()
  137.     {
  138.         LOD1.enabled = true;
  139.     }
  140.  
  141.     private void EnableLOD0()
  142.     {
  143.         LOD0.enabled = true;
  144.     }
  145.  
  146.     void DisableAll()
  147.     {
  148.         LOD0.enabled = false;
  149.         LOD1.enabled = false;
  150.         LOD2.enabled = false;
  151.     }
  152.    
  153.     //methods for shader LOD's
  154.  
  155.     private void ShadernoLOD()
  156.     {
  157.         thisRenderer.sharedMaterial.EnableKeyword("_NORMALMAP"); //enable normal map
  158.         thisRenderer.shadowCastingMode = ShadowCastingMode.On; //enable shadows
  159.     }
  160.  
  161.     private void ShaderLOD1()
  162.     {
  163.         thisRenderer.sharedMaterial.DisableKeyword("_NORMALMAP"); //drop normalmap
  164.         thisRenderer.shadowCastingMode = ShadowCastingMode.Off; //disable shadows
  165.         Resources.UnloadUnusedAssets(); //unload normal map
  166.     }
  167.  
  168.     private void ShaderLOD2()
  169.     {
  170.         //drop MOAR map
  171.         thisRenderer.sharedMaterial.DisableKeyword("_METALLICGLOSSMAP");
  172.         thisRenderer.sharedMaterial.DisableKeyword("_SPECGLOSSMAP");
  173.         Resources.UnloadUnusedAssets(); //unload MOAR map
  174.     }
  175.  
  176.     private void ShaderLODTransition()
  177.     {
  178.         //enable MOAR map keywords
  179.         thisRenderer.sharedMaterial.EnableKeyword("_METALLICGLOSSMAP");
  180.         thisRenderer.sharedMaterial.EnableKeyword("_SPECGLOSSMAP");
  181.     }
  182. }
  183. public class GetChildByName : MonoBehaviour
  184. {
  185.     public static GameObject getChildGameObject(GameObject gameObjectToCheck, string nameToLookFor)
  186.     {
  187.         Transform[] ts = gameObjectToCheck.transform.GetComponentsInChildren<Transform>();
  188.         foreach (Transform t in ts) if (t.gameObject.name == nameToLookFor) return t.gameObject;
  189.         return null;
  190.     }
  191. }
  192.  
  193.  
Add Comment
Please, Sign In to add comment