Search Unity

  1. 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

Using Shader Framebuffer Fetch with LWRP

Discussion in 'Shaders' started by Deleted User, May 8, 2019.

  1. Deleted User

    Deleted User

    Guest

    I'm attempting to use Framebuffer fetch on mobile with LWRP. The code example in the docs (https://docs.unity3d.com/Manual/SL-PlatformDifferences.html) is written in CG and it uses SV_Target for the input semantic. This doesn't seem to work in an HLSLPROGRAM when compiling for OpenGL ES 3.1.

    When I attempt to compile a simple fragment function like this:
    Code (JavaScript):
    1. void frag(Varyings input, inout half4 ocol : SV_Target) {
    2.     ocol /= 2;
    3. }
    I get the compiler error: `invalid ps_5_0 input semantic 'SV_Target'`. Does anyone know the correct inout semantic to use or if there's some other mistake here?
     
  2. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    1,606
    LWRP doesn't (yet) define the macros for framebuffer fetch.
    You can use "CoLoR" instead of "SV_Target" or indexed versions if you need those (e.g. CoLoR1 instead of SV_Target1).
     
  3. Deleted User

    Deleted User

    Guest

    CoLoR1 works in editor, it now compiles a valid shader but it doesn't seem to run on device. I'll just find another solution until this is supported, thanks for the help.
     
  4. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    1,606
    If you're not rendering to multiple render targets, it should be CoLoR or CoLoR0, not CoLoR1.
     
  5. Deleted User

    Deleted User

    Guest

    So that still didn't quite work, it seems to generate the wrong GLSL code. If I write the shader directly in GLSL I can make it work:

    before-draw.PNG after-draw.PNG

    GLSL:

    Code (JavaScript):
    1. #version 310 es
    2. #extension GL_EXT_shader_framebuffer_fetch : require
    3.  
    4. precision highp float;
    5. precision highp int;
    6. layout(location = 0) inout lowp vec4 SV_Target0;
    7.  
    8. void main()
    9. {
    10.     float gray = (SV_Target0.x + SV_Target0.y + SV_Target0.z) / 3.0;
    11.     SV_Target0 = vec4(gray, gray, gray, 1);
    12.     return;
    13. }
     
  6. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    1,606
    I tested it last week, and it worked for me :)

    Are you still testing with the shader you provided in the first snippet?
    Which Unity version are you on?
     
  7. wangtianyu

    wangtianyu

    Joined:
    Jul 29, 2020
    Posts:
    15
    I have a same problem in 2019.3.1f1 and 2020.1.0f1c1.
    Change "SV_Target" to "CoLoR" can resolve the compiler error, but it's not work when i generate to GLSL for GLES3.2 android device.
    by the way CG is work. upload_2020-7-29_17-31-11.png
     
  8. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    1,606
    @wangtianyu What do the logs on the device say?
    What's the device you are trying this on?
     
  9. wangtianyu

    wangtianyu

    Joined:
    Jul 29, 2020
    Posts:
    15
    sorry i miss the log... it's should be like "vs_SV_Target0" is undefined ? i guess
    And my company has the source code, in CompilerHLSL.cpp ParseNeedForFramebufferFetchEnabled , should we add KCoLoRToken to match the "inout <type> <var> : CoLoR" oneliner?
     
  10. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    1,606
    There's no "vs_SV_Target0", SV_Target<X> is a fragment shader thing.

    No, it should work without adding this.
     
  11. wangtianyu

    wangtianyu

    Joined:
    Jul 29, 2020
    Posts:
    15
    Log:
    07-30 16:26:57.052: E/Unity(6904): -------- GLSL link error: Error: input vs_SV_Target0 not declared in output from previous stage.
    07-30 16:26:57.052: E/Unity(6904): Error: Linking failed.


    No, it should work without adding this.[/QUOTE]
    My goal is not use framebuffer in HLSL,I want is right generate to GLSL.

    I provided two demo, I expect them to achieve the same result, may be is wrong?
     

    Attached Files:

  12. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    1,606
    So, which one works and which one doesn't?
    Looks like you have one for built-in render pipeline and one for SRP.
     
  13. wangtianyu

    wangtianyu

    Joined:
    Jul 29, 2020
    Posts:
    15
    yes ,i try to transplant to srp
    SRP has problem.

    HLSLSupport.cginc
    #if defined(UNITY_FRAMEBUFFER_FETCH_AVAILABLE) && defined(UNITY_FRAMEBUFFER_FETCH_ENABLED) && defined(UNITY_COMPILER_HLSLCC)
    #define SV_Target CoLoR

    I found this code, maybe i should define like cg to make generate match SV_Target?
     
  14. wangtianyu

    wangtianyu

    Joined:
    Jul 29, 2020
    Posts:
    15
    anyway is work..but uglily
     

    Attached Files:

  15. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    1,606
    Well, this means you can just change SV_Target to CoLoR in your code and it will work.
     
  16. wangtianyu

    wangtianyu

    Joined:
    Jul 29, 2020
    Posts:
    15
    yes , use CoLoR replace SV_Target and keep the code is SV_Target for generate to glsl...great...
     
  17. wangtianyu

    wangtianyu

    Joined:
    Jul 29, 2020
    Posts:
    15
    hi.me again.
    about the EXT_shader_framebuffer_fetch, i found the OpenGL document about "How is framebuffer data treated during multisample rendering?" ,the answer was
    RESOLVED: Reading the value of gl_LastFragData produces a different
    result for each sample. This implies that all or part of the shader be
    run once for each sample, but has no additional implications on fragment
    shader input variables which may still be interpolated per pixel by the
    implementation.
    what the "This implies that all or part of the shader be run once for each sample" mean.If I use the msaa x4 and framebuffer fetch ,the pixel shader will be run 4 times for each pixel?

    https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_shader_framebuffer_fetch.txt
     
    liam_unity628 likes this.
  18. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    1,606
    It depends on how the MSAA algorithm on the GPU works. I'd say it's not "4 times", but "up to 4 times". If the GPU only applies MSAA to the triangle edges, you'll get 4x fragment shader invocations on those and 1 invocation inside the triangle.
     
  19. wangtianyu

    wangtianyu

    Joined:
    Jul 29, 2020
    Posts:
    15
    Thank you.
    so,that's mean i use both of them, rendering effeciency probably go down a lot.
     
  20. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    1,606
    Not really - depends on what is being rendered. MSAA 4x is usually not very expensive on mobile.
     
  21. wangtianyu

    wangtianyu

    Joined:
    Jul 29, 2020
    Posts:
    15
    But, usually MSAA runs the fragment program just once per pixel rasterized, open the framebuffer fetch it's going to be 4 times(like the SSAA) ,even if it's only on the edge.this looks terrible...
     
  22. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    1,606
    No, I think it should be exactly the same here.
    With MSAA the fragment shader doesn't run once per rasterized pixel, as I said earlier. It depends on the GPU and the driver. Most likely it will run once for fragments that are inner to the triangle and 4 times for fragments on the edges.
     
  23. wangtianyu

    wangtianyu

    Joined:
    Jul 29, 2020
    Posts:
    15
    OK,I want talk about OpenGLES,I found this in wiki(but the wiki for OpenGL) about MSAA.
    " Unlike supersampling (SSAA) which can result in the same pixel being shaded multiple times per pixel, multisampling runs the fragment program just once per pixel rasterized."
    https://www.khronos.org/opengl/wiki/Multisampling
    Maybe I made a mistake?
     
  24. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    1,606
    This just means that triangle edges generate more than one rasterized pixel. Otherwise there would have been no AA at all.
     
  25. wangtianyu

    wangtianyu

    Joined:
    Jul 29, 2020
    Posts:
    15
    HI,I do a test, i create a particle system has 100 particles use the shader that just a simple Blend SrcAlpha One with use framebuffer fetch .I use the particle system full my screen
    When the MSAA is off
    On my device the run with 30 FPS.
    When the MSAA is on
    it's just run with 7 FPS
    so , it's seems big impact to render efficiency.
    shader ps like this:
    Code (CSharp):
    1.                    
    2. void frag(v2f i, inout float4 color : SV_Target)
    3. {
    4. color += float4(0.5,0,0,1);
    5. }
    6.  
     
  26. wangtianyu

    wangtianyu

    Joined:
    Jul 29, 2020
    Posts:
    15
    And i found a bug..
    when i sample a texture and use buffer fetch together, the shader will error.
    like this
    Code (CSharp):
    1. void frag(v2f i, inout float4 color : SV_Target)
    2. {
    3.     half4 col = /*2.0f * i.color **/ _TintColor * tex2D(_MainTex, i.texcoord);
    4.     col.a = saturate(col.a);
    5.     color += (1 - col.a)* col;
    6. }
    because the layout same location 0,they are conflict.

    upload_2020-8-19_14-47-14.png
     

    Attached Files:

  27. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    1,606
    Can you please report a bug with this finding?
    Thanks!
    And what if you don't use blending? Also, what GPU are you trying this on?
     
  28. wangtianyu

    wangtianyu

    Joined:
    Jul 29, 2020
    Posts:
    15
    i use the buffer fetch , the "+=" like the blending add.so i'm not use blending.

    device is "xiaomi 8 se",gpu:Adreno 616

    i have reported this bug to you colleague that on stay my company.I can ask the id to him if you need.
     
  29. unity_F6XSqL4MmNGmOg

    unity_F6XSqL4MmNGmOg

    Unity Technologies

    Joined:
    Jul 27, 2020
    Posts:
    1
    Hi, Aleksandrk. Wangtianyu has sent me a project to reproduce this problem and the support ticket number is 866268.
     
    aleksandrk likes this.
unityunity