Let's say I have assigned a 32-bit number to each of the meshes I will render, and I want to somehow store those identifiers in a texture for reference by a later fragment shading phase. I'm guessing that I would use unlit rendering and a pixel format like PFG_R32_UINT
. But since HlmsUnlitDatablock::setColour
takes colors made up of 32-bit floating point numbers, and not every pattern of 32 bits is a legal floating point number, that seems tricky to get right. Is there an easier way I'm not thinking of?
Rendering identifiers for meshes Topic is solved
-
- Goblin
- Posts: 268
- Joined: Thu Aug 12, 2021 10:06 pm
- Location: San Diego, CA, USA
- x 19
Rendering identifiers for meshes
-
- OGRE Team Member
- Posts: 5477
- Joined: Sat Jul 21, 2007 4:55 pm
- Location: Buenos Aires, Argentina
- x 1359
Re: Rendering identifiers for meshes
This is best achieved by customizing HlmsPbs.
See Tutorial_Hlms05_CustomizationPerObjData sample which explains how to send arbitrary per-object data.
You probably want to turn this on/off based on which pass you're doing. Or maybe leave it always on and send the value to an MRT target (i.e. you can send the tags and do the normal rendering in a single pass).
To turn it off, you must define a property in preparePassHash so that your customizations are not included (i.e. right now this is controlled in the sample by the property "use_arbitrary_colour").
-
- Goblin
- Posts: 268
- Joined: Thu Aug 12, 2021 10:06 pm
- Location: San Diego, CA, USA
- x 19
Re: Rendering identifiers for meshes
dark_sylinc wrote: ↑Sat Feb 22, 2025 9:41 pmOr maybe leave it always on and send the value to an MRT target (i.e. you can send the tags and do the normal rendering in a single pass).
Could you please expand on that? I assume that MRT stands for multiple render target, which does not seem to be discussed at all in the OgreNext manual. All I can find is a commented-out compositor node TestMRT
in Postprocessing.compositor. Apparently the target
line in the script allows one to specify multiple pixel formats. But what's that mysterious line material_scheme MRT
? And how do you use different pixel shaders for different MRT surfaces?
-
- OGRE Team Member
- Posts: 5477
- Joined: Sat Jul 21, 2007 4:55 pm
- Location: Buenos Aires, Argentina
- x 1359
Re: Rendering identifiers for meshes
Yes.
Make an RTV with multiple colours, like the ScreenSpaceReflections sample:
Code: Select all
texture myColor target_width target_height PFG_RGBA8_UNORM_SRGB msaa_auto
texture arbitraryData target_width target_height PFG_R32_FLOAT msaa_auto
// Optional. If you don't set myDepth, then a shared depth buffer from myColor's depth pool will be assigned.
// texture myDepth target_width target_height PFG_D32_FLOAT msaa_auto
rtv mrtRtv
{
colour myColor arbitraryData
// Optional.
// depth myDepth
}
target mrtRtv
{
// The rest remains the same.
}
Then for the pixel shader, have all the pixel shaders output something to outPs_colour1:
Code: Select all
@property( syntax == glsl || syntax == glslvk )
@piece( custom_ps_uniformDeclaration )
layout(location = 1) out float outPs_colour1;
@end
@end
@property( syntax == hlsl )
@piece( ExtraOutputTypes )
float outPs_colour1 : SV_Target1;
@end
@end
@property( syntax == metal )
@piece( ExtraOutputTypes )
float outPs_colour1 : [[ color(1) ]];
@end
@end
@piece( custom_ps_posExecution )
outPs_colour1 = 1.0f;
@end
I set it to PFG_R32_FLOAT, so I made outPs_colour1 float.
Since MRT is not common, I now realize that there are a few issues with OgreNext:
- OgreNext should ideally automatically define outPs_colour1 for you, you shouldn't have to do that.
- ExtraOutputTypes should work in GLSL. It's not, right now.
- ExtraOutputTypes does not follow the custom_ps_ convention.
-
- OGRE Team Member
- Posts: 5477
- Joined: Sat Jul 21, 2007 4:55 pm
- Location: Buenos Aires, Argentina
- x 1359
Re: Rendering identifiers for meshes
OK added custom_ps_output_types.
OgreNext should ideally automatically define outPs_colour1 for you, you shouldn't have to do that.
Turns out this was trickier than I thought it would be. There were a few hard-to-solve details.
ExtraOutputTypes should work in GLSL. It's not, right now.
It was not using the convention because it was something internal. Hence I added custom_ps_output_types
.
Thus the final shader code would end up as:
Code: Select all
@piece( custom_ps_output_types )
@property( syntax == glsl || syntax == glslvk )
layout(location = 1) out float outPs_colour1;
@end
@property( syntax == hlsl )
float outPs_colour1 : SV_Target1;
@end
@property( syntax == metal )
float outPs_colour1 : [[ color(1) ]];
@end
@end
@piece( custom_ps_posExecution )
outPs_colour1 = 1.0f;
@end
Cheers
Edit: Updated documentation to refer to the RTV section of the manual.
-
- Goblin
- Posts: 268
- Joined: Thu Aug 12, 2021 10:06 pm
- Location: San Diego, CA, USA
- x 19
Re: Rendering identifiers for meshes
@dark_sylinc:
Why do I see @insertpiece( custom_ps_output_types )
in Hlms/Pbs/GLSL/PixelShader_ps.glsl
but not in Hlms/Pbs/Metal/PixelShader_ps.metal
? I don't see how that piece will get used in Metal or HLSL.
-
- OGRE Team Member
- Posts: 5477
- Joined: Sat Jul 21, 2007 4:55 pm
- Location: Buenos Aires, Argentina
- x 1359
Re: Rendering identifiers for meshes
Because it was added to RenderDepthOnly_piece_ps.metal which is inserted inside piece DeclOutputType, which is in turn inserted by PixelShader_ps.metal (unless I missed something?).
The same happens with HLSL.
Cheers!
-
- Goblin
- Posts: 268
- Joined: Thu Aug 12, 2021 10:06 pm
- Location: San Diego, CA, USA
- x 19
Re: Rendering identifiers for meshes
OK, that seems right... I foolishly assumed that RenderDepthOnly_piece_ps.metal was only relevant to rendering depth only, so I ignored it.
-
- Goblin
- Posts: 268
- Joined: Thu Aug 12, 2021 10:06 pm
- Location: San Diego, CA, USA
- x 19
Re: Rendering identifiers for meshes
For the record, there was a syntax error in the Metal part of the recommended shader code, it should be:
Code: Select all
@property( syntax == metal )
float outPs_colour1 [[ color(1) ]];
@end
(Colon removed.)
-
- Goblin
- Posts: 268
- Joined: Thu Aug 12, 2021 10:06 pm
- Location: San Diego, CA, USA
- x 19
Re: Rendering identifiers for meshes
I tried using a multi render target in which the second texture has format PFG_R32_UINT
. But then I get an error:
validateWithDevice, line 4170: error 'Render Pipeline Descriptor Validation
Blending is enabled for render target 1; however, the pixelformat MTLPixelFormatR32Uint for this render target is not blendable.'
I'm trying to write identifiers for meshes, so I don't want those valued to be blended. Does that mean that the idea of using MRT for this cannot work?
-
- OGRE Team Member
- Posts: 5477
- Joined: Sat Jul 21, 2007 4:55 pm
- Location: Buenos Aires, Argentina
- x 1359
Re: Rendering identifiers for meshes
You could try using separate blending modes for alpha blending.
OgreNext unfortunately did not include support for per-MRT blending modes (there's usually driver bugs anyway).
If not, then you could duplicate those items and render them separately in different passes.