Using Shader Framebuffer Fetch with LWRP

I’m attempting to use Framebuffer fetch on mobile with LWRP. The code example in the docs (Unity - Manual: Writing shaders for different graphics APIs) 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:

void frag(Varyings input, inout half4 ocol : SV_Target) {
    ocol /= 2;
}

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?

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

1 Like

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.

If you’re not rendering to multiple render targets, it should be CoLoR or CoLoR0, not CoLoR1.

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:

GLSL:

#version 310 es
#extension GL_EXT_shader_framebuffer_fetch : require

precision highp float;
precision highp int;
layout(location = 0) inout lowp vec4 SV_Target0;

void main()
{
    float gray = (SV_Target0.x + SV_Target0.y + SV_Target0.z) / 3.0;
    SV_Target0 = vec4(gray, gray, gray, 1);
    return;
}

I tested it last week, and it worked for me :slight_smile:

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

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.6145289--671078--upload_2020-7-29_17-31-11.jpg

@wangtianyu What do the logs on the device say?
What’s the device you are trying this on?

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 : CoLoR” oneliner?

There’s no “vs_SV_Target0”, SV_Target is a fragment shader thing.

No, it should work without adding this.

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?

6149872–671740–GLSLTest.shader (797 Bytes)
6149872–671743–HLSLTest.shader (913 Bytes)

So, which one works and which one doesn’t?
Looks like you have one for built-in render pipeline and one for SRP.

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?

anyway is work…but uglily

6150109–671794–decal.shader (1.08 KB)

Well, this means you can just change SV_Target to CoLoR in your code and it will work.

yes , use CoLoR replace SV_Target and keep the code is SV_Target for generate to glsl…great…

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

1 Like

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.

Thank you.
so,that’s mean i use both of them, rendering effeciency probably go down a lot.

Not really - depends on what is being rendered. MSAA 4x is usually not very expensive on mobile.