Search Unity

Logical BlendOps not working

Discussion in 'Shaders' started by at1012, Feb 28, 2017.

  1. at1012

    at1012

    Joined:
    Mar 10, 2013
    Posts:
    6
    Hello, I am attempting to voxelize the scene through a logical blending operation using the dx 11.1 blend ops referenced here. However, this appears to have no effect in the final render

    I am using the dx 11 option in the player settings, and other blend modes, such as Min, Max, etc. seem to work fine. I have attached references to compare against the effect from max blending (since I write 32 bits per channel with ARGBFloat format). Any ideas or suggestions on what might be causing the problem are greatly appreciated.

    Thank you!

    References:

    With Logical Blending:

    logical.jpg

    With Max Blending:

    max.jpg

    Shader Code:

    Code (CSharp):
    1. Shader "Hidden/T_Voxelize"
    2. {
    3.     Properties
    4.     {
    5.         _MainTex("Base (RGB)", 2D) = "black" {}
    6.     }
    7.    
    8.     CGINCLUDE
    9.    
    10.     #include "UnityCG.cginc"
    11.    
    12.     struct appdata_t
    13.     {
    14.         float4 vertex : POSITION;
    15.     };
    16.    
    17.     struct v2f
    18.     {
    19.         float4 vertex : SV_POSITION;
    20.         float vdist : TEXCOORD0;
    21.     };
    22.    
    23.     uniform sampler2D _MainTex;
    24.    
    25.     v2f vert (appdata_t v)
    26.     {
    27.         v2f o;
    28.         o.vertex = mul(UNITY_MATRIX_MV, v.vertex);
    29.         o.vdist = -o.vertex.z;
    30.         o.vertex = mul(UNITY_MATRIX_P, o.vertex);
    31.        
    32.         return o;
    33.     }
    34.  
    35.     float4 frag (v2f i) : SV_Target
    36.     {
    37.         int shift = floor(i.vdist / _ProjectionParams.z * 127 + 0.5);
    38.        
    39.         float rshift = shift > 31 ? 0 : 1 << shift;
    40.         float gshift = shift > 63 || shift < 32 ? 0 : 1 << (shift - 32);
    41.         float bshift = shift > 95 || shift < 64 ? 0 : 1 << (shift - 64);
    42.         float ashift = shift < 96 ? 0 : 1 << (shift - 96);
    43.        
    44.         return float4(rshift, gshift, bshift, ashift);
    45.     }
    46.    
    47.     ENDCG
    48.    
    49.     SubShader
    50.     {
    51.         Pass
    52.         {
    53.             Fog { Mode Off }
    54.             ZTest Always Cull Off ZWrite Off
    55.             Blend One One
    56.             BlendOp LogicalOr
    57.            
    58.             CGPROGRAM
    59.            
    60.             #pragma target 5.0
    61.             #pragma vertex vert
    62.             #pragma fragment frag
    63.            
    64.             ENDCG
    65.         }
    66.     }
    67.     Fallback off
    68. }
    69.  
     
  2. at1012

    at1012

    Joined:
    Mar 10, 2013
    Posts:
    6
    After looking at this some more, it seems that for some reason the logical blendops do not work when rendering into an ARGBFloat format render texture (any ideas as to why would be appreciated). Anyway, after modifying the shader to render into 4 ARGB32 targets I am getting the desired result for the first 3 targets; however, the last target is not being filled out and I am receiving a strange error message "count < kMaxSupportedRenderTargets" when calling Camera.RenderWithShader().

    From what I have seen with multiple render targets, I should be able to render into 4 with my current hardware, so I am puzzled about this error message. Furthermore, when reducing down to 3 render targets, the message goes away.

    Any ideas/suggestions on what might be causing the error would be greatly appreciated. I have also added the updated shader and draw call code below.

    Shader:
    Code (CSharp):
    1. Shader "Hidden/T_Voxelize"
    2. {
    3.     CGINCLUDE
    4.    
    5.     #include "UnityCG.cginc"
    6.    
    7.     struct appdata_t
    8.     {
    9.         float4 vertex : POSITION;
    10.     };
    11.    
    12.     struct v2f
    13.     {
    14.         float4 vertex : SV_POSITION;
    15.         float vdist : TEXCOORD0;
    16.     };
    17.    
    18.     struct f2a
    19.     {
    20.         float4 col0 : SV_Target0;
    21.         float4 col1 : SV_Target1;
    22.         float4 col2 : SV_Target2;
    23.         float4 col3 : SV_Target3;
    24.     };
    25.    
    26.     v2f vert (appdata_t v)
    27.     {
    28.         v2f o;
    29.         o.vertex = mul(UNITY_MATRIX_MV, v.vertex);
    30.         o.vdist = -o.vertex.z;
    31.         o.vertex = mul(UNITY_MATRIX_P, o.vertex);
    32.        
    33.         return o;
    34.     }
    35.  
    36.     f2a frag (v2f i)
    37.     {
    38.         f2a o;
    39.        
    40.         int shift = floor(i.vdist / _ProjectionParams.z * 127 + 0.5);
    41.        
    42.         float r1 = shift > 7 ? 0 : 1 << shift;
    43.         float g1 = shift > 15 || shift < 8 ? 0 : 1 << (shift - 8);
    44.         float b1 = shift > 23 || shift < 16 ? 0 : 1 << (shift - 16);
    45.         float a1 = shift > 31 || shift < 24 ? 0 : 1 << (shift - 24);
    46.        
    47.         float r2 = shift > 39 || shift < 32 ? 0 : 1 << (shift - 32);
    48.         float g2 = shift > 47 || shift < 40 ? 0 : 1 << (shift - 40);
    49.         float b2 = shift > 55 || shift < 48 ? 0 : 1 << (shift - 48);
    50.         float a2 = shift > 63 || shift < 56 ? 0 : 1 << (shift - 56);
    51.        
    52.         float r3 = shift > 71 || shift < 64 ? 0 : 1 << (shift - 64);
    53.         float g3 = shift > 79 || shift < 72 ? 0 : 1 << (shift - 72);
    54.         float b3 = shift > 87 || shift < 80 ? 0 : 1 << (shift - 80);
    55.         float a3 = shift > 95 || shift < 88 ? 0 : 1 << (shift - 88);
    56.        
    57.         float r4 = shift > 103 || shift < 96 ? 0 : 1 << (shift - 96);
    58.         float g4 = shift > 111 || shift < 104 ? 0 : 1 << (shift - 104);
    59.         float b4 = shift > 119 || shift < 112 ? 0 : 1 << (shift - 112);
    60.         float a4 = shift < 120 ? 0 : 1 << (shift - 120);
    61.        
    62.         o.col0 = float4(r1, g1, b1, a1);
    63.         o.col1 = float4(r2, g2, b2, a2);
    64.         o.col2 = float4(r3, g3, b3, a3);
    65.         o.col3 = float4(r4, g4, b4, a4);
    66.        
    67.         return o;
    68.     }
    69.    
    70.     ENDCG
    71.    
    72.     SubShader
    73.     {
    74.         Pass
    75.         {
    76.             Fog { Mode Off }
    77.             ZTest Always Cull Off ZWrite Off
    78.             Blend One One
    79.             BlendOp LogicalOr
    80.            
    81.             CGPROGRAM
    82.            
    83.             #pragma target 5.0
    84.             #pragma vertex vert
    85.             #pragma fragment frag
    86.            
    87.             ENDCG
    88.         }
    89.     }
    90.     Fallback off
    91. }
    92.  
    C#:
    Code (CSharp):
    1. private void OnPreRender()
    2.     {
    3.         for (int i = 0; i < 4; i++)
    4.         {
    5.             _voxelBuffers[i] = RenderTexture.GetTemporary (128, 128, 0, RenderTextureFormat.ARGB32);
    6.             _voxelBuffers[i].filterMode = FilterMode.Point;
    7.             _voxelBuffers[i].wrapMode = TextureWrapMode.Clamp;
    8.             _voxelBuffers[i].useMipMap = true;
    9.             _voxelBuffers[i].DiscardContents ();
    10.  
    11.             _voxelColorBuffers[i] = _voxelBuffers[i].colorBuffer;
    12.         }
    13.  
    14.         _voxelCam.SetTargetBuffers (_voxelColorBuffers, _voxelBuffers[0].depthBuffer);
    15.         _voxelCam.RenderWithShader (_voxelizeShader, string.Empty);
    16.  
    17.         _giMaterial.SetTexture ("_VoxelBuffer0", _voxelBuffers[0]);
    18.         _giMaterial.SetTexture ("_VoxelBuffer1", _voxelBuffers[1]);
    19.         _giMaterial.SetTexture ("_VoxelBuffer2", _voxelBuffers[2]);
    20.         _giMaterial.SetTexture ("_VoxelBuffer3", _voxelBuffers[3]);
    21.     }