diff options
Diffstat (limited to 'Scripts')
| -rw-r--r-- | Scripts/Impostors.cs | 109 |
1 files changed, 84 insertions, 25 deletions
diff --git a/Scripts/Impostors.cs b/Scripts/Impostors.cs index 6d8d67b..ded7e6d 100644 --- a/Scripts/Impostors.cs +++ b/Scripts/Impostors.cs @@ -130,29 +130,67 @@ public class Impostors : MonoBehaviour SetRenderersEnabled(true); if (cameras == null || cameras.Length != gridResolution * gridResolution || cameras[0] == null) CreateCameras(); + // Load depth blit shader + Shader depthBlitShader = Shader.Find("Hidden/yum_food/DepthBlit"); + if (depthBlitShader == null) { Debug.LogError("DepthBlit shader not found"); return; } + Material depthBlitMat = new Material(depthBlitShader); + // Render atlas int size = cameraResolution * gridResolution; - Texture2D atlas = new Texture2D(size, size, TextureFormat.RGBA32, false); - RenderTexture rt = RenderTexture.GetTemporary(cameraResolution, cameraResolution, 24); + Texture2D colorAtlas = new Texture2D(size, size, TextureFormat.RGBA32, false); + Texture2D depthAtlas = new Texture2D(size, size, TextureFormat.RFloat, false); + + // Create RT with depth buffer that can be sampled as texture + RenderTextureDescriptor desc = new RenderTextureDescriptor(cameraResolution, cameraResolution, RenderTextureFormat.ARGB32, 24); + desc.sRGB = true; + RenderTexture colorRT = RenderTexture.GetTemporary(desc); + + // Separate depth texture + RenderTextureDescriptor depthDesc = new RenderTextureDescriptor(cameraResolution, cameraResolution, RenderTextureFormat.Depth, 24); + RenderTexture depthOnlyRT = RenderTexture.GetTemporary(depthDesc); + + // Output for linearized depth + RenderTexture linearDepthRT = RenderTexture.GetTemporary(cameraResolution, cameraResolution, 0, RenderTextureFormat.RFloat); int idx = 0; for (int y = 0; y < gridResolution; y++) { for (int x = 0; x < gridResolution; x++) { - cameras[idx++].targetTexture = rt; - cameras[idx - 1].Render(); - RenderTexture.active = rt; - Texture2D temp = new Texture2D(cameraResolution, cameraResolution); - temp.ReadPixels(new Rect(0, 0, cameraResolution, cameraResolution), 0, 0); - temp.Apply(); - atlas.SetPixels(x * cameraResolution, y * cameraResolution, cameraResolution, cameraResolution, temp.GetPixels()); - DestroyImmediate(temp); + Camera cam = cameras[idx++]; + + // Render to color + depth buffers simultaneously + cam.SetTargetBuffers(colorRT.colorBuffer, depthOnlyRT.depthBuffer); + cam.Render(); + + // Read color + RenderTexture.active = colorRT; + Texture2D colorTemp = new Texture2D(cameraResolution, cameraResolution); + colorTemp.ReadPixels(new Rect(0, 0, cameraResolution, cameraResolution), 0, 0); + colorTemp.Apply(); + colorAtlas.SetPixels(x * cameraResolution, y * cameraResolution, cameraResolution, cameraResolution, colorTemp.GetPixels()); + DestroyImmediate(colorTemp); + + // Blit depth buffer through linearization shader + depthBlitMat.SetTexture("_DepthTex", depthOnlyRT); + Graphics.Blit(null, linearDepthRT, depthBlitMat); + + // Read linearized depth + RenderTexture.active = linearDepthRT; + Texture2D depthTemp = new Texture2D(cameraResolution, cameraResolution, TextureFormat.RFloat, false); + depthTemp.ReadPixels(new Rect(0, 0, cameraResolution, cameraResolution), 0, 0); + depthTemp.Apply(); + depthAtlas.SetPixels(x * cameraResolution, y * cameraResolution, cameraResolution, cameraResolution, depthTemp.GetPixels()); + DestroyImmediate(depthTemp); } } - atlas.Apply(); + colorAtlas.Apply(); + depthAtlas.Apply(); RenderTexture.active = null; - RenderTexture.ReleaseTemporary(rt); + RenderTexture.ReleaseTemporary(colorRT); + RenderTexture.ReleaseTemporary(depthOnlyRT); + RenderTexture.ReleaseTemporary(linearDepthRT); + DestroyImmediate(depthBlitMat); // Save if (!AssetDatabase.IsValidFolder(OutputFolder)) @@ -163,24 +201,43 @@ public class Impostors : MonoBehaviour } string name = gameObject.name.Replace(" ", "_"); - string path = Path.Combine(OutputFolder, $"{name}_atlas.png"); - File.WriteAllBytes(Path.Combine(Application.dataPath, "..", path), atlas.EncodeToPNG()); - DestroyImmediate(atlas); + string colorPath = Path.Combine(OutputFolder, $"{name}_atlas.png"); + string depthPath = Path.Combine(OutputFolder, $"{name}_depth.exr"); + + File.WriteAllBytes(Path.Combine(Application.dataPath, "..", colorPath), colorAtlas.EncodeToPNG()); + File.WriteAllBytes(Path.Combine(Application.dataPath, "..", depthPath), depthAtlas.EncodeToEXR(Texture2D.EXRFlags.OutputAsFloat)); + DestroyImmediate(colorAtlas); + DestroyImmediate(depthAtlas); AssetDatabase.Refresh(); - TextureImporter importer = AssetImporter.GetAtPath(path) as TextureImporter; - if (importer != null) + + // Configure color atlas importer + TextureImporter colorImporter = AssetImporter.GetAtPath(colorPath) as TextureImporter; + if (colorImporter != null) + { + colorImporter.mipmapEnabled = true; + colorImporter.alphaIsTransparency = true; + colorImporter.wrapMode = TextureWrapMode.Clamp; + colorImporter.filterMode = FilterMode.Trilinear; + colorImporter.SaveAndReimport(); + } + + // Configure depth atlas importer + TextureImporter depthImporter = AssetImporter.GetAtPath(depthPath) as TextureImporter; + if (depthImporter != null) { - importer.mipmapEnabled = true; - importer.alphaIsTransparency = true; - importer.wrapMode = TextureWrapMode.Clamp; - importer.filterMode = FilterMode.Trilinear; - importer.SaveAndReimport(); + depthImporter.mipmapEnabled = false; + depthImporter.sRGBTexture = false; // Linear data + depthImporter.wrapMode = TextureWrapMode.Clamp; + depthImporter.filterMode = FilterMode.Bilinear; + depthImporter.textureCompression = TextureImporterCompression.Uncompressed; + depthImporter.SaveAndReimport(); } // Create impostor - Texture2D tex = AssetDatabase.LoadAssetAtPath<Texture2D>(path); - if (tex != null) + Texture2D colorTex = AssetDatabase.LoadAssetAtPath<Texture2D>(colorPath); + Texture2D depthTex = AssetDatabase.LoadAssetAtPath<Texture2D>(depthPath); + if (colorTex != null) { DestroyExistingImpostor(); @@ -188,8 +245,10 @@ public class Impostors : MonoBehaviour if (shader == null) { Debug.LogError("Shader not found"); return; } impostorMaterial = new Material(shader); - impostorMaterial.SetTexture("_ImpostorAtlas", tex); + impostorMaterial.SetTexture("_ImpostorAtlas", colorTex); + impostorMaterial.SetTexture("_ImpostorDepthAtlas", depthTex); impostorMaterial.SetInt("_GridResolution", gridResolution); + impostorMaterial.SetFloat("_SphereRadius", sphere_radius_); AssetDatabase.CreateAsset(impostorMaterial, Path.Combine(OutputFolder, $"{name}_mat.mat")); impostorObject = GameObject.CreatePrimitive(PrimitiveType.Quad); |
