feat: add normal map preprocessing pipeline for correct channel layout conversion#87
Merged
feat: add normal map preprocessing pipeline for correct channel layout conversion#87
Conversation
…utDetector.Resolve
There was a problem hiding this comment.
Pull request overview
This PR adds a normal-map-aware preprocessing and resize pipeline so normal maps can be resized/compressed without channel-layout corruption (DXTnm AG vs RG vs RGB) and without gamma/sRGB side effects.
Changes:
- Add
NormalMapPreprocessorandNormalMapSourceLayoutDetectorto detect/convert normal map channel layouts before compression. - Update
TextureCompressorServiceto preprocess normal maps beforeEditorUtility.CompressTexture, including fallback handling and semantic-alpha decisions for BC7. - Update
TextureProcessorto supportisNormalMapresizing (linear read/write + higher-precision RT when available) and add extensive editor tests covering the pipeline end-to-end.
Reviewed changes
Copilot reviewed 21 out of 21 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| Editor/TextureCompressor/Core/Services/TextureProcessor.cs | Adds isNormalMap resize path using linear color space + float/half RT selection. |
| Editor/TextureCompressor/Core/Services/TextureCompressorService.cs | Integrates normal map preprocessing + source-layout detection into compression and fallback flow. |
| Editor/TextureCompressor/Core/Services/TextureFormatSelector.cs | Narrows responsibility to format prediction; exposes ResolvePlatform. |
| Editor/TextureCompressor/Core/Services/NormalMapPreprocessor.cs | New normal map channel packing/normalization logic for BC5/DXT5/BC7 + semantic alpha rules. |
| Editor/TextureCompressor/Core/Services/NormalMapSourceLayoutDetector.cs | New heuristic detector for AG vs RG vs RGB layouts in ambiguous formats (DXT5/BC7). |
| Tests/Editor/TestUtilities/NormalMapTestTextureFactory.cs (+ .meta) | Adds deterministic normal-map texture generators for test patterns and layouts. |
| Tests/Editor/Core/Services/TextureProcessorTests.cs | Expands resize tests to cover normal-map-specific behavior. |
| Tests/Editor/Core/Services/TextureFormatSelectorTests.cs | Removes compression-invocation tests now handled at service level; adds platform resolution tests. |
| Tests/Editor/Core/Services/TextureCompressorServiceTests.cs | Adds extensive integration tests for compression format selection, frozen overrides, layout detection, and alpha semantics. |
| Tests/Editor/Core/Services/NormalMapSourceLayoutDetectorTests.cs (+ .meta) | Adds unit tests for layout detection and resolve behavior. |
| Tests/Editor/Core/Services/NormalMapResizePipelineTests.cs (+ .meta) | Adds resize pipeline regression tests focused on normal map integrity. |
| Tests/Editor/Core/Services/NormalMapPreprocessorTests.cs (+ .meta) | Adds unit tests for preprocessing conversions and normalization behavior. |
| Tests/Editor/Core/Services/NormalMapPreprocessorPipelineTests.cs (+ .meta) | Adds end-to-end tests for resize + preprocess + real compression round-trips. |
| Tests/Editor/TestUtilities.meta | Adds Unity folder meta for new test utilities location. |
Comments suppressed due to low confidence (1)
Editor/TextureCompressor/Core/Services/TextureProcessor.cs:177
ResizeTochangesRenderTexture.activeand allocates a temporaryRenderTexturebut doesn’t use atry/finally. IfGraphics.Blit,ReadPixels, orApplythrows,RenderTexture.activemay remain modified and the temporary RT may leak. Wrap the body intry/finallyto always restoreRenderTexture.activeandReleaseTemporary(rt)(and consider cleaning up the partially-createdresult).
RenderTexture previous = RenderTexture.active;
RenderTexture.active = rt;
Graphics.Blit(source, rt);
// Preserve mipmap setting from source texture
// For normal maps, use linear color space to prevent gamma correction
Texture2D result = new Texture2D(
newWidth,
newHeight,
TextureFormat.RGBA32,
source.mipmapCount > 1,
isNormalMap
);
result.ReadPixels(new Rect(0, 0, newWidth, newHeight), 0, 0);
result.Apply(source.mipmapCount > 1);
// Copy texture settings from source
result.wrapModeU = source.wrapModeU;
result.wrapModeV = source.wrapModeV;
result.wrapModeW = source.wrapModeW;
result.filterMode = source.filterMode;
result.anisoLevel = source.anisoLevel;
RenderTexture.active = previous;
RenderTexture.ReleaseTemporary(rt);
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 21 out of 21 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
closes #40