Search Unity

  1. Looking for a job or to hire someone for a project? Check out the re-opened job forums.
    Dismiss Notice
  2. Unity 2020 LTS & Unity 2021.1 have been released.
    Dismiss Notice
  3. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

Graphics.Blit with material resulting in corrupted output

Discussion in 'Editor & General Support' started by Tim-C, Feb 13, 2010.

  1. Tim-C

    Tim-C

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    2,161
    Hi,

    I've been trying to use the blit functionality to do some texture generation on the GPU (I have been using the CPU, but it is far to slow!).

    When attempting to blit with a material specified I get corruption ocuring. This happens with the built in shaders as well as shaders I have written myself.

    I have written an example script that shows the issue:
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class BrokenTest : MonoBehaviour {
    6.  
    7.     void Start ()
    8.     {
    9.         Texture2D smallTexture = new Texture2D( 32,
    10.                                                 32,
    11.                                                 TextureFormat.ARGB32,
    12.                                                 false );
    13.        
    14.         RenderTexture largeTexture = new RenderTexture( 256,
    15.                                                         256,
    16.                                                         0 );
    17.         largeTexture.isPowerOfTwo = true;
    18.         largeTexture.Create();
    19.        
    20.         FillTexureWithNoise( smallTexture );
    21.        
    22.         Graphics.Blit( smallTexture, largeTexture, new Material(Shader.Find("Diffuse") ) );
    23.        
    24.         Material materialTest = new Material (Shader.Find("Diffuse")); 
    25.         materialTest.SetTexture( "_MainTex", largeTexture );
    26.         renderer.material = materialTest;
    27.     }
    28.    
    29.     private void FillTexureWithNoise( Texture2D noiseTexture)
    30.     {
    31.         for( int x = 0; x < noiseTexture.width; x++ )
    32.         {
    33.             for( int y = 0; y < noiseTexture.height; y++ )
    34.             {
    35.                 float value = Random.value;
    36.                 noiseTexture.SetPixel(x, y, new Color( value, value, value, value ) );
    37.             }
    38.         }
    39.         noiseTexture.Apply();
    40.     }
    41. }
    42.  
    What I do is I generate a small texture and fill each pixel with a random noise. I then upscale the texture using the GPU to a larger RenderTexture.

    The specific line with issue is:
    Code (csharp):
    1.  
    2. Graphics.Blit( smallTexture, largeTexture, new Material(Shader.Find("Diffuse") ) );
    3.  
    If I remove the 'new Material' and use whatever default the blitter uses it works properly.

    Here is a comparison of what setting a material vs not setting a material (not setting a material results in the correct output).

    Bad (mmmm random framebuffer values):


    Good:


    Is there something I am not doing to the material to ensure that it is valid? Is there a special material I should be using? If you want to test the script out just attach it to a default cube / sphere. It will set up all the materials ect.
     
  2. rookboom

    rookboom

    Joined:
    Sep 17, 2010
    Posts:
    3
    This seems to be a bug... I am seeing the same behavior.
     
  3. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    I think this topic came up already once or twice in the past and back then it was related heavily to what the material does because the input is pushed through the materials shader and when the input does not comply to the requirements then it messes up, same if the output can not correctly be mapped back due to texture format and alike
     
unityunity