User avatar
stonstad
Topic Author
Posts: 247
Joined: 06 Jun 2016, 18:14
Location: Lesser Magellanic Cloud
Contact:

Offscreen Texture Alpha (User Error)

12 Mar 2019, 15:10

**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:
Image


And here is a rectangle with a background set to the same render target texture. You can see that alpha partially works.
Image


Here is the code I'm using which shows construction of the Noesis texture.
        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
            };
        }
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!
Last edited by stonstad on 21 May 2019, 22:21, edited 2 times in total.
 
User avatar
jsantos
Site Admin
Posts: 4096
Joined: 20 Jan 2012, 17:18
Contact:

Re: Offscreen Texture Alpha

12 Mar 2019, 19:08

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!
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:
    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);
        }
    }
 
User avatar
stonstad
Topic Author
Posts: 247
Joined: 06 Jun 2016, 18:14
Location: Lesser Magellanic Cloud
Contact:

Re: Offscreen Texture Alpha

12 Mar 2019, 20:06

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?
 
User avatar
stonstad
Topic Author
Posts: 247
Joined: 06 Jun 2016, 18:14
Location: Lesser Magellanic Cloud
Contact:

Re: Offscreen Texture Alpha

12 Mar 2019, 20:15

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
 
User avatar
jsantos
Site Admin
Posts: 4096
Joined: 20 Jan 2012, 17:18
Contact:

Re: Offscreen Texture Alpha

12 Mar 2019, 20:41

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.
 
User avatar
stonstad
Topic Author
Posts: 247
Joined: 06 Jun 2016, 18:14
Location: Lesser Magellanic Cloud
Contact:

Re: Offscreen Texture Alpha

03 Apr 2019, 17:28

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!
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
				}
			}
		}
}
Result:
Image
 
nokola
Posts: 188
Joined: 10 Mar 2015, 05:29

Re: Offscreen Texture Alpha

04 Apr 2019, 08:06

Offtopic: How do you generate the planets? Looks very cool!
 
User avatar
stonstad
Topic Author
Posts: 247
Joined: 06 Jun 2016, 18:14
Location: Lesser Magellanic Cloud
Contact:

Re: Offscreen Texture Alpha

04 Apr 2019, 12:46

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.
 
nokola
Posts: 188
Joined: 10 Mar 2015, 05:29

Re: Offscreen Texture Alpha

05 Apr 2019, 16:17

Thanks!
 
User avatar
jsantos
Site Admin
Posts: 4096
Joined: 20 Jan 2012, 17:18
Contact:

Re: Offscreen Texture Alpha

05 Apr 2019, 21:11

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!
Make sure alpha blending is disabled in that shader, or it will blend with the background corrupting the result.

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