Pdr
Topic Author
Posts: 8
Joined: 29 Sep 2025, 16:31

BeginOffscreenRender

05 Nov 2025, 11:45

Hi.
Just updated the SDK to 3.2.10 from 3.2.7
Now I'm not getting BeginOffscreenRender() invoked when doing view->GetRenderer()->RenderOffscreen();
Is this intended? I'm relying on the Begin/End functions to setup and dispatch our internal render contexts which are being filled out of the other functions called during a render (UpdateTexture, CreateRenderTarget, DrawBatch etc)
 
User avatar
jsantos
Site Admin
Posts: 4823
Joined: 20 Jan 2012, 17:18
Contact:

Re: BeginOffscreenRender

05 Nov 2025, 12:00

I am checking the code, and it should be called only if the offscreen pass is needed:
// --- Offscreen ---
if (needsOffscreen)
{
    NS_PROFILE_CPU("Tree/FlushOffscreen");
    mTree->GetContext()->ClearStereoMatrices();
    mTree->GetDevice()->BeginOffscreenRender();
    mTree->GetContext()->Flush();
    mTree->GetDevice()->EndOffscreenRender();
}
The following XAML requires offscreen. Could you check with it?
<Grid
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid.Background>
        <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
            <GradientStop Offset="0" Color="White"/>
            <GradientStop Offset="1" Color="Blue"/>
        </LinearGradientBrush>
    </Grid.Background>
    <Viewbox>
        <Grid Margin="40">
            <Rectangle Fill="Red" Width="200" Height="120"/>
            <Grid Width="280" Height="80" Background="Yellow" Opacity="0.6">
                <Rectangle Fill="Lime" Width="300" Height="50" Opacity="0.8" RenderTransformOrigin="0.5,0.5">
                    <Rectangle.RenderTransform>
                        <RotateTransform Angle="90"/>
                    </Rectangle.RenderTransform>
                </Rectangle>
            </Grid>
        </Grid>
    </Viewbox>
</Grid>
 
Pdr
Topic Author
Posts: 8
Joined: 29 Sep 2025, 16:31

Re: BeginOffscreenRender

05 Nov 2025, 12:19

It's not being called using that Xaml.
When calling view->GetRenderer()->RenderOffscreen(); I'm getting a call to CreateRenderTarget (which in our implementation requires Begin to have been called before, as it used to be in the last version.
I don't know if it's changed so Begin/End is only called if any DrawBatch'es are going to be issued, but I used it to setup our engine's render and resource-contexts which we use to create and update resources, as well as rendering stuff with. So if this is the case then I'll have to rethink that whole thing instead.

Edit: Yeah, after fiddling around a bit I see that CreateRenderTarget, and UpdateTexture are being called before and after the Begin/End respectively. It's fine I guess, and probably what would be expected. I actually prefer that as now I can safely flush any RenderTarget creation before doing the DrawBatch, which was a problem before.
 
User avatar
jsantos
Site Admin
Posts: 4823
Joined: 20 Jan 2012, 17:18
Contact:

Re: BeginOffscreenRender

05 Nov 2025, 13:31

In versions 3.2.9 and 3.2.10, we introduced improvements designed to simplify renderer implementations:

- UpdateTexture is no longer invoked in the middle of a render pass. For example, this significantly simplified our Vulkan and Unreal renderers.
- Resource creation calls (such as LoadTexture) no longer occur inside UpdateRenderTree. These operations have been moved to RenderOffscreen (but outside Begin/End), where implementations can rely on the command buffer being ready for new commands
 
Pdr
Topic Author
Posts: 8
Joined: 29 Sep 2025, 16:31

Re: BeginOffscreenRender

06 Nov 2025, 11:52

Is there any other big changes that have occured between 3.2.7 and 3.2.10?

The exact same implementation I have now works fine on 3.2.7, and not at all on 3.2.10.
I am using a slightly modified version of the Styles.xaml from the samples.
On 3.2.7 everything works as intended, but on 3.2.10 I'm not even getting any DrawBatch invokations, no nothing, no resources are being setup or anything.

The implementation is sort of this:
Mainthread:
view->Update(time)

RenderThread:
(Early in the frame)
if(view->GetRenderer()->UpdateRenderTree()) {
   view->GetRenderer()->RenderOffscreen();
}
(Dispatch whatever commands was issued)

.. later in frame ..

view->GetRenderer()->Render();
(Dispatch issued commands during regular render pipeline)
When I flip the SDK back to 3.2.7 everything works as expected, I'm getting calls to CreateRenderTarget, MapVertices, DrawBatch in my implementation of the RenderDevice, but when I switch to 3.2.10 SDK all that stops. I'm getting no calls to Begin/EndOffscreenRender, I am getting calls to Begin/EndOnscreenRender, but nothing else in between. Not getting any Noesis error printouts either. What am I missing here?
 
User avatar
jsantos
Site Admin
Posts: 4823
Joined: 20 Jan 2012, 17:18
Contact:

Re: BeginOffscreenRender

06 Nov 2025, 14:34

We should emphasize this more clearly in the documentation: RenderOffscreen() must always be called before Render() whenever you plan to render. You can't skip it. The reason is that Render() is executed inside a render pass, so at that point it's too late to perform certain calculations in a optimal way. We use the offscreen phase for that (like UpdatingTextures). This has always been the requirement, but starting in 3.2.9 we introduced some optimizations that rely on this assumption.

A typical frame workflow should look like this:
  • On each update in the main thread, enqueue an UpdateRenderTree on the render thread.
  • For each new frame rendered on the render thread:
    • Call RenderOffscreen() before binding your render target
    • Start your render pass
    • Render your 3D world
    • Call Noesis Render()
    • Keep rendering more 3D world if needed, depending on your layer setup
    • End your render pass

Who is online

Users browsing this forum: Semrush [Bot] and 2 guests