Hello,
could you please provide a complete working code ?
I'm also trying to reconstruct the 3D position from the depth pixel value, but I keep the viewspace and use a ray to get the source position.
It's almost working but I hate maths and I don't really understand why the precision is perfect on the middle of the screen but loose on the sides.
I think I have to manage the perspective matrix but I don't understand what your "createPerspProjMatrix" do.
here my shader code (I use MRT for subentity selection) :
Code: Select all
float4 pack(float value)
{
float4 shift = float4(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0);
float4 mask = float4(0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0);
float4 ret = frac(value * shift);
ret -= ret.xxyz * mask;
return ret.wzyx;
}
// vertex shader main entry
void main_plain_color_vp(
float4 position: POSITION,
out float4 oPos: POSITION,
out float4 oColor: TEXCOORD0,
out float2 oDepth: TEXCOORD1,
uniform float4x4 worldViewProj,
uniform float4 texelOffsets,
uniform float4 inColor
)
{
oPos = mul(worldViewProj, position); // calculate output coords
oPos.xy += texelOffsets.zw * oPos.w;
oDepth = oPos.zw;
oColor = inColor;
}
void main_plain_color_fp(
float4 position: POSITION,
float4 iColor: TEXCOORD0,
float2 iDepth: TEXCOORD1,
out float4 Colour0 : COLOR0,
out float4 Colour1 : COLOR1
)
{
Colour0 = iColor;
//depth mrt
float fdepth = iDepth.x / iDepth.y;
Colour1 = pack(fdepth);
}
part that retrieve the depth pixel value (it's a 1x1 texture for performances)
Code: Select all
Ogre::Pass* pickerPass = pickerTech->getPass(0);
Ogre::GpuProgramParametersSharedPtr fparams = pickerPass->getFragmentProgramParameters();
fparams->setNamedConstant("inMouse", mousePos);
pickerPass->getTextureUnitState(0)->setTexture(mOgreDepthTexture);
mOgrePickerRenderTexture->update();
mOgrePickerRenderTexture->copyContentsToMemory(Ogre::Box(0, 0, 1, 1), *mOgrePixelBox, Ogre::RenderTarget::FB_AUTO);
ogreColour = mOgrePixelBox->getColourAt(0, 0, 0);
//unpack RGBA to float
Ogre::Vector4 shift(1.0f / (256.0f * 256.0f * 256.0f), 1.0f / (256.0f * 256.0f), 1.0f / 256.0f, 1.0f);
zpos = Ogre::Vector4(ogreColour.a, ogreColour.b, ogreColour.g, ogreColour.r).dotProduct(shift);
and finally my fail code to reconstruct
Code: Select all
Ogre::Matrix4 wvp = camera->getProjectionMatrixRS();
// x & y are in range [-1; 1]; zdepth is the value you got from the depth buffer.
Ogre::Vector4 clipSpaceValue(xR * 2.0f - 1.0f, yR * 2.0f - 1.0f, zdepth, 1.0f);
Ogre::Vector4 viewPos = wvp.inverse() * clipSpaceValue;
viewPos /= viewPos.w;
Ogre::Ray ray = camera->getCameraToViewportRay(xR, yR);
pos = ray.getOrigin() + (ray.getDirection() * viewPos.z);