Forum Discussion

🚨 This forum is archived and read-only. To submit a forum post, please visit our new Developer Forum. 🚨
vhv-developer's avatar
7 years ago

How to Use Pixel Shader on ovrTextureSwapChain?

Maybe someone is kind enough to point me into the right direction.
I have a HUD layer (ovrLayerQuad) which is represented by a ovrTextureSwapChain. Now I need to apply a pixel shader but I don't know if there is a predestined way of doing this, provided by Oculus, or if I have to handle it like a regular ID3D11Texture2D which would be a lot to code (e.g. having a pass-through vertex shader and another dozen of DX11 objects to setup and deal with...). My best guess would be something like this:

int currentIndex = 0;
ovr_GetTextureSwapChainCurrentIndex(m_session, m_HudRenderTexture, &currentIndex);
ID3D11Texture2D* tex = nullptr;
ovr_GetTextureSwapChainBufferDX(m_session, m_HudRenderTexture, currentIndex, IID_PPV_ARGS(&tex));
//SOMEHOW APPLY PIXEL SHADER TO tex
ovr_CommitTextureSwapChain(m_session, m_HudRenderTexture);
...
// Initialize the HUD layer, fixed to the player's head
ovrLayerQuad hudLayer;
hudLayer.Header.Type = ovrLayerType_Quad;
hudLayer.Header.Flags = ovrLayerFlag_HeadLocked;
hudLayer.ColorTexture = m_HudRenderTexture;
...

5 Replies

  • Don't count on oculus, do it by yourself. Use Compute Shaders instead of Pixel Shader to avoid all this Vertex Shader pass through bullshit. Compute Shaders also have the great advantage of being mostly independent from the scanline pipeline (execution wise)
  • Thank you, I'll do it on my own!. :) Good hint trying to solve my problem with computer shaders. I'll have a look and report back.
  • volgaksoy's avatar
    volgaksoy
    Expert Protege
    Compute shaders can help. However, if you want to use a pixel shader to write into a given texture, you need to create a Render Target View and assign that RTV to be the render target on your current D3D11 device context. Next create a vertex buffer with 1 or triangles in it that will cover the whole render target space. Then create a vertex shader that simply passes thru the vertex buffer values to help get the triangle(s) rasterized. When they're being rasterized, each pixel being rasterized will invoke your pixel shader. As you might imagine, there's quite a bit of setup needed to do this and when combined with the need to sometimes also deal with render states, it can get fairly tricky especially if it's the first draw call you're trying to invoke correctly.

    I'd recommend you take a peek at our OculusRoomTiny demo which renders the world using simple shaders. Even though your use case is slightly different (2D vs 3D rendering), it's still going to use the same GPU rasterization pipeline to make a draw call... that is unless you go down the compute shader path.
  • Thanks a lot for outlining a solution, @volgaksoy!
    The OculusRoomTiny demo includes a specific header file where it hides the shader usage within a material struct which is used in a model struct. In my opinion this makes it harder to understand, and harder to use as it should be, although this structure makes total sense for this tiny room example. 
    Nevertheless, I made the effort and wrote a similar structure so that I can use it like a mixture between OculusTexture and Model struct.
    But in the end I had to give up because the setup you've described has to work well with our licensed game engine. This means not only having to know a lot about DX11 and the rendering pipeline, I also have to know much details about how the engine sets up the pipeline. This is too much for me to wrap my head around at this time.
    So, I solved it with the way the engine offered, which means to include my shader into the engine's shader system and use it with the permitted object types. Oculus now gets the result as a ID3D11Texture2D texture.
    This does the job, for now! I'll do performance tests and see if it's fast enough. If not, a compute shader may help...

    @thewhiteambit:
    Using compute shader seems like a shortcut and may be even faster. What I've read about that is, that you need to have a good knowledge about the mechanics of compute shader and one of the main advantages is that it can have shared data in order to prevent multiple passes. I don't need that, and I've never done a compute shader before. So, if the pixel shader solution is not fast enough, then I'll have this solution as an alternative.
  • Compute Shaders are much more simple than even a Pixel-Shader. They are really the most simple form of a shader and anybody able of setting up RTV etc. can easily write Compute Shaders. You should dare it, Compute Shaders are really dead simple! I use Compute Shaders for a similar purpose (1:1 pixel transfers with calculations) and would never ever solve such problems with Pixel Shaders again.