View Issue Details
|ID||Project||Category||View Status||Date Submitted||Last Update|
|0001726||NoesisGUI||C++ SDK||public||2020-06-17 01:24||2020-06-25 11:25|
|Target Version||Fixed in Version|
|Summary||0001726: Child elements clipped by stencil buffer when render transforms take a child out the bounds of the parent panel|
|Description||Hi guys, apologies for the long summary. I'm not sure that this is a bug, but it's a odd behaviour which acts differently between Blend and Noesis C++ API. I tried to report this as a forum post but it won't let me upload a ZIP file with a RenderDoc capture inside.|
I'm trying to debug an issue in our game. I've tried to reproduce the issue outside of our game and I've been unable to repro it in the XAML Toy / XAML Player. I've attached my attempts at trying to repro it so you get an idea what I'm trying to do.
Essentially I have an ItemsControl containing some number of items representing a grid of menu items. These menu items have a select / deselect storyboard. The select storyboard changes the render scale of the ContentControl to 5% larger than the normal value. These items normally butt up right to the edge of the panel container, which is just an ordinary grid. In our game the stencil buffer causes the elements to be clipped at the edge of the grid.
So I have had a look in RenderDoc, there are 2 draw calls at fault. The first call just draws a quad for the entire grid. It doesn't actually write anything anything in the pixel shader, but it writes to the stencil buffer with Pass Op being "Inc Wrap". The next draw call batch actually draws the elements on the grid (the buttons) with stencil Pass Op being "Keep". This is the test which fails because the stencil buffer is limited to the size of the grid container, and the individual children elements expand past the grid's bounds. I've attached an image of this stencil failure to give you a better idea. In the image you can see that the stencil buffer test pass where it shows in green, and fails where it is in red. The red area causes the texture to appear clipped at a harsh border. The stencil buffer is sized to the size of the grid which is the item panel template for the itemscontrol. The grid is *not* set to ClipToBounds. This all works fine in Blend. it scales outside the volume of the panel without any issues. My attempt at reproducing this in XamlPlayer also does not hit any issues with doing this, so I know it's not an issue with my XAML setup.
I've also taken a RenderDoc capture of my repro attempt in XamlPlayer. I'm attaching the RenderDoc output for this in the Zip as well. The major difference is that there is no first draw call which writes to the stencil buffer. The first draw call simply draws the ContentControl elements.
So my question is what causes batch state to be requested with a stencil state? Why is it that in our game it renders the grid item panel to the stencil buffer, but in XamlToy it doesn't need to do this? I was able to narrow it down to simplifying the DataTemplate of the individual items. My 5 buttons use 3 different data templates depending on the content on the buttons. If I make the DataTemplate use a single empty grid, it was fine. I added a text block to one of the data templates it was still fine. I added a text block to 2 DataTemplates and then the issue started happening. It basically seems really random. It seems that if I make the DataTemplates slightly complicated it'll require that the root ItemPanelTemplate write the bounds to the stencil buffer. What makes the API think it needs to write the batch using a stencil state. Our render device uses this property in RequestState:
if (batch.renderState.f.stencilMode == ....)
So just to clarify, what causes that property to be anything other than disabled for the outer grid?
My second question would be to see if there is any way I can override this or have it so the first call which renders the initial quad to the stencil buffer also take into account the child bounds so the stencil test won't fail when the children are drawn? So I'm guessing the vertices it uses for the bounds of the stencil bounds for the initial batch call uses the layout size for the root element. However, render transforms may cause child elements to clip outside the bounds of the parent element. Is there any way to change it so the bounds take the union of all render volumes to ensure that child elements are not clipped to the bounds of the parent layout volume? I know this is the correct behaviour if ClipToBounds is on, but I've double checked that the property is not set on any of the parent elements.
I hope that this all makes sense. Sorry for the wall of text.
|Tags||No tags attached.|
Oops, forgot to attach zip file.
stencil_buffer_clipping.zip (437,759 bytes)
UI elements get clipped (implemented using stencil) for various reasons:
- UIElement.Clip property, uses the specified geometry to clip contents of the element (I don't think you are using this).
- UIElement.ClipToBounds property, when enabled element content is clipped to element's bound rect (I don't think you are using this either).
- If any of Width/Height or MaxWidth/Height properties is set to a smaller than the desired size for the element it also clips element content to its bound rect.
- If element's final render size is bigger than the available size provided by its container then it also enables clipping to the available size rect. Margins and LayoutTransform affect the final render size and are taken into account when comparing against the available size.
All that logic is evaluated in FrameworkElement::GetLayoutClip() if you want to verify which one is being applied in your case. My guess is that the last one is what happens in your game. You can try to specify a smaller fixed width/heigh for that grid to see if clipping disappears. If you can share the xaml where that Grid is placed I can help identify what could be happening.
|2020-06-17 01:24||steveh||New Issue|
|2020-06-17 01:24||steveh||File Added: stencil_buffer_clipping.zip|
|2020-06-17 01:24||steveh||Note Added: 0006442|
|2020-06-18 21:00||sfernandez||Assigned To||=> sfernandez|
|2020-06-18 21:00||sfernandez||Status||new => assigned|
|2020-06-25 11:25||sfernandez||Status||assigned => feedback|
|2020-06-25 11:25||sfernandez||Note Added: 0006455|