diff options
| author | yum <yum.food.vr@gmail.com> | 2026-01-18 11:48:35 -0800 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2026-01-18 11:48:35 -0800 |
| commit | fbe7ed126883b0c4a1d5115e5c953bc244bc0214 (patch) | |
| tree | 7bf3926507eb33c3b4278de375f4cd68740e378f /Scripts | |
| parent | 29fcaf34e1e6932379714ec3f2adffbbd487810e (diff) | |
Impostors: baking script now auto-scales bounds
Diffstat (limited to 'Scripts')
| -rwxr-xr-x | Scripts/Impostors.cs | 64 |
1 files changed, 48 insertions, 16 deletions
diff --git a/Scripts/Impostors.cs b/Scripts/Impostors.cs index 1214b8f..e77be4e 100755 --- a/Scripts/Impostors.cs +++ b/Scripts/Impostors.cs @@ -7,7 +7,7 @@ using System.IO; public class Impostors : MonoBehaviour { [Header("Bounding Sphere")] - public float sphere_radius_ = 1f; + public float radiusScale = 1f; [Header("Grid Settings")] [Range(2, 20)] public int gridResolution = 5; @@ -27,9 +27,23 @@ public class Impostors : MonoBehaviour private Material impostorMaterial; public bool HasImpostor => impostorObject != null; - private float Radius => sphere_radius_ * Mathf.Max(transform.lossyScale.x, transform.lossyScale.y, transform.lossyScale.z); private string OutputFolder => GetOutputFolder(); + Bounds GetCombinedBounds() + { + Renderer[] allRenderers = originalMesh.GetComponentsInChildren<Renderer>(true); + Renderer[] renderers = System.Array.FindAll(allRenderers, r => r.gameObject != impostorObject); + Bounds bounds = renderers[0].bounds; + for (int i = 1; i < renderers.Length; i++) + bounds.Encapsulate(renderers[i].bounds); + return bounds; + } + + float GetBoundingSphereRadius() + { + return GetCombinedBounds().extents.magnitude * radiusScale; + } + void OnEnable() => Camera.onPreRender += UpdateMainCameraPos; void OnDisable() => Camera.onPreRender -= UpdateMainCameraPos; @@ -41,8 +55,14 @@ public class Impostors : MonoBehaviour void OnDrawGizmos() { + if (originalMesh == null) return; + + Bounds bounds = GetCombinedBounds(); + Vector3 center = bounds.center; + float radius = GetBoundingSphereRadius(); + Gizmos.color = Color.cyan; - Gizmos.DrawWireSphere(transform.position, Radius); + Gizmos.DrawWireSphere(center, radius); if (Application.isEditor && gridResolution > 0) { @@ -51,9 +71,9 @@ public class Impostors : MonoBehaviour { for (int x = 0; x < gridResolution; x++) { - Vector3 worldPos = transform.position + PlaneToHemiOctahedron(x, y) * (Radius + nearClippingDistance); - Gizmos.DrawSphere(worldPos, Radius * 0.05f); - Gizmos.DrawLine(worldPos, transform.position); + Vector3 worldPos = center + PlaneToHemiOctahedron(x, y) * (radius + nearClippingDistance); + Gizmos.DrawSphere(worldPos, radius * 0.05f); + Gizmos.DrawLine(worldPos, center); } } } @@ -110,23 +130,27 @@ public class Impostors : MonoBehaviour cameras = new Camera[gridResolution * gridResolution]; int idx = 0; + Bounds bounds = GetCombinedBounds(); + Vector3 center = bounds.center; + float radius = GetBoundingSphereRadius(); + for (int y = 0; y < gridResolution; y++) { for (int x = 0; x < gridResolution; x++) { Vector3 localDir = PlaneToHemiOctahedron(x, y); - Vector3 worldPos = transform.position + (transform.rotation * localDir) * (Radius + nearClippingDistance); + Vector3 worldPos = center + (transform.rotation * localDir) * (radius + nearClippingDistance); GameObject camObj = new GameObject($"Camera_{x}_{y}"); camObj.transform.SetParent(parent.transform, false); camObj.transform.position = worldPos; - camObj.transform.LookAt(transform.position, transform.up); + camObj.transform.LookAt(center, transform.up); Camera cam = camObj.AddComponent<Camera>(); cam.orthographic = true; - cam.orthographicSize = Radius; + cam.orthographicSize = radius; cam.nearClipPlane = nearClippingDistance; - cam.farClipPlane = Radius * 2f + nearClippingDistance; + cam.farClipPlane = radius * 2f + nearClippingDistance; cam.cullingMask = cullingMask; cam.clearFlags = renderSkybox ? CameraClearFlags.Skybox : CameraClearFlags.SolidColor; cam.backgroundColor = Color.clear; @@ -250,7 +274,7 @@ public class Impostors : MonoBehaviour public void BakeTexture() { SetRenderersEnabled(true); - if (cameras == null || cameras.Length != gridResolution * gridResolution || cameras[0] == null) CreateCameras(); + CreateCameras(); Shader depthBlitShader = Shader.Find("Hidden/yum_food/DepthBlit"); if (depthBlitShader == null) { Debug.LogError("DepthBlit shader not found"); return; } @@ -539,14 +563,17 @@ public class Impostors : MonoBehaviour Shader shader = Shader.Find("yum_food/3ner"); if (shader == null) { Debug.LogError("Shader not found"); return; } + Bounds bounds = GetCombinedBounds(); + float radius = GetBoundingSphereRadius(); + impostorMaterial = new Material(shader); impostorMaterial.enableInstancing = true; for (int i = 0; i < textures.Length; i++) impostorMaterial.SetTexture(exportSettings[i].materialProp, textures[i]); impostorMaterial.SetInt("_Impostors_Grid_Resolution", gridResolution); - impostorMaterial.SetFloat("_Impostors_Sphere_Radius", sphere_radius_); + impostorMaterial.SetFloat("_Impostors_Sphere_Radius", radius); impostorMaterial.SetFloat("_Impostors_Near_Clip", nearClippingDistance); - impostorMaterial.SetFloat("_Impostors_Far_Clip", sphere_radius_ * 2f + nearClippingDistance); + impostorMaterial.SetFloat("_Impostors_Far_Clip", radius * 2f + nearClippingDistance); impostorMaterial.SetFloat("_ZTest", (float)UnityEngine.Rendering.CompareFunction.LessEqual); impostorMaterial.SetFloat("_Impostors_Enabled", 1); impostorMaterial.SetFloat("_Impostors_Parallax", 1); @@ -555,8 +582,9 @@ public class Impostors : MonoBehaviour impostorObject = GameObject.CreatePrimitive(PrimitiveType.Quad); impostorObject.name = "Impostor"; - impostorObject.transform.SetParent(transform, false); - impostorObject.transform.localScale = Vector3.one * sphere_radius_ * 2.0f; + impostorObject.transform.position = bounds.center; + impostorObject.transform.localScale = Vector3.one * radius * 2.0f; + impostorObject.transform.SetParent(transform, true); DestroyImmediate(impostorObject.GetComponent<Collider>()); impostorObject.GetComponent<MeshRenderer>().sharedMaterial = impostorMaterial; @@ -584,7 +612,11 @@ public class Impostors : MonoBehaviour if (originalMesh == null) return; foreach (Renderer r in originalMesh.GetComponentsInChildren<Renderer>(true)) r.enabled = enabled; - if (impostorObject != null) impostorObject.SetActive(!enabled); + if (impostorObject != null) + { + Renderer impostorRenderer = impostorObject.GetComponent<Renderer>(); + if (impostorRenderer != null) impostorRenderer.enabled = !enabled; + } } } |
