summaryrefslogtreecommitdiffstats
path: root/Scripts/Impostors.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Scripts/Impostors.cs')
-rwxr-xr-xScripts/Impostors.cs64
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;
+ }
}
}