[Fixed] Usage of noise() GLSL functions

Bugs that have been investigated and resolved somehow.

Moderator: GZDoom Developers

Usage of noise() GLSL functions

Postby _mental_ » Tue Apr 30, 2019 7:13 am

GZDoom with Vulkan backend enables fails to start if mod uses a shader with noise() GLSL function.
According to spec, noiseX() functions were deprecated in OpenGL 4.4 and removed completely in GL_KHR_vulkan_glsl Vulkan extension.

For example, Doom Slayer Chronicles and Don't Play with Hell mods use shaders with noise2() function.
I attached a small sample based on the latter to avoid loading of 250+ MB mod.

For compatibility reasons, I think it's worth implementing those functions for Vulkan.
A minimal viable solution would be to return zero values from them.
There are several standalone implementations of GLSL noise generators.
Probably we can use one of them to provide a replacement better than naive.

Also, there is an unrelated problem with noise() functions which however may benefit from fixing the initial issue.
Apple's OpenGL implementation has a bug related to the mentioned functions.
It appeared that noise() causes significant performance drop even when used for a single drawcall.
Values returned from it seem bogus as well. No surprise here to be honest.
Attachments
glsl_noise.pk3
(9.34 KiB) Downloaded 4 times
_mental_
 
 
 
Joined: 07 Aug 2011

Re: Usage of noise() GLSL functions

Postby vsonnier » Tue Apr 30, 2019 9:50 am

Hi _mental_,
I wondered why this problem didn't shows up sooner. I had the same problem with Brutal Doom Black Edition v3.1d Final (same authors as the mod you mentioned) which likely use the same shaders.
(Disclamer: I know nothing of GLSL programing, Doom scripting, etc... at all)
I saw that such scripts are used through the file GLDEFS, and track their reference from here in the rest of BE mod.
Turns out grass.shader, trees.shader were not used (apparently) so I've defined a noise2 function local to them doing nothing, namely returning the argument itself.
There was another shader TP.shader which on the contrary was used.
I replaced its code with the following, after looking at the Internet:

Code: Select allExpand view
uniform float timer;
const float pi = 3.14159265358979323846;
const float Intensity = 0.4;

float rand(float xx)
{
    float x0 = floor(xx);
    float x1 = x0+1;
    float v0 = fract(sin (x0*.014686)*31718.927+x0);
    float v1 = fract(sin (x1*.014686)*31718.927+x1);         

   return (v0*(1-fract(xx))+v1*(fract(xx)))*2-1*sin(xx);
}

vec2 SineWave( vec2 p ){
//    float pi = 3.14159;
    float A = 0.15;
    float w = 10.0 * pi;
    float t = 30.0*pi/180.0;
   float x = p.x + p.y*tan( -0.5);
   float y = sin( w*x + t) * A;
   return vec2(p.x, p.y+y);
}
///////////////////////////////////// ADD NOISE2 REPLACEMENT //////////////////////
//self: https://www.shadertoy.com/view/4llcWn
//This shader mostly shows big LCG differences due to minor seed-precision differences.
//Than it "randomly" rants A LOT about "randomness", being more about noise than hash.

const float Phi=sqrt(5.)*.5+.5;//1.61; Phi-1=1/Phi , larger  root.
const float fha=14142.1356237; //most famous arbitiary amplitude fora hash what uses cos()

//maximum precision "gold noise", is "better" or "worse" depending on your bias==context.
float h12goldM(vec2 coordinate,float seed) {

   return fract(sin(dot(coordinate*seed,vec2(Phi,pi)))*fha);
}
 
//high precision "gold noise" , similar to from gold_noiseH()
// but it has LESS apparent diagonal lines, as these get lost with lower precision.
float h12goldH(vec2 coordinate,float seed) {

   return fract(sin(dot(coordinate*seed, vec2(1.61803398875,
                                           3.14159265359)))*fha);
}

vec2 noise2(in vec2 coordinate) {
   return vec2(h12goldM(coordinate, timer),
               h12goldH(coordinate, timer));
}
///////////////////////////////////////////////////////////////////////////////////////////

vec4 Process(vec4 color)
{
  vec2 t = gl_TexCoord[0].st;
  vec2 test = SineWave(vec2(rand(1.5),timer));
  t.x += Intensity * (cos( timer/test.x) * (1.0 - t.y)) * sin( t.x * pi * .5 );
  t.y += Intensity * (cos( timer/test.y) * (1.0 - t.x)) * sin( t.y * pi * .5 );
  t += noise2(t) * sin( pi * 0.5 *( timer* 1.5 ));
  return getTexel(t) * color;
}


The code above (//////) is from me using this as inpiration: https://www.shadertoy.com/view/4llcWn
I've no idea if it is correct, as any kind of meaning, or how it is copyrighted either.

According to GLDEFS I guess it is used for TelePorter rendering: TF0G[A-H]0 files, indeed PNG files are found in SPRITES/PARTICLES directory of the mod, and match the teleporter effects that can be seen in game.
Code: Select allExpand view
...
HardwareShader Sprite TFOGA0
{
   Shader "Shaders/TP.shader"
   Speed 1.0
}

HardwareShader Sprite TFOGB0
{
   Shader "Shaders/TP.shader"
   Speed 1.1
}

HardwareShader Sprite TFOGC0
{
   Shader "Shaders/TP.shader"
   Speed 1.2
}
...


So far it allowed me to run BE in Vulkan, but clearly a proper replacement would be better.
vsonnier
 
Joined: 11 Apr 2019
Github ID: vsonnier
Operating System: Windows 10/8.1/8 64-bit
Graphics Processor: nVidia (Modern GZDoom)

Re: Usage of noise() GLSL functions

Postby dpJudas » Thu May 02, 2019 12:13 pm

I guess since they've been removed in the vulkan glsl compiler it should be safe to just add an implementation of our own. For OpenGL I don't know if we should do something or not. In macOS it would be preferable to get the vulkan backend improved past OpenGL as Apple intends to remove OpenGL anyway.

Does anyone know why they were deprecated/removed? Kind of curious to know the reason.
dpJudas
 
 
 
Joined: 28 May 2016

Re: Usage of noise() GLSL functions

Postby _mental_ » Thu May 02, 2019 2:20 pm

Regarding noise functions for Vulkan, it’s mostly about how to choose proper implementation. Or to write our own, if no suitable one will be found.

As for macOS imperfect and now deprecated OpenGL, it’s OK to leave it as is. Vulkan renderer, however, is far from being stable here.
There are several known issues which I’m trying to solve, with zero progress so far. Most likely I’ll post a few bug reports soon.
_mental_
 
 
 
Joined: 07 Aug 2011

Re: Usage of noise() GLSL functions

Postby vsonnier » Wed May 08, 2019 10:21 am

Hello there,

Finally in the particular case of Brutal Doom Black Edition v3.1d Final, I simply replaced the noise2 function everywhere by this:
Code: Select allExpand view
vec2 noise2(in vec2 coordinate) {
    // do nothing.
    return coordinate;
}

even for the T(ele)P(ort).shader, where the "doing nothing" noise2 actually gave the closest results to the OpenGL version, while the more compicated one broke the teleport effect.
The simpler the better I suppose.
vsonnier
 
Joined: 11 Apr 2019
Github ID: vsonnier
Operating System: Windows 10/8.1/8 64-bit
Graphics Processor: nVidia (Modern GZDoom)

Re: Usage of noise() GLSL functions

Postby _mental_ » Wed May 08, 2019 2:58 pm

'Do nothing' noise functions should return zeroes instead of their arguments.
The return value(s) are always in the range [-1.0,1.0] ...
The return value(s) have an overall average of 0.0
_mental_
 
 
 
Joined: 07 Aug 2011

Re: Usage of noise() GLSL functions

Postby vsonnier » Thu May 09, 2019 3:16 am

_mental_ wrote:'Do nothing' noise functions should return zeroes instead of their arguments.
The return value(s) are always in the range [-1.0,1.0] ...
The return value(s) have an overall average of 0.0


Thanks! Returning a zero vector do not change the in-game appearence for the Teleport effect, which goal is (as far as I understand the TP.shader code) to
add some sinusoidal wobble to the texture, AND some noise on top of that.
At the end, the noise part looks invisible to the eye all the more that the whole frames are mostly transparent and take no more than few second or something to play during a teleport.
vsonnier
 
Joined: 11 Apr 2019
Github ID: vsonnier
Operating System: Windows 10/8.1/8 64-bit
Graphics Processor: nVidia (Modern GZDoom)

Re: Usage of noise() GLSL functions

Postby _mental_ » Thu May 09, 2019 3:27 am

I was thinking about fixing this with such dummy functions. However, I'm afraid that some purists will appear quickly to whine aloud and to blame me for screwing "everything".
_mental_
 
 
 
Joined: 07 Aug 2011

Re: Usage of noise() GLSL functions

Postby dpJudas » Thu May 09, 2019 4:37 am

Dummy functions are better than nothing as they will at least let people play a mod that used them.

I fear a full implementation would require binding some random texture or something along those lines. While always binding such a texture isn't too hard, make it part of descriptor set 0 (the "dynamic set"), I'm not sure how that will affect performance. Pretty annoying they used vulkan to get rid of things in glsl they didn't want to implement.
dpJudas
 
 
 
Joined: 28 May 2016

Re: Usage of noise() GLSL functions

Postby _mental_ » Thu May 09, 2019 4:50 am

GLSL deprecated these functions and conforming implementation should return zero(es).
The noise functions noise1, noise2, noise3, and noise4 have been deprecated starting with version 4.4 of GLSL. When not generating SPIR-V they are defined to return the value 0.0 or a vector whose components are all 0.0. When generating SPIR-V the noise functions are not declared and may not be used.

I think we can start with this dummy implementation because it complies with the spec ;) Is it OK to add these functions to shaders' header?
_mental_
 
 
 
Joined: 07 Aug 2011

Re: Usage of noise() GLSL functions

Postby dpJudas » Thu May 09, 2019 5:06 am

Ah, excellent. We can say we are just following the Vulkan standard if people complain. ;)

Adding the functions to the header should be fine - the compiler should optimize them away when they aren't called.
dpJudas
 
 
 
Joined: 28 May 2016

Re: Usage of noise() GLSL functions

Postby _mental_ » Thu May 09, 2019 5:31 am

Added in 7e998c2.
_mental_
 
 
 
Joined: 07 Aug 2011

Re: Usage of noise() GLSL functions

Postby Talon1024 » Thu May 09, 2019 5:38 am

On a related note, I had to remove/change a bunch of texture2D usages in WolfenDoom: Blade of Agony in order to get it to work with the Vulkan renderer.
Talon1024
 
 
 
Joined: 27 Jun 2016
Github ID: Talon1024
Operating System: Debian-like Linux (Debian, Ubuntu, Kali, Mint, etc) 64-bit
Graphics Processor: nVidia with Vulkan support

Re: Usage of noise() GLSL functions

Postby _mental_ » Thu May 09, 2019 6:01 am

For old mods this can be solved by patching shaders on runtime before compiling them. Although, this is unrelated issue, or rather feature suggestion.
_mental_
 
 
 
Joined: 07 Aug 2011

Re: Usage of noise() GLSL functions

Postby vsonnier » Thu May 09, 2019 8:23 am

_mental_ wrote:Added in 7e998c2.


Works for me thanks, tried on both GeForce 1050 Ti Mobile (API Vulkan 1.1) and Intel HD Graphics 630 integrated GPU. (API Vulkan 1.0)
vsonnier
 
Joined: 11 Apr 2019
Github ID: vsonnier
Operating System: Windows 10/8.1/8 64-bit
Graphics Processor: nVidia (Modern GZDoom)

Next

Return to Closed Bugs

Who is online

Users browsing this forum: No registered users and 1 guest