Render to texture

Started by
4 comments, last by beebs1 15 years, 7 months ago
I want to render to 3 textures using the same geometry each loop, is this possible? I think MRT's is the way to go, but I only want to draw the geometry once not 3 times like I am currently doing. thanks.
Advertisement
You should be able to to bind 3 render targets (as long as the video hardware supports this), and use a pixel shader to output to all 3 at once.

What API are you using?

In Direct3D 9, you can use IDirect3DDevice9::SetRenderTarget().

Then, in your pixel shader, you'd use the output semantics COLOR0, COLOR1, etc to output to different RTs. See here.
Thanks for the fast reply I am using DX 9.0. I can make and set the render targets fine. They work on my machine. I have read what you are talking about and the shader I have is from DBP and the way DBP works is not like how you would do it in C++, so I'm trying to convert this, perhaps there is some way you can look at the shader and then help me figure out what I need to do. Thank you.
No problem, paste it in source tags and we can have a look.
ok thank you here is the shader...

//====================================================// Deferred Shading// By EVOLVED//====================================================//--------------// un-tweaks//--------------   matrix WorldVP:WorldViewProjection;    matrix World:World;       matrix Worldit:WorldInverseTranspose;   matrix ViewInv:ViewInverse; //--------------// tweaks//--------------   float WorldSize=1000;   float3 Ambient = {0.1f, 0.1f, 0.1f};    float Heightvec = 0.025;   float BiasHeight = 0.25;//--------------// Textures//--------------   texture BaseTX     <	string Name="";    >;	   sampler2D Base = sampler_state     { 	texture = <BaseTX>;    };   texture NormalTX    <	string Name="";    >;	   sampler2D Normal = sampler_state     { 	texture = <NormalTX>;    };   texture HeightTX      <	string Name="";      >;	   sampler2D Height = sampler_state       { 	texture = <HeightTX>;      };   texture WorldPosTX       <      	string Name = " ";      >;   sampler2D WorldPos=sampler_state       {	Texture=<WorldPosTX>;   	ADDRESSU = CLAMP;   	ADDRESSV = CLAMP;   	ADDRESSW = CLAMP;	MagFilter = None;	MinFilter = None;	MipFilter = None;      };   texture LightingTX    <	string Name="";    >;	   sampler2D Lighting = sampler_state     { 	texture = <LightingTX>;   	ADDRESSU = CLAMP;   	ADDRESSV = CLAMP;   	ADDRESSW = CLAMP;	MagFilter = None;	MinFilter = None;	MipFilter = None;    };//--------------// structs //--------------   struct input     { 	float4 Pos:POSITION;  	float2 UV:TEXCOORD;	float3 Normal:NORMAL; 	float3 Tangent:TANGENT; 	float3 Binormal:BINORMAL;      };   struct output     {	float4 OPos:POSITION;  	float2 Tex:TEXCOORD0;   	float4 Proj:TEXCOORD1; 	float3 ViewVec:TEXCOORD2;      };   struct In_WorldPos     { 	float4 Pos:POSITION;      };   struct Out_WorldPos     {	float4 OPos:POSITION;   	float3 Wpos:TEXCOORD1;      };   struct In_WorldDepth     { 	float4 Pos:POSITION;      };   struct Out_WorldDepth     {	float4 OPos:POSITION;   	float3 Wpos:TEXCOORD1;   	float4 Proj:TEXCOORD2;      };   struct In_WorldNormals     { 	float4 Pos:POSITION;  	float2 UV:TEXCOORD; 	float3 Normal:NORMAL; 	float3 Tangent:TANGENT; 	float3 Binormal:BINORMAL;     };   struct Out_WorldNormals     {	float4 OPos:POSITION;  	float2 Tex:TEXCOORD0; 	float3 ViewVec:TEXCOORD1;   	float3 tbnRow1:TEXCOORD2;   	float3 tbnRow2:TEXCOORD3;   	float3 tbnRow3:TEXCOORD4;      };//--------------// vertex shader//--------------   output VS(input IN)      { 	output OUT;	OUT.OPos=mul(IN.Pos,WorldVP);  	OUT.Tex=IN.UV;	float4 Vp=float4(OUT.OPos.x*0.5+0.5*OUT.OPos.w,0.5*OUT.OPos.w-        OUT.OPos.y*0.5,OUT.OPos.w,OUT.OPos.w);		OUT.Proj=Vp+float4(0.01,0.01,0,0);	float3x3 TBN={IN.Tangent,IN.Binormal,IN.Normal};	float3 WPos=mul(IN.Pos,World); 	float3 ViewPos=ViewInv[3].xyz-WPos; 	OUT.ViewVec=mul(ViewPos,transpose(mul(TBN,World)));  	return OUT;     }   Out_WorldPos VS_WorldPos(In_WorldPos IN)      { 	Out_WorldPos OUT;	OUT.OPos=mul(IN.Pos,WorldVP);	OUT.Wpos=0.5f+mul(IN.Pos,World)/WorldSize;	return OUT;     }   Out_WorldDepth VS_WorldDepth(In_WorldDepth IN)      { 	Out_WorldDepth OUT;	OUT.OPos=mul(IN.Pos,WorldVP);	OUT.Wpos=mul(IN.Pos,World);	float4 Vp=float4(OUT.OPos.x*0.5+0.5*OUT.OPos.w,0.5*OUT.OPos.w-        OUT.OPos.y*0.5,OUT.OPos.w,OUT.OPos.w);		OUT.Proj=Vp+float4(0.01,0.01,0,0);	return OUT;     }   Out_WorldNormals VS_WorldNormals(In_WorldNormals IN)      { 	Out_WorldNormals OUT;	OUT.OPos=mul(IN.Pos,WorldVP); 	OUT.Tex=IN.UV;	float3x3 TBN={IN.Tangent,IN.Binormal,IN.Normal};	float3 WPos=mul(IN.Pos,World); 	float3 ViewPos=ViewInv[3].xyz-WPos; 	OUT.ViewVec=mul(ViewPos,transpose(mul(TBN,World)));  	TBN=mul(TBN,Worldit);	OUT.tbnRow1=TBN[0];	OUT.tbnRow2=TBN[1];	OUT.tbnRow3=TBN[2];	return OUT;     }//--------------// pixel shader//--------------    float4 PS(output IN)  : COLOR     { 	float3 View=normalize(IN.ViewVec);	float HeightTex=tex2D(Height,IN.Tex).x+BiasHeight; 	float2 NewUv=(Heightvec*HeightTex-0.02)*View+IN.Tex;	float3 Texture=tex2D(Base,NewUv);	float3 Light=tex2Dproj(Lighting,IN.Proj)*1.25;	return float4(Texture*(Light+Ambient),1);     }   float4 PS_WorldPos(Out_WorldPos IN)  : COLOR     {	return float4(IN.Wpos,1);     }   float4 PS_WorldDepth(Out_WorldDepth IN)  : COLOR     {	float3 WPos=(tex2Dproj(WorldPos,IN.Proj)*2-1)*(WorldSize/2);	WPos=0.5f+(IN.Wpos-WPos)/(WorldSize/200);	return float4(WPos,1);     }   float4 PS_WorldNormals(Out_WorldNormals IN)  : COLOR     {	float3 View=normalize(IN.ViewVec);	float HeightTex=tex2D(Height,IN.Tex).x+BiasHeight; 	float2 NewUv=(Heightvec*HeightTex-0.02)*View+IN.Tex;	return float4(0.5f+mul(tex2D(Normal,NewUv)*2-1,float3x3(IN.tbnRow1,IN.tbnRow2,IN.tbnRow3))*0.5f,1);     }//--------------// techniques   //--------------   technique Texture      { 	pass p1      {		 	vertexShader = compile vs_2_0 VS();  	pixelShader  = compile ps_2_0 PS();	      }      }   technique WorldPos      { 	pass p1      {		 	vertexShader = compile vs_2_0 VS_WorldPos();  	pixelShader  = compile ps_2_0 PS_WorldPos(); 	 	//vertexShader = compile vs_2_0 VS_WorldNormals(); // 	pixelShader  = compile ps_2_0 PS_WorldNormals();            }      }   technique WorldDepth      { 	pass p1      {		 	vertexShader = compile vs_2_0 VS_WorldDepth();  	pixelShader  = compile ps_2_0 PS_WorldDepth(); 	      }      }   technique WorldNormals      { 	pass p1      {		 	vertexShader = compile vs_2_0 VS_WorldNormals();  	pixelShader  = compile ps_2_0 PS_WorldNormals(); 	      }      }


I have this shader working but I have to draw the geometry 4 times, also, I'm sure I should be able to draw it once, but the shader needs to be modified, to output to 3 render targets. Thanks.
I think you'll need a new structure to output from the pixel shader (instead of a single colour value), something like this:
struct PSOutput{   float4 RT0 : COLOR0;   // 3 render targets   float4 RT1 : COLOR1;   float4 RT2 : COLOR2;};

Then modify your pixel shader to use it:
PSOutput PS(output IN){   // Initialise the structure   PSOutput Out = (PSOutput)0;   float3 View=normalize(IN.ViewVec);   float HeightTex=tex2D(Height,IN.Tex).x+BiasHeight;    float2 NewUv=(Heightvec*HeightTex-0.02)*View+IN.Tex;   float3 Texture=tex2D(Base,NewUv);   float3 Light=tex2Dproj(Lighting,IN.Proj)*1.25;   // return float4(Texture*(Light+Ambient),1);   // Fill out the structure and return it   Out.RT0 = float4(Texture*(Light+Ambient),1);   Out.RT1 = float4(1.0, 0, 0, 1.0);              // Red   Out.RT2 = float4(0, 1.0, 0, 1.0);              // Green   return Out;}

Also, I believe you need to set the render target colours in order - you can't set COLOR1 without first setting COLOR0, etc.

This topic is closed to new replies.

Advertisement