Custom Postprocessing Shaders - in devbuilds now

Archive of the old editing forum
Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. This forum is archived - please use this set of forums to ask new questions.
User avatar
Nash
 
 
Posts: 17296
Joined: Mon Oct 27, 2003 12:07 am
Twitch ID: nashmuhandes
Github ID: nashmuhandes
Location: Kuala Lumpur, Malaysia

Re: [QZDoom] Custom Postprocessing Shaders - in devbuilds no

Post by Nash »

What am I supposed to do go get the custom PP before the built-in stuff? Where do I type in the beforebloom thing?
dpJudas
 
 
Posts: 2869
Joined: Sat May 28, 2016 1:01 pm

Re: [QZDoom] Custom Postprocessing Shaders - in devbuilds no

Post by dpJudas »

The third argument to to the hardwareshader line is the insertion point. Change scene to beforebloom, like this:

Code: Select all

hardwareshader postprocess beforebloom
{
   ...
}
User avatar
Nash
 
 
Posts: 17296
Joined: Mon Oct 27, 2003 12:07 am
Twitch ID: nashmuhandes
Github ID: nashmuhandes
Location: Kuala Lumpur, Malaysia

Re: [QZDoom] Custom Postprocessing Shaders - in devbuilds no

Post by Nash »

Okay, thanks.

Can anyone recommend me a really, really noob-tier, baby's first Hello World shader tutorial? I really have no idea where to even begin. =[
User avatar
Rachael
Admin
Posts: 12952
Joined: Tue Jan 13, 2004 1:31 pm
Discord: Rachael#3767
Twitch ID: madamerachelle
Github ID: madame-rachelle
Preferred Pronouns: She/Her

Re: [QZDoom] Custom Postprocessing Shaders - in devbuilds no

Post by Rachael »

Think of shaders basically as C++ (except a bit more simplified) and, in the case of PP shaders (or texture shaders) execute their function once on every single pixel per frame.

We've written a few samples and attached them in this thread - you can also review some of q/gzdoom.pk3's internal ones as well. Check the Graphic/Sound patches board, too - shader projects are starting to appear there, as well (even though there's only one at the moment).

Beyond that, I don't know how much more simplified it can get. :( I really recommend checking out dpJudas's health shader. It probably has one of the most clear and simple examples of how to get the GPU to manipulate the screen that I can think of. Beyond that, tell me what you want to accomplish and I may be able to help you.
User avatar
Rachael
Admin
Posts: 12952
Joined: Tue Jan 13, 2004 1:31 pm
Discord: Rachael#3767
Twitch ID: madamerachelle
Github ID: madame-rachelle
Preferred Pronouns: She/Her

Re: [QZDoom] Custom Postprocessing Shaders - in devbuilds no

Post by Rachael »

@Nash: A quick Google netted this: https://gamedevelopment.tutsplus.com/tu ... -cms-23313

I don't know how helpful it will be - let me know. :)
User avatar
Nash
 
 
Posts: 17296
Joined: Mon Oct 27, 2003 12:07 am
Twitch ID: nashmuhandes
Github ID: nashmuhandes
Location: Kuala Lumpur, Malaysia

Re: [QZDoom] Custom Postprocessing Shaders - in devbuilds no

Post by Nash »

Thanks... that tutorial is definitely a good start. I understand the concept of writing code to alter every single pixel on the screen, however I am still left confused with a lot of the basic fundamentals...

- What is TexCoord
- What is InputTexture
- What is vTexCoord and what does the .st member do (GZDoom's shaders use this a lot)
- What is the difference between Process, ProcessTexel, and Main functions

Also, the examples on the first page don't run with the latest QZDoom devbuild...

[Also, sorry to clutter this thread - feel free to split the noob questions off into it's own thread :D]
User avatar
Rachael
Admin
Posts: 12952
Joined: Tue Jan 13, 2004 1:31 pm
Discord: Rachael#3767
Twitch ID: madamerachelle
Github ID: madame-rachelle
Preferred Pronouns: She/Her

Re: [QZDoom] Custom Postprocessing Shaders - in devbuilds no

Post by Rachael »

I'll update the examples later on, then. Thanks for pointing it out.

InputTexture is the screen - in the state that it is in at the time that the shader is run.

That's the only question I know how to definitively answer, right now, but I assume TexCoord and vTexCoord are related to that. (You can try "FragColor = TexCoord/vec3(64);" and see what happens - if it works, remember you can alt-F4 to exit GZDoom since executing this shader will make the screen unusable - but the whole idea of doing that is to give you some idea what TexCoord does)
User avatar
Gutawer
User Accounts Assistant
Posts: 462
Joined: Sat Apr 16, 2016 6:01 am
Discord: Gutawer#3431
Preferred Pronouns: She/Her

Re: [QZDoom] Custom Postprocessing Shaders - in devbuilds no

Post by Gutawer »

I can answer the first two, and part of the 3rd - TexCoord is the coordinate of the current pixel (this isn't done in screen coordinates, instead it's bounded between 0 and 1 - 0 is the left/top of the screen, and 1 is the right/bottom of the screen). InputTexture is the texture being given to the shader, so in the case of the postprocessing shader, this is the screen - it is treated as a texture, as a sampler2D type, which you can sample pixels from using the texture() function. Not sure what vTexCoord is, but .st isn't really a member in the sense you'll be used to - it's a vec2 gotten by a feature of glsl called Swizzling - https://www.khronos.org/opengl/wiki/Dat ... #Swizzling, and relates to the texture mapping (which you'd be better off Googling than me explaining it, since I don't fully understand it myself :P - new to all this, too, heh) - GLSL vec4's have 4 sets of coordinates which do the same thing functionally, xyzw, stpq, and rgba, but are used in different contexts - xyzw for world coordinates (w is used with regards to projection, as I understand it), rgba for colors, and stpq for texture coordinates. It's just convention to use the "correct" set of coordinates for each job - you could use .xy or .rg for texture coordinates, and your shader would function identically.
dpJudas
 
 
Posts: 2869
Joined: Sat May 28, 2016 1:01 pm

Re: [QZDoom] Custom Postprocessing Shaders - in devbuilds no

Post by dpJudas »

Nash wrote: - What is TexCoord
- What is InputTexture
InputTexture is the 2D texture holding the framebuffer as it looked like just before the postprocess shader. TexCoord is a vec2 with the texture coordinate that you should use to sample from InputTexture. And FragColor is the output pixel that the framebuffer will get after the shader ran.
Nash wrote:- What is vTexCoord and what does the .st member do (GZDoom's shaders use this a lot)
GLSL vectors have 2 to 4 elements. You can refer to each element in various ways where it is the same value you are getting. For example, foobar.x, foobar.r, footbar.s and foobar.u are all the same variable. You can use any of them, but generally people use .xyz if its a position, .rgb if it is a color, .st or .uv if its a texture coordinate.

I chose to call the input variable holding the texture coordinate for TexCoord. Graf chose to call it vTexCoord. It is the same thing, just different names. But note that you cannot use the name vTexCoord in the PP shaders, and you can't use the TexCoord name in the material shaders.
Nash wrote: - What is the difference between Process, ProcessTexel, and Main functions
Now this requires a long answer. A real GLSL shader, as OpenGL wants it, looks like this:

Code: Select all

#version 330

in vec2 TexCoord;
out vec4 FragColor;

uniform sampler2D InputTexture;

layout(std140) uniform UniformBlock
{
    uniform float foobar;
    uniform float foobar2;
};

void main()
{
    FragColor = texture(InputTexture, TexCoord);
    FragColor.r = 1.0; // A very bloody PP shader!
    FragColor.g += foobar;
    FragColor.b += foobar2;
}
main is the function that OpenGL calls. When it returns OpenGL grabs the value in FragColor and stores that in the framebuffer.

However, because GZDoom needs to be able to run on OpenGL 2 to 4.5 it can't just hardcode the GLSL version to 330. The first line is therefore added in front of the shader code in the lump before it is passed along to OpenGL.

For similar reasons, the C++ code also declares all the uniforms for you. When you type 'uniform vec2 foobar' in the GLDEFS file the C++ code adds "uniform vec2 foobar" to the UniformBlock I listed above. This is required because the memory layout has to match what GZDoom puts into a memory buffer. By making the C++ autogenerate that code it is guaranteed that the layout will be valid and match what GZDoom uploads.

Anyway, so when all the autogenerated code is no longer in the lump, it ends up looking like this:

Code: Select all

void main()
{
    FragColor = texture(InputTexture, TexCoord);
    FragColor.r = 1.0; // A very bloody PP shader!
    FragColor.g += foobar;
    FragColor.b += foobar2;
}
For the GZDoom material shaders it gets even more complicated because the final GLSL file is actually a concatenation of several lumps: shaderdefs.i + main.fp + your_material_shader.fp. The shaderdefs.i lump contains the uniforms set by the GL scene drawer, the main.fp contains the main() function and does all light calculations. Somewhere while doing that it calls a function called ProcessTexel(), which is the code you placed in your_material_shader.fp. The general principle is the same, though: you write some parts of the shader, the engine adds the rest.

I hope I didn't scare you away with this answer. :p
User avatar
Gutawer
User Accounts Assistant
Posts: 462
Joined: Sat Apr 16, 2016 6:01 am
Discord: Gutawer#3431
Preferred Pronouns: She/Her

Re: [QZDoom] Custom Postprocessing Shaders - in devbuilds no

Post by Gutawer »

I feel it'd make sense to post my shader thread as a link here, as an example to anyone wanting learn and to use the system, with the way it works in QZD 2.0.0: viewtopic.php?f=46&t=57168
User avatar
Nash
 
 
Posts: 17296
Joined: Mon Oct 27, 2003 12:07 am
Twitch ID: nashmuhandes
Github ID: nashmuhandes
Location: Kuala Lumpur, Malaysia

Re: [QZDoom] Custom Postprocessing Shaders - in devbuilds no

Post by Nash »

Thank you for the very detailed information everyone, it will take some time for me to fully digest these. In the mean time, I have another question:

In Gutawer's examples, why is "timer" marked as placeholder? Isn't the timer available from the engine? I've seen timer used in the stock warp shaders. Are they not the same variable?
dpJudas
 
 
Posts: 2869
Joined: Sat May 28, 2016 1:01 pm

Re: [QZDoom] Custom Postprocessing Shaders - in devbuilds no

Post by dpJudas »

in the PP shaders there are no predefined variables except for TexCoord and InputTexture. Unlike the material shaders you can declare your own uniforms. If you want a timer uniform you have to declare and set it yourself.
User avatar
Rachael
Admin
Posts: 12952
Joined: Tue Jan 13, 2004 1:31 pm
Discord: Rachael#3767
Twitch ID: madamerachelle
Github ID: madame-rachelle
Preferred Pronouns: She/Her

Re: [QZDoom] Custom Postprocessing Shaders - in devbuilds no

Post by Rachael »

I was thinking of actually passing "timer" in as an official engine-managed uniform. Would this be an issue? (I should've done this before release...)
User avatar
Nash
 
 
Posts: 17296
Joined: Mon Oct 27, 2003 12:07 am
Twitch ID: nashmuhandes
Github ID: nashmuhandes
Location: Kuala Lumpur, Malaysia

Re: [QZDoom] Custom Postprocessing Shaders - in devbuilds no

Post by Nash »

Rachael wrote:I was thinking of actually passing "timer" in as an official engine-managed uniform. Would this be an issue? (I should've done this before release...)
IMO it would have been better to standardize the engine-managed uniforms... currently I think the material and PP shaders are quite disconnected from each other in terms of conventions... might cause a lot of confusion for users. Better to have both systems follow and provide the same basic fundamental principles, I think...
dpJudas
 
 
Posts: 2869
Joined: Sat May 28, 2016 1:01 pm

Re: [QZDoom] Custom Postprocessing Shaders - in devbuilds no

Post by dpJudas »

I could have created a tiny main function basically saying "void main() { FragColor = Process(texture(InputText, TexCoord)); }", but beyond that they have really nothing in common. Since you might not want to sample from the input texture in such a straightforward manner, even this forced similarity would only cause problems.

Of all the uniforms listed on the wiki only the timer uniform is relevant.

Always passing in a timer uniform could be done, of course.

Edit: @Rachael, if you decide to add a built-in 'timer' uniform, I'd personally do it by adding support for the "Speed <Value>" parameter in the hardwareshader block and only if a speed is declared will it create a timer uniform.

Return to “Editing (Archive)”