I am trying to access/resolve the MSAA Render Texture/Target in a custom fullscreen pass / image effect. However, when I declare my Texture2DMS in my shader, I get the following error:
Shader error in 'Custom/customres': Fragment program 'frag': unrecognized sampler type msaaTex (on d3d11)
Does Unity support Texture2DMS access? Am I missing something in my declaration?
System: Windows / HLSL / SM 5.0
I am now stuck with the same issue, after a bit of research it seams that Unity will force the MSAA resolve BEFORE you bind your MSAA texture to your shader, and as a result you won’t have access to the sample data because a MSAA depth texture simply cannot be resolved, not a bug thats just how it is defined.
That’s a huge pity in my case because I’m rendering in MSAA for VR, but I don’t have any way to access the depth buffer I just rendered my geometries in.
The only work around ATM is to NOT use MSAA or to force the camera to re-render the scene in a non-MSAA texture using Camera.depthTextureMode (easy fix if your scene is simple) and then use the texture “_CameraDepthTexture” in your shader (the texture will get automatically attached to your shader for you behind the scenes).
But in my case that is not possible because my scenes are very complex and I can’t afford rendering the scene twice (CAD scenario).
I would love to hear from Unity gurus to know if there is a solution to that problem maybe @Aras ?
At the moment I am thinking of writing a native C++ plugin to copy the only a single sample channel from a MSAA to a non-MSAA texture behind the scene, but if there would be a simpler hack I would be so happy…
Hi, do you find out some way to solve the problem ? I came into the same problem.And My scene is also complex so it’s too expensive to use the depthTextureMode.
And you can tell a MSAA render texture to not resolve to a non-MSAA target when used as a texture property.
Theoretically this should be usable for the built in renderer, though you’ll probably need to use your own render textures and set the camera’s buffers yourself.
Thanks for your reply. Our project is using the 2018.1.6 version. And the doc for 2018.1 says that the SRPs is in preview, so I guess it’s unsafe to use it for our project.
Just an FYI: The current implementation of URP/LWRP falls back to a depth pre-pass (which is serious perf hit for us) due to this line:
// TODO: We don’t have support to highp Texture2DMS currently and this breaks depth precision.
// currently disabling it until shader changes kick in.
In forwardrenderer.cs
I have gotten the copy to work, but I am not sure how reliable it will be across devices.
For example on DX, you can auto-resolve the depth buffer (I am not sure what operation it does to combine 4 depths into 1)
On mobile, we have to resolve the whole MSAA depth surface to memory and access it as a Texture2DMS<float, samples>. This is expensive but it seems less expensive than the depth pre-pass.
@DavidSWu this TODO is outdated. Can you please report a bug so that we fix this?
Support for precision postfixes for all variants of textures is there since 2018.3.0a2
Thank you for the information, I will report it!
What exactly are the precision postfixes?
We use Texture2DMS<float,4>, are we getting low precision results?
Also are there ways to get 4 pixels at a time? Either the 4 MSAA samples or a form of Gather4 that works on an MSAA index?
Thanks!
You can use all of the Texture* (Texture2D, Texture3D and all others) with “_half” or “_float” postfixes, e.g.
Texture2DMS_float<float, 4>.
Unity 2020.1 extracts information from “<float, 4>”, so it shouldn’t be required there anymore.
I don’t think that this is still the case.
While resolving a depth buffer is not well defined (there is no obvious operation to use, i.e. average, an average of reciprocals, max, etc. ), it seems to be supported on a growing number of platforms.
If you are only accessing the depth of the pixel that you are rendering to, and you are rendering at the same MSAA and resolution you might be about to use the RenderPass api. This seems like the most efficient solution by far.
However, I don’t know what platforms it will be natively supported on. It seems like with GLES it currently emulates with rendertargets and resolves. On Vulcan and Metal it is native.
Has anyone successfully accessed MSAA data before resolve? I have not been successful using RenderTextureDescriptor.bindMS. When I blit the cameraColorTargetHandle to an RTHandle with this setting on its descriptor, I still appear to be getting resolved values for each pixel (i.e., each subsample value is identical to 8+ places). In contrast, when I readout pixel sample data from the cameraDepthTargetHandle, I DO get subsample data which varies between each sample. I cannot find any way to achieve the same results with color as opposed to depth.
@aleksandrk can anyone comment whether it is possible to copy out the full MSAA render target of the color buffer before it ever gets resolved? There is radio silence on this topic across the board.
Thank you for your response @aleksandrk ! I have not seen this flag until now. Can you give an example of how to use this in a scriptable render pass? I tried to set it but an error says its read only. I do not see a RenderTexture or RenderTextureDescriptor constructor that will allow me to set this flag.
How do I set the flags on theRenderTextureDescriptor though? If i do something like descriptor.flags = RenderTextureCreationFlags.NoresolvedColorSurface then I get an error saying that flags are read-only. And again, I cannot find a constructor for RenderTextureDescriptor that takes this flag as an argument