Skip to content

Commit

Permalink
Merge pull request alelievr#38 from peeweek/fix/srgb-read-write-fixes
Browse files Browse the repository at this point in the history
External Output sRGB Write Fix / sRGB Preview Fixes
  • Loading branch information
alelievr authored Jan 15, 2022
2 parents 836c934 + 2eb0cf4 commit ecf03cd
Show file tree
Hide file tree
Showing 9 changed files with 119 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<ui:VisualElement name="MipMapLow" style="background-image: resource(&apos;Icons/TextureMipMapLow&apos;); width: 16px; height: 16px; margin-top: 1px;" />
<ui:Label text="0" name="MipMapNumberText" style="-unity-text-align: middle-center; width: 20px;" />
</ui:VisualElement>
<uie:ToolbarToggle label="sRGB" value="true" name="ToggleSRGB" style="width: 44px; font-size: 14px;" />
</uie:Toolbar>
<ui:VisualElement name="SliceInputs" style="flex-direction: row;">
<ui:VisualElement name="LayersIcon" style="width: 18px; height: 16px; background-image: resource(&apos;Icons/LayersIcon&apos;); -unity-background-image-tint-color: rgb(127, 127, 127);" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,16 @@ protected override void BuildOutputNodeSettings()
externalOutputNode.external2DOoutputType = (ExternalOutputNode.External2DOutputType)outputType;
MarkDirtyRepaint();
}

EditorGUI.BeginChangeCheck();
var outputFileType = EditorGUILayout.EnumPopup("File Type", externalOutputNode.externalFileType);
if (EditorGUI.EndChangeCheck())
{
externalOutputNode.externalFileType = (ExternalOutputNode.ExternalFileType)outputFileType;
UpdateButtons();
MarkDirtyRepaint();
}

}
else if (externalOutputNode.externalOutputDimension == ExternalOutputNode.ExternalOutputDimension.Texture3D)
{
Expand All @@ -94,6 +104,21 @@ protected override void BuildOutputNodeSettings()
MarkDirtyRepaint();
}
}

EditorGUI.BeginChangeCheck();
var exportAlpha = EditorGUILayout.Toggle("Export Alpha", externalOutputNode.exportAlpha);
if (EditorGUI.EndChangeCheck())
{
externalOutputNode.exportAlpha = exportAlpha;
MarkDirtyRepaint();
}

externalOutputNode.previewSRGB =
externalOutputNode.externalFileType == ExternalOutputNode.ExternalFileType.PNG &&
externalOutputNode.externalOutputDimension == ExternalOutputNode.ExternalOutputDimension.Texture2D &&
(externalOutputNode.external2DOoutputType == ExternalOutputNode.External2DOutputType.Color ||
externalOutputNode.external2DOoutputType == ExternalOutputNode.External2DOutputType.LatLongCubemapColor);

GUILayout.Space(8);
}
);
Expand Down Expand Up @@ -149,7 +174,14 @@ void UpdateButtons()
// Manage First save or Update
button.save.style.display = DisplayStyle.Flex;
button.update.style.display = DisplayStyle.Flex;
button.update.SetEnabled(externalOutputNode.asset != null);

bool valid = externalOutputNode.asset != null && (
(AssetDatabase.GetAssetPath(externalOutputNode.asset).ToLower().EndsWith("exr") && externalOutputNode.externalFileType == ExternalOutputNode.ExternalFileType.EXR)
|| (AssetDatabase.GetAssetPath(externalOutputNode.asset).ToLower().EndsWith("png") && externalOutputNode.externalFileType == ExternalOutputNode.ExternalFileType.PNG)
|| (AssetDatabase.GetAssetPath(externalOutputNode.asset).ToLower().EndsWith("asset") && externalOutputNode.externalOutputDimension != ExternalOutputNode.ExternalOutputDimension.Texture2D)) ;

button.update.SetEnabled(valid);

}
}
}
Expand Down
20 changes: 17 additions & 3 deletions Packages/com.alelievr.mixture/Editor/Views/MixtureNodeView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,20 @@ protected virtual void DrawPreviewToolbar(Texture texture)
}

GUILayout.FlexibleSpace();

if(nodeTarget.canEditPreviewSRGB)
{
EditorGUI.BeginChangeCheck();

bool srgb = GUILayout.Toggle(nodeTarget.previewSRGB, "sRGB", EditorStyles.toolbarButton);

if (EditorGUI.EndChangeCheck())
{
owner.RegisterCompleteObjectUndo("Updated Preview Masks");
nodeTarget.previewSRGB = srgb;
}
}

}

void DrawTextureInfoHover(Rect previewRect, Texture texture)
Expand Down Expand Up @@ -592,7 +606,7 @@ protected virtual void DrawImGUIPreview(MixtureNode node, Rect previewRect, floa
MixtureUtils.texture2DPreviewMaterial.SetVector("_Channels", MixtureEditorUtils.GetChannelsMask(nodeTarget.previewMode));
MixtureUtils.texture2DPreviewMaterial.SetFloat("_PreviewMip", nodeTarget.previewMip);
MixtureUtils.texture2DPreviewMaterial.SetFloat("_EV100", nodeTarget.previewEV100);
MixtureUtils.texture2DPreviewMaterial.SetFloat("_IsSRGB", 0);
MixtureUtils.texture2DPreviewMaterial.SetFloat("_IsSRGB", nodeTarget.previewSRGB? 1 : 0);

if (Event.current.type == EventType.Repaint)
EditorGUI.DrawPreviewTexture(previewRect, node.previewTexture, MixtureUtils.texture2DPreviewMaterial, ScaleMode.ScaleToFit, 0, 0);
Expand All @@ -603,7 +617,7 @@ protected virtual void DrawImGUIPreview(MixtureNode node, Rect previewRect, floa
MixtureUtils.texture3DPreviewMaterial.SetFloat("_PreviewMip", nodeTarget.previewMip);
MixtureUtils.texture3DPreviewMaterial.SetFloat("_Depth", currentSlice / nodeTarget.settings.GetResolvedDepth(owner.graph));
MixtureUtils.texture3DPreviewMaterial.SetFloat("_EV100", nodeTarget.previewEV100);
MixtureUtils.texture3DPreviewMaterial.SetFloat("_IsSRGB", 0);
MixtureUtils.texture3DPreviewMaterial.SetFloat("_IsSRGB", nodeTarget.previewSRGB ? 1 : 0);

if (Event.current.type == EventType.Repaint)
EditorGUI.DrawPreviewTexture(previewRect, Texture2D.whiteTexture, MixtureUtils.texture3DPreviewMaterial, ScaleMode.ScaleToFit, 0, 0, ColorWriteMask.Red);
Expand All @@ -613,7 +627,7 @@ protected virtual void DrawImGUIPreview(MixtureNode node, Rect previewRect, floa
MixtureUtils.textureCubePreviewMaterial.SetVector("_Channels", MixtureEditorUtils.GetChannelsMask(nodeTarget.previewMode));
MixtureUtils.textureCubePreviewMaterial.SetFloat("_PreviewMip", nodeTarget.previewMip);
MixtureUtils.textureCubePreviewMaterial.SetFloat("_EV100", nodeTarget.previewEV100);
MixtureUtils.textureCubePreviewMaterial.SetFloat("_IsSRGB", 0);
MixtureUtils.textureCubePreviewMaterial.SetFloat("_IsSRGB", nodeTarget.previewSRGB ? 1 : 0);

if (Event.current.type == EventType.Repaint)
EditorGUI.DrawPreviewTexture(previewRect, Texture2D.whiteTexture, MixtureUtils.textureCubePreviewMaterial, ScaleMode.ScaleToFit, 0, 0);
Expand Down
11 changes: 7 additions & 4 deletions Packages/com.alelievr.mixture/Editor/Views/NodeTexturePreview.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public class NodeTexturePreview : VisualElement

// Texture Preview elements
VisualElement previewContainer;
Toggle rgb, r, g, b, a;
Toggle rgb, r, g, b, a, srgb;
VisualElement mipmapInputs;
SliderInt mipmapSlider;
Label currentMipIndex;
Expand Down Expand Up @@ -52,7 +52,7 @@ public NodeTexturePreview(MixtureNodeView view)
g = previewRoot.Q("ToggleG") as Toggle;
b = previewRoot.Q("ToggleB") as Toggle;
a = previewRoot.Q("ToggleA") as Toggle;

srgb = previewRoot.Q("ToggleSRGB") as Toggle;
mipmapSlider = previewRoot.Q("MipMapSlider") as SliderInt;
mipmapInputs = previewRoot.Q("MipMapInput") as VisualElement;
currentMipIndex = previewRoot.Q("MipMapNumberText") as Label;
Expand Down Expand Up @@ -104,6 +104,7 @@ void DrawPreviewImage()
MixtureUtils.texture2DPreviewMaterial.SetVector("_Channels", MixtureEditorUtils.GetChannelsMask(node.previewMode));
MixtureUtils.texture2DPreviewMaterial.SetFloat("_PreviewMip", node.previewMip);
MixtureUtils.texture2DPreviewMaterial.SetFloat("_EV100", node.previewEV100);
MixtureUtils.texture2DPreviewMaterial.SetInt("_IsSRGB", node.previewSRGB ? 1 : 0);

if (Event.current.type == EventType.Repaint)
EditorGUI.DrawPreviewTexture(previewRect, node.previewTexture, MixtureUtils.texture2DPreviewMaterial, ScaleMode.ScaleToFit, 0, 0);
Expand All @@ -114,17 +115,19 @@ void DrawPreviewImage()
MixtureUtils.texture3DPreviewMaterial.SetFloat("_PreviewMip", node.previewMip);
MixtureUtils.texture3DPreviewMaterial.SetFloat("_Depth", (node.previewSlice + 0.5f) / node.settings.GetResolvedDepth(graphView.graph));
MixtureUtils.texture3DPreviewMaterial.SetFloat("_EV100", node.previewEV100);
MixtureUtils.texture3DPreviewMaterial.SetInt("_IsSRGB", node.previewSRGB ? 1 : 0);

if (Event.current.type == EventType.Repaint)
if (Event.current.type == EventType.Repaint)
EditorGUI.DrawPreviewTexture(previewRect, Texture2D.whiteTexture, MixtureUtils.texture3DPreviewMaterial, ScaleMode.ScaleToFit, 0, 0, ColorWriteMask.Red);
break;
case TextureDimension.Cube:
MixtureUtils.textureCubePreviewMaterial.SetTexture("_Cubemap", node.previewTexture);
MixtureUtils.textureCubePreviewMaterial.SetVector("_Channels", MixtureEditorUtils.GetChannelsMask(node.previewMode));
MixtureUtils.textureCubePreviewMaterial.SetFloat("_PreviewMip", node.previewMip);
MixtureUtils.textureCubePreviewMaterial.SetFloat("_EV100", node.previewEV100);
MixtureUtils.textureCubePreviewMaterial.SetInt("_IsSRGB", node.previewSRGB ? 1 : 0);

if (Event.current.type == EventType.Repaint)
if (Event.current.type == EventType.Repaint)
EditorGUI.DrawPreviewTexture(previewRect, Texture2D.whiteTexture, MixtureUtils.textureCubePreviewMaterial, ScaleMode.ScaleToFit, 0, 0);
break;
default:
Expand Down
33 changes: 13 additions & 20 deletions Packages/com.alelievr.mixture/Runtime/Graph/MixtureGraph.cs
Original file line number Diff line number Diff line change
Expand Up @@ -555,8 +555,7 @@ public void SaveExternalTexture(ExternalOutputNode external, bool saveAs = false
try
{
Texture outputTexture = null;
bool isHDR = external.settings.IsHDR(this);


TextureDimension dimension = external.settings.GetResolvedTextureDimension(this);
GraphicsFormat format = (GraphicsFormat)external.settings.GetGraphicsFormat(this);
var rtSettings = external.settings;
Expand Down Expand Up @@ -587,9 +586,9 @@ public void SaveExternalTexture(ExternalOutputNode external, bool saveAs = false

if (dimension == TextureDimension.Tex2D)
{
if (isHDR)
if (external.externalFileType == ExternalOutputNode.ExternalFileType.EXR)
extension = "exr";
else
else if (external.externalFileType == ExternalOutputNode.ExternalFileType.PNG)
extension = "png";
}

Expand Down Expand Up @@ -629,24 +628,10 @@ public void SaveExternalTexture(ExternalOutputNode external, bool saveAs = false
{
byte[] contents = null;

if (isHDR)
if (external.externalFileType == ExternalOutputNode.ExternalFileType.EXR)
contents = ImageConversion.EncodeToEXR(outputTexture as Texture2D);
else
{
var colors = (outputTexture as Texture2D).GetPixels();

// We only do the conversion for whe the graph uses SRGB images
if (external.external2DOoutputType == ExternalOutputNode.External2DOutputType.Color
|| external.external2DOoutputType == ExternalOutputNode.External2DOutputType.LatLongCubemapColor)
{
for (int i = 0; i < colors.Length; i++)
colors[i] = colors[i].gamma;
}

(outputTexture as Texture2D).SetPixels(colors);

else if (external.externalFileType == ExternalOutputNode.ExternalFileType.PNG)
contents = ImageConversion.EncodeToPNG(outputTexture as Texture2D);
}

System.IO.File.WriteAllBytes(System.IO.Path.GetDirectoryName(Application.dataPath) + "/" + assetPath, contents);

Expand All @@ -657,25 +642,33 @@ public void SaveExternalTexture(ExternalOutputNode external, bool saveAs = false
switch (external.external2DOoutputType)
{
case ExternalOutputNode.External2DOutputType.Color:
importer.textureShape = TextureImporterShape.Texture2D;
importer.textureType = TextureImporterType.Default;
importer.sRGBTexture = true;
importer.alphaSource = external.exportAlpha? TextureImporterAlphaSource.FromInput : TextureImporterAlphaSource.None;
break;
case ExternalOutputNode.External2DOutputType.Linear:
importer.textureShape = TextureImporterShape.Texture2D;
importer.textureType = TextureImporterType.Default;
importer.sRGBTexture = false;
importer.alphaSource = external.exportAlpha ? TextureImporterAlphaSource.FromInput : TextureImporterAlphaSource.None;
break;
case ExternalOutputNode.External2DOutputType.Normal:
importer.textureShape = TextureImporterShape.Texture2D;
importer.textureType = TextureImporterType.NormalMap;
importer.alphaSource = TextureImporterAlphaSource.None;
break;
case ExternalOutputNode.External2DOutputType.LatLongCubemapColor:
importer.textureShape = TextureImporterShape.TextureCube;
importer.generateCubemap = TextureImporterGenerateCubemap.Cylindrical;
importer.sRGBTexture = true;
importer.alphaSource = external.exportAlpha ? TextureImporterAlphaSource.FromInput : TextureImporterAlphaSource.None;
break;
case ExternalOutputNode.External2DOutputType.LatLongCubemapLinear:
importer.textureShape = TextureImporterShape.TextureCube;
importer.generateCubemap = TextureImporterGenerateCubemap.Cylindrical;
importer.sRGBTexture = false;
importer.alphaSource = external.exportAlpha ? TextureImporterAlphaSource.FromInput : TextureImporterAlphaSource.None;
break;
}
importer.SaveAndReimport();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ public enum PowerOf2Mode
[Output(name = "Texture")]
public Texture outputTexture;

public override bool hasSettings => false;
public override bool canEditPreviewSRGB => !IsInputImportedTexture();

public override bool hasSettings => false;
public override string name => "Texture";
public override Texture previewTexture => outputTexture;
public override bool showDefaultInspector => true;
Expand Down Expand Up @@ -82,7 +84,9 @@ protected override bool ProcessNode(CommandBuffer cmd)
#if UNITY_EDITOR
var importer = UnityEditor.AssetImporter.GetAtPath(UnityEditor.AssetDatabase.GetAssetPath(textureAsset));
if (importer is UnityEditor.TextureImporter textureImporter)
{
normalMap = textureImporter.textureType == UnityEditor.TextureImporterType.NormalMap;
}
#endif

int targetWidth = textureAsset.width;
Expand Down Expand Up @@ -166,6 +170,16 @@ protected override bool ProcessNode(CommandBuffer cmd)
return true;
}

bool IsInputImportedTexture()
{
#if UNITY_EDITOR
var importer = UnityEditor.AssetImporter.GetAtPath(UnityEditor.AssetDatabase.GetAssetPath(textureAsset));
return importer != null && importer is UnityEditor.TextureImporter;
#else
return false;
#endif
}

public bool InitializeNodeFromObject(Texture value)
{
textureAsset = value;
Expand Down
14 changes: 14 additions & 0 deletions Packages/com.alelievr.mixture/Runtime/Nodes/ExternalOutputNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,29 @@ public enum External2DOutputType
LatLongCubemapColor,
LatLongCubemapLinear,
}
public enum ExternalFileType
{
PNG,
EXR
}


public override string name => "External Output";

public Texture asset;

public ExternalOutputDimension externalOutputDimension = ExternalOutputDimension.Texture2D;
public External2DOutputType external2DOoutputType = External2DOutputType.Color;
public ExternalFileType externalFileType = ExternalFileType.PNG;
public ConversionFormat external3DFormat = ConversionFormat.RGBA32;
public bool exportAlpha = true;

public override Texture previewTexture => outputTextureSettings.Count > 0 ? (Texture)mainOutput.finalCopyRT : Texture2D.blackTexture;

public override bool hasSettings => true;

public override bool canEditPreviewSRGB => false;

protected override MixtureSettings defaultSettings
{
get
Expand Down Expand Up @@ -81,7 +92,10 @@ protected override bool ProcessNode(CommandBuffer cmd)
if(graph.type != MixtureGraphType.Realtime)
{
if(settings.GetResolvedTextureDimension(graph) != TextureDimension.Cube)
{
outputTextureSettings.First().sRGB = false;
return base.ProcessNode(cmd);
}
else
{
if (uniqueMessages.Add("CubemapNotSupported"))
Expand Down
16 changes: 12 additions & 4 deletions Packages/com.alelievr.mixture/Runtime/Nodes/MixtureNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ public abstract class MixtureNode : BaseNode
OutputDimension.CubeMap,
};
public virtual PreviewChannels defaultPreviewChannels => PreviewChannels.RGBA;

public virtual bool canEditPreviewSRGB => true;
public virtual bool defaultPreviewSRGB => false;

public virtual bool showDefaultInspector => false;
public virtual bool showPreviewExposure => false;
[SerializeField, HideInInspector]
Expand All @@ -54,10 +58,13 @@ public abstract class MixtureNode : BaseNode

protected Dictionary<string, Material> temporaryMaterials = new Dictionary<string, Material>();

// UI Serialization
[SerializeField, HideInInspector]
public PreviewChannels previewMode;
[SerializeField, HideInInspector]
// UI Serialization
[SerializeField, HideInInspector]
public PreviewChannels previewMode;
[SerializeField, HideInInspector]
public bool previewSRGB;

[SerializeField, HideInInspector]
public float previewMip = 0.0f;
[SerializeField, HideInInspector]
public bool previewVisible = true;
Expand Down Expand Up @@ -138,6 +145,7 @@ public override void OnNodeCreated()
base.OnNodeCreated();
settings = defaultSettings;
previewMode = defaultPreviewChannels;
previewSRGB = defaultPreviewSRGB;

// Patch up inheritance mode with default value in graph
onEnabled += () => settings.SyncInheritanceMode(graph.defaultNodeInheritanceMode);
Expand Down
8 changes: 7 additions & 1 deletion Packages/com.alelievr.mixture/Runtime/Nodes/OutputNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ public class OutputNode : MixtureNode, IUseCustomRenderTextureProcessing
public override Texture previewTexture => graph?.type == MixtureGraphType.Realtime ? outputTextureSettings[selectedPreviewIndex].finalCopyRT : outputTextureSettings.Count > 0 ? outputTextureSettings[selectedPreviewIndex].finalCopyRT : null;
public override float nodeWidth => 350;

[SerializeField, HideInInspector]
public override bool canEditPreviewSRGB => false;
public override bool defaultPreviewSRGB => false;

[SerializeField, HideInInspector]
int _selectedPreviewIndex;
internal int selectedPreviewIndex
{
Expand Down Expand Up @@ -169,6 +172,9 @@ protected override bool ProcessNode(CommandBuffer cmd)

UpdateMessages();

// Never preview as sRGB, as output will be actually converted to sRGB (thus previewed as sRGB) if defined in settings.
previewSRGB = false;

foreach (var output in outputTextureSettings)
{
// Update the renderTexture reference for realtime graph
Expand Down

0 comments on commit ecf03cd

Please sign in to comment.