We all know that pixel shader is executed at pixel frequency in MSAA rendering and a given position (with SV_POSITION semantic) is a random position inside a pixel. However, I do not know how to position of each sample using HLSL and DirectX 11. Is there anyway to get position of each sample inside pixel shader when using multisampling?
How find sample positions in mulisampling rendering?
The 'standard' Multisample positions are documented on https://msdn.microsoft.com/en-us/library/windows/desktop/ff476218(v=vs.85).aspx
If you use anything else you might have to take a look at MJP's MSAA Sample Pattern Detector: https://mynameismjp.wordpress.com/2010/07/07/msaa-sample-pattern-detector/
What I'm not sure about is why his Sample Pattern Detector didn't just bind a 1x1 Texture2DMS to the shader and retrieve the sample positions via GetSamplePosition. Perhaps he can chip in with what the 'gotcha' is for using GetSamplePosition.
EDIT: To clarify, my proposal would be to find a 1x1 Texture2DMS, extract the sample positions using GetSamplePosition, get them back to the CPU and then store them in a constant buffer, just in case "GetSamplePosition" isn't as efficient as it could be across all vendors. Though I have a feeling it's usually implemented as a hidden constant buffer.
Thank guys. I have seen msdn document about sample pattern. In case of 4xMSAA, sample positions are (-2, 6), (6, -2), (-6, 2), (2, 6). I think I need to scale those sample positions with 1/16 and hard code in pixel shader. Is that right?
I believe the situation at the time of the writing was that D3D 10.1 compliant hardware was not yet widely available.
I'm not sure if any GPU drivers actually make use of this feature when you're using D3D11, but many GPU's actually support sample patters that are defined over a 2x2 pixel area -- i.e. neighbouring pixels don't have to use the same pattern as each other.
Yes, I'm just unclear on exactly when those situations arise.
When your user only has feature level 10_0 or 9_*.
Also, on 10_1 and 11_*, you don't have to use the standard patterns - there's also the traditional vendor-specific patterns available. I assume that GetSamplePosition works for these... but maybe not if the vendor is doing a larger than 1x1 pixel area pattern. e.g. you can call GetSamplePosition from a VS, in which case the GPU would have no way to know which pixel within the pattern you wish to query. If it does work in that situation, perhaps for 4xMSAA with a 2x2 px pattern, you can pass 0..15 to GetSamplePosition to query the 16 samples within the pattern, even though there's only 4 per pixel?? This is all beyond the spec though, so who knows. Might be interesting to test MJP's approach against this part of the API on all the vendor patterns out there :D
I can understand GetSamplePosition not being available on 9_x due to Texture2DMS requiring SM4.0, but what would disqualify GetSamplePosition from working on 10_0?
Because MSDN says so - that's the link you posted above!
D3D11's SM4 is very close to D3D9's SM3 (which isn't available in D3D11 -- it jumps straight from three slightly different versions of SM2 straight to SM4), and SM4.1 added a lot of MSAA-related features. SM4 is basically the top-end D3D9 GPU's, and SM4.1 is the next generation of mature D3D10 GPUs.
From memory, Texture2DMS.Load always returns sample #0 on FL_10_0, but allows you to specify the sample index on FL_10_1... but right now I can't find an MSDN link to back this up... Maybe I'm remember that wrongly...
Also IIRC, D3D10.1 added SV_SampleIndex, which allows the PS to run per-sample instead of per-pixel - at which point, MSAA + Deferred started becoming viable.