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

Started by
8 comments, last by XVincentX 15 years, 10 months ago
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]
Advertisement
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.
Sirob Yes.» - status: Work-O-Rama.
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?
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.
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....
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() ) );	}}
noone knows anything?
nothing?
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.
Finally i resolved it at all.
Thanks to all (:D) for the help!

This topic is closed to new replies.

Advertisement