Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

Graphics Texture arrays

Discussion in '5.4 Beta' started by jimmikaelkael, Mar 16, 2016.

  1. jimmikaelkael

    jimmikaelkael

    Joined:
    Apr 27, 2015
    Posts:
    796
    Hi,

    I've tried Unity 5.4 beta yesterday and its Texture array support in shaders to see the shader finally compiles when using them.

    However I've been unable to set a texture array from script (I'm just trying to deinterleave/reinterleave a sample texture). Will there be a Material.SetTextureArray method or something like that ?
     
    Last edited: Mar 16, 2016
  2. Hyp-X

    Hyp-X

    Joined:
    Jun 24, 2015
    Posts:
    438
    Texture2DArray inherits from Texture, so you should be able to use Material.SetTexture with it.
     
    nabergh likes this.
  3. jimmikaelkael

    jimmikaelkael

    Joined:
    Apr 27, 2015
    Posts:
    796
    I'll try this. However I'm dubious as Material.SetTexture is expecting a Texture...
    Should I pass it the first texture from the array ?
     
  4. TimCabbage

    TimCabbage

    Joined:
    Feb 13, 2011
    Posts:
    66
    Code (CSharp):
    1. public static void loadTextures(){
    2.         mainTexture = new Texture2DArray(MyProject.BASE_TILE_SIZE, MyProject.BASE_TILE_SIZE, MyProject.ATLAS_IMAGECOUNT*MyProject.ATLAS_IMAGECOUNT, TextureFormat.RGBA32, false);
    3.         mainTexture.filterMode = FilterMode.Point;
    4.         mainTexture.wrapMode = TextureWrapMode.Clamp;
    5.  
    6.         List<string> keyList = new List<string>(textureBank.Keys);
    7.         Texture2D badTex = Resources.Load ("Textures/invalid_texture") as Texture2D;
    8.         for(int i = 0; i<keyList.Count; i++){
    9.             Texture2D smallTex = Resources.Load ("Textures/"+keyList[i]) as Texture2D;
    10.             if(smallTex==null){
    11.                 Debug.Log("Textures/"+keyList[i]+" not found.");
    12.                 mainTexture.SetPixels32(badTex.GetPixels32(), textureBank[keyList[i]]);
    13.             } else {
    14.                 mainTexture.SetPixels32(smallTex.GetPixels32(), textureBank[keyList[i]]);
    15.             }
    16.         }
    17.  
    18.         mainTexture.Apply();
    19.         terrainMaterial.SetTexture("_MainTex",mainTexture);
    20.     }
    I use this in my project - creates the texture array, fills it with images loaded from resources(have to be readable) and sets the texture to be used by the terrain.
     
    jimmikaelkael likes this.
  5. jimmikaelkael

    jimmikaelkael

    Joined:
    Apr 27, 2015
    Posts:
    796
    I appreciate the help! thank you :)

    However in my case I output a RenderTexture array from a shader pass:
    Code (csharp):
    1.  
    2.   private void RenderMRT (RenderBuffer[] colorBuffers, RenderBuffer depthBuffer, int pass) {
    3.  
    4.      Graphics.SetRenderTarget (colorBuffers, depthBuffer);
    5.      GL.Clear (false, true, Color.clear);
    6.      GL.PushMatrix ();
    7.      GL.LoadOrtho ();
    8.      _ShaderMaterial.SetPass (pass);
    9.  
    10.      // Render the full screen quad manually.
    11.      GL.Begin (GL.QUADS);
    12.      GL.TexCoord2 (0.0f, 0.0f);
    13.      GL.Vertex3 (0.0f, 0.0f, 0.1f);
    14.      GL.TexCoord2 (1.0f, 0.0f);
    15.      GL.Vertex3 (1.0f, 0.0f, 0.1f);
    16.      GL.TexCoord2 (1.0f, 1.0f);
    17.      GL.Vertex3 (1.0f, 1.0f, 0.1f);
    18.      GL.TexCoord2 (0.0f, 1.0f);
    19.      GL.Vertex3 (0.0f, 1.0f, 0.1f);
    20.      GL.End ();
    21.  
    22.      GL.PopMatrix ();
    23.    }
    24.  
    But doing the following is not allowed :
    Code (csharp):
    1.  
    2.   RenderTexture[] mrt = new RenderTexture[8];
    3.   RenderBuffer[] mrtRB = new RenderBuffer[8];
    4.   for (int i = 0; i < mrtRB.Length; i++) {
    5.        mrt[i] = RenderTexture.GetTemporary (IntDivUp(source.width, 4), IntDivUp(source.height, 4), 0, RenderTextureFormat.RFloat);
    6.        mrtRB [i] = mrtTex [i].colorBuffer;
    7.   }
    8.   ...
    9.   RenderTexture oldRT = RenderTexture.active;
    10.   RenderMRT (mrtRB, mrt[0].depthBuffer, 2); // pass 2 outputs 8 render textures.
    11.   RenderTexture.active = oldRT;
    12.   ...
    13.   _ShaderMaterial.SetTexture ("_TexArray", mrt); // DOES NOT WORK !!!
    14.  
    My goal is to deinterleave a texture from a shader pass (this part works as expected) then reinterleave it in another pass (this is where I'm unable to pass back the RenderTexture array to the shader)

    Anyone ?
     
    Last edited: Mar 17, 2016
  6. TimCabbage

    TimCabbage

    Joined:
    Feb 13, 2011
    Posts:
    66
    You need to copy the contents of rendertextures into the texture array - texture array is NOT array of texture objects.
    After rendering stuff to the textures, just copy those contents into the texture array by using GetPixels and SetPixels to a particular layer of the array texture.

    EDIT: It looks like You're using 8 textures here - can't you pass 8 textures to a material? Never done more than 6 so that's why I'm asking.
     
    Last edited: Mar 17, 2016
  7. jimmikaelkael

    jimmikaelkael

    Joined:
    Apr 27, 2015
    Posts:
    796
    Sounds like an overkill. I'll loose all benefit of interleaving...

    I can pass the texture separately sure, but once again I'll loose all benefit of interleaving for which the goal is to read the slice you need in the shader pass and hence optimize the cache utilization:
    https://developer.nvidia.com/sites/default/files/akamai/gameworks/samples/DeinterleavedTexturing.pdf
    This article is talking about 2x2 deinterleaving while I'm trying 4x4 deinterleaving but the method is the same.

    In fact, I'm working on a SSAO post effect for which I'm deinterleaving the depth into 16 quarter resolution textures (requires 2 shader pass each giving 8 render texures), calculate AO for each layer (separable kernel) then reinterleave the result into a full resolution texture (this is where I need to read the slices).

    Would be great if Material.SetTexture could set a RenderTexture array.
     
  8. TimCabbage

    TimCabbage

    Joined:
    Feb 13, 2011
    Posts:
    66
    So as I understand it, You want to render to texture on GPU and put it into a texture array without it leaving the GPU.
    I read somewhere a writeup about this, but it was "deep magic" as in - it was using raw OpenGL calls to do this and I would assume that's what You'll have to do.
    I have no idea about the details of Your project, but I would try to use a simple Texture atlas for this, if possible.
    If not, try to use the raw OpenGL route and see where that gets You. One guy implemented TextureArrays this way before it was introduced to Unity and the only thing he was missing was the GC compiler things responsible for the sampler. Try looking that up and it might give You an idea about how to solve Your issues. Beware of platform differences though.

    Sorry I can't help much more, but that's as far as I've ever gone into Unity :)

    Cheers,
    Siv.
     
    jimmikaelkael likes this.
  9. abeacco

    abeacco

    Joined:
    Apr 24, 2015
    Posts:
    3
    Hi,

    I've been trying the whole morning to use the new Texture2DArrays, but though I am properly creating them in my scripts, I am not able to compile any Shader that uses them.
    How are you guys declaring the samplers in your shader code?
    I've tried with "sampler2DARRAY" but the compiler does not know what it means.
    Same thing with the texture fetch function, I am not able to make the compiler recognize the "tex2DARRAY" function.

    Thanks in advance,

    Alejandro
     
  10. jimmikaelkael

    jimmikaelkael

    Joined:
    Apr 27, 2015
    Posts:
    796
    I guess you can do:
    Code (csharp):
    1.  
    2. UNITY_DECLARE_TEX2DARRAY(name)
    3. UNITY_SAMPLE_TEX2DARRAY(name,coord) // coord is float3
    4.  
    source: https://gist.github.com/aras-p/a3aeac5c84ce233f6787

    On my side I simply have declared it as follow:
    Code (csharp):
    1.  
    2. Texture2DArray<float4> _MyTexArray
    3.  
     
  11. jimmikaelkael

    jimmikaelkael

    Joined:
    Apr 27, 2015
    Posts:
    796
    Thank you for your help!

    In fact I already had a workaround for 2x2 interleaving, I used to pass 4 separate textures to the shader that needs to reinterleave the texture, and I used branching depending on the offset to read the texture slice accordingly.
    This worked fine, however for 4x4 interleaving you get 16 textures to fetch so it's an overkill to workaround and honestly I would prefer to use a regular texture array functionality which should be more efficient.

    Would be far more easier if one could set a texture array from a RenderTexture array directly:
    Code (csharp):
    1.  
    2. Material myShaderMaterial;
    3. RenderTexture[] myRenderTextureArray;
    4. ....
    5. myShaderMaterial.SetTexture("_MyTexArray", myRenderTextureArray);
    6.  
    This would open the texture arrays functionality to those who wants to use advanced techniques like deinterleaving instead of restricting it to texture atlas / terrain textures...

    Unity guys, any word on this ?
     
  12. abeacco

    abeacco

    Joined:
    Apr 24, 2015
    Posts:
    3
    Hi,

    Thanks for replying but this isn't helping.
    The compiler still does not recognize any of those tokens.

    In any case, what I am asking for is just a simple example where you use the native support for Texture2DArray that the new 5.4 beta version of Unity is suppose to give.
    As I said, I am able to create the texture in C# scripts using the new Texture2DArray class, but there is no clue at all about how to use them in the shaders.

    Thanks,

    Alejandro
     
  13. jimmikaelkael

    jimmikaelkael

    Joined:
    Apr 27, 2015
    Posts:
    796
    Declaring a Texture2DArray<float4> in the shader SHOULD work as it's what I'm using and shader is compiling fine.
    Make sure you are targetting the proper Shader Model.
     
  14. TimCabbage

    TimCabbage

    Joined:
    Feb 13, 2011
    Posts:
    66
    Declaring a shader input for texture array (in properties): _MainTex ("Texture", 2DArray) = "white" {}
    Declaring a sampler: UNITY_DECLARE_TEX2DARRAY(name)
    Using a sampler: half4 baseColor = UNITY_SAMPLE_TEX2DARRAY(_MainTex, i.UV);

    So what jimmikaelkael gave You was all that's needed:)
     
  15. abeacco

    abeacco

    Joined:
    Apr 24, 2015
    Posts:
    3
    Hi again,

    Though I really appreciate your help (the only one I am finding right now), I think we are still having some missunderstanding or missing pieces.
    The Macros you are telling me to use are not working at all (the compiler keeps complaining about syntax error with those lines).
    So, for the sake of clarity and for future readers of this thread, can we summarize all that is needed in order to make Texture2DArray work in Unity 5.4.0b10 ?
    What is the proper Shader Model to target? I am using 5.0.
    What is the shader compiler needed and how to change it? I am writing in Cg.
    What platforms are supported? I guess only d3d11, although OpenGL should work too...
    And why the hell should we use this kind of macros? Shouldn't they be built-in tokens such as "Sampler2DARRAY" and "tex2DARRAY" ?? I can't understand what this is still not in Unity :(

    Thanks again in advance,

    Cheers,

    Alejandro
     
  16. Ramon-Oliva

    Ramon-Oliva

    Joined:
    Oct 7, 2013
    Posts:
    3
    Hi,

    I am also encountering issues with the Texture2DArray and shaders. I've been following the steps given by jimmikaelkael and sivael (thanks both for your valuable help) and the result is that I am able to declare a Texture2DArray in a custom vertex and fragment shader, but not in a surface shader. I mean, in the surface shader it gives a sintax error, so I guess this is the issue abeacco is refering to.

    Please, find attached both shaders in case you want to try. The surface shader (not compiling):

    Code (CSharp):
    1. Shader "Custom/Tex2DArray" {
    2.     Properties {
    3.         _Color ("Color", Color) = (1,1,1,1)
    4.         _MainTex ("Albedo (RGB)", 2D) = "white" {}
    5.         _Glossiness ("Smoothness", Range(0,1)) = 0.5
    6.         _Metallic ("Metallic", Range(0,1)) = 0.0
    7.         _Tex2DArray ("Tex2DArray (RGB)", 2DArray) = "white" {}
    8.     }
    9.     SubShader {
    10.         Tags { "RenderType"="Opaque" }
    11.         LOD 200
    12.        
    13.         CGPROGRAM
    14.         // Physically based Standard lighting model, and enable shadows on all light types
    15.         #pragma surface surf Standard fullforwardshadows
    16.  
    17.         // Use shader model 3.0 target, to get nicer looking lighting
    18.         #pragma target 4.0
    19.  
    20.         sampler2D _MainTex;
    21.         UNITY_DECLARE_TEX2DARRAY(_Tex2DArray);
    22.  
    23.         struct Input {
    24.             float2 uv_MainTex;
    25.         };
    26.  
    27.         half _Glossiness;
    28.         half _Metallic;
    29.         fixed4 _Color;
    30.  
    31.         void surf (Input IN, inout SurfaceOutputStandard o) {
    32.             // Albedo comes from a texture tinted by color
    33.             fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
    34.             o.Albedo = c.rgb;
    35.             // Metallic and smoothness come from slider variables
    36.             o.Metallic = _Metallic;
    37.             o.Smoothness = _Glossiness;
    38.             o.Alpha = c.a;
    39.         }
    40.         ENDCG
    41.     }
    42.     FallBack "Diffuse"
    43. }
    44.  
    And the custom vertex and fragment shader (compiling fine):

    Code (CSharp):
    1. Shader "Unlit/Tex2DArray2"
    2. {
    3.     Properties
    4.     {
    5.         _MainTex ("Texture", 2D) = "white" {}
    6.         _Tex2DArray ("Tex2DArray (RGB)", 2DArray) = "white" {}
    7.     }
    8.     SubShader
    9.     {
    10.         Tags { "RenderType"="Opaque" }
    11.         LOD 100
    12.  
    13.         Pass
    14.         {
    15.             CGPROGRAM
    16.             #pragma vertex vert
    17.             #pragma fragment frag
    18.             // make fog work
    19.             #pragma multi_compile_fog
    20.            
    21.             #include "UnityCG.cginc"
    22.  
    23.             struct appdata
    24.             {
    25.                 float4 vertex : POSITION;
    26.                 float2 uv : TEXCOORD0;
    27.             };
    28.  
    29.             struct v2f
    30.             {
    31.                 float2 uv : TEXCOORD0;
    32.                 UNITY_FOG_COORDS(1)
    33.                 float4 vertex : SV_POSITION;
    34.             };
    35.  
    36.             sampler2D _MainTex;
    37.             UNITY_DECLARE_TEX2DARRAY(_Tex2DArray);
    38.             float4 _MainTex_ST;
    39.            
    40.             v2f vert (appdata v)
    41.             {
    42.                 v2f o;
    43.                 o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
    44.                 o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    45.                 UNITY_TRANSFER_FOG(o,o.vertex);
    46.                 return o;
    47.             }
    48.            
    49.             fixed4 frag (v2f i) : SV_Target
    50.             {
    51.                 // sample the texture
    52.                 fixed4 col = tex2D(_MainTex, i.uv);
    53.                 // apply fog
    54.                 UNITY_APPLY_FOG(i.fogCoord, col);
    55.                 return col;
    56.             }
    57.             ENDCG
    58.         }
    59.     }
    60. }
    61.  
    So is there something I am missing in the case of the surface shader? Maybe an include or a pragma? Or it is simply a bug of the current beta version that will be adressed in a future release?

    Thanks in advance!
     
  17. jimmikaelkael

    jimmikaelkael

    Joined:
    Apr 27, 2015
    Posts:
    796
    @Ramon Oliva
    In the surface shader it seems you're not including UnityCG.cginc
     
  18. Ramon-Oliva

    Ramon-Oliva

    Joined:
    Oct 7, 2013
    Posts:
    3
    Hi,

    I've already tried this, but it still does not work. Even I've tried to include the specific file where this macro is declared (HLSLSupport.cginc) and it says the same, sintax error at the line corresponding to UNITY_DECLARE_TEX2DARRAY(_Tex2DArray);

    Also notice that I've forced to compile using pragma target 4.0, as I've readed in the releases notes that you need at least target 3.5 in order to get TextureArrays to work.

    So anyone has been able to compile a surface shader with a Texture2DArray property? And if this is the case, could you put a simple example? Maybe an official Unity developer could shed light on this issue in order to know if it is a Unity bug or something am I missing.
     
  19. TimCabbage

    TimCabbage

    Joined:
    Feb 13, 2011
    Posts:
    66
    Hm.
    Doesn't look like it's working very well - the surface shader compilation pipeline seems to be breaking somewhere along the way if using texture arrays anywhere.
    You could extract the final vertex and fragment shaders and use those with Your modifications, I guess.
     
  20. Kaneleka

    Kaneleka

    Joined:
    Sep 23, 2013
    Posts:
    18
    I've seen the same issue of texture arrays not working under a surface shader. I can live with that for now but what's more concerning to me is why I'm seeing half the FPS in my terrain shader now by just switching from 10 texture samples to 2 texture arrays of 5 diffuse & normal maps. I'm in the process of simplifying the shader to further troubleshoot and compare against, but was wondering if anyone else has noticed and can confirm a similar drop in performance by using the Texture2DArray?
    Unity ver: Beta 10
     
  21. TimCabbage

    TimCabbage

    Joined:
    Feb 13, 2011
    Posts:
    66
    Yes, I've seen slight drops in Texture Array FPS(1-5%), I assume it's connected to the way they're handled - and it's to be expected.
    Texture arrays simply enable you to do stuff You wouldn't be able to do otherwise, like passing two Vector3s with 3 weights for textures to be blended(by index), instead of passing a giant atlas or many textures. It's not magically faster, it's just enabling You to do stuff You couldn't otherwise.
     
  22. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,770
    Right, in the surface shaders you have to wrap the texture array code with some ifdef, e.g. (typing out of my head):

    #ifndef SHADER_TARGET_SURFACE_ANALYSIS
    UNITY_DECLARE_TEX2DARRAY(_MyArray);
    #endif

    ..and similar for sampling it. Currently the parser we use for surface shader analysis step does not quite understand DX10/DX11 syntax, which includes texture arrays. See note at the end here http://docs.unity3d.com/Manual/SL-SurfaceShaders.html -- I'll expand & clarify the docs.
     
  23. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,770
    I'll fix surface shader compiler so that it does not go belly up on texture array macros...
     
    Ramon-Oliva and Peter77 like this.
  24. jimmikaelkael

    jimmikaelkael

    Joined:
    Apr 27, 2015
    Posts:
    796
    @Aras Great news. What about my request just a few post above to be able to pass a RenderTexture array to Material.SetTexture ?

    Code (csharp):
    1.  
    2.   RenderTexture[] mrt = new RenderTexture[8];
    3.   RenderBuffer[] mrtRB = new RenderBuffer[8];
    4.   for (int i = 0; i < mrtRB.Length; i++) {
    5.        mrt[i] = RenderTexture.GetTemporary (IntDivUp(source.width, 4), IntDivUp(source.height, 4), 0, RenderTextureFormat.RFloat);
    6.        mrtRB [i] = mrtTex [i].colorBuffer;
    7.   }
    8.   ...
    9.   RenderTexture oldRT = RenderTexture.active;
    10.   RenderMRT (mrtRB, mrt[0].depthBuffer, 2); // pass 2 outputs 8 render textures.
    11.   RenderTexture.active = oldRT;
    12.   ...
    13.   _ShaderMaterial.SetTexture ("_TexArray", mrt); // DOES NOT WORK !!!
    14.  
    Would be great to allow texture reinterleaving in post effect shaders.
     
  25. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,770
    But that is entirely different. An array of textures is _not_ a texture array :)

    If you want a render texture that is an TextureArray, create a RenderTexture and set .dimention to texture array.
     
    jimmikaelkael likes this.
  26. jimmikaelkael

    jimmikaelkael

    Joined:
    Apr 27, 2015
    Posts:
    796
    @Aras thank you so much or your reply!

    Some things still unclear to me, will the following code be valid ?
    Will I get all the slices into "rt" from a shader pass that outputs multiple textures ?

    Code (csharp):
    1.  
    2. RenderTexture rt = RenderTexture.GetTemporary (source.width, source.height, 0, RenderTextureFormat.RFloat);
    3. rt.dimension = TextureDimension.Tex2DArray;
    4. Graphics.Blit(source, rt, _ShaderMaterial, 2);
    5. _ShaderMaterial.SetTexture("_TexArray", rt);
    6.  
    EDIT: What I want is that my texture array does not leave the GPU, for example deinterleave depth in a shader pass, do some work in another pass, then reinterleave the result in a final pass.
     
    Last edited: Mar 31, 2016
  27. Ramon-Oliva

    Ramon-Oliva

    Joined:
    Oct 7, 2013
    Posts:
    3
    Hi Aras,

    Thanks! This is great news! Please, let us know when it is done! :)
     
  28. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,770
    But for that you don't need texture arrays. Render stuff into one texture, render into another, set them up as parameters for your shader, read them in the shader etc. The pixels never leave the GPU.

    Only things like Texture2D.ReadPixels ("read pixels from current render target into system memory") and the like are "leave the GPU" case.
     
  29. jimmikaelkael

    jimmikaelkael

    Joined:
    Apr 27, 2015
    Posts:
    796
    If not using texture array, when reinterleaving you need to fetch from several textures... (16 for 4x4 deinterleaving !) You are advising me to feed my shader pass with 16 differents textures (and handle offsets myself) and fetch them all to reinterleave ?

    Seriously, with a texture array you just need to get the slice index and read (no branching whatsover, and better efficiency).

    I want to implement this technique: https://developer.nvidia.com/sites/default/files/akamai/gameworks/samples/DeinterleavedTexturing.pdf
    This describe 2x2 deinterleaving but overall it works the same way.
     
  30. SenRey

    SenRey

    Joined:
    Jun 20, 2015
    Posts:
    3
    That's a great news. Do you have a ETA for fix?
     
  31. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,770
    Should be in 5.4 beta 15 already: "Shaders: Change to make it possible to use texture arrays (UNITY_DECLARE_TEX2DARRAY etc.) in surface shaders without jumping through hoops." https://unity3d.com/unity/beta/unity5.4.0b15
     
  32. Brian-Kehrer

    Brian-Kehrer

    Joined:
    Nov 7, 2006
    Posts:
    411
    I'm also struggling a bit - but in custom shaders.

    Should this work for arrays, and 3D textures? (I've tried both).

    Depth is calculated out of the vertex shader
    Code (csharp):
    1.  
    2. RenderTexture texture = new RenderTexture(width, height,0,RenderTextureFormat.R8,RenderTextureReadWrite.Linear);
    3. texture.hideFlags = HideFlags.HideAndDontSave;
    4. texture.antiAliasing = 1;
    5. texture.filterMode = FilterMode.Trilinear;
    6. texture.generateMips = true;
    7. texture.useMipMap = true;
    8. texture.wrapMode = TextureWrapMode.Clamp;
    9. texture.dimension = UnityEngine.Rendering.TextureDimension.Tex2DArray;
    10. texture.volumeDepth = 128;
    11. texture.Create();
    12.  
    13. Graphics.SetRenderTarget(texture, 0, CubemapFace.Unknown, -1);
    14. Shader.SetGlobalTexture("_MyArr",texture);
    15.  
    Code (csharp):
    1.  
    2. struct GSOutput
    3. {
    4.     float4 position : SV_POSITION;
    5.  
    6.  
    7.     float3 voxelPosition : TEXCOORD0;
    8.     float depth : TEXCOORD1;
    9.     float3 normal : TEXCOORD2;
    10.     uint slice : SV_RenderTargetArrayIndex;
    11.  
    12. }
    13.  
    14. [maxvertexcount(12)]
    15. void GeometryProgram(triangle GSInput p[3], inout TriangleStream<GSOutput> triStream){
    16.  
    17.  
    18.     uint minDepth = min(min(p[0].depth, p[1].depth), p[2].depth);
    19.     uint maxDepth = max(max(p[0].depth, p[1].depth), p[2].depth);
    20.     int tris = min(4, max(1,maxDepth - minDepth));
    21.  
    22.  
    23.     GSOutput o;
    24.     for(int i=0; i<tris; i++){
    25.         o.position = p[0].position;
    26.         o.voxelPosition = p[0].voxelPosition;
    27.         o.depth = p[0].depth;
    28.         o.normal = p[0].normal;
    29.         o.slice = minDepth +i;
    30.         triStream.Append(o);
    31.  
    32.  
    33.         o.position = p[1].position;
    34.         o.voxelPosition = p[1].voxelPosition;
    35.         o.depth = p[1].depth;
    36.         o.normal = p[2].normal;
    37.         o.slice = minDepth +i;
    38.         triStream.Append(o);
    39.  
    40.  
    41.         o.position = p[2].position;
    42.         o.voxelPosition = p[2].voxelPosition;
    43.         o.depth = p[2].depth;
    44.         o.normal = p[2].normal;
    45.         o.slice = minDepth +i;
    46.         triStream.Append(o);
    47.     }
    48. }
    49.  
     
    SpaceToad likes this.