Ticket #434 (closed enhancement: fixed)

Opened 3 years ago

Last modified 23 months ago

[PATCH] Don't render transparent objects twice

Reported by: Philip Owned by: philip
Priority: Nice to Have Milestone: Alpha 7
Component: Core engine Keywords:
Cc: peter_ym_account

Description

CRenderer::RenderSubmissions() calls RenderTransparentModels() twice, once before drawing water and once after, so that underwater transparent models will blend properly.

That seems like a terrible idea. We have lots of transparent objects (trees) so it will kill performance; and the overdraw makes transparent objects look different, so when we fix the performance bug all the art will be wrongly calibrated.

Possible temporary solution: don't support transparent objects underwater. Possible better solution: do the overdraw only on models which intersect the water plane. Ideal solution: render transparent objects correctly always (but I don't know how that'd be implemented).

Attachments

singlerender.jpg (50.4 KB) - added by peter_ym_account 3 years ago.
Single render transparent objects screenshot
doublerender.jpg (52.7 KB) - added by peter_ym_account 3 years ago.
double render transparent objects (current behavior) screenshot
water.434.patch (2.2 KB) - added by peter_ym_account 3 years ago.
2nd try: changes transparent objects rendering behavior so they are rendered only once; except for the underwater portion when fancy water is disabled
waterblend.jpg (61.8 KB) - added by Philip 3 years ago.
blending at edge of water

Change History

Changed 3 years ago by peter_ym_account

Single render transparent objects screenshot

Changed 3 years ago by peter_ym_account

double render transparent objects (current behavior) screenshot

comment:1 Changed 3 years ago by peter_ym_account

As Philip reported, and illustrated in the screenshots, transparent objects are twice as opaque when rendered twice. Underwater objects appear to render correctly with only a single post-water render when fancy water is enabled; so maybe the underwater transparency double-rendering is only necessary when fancy water is disabled.

comment:2 Changed 3 years ago by peter_ym_account

It looks like rendering the transparent objects before plain water, but after fancy water lets us get away with only rendering them once; the attached patch makes this change. Can anyone confirm whether the patch works, thanks.

comment:3 Changed 3 years ago by fcxSanya

  • Keywords review added

peter_ym_account you can add the "review" keyword (like I did it) when you want that someone to checked your patch. Usually Philip does it in the next few days.

comment:4 Changed 3 years ago by peter_ym_account

  • Keywords review removed

removing review keyword for now -- it seems alpha blending over water with fancy water disabled is not quite right with this patch.

Changed 3 years ago by peter_ym_account

2nd try: changes transparent objects rendering behavior so they are rendered only once; except for the underwater portion when fancy water is disabled

comment:5 Changed 3 years ago by peter_ym_account

  • Keywords review added

I updated the patch - it now blends correctly in both fancy/plain water cases. Transparent objects are only rendered once, after the water, except when fancy water is disabled. When fancy water is disabled, a clipping plane is used to overdraw only the underwater portion (before the water).

As Philip mentioned, this means transparent objects everywhere will no longer look twice as opaque, which may require recalibrating art.

Critical feedback is appreciated! thanks

Changed 3 years ago by Philip

blending at edge of water

comment:6 follow-up: ↓ 20 Changed 3 years ago by Philip

  • Keywords review removed

Thanks, seems mostly good - the clipping planes sound useful here.

I think this introduces a problem where fancy water uses alpha blending, mainly around the edges where it meets terrain. In the attachment there's some (white) terrain and a partially-submerged bush - the left screenshot is with this patch, the right screenshot is with the if (!m_WaterManager->WillRenderFancyWater()) line removed (so it renders twice). The left one cuts off too suddenly at the water, which isn't nice. (In deeper water it's okay because it's rendering the refraction texture instead of blending.)

With fancy water disabled, the patch seems to actually reduce performance slightly, since it's still rendering as many polygons as before but now it's got the clipping plane too. Since the goal is to improve performance, that seems important to fix. I guess what we could possibly do is:

  • Model.h could add flags MODELFLAG_ABOVEWATER, MODELFLAG_BELOWWATER
  • Something like CModel::ValidatePosition (not sure if that's a great place) could set one or two of those flags, depending on whether the bounding box intersects the water plane.
  • CRenderer::RenderTransparentModels can pass a flag filter to Render.
  • Then the pre-/post-water calls to RenderTransparentModels can tell it to filter out objects that aren't (at least partially) below/above the water. (Also the reflection and refraction code can then filter out objects on the wrong side of the water, so this seems useful for more than just transparent objects.)

comment:7 Changed 3 years ago by anonymous

  • Milestone Unclassified deleted

Milestone Unclassified deleted

comment:8 Changed 3 years ago by wacko

  • Owner set to peter_ym_account
  • Milestone set to Backlog

comment:9 Changed 3 years ago by peter_ym_account

thanks for the feedback! I'll have to revisit the approach.

comment:10 Changed 3 years ago by fabio

  • Milestone changed from Backlog to Alpha 3

comment:11 Changed 2 years ago by k776

  • Milestone changed from Alpha 3 to Alpha 4

comment:12 Changed 2 years ago by k776

  • Priority changed from major to minor

comment:13 Changed 2 years ago by k776

  • Owner peter_ym_account deleted

comment:14 Changed 2 years ago by k776

  • Summary changed from Don't render transparent objects twice to [PATCH] Don't render transparent objects twice

comment:15 Changed 2 years ago by k776

  • Keywords review added

comment:16 Changed 2 years ago by Philip

  • Keywords review removed
  • Milestone changed from Alpha 4 to Alpha 5

Reviewed already - I think we need to do something roughly like in my earlier comment.

(Moving to Alpha 5 since that might be a good time to sort out these graphics things.)

comment:17 Changed 2 years ago by k776

  • Priority changed from Nice to Have to Should Have

comment:18 Changed 2 years ago by k776

  • Cc peter_ym_account added
  • Owner set to peter_ym_account

comment:19 Changed 2 years ago by k776

  • Milestone changed from Alpha 5 to Alpha 6

comment:20 in reply to: ↑ 6 Changed 2 years ago by Philip

Replying to Philip:

Model.h could add flags MODELFLAG_ABOVEWATER, MODELFLAG_BELOWWATER. Something like CModel::ValidatePosition (not sure if that's a great place) could set one or two of those flags, depending on whether the bounding box intersects the water plane.

I don't think that's a good idea now - we ought to add a decent culling system so we can find all objects in the frustum below the water, render them, find all the ones above, render them, etc, instead of special-casing this with extra flags. (The culling system is probably mostly a separate task from this.)

comment:21 Changed 23 months ago by k776

  • Milestone changed from Alpha 6 to Alpha 7

comment:22 Changed 23 months ago by k776

  • Priority changed from Should Have to Nice to Have

comment:23 Changed 23 months ago by k776

  • Owner changed from peter_ym_account to philip

comment:24 Changed 23 months ago by k776

  • Type changed from task to enhancement

comment:25 Changed 23 months ago by philip

  • Status changed from new to closed
  • Resolution set to fixed

(In [9814]) Graphics optimisations and features from eihrul. Add shadow filtering (PCF) option. Fix ugly shadow saturation in old lighting mode. Fix fancy water shader. Fix camera matrix computation. Support scissoring of camera frustum. Optimise vertex skinning. Inline various matrix functions. Support filtering of the list of submitted models before a rendering pass, for more precise culling. Optimise water renderer (fixes #721, based on patch by ortalo). Use scissoring when generating reflection/refraction textures. Skip reflection/refraction texture generation when no water is visible. Render alpha-blended objects differently (fixes #434). Reduce shadow swimming effects.

Note: See TracTickets for help on using tickets.