Sign in to follow this  

Indexed Multiple render targets in D3D10[NEWS...READ PLEASE]

This topic is 3480 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, i'm trying to make an example of D3D10's new feature: Indexed Multiple Render Target. So at first, i've created the second rendertarget and depth stencil as an array
	ID3D10Texture2D *text;
	D3D10_TEXTURE2D_DESC desc;

	desc.Width = 400;
	desc.Height = 400;
	desc.MipLevels = 1;
	desc.ArraySize = num;
	desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	desc.SampleDesc.Count = 1;
	desc.SampleDesc.Quality = 0;
	desc.Usage = D3D10_USAGE_DEFAULT;
	desc.BindFlags = D3D10_BIND_SHADER_RESOURCE | D3D10_BIND_RENDER_TARGET;
	desc.CPUAccessFlags = 0;
	desc.MiscFlags = 0;

	device->CreateTexture2D(&desc,0,&text);

	{
		D3D10_RENDER_TARGET_VIEW_DESC dc;

		dc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
		dc.ViewDimension = D3D10_RTV_DIMENSION_TEXTURE2DARRAY;
		dc.Texture2DArray.ArraySize = num;
		dc.Texture2DArray.FirstArraySlice = 0;
		dc.Texture2DArray.MipSlice = 0;

		device->CreateRenderTargetView(text,&dc,&rendertarget);
	}

	{
		D3D10_SHADER_RESOURCE_VIEW_DESC dc;
		dc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
		dc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2DARRAY;
		dc.Texture2D.MipLevels = 1;
		dc.Texture2DArray.MostDetailedMip = 0;
		dc.Texture2DArray.FirstArraySlice = 0;
		dc.Texture2DArray.ArraySize = num;

		device->CreateShaderResourceView(text,&dc,&ShaderText);
	}

	{
		text->Release();

		D3D10_DEPTH_STENCIL_VIEW_DESC dc;
		desc.BindFlags = D3D10_BIND_DEPTH_STENCIL;
		desc.Format = DXGI_FORMAT_D32_FLOAT;

		device->CreateTexture2D(&desc,NULL,&text);

		dc.Format = DXGI_FORMAT_D32_FLOAT;
		dc.ViewDimension = D3D10_DSV_DIMENSION_TEXTURE2DARRAY;
		dc.Texture2DArray.MipSlice = 0;
		dc.Texture2DArray.ArraySize = num;
		dc.Texture2DArray.FirstArraySlice = 0;

		device->CreateDepthStencilView(text,&dc,&depth);

		text->Release();
	}



But now? I read somewhere that i'm forced to use Geometry Shader, and that i've to consider the presence of an uint that indicates the Index of Render Target. Other infos? [Edited by - XVincentX on June 5, 2008 1:43:07 PM]

Share this post


Link to post
Share on other sites
The Cube Map GS sample uses that technique to render to the different faces of a cube map. You can look at the sample to get all the info you need.

Alternatively, the docs have some info on it in the Semantics Article. Search for SV_RenderTargetArrayIndex.

Share this post


Link to post
Share on other sites
I tried to understand the tutorial but nothing.
I ask help you again.

My intentions is to render the same scene (6) on a cube, but each one with a different color. So:


__forceinline void MakeRenderTarget(int num)
{
ID3D10Texture2D *text;
D3D10_TEXTURE2D_DESC desc;

desc.Width = 400;
desc.Height = 400;
desc.MipLevels = 1;
desc.ArraySize = num;
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D10_USAGE_DEFAULT;
desc.BindFlags = D3D10_BIND_SHADER_RESOURCE | D3D10_BIND_RENDER_TARGET;
desc.CPUAccessFlags = 0;
desc.MiscFlags = 0;

device->CreateTexture2D(&desc,0,&text);

{
D3D10_RENDER_TARGET_VIEW_DESC dc;

dc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
dc.ViewDimension = D3D10_RTV_DIMENSION_TEXTURE2DARRAY;
dc.Texture2DArray.ArraySize = num;
dc.Texture2DArray.FirstArraySlice = 0;
dc.Texture2DArray.MipSlice = 0;

device->CreateRenderTargetView(text,&dc,&rendertarget);
}

{
D3D10_SHADER_RESOURCE_VIEW_DESC dc;
dc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
dc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2DARRAY;
dc.Texture2D.MipLevels = 1;
dc.Texture2DArray.MostDetailedMip = 0;
dc.Texture2DArray.FirstArraySlice = 0;
dc.Texture2DArray.ArraySize = num;

device->CreateShaderResourceView(text,&dc,&ShaderText);
}

{
text->Release();

D3D10_DEPTH_STENCIL_VIEW_DESC dc;
desc.BindFlags = D3D10_BIND_DEPTH_STENCIL;
desc.Format = DXGI_FORMAT_D32_FLOAT;

device->CreateTexture2D(&desc,NULL,&text);

dc.Format = DXGI_FORMAT_D32_FLOAT;
dc.ViewDimension = D3D10_DSV_DIMENSION_TEXTURE2DARRAY;
dc.Texture2DArray.MipSlice = 0;
dc.Texture2DArray.ArraySize = num;
dc.Texture2DArray.FirstArraySlice = 0;

device->CreateDepthStencilView(text,&dc,&depth);

text->Release();
}

}





In this way, i build up a rendertargets array to render on it.
After, in the rendering function


...
shader->GetVariableByIndex(7)->AsShaderResource()->SetResource(ShaderText);
shader->GetVariableByIndex(1)->AsMatrix()->SetMatrix((float*)&mat);
shader->GetTechniqueByIndex(0)->GetPassByIndex(1)->Apply(0);

Cubo.DrawCollada(device); //works, do not warry.


swapChain->Present(0,0); //Front buffer presentation.
...




And this is the shader


float4x4 ViewMatrix;
float4x4 WorldMatrix;
float4x4 ProjMatrix;
float4 LightDirection;
float4 MaterialColor;
float3 EyePosition;
texture2D Texture;
Texture2DArray RenderText;

SamplerState SamplText
{
Filter = MIN_MAG_MIP_LINEAR;
AddressU = Wrap;
AddressV = Wrap;
};

SamplerState RenderSampl
{
Filter = MIN_MAG_MIP_LINEAR;
AddressU = Mirror;
AddressV = Mirror;
};

struct VS_INPUT
{
float4 Pos : POSITION;
float3 Tex : TEXCOORD;
float3 Nor : NORMAL;
};

struct PS_INPUT
{
float4 Pos : SV_POSITION;
float4 WorldPos: WORLDPOSITION;
float3 Tex : TEXCOORD;
float3 Nor : NORMAL;
};

PS_INPUT vs_main(VS_INPUT Input)
{
PS_INPUT Out = (PS_INPUT)0;
Out.Pos = mul(mul(mul(Input.Pos,WorldMatrix),ViewMatrix),ProjMatrix);
Out.WorldPos = mul(Input.Pos,WorldMatrix);
Out.Tex = Input.Tex;
Out.Nor = mul(Input.Nor,WorldMatrix);
return Out;
}

float4 ps_main(PS_INPUT In) : SV_TARGET
{
float3 L = normalize(LightDirection.xyz);
float4 D = saturate(dot(In.Nor,L) * float4(1,0.0,0.0,1) * MaterialColor);
float3 V = normalize(EyePosition - In.WorldPos);
float3 R = normalize(2.0F * In.Nor * dot(In.Nor,L) - L);
float4 S = pow(max(0.0F,dot(R,V)),10);

return saturate(D + S);

}

struct VGS_TEXT_INPUT
{
float4 Pos : POSITION;
float2 Tex : TEXCOORD;
};

struct PS_TEXT_INPUT
{
float4 Pos : SV_POSITION;
float2 Tex : TEXCOORD;
uint Index: SV_RenderTargetArrayIndex;
};



VGS_TEXT_INPUT vs_text_main(VGS_TEXT_INPUT In)
{
return In;
}

[maxvertexcount(24)]
void gs_text_main(triangle VGS_TEXT_INPUT In[3],inout TriangleStream<PS_TEXT_INPUT> Stream)
{
PS_TEXT_INPUT New = (PS_TEXT_INPUT)0;
for (int i = 0; i < 6; i++)
{
New.Index = i;

for (int t = 0; t < 3; t++)
{
New.Tex = In[t].Tex;
New.Pos = mul(mul(mul(In[t].Pos,WorldMatrix),ViewMatrix),ProjMatrix);

Stream.Append(New);
}

Stream.RestartStrip();
}
}

float4 ps_text_main(PS_TEXT_INPUT In) : SV_TARGET
{
return RenderText.Sample(RenderSampl,float3(In.Tex,In.Index)) * In.Index;
}

technique10 RenderToTexture
{
Pass WhatYouWantToRenderOnTheTexture
{
SetVertexShader( CompileShader( vs_4_0, vs_main() ) );
SetGeometryShader(NULL);
SetPixelShader( CompileShader( ps_4_0, ps_main() ) );
}

Pass TexturePass
{
SetVertexShader( CompileShader( vs_4_0,vs_text_main() ) );
SetGeometryShader( CompileShader ( gs_4_0, gs_text_main() ) );
SetPixelShader( CompileShader( ps_4_0,ps_text_main() ) );
}
}




If i compile and run, i see all the cube black.
If i remove the multiplication * In.Index in pixel shader, i can see the same scene on all the cube; but if in the index of float3 i write 0 i see the same scene on all the cube. If i write 1, i can see only the color of render target clear, but not the mesh drawn on it.
What's wrong?

Share this post


Link to post
Share on other sites
SV_RenderTargetArrayIndex is only an output value from the GS to the rasteriser, and can't be accessed in the pixel shader. Looks like you're getting 0 when you try to access it, and therefore you get black when multiplying by it.

If you need to get the index in the PS, pass it as another value with a different semantic.

Share this post


Link to post
Share on other sites
Ok, but why if i write 0 in the Sample function, it works propely?
It should show me only a face with the mesh rendered on it.

If i can't use it in the pixel shader...i shoul pass it as another uint....

Share this post


Link to post
Share on other sites
I tried by using a new value as index, but nothing:


float4x4 ViewMatrix;
float4x4 WorldMatrix;
float4x4 ProjMatrix;
float4 LightDirection;
float4 MaterialColor;
float3 EyePosition;
texture2D Texture;
Texture2DArray RenderText;

SamplerState SamplText
{
Filter = MIN_MAG_MIP_LINEAR;
AddressU = Wrap;
AddressV = Wrap;
};

SamplerState RenderSampl
{
Filter = MIN_MAG_MIP_LINEAR;
AddressU = Mirror;
AddressV = Mirror;
};

struct VS_INPUT
{
float4 Pos : POSITION;
float3 Tex : TEXCOORD;
float3 Nor : NORMAL;
};

struct PS_INPUT
{
float4 Pos : SV_POSITION;
float4 WorldPos: WORLDPOSITION;
float3 Tex : TEXCOORD;
float3 Nor : NORMAL;
};

PS_INPUT vs_main(VS_INPUT Input)
{
PS_INPUT Out = (PS_INPUT)0;
Out.Pos = mul(mul(mul(Input.Pos,WorldMatrix),ViewMatrix),ProjMatrix);
Out.WorldPos = mul(Input.Pos,WorldMatrix);
Out.Tex = Input.Tex;
Out.Nor = mul(Input.Nor,WorldMatrix);
return Out;
}

float4 ps_main(PS_INPUT In) : SV_TARGET
{
float3 L = normalize(LightDirection.xyz);
float4 D = saturate(dot(In.Nor,L) * float4(1,0.0,0.0,1) * MaterialColor);
float3 V = normalize(EyePosition - In.WorldPos);
float3 R = normalize(2.0F * In.Nor * dot(In.Nor,L) - L);
float4 S = pow(max(0.0F,dot(R,V)),10);

return saturate(D + S);

}

struct VGS_TEXT_INPUT
{
float4 Pos : POSITION;
float2 Tex : TEXCOORD;
};

struct PS_TEXT_INPUT
{
float4 Pos : SV_POSITION;
float2 Tex : TEXCOORD;
uint RTIndex: SV_RenderTargetArrayIndex;
uint Index:POPPI;
};



VGS_TEXT_INPUT vs_text_main(VGS_TEXT_INPUT In)
{
return In;
}

[maxvertexcount(24)]
void gs_text_main(triangle VGS_TEXT_INPUT In[3],inout TriangleStream<PS_TEXT_INPUT> Stream)
{
PS_TEXT_INPUT New = (PS_TEXT_INPUT)0;
for (int i = 0; i < 6; i++)
{
New.Index = i;
New.RTIndex = i;

for (int t = 0; t < 3; t++)
{
New.Tex = In[t].Tex;
New.Pos = mul(mul(mul(In[t].Pos,WorldMatrix),ViewMatrix),ProjMatrix);

Stream.Append(New);
}

Stream.RestartStrip();
}
}

float4 ps_text_main(PS_TEXT_INPUT In) : SV_TARGET
{
return RenderText.Sample(RenderSampl,float3(In.Tex,In.Index)) * In.Index;
}

technique10 RenderToTexture
{
Pass WhatYouWantToRenderOnTheTexture
{
SetVertexShader( CompileShader( vs_4_0, vs_main() ) );
SetGeometryShader(NULL);
SetPixelShader( CompileShader( ps_4_0, ps_main() ) );
}

Pass TexturePass
{
SetVertexShader( CompileShader( vs_4_0,vs_text_main() ) );
SetGeometryShader( CompileShader ( gs_4_0, gs_text_main() ) );
SetPixelShader( CompileShader( ps_4_0,ps_text_main() ) );
}
}

Share this post


Link to post
Share on other sites
There are some news in my "mission".
I finally resolved the problem: all the logic was completely wrong, now i've fixed it and it seems to work.

Now there is another problem: after i've set the RenderTargetIndexArray, i use another uint calle face, to set the index of render target view.

In this way, i render my cube, on which there are meshes drawn.



for (int i = 0; i < 6; i++)
{
shader->GetVariableByIndex(5)->AsScalar()->SetInt(i);
shader->GetTechniqueByIndex(0)->GetPassByIndex(1)->Apply(0);

Cubo.DrawCollada(device);
}





Now the problem is that i see, on all cube's quads, the same face, but this time, if i change the index of render target, it works.
Little example:
Cube's Pixel Shader


float4 ps_main(PS_INPUT In) : SV_TARGET
{
return ArrayText.Sample(RenderSampl,float3(In.Tex,3)); //3 it's index
}




ArrayText it's a Texture2DArray
With index = 0
Poppi
with index = 1
Poppi2

Now the code works, the problem it's that the cube it's rendered each time with a new index, and it's overwritten. So at last there is only the last index (5), by using face (set in the shader from the code above).

A my friend suggested me to draw the cube by dividing it into little subsets. Actually i make an unique DrawIndexed(Indices,0,0); to draw it, and i do not know how to split it. So i tried a solution from the shader, in this way



float4 ps_main(PS_INPUT In) : SV_TARGET
{
[unroll] for (int i = 0; i < 6; i++)
{
if (i == Face)
{
return ArrayText.Sample(RenderSampl,float3(In.Tex,3));
break;
}
else
{
continue;
}
}

return 0;
}





But i gained no results.
So, how can i show on each face a different mesh's position?
Let me know if you don't understand.

Share this post


Link to post
Share on other sites

This topic is 3480 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this