Multiple View Postprocessing Shader (Oculus Rift)

Posted By: yorisimo

Multiple View Postprocessing Shader (Oculus Rift) - 11/04/13 22:30

I am trying to implement the postprocessing pixel shader required for use of the Oculus Rift with GS.

To use Oculus, you create two views (a left and right eye view displayed simultaneously on the screen). You then apply a pixel shader to distort the views (so that they look correct when looking through the Oculus lenses). The problem is I can't get them to both show up distorted at the same time. If I enable both distortion modes the right side goes black. It seems to have something to do with what gets rendered when and that the pixel shader affects all the pixels on the screen not just in that view. What would be the best way to go about getting both views distorted and rendered simultaneously?

PS, I plan to work on and share a plug-in for enabling the Oculus head tracking in GS games as well

Non-Distorted View:


Left View Distorted:


Right View Distorted:


Here's the Pixel shader:
Code:
//Texture2D Texture : register(t0);
//SamplerState Linear : register(s0);
Texture TargetMap;
sampler2D g_samSrcColor = sampler_state { texture = <TargetMap>; MipFilter = Linear;	};

float4 vecSkill1;//DistortK
float4 vecSkill5;//x,y,xCenterOffset, DistortScale

	
float4 postprocessing_undistort(float2 texCoordIn : TEXCOORD0) : COLOR0 				
{
	float2 texCoordOut=texCoordIn;
	
	float2 LensCenter = {vecSkill5.x+(0.5+vecSkill5.z*0.5)*0.5, vecSkill5.y + 0.5};
	float2 ScreenCenter = {vecSkill5.x + 0.25, vecSkill5.y + 0.5};
	float2 ScaleOut = {0.25/vecSkill5.w,  0.4/vecSkill5.w};
	float2 ScaleIn = {4.0, 2.5};
	float4 K = vecSkill1;
	
	//if( texCoordIn.x>=vecSkill5.x && texCoordIn.x<=(vecSkill5.x+0.5) )
	//{
		float2 theta = (texCoordIn - LensCenter) * ScaleIn; //
		float rSq = theta.x * theta.x + theta.y * theta.y;
		float2 rvector = theta * (K.x + K.y*rSq + K.z*rSq*rSq +	K.w*rSq*rSq*rSq);
		
		texCoordOut = LensCenter + ScaleOut*rvector;
		
		if (any(clamp(texCoordOut, ScreenCenter-float2(0.25,0.5), ScreenCenter+float2(0.25, 0.5)) - texCoordOut))
		return 0;
	//}
	//else texCoordOut=texCoordIn;
	return tex2D(g_samSrcColor, texCoordOut);
}

technique PostProcess 
{

	pass p1 
	{
		AlphaBlendEnable = false;	
		VertexShader = null;
		PixelShader = compile ps_2_0 postprocessing_undistort();
	}
}



Here is the main code:
Code:
//required includes with lite-C
#include <acknex.h>
#include <windows.h>
#include <d3d9.h>
#include <mtlView.c>
//#include <default.c>

//JML includes
#include <JML\WindowSizing.c>
#include <JML\AxesConnect.c>
#include <JML\CamMovement.c>

#define OculusK1 					skill1 //vecSkill1
#define OculusK2   				skill2
#define OculusK3 					skill3
#define OculusK4			   	skill4
#define OculusX 					skill5 //vecSkill5
#define OculusY   				skill6
#define OculusXCenterOffset 	skill7
#define OculusScale			   skill8

MATERIAL* mtl_fx_left =
{
	effect = "pp_undistort.fx";
	flags = AUTORELOAD;
}

MATERIAL* mtl_fx_right =
{
	effect = "pp_undistort.fx";
	flags = AUTORELOAD;
}

VIEW* camera_left_effect =
{ 		
	material = mtl_fx_left;
  	flags = PROCESS_TARGET;
}

VIEW* camera_right_effect =
{ 		
	material = mtl_fx_right;
  	flags = PROCESS_TARGET;
}

VIEW* camera_left =
{ 		
  layer = 0;
  pos_x = 0;
  pos_y = 0;
  stage = camera_left_effect;
  arc = 98;
  flags = SHOW;
}

VIEW* camera_right =
{ 		
  layer = 0;
  pos_y = 0;
  stage = camera_right_effect;
  arc = 98;
  flags = SHOW;
}

PANEL* display_panel =
{ 		
  //digits = (10, 10, "%5.5f", "Arial#12b", 1, camera_left.aspect);
  flags = SHOW;// | PROCESS_TARGET;
}


 
function main(){
	var ipi=120;
	InitWindow("Oculus Demo");
	video_set(1280, 800,0,0);
	
	light_view = NULL;
	reset(camera, SHOW);
	on_f12 = ToggleFullScreen;
	OnResizeEvent();
	level_load("world.wmb");
	vec_set(camera_left.x, vector(0,ipi/2,90));
	vec_set(camera_right.x, vector(0,-ipi/2,90));
	
	mtl_fx_left.OculusX = floatv(0.0);
	mtl_fx_left.OculusXCenterOffset = floatv(0.152);
	mtl_fx_left.OculusY  = floatv(0);
	mtl_fx_left.OculusScale = floatv(1.2);
	mtl_fx_left.OculusK1 = floatv(1.0); 
	mtl_fx_left.OculusK2 = floatv(0.22); 
	mtl_fx_left.OculusK3 = floatv(0.24); 
	mtl_fx_left.OculusK4 = floatv(0.0);
	
	mtl_fx_right.OculusX = floatv(0.5);
	mtl_fx_right.OculusXCenterOffset = floatv(-0.152);
	mtl_fx_right.OculusY  = floatv(0);
	mtl_fx_right.OculusScale = floatv(1.2);
	mtl_fx_right.OculusK1 = floatv(1.0); 
	mtl_fx_right.OculusK2 = floatv(0.22); 
	mtl_fx_right.OculusK3 = floatv(0.24); 
	mtl_fx_right.OculusK4 = floatv(0.0);
	
	
	while(1){
		wait(1);	
	}
	
}

Posted By: txesmi

Re: Multiple View Postprocessing Shader (Oculus Rift) - 11/05/13 08:39

Does OnResizeEvent set the proper sizes to the pp views? Your code left the view sizes as default so they occupy the whole screen area, maybe the right side is occluded by the left view?
Posted By: yorisimo

Re: Multiple View Postprocessing Shader (Oculus Rift) - 11/05/13 14:43

Yes, OnResizeEvent sets the view sizes appropriately
Code:
function OnResizeEvent(){
	camera_left.pos_x = 0;
	camera_right.pos_x = screen_size.x/2;
	camera_left.size_x = camera_right.size_x = screen_size.x/2;
	camera_left.size_y = camera_right.size_y = screen_size.y;
	
}

Posted By: txesmi

Re: Multiple View Postprocessing Shader (Oculus Rift) - 11/05/13 15:28

I guess you need to resize the _effect views too.
Posted By: yorisimo

Re: Multiple View Postprocessing Shader (Oculus Rift) - 11/05/13 15:37

yep, that fixed it. needed to position and size the _effect views. Thanks for your help!
Posted By: Feindbild

Re: Multiple View Postprocessing Shader (Oculus Rift) - 11/06/13 08:19

Okay, now I need an Oculus too.
© 2024 lite-C Forums