简体   繁体   English

顶点着色器中的采样返回缓冲区始终返回0和float1而不是float4

[英]Sampling Back Buffer in vertex Shader always returns 0 and float1 instead of float4

I am totally lost now. 我现在完全迷路了。 Have been trying to read the backbuffer inside a vertex shader for days with no luck whatsoever. 几天来一直在尝试读取顶点着色器中的backbuffer,但没有任何运气。

I'm trying to read the vertexes position from the backbuffer and it's neighboring pixels. 我正在尝试从后缓冲区及其附近的像素读取顶点位置。 (I'm trying to count how many black pixels are around a vertex, and if there are any color that vertex red in the pixel shader). (我试图计算顶点周围有多少个黑色像素,以及像素着色器中是否有顶点红色的颜色)。 I've created a separate ID3D11Texture2D and an SRV to go with the backBuffer. 我创建了一个单独的ID3D11Texture2D和一个SRV与backBuffer一起使用。 I copy the backbuffer into this SRV's resource. 我将后缓冲区复制到此SRV的资源中。 Bind the SRV using VSSetShaderResources but just can't seem to be able to read from it inside the vertex shader. 使用VSSetShaderResources绑定SRV,但似乎无法从顶点着色器中读取SRV。

I will share some code here from the creation of these elements as well as include some RenderDoc screenshots that keep showing that the SRV is being bound to the VS stage and has the right texture associated with it but every Load or []operator or tex2dlod or SampleLevel(i bound a SamplerState too) just keeps returning a single 1.0 value with the rest of the float4 never being returned, meaning i only get a float1 back. 我将在此处分享这些元素的创建过程中的一些代码,以及一些RenderDoc屏幕快照,这些屏幕快照始终显示SRV已绑定到VS舞台并具有正确的纹理,但每个Load或[] operator或tex2dlod或SampleLevel(我也绑定了SamplerState)仅保持返回一个1.0值,而其余的float4则永不返回,这意味着我只能获得一个float1。 I will also include a renderdoc capture file if anyone wants to take a look. 如果有人想看看,我还将提供一个renderdoc捕获文件。

This is a simple scene from tutorial 42 on the rastertek.com site, there is a ground plane with a cube and a sphere on it : 这是rastertek.com网站上的教程42中的一个简单场景,上面有一个带有立方体和球体的地平面:

https://i.imgur.com/cbVC48E.gif https://i.imgur.com/cbVC48E.gif

// Here is some code when creating the secondary texture and SRV that houses a //backBuffer
// Get the pointer to the back buffer.
    result = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr);
    if(FAILED(result))
    {
        MessageBox((*(hwnd)), L"Get the pointer to the back buffer FAILED", L"Error", MB_OK);
        return false;
    }


    // Create another texture2d that we will use to make an SRV out of, and this texture2d will be used to copy the backbuffer to so we can read it in a shader
    D3D11_TEXTURE2D_DESC bbDesc;
    backBufferPtr->GetDesc(&bbDesc);
    bbDesc.MipLevels = 1;
    bbDesc.ArraySize = 1;
    bbDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    bbDesc.Usage = D3D11_USAGE_DEFAULT;
    bbDesc.MiscFlags = 0;
    bbDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
    result = m_device->CreateTexture2D(&bbDesc, NULL, &m_backBufferTx2D);
    if (FAILED(result))
    {
        MessageBox((*(m_hwnd)), L"Create a Tx2D for backbuffer SRV FAILED", L"Error", MB_OK);
        return false;
    }
    D3D11_SHADER_RESOURCE_VIEW_DESC descSRV;
    ZeroMemory(&descSRV, sizeof(descSRV));
    descSRV.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    descSRV.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
    descSRV.Texture2D.MipLevels = 1;
    descSRV.Texture2D.MostDetailedMip = 0;
    result = GetDevice()->CreateShaderResourceView(m_backBufferTx2D, &descSRV, &m_backBufferSRV);
    if (FAILED(result))
    {
        MessageBox((*(m_hwnd)), L"Creating BackBuffer SRV FAILED.", L"Error", MB_OK);
        return false;
    }

    // Create the render target view with the back buffer pointer.
    result = m_device->CreateRenderTargetView(backBufferPtr, NULL, &m_renderTargetView);

First I render the scene in all white and then I copy that to the SRV and bind it for the next shader that's supposed to sample it. 首先,我将场景渲染为全白,然后将其复制到SRV,并将其绑定到应该采样的下一个着色器。 I'm expecting to get a float4(1.0, 1.0, 1.0, 1.0) value returned when i sample the backbuffer with the vertex's on screen position 当我在屏幕上的顶点位置采样后缓冲时,我期望返回一个float4(1.0,1.0,1.0,1.0)值

https://i.imgur.com/N9CYg8c.png https://i.imgur.com/N9CYg8c.png

as shown on the top left in the event browser, there were three drawindexed calls for rendering everything in white and then a CopyResource. 如事件浏览器左上角所示,有三个drawindexed调用以白色呈现所有内容,然后是CopyResource。 I've selected the next (fourth) DrawIndexed and on the right side outlined in red are the inputs for this next shader clearly showing that the backBuffer has been successfully bound to the vertex shader. 我选择了下一个(第四个)DrawIndexed,并在右侧用红色勾勒出了下一个着色器的输入,清楚地表明backBuffer已成功绑定到顶点着色器。

And now for the part that's giving me trouble 现在让我麻烦的部分

https://i.imgur.com/ENuXk0n.png https://i.imgur.com/ENuXk0n.png

I'm gonna be debugging this top-left vertex as shown on the screenshot, the vertex Shader has a Texture2D prevBackBuffer: register(t0); 我将如屏幕截图所示调试该左上角的顶点,该顶点着色器具有Texture2D prevBackBuffer:register(t0); written at the top 写在顶部

https://i.imgur.com/8cihNsq.png https://i.imgur.com/8cihNsq.png

When trying to sample the left neighboring pixel this line of code returns newCoord = float2(158, 220) when entering these pixel values in the texture view i get this pixel 当尝试采样左相邻像素时,此代码行在纹理视图中输入这些像素值时返回newCoord = float2(158,220),我得到了这个像素

https://i.imgur.com/DT72Fl1.png https://i.imgur.com/DT72Fl1.png

so the coordinates are ok so far, and as outlined i'm expecting to get a float4(0.0, 0.0, 0.0, 1,0) returned when i sample this pixel (I'm trying to count how many black pixels are around a vertex, and if there are any color that vertex red in the pixel shader) 因此到目前为止,坐标还可以,并且如概述所示,我希望在我对该像素进行采样时得到一个float4(0.0、0.0、0.0、1,0)返回(我正在尝试计算一个像素周围有多少个黑色像素)顶点,以及像素着色器中是否有任何顶点为红色的颜色)

AND YET, when i sample that pixel right after altering the pixel coordinates since load counts pixels from bottom left so i need newCoord = float2(158, 379), i get this 而且,当我在更改像素坐标后立即采样该像素时,因为负载从左下角开始计数像素,所以我需要newCoord = float2(158,379),我得到了

https://i.imgur.com/8SuwOzz.png https://i.imgur.com/8SuwOzz.png

why is this, even if it's out of range, load should return all zeros, since I'm not sure about the whole load counts from bottom left thing I tried sampling using the top left coordinates (158, 220) but end up getting 0.0, ?, ?, ? 为什么会这样,即使超出范围,负载也应返回全零,因为我不确定从左下角开始的总负载计数,因此我尝试使用左上角坐标(158,220)进行采样,但最终得到0.0 ,?,?,?

I'm completely stumped and have no idea what to try next. 我完全迷住了,不知道下一步该怎么做。 I've tried using a sample state : 我试过使用示例状态:

// Create a clamp texture sampler state description.
    samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
    samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
    samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
    samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
    samplerDesc.MipLODBias = 0.0f;
    samplerDesc.MaxAnisotropy = 1;
    samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
    samplerDesc.BorderColor[0] = 0;
    samplerDesc.BorderColor[1] = 0;
    samplerDesc.BorderColor[2] = 0;
    samplerDesc.BorderColor[3] = 0;
    samplerDesc.MinLOD = 0;
    samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;

    // Create the texture sampler state.
    result = device->CreateSamplerState(&samplerDesc, &m_sampleStateClamp);

but still never get a proper float4 back when reading the texture. 但在读取纹理时仍永远不会返回正确的float4。

Any ideas, suggestions, I'll take anything at this point. 任何想法,建议,在这一点上我都会采取任何措施。 Oh and here's a RenderDoc file of the frame i was examining : http://www.mediafire.com/file/1bfiqdpjkau4l0n/my_capture.rdc/file 哦,这是我正在检查的框架的RenderDoc文件: http : //www.mediafire.com/file/1bfiqdpjkau4l0n/my_capture.rdc/file

So from my experience, reading from the back buffer is not really an operation that you want to be doing in the first place. 因此,以我的经验来看,从后台缓冲区读取并不是真正要首先执行的操作。 If you have to do any operation on the rendered scene, the best way to do that is to render the scene to an intermediate texture, perform the operation on that texture, then render the final scene to the back buffer. 如果必须对渲染的场景进行任何操作,最好的方法是将场景渲染为中间纹理,对该纹理执行操作,然后将最终的场景渲染到后台缓冲区。 This is generally how things like dynamic shadows are done - the scene is rendered from the perspective of the light, and the resulting buffer is interpreted to get a shadow value that is then applied to the final scene (this is also why dynamic light sources are limited in commercial game engines - they're rather expensive to use). 通常这是完成动态阴影之类的方式-从灯光的角度渲染场景,然后解释生成的缓冲区以获取阴影值,然后将其应用于最终场景(这也是为什么动态光源是受限于商业游戏引擎-使用起来相当昂贵)。

A similar idea can be applied here. 类似的想法可以在这里应用。 First, render the whole scene to an intermediate texture, bound as a render target view (where the pixel format is specified by you, the programmer ). 首先,将整个场景渲染为中间纹理,绑定为渲染目标视图(其中像素格式由您( 程序员 )指定)。 Next, rebind that intermediate texture as a shader resource view, and render the scene again, using the edge detection shader and the real back buffer (where the pixel format is defined by the hardware ). 接下来,将中间纹理重新绑定为着色器资源视图,并使用边缘检测着色器和实际的后缓冲区(其中像素格式由硬件定义)再次渲染场景。

This, fundamentally, is what I believe the issue is - a back buffer is a device dependent resource, and its format can change depending on the hardware. 从根本上讲,这就是我认为的问题-后备缓冲区是与设备相关的资源,其格式可以根据硬件而改变。 Therefore, using it from a shader is not safe, as you don't always know what the format will be. 因此,从着色器使用它并不安全,因为您并不总是知道格式是什么。 A device independent resource, on the other hand, will always have the same format, and you can safely use it however you like from a shader. 另一方面,与设备无关的资源将始终具有相同的格式,并且可以从着色器中随意使用,但可以放心使用。

I wasn't able to get sampling an SRV in the vertex shader to work but what i was able to get working is using a backBuffer.SampleLevel inside a compute shader I also had to change the sampler to something like this : 我无法在顶点着色器中对SRV进行采样,但是我能够使用的是在计算着色器中使用backBuffer.SampleLevel,我还必须将采样器更改为如下所示:

D3D11_SAMPLER_DESC samplerDesc;

samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_BORDER;
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_BORDER;
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_BORDER;
samplerDesc.MipLODBias = 0.0f;
samplerDesc.MaxAnisotropy = 1;
samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
samplerDesc.BorderColor[0] = 0.5f;
samplerDesc.BorderColor[1] = 0.5f;
samplerDesc.BorderColor[2] = 0.5f;
samplerDesc.BorderColor[3] = 0.5f;
samplerDesc.MinLOD = 0;
samplerDesc.MaxLOD = 0;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM