Hi !

I've tried this morning to mimic a 3D image using one picture + zBuffer instead of the classic way, compute one picture for each eye.

It was it was obviously more complicated than what I expected, but I got something which is nearly functional

It use 4 pass, two θ(1) and two θ(divergence) so it's pretty fast and this can certainly be improved, cuz I'm not very familiar with shader programming

There's still some artifact, especially to fill the "empty" areas for each eye.

It work with red/cyan glasses, I've no 3D TV but I think it could work using frame sequential 3D or side-by-side (but will reduce resolution).

#define pix float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT)
uniform float frames < source = "framecount"; >;
texture2D texR { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8;};
texture2D texL { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8;};
texture2D texC { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA32F;}; //needed to recover accurate coordinates
sampler2D SamplerR
{
Texture = texR;
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = LINEAR;
AddressU = Clamp;
AddressV = Clamp;
};
sampler2D SamplerL
{
Texture = texL;
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = LINEAR;
AddressU = Clamp;
AddressV = Clamp;
};
sampler2D SamplerC
{
Texture = texC;
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = LINEAR;
AddressU = Clamp;
AddressV = Clamp;
};
#define divergence 30
#define RENDER 1 // 1:Anaglyph 2:Frame-by-Frame
#define USE_DUBOIS_CORRECTION 1
#define ANAGLYPHE_DEBUG 0 // 0:None 1:Only Left 2:Only Right
float geth (float2 tex) {
return (pow(abs(1-tex2D(RFX_depthTexColor, tex).r),10));
//return (-1+(pow(abs(1-tex2D(RFX_depthTexColor, tex).r),10))*2); //For depth
}
void PS_calcRL(in float4 position : SV_Position, in float2 tex : TEXCOORD0, out float3 color : SV_Target)
{
color.rgb = float3(0,0,tex.x-divergence*pix.x*geth(tex));
color.r = tex.x+divergence*pix.x*geth(tex);
}
void PS_renderL(in float4 position : SV_Position, in float2 tex : TEXCOORD0, out float3 color : SV_Target)
{
color.rgb = tex2D(RFX_backbufferColor, float2(tex.x-divergence*pix.x*geth(tex), tex.y)).rgb;//tex2D(RFX_backbufferColor, tex).rgb;
for (int i = 0; i <= divergence+1; i++) {
if (tex2D(SamplerC, float2(tex.x-i*pix.x,tex.y)).r >= tex.x-pix.x/2 && tex2D(SamplerC, float2(tex.x-i*pix.x,tex.y)).r <= tex.x+pix.x/2) {
color.rgb = tex2D(RFX_backbufferColor, float2(tex.x-i*pix.x, tex.y)).rgb;
}
}
}
void PS_renderR(in float4 position : SV_Position, in float2 tex : TEXCOORD0, out float3 color : SV_Target)
{
color.rgb = tex2D(RFX_backbufferColor, float2(tex.x+divergence*pix.x*geth(tex), tex.y)).rgb;
float2 col = float2 (0,0);
for (int j = 0; j <= divergence+1; j++) {
if (tex2D(SamplerC, float2(tex.x+j*pix.x,tex.y)).b >= tex.x-pix.x/2 && tex2D(SamplerC, float2(tex.x+j*pix.x,tex.y)).b <= tex.x+pix.x/2) {
color.rgb = tex2D(RFX_backbufferColor, float2(tex.x+j*pix.x, tex.y)).rgb;
}
}
}
void PS_DisplayDepth(in float4 position : SV_Position, in float2 tex : TEXCOORD0, out float3 color : SV_Target)
{
float4 l = tex2D(SamplerR, tex);
float4 r = tex2D(SamplerL, tex);
#if RENDER == 1
#if USE_DUBOIS_CORRECTION == 1
float red = 0.456100 * l.r + 0.500484 * l.g + 0.176381 * l.b
- 0.0434706 * r.r - 0.0879388 * r.g - 0.00155529 * r.b;
if (red > 1) { red = 1; } if (red < 0) { red = 0; }
float green = -0.0400822 * l.r - 0.0378246 * l.g
-0.0157589 * l.b + 0.378476 * r.r
+0.73364 * r.g - 0.0184503 * r.b;
if (green > 1) { green = 1; } if (green < 0) { green = 0; }
float blue = -0.0152161 * l.r - 0.0205971 * l.g
-0.00546856 * l.b - 0.0721527 * r.r
-0.112961 * r.g + 1.2264 * r.b;
if (blue > 1) { blue = 1; } if (blue < 0) { blue = 0; }
color.rgb = float3(red, green, blue);
#endif
#if USE_DUBOIS_CORRECTION == 0
color.rgb = l.rgb;
color.r = r.r;
#endif
#endif
#if RENDER == 2
if ((frames%2) == 0) {
color.rgb = l.rgb;
} else {
color.rgb = r.rgb;
}
#endif
#if ANAGLYPHE_DEBUG == 1
color.rgb = l.rgb;
#endif
#if ANAGLYPHE_DEBUG == 2
color.rgb = r.rgb;
#endif
}
technique Depth_Tech < enabled = true; toggle = Depth_ToggleKey;>
{
pass
{
VertexShader = RFX_VS_PostProcess;
PixelShader = PS_calcRL;
RenderTarget = texC;
}
pass
{
VertexShader = RFX_VS_PostProcess;
PixelShader = PS_renderR;
RenderTarget = texR;
}
pass
{
VertexShader = RFX_VS_PostProcess;
PixelShader = PS_renderL;
RenderTarget = texL;
}
pass
{
VertexShader = RFX_VS_PostProcess;
PixelShader = PS_DisplayDepth;
}
}

If you have some idea to improve this, I take