DirectX 11 Render To Texture - c++

basically I am trying to render a scene to a texture as in this ogl tutorial here but in DirectX 11, and I faced some issues:
Absolutely nothing is rendered when I launch the program IDK why.
The only thing the texture displays 'correctly' is the clear color.
I have examined the executable in RenderDoc, and in the captured frame the back buffer draws the quad and the texture on it displays the scene correctly!
Source code peak:
D3D11_TEXTURE2D_DESC texDesc;
ZeroMemory(&texDesc, sizeof(D3D11_TEXTURE2D_DESC));
texDesc.Width = Data.Width;
texDesc.Height = Data.Height;
texDesc.Format = R32G32B32A32_FLOAT;
texDesc.Usage = D3D11_USAGE_DEFAULT;
texDesc.SampleDesc.Count = 1;
texDesc.SampleDesc.Quality = 0;
texDesc.CPUAccessFlags = 0;
texDesc.ArraySize = 1;
texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
texDesc.MiscFlags = 0;
texDesc.MipLevels = 1;
if (Data.Img_Data_Buf == NULL)
{
if (FAILED(DX11Context::GetDevice()->CreateTexture2D(&texDesc, NULL, &result->tex2D)))
{
Log.Error("[DirectX] Texture2D Creation Failed for Null-ed Texture2D!\n");
return;
}
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
srvDesc.Format = texDesc.Format;
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
srvDesc.Texture2D.MostDetailedMip = 0;
srvDesc.Texture2D.MipLevels = 1;
DX11Context::GetDevice()->CreateShaderResourceView(result->tex2D, &srvDesc, &result->resourceView);
return;
}
//depth stencil texture
D3D11_TEXTURE2D_DESC texDesc;
{
texDesc.Width = size.x;
texDesc.Height = size.y;
texDesc.MipLevels = 1;
texDesc.ArraySize = 1;
texDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
texDesc.SampleDesc.Count = 1;
texDesc.SampleDesc.Quality = 0;
texDesc.Usage = D3D11_USAGE_DEFAULT;
texDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
texDesc.CPUAccessFlags = 0;
texDesc.MiscFlags = 0;
}
if (FAILED(API::DirectX::DX11Context::GetDevice()->CreateTexture2D(&texDesc, nullptr, &depthstenciltex)))
{
Log.Error("[DX11RenderTarget] Failed to create DepthStencilTexture for render-target!\n");
//Return or the next call will fail too
return;
}
if (FAILED(API::DirectX::DX11Context::GetDevice()->CreateDepthStencilView(depthstenciltex, nullptr, &depthstencilview)))
{
Log.Error("[DX11RenderTarget] Failed to create DepthStencilView for render-target!\n");
}
//render target
D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc;
ZeroMemory(&renderTargetViewDesc, sizeof(D3D11_RENDER_TARGET_VIEW_DESC));
renderTargetViewDesc.Format = texDesc.Format;
renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
renderTargetViewDesc.Texture2D.MipSlice = 0;
ID3D11RenderTargetView* rtv;
if (FAILED(API::DirectX::DX11Context::GetDevice()->CreateRenderTargetView(texture->tex2D, &renderTargetViewDesc, &rtv)))
{
Log.Error("[DX11RenderTarget] Failed to create render-target-view (RTV)!\n");
return;
}
//binding
Context->OMSetRenderTargets(1, &rtv, rt->depthstenciltex);
Shaders:
std::string VertexShader = R"(struct VertexInputType
{
float4 position : POSITION;
float2 tex : TEXCOORD;
};
struct PixelInputType
{
float4 position : SV_POSITION;
float2 tex : TEXCOORD;
};
cbuffer NE_Camera : register(b0)
{
matrix Model;
matrix View;
matrix Projection;
};
PixelInputType main(VertexInputType input)
{
PixelInputType output;
// Calculate the position of the vertex against the world, view, and projection matrices.
output.position = mul(Model, input.position);
output.position = mul(View, output.position);
output.position = mul(Projection, output.position);
// Store the input texture for the pixel shader to use.
output.tex = input.tex;
return output;
})";
std::string PixelShader = R"(
struct PixelInputType
{
float4 position : SV_POSITION;
float2 tex : TEXCOORD;
};
Texture2D NE_Tex_Diffuse : register(t0);
SamplerState NE_Tex_Diffuse_Sampler : register(s0);
float4 main(PixelInputType input) : SV_TARGET
{
return NE_Tex_Diffuse.Sample(NE_Tex_Diffuse_Sampler, input.tex);
}
)";
std::string ScreenVertexShader = R"(struct VertexInputType
{
float2 position : POSITION;
float2 tex : TEXCOORD;
};
struct PixelInputType
{
float4 position : SV_POSITION;
float2 tex : TEXCOORD;
};
PixelInputType main(VertexInputType input)
{
PixelInputType output;
// CalcSulate the position of the vertex against the world, view, and projection matrices.
output.position = float4(input.position.x,input.position.y,0.0f,1.0f);
// Store the input texture for the pixel shader to use.
output.tex = input.tex;
return output;
})";
std::string ScreenPixelShader = R"(
struct PixelInputType
{
float4 position : SV_POSITION;
float2 tex : TEXCOORD;
};
Texture2D ScreenTexture : register(t0);
SamplerState ScreenTexture_Sampler : register(s0);
float4 main(PixelInputType input) : SV_TARGET
{
return float4(ScreenTexture.Sample(ScreenTexture_Sampler, input.tex).rgb, 1.0f);
}
)";
Full Source Code
Also I captured a frame with visual studio graphics debugger, and noticed that the render to texture draw call has the PS shader with "stage didn't run, no output".
Note: I know that the scene should be flipped in DirectX.

I have found the bug causing this problem, I wasn't clearing the depth stencil view at rendering, I wonder why is clearing the DSV essential for RenderTarget output.

Related

How to add opacity to objects in directX11 with shaders

I'm new to directx and I need to set up opacity in my shaders. I don't use textures or anything and I just need to add opacity to whole objects based on one variable in shader.
I've tried to simply put this variable in shader's output color alpha channel, but it didn't work and I guess that the solution of this problem is not in shaders. This is my shader so far.
cbuffer ConstantBuffer : register(b0)
{
matrix World;
matrix View;
matrix Projection;
float4 vLigthDir[2];
float4 vLigthColor[2];
float4 vOutputColor;
float intensity;
float3 colors;
}
struct VS_INPUT
{
float4 pos : POSITION;
float3 norm : NORMAL;
};
struct PS_INPUT
{
float4 pos : SV_POSITION;
float3 norm : TEXCOORD0;
};
PS_INPUT VS(VS_INPUT input)
{
PS_INPUT output = (PS_INPUT) 0;
output.pos = mul(input.pos, World);
output.pos = mul(output.pos, View);
output.pos = mul(output.pos, Projection);
output.norm = mul(input.norm, World);
return output;
}
float4 PS(PS_INPUT input) : SV_Target
{
float4 finalColor = 0;
finalColor.r = colors.r;
finalColor.g = colors.g;
finalColor.b = colors.b;
finalColor.a = intensity;
return finalColor;
}
float4 PSSolid(PS_INPUT input) : SV_Target
{
return vOutputColor;
}
//Create BlendState
D3D11_BLEND_DESC blendDesc;
blendDesc.AlphaToCoverageEnable = false;
blendDesc.IndependentBlendEnable = false;
blendDesc.RenderTarget[0].BlendEnable = true;
blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
hr = g_pd3dDevice->CreateBlendState(&blendDesc, &pBlendState);
//Using BlendState
float blendFactor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
UINT sampleMask = 0xffffffff;
g_pImmediateContext->OMGetBlendState(&pBlendState, blendFactor, &sampleMask);
///////////Rendering geometry part///////////
g_pImmediateContext->OMGetBlendState(NULL, NULL, NULL);
I expect some objects to have opacity, but instead nothing happenening at all, there are just solid color.

DirectX alpha blending not working in UWP

I have an application based on the Windows8-DirectX template from the Visual Studio and i'm trying to draw a texture with an alpha channel with the following D3D11_BLEND_DESC:
D3D11_BLEND_DESC blendDesc{};
blendDesc.RenderTarget[0].BlendEnable = TRUE;
blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_INV_DEST_ALPHA;
blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ONE;
blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
ThrowIfFailed(device->CreateBlendState(&blendDesc, &_blendState));
And i'm binding this blend state this way:
float blendFactor[4] = { 0.0f, 0.0f, 1.0f, 1.0f };
UINT sampleMask = 0xffffffff;
context->OMSetBlendState(_blendState.Get(), blendFactor, sampleMask);
Here is my Vertex Shader:
cbuffer ModelViewProjectionConstantBuffer : register(b0)
{
matrix model;
matrix view;
matrix projection;
};
struct VertexShaderInput
{
float3 pos : POSITION;
float2 texcoord : TEXCOORD;
};
struct PixelShaderInput
{
float4 pos : SV_POSITION;
float2 texcoord : TEXCOORD;
};
PixelShaderInput main(VertexShaderInput input)
{
PixelShaderInput output;
float4 pos = float4(input.pos, 1.0f);
pos = mul(pos, model);
pos = mul(pos, view);
pos = mul(pos, projection);
output.pos = pos;
output.texcoord = input.texcoord;
return output;
}
Pixel Shader:
Texture2D tex0;
SamplerState s0;
struct PixelShaderInput
{
float4 pos : SV_POSITION;
float2 texcoord : TEXCOORD;
};
float4 main(PixelShaderInput input) : SV_TARGET
{
float4 color = tex0.Sample(s0, input.texcoord);
return color;
}
And that is my texture:
D3D11_TEXTURE2D_DESC textureDesc{};
textureDesc.Width = width;
textureDesc.Height = height;
textureDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
textureDesc.MipLevels = textureDesc.ArraySize = 1;
textureDesc.SampleDesc.Count = 1;
ThrowIfFailed(device->CreateTexture2D(&textureDesc, NULL, &_texture));
ThrowIfFailed(device->CreateShaderResourceView(_texture.Get(), NULL, &_textureView));
But the problem is that the blending is not working properly. An texture is only blending with the background, but not with another texture, eg. if i call the ClearRenderTargetView method with blue color as third parameter then the partially transparent texture will be bluish but will not be blended with an overlapping texture.

DirectX10, Rendering to a Rendertarget - No Alpha

My Problem is, that when I render to a rendertarget, which has a texture binded to it, the rendered information cannot be seen, because the alpha is 0.
If I turn the alpha value within the shader to 1 when displaying the rendertarget, then I can see it clear.
If I save the texture to a file, everywhere where there is nothing rendered, it is the clearcolor. Everywhere, where something is rendered, there's alpha = 0.
My blendstate:
D3D10_BLEND_DESC BlendState;
ZeroMemory(&BlendState, sizeof(D3D10_BLEND_DESC));
BlendState.AlphaToCoverageEnable = FALSE;
for (int32 i=0;i<this->m_TextureCount;i++)
BlendState.BlendEnable[i] = TRUE;
BlendState.SrcBlend = D3D10_BLEND_SRC_ALPHA;
BlendState.DestBlend = D3D10_BLEND_INV_SRC_ALPHA;
BlendState.BlendOp = D3D10_BLEND_OP_ADD;
BlendState.SrcBlendAlpha = D3D10_BLEND_ZERO;
BlendState.DestBlendAlpha = D3D10_BLEND_ZERO;
BlendState.BlendOpAlpha = D3D10_BLEND_OP_ADD;
for (int32 i = 0; i<this->m_TextureCount; i++)
BlendState.RenderTargetWriteMask[i] = D3D10_COLOR_WRITE_ENABLE_ALL;
this->m_pDevice->CreateBlendState(&BlendState, &this->m_pBlendState);
Before rendering:
this->m_pDevice->OMSetBlendState(this->m_pBlendState, 0, 0xffffffff);
Shadercode to draw the bricks:
float4x4 View;
float4x4 Projection;
Texture2D Diffuse;
SamplerState TextureSampler
{
Filter = MIN_MAG_MIP_Linear;
AddressU = WRAP;
AddressV = WRAP;
};
struct VertexShaderInput
{
float3 Position : POSITION0;
float2 UV : TEXCOORD0;
float3 Color : COLOR0;
float3 Normal : NORMAL0;
row_major float4x4 Offset : MATRIX;
};
struct VertexShaderOutput
{
float4 PositionOut : SV_POSITION;
float4 Position : POSITION0;
float2 UV : TEXCOORD0;
float3 Color : COLOR0;
float3 Normal : NORMAL0;
};
struct PixelShaderOutput
{
float4 colorMap: SV_TARGET0;
float4 normalMap: SV_TARGET1;
float4 positionMap: SV_TARGET2;
};
VertexShaderOutput VS_MAIN(VertexShaderInput input)
{
VertexShaderOutput Output = (VertexShaderOutput)0;
float4 pos = float4(input.Position.xyz, 1);
float4x4 Model = input.Offset;
float4x4 MVP = mul(mul(Model,View),Projection);
Output.Position = mul(pos,MVP);
Output.PositionOut = mul(pos,MVP);
Output.UV = input.UV;
Output.Color = input.Color;
Output.Normal = normalize(mul(input.Normal,(float3x3)Model));
return Output;
}
PixelShaderOutput PS_MAIN(VertexShaderOutput input)
{
PixelShaderOutput output;
output.colorMap = float4(1,0,0,1); // This is the texture above
output.normalMap = float4(input.Normal,1);
output.positionMap = float4(input.Position.xyz,1);
return output;
}
technique10 Main
{
pass p0
{
SetVertexShader(CompileShader(vs_4_0, VS_MAIN()));
SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_4_0, PS_MAIN()));
}
};
changed Rendertarget's Blendstate to
D3D10_BLEND_DESC BlendState;
ZeroMemory(&BlendState, sizeof(D3D10_BLEND_DESC));
BlendState.AlphaToCoverageEnable = true;
for (int32 i=0;i<this->m_TextureCount;i++)
BlendState.BlendEnable[i] = TRUE;
BlendState.SrcBlend = D3D10_BLEND_SRC_ALPHA;
BlendState.DestBlend = D3D10_BLEND_INV_SRC_ALPHA;
BlendState.BlendOp = D3D10_BLEND_OP_ADD;
BlendState.SrcBlendAlpha = D3D10_BLEND_SRC_ALPHA;
BlendState.DestBlendAlpha = D3D10_BLEND_INV_SRC_ALPHA;
BlendState.BlendOpAlpha = D3D10_BLEND_OP_ADD;
for (int32 i = 0; i<this->m_TextureCount; i++)
BlendState.RenderTargetWriteMask[i] = D3D10_COLOR_WRITE_ENABLE_ALL;
this->m_pDevice->CreateBlendState(&BlendState, &this->m_pBlendState);
And it works now.

directx 11 change texture using PSSetShaderResources

Hi I am just learning directx11 and have come across a problem with PSSetShaderResources
if I change textures before the call to swapchain->Present only the first texture is displayed.
if I change textures between Present calls both are displayed but on consecutive frames.
Is there anyway of changing textures with PSSetShaderResources so I can use both (or more) on a single frame?
I know I can use texture arrays but it appears to me that you must have same size textures?
also I could upload two textures (or more) at a time but I would then have to have conditional statements within shader.
Below is the drawing loop I am using. And the simple shader that I am using
any help would be appreciated.
Paul
24OCT2014
tempBool = false;
for (int j = 0; j < 2; j++) //change 2 to texCount
{
devcon->UpdateSubresource(pConstantBuffer, 0, NULL, &cb, 0, 0);
devcon->VSSetConstantBuffers(0, 1, &pConstantBuffer);
devcon->PSSetConstantBuffers(0, 1, &pConstantBuffer);
tempBool = !tempBool;
if (tempBool)
{
devcon->PSSetShaderResources(0, 1, &pTex[0]);
}
else
{
devcon->PSSetShaderResources(0, 1, &pTex[1]);
}
for (int i = 0; i < texRun[j]; i++)
{
devcon->Draw(obLens[curPos+i], obStarts[curPos+i]);
}
curPos += texRun[j];
}
swapchain->Present(0, 0);
Texture2D txDiffuse : register( t0 );
SamplerState samLinear : register( s0 );
cbuffer ConstantBuffer : register( b0 )
{
matrix World;
matrix View;
matrix Projection;
float4 vLightDir;
float4 vLightColor;
};
struct VOut
{
float4 Pos : SV_POSITION;
float3 Norm : NORMAL;
float2 Tex : TEXCOORD;
};
VOut VShader(float4 position : POSITION, float3 Norm : NORMAL, float2 Tex : TEXCOORD)
{
VOut output = (VOut)0;
output.Pos = mul( position, World );
output.Pos = mul( output.Pos, View );
output.Pos = mul( output.Pos, Projection );
output.Norm = mul(Norm, World);
output.Tex = Tex;
return output;
}
float4 PShader0(float4 position : SV_POSITION, float3 Norm : NORMAL,
float2 Tex : TEXCOORD ) : SV_TARGET
{
float4 diffuse = 0;
diffuse = txDiffuse.Sample( samLinear, Tex );
float4 finalColor = 0;
finalColor = diffuse; // * 0.2;
finalColor += saturate( dot((float3)vLightDir,Norm) * diffuse);
finalColor.a = 1.0;
return finalColor;
}
Finally tracked down the error it was in my object loading code and nothing to do width direct3d
I was Loading second lot of objects over the first lot
for first lot of objects I am reading into verts which is my vertex data pointer
for the second lot I was also reading into verts instead of &verts[firstVertsCount]
anyway thanks for the help
Paul

Set uniform color to pixel shader

I am a newbie in DirectX11, so sorry for a dull question.
I have a pixel shader:
struct PixelShaderInput
{
float4 pos : SV_POSITION;
float2 texCoord : TEXCOORD0;
};
Texture2D s_texture : register(t0);
SamplerState s_sampleParams
{
Filter = MIN_MAG_MIP_LINEAR;
AddressU = CLAMP;
AddressV = CLAMP;
};
float4 main(PixelShaderInput input) : SV_TARGET
{
float4 t = s_texture.Sample(s_sampleParams, input.texCoord);
return t;
}
Now I want to add a color to my shader:
struct PixelShaderInput
{
float4 pos : SV_POSITION;
float2 texCoord : TEXCOORD0;
};
Texture2D s_texture : register(t0);
float4 s_color;
SamplerState s_sampleParams
{
Filter = MIN_MAG_MIP_LINEAR;
AddressU = CLAMP;
AddressV = CLAMP;
};
float4 main(PixelShaderInput input) : SV_TARGET
{
float4 t = s_texture.Sample(s_sampleParams, input.texCoord);
return t * s_color;
}
How do I set s_color from C++ code? Do I have to use m_d3dContext->PSSetConstantBuffers? In this case I should change
`float4 s_color;`
to
cbuffer ColorOnlyConstantBuffer : register(b0)
{
float4 m_color;
};
, right?
Or I can keep simple definition float4 s_color; and set it from C++ somehow else?
As far as I remember, you specify input items for vertex shader by using specific structure:
D3D11_INPUT_ELEMENT_DESC inputLayoutDesc[2] =
{
{ "Position",
0,
DXGI_FORMAT_R32G32B32_FLOAT,
0,
D3D11_APPEND_ALIGNED_ELEMENT,
D3D11_INPUT_PER_VERTEX_DATA,
0
},
{ "Color",
0,
DXGI_FORMAT_R32G32B32_FLOAT,
0,
D3D11_APPEND_ALIGNED_ELEMENT,
D3D11_INPUT_PER_VERTEX_DATA,
0
}
};
This structure is being used to create ID3D11InputLayout:
const UINT inputLayoutDescCount = 2;
hr = device->CreateInputLayout(
inputLayoutDesc,
inputLayoutDescCount,
compiledVsShader->GetBufferPointer(),
compiledVsShader->GetBufferSize(),
&inputLayout);
You can then use semantics to specify, which element represents which entry:
struct VS_INPUT
{
float4 Pos : POSITION;
float4 Col : COLOR;
};
Edit: in response to comments.
Sorry, didn't get that. You'll need a constant buffer. Relevant (sample) parts of code follows. Just modify them to your needs:
struct PixelConstantBuffer
{
XMFLOAT4 lightPos;
XMFLOAT4 observerPos;
};
// ***
D3D11_BUFFER_DESC pixelConstantBufferDesc;
pixelConstantBufferDesc.ByteWidth = sizeof(PixelConstantBuffer);
pixelConstantBufferDesc.Usage = D3D11_USAGE_DEFAULT;
pixelConstantBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
pixelConstantBufferDesc.CPUAccessFlags = 0;
pixelConstantBufferDesc.MiscFlags = 0;
pixelConstantBufferDesc.StructureByteStride = 0;
hr = device->CreateBuffer(&pixelConstantBufferDesc, nullptr, &pixelConstantBuffer);
// ***
context->PSSetConstantBuffers(1, 1, &pixelConstantBuffer);
context->PSSetShader(pixelShader, nullptr, 0);
// ***
PixelConstantBuffer pcBuffer;
pcBuffer.lightPos = XMFLOAT4(lightPos.m128_f32[0], lightPos.m128_f32[1], lightPos.m128_f32[2], lightPos.m128_f32[3]);
pcBuffer.observerPos = XMFLOAT4(camPos.m128_f32[0], camPos.m128_f32[1], camPos.m128_f32[2], camPos.m128_f32[3]);
context->UpdateSubresource(pixelConstantBuffer, 0, nullptr, &pcBuffer, 0, 0);
// *** (hlsl)
cbuffer PixelConstantBuffer : register(b1)
{
float4 LightPos;
float4 ObserverPos;
}