ZeroK-RTS / Zero-K

Open source RTS game running on the Spring/Recoil engine
https://zero-k.info
GNU General Public License v2.0
683 stars 204 forks source link

Update outline widget #3574

Closed GoogleFrog closed 8 months ago

GoogleFrog commented 5 years ago

ivand has written shader based unit outlines: https://github.com/beyond-all-reason/Beyond-All-Reason/blob/master/luaui/Widgets_BAR/gfx_outline.lua

The old widget should remain as an automatic fallback for players without the requisite shader abilities.

dvr333 commented 5 years ago

I was actually thinking about this exact implmentation, but I had two concerns:

Does this work underwater with all Refraction and Reflection settings?

Does this also make rocks and trees get outlines?

lhog commented 5 years ago

Does this work underwater with all Refraction and Reflection settings?

That is actually a very good remark by @dvr333 and I wasn't sure how it behaved before I checked. Currently outline seems to ignore other effects of top, such as shields, water, smoke particles screen00760 screen00761

I'm not sure it's desired, also I'm not sure if I can change much to the way it behaves.

Does this also make rocks and trees get outlines?

The widget can be configured to skip certain "materials", where material is defined by material index: https://github.com/beyond-all-reason/Beyond-All-Reason/blob/master/materials/Shaders/default.lua#L364 https://github.com/beyond-all-reason/Beyond-All-Reason/blob/master/materials/1_normalmapping.lua#L30 https://github.com/beyond-all-reason/Beyond-All-Reason/blob/master/luaui/Widgets_BAR/Shaders/outlineShape.frag.glsl#L26

The current ZK CUS and default CUS shader are very close to what BAR has, so implementing these changes should require ~10 LoC across several files.

dvr333 commented 5 years ago

Awesome, that looks perfect.

I suppose if you wanted it to respect shields/fog/smoke you could write a depth value and have that preserved across the blurring, but I'm not sure how well that would work in the first place.

GoogleFrog commented 5 years ago

Smoke and underwater outlines could look fine. Is the thickness of the line able to be modified on the fly? The current widget has some settings that slightly reduce the thickness of the line when you zoom out.

I was also unable to get the BAR widget working myself.

lhog commented 5 years ago

I suppose if you wanted it to respect shields/fog/smoke you could write a depth value and have that preserved across the blurring, but I'm not sure how well that would work in the first place.

Yeah, same idea came to my mind. However, this will require carrying second buffer across blur process, so twice bandwidth and blurring non-linear depth values will unlikely give precise results.

Smoke and underwater outlines could look fine. Is the thickness of the line able to be modified on the fly? The current widget has some settings that slightly reduce the thickness of the line when you zoom out.

This is something new. Indeed ZK version of original widget has some scaling code. It is wrong, but should do its job unless camera is heavily tilted. The correct solution requires access to correct depth information for the outline pixels, so same problem as above.

I was also unable to get the BAR widget working myself.

I'm going to try my luck with https://github.com/ZeroK-RTS/Zero-K/issues/3556 in the next days. Since outline, api_CUS and https://github.com/ZeroK-RTS/Zero-K/issues/3556 are interwined, I can fix outline along the way.

GoogleFrog commented 5 years ago

This is something new. Indeed ZK version of original widget has some scaling code. It is wrong, but should do its job unless camera is heavily tilted. The correct solution requires access to correct depth information for the outline pixels, so same problem as above.

This harks back to our old disagreement over perfection vs. practicality. The camera height scaling does what it needs to do and works in common cases.

The height scaling is intended the counteract the illusion that the outlines thicken as you zoom out. The thickening is an illusion caused by the expectation of perspective when zooming in or out (since the units change size). The weird magic scaling function is a result of me adding tweaks until zooming no longer made me nauseous. I think I experienced something similar to trypophobia.

lhog commented 5 years ago

This harks back to our old disagreement over perfection vs. practicality. The camera height scaling does what it needs to do and works in common cases.

No problem. I'm in for whatever works. Anyway I can't get the perfect solution cheaply.

The height scaling is intended the counteract the illusion that the outlines thicken as you zoom out. The thickening is an illusion caused by the expectation of perspective when zooming in or out (since the units change size). The weird magic scaling function is a result of me adding tweaks until zooming no longer made me nauseous. I think I experienced something similar to trypophobia.

I agree. This option is useful indeed.

GoogleFrog commented 5 years ago

image

This requires Spring 104-1244

lhog commented 5 years ago

We could use one of the intermediate implementation options I have gone through. Though they all lacked something to for my liking:

The one on the screenshots had "always on" strong outline, which I later replaced with "two phase" outline: one phase is strong, but is getting affected by water, smoke, etc, the other phase is like 20% strength, but always on. These two blended together gave very good effect, except two unfortunate things: ghosting, because they used previous drawframe information (due to unavailability of the key engine callin, the thing we solved in 1244) and sieve like patters on the edge of the model.

To resolve the latter, I changed implementation to depth based hack. Sadly this hack produced artifacts on unrelated objects, so I yesterday I changed implementation once again. Right now I need to polish it a little bit.

So all in all, there are two options really:

I'm not taking back my promise to upgrade ZK CUS and features highlight (which is far worse offender IMO), just haven't had enough energy and concentration yet.

lhog commented 5 years ago

I've ported the current version of BAR shader to ZK and made several changes to CUS shaders and materials.

However around half of the units still do not receive outline. This means that not every unit is drawn by means of custom unit shaders. It's not good, because single shader within CUS framework guarantees consistent look across units.

screen00798

https://github.com/ZeroK-RTS/Zero-K/pull/3583

lhog commented 5 years ago

I've added fallback materials to my branch of ZK (not committed yet), so all units have their own custom shader drawer. Looks more or less ok, except for 3do models:

screen00801

I'm digging info myself, but I'd be great if someone, who knows what 3do is, explained me how to get their texture(s) and what their meaning is.

EDIT: Nvm, everything is cool, all units got their deferred outlines.

GoogleFrog commented 5 years ago

Looks like good progress. I'd assume many of the models didn't receive the shader because they lack normals.

GoogleFrog commented 5 years ago

Apparently a version which draws around terrain should be found around here: https://github.com/beyond-all-reason/Beyond-All-Reason/blob/05ad3c1d599163bd79e4e2d6125f8810f5c134a9/luaui/Widgets_BAR/gfx_outline.lua

sprunk commented 4 years ago

Looks done (unless @lhog has some further plans stashed).