Shader function with custom defined return type
Asked Answered
P

16

0

I have a file called definitions.gdshaderinc that contains the following:

#define Number float

and on another file called functions.gdshaderinc I have the following:

#include "definitions.gdshaderinc"

Number ClampCosine(Number mu) {
  return clamp(mu, Number(-1.0), Number(1.0));
}

That produces the following error:

What am I doing wrong here?

Polyester answered 19/10, 2022 at 18:47 Comment(0)
C
0

Polyester I think I found a fix for this. Are your shaders located in a folder? If so try giving the full path to the include
#include "definitions.gdshaderinc" --> #include "YourShaderFolder/definitions.gdshaderinc"
I found this while I was also trying to port the Atmospheric scattering stuff into Godot

As for the error with assert, it's because glsl and gdshader doesn't have an assert function.
In Bruneton's atmosphere implementation, he actually combines the shader files in code (model.cc) and adds this to the top

#define IN(x) const in x
#define OUT(x) out x
#define assert(x)

This removes all the asserts and also changes the INs and OUTs into glsl versions.

Concinnous answered 25/10, 2022 at 4:16 Comment(0)
P
0

Polyester What am I doing wrong here?

Here about it.

The line:

#define Number float

must be replaced

uniform float Number = [value];

and:

#include 

should also be changed to something

Predilection answered 19/10, 2022 at 19:32 Comment(0)
P
0

Predilection This is not exactly what I intended the effect to be. I do not want Number to represent some float value. I just define Number as float, so I expect the preprocessor to replace it with float later on.

Polyester answered 19/10, 2022 at 20:39 Comment(0)
P
0

Polyester But replace "#define" with something that Godot understands. I just started studying shaders and can't say exactly yet.

The value can be redefined in the process.

I'm not really sure, but it looks like Godot requires a certain value. It can be changed afterwards.

UP. Сould try:

varying float Number;
Predilection answered 19/10, 2022 at 21:12 Comment(0)
B
0

I put your code into Godot 4.0 beta 3 and it all works fine.
Are you sure it's the define that's causing the problem? What's on line 56 (the error location)?

Biolysis answered 20/10, 2022 at 0:35 Comment(0)
P
0

Biolysis This is what's on line 56.

Polyester answered 20/10, 2022 at 2:10 Comment(0)
B
0

Strange. Mine doesn't have an error for that:

I'm doing the same thing. One gdshaderinc with the define, another gdshaderinc with the ClampCosine that includes the first file, then a gdshader file that includes the second file.

Which version of Godot are you using? Shader macros was a recent addition, its new enough that the 4.0 docs say it doesn't exist (they explicitly state GLSL macros like #define can't be easily ported to Godot). It's working for me in 4.0 beta 3 and 4.0 alpha 15, but it might be broken earlier than that.

Another idea: what does the end of definitions.gdshaderinc look like? Maybe there's a stray character or something that is coming in with the include and affecting the ClampCosine (since it's the first thing after the include that isn't a comment).

Biolysis answered 20/10, 2022 at 2:27 Comment(0)
P
0

Biolysis That's odd! Yes I'm on beta 3 as well. There isn't anything weird on the definitions,
Maybe I should start the project again, just to be sure.

Polyester answered 20/10, 2022 at 2:38 Comment(0)
P
0

Biolysis No, a completely new project with just the lines in question, still gives me the same error

Polyester answered 20/10, 2022 at 2:43 Comment(0)
B
0

Here's my test project.
(Not sure if zip uploads work...)

Nope, uploading worked but the file isn't visible.
So here's a link: https://www.dropbox.com/s/yewwk0cb5i37vh5/testshader2.zip?dl=0

Biolysis answered 20/10, 2022 at 3:26 Comment(0)
P
0

Biolysis Did you do anything else apart from defining those shaders?
You project is working, but mine, with the exact two files was not working yesterday.

Polyester answered 20/10, 2022 at 14:45 Comment(0)
B
0

I added a plane mesh to a new project, gave it a shader material, gave that a default shader, then copy pasted that file to make the two include files.

What kind of shader are you making? There's spatial (I used that), canvas and particle. Maybe only spatial is working and canvas or particle aren't complete yet.

Biolysis answered 20/10, 2022 at 15:5 Comment(0)
P
0

Biolysis I figured something out at least, In my .gdshaderinc files I want to use PI, but it does not exist, so I had to define it inside the definitions.gdshaderinc as such:

const float PI = 3.14159265358979323846f;

But it seems that PI is already defined in a .gdshader file so in your project I get

And oddly in mine (which is the exact same as yours only that I started it on my own from scratch) I get the same error as before inside functions.gdshaderinc.

btw: the error message is about line 121 because I copy pasted all the contents of my original definitions and functions in your respective shader files.

btw2: another, possibly unrelated issue, in your project if I decide to use an assert

Number ClampCosine(Number mu) {
  assert(1 <= 2);
  return clamp(mu, Number(-1.0), Number(1.0));
}

Then I get the following error:

I don't know if all these are bugs or what!

Polyester answered 20/10, 2022 at 15:30 Comment(0)
C
0

Polyester I think I found a fix for this. Are your shaders located in a folder? If so try giving the full path to the include
#include "definitions.gdshaderinc" --> #include "YourShaderFolder/definitions.gdshaderinc"
I found this while I was also trying to port the Atmospheric scattering stuff into Godot

As for the error with assert, it's because glsl and gdshader doesn't have an assert function.
In Bruneton's atmosphere implementation, he actually combines the shader files in code (model.cc) and adds this to the top

#define IN(x) const in x
#define OUT(x) out x
#define assert(x)

This removes all the asserts and also changes the INs and OUTs into glsl versions.

Concinnous answered 25/10, 2022 at 4:16 Comment(0)
P
0

Concinnous Are you also trying to port this in Godot. That's awesome. I'd definitely like to have a look at your work, or have someone to ask haha. This is a great learning exercise, after porting all the Shadertoy glitch shaders to godot.

Right now I am stuck at the use of TEMPLATE which is something I haven't seen before.

Polyester answered 29/10, 2022 at 19:28 Comment(0)
C
0

Polyester The one I'm porting is this. I think your one is also based on this. They also have a full documentation here which helps a lot.

TEMPLATE is also another function that gets removed by the preprocessor. Check out model.cc in the documentation link. In the line glsl_header_factory_ you can see the stuff being defined and removed by the preprocessor.

I'm not sure how well this will perform in gdshaders. You're going to have to use viewports and stuff to get a output from these. That's going to be especially difficult with the sampler3d for the scattering textures.

What I'm doing right now is implementing it in the new compute shaders. This let's me control when the shaders run instead of them running all the time like gdshaders. I can also store the output for later but It's a bit hard without any documentation.

Concinnous answered 29/10, 2022 at 22:13 Comment(0)
P
0

Concinnous That sounds interesting for sure. I need to try this myself, even though I'm a beginner in shaders.

Polyester answered 29/10, 2022 at 22:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.