diff options
| -rw-r--r-- | 3ner.cginc | 5 | ||||
| -rw-r--r-- | Scripts/Impostors.cs | 55 | ||||
| -rw-r--r-- | impostor.cginc | 9 | ||||
| -rw-r--r-- | pbr.cginc | 2 |
4 files changed, 68 insertions, 3 deletions
@@ -273,6 +273,11 @@ float4 frag(v2f i, uint facing : SV_IsFrontFace) : SV_Target { i.normal *= facing ? 1 : -1; Pbr pbr = getPbr(i); + +#if defined(_IMPOSTORS) + i.normal = pbr.normal; +#endif + #if defined(_DEBUG_VIEW_UNLIT) return pbr.albedo; #elif defined(_DEBUG_VIEW_WORLD_SPACE_NORMALS) diff --git a/Scripts/Impostors.cs b/Scripts/Impostors.cs index 30b06f6..ffd32b4 100644 --- a/Scripts/Impostors.cs +++ b/Scripts/Impostors.cs @@ -287,6 +287,56 @@ public class Impostors : MonoBehaviour } } + void DilateTexture(Texture2D tex, Texture2D alphaSource, bool preserveAlpha = false, int iterations = 8) + { + int w = tex.width, h = tex.height; + Color[] pixels = tex.GetPixels(); + Color[] alpha = alphaSource.GetPixels(); + Color[] origAlpha = preserveAlpha ? (Color[])alpha.Clone() : null; + Color[] buffer = (Color[])pixels.Clone(); + + int[] dx = { -1, 1, 0, 0 }; + int[] dy = { 0, 0, -1, 1 }; + + for (int iter = 0; iter < iterations; iter++) + { + for (int y = 0; y < h; y++) + { + for (int x = 0; x < w; x++) + { + int i = y * w + x; + if (alpha[i].a > 0.01f) continue; + + Color sum = Color.clear; + 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 (alpha[ni].a > 0.01f || (iter > 0 && pixels[ni].a > 0)) + { + sum += pixels[ni]; + count++; + } + } + if (count > 0) + { + buffer[i] = sum / count; + buffer[i].a = 1; + } + } + } + var tmp = pixels; pixels = buffer; buffer = tmp; + } + + if (preserveAlpha) + for (int i = 0; i < pixels.Length; i++) pixels[i].a = origAlpha[i].a; + + tex.SetPixels(pixels); + tex.Apply(); + } + void SaveAndConfigureTexture(Texture2D atlas, TextureExportSettings settings, string baseName, out string path) { path = Path.Combine(OutputFolder, $"{baseName}_{settings.suffix}.{(settings.isEXR ? "exr" : "png")}"); @@ -332,6 +382,11 @@ public class Impostors : MonoBehaviour (new TextureExportSettings("depth", isEXR: true, mipmaps: false, sRGB: false, filter: FilterMode.Bilinear, uncompressed: true), "_Impostors_Depth_Atlas") }; + // Dilate RGB to prevent dark halos from texture filtering + DilateTexture(albedoAtlas, albedoAtlas, preserveAlpha: true); + DilateTexture(normalAtlas, albedoAtlas); + DilateTexture(metallicGlossAtlas, albedoAtlas); + Texture2D[] atlases = { albedoAtlas, normalAtlas, metallicGlossAtlas, depthAtlas }; string[] paths = new string[exportSettings.Length]; for (int i = 0; i < exportSettings.Length; i++) diff --git a/impostor.cginc b/impostor.cginc index f271612..1623681 100644 --- a/impostor.cginc +++ b/impostor.cginc @@ -105,8 +105,13 @@ ImpostorSample SampleImpostorCell(float2 cell, float3 frameDir, float3 pivotToCa ImpostorSample BlendImpostorSamples(ImpostorSample s00, ImpostorSample s01, ImpostorSample s10, ImpostorSample s11, float4 bw) { ImpostorSample result; result.albedo = s00.albedo * bw.x + s01.albedo * bw.y + s10.albedo * bw.z + s11.albedo * bw.w; - result.normal = s00.normal * bw.x + s01.normal * bw.y + s10.normal * bw.z + s11.normal * bw.w; - result.metallicGloss = s00.metallicGloss * bw.x + s01.metallicGloss * bw.y + s10.metallicGloss * bw.z + s11.metallicGloss * bw.w; + + // Weight normal/metallicGloss by alpha to avoid blending with transparent (zero) pixels + float4 alphaBw = float4(s00.albedo.a, s01.albedo.a, s10.albedo.a, s11.albedo.a) * bw; + alphaBw /= max(dot(alphaBw, 1), 0.001); + + result.normal = s00.normal * alphaBw.x + s01.normal * alphaBw.y + s10.normal * alphaBw.z + s11.normal * alphaBw.w; + result.metallicGloss = s00.metallicGloss * alphaBw.x + s01.metallicGloss * alphaBw.y + s10.metallicGloss * alphaBw.z + s11.metallicGloss * alphaBw.w; return result; } @@ -165,7 +165,7 @@ Pbr getPbr(v2f i) { pbr.albedo = imp.albedo * _Color; pbr.normal = imp.normal; pbr.smoothness = imp.smoothness; - pbr.metallic = imp.metallic * _Metallic; + pbr.metallic = imp.metallic; #else pbr.albedo = _MainTex.Sample(aniso16_trilinear_repeat_s, uv_parallax * _MainTex_ST.xy + _MainTex_ST.zw); pbr.albedo *= _Color; |
