ptitSeb / gl4es

GL4ES is a OpenGL 2.1/1.5 to GL ES 2.0/1.1 translation library, with support for Pandora, ODroid, OrangePI, CHIP, Raspberry PI, Android, Emscripten and AmigaOS4.
http://ptitseb.github.io/gl4es/
MIT License
712 stars 160 forks source link

OpenMW's Post Processing #377

Open AbduSharif opened 2 years ago

AbduSharif commented 2 years ago

The OpenMW post processing merge request is in final review and testing stage, and while OpenMW Android port with the latest gl4es nightly can run with post processing on or off without glitches, and while gl4es meets the minimum requirements to get post processing shaders working, there's always shader compile errors for almost every shader?

What could possibly be the reason? Is the gl4es shader conversion strict? Or is it just prone to more compilation failures more often than on PC?

Here's an example post processing shader mod pack, Volumetric Clouds and Mist and FXAA: https://github.com/zesterer/openmw-volumetric-clouds

And here's the post processing merge request: https://gitlab.com/OpenMW/openmw/-/merge_requests/1124

To use the mod, your settings in settings.cfg should be like this:

[Post Processing]

# Enables post-processing 
enabled = true

# List of active shaders. This is more easily with the in-game shader HUD, by default accessible with the F2 key.
chain = clouds, fxaa

# Reload active shaders when modified on local filesystem. This is a DEBUG mode, and should be disabled in normal gameplay.
live reload = false

# Used for eye adaptation to control speed at which scene luminance can change from one frame to the next. No effect when HDR is not being utilized.
hdr exposure time = 0.1

# Transparent depth postpass. Re-renders transparent objects with alpha-clipping forced with a fixed threshold.
transparent postpass = true

Paste the shader pack into the Morrowind "Data Files" folder.

You can use F2 to open the post processing HUD.

Here are the errors I'm getting with that pack enabled:

[04:00:18.053 W] FRAGMENT glCompileShader "main" FAILED
[04:00:18.053 W] FRAGMENT Shader "main" infolog:
[04:00:18.053 W] 0:119: L0001: Expected literal or '(', got '^'
[04:00:18.053 W] 0:120: L0002: Undeclared variable 'n'
[04:00:18.053 W] 0:129: L0002: No matching function for call to 'trunc'
[04:00:18.053 W] 0:130: L0002: Undeclared variable 'z'
[04:00:18.053 W] 0:131: L0002: Undeclared variable 'z'
[04:00:18.053 W] 0:133: L0002: Undeclared variable 'offs0'
[04:00:18.053 W] glLinkProgram 0x7417f36d00"clouds" FAILED
[04:00:18.053 W] Program "clouds" infolog:
[04:00:18.053 W] Link failed because of invalid fragment shader.
[04:00:18.058 W] FRAGMENT glCompileShader "main" FAILED
[04:00:18.058 W] FRAGMENT Shader "main" infolog:
[04:00:18.058 W] 0:20: L0002: No matching function for call to 'texture'
[04:00:18.058 W] 0:21: L0002: No matching function for call to 'texture'
[04:00:18.058 W] 0:22: L0002: No matching function for call to 'texture'
[04:00:18.058 W] 0:23: L0002: No matching function for call to 'texture'
[04:00:18.058 W] 0:24: L0002: No matching function for call to 'texture'
[04:00:18.058 W] 0:25: L0002: Undeclared variable 'texColor'
[04:00:18.058 W] 0:27: L0002: Undeclared variable 'rgbNW'
[04:00:18.058 W] 0:28: L0002: Undeclared variable 'rgbNE'
[04:00:18.058 W] 0:29: L0002: Undeclared variable 'rgbSW'
[04:00:18.058 W] 0:30: L0002: Undeclared variable 'rgbSE'
[04:00:18.058 W] 0:31: L0002: Undeclared variable 'rgbM'
[04:00:18.058 W] 0:32: L0002: Undeclared variable 'lumaM'
[04:00:18.058 W] 0:33: L0002: Undeclared variable 'lumaM'
[04:00:18.058 W] 0:36: L0002: Undeclared variable 'lumaNW'
[04:00:18.058 W] 0:37: L0002: Undeclared variable 'lumaNW'
[04:00:18.058 W] 0:39: L0002: Undeclared variable 'lumaNW'
[04:00:18.058 W] 0:42: L0002: Undeclared variable 'dirReduce'
[04:00:18.058 W] 0:45: L0002: Undeclared variable 'rcpDirMin'
[04:00:18.058 W] 0:48: L0002: No matching function for call to 'texture'
[04:00:18.058 W] 0:50: L0002: Undeclared variable 'rgbA'
[04:00:18.058 W] 0:54: L0002: Undeclared variable 'rgbB'
[04:00:18.058 W] 0:55: L0002: Undeclared variable 'lumaB'
[04:00:18.058 W] 0:57: L0001: else statement not preceded by if
[04:00:18.058 W] glLinkProgram 0x7417f36e00"fxaa" FAILED
[04:00:18.058 W] Program "fxaa" infolog:
[04:00:18.058 W] Link failed because of invalid fragment shader.

Are there ways to work around this? And is there an environment variable to make gl4es send the shaders without conversion for testing?

ptitSeb commented 2 years ago

I need the actual shader sources. Use LIBGL_LOGSHADERERROR=1 to get shader sources (before and after transformation) that fail compilation or linking.

AbduSharif commented 2 years ago

I'll try to once I'm able to (I don't have a PC around currently).

So here are some findings, most of those shaders that failed to compile have "illegal GLSL" used, one of them (the FXAA one) relays on something that's usually used in the version 330, I assume GL4ES doesn't support that version?

AbduSharif commented 2 years ago

So here's another update, shaders that follow the version 120 should work fine, here's an example that worked after tweaking, Sunrays shader:

sunrays

Here's the shader, made by MGE XE and converted from HLSL to GLSL by two OpenMW developers (one of them who's the creator of the merge request, he made it work with GL4ES), it isn't optimized but was useful for testing: Sunrays.zip

AbduSharif commented 2 years ago

Forgot to mention, the FXAA shader errors can be fixed by just replacing texture with texture2D.

So the only remaining errors are from the clouds shader:

[03:02:44.661 W] 0:119: L0001: Expected literal or '(', got '^'
[03:02:44.661 W] 0:120: L0002: Undeclared variable 'n'
[03:02:44.661 W] 0:129: L0002: No matching function for call to 'trunc'
[03:02:44.661 W] 0:130: L0002: Undeclared variable 'z'
[03:02:44.661 W] 0:131: L0002: Undeclared variable 'z'
[03:02:44.661 W] 0:133: L0002: Undeclared variable 'offs0'
[03:02:44.661 W] glLinkProgram 0x77929ffb00"clouds" FAILED
[03:02:44.661 W] Program "clouds" infolog:
[03:02:44.661 W] Link failed because of invalid fragment shader.

Once I get the shader sources, I'll send them.

AbduSharif commented 2 years ago

So the clouds shader author replaced the non-supported "trunc" to "floor" as it seems fine, so the remaining errors are:

[06:55:49.952 W] FRAGMENT glCompileShader "main" FAILED
[06:55:49.952 W] FRAGMENT Shader "main" infolog:
[06:55:49.952 W] 0:119: L0001: Expected literal or '(', got '^'
[06:55:49.952 W] 0:120: L0002: Undeclared variable 'n'
[06:55:49.953 W] glLinkProgram 0x76f1aa1200"clouds" FAILED
[06:55:49.953 W] Program "clouds" infolog:
[06:55:49.953 W] Link failed because of invalid fragment shader.
glassmancody commented 2 years ago

To clarify these are not actual issues with GL4ES, the shaders are not written with GL4ES in mind so use things like bitwise operators and non-cost variables in global scope . Not sure what exactly needs to be done here, if anything.

AbduSharif commented 2 years ago

Can the bitwise operators be supported by GL4ES or not? IIRC you can declare the GL ES versions 300 es and 310 es with GL4ES, right?

Sisah2 commented 2 years ago

For current openmw postprocessing shaders it wil be usefull to initialize GL_EXT_shader_non_constant_global_initializers extension. I tried to add it in shaderconv as there are already others added this way .

const char* GLESUseShaderLod = "#extension GL_EXT_shader_texture_lod : enable\n"; Tmp = InplaceInsert(GetLine(Tmp, 1), GLESUseShaderLod, Tmp, &tmpsize);

But if i try to add that non const initializer this way, that inplaceInsert function add it to wrong place it seems, or overwrite precision and shader fail to compile :(

Any idea what is wrong?

Sisah2 commented 2 years ago

Basically doing this https://github.com/Sisah2/gl4es/commit/1f199df25a00811e63d3f110d94690fe1decf700 result in ` New Shader source:

version 100

extension GL_EXT_draw_buffers : enable

extension GL_OES_standard_derivatives : enable

extension GL_OES_texture_3D : enable

extension GL_EXT_shader_non_constant_global_initializers : enable

precision highp float; uniform highp mat4 _gl4es_IModelViewMatrix; uniform highp mat3 _gl4es_NormalMatrix; struct _gl4es_LightModelParameters { vec4 ambient; }; ` missing precision for int, but only in some shaders for some reason.

ptitSeb commented 2 years ago

enabling extension is fine, but happens when the extension is not supported? a workaround for GL_EXT_shader_non_constant_global_initializers is not trivial to write.

Sisah2 commented 2 years ago

Well enabling it this way failing for me in some shaders, it says "extension directive must occur before any non-preprocesor tokens in ESSL1" on phone, on pc that it cant be in middle of shader. Or it replace default precision :( . This extension is supported on my phone and work in shaders that dont get borked.

Sisah2 commented 2 years ago

Also if i add only one extension here, it seems to work, but if i try add second one it die :D

Sisah2 commented 2 years ago

I think i solved that, first i needed to bump headline to 6 and then gl_clip vertex get mixed to extensions list in vertex shader, so changed his line to headline instead of hardcoded 2 and it seems to work :)

But this can be workarounded by editing shaders, what we really need is texture3d support, bitwise operator for the most advanced shader currently (version 300+ cant be used with gles 2.0 context right? Even outside of gl4es), and writing to gl_fragData[x] there must be some isdue with it in gl4es as using it broke terrain blending and other stuff).

AbduSharif commented 2 years ago

I think having this extension exposed even with an environment variable for supported devices would be great, it was really really nice not having to edit the shaders to accommodate for the function that can be used with just enabling the extension. Would be easier than patching GL4ES or using a fork just to enable it too.

AbduSharif commented 2 years ago

I'm talking about this particular extension: https://opengles.gpuinfo.org/listreports.php?extension=GL_EXT_shader_non_constant_global_initializers