[Solved] Can GLSL extensions be enabled in effects?

When trying to run my game on android, I tried to use ddx/ddy to compute the normal of 2D Perlin Noise. They calculate the gradient of a variable across a fragment. The central difference method I used on other platforms doesn’t look good because OpenGL ES 2.0 doesn’t support floating point textures. ddx and ddy translate to dFdx/dFdy and are only supported on GL ES 2.0 with the extension GL_OES_standard_derivatives. To enable an extension one has to use the GLSL preprocessor directive #extension.
Is it currently possible to use GLSL extensions in Monogame?

Wouldn’t it take less time to just try it instead of asking on the forum? At worst it will crash or not work at all.

There is no way to do this directly with MG, but you can build your effect for a GL platform and edit the built file by hand to add in the #extension directive. I think that should work.

Are you talking about XNB files or is there a way to edit the GLSL directly (If I understand the system correctly, an internal GLSL shader is generated from the fx file?). The shader in the XNB file is encoded, it did not work to add something there.
@darkhog Of course I tried to add it into the .fx file before, that doesn’t work.

Oh, this doesn’t work with the Pipeline Tool, I thought it did! You need to use 2MGFX.

There are 2 ways to build effects for MG runtime consumption. You can use the Pipeline Tool or you can use MonoGames effect building tool 2MGFX directly. That will write out the shader + metadata without the XNB header. It will be mostly readable GLSL (but variable names get mangled, so it looks very different from your HLSL shader). You can find 2MGFX in the MonoGame installation folder (the default path on Windows is C:\Program Files (x86)\MSBuild\MonoGame\v3.0\Tools\2MGFX.exe; you can add the tools folder to your PATH to run them from cmd without specifying the full path). To build your effect with 2MGFX you can run 2MGFX <SourceFile> <OutputFile> [Options], e.g. 2MGFX effect.fx effect.ogl.mgfxo /Profile:OpenGL to build your effect.fx file into effect.ogl.mgfxo. The output file should look something like this:

MGFX ʘâóvs_uniforms_vec4@     Æ   #ifdef GL_ES
precision mediump float;
precision mediump int;

varying vec4 vFrontColor;
#define ps_v0 vFrontColor
#define ps_oC0 gl_FragColor

void main()
    ps_oC0 = ps_v0;

   É  #ifdef GL_ES
precision highp float;
precision mediump int;

uniform vec4 vs_uniforms_vec4[4];
uniform vec4 posFixup;
#define vs_c0 vs_uniforms_vec4[0]
#define vs_c1 vs_uniforms_vec4[1]
#define vs_c2 vs_uniforms_vec4[2]
#define vs_c3 vs_uniforms_vec4[3]
attribute vec4 vs_v0;
#define vs_o0 gl_Position
attribute vec4 vs_v1;
varying vec4 vFrontColor;
#define vs_o1 vFrontColor

void main()
    vs_o0.x = dot(vs_v0, vs_c0);
    vs_o0.y = dot(vs_v0, vs_c1);
    vs_o0.z = dot(vs_v0, vs_c2);
    vs_o0.w = dot(vs_v0, vs_c3);
    vs_o1 = vs_v1;
    gl_Position.y = gl_Position.y * posFixup.y;
    gl_Position.xy += posFixup.zw * gl_Position.ww;
    gl_Position.z = gl_Position.z * 2.0 - gl_Position.w;

  vs_v0    vs_v1   WorldViewProjection                                                                    BasicColorDrawing P0     

You should be able to add an #extension directive in there. Good luck! :slight_smile:

Yes, the HLSL shaders are built into HLSL bytecode, which gets translated to GLSL.

Well that worked, but I had to change the shader length with a hex editor. To do it properly I think I you would have to modify the MGFX preprocessor. Anyways the gradients also have a far too low precision on android to be usable for me.

1 Like