Game Development Community

CustomMaterial Back Buffer Refraction

by Tim Dix (Raverix) · in Torque 3D Professional · 09/04/2010 (5:31 pm) · 12 replies

What's the correct way to get the back buffer into a custom material shader? Using the water shader as a guide, I currently have:

singleton CustomMaterial( RefractMat )
{
...
   sampler["backbuff"] = "$backbuff";
}

But I'm always getting a completely black object with:
#define IN_HLSL
#include "shdrConsts.h"

//-----------------------------------------------------------------------------
// Structures                                                                  
//-----------------------------------------------------------------------------
struct ConnectData
{
   float2 texCoord        : TEXCOORD0;
   float3 eyePos          : TEXCOORD1;
   float3 normal          : TEXCOORD2;
   float3 pos             : TEXCOORD3;
   float4 hpos2           : TEXCOORD4;
   float3 screenNorm      : TEXCOORD5;
   float3 lightVec        : TEXCOORD6;
};


struct Fragout
{
   float4 col : COLOR0;
};


//-----------------------------------------------------------------------------
// Main                                                                        
//-----------------------------------------------------------------------------
Fragout main( ConnectData IN,
              uniform sampler2D refractMap   : register(S0),
              uniform sampler2D colorMap     : register(S1),
              uniform sampler2D diffuseMap   : register(S2),
	      uniform sampler   backbuff : register( S3 )
)
{
   Fragout OUT;


   OUT.col = tex2D(backbuff, IN.texCoord);
   return OUT;
}

Note all my other maps are correctly passed in.

#1
09/04/2010 (6:53 pm)
Looks correct.
Use sampler2D for backbuff.
#2
09/04/2010 (8:48 pm)
I have tried both sampler2D, and sampler, neither one is working for me. waterP.hlsl has the following:

uniform sampler      bumpMap     : register( S0 );
uniform sampler2D    prepassTex  : register( S1 );
uniform sampler2D    reflectMap  : register( S2 );
uniform sampler      refractBuff : register( S3 );
uniform samplerCUBE  skyMap      : register( S4 );
uniform sampler      foamMap     : register( S5 );


which is why I'm using the sampler right now, but to be honest, I'm not sure what the difference is.
#3
09/04/2010 (9:55 pm)
sgData.backBuffTex is always null.

case Material::BackBuff:
   GFX->setTexture( i, sgData.backBuffTex );
   break;
}

Despite code to set the the shader register, apparently you still have to manually set the back buff texture yourself. Maybe stock code will set this automatically? As I see it now, if you want to use this custom material on an object, you'll need to modify engine code to enable this.
sgData.backBuffTex = REFLECTMGR->getRefractTex();
#4
09/05/2010 (7:14 pm)
@Tim

Stock refraction effects had been broken for a while now. I've been wanting to expose them to materials, but haven't had the time.

The big question is how often do you take a refraction copy of the back buffer?

Currently REFLECTMGR->getRefractTex() make a refraction copy of the back buffer once per-frame... the first call has it make a copy and all other calls get the same surface.

I'm unsure how expensive a backbuffer copy is on a graphics device. If its minor it could be possible to let it make a copy on every request. If its more expensive i could maybe let it make a copy once per-render bin.
#5
09/07/2010 (5:58 pm)
When I did my quick work around, I was doing it on every frame, and for my debug build, that dropped me from ~30 to ~15, so I'm not sure it's worth it. Don't know, stress testing would help I guess.

Perhaps exposing some type of 'accepted staleness' attribute to the material?

Any chance that this will make it into 1.1 final, or should I continue to work on my own solution?

Ya know, now I'm curious... I don't have the code in front of me, but what I was doing was basically:

case Material::BackBuff:
   if(!sgData.backBuffTex)
       sgData.backBuffTex = REFLECTMGR->getRefractTex();  
   GFX->setTexture( i, sgData.backBuffTex );
   break;
}

Was that every frame, or every pass?
#6
09/07/2010 (6:51 pm)
Quote:Any chance that this will make it into 1.1 final
I don't think so... we want to get 1.1 finished so we can move to a more fluid release process.

Quote:Was that every frame, or every pass?
That is once per-frame... that really shouldn't hurt you framerate very much.
#7
02/16/2011 (5:08 am)
Let's give a bump to this...
Its an old thread but I don't see a good "flagship" engine without refraction...
#8
02/16/2011 (10:06 am)
I agree, TGEA had this..and T3D does not. A tad silly.
#9
03/15/2011 (1:26 pm)
Greetings!

Logged as THREED-1449 so we don't lose it. Thanks!

- Dave
#10
11/27/2011 (7:02 pm)
Another bump for this thread.

Getting something like the blobRefract shader effect from TGEA 1.03 would be nice.
#11
04/17/2013 (9:57 pm)
"Logged as THREED-1449 so we don't lose it. Thanks!"
was that fixed?

"we want to get 1.1 finished so we can move to a more fluid release process."
what means " fluid release process" ?
#12
04/18/2013 (8:17 am)
By "fluid" he probably meant "smoother and more reactive" - but I'm just guessing.

Two year old comments - particularly when discussing a completely different product structure - are rarely relevant to today's situation. Since GarageGames is not governing this process anymore the comment is no longer applicable. You'll have to take it up with the current Steering Committee.... lol