diff options
| author | yum <yum.food.vr@gmail.com> | 2026-01-15 16:52:25 -0800 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2026-01-15 17:28:02 -0800 |
| commit | 568f813fe37cd7beb1709fb1a92268fef2581d4e (patch) | |
| tree | 461042b70cac0a2b5b444a8bf57a9202b99dbe61 /Scripts | |
| parent | 2e99a2275ce3d0d9eef7892cf7485a5f278cacb4 (diff) | |
Impostors: add parallax correction
Diffstat (limited to 'Scripts')
| -rw-r--r-- | Scripts/Impostors.cs | 65 |
1 files changed, 61 insertions, 4 deletions
diff --git a/Scripts/Impostors.cs b/Scripts/Impostors.cs index ffd32b4..46e6cd1 100644 --- a/Scripts/Impostors.cs +++ b/Scripts/Impostors.cs @@ -26,7 +26,7 @@ public class Impostors : MonoBehaviour private Material impostorMaterial; public bool HasImpostor => impostorObject != null; - private float Radius => sphere_radius_ * transform.lossyScale.x; + private float Radius => sphere_radius_ * Mathf.Max(transform.lossyScale.x, transform.lossyScale.y, transform.lossyScale.z); private const string OutputFolder = "Assets/yum_food/3ner/Impostor_Generated"; void OnEnable() => Camera.onPreRender += UpdateMainCameraPos; @@ -35,7 +35,7 @@ public class Impostors : MonoBehaviour static void UpdateMainCameraPos(Camera cam) { if (cam.cameraType == CameraType.Game || cam.cameraType == CameraType.SceneView) - Shader.SetGlobalVector("_ImpostorMainCameraPos", cam.transform.position); + Shader.SetGlobalVector("_Impostors_Main_Camera_Pos", cam.transform.position); } void OnDrawGizmos() @@ -105,9 +105,9 @@ public class Impostors : MonoBehaviour Camera cam = camObj.AddComponent<Camera>(); cam.orthographic = true; - cam.orthographicSize = sphere_radius_; + cam.orthographicSize = Radius; cam.nearClipPlane = nearClippingDistance; - cam.farClipPlane = sphere_radius_ * 2f + nearClippingDistance; + cam.farClipPlane = Radius * 2f + nearClippingDistance; cam.cullingMask = cullingMask; cam.clearFlags = renderSkybox ? CameraClearFlags.Skybox : CameraClearFlags.SolidColor; cam.backgroundColor = Color.clear; @@ -337,6 +337,61 @@ public class Impostors : MonoBehaviour tex.Apply(); } + void DilateDepthTexture(Texture2D depthTex, Texture2D alphaSource, int iterations = 8) + { + int w = depthTex.width, h = depthTex.height; + Color[] depth = depthTex.GetPixels(); + Color[] mask = alphaSource.GetPixels(); + + bool[] filled = new bool[depth.Length]; + for (int i = 0; i < depth.Length; i++) + filled[i] = mask[i].a > 0.01f; + + Color[] buffer = (Color[])depth.Clone(); + bool[] filledNext = new bool[filled.Length]; + + int[] dx = { -1, 1, 0, 0 }; + int[] dy = { 0, 0, -1, 1 }; + + for (int iter = 0; iter < iterations; iter++) + { + System.Array.Copy(filled, filledNext, filled.Length); + + for (int y = 0; y < h; y++) + { + for (int x = 0; x < w; x++) + { + int i = y * w + x; + if (filled[i]) continue; + + float sum = 0f; + int count = 0; + for (int d = 0; d < 4; d++) + { + int nx = x + dx[d], ny = y + dy[d]; + if (nx < 0 || nx >= w || ny < 0 || ny >= h) continue; + int ni = ny * w + nx; + if (!filled[ni]) continue; + sum += depth[ni].r; + count++; + } + + if (count > 0) + { + buffer[i].r = sum / count; + filledNext[i] = true; + } + } + } + + var tmpFilled = filled; filled = filledNext; filledNext = tmpFilled; + var tmpDepth = depth; depth = buffer; buffer = tmpDepth; + } + + depthTex.SetPixels(depth); + depthTex.Apply(); + } + void SaveAndConfigureTexture(Texture2D atlas, TextureExportSettings settings, string baseName, out string path) { path = Path.Combine(OutputFolder, $"{baseName}_{settings.suffix}.{(settings.isEXR ? "exr" : "png")}"); @@ -386,6 +441,7 @@ public class Impostors : MonoBehaviour DilateTexture(albedoAtlas, albedoAtlas, preserveAlpha: true); DilateTexture(normalAtlas, albedoAtlas); DilateTexture(metallicGlossAtlas, albedoAtlas); + DilateDepthTexture(depthAtlas, albedoAtlas); Texture2D[] atlases = { albedoAtlas, normalAtlas, metallicGlossAtlas, depthAtlas }; string[] paths = new string[exportSettings.Length]; @@ -426,6 +482,7 @@ public class Impostors : MonoBehaviour impostorMaterial.SetInt("_Impostors_Grid_Resolution", gridResolution); impostorMaterial.SetFloat("_Impostors_Sphere_Radius", sphere_radius_); impostorMaterial.SetFloat("_Impostors_Enabled", 1); + impostorMaterial.SetFloat("_Impostors_Parallax", 1); impostorMaterial.SetFloat("_Cull", (float)UnityEngine.Rendering.CullMode.Front); AssetDatabase.CreateAsset(impostorMaterial, Path.Combine(OutputFolder, $"{baseName}_mat.mat")); |
