WIP Stereoscopic 3D support for half/full SBS, over/under, etc
People , i have a fairly good pixel and vertex shader knowledge , i already developed an app that uses pixel shaders and support all kind of 3d

So i will post pixel shader for all kinds of 3D (Including line interleaved) that has the ability to display half size or full size or even 2D
As well as controlling depth and vertical alignment of the 2 cameras which is useful when the 3d is recorded with 2 Different video cams
That has some mis vertical alignment.
This is done with shader input parameters that if manipulated with the application can control 3D parameters.

So the only missing thing now is the subtitles 3d depth adjustment , if some one figures out how to do it then we will have a complete 3D solution.

Now enough of all that here are the actual pixel shaders i really hope that they come in handy:

///////////////Red-Cyan Anaglyph
sampler s0 : register(s0); // Video Texture
float fTU; // Width of the texture in Texels (0.0 to 1.0) (In our case the texture has the same resolution as the screen so we can put this =1.0)
float fTV; // Height of the texture in Texels (0.0 to 1.0)(In our case the texture has the same resolution as the screen so we can put this =1.0)
float depthDistanceV; // Vertical Offset in Texels
float depthDistanceH; // Horizontal Offset in Texels
bool displayOneSide; // TRUE if need to view 2D side only, FALSE if view 3D
bool reverseLR; // To Reverse Left and Right Cameras
bool isFullWidth; // TRUE for full size 3D, FALSE for half size
float scaleFactorX; // Scaling in Width for the viewing window (In case of full screen this =1.0 )
float scaleFactorY; // Scaling in Height for the viewing window (In case of full screen this =1.0 )

float4 main(float2 tex0 : TEXCOORD0) : COLOR
{
float4 stereoscope;
if (!isFullWidth) tex0.x *= scaleFactorX;
float4 l = tex2D(s0, tex0);
if (displayOneSide)
stereoscope = l;
else
{
float4 r;
tex0.x += fTU / 2.0 - depthDistanceH;
tex0.y += depthDistanceV;
if (tex0.x < fTU / 2.0f || tex0.x > fTU || tex0.y < 0.0 || tex0.y > fTV)
{
l = float4(0, 0, 0, 1);
r = float4(0, 0, 0, 1);
}
else
{
r = tex2D(s0, tex0);
}
if (!reverseLR)
{
float redGray = dot(l, float4(0.299, 0.587, 0.114, 0));
stereoscope = float4(redGray, r.g, r.b, 1.0);
}
else
{
float redGray = dot(r, float4(0.299, 0.587, 0.114, 0));
stereoscope = float4(redGray, l.g, l.b, 1.0);
}
}
return stereoscope;
}

//////////////Green Magenta
sampler s0 : register(s0); // Video Texture
float fTU; // Width of the texture in Texels (0.0 to 1.0)
float fTV; // Height of the texture in Texels (0.0 to 1.0)
float depthDistanceV; // Vertical Offset in Texels
float depthDistanceH; // Horizontal Offset in Texels
bool displayOneSide; // TRUE if need to view 2D side only, FALSE if view 3D
bool reverseLR; // To Reverse Left and Right Cameras
bool isFullWidth; // TRUE for full size 3D, FALSE for half size
float scaleFactorX; // Scaling in Width for the viewing window
float scaleFactorY; // Scaling in Height for the viewing window

float4 main(float2 tex0 : TEXCOORD0) : COLOR
{
float4 stereoscope;
if (!isFullWidth) tex0.x *= scaleFactorX;
float4 l = tex2D(s0, tex0);
if (displayOneSide)
stereoscope = l;
else
{
float4 r;
tex0.x += fTU / 2.0f - depthDistanceH;
tex0.y += depthDistanceV;
if (tex0.x < fTU / 2.0f || tex0.x > fTU || tex0.y < 0.0 || tex0.y > fTV)
{
l = float4(0, 0, 0, 1);
r = float4(0, 0, 0, 1);
}
else
{
r = tex2D(s0, tex0);
}
if (!reverseLR) stereoscope = float4(r.r * 1.2, l.g * 1.2, r.b * 1.2, 1.0);
else stereoscope = float4(l.r * 1.2, r.g * 1.2, l.b * 1.2, 1.0);
}
return stereoscope;
};

//////////////Color Coded (Blue amber)
sampler s0 : register(s0); // Video Texture
float fTU; // Width of the texture in Texels (0.0 to 1.0)
float fTV; // Height of the texture in Texels (0.0 to 1.0)
float depthDistanceV; // Vertical Offset in Texels
float depthDistanceH; // Horizontal Offset in Texels
bool displayOneSide; // TRUE if need to view 2D side only, FALSE if view 3D
bool reverseLR; // To Reverse Left and Right Cameras
bool isFullWidth; // TRUE for full size 3D, FALSE for half size
float scaleFactorX; // Scaling in Width for the viewing window
float scaleFactorY; // Scaling in Height for the viewing window

float4 main(float2 tex0 : TEXCOORD0) : COLOR
{
float4 stereoscope;
if (!isFullWidth) tex0.x *= scaleFactorX;
float4 l = tex2D(s0, tex0);
if (displayOneSide)
stereoscope = l;
else
{
float4 r;
tex0.x += fTU / 2.0f - depthDistanceH;
tex0.y += depthDistanceV;
if (tex0.x < fTU / 2.0f || tex0.x > fTU || tex0.y < 0.0 || tex0.y > fTV)
{
l = float4(0, 0, 0, 1);
r = float4(0, 0, 0, 1);
}
else
{
r = tex2D(s0, tex0);
}
if (!reverseLR){
float blueGray = dot(r, float4(0.15, 0.15, 0.99, 0));
stereoscope = float4(l.r * 1.25, l.g * 1.25, blueGray * 1.25, 1.0);}
else{
float blueGray = dot(l, float4(0.15, 0.15, 0.99, 0));
stereoscope = float4(r.r * 1.25, r.g * 1.25, blueGray * 1.25, 1.0);}
}
return stereoscope;
};

//////Line Interleaved
struct VertexPositionTextureTexture {
float4 Position : POSITION0;
float2 Texture : TEXCOORD0;
float2 NormalisedTexture : TEXCOORD1;
};

sampler ImageSampler : register(s0); // Video Texture
float fTU; // Width of the texture in Texels (0.0 to 1.0)
float fTV; // Height of the texture in Texels (0.0 to 1.0)
float depthDistanceV; // Vertical Offset in Texels
float depthDistanceH; // Height of the texture in Texels (0.0 to 1.0)
float height; // Video Height
float posY; // The Top Left Y position of the viewer window
bool displayOneSide; // TRUE if need to view 2D side only, FALSE if view 3D
bool reverseLR; // To Reverse Left and Right Cameras
float scaleFactorX; // Scaling in Width for the viewing window
float scaleFactorY; // Scaling in Height for the viewing window

float4 main(VertexPositionTextureTexture input ) : COLOR0
{
float4 retColor = float4(0.0, 0.0, 0.0, 1.0);

input.Texture.x *= scaleFactorX;
input.Texture.y *= scaleFactorY;

if (displayOneSide)
retColor = tex2D(ImageSampler, input.Texture);
else
{
float ry = (input.Texture.y * (height / scaleFactorY) + posY) * 0.5f;
float4 retColorL = float4(1.0, 1.0, 1.0, 1.0);
float4 retColorR = float4(0.0, 0.0, 0.0, 1.0);
retColorL = tex2D(ImageSampler, input.Texture);
input.Texture.x = input.Texture.x + fTU / 2.0f - depthDistanceH;
input.Texture.y = input.Texture.y + depthDistanceV;
if (input.Texture.y >= 0.0 && input.Texture.y <= fTV)
retColorR = tex2D(ImageSampler, input.Texture);
else
{
retColorL = float4(0.0, 0.0, 0.0, 1.0);
retColorR = float4(0.0, 0.0, 0.0, 1.0);
}
input.Texture.x = input.Texture.x - fTU / 2.0f;
if (input.Texture.x <= fTU / 2.0f && input.Texture.x >= 0.0)
{
float rem = abs(ry - round(ry));
if (rem < 0.1f)
{
if (!reverseLR)
retColor = retColorR;
else
retColor = retColorL;
}
else
{
if (!reverseLR)
retColor = retColorL;
else
retColor = retColorR;
}
}
else
{
retColorL = float4(0.0, 0.0, 0.0, 1.0);
retColorR = float4(0.0, 0.0, 0.0, 1.0);
}
}
return retColor;
}

//////////////Side by Side
sampler s0 : register(s0); // Video Texture
bool displayOneSide; // TRUE if need to view 2D side only, FALSE if view 3D
bool isFullWidth; // TRUE for full size 3D, FALSE for half size

float4 main(float2 tex0 : TEXCOORD0) : COLOR
{
float4 retColor = float4(0.0, 0.0, 0.0, 1.0);
if (isFullWidth) tex0.x *= 2.0;
if (displayOneSide)
{
tex0.x = tex0.x / 2.0;
retColor = tex2D(s0, tex0);
}
else
retColor = tex2D(s0, tex0);
return retColor;
};
Reply


Messages In This Thread
RE: Stereoscopic 3D support for half/full SBS, over/under, etc - by opengl1971 - 2013-12-25, 12:32
Intel® InTru™ 3D support - by acidizer - 2014-01-26, 12:47


Logout Mark Read Team Forum Stats Members Help
Stereoscopic 3D support for half/full SBS, over/under, etc11
This forum uses Lukasz Tkacz MyBB addons.