Offscreen Texture Alpha (User Error)
**update** This was caused by user error.
I have asked so many questions here about Noesis and I feel bad for asking another question. :|
Today I am working with setting a rectangle fill to an offscreen rendered texture (Unity). The texture contains alpha.
The behavior seems to be that alpha is only partially respected -- i.e. if it's 100% alpha ("transparent") it works in the Noesis control but partial alpha appears black.
Here is the render target texture:
And here is a rectangle with a background set to the same render target texture. You can see that alpha partially works.
Here is the code I'm using which shows construction of the Noesis texture.
Does anyone have any thoughts on what could possibly cause this behavior? I have not ruled out Unity -- just not sure if this has been seen before. Thank you!
I have asked so many questions here about Noesis and I feel bad for asking another question. :|
Today I am working with setting a rectangle fill to an offscreen rendered texture (Unity). The texture contains alpha.
The behavior seems to be that alpha is only partially respected -- i.e. if it's 100% alpha ("transparent") it works in the Noesis control but partial alpha appears black.
Here is the render target texture:
And here is a rectangle with a background set to the same render target texture. You can see that alpha partially works.
Here is the code I'm using which shows construction of the Noesis texture.
Code: Select all
private void InitializeComponent()
{
GUI.LoadComponent(this, "Assets/User Interface/Controls/Render Control/RenderControl.xaml");
FrameworkElement root = this.Content as FrameworkElement;
_RenderRectangle = root.FindName("_RenderRectangle") as Rectangle;
_OffscreenCameraGameObject = this.FindInactiveGameObject("Offscreen Camera");
_Camera = _OffscreenCameraGameObject.GetComponent<Camera>();
// create render texture
_RenderTexture = new RenderTexture((int)_Dimensions.x, (int)_Dimensions.y, 1, RenderTextureFormat.Default);
RenderTexture.active = _RenderTexture;
// create Noesis texture
_RenderTexture.Create();
NoesisTexture noesisTexture = NoesisTexture.WrapTexture(_RenderTexture, _RenderTexture.GetNativeTexturePtr(),
_RenderTexture.width, _RenderTexture.height, 1);
// create brush to store render texture and assign it to the rectangle
_RenderRectangle.Fill = new ImageBrush()
{
ImageSource = new TextureSource(noesisTexture),
Stretch = Stretch.None,
Opacity = 1.0f
};
}
Last edited by stonstad on 21 May 2019, 22:21, edited 2 times in total.
Re: Offscreen Texture Alpha
NoesisGUI expects textures in premultiplied alpha format. So, you need to multiply each channel by the alpha. We are doing this in our Unity AssetPostprocessor:Does anyone have any thoughts on what could possibly cause this behavior? I have not ruled out Unity -- just not sure if this has been seen before. Thank you!
Code: Select all
private void OnPostprocessTexture(Texture2D texture)
{
if (AssetDatabase.GetLabels(assetImporter).Contains("Noesis"))
{
Color[] c = texture.GetPixels(0);
// NoesisGUI needs premultipled alpha
for (int i = 0; i < c.Length; i++)
{
c[i].r = c[i].r * c[i].a;
c[i].g = c[i].g * c[i].a;
c[i].b = c[i].b * c[i].a;
}
// Set new content and make the texture unreadable at runtime
texture.SetPixels(c, 0);
texture.Apply(true, true);
}
}
Re: Offscreen Texture Alpha
The planet shown above rotates at about 30FPS. Would this approach still work, and if not, are there alternatives? i.e. would I need to write a custom shader?
Re: Offscreen Texture Alpha
I'm thinking I might need to apply a post-processing effect to the camera creating a render texture -- so that the texture is premultiplied alpha. ... maybe a screenspace shader similar to: https://answers.unity.com/questions/764 ... alpha.html
Re: Offscreen Texture Alpha
Yes, sorry for the confusion. My code was pretending to show you how we are generating the premultiplied alpha for offline textures. For render targets you need to do that when rendering, using shaders or whatever similar in Unity. If you don't do it that way, you kill the performance as you observed.
Re: Offscreen Texture Alpha
This is what I am using to premultiply alpha via shader in Unity. It should be working, I think -- because it premultiplies alpha but Unity/Noesis still shows the banded black outline where semi-transparent pixels exist. It works fine with full transparency. Close but not quite there!
Result:
Code: Select all
Shader "Noesis/Alpha Blended Premultiply" {
Properties{
_MainTex("RenderTexture", 2D) = "black" {}
}
Category{
//Tags { "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" }
//Blend SrcAlpha OneMinusSrcAlpha // traditional transparency blending
//Blend One OneMinusSrcAlpha // premultiplied alpha transpanrecy blending
//ColorMask RGB
Cull Off
Lighting Off
ZWrite Off
Fog { Mode Off }
SubShader {
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
struct appdata_t {
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
struct v2f {
float4 vertex : SV_POSITION;
float2 texcoord : TEXCOORD0;
};
float4 _MainTex_ST;
v2f vert(appdata_t v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex);
return o;
}
fixed4 frag(v2f i) : SV_Target
{
fixed4 c = tex2D(_MainTex, i.texcoord);
c.r *= c.a;
c.g *= c.a;
c.b *= c.a;
return c;
}
ENDCG
}
}
}
}
Re: Offscreen Texture Alpha
Offtopic: How do you generate the planets? Looks very cool!
Re: Offscreen Texture Alpha
Hey Nokola. It is a Unity Asset Store package -- Planets by Forge3D. They are heavily controlled by shaders which allows for a bit of customization.
Re: Offscreen Texture Alpha
Make sure alpha blending is disabled in that shader, or it will blend with the background corrupting the result.This is what I am using to premultiply alpha via shader in Unity. It should be working, I think -- because it premultiplies alpha but Unity/Noesis still shows the banded black outline where semi-transparent pixels exist. It works fine with full transparency. Close but not quite there!
One question about this, are you doing that pass per frame? Can't you do that operation at the same time you are rendering the planet?
Who is online
Users browsing this forum: ShenCiao and 3 guests