Search Unity

  1. If you have experience with import & exporting custom (.unitypackage) packages, please help complete a survey (open until May 15, 2024).
    Dismiss Notice
  2. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice

BlendOp LogicalOr

Discussion in 'Shaders' started by LacunaCorp, Jan 13, 2019.

  1. LacunaCorp

    LacunaCorp

    Joined:
    Feb 15, 2015
    Posts:
    147
    Long story short, I need to use BlendOp LogicalOr in a shader to draw to a RenderTexture. I also need this shader to work on DX11+, and OpenGL 2.0+.

    It works as intended on DX11 and DX12, which is an important side note, because the docs claim that it only works on DX11.1, just for reference.

    When forcing OpenGL (4.5), the shader won't compile. I get the generic "not supported on this GPU" message. When I remove the blending instructions, it compiles fine, but obviously doesn't logically work.

    So, I stripped the blending instructions when compiling for OGL. I think it should be possible to achieve what I'm trying to do here, but it's the first time I've looked into this so there may be some obvious context issue I'm missing, such as making these calls at the wrong time relative to rendering.

    First, I set up bindings for OGL as follows, taking the symbolic constant values from gl.h;

    Code (CSharp):
    1. private const string PATH_LIB_OGL = "opengl32.dll"; //condensed for sake of question- this is the platform-correct path
    2.  
    3. public const uint
    4.             CAP_GL_BLEND = 0x0BE2,
    5.             CAP_GL_COLOR_LOGIC_OP = 0x0BF2,
    6.             BLD_ONE = 1,
    7.             BLDOP_GL_OR = 0x1507;
    8.  
    9. [DllImport(PATH_LIB_OGL)] private static extern void glEnable(uint cap);
    10. [DllImport(PATH_LIB_OGL)] private static extern void glDisable(uint cap);
    11. [DllImport(PATH_LIB_OGL)] private static extern void glBlendFunc(uint src, uint dst);
    12. [DllImport(PATH_LIB_OGL)] private static extern void glLogicOp(uint cap);
    13. [DllImport(PATH_LIB_OGL)] private static extern void glFlush();
    I need to render a mesh to a RenderTexture with this shader. The following works fine with DirectX, just to be clear;

    Code (CSharp):
    1. switch (_gApi)
    2. {
    3.     case GraphicsDeviceType.OpenGLES2:
    4.     case GraphicsDeviceType.OpenGLES3:
    5.     case GraphicsDeviceType.OpenGLCore:
    6.         GLibBindings.GLEnable(GLibBindings.CAP_GL_BLEND);
    7.         GLibBindings.GLBlendFunc(GLibBindings.BLD_ONE, GLibBindings.BLD_ONE);
    8.         GLibBindings.GLEnable(GLibBindings.CAP_GL_COLOR_LOGIC_OP);
    9.         GLibBindings.GLLogicOp(GLibBindings.BLDOP_GL_OR);
    10.         break;
    11. }
    12. _camMask.SetTargetBuffers(mask.colorBuffer, mask.depthBuffer);
    13. GL.RenderTargetBarrier();
    14. Graphics.DrawMesh(mesh, Matrix4x4.TRS(_trs.localToWorldMatrix.MultiplyPoint3x4(new Vector3(0, 0, _offsetClip + offset)), _trs.rotation, new Vector3(1, 1, 1)), MatMaskBuilder, LAYER_MASK, _camMask, 0, propBlock);
    15. _camMask.RenderWithShader(MatMaskBuilder.shader, null);
    16. _camMask.targetTexture = null;
    My idea was to P/Invoke the blending functions, which should work in theory, as far as I'm aware, so I take it I might be missing something about the order in which this all happens. Also, just to be totally clear, the shader output is fine with OpenGL, it's just stomping the existing data, which is why I need the OR blending. In other words, it's not some other GLSL compilation issue, this is absolutely down to the blending.

    I'd really appreciate any pointers here.

    Cheers,
    -Josh
     
    Last edited: Jan 13, 2019
  2. LacunaCorp

    LacunaCorp

    Joined:
    Feb 15, 2015
    Posts:
    147
    So it seems as though this is only possible via a native plugin, due to the rendering context. I wanted to port some vertex work to unmanaged anyhow so it's not big issue, I just wanted to post back here for reference. I'm stripping out the Graphics calls shown above and replacing them in the same order with calls to a native plugin which binds to the active rendering API, where I can then inject the proper OGL caps.