Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Post processing shader system overhaul! #10362

Draft
wants to merge 33 commits into
base: master
Choose a base branch
from

Conversation

iwubcode
Copy link
Contributor

@iwubcode iwubcode commented Jan 8, 2022

TODO:

  • Fix OpenGL (somehow the last few weeks it became completely broken)
  • Support D3D12 multi output for compute shaders
  • Fix broken depth (screenshot is from old build)
  • Fix error reporting in UI
  • Allow saving profiles for shaders
  • Code cleanup

Have you ever cried into your pillow at night wishing that Dolphin used more of your GPU? Well hang on to your star bits because after a year (off and on) of development, a new system is here that might help you get your wish. That's right, the revamped post processing system is now up for review!

Note for reviewers: When I set out to write the new system, I didn't want to do things a little better. I didn't want to just match other software out there in terms of functionality. I wanted to punch-out the competition and set a new example for what you could do with enhancements in an emulator. So my apologies in advance for the large amounts of code, I am happy to split out into separate PRs.

Features

Configuration

The new system uses json for configuration to handle the structure needed to support all the new features.

{
	"meta":
	{
		"author": "iwubcode, Fubaxiusz",
		"description": "A shader that draws a color LUT (lookup-table)"
	},
	"options":
	[
		{
			"type": "int",
			"name": "_LutSize",
			"ui_name": "LUT Block Size",
			"min": [ 16.0 ],
			"max": [ 64.0 ],
			"default": [ 32.0 ]
		},
		{
			"type": "bool",
			"name": "LUT_VERTICAL",
			"ui_name": "LUT Vertical",
			"default": false,
			"is_constant": true
		}
	],
	"passes":
	[
		{
			"entry_point": "main",
			"inputs":
			[
				{
					"type": "previous_pass",
					"texture_filter": "linear",
					"texture_mode": "clamp"
				}
			]
		}
	]
}

Multiple Shaders

The first feature you may notice is that you can now have multiple shaders in one go. How you order the shaders affects the outcome:

shaders

Multiple Passes

Shaders can now use multiple passes. Each pass specifies a different entry point in the shader.

Depth

The biggest feature users ask for when they talk about shaders is leveraging depth effects and that is possible:

00000000_2021-12-04_00-09-38

Compute Shaders

The code supports general purpose compute shaders, here's an emboss effect done with compute:

tos_compute

Multiple Output

Shaders can be configured to output to multiple output textures. Output can then be accessed later on by name. This can be more performant than using multiple passes and makes porting from other systems easier.

Upscaling / Downscaling

Shaders internally support an "output scale" which allows the resulting image to be upscaled or downscaled.

UI

New controls

New controls have been added to support color selection or a list of options via a drop-down.

outline_shader

Images

Images can be defined by the shader, these images are not exposed to the user.

The shader can also define user images. This allows the user to modify them using a button to select the image. This control also supports drag and drop:

image_drag_drop

Grouped controls

Controls can be in a group, this puts them under a tab:

lightroom-shader

Lightroom inspired snapshots

You can load and save snapshots of options, so as to try out different presets to find what you are happy with.

snapshots

Tooltips

Tooltips can be defined for shader options:

tooltip

Adding Shaders

When adding a shader, you can pick from a system shader (which is categorized by 'type'):

shader-config-window-add

Or a user shader (with drag/drop capability).

Stereoscopic changes

Anaglyph and passive stereoscopic modes behaved strangely with the old system. Using one would set a shader in the post processing system, meaning you couldn't use any other shader. The new system applies anaglpyh or passive stereoscopic shaders after the general post processing shaders to ensure you can avoid your very own disaster, day of crisis.

anaglyph

Integrated with Graphics Mods

Graphics mods are now the way to access depth or trigger effects at certain points during the game rendering pipeline. An example below of using a bloom shader instead of the game's internal bloom.

No Graphics Mods:
arc-no-mods

Graphics Mods (Skip Bloom, Skip "fixup" bloom copy game does, custom 'pirate bloom' ported from Reshade with heavily exaggerated bloom):
arc-with-mods

@iwubcode iwubcode marked this pull request as draft January 8, 2022 22:20
@iwubcode iwubcode force-pushed the post-enhance-shader-system branch 3 times, most recently from 5ce0dc7 to 96d0634 Compare January 9, 2022 00:35
@Miksel12
Copy link
Contributor

Miksel12 commented Jan 9, 2022

Awesome to see this come to fruition! I did some brief testing and it looks awesome!
There was a crash when closing the game and D3D12 didn't like the shaders but that is to be expected from a wip pr.
Something that can be improved in the UI I think, is the trigger selection dropdown. It is currently located in a sub menu which makes it a bit of a chore to change. I don't see any reason to not place the dropdown on the main screen.

@iwubcode iwubcode force-pushed the post-enhance-shader-system branch 2 times, most recently from d368b25 to ff9b694 Compare January 9, 2022 01:38
@iwubcode
Copy link
Contributor Author

iwubcode commented Jan 9, 2022

Thank you for testing @Miksel12 !

There was a crash when closing the game and D3D12 didn't like the shaders but that is to be expected from a wip pr.

Crash on what backend? Also, what do you mean by D3D12 didn't like the shaders? Which one?

Something that can be improved in the UI I think, is the trigger selection dropdown. It is currently located in a sub menu which makes it a bit of a chore to change. I don't see any reason to not place the dropdown on the main screen.

Yeah, if I remember right, I think part of the reason might be for reuse but I can likely make it a combo box class that can be reused. Only advantage a separate dialog would provide is if we wanted to do something more advanced but I don't have any ideas at the moment.

@iwubcode iwubcode force-pushed the post-enhance-shader-system branch 2 times, most recently from 9e43b77 to 62ecc51 Compare January 9, 2022 07:55
@BhaaLseN
Copy link
Member

BhaaLseN commented Jan 9, 2022

Thoughts on adding a JSON schema for those descriptor files? See docs/game-mod-descriptor.json from #10187 and #10334 for an example.

Nothing more annoying than writing a file that looks correct but missing a level, letter or having some other typo that makes it invalid.

@Miksel12
Copy link
Contributor

Miksel12 commented Jan 9, 2022

Crash on what backend? Also, what do you mean by D3D12 didn't like the shaders? Which one?

D3D12 gives the error: "Create failed in ...VideoBackends\D3D12\DX12Texture.cpp at line 119: Create D3D12 texture resource" multiple times, after clicking ok on all of them, Dolphin crashes. This happens without any post processing enabled. W10, GTX 1060 on 497.09

@iwubcode
Copy link
Contributor Author

iwubcode commented Jan 9, 2022

D3D12 gives the error: "Create failed in ...VideoBackends\D3D12\DX12Texture.cpp at line 119: Create D3D12 texture resource" multiple times, after clicking ok on all of them, Dolphin crashes. This happens without any post processing enabled. W10, GTX 1060 on 497.09

Do you use D3D12 normally without issue? I am not able to reproduce that error.

I am able to reproduce some errors on shutdown. I am looking into those.

Thoughts on adding a JSON schema for those descriptor files?

I saw that and am not opposed to doing so but do we even have support for json validation?

@BhaaLseN
Copy link
Member

BhaaLseN commented Jan 9, 2022

Thoughts on adding a JSON schema for those descriptor files?

I saw that and am not opposed to doing so but do we even have support for json validation?

Main aspect is that the ones creating them get syntax completion and stuff, to help them get it right the first time. I don't think we validate the files as such (yet).

Validating them, or at least returning errors while reading is a plus though, but that can always come later to limit the scope of this PR (just like the schema itself; was mainly to bring it up, not necessarily to have it implemented in here if you want to defer it for later).

@iwubcode
Copy link
Contributor Author

iwubcode commented Jan 9, 2022

Makes sense. My plan was to add some documentation, though I wasn't sure if I'd do it as a subsequent PR as this one is already insanely large (assuming it isn't broken apart). I'll add a json schema too. I wasn't aware of that, some of my other projects also need it.

@Miksel12
Copy link
Contributor

Miksel12 commented Jan 9, 2022

Do you use D3D12 normally without issue? I am not able to reproduce that error.

Yes, D3D12 on master works without any problems.

@JMC47
Copy link
Contributor

JMC47 commented Jan 12, 2022

I'm stupid and dumb, so I don't really know how to make shaders, but in my use this is pretty cool.

@iwubcode iwubcode force-pushed the post-enhance-shader-system branch from 62ecc51 to 28ee4dc Compare January 25, 2022 03:07
@iwubcode
Copy link
Contributor Author

iwubcode commented Jan 25, 2022

Hmm, well thought I fixed OpenGL. In my local tests OGL is now working. Strange that buildbot says it isn't. Maybe OGL on AMD is less strict than OGL on other platforms. That's a shame.

However, I did fix the shutdown crash.

@iwubcode iwubcode force-pushed the post-enhance-shader-system branch 4 times, most recently from ba7b40b to bec8cb8 Compare January 29, 2022 19:47
@AaronBPaden
Copy link

Trying to see if I can port MAME's crt-geom-deluxe over using this new system. I don't really understand shaders but I can read code well enough to do a port job. Well unless it's too hard and I give up. 50/50 chances heh

But does this new system support vertex shaders? I think all the included shaders are fragment shaders, which is a problem I ran into last time I tried something similar with the old system.

@iwubcode
Copy link
Contributor Author

iwubcode commented Feb 6, 2022

Trying to see if I can port MAME's crt-geom-deluxe over using this new system. I don't really understand shaders but I can read code well enough to do a port job. Well unless it's too hard and I give up. 50/50 chances heh

Just full disclosure, I may remove or rename some of the shader functions that are currently exposed. I'm still thinking about the final "api".

But does this new system support vertex shaders? I think all the included shaders are fragment shaders, which is a problem I ran into last time I tried something similar with the old system.

It does not. A post process is done with a single quad (4 vertices). I take the same stance as the previous author who attempted to implement this, I don't really see any use cases where we need a vertex shader. Any effect should be doable with a fragment shader or compute shader.

If we really need vertex shader support for some use case, we can look into adding it at a later date.

@AaronBPaden
Copy link

Just full disclosure, I may remove or rename some of the shader functions that are currently exposed. I'm still thinking about the final "api".

OK, thanks for the heads up!

It does not. A post process is done with a single quad (4 vertices). I take the same stance as the previous author who attempted to implement this, I don't really see any use cases where we need a vertex shader. Any effect should be doable with a fragment shader or compute shader.

Oh yeah, maybe. Well like I said, my shader knowledge is limited. I would have thought that the geometry warping part would be done with a vertex shader, but I'm looking at it now in crt-geom-deluxe and it looks like it just does the standard thing and is just using the vertex shader to calculate some values that are sent to the fragment shader anyway.

So maybe it isn't necessary, as long as the fragment shader has access to enough information. But it would definitely make porting the other shaders that are around more straightforward.

Actually, looking at some files I have lying around I think I came to the conclusion before that I could just put everything in the fragment shader and the real issue I ended up having was with trying to combine multiple shaders into one file. This led to all kinds of fun and ultimately me just using a bilinear shader for Dolphin hehe.

Multiple passes should make this more manageable. I'm interested in seeing what I can do. I'll try and put together a demo.

@iwubcode
Copy link
Contributor Author

iwubcode commented Feb 6, 2022

Actually, looking at some files I have lying around I think I came to the conclusion before that I could just put everything in the fragment shader and the real issue I ended up having was with trying to combine multiple shaders into one file. This led to all kinds of fun and ultimately me just using a bilinear shader for Dolphin hehe.

Yes, there could be some more work to be done to share shader functions amongst multiple shaders. When porting a number of shaders, I didn't really need that but I could see how that would be beneficial. That may be something I look into in the future.

Multiple passes should make this more manageable. I'm interested in seeing what I can do. I'll try and put together a demo.

Looking forward to it. Let me know if you hit any major road blocks.

@AaronBPaden
Copy link

OK, I have a couple of quick ports done which I've published here.

I went ahead and ported CRT Lottes because it's simpler. It doesn't look great. If the emulator outputs to 480p you really need to pair your CRT shader with a shader that simulates interlacing I think to get good results. But it looks alright and it'll do for now for a demo.

I've did also port the lowpass filter from crt-geom-deluxe to give it a slight analog blur.

A couple problems I noticed:

  • The warping feature of CRT Lottes doesn't work here. If you change warpX and warpY you'll see that the edges become smudged, not rounded. Maybe you have some insight here?
  • Weirdly-ranged inputs seem to be broken in the options UI. The options in CRT Lottes that started negative always started at 0.0 in the UI. The lowpass settings which have large numbers also start at 0 and I can't change them at all in the UI.

A couple screenshots showing off (needs to be viewed full screen to see the scanline effect):

2022-02-06-20:26:51

2022-02-06-20:31:20

@iwubcode iwubcode force-pushed the post-enhance-shader-system branch from bec8cb8 to 35f5bde Compare February 7, 2022 05:56
@iwubcode
Copy link
Contributor Author

iwubcode commented Feb 7, 2022

I went ahead and ported CRT Lottes because it's simpler. It doesn't look great. If the emulator outputs to 480p you really need to pair your CRT shader with a shader that simulates interlacing I think to get good results. But it looks alright and it'll do for now for a demo.
I've did also port the lowpass filter from crt-geom-deluxe to give it a slight analog blur.

Great job on the demo. I ran your crt shader and had to make some changes because it didn't run on D3D. A couple minor comments about portability:

  • Use float3 instead of vec3, float2 instead of vec2, etc
  • HLSL doesn't like it when you do float2(0.5). If you intend to do float2, do float2(0.5, 0.5). There was one place I needed to introduce a variable because of that.

The warping feature of CRT Lottes doesn't work here. If you change warpX and warpY you'll see that the edges become smudged, not rounded. Maybe you have some insight here?

Not sure where this was ported from but you're dealing with textures on a quad outputted to the screen. Because of that, you will always have a square picture with distribution of the pixel data. Are you expecting black or some other color on the edges to make it look spherical? If so, you'd have to output that color at that offset.

I guess this was ported from some vertex shader. In that scenario, I guess a vertex shader would be useful, as you could actually bend the vertices into that form (and the background color would show behind). We don't have that luxury.

Weirdly-ranged inputs seem to be broken in the options UI. The options in CRT Lottes that started negative always started at 0.0 in the UI. The lowpass settings which have large numbers also start at 0 and I can't change them at all in the UI.

Thank for reporting that! I fixed that issue.

EDIT: also, you had an issue in your lowpass filter where the values weren't specified as an array, ex:

"max": 300.0,

should be

"max": [300.0],

…njunction with any custom post processing shaders
…r future adding or removing parameters with less code overhead
@TryTwo
Copy link
Contributor

TryTwo commented Jun 10, 2024

Seeing this mentioned again, the UI stuff is my most expected feature, as it opens up a whole lot to the end user. I would love a bit of an update on the progress and goals. I don't think it needs to be perfected, the stuff shown here years ago is enough to warrant its use.

@iwubcode
Copy link
Contributor Author

I would love a bit of an update on the progress and goals

Unfortunately, not much update right now. The main focus has been getting the custom shader solution cleaned up, graphics mods 2.0, as well as the graphics mod editor. Some of those features will impact post processing, which is why I stopped working on it in the first place.

Luckily, most of the difficult part of this PR (the graphics backend changes to Dolphin) have been merged to master in the last couple years. So there's really the post processing logic itself and the UI left.

Version 3 of post processing has the following tasks:

  1. Separate backends for different post processing sources. We'll still have Dolphin but we might support Reshade's API for instance. I haven't done much research here so it really depends on whether this is a good fit but I'd like to support other systems if possible.
  2. Initial implementation will be built against graphics mods and integrated into the editor using imgui. This system will be more geared toward modders and likely have more features available (named render targets from custom shaders, depth access, etc). Modders will have the ability to target when the post processing shader gets triggered (ex: replacement bloom for normal game bloom)
  3. Something similar to what is shown here will be done for users. Most likely it will be in qt. To reduce complexity, this will only allow post processing of the final color output (ex: color correction, scanline shaders, etc). This should mainly be UI work and some configuration, all the post processing functionality should be done by then. I hope this will largely be lift and shift from this implementation.

One outstanding feature I'd like to add to custom shaders that would be nice for post processing as well, is a library/include system. Not sure if I will tackle this first or wait until I'm further along.

My hope is to start on post processing v3 sometime this summer (late July or August) but things tend to take longer than I expect 😄 .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

6 participants