Usage of noise() GLSL functions

Bugs that have been investigated and resolved somehow.

Moderator: GZDoom Developers

Forum rules
Please don't bump threads here if you have a problem - it will often be forgotten about if you do. Instead, make a new thread here.
_mental_
 
 
Posts: 3812
Joined: Sun Aug 07, 2011 4:32 am

Usage of noise() GLSL functions

Post by _mental_ »

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 57 times
User avatar
vsonnier
Posts: 80
Joined: Wed Apr 10, 2019 11:22 pm
Graphics Processor: nVidia with Vulkan support
Contact:

Re: Usage of noise() GLSL functions

Post by vsonnier »

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 all

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 all

...
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.
dpJudas
 
 
Posts: 3040
Joined: Sat May 28, 2016 1:01 pm

Re: Usage of noise() GLSL functions

Post by dpJudas »

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.
_mental_
 
 
Posts: 3812
Joined: Sun Aug 07, 2011 4:32 am

Re: Usage of noise() GLSL functions

Post by _mental_ »

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.
User avatar
vsonnier
Posts: 80
Joined: Wed Apr 10, 2019 11:22 pm
Graphics Processor: nVidia with Vulkan support
Contact:

Re: Usage of noise() GLSL functions

Post by vsonnier »

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 all

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.
_mental_
 
 
Posts: 3812
Joined: Sun Aug 07, 2011 4:32 am

Re: Usage of noise() GLSL functions

Post by _mental_ »

'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
User avatar
vsonnier
Posts: 80
Joined: Wed Apr 10, 2019 11:22 pm
Graphics Processor: nVidia with Vulkan support
Contact:

Re: Usage of noise() GLSL functions

Post by vsonnier »

_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.
_mental_
 
 
Posts: 3812
Joined: Sun Aug 07, 2011 4:32 am

Re: Usage of noise() GLSL functions

Post by _mental_ »

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".
dpJudas
 
 
Posts: 3040
Joined: Sat May 28, 2016 1:01 pm

Re: Usage of noise() GLSL functions

Post by dpJudas »

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.
_mental_
 
 
Posts: 3812
Joined: Sun Aug 07, 2011 4:32 am

Re: Usage of noise() GLSL functions

Post by _mental_ »

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?
dpJudas
 
 
Posts: 3040
Joined: Sat May 28, 2016 1:01 pm

Re: Usage of noise() GLSL functions

Post by dpJudas »

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.
_mental_
 
 
Posts: 3812
Joined: Sun Aug 07, 2011 4:32 am

Re: Usage of noise() GLSL functions

Post by _mental_ »

Added in 7e998c2.
Talon1024
 
 
Posts: 374
Joined: Mon Jun 27, 2016 7:26 pm
Preferred Pronouns: He/Him
Graphics Processor: nVidia with Vulkan support
Contact:

Re: Usage of noise() GLSL functions

Post by Talon1024 »

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.
_mental_
 
 
Posts: 3812
Joined: Sun Aug 07, 2011 4:32 am

Re: Usage of noise() GLSL functions

Post by _mental_ »

For old mods this can be solved by patching shaders on runtime before compiling them. Although, this is unrelated issue, or rather feature suggestion.
User avatar
vsonnier
Posts: 80
Joined: Wed Apr 10, 2019 11:22 pm
Graphics Processor: nVidia with Vulkan support
Contact:

Re: Usage of noise() GLSL functions

Post by vsonnier »

_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)
Post Reply

Return to “Closed Bugs [GZDoom]”