Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 02 Jul 2009
Offline Last Active Jul 20 2014 04:06 PM

Topics I've Started

Deferred Depth Reconstruction

19 April 2014 - 04:25 PM

Hi All,


I am porting/migrating my pipeline from forward to deferred rendering because I want precomputed atmospheric scattering. If I do not learn how to achieve the technique I will never die a happy man (and vice versa smile.png). The goal is:



The paper with it is interesting reading as is prolands source code example, however prolands demo does not actually use a GBuffer so I need to blend their high level behaviour from this DX port to achieve the effect in GLSL 330.


I am binding my render buffer as a texture (24bit 8 bit stencil), I can read and draw it to a quad on screen, I know that the none linear depth values it writes are valid and my shader/model binding process is tried and true (right handed). My current goal is to establish all the fiddly unpleasant transforms required to get from GBuffer post processing exposed and to better understand the most practical way to handle transforms around depth. My first stop was the realisation that if I can get the post process surfacePos below I will be home free as all the lighting is similar it is just the sources used to lookup values that have changed.


Here is the code I am attempting to port, the transforms through various coordinate space I have a loose grasp of, but the part I do not get is how the SV_POSITION translates in GLSL. Changing the gl_FragDepth to try and mimic screen space changes ends badly.


GBUFFER GEOMETRY___________________________________________________


struct VS_OUT {

float4 posH : SV_POSITION;

float3 posW : POSITION;

float3 tangent : TANGENT0;

float3 bitangent : TANGENT1;

float2 texC : TEXCOORD0;





Vertex shader snippet of interest to position:


output.posH = mul(float4(posWorld, 1.0f), g_viewProj);

output.posH.z = output.posH.z * output.posH.w * g_invFarPlane;


POST PROCESSING_____________________________________________________


Vertex Shader

static const float EPSILON_ATMOSPHERE = 0.002f;

static const float EPSILON_INSCATTER = 0.004f;


Texture2D g_depth;

Texture2D g_color;

Texture2D g_normal;

Texture2D g_texIrradiance;

Texture3D g_texInscatter;

float3 g_cameraPos;

float3 g_sunVector;

float4x4 g_cameraWorld;

float4 g_frustumFar[4];

float4 g_frustumNear[4];


struct VS_IN {

float3 posL : POSITION;

float2 texC : TEXCOORD0;

uint index : TEXCOORD1;



struct VS_OUT {

float4 posH : SV_POSITION;

float2 texC : TEXCOORD0;

float3 nearToFar : TEXCOORD2;

float3 cameraToNear : TEXCOORD3;



VS_OUT VS(VS_IN input) {

VS_OUT output;

output.posH = float4(input.posL,1.0f);

output.texC = input.texC;

float3 frustumFarWorld = mul(float4(g_frustumFar[input.index].xyz, 1.0f), g_cameraWorld).xyz;

float3 frustumNearWorld = mul(float4(g_frustumNear[input.index].xyz, 1.0f), g_cameraWorld).xyz;

output.cameraToNear = frustumNearWorld - g_cameraPos;

output.nearToFar = frustumFarWorld - frustumNearWorld;

return output;



Pixel Shader:


// reconstructing world space postion by interpolation

float depthVal = g_depth.SampleLevel( PointSamplerClamp, input.texC, 0 ).r;

float3 surfacePos = g_cameraPos + input.cameraToNear + depthVal * input.nearToFar;


// obtaining the view direction vector

float3 viewDir = normalize(input.nearToFar);


  • Can anyone confirm how the PosH value is impacting the encoding of the depth buffer and what the openGL equivalent would be?
  • Can anyone tell me the real values of those vec4[4] fustrums and where they can be derived from? I have no problem adding an index to my screen quad to link to it or building a clipping frustrum near or far plane. The problem I have is that it is glossed over and I am worried my deductive reasoning will be slower than the my goal. I really want my GBuffer ready to start assembling this post processing effect before the Easter holiday is done.


I believe g_cameraWorld is the world rotation of the camera.


I have gone through all of the following resources to try and understand how people are handling this process:


So far I have had no success reconstructing raw depth by blending these snippets input on the problem or testing them in relative isolation, I have a feeling that everyone is tampering with depth output in the geometry buffer but its not very clear in many of the snippets I have found exactly what parameters they are using to do this and why. I am going to try and focus on filling in the gaps from the model above because the resources above suggest it is still an efficient mechanism for solving reconstructing the desirable spaces in most post processes.


Does anyone have a tutorial where this reconstruction process is applied as a holistic piece of functioning code? I would love to see the implementation for these frustum shapes on the near and far plane. I just need to see a proper GBuffer pipeline using depth to reconstruct position and linear depth so I can reverse engineer and inspect its properties to understand the bugs in my own code and move on.


I really cannot wait to play with that effect. If I get my shaders to reconstruct from depth I will post them up and describe the parts that have as of yet confounded me.


I welcome any input.


Many Thanks,

Enlightened One

Shared context and VAOs

18 October 2011 - 04:02 PM


I am on OGLES2 on iOS5 and I have two threads handling the bulk of my program, one thread loads data including my vertex model information, and the other draws everything.

I have only just got a handle on what VAOs do so I set them up as I had seen them elsewhere, all the code works apart from the point where the VAO fails to bind on the second thread so your welcome to jump to the next bit of text.

The loading thread does this per model.

   glGenVertexArraysOES(1, &puiVAO);
	if (!puiVbo)
    	puiVbo = new GLuint[modScene.nNumMesh];
	if (!puiIndexVbo)
    	puiIndexVbo = new GLuint[modScene.nNumMesh];
	glGenBuffers(modScene.nNumMesh, puiVbo);
	for (unsigned int i = 0; i < modScene.nNumMesh; ++i)
		// Load vertex data into buffer object
		SPODMesh& Mesh = modScene.pMesh[i];
		unsigned int uiSize = Mesh.nNumVertex * Mesh.sVertex.nStride;
		glBindBuffer(GL_ARRAY_BUFFER, puiVbo[i]);
		glBufferData(GL_ARRAY_BUFFER, uiSize, Mesh.pInterleaved, GL_STATIC_DRAW);
		// Load index data into buffer object if available
		puiIndexVbo[i] = 0;
		if (Mesh.sFaces.pData)
			glGenBuffers(1, &puiIndexVbo[i]);
			uiSize = PVRTModelPODCountIndices(Mesh) * sizeof(GLshort);
			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, puiIndexVbo[i]);
			glBufferData(GL_ELEMENT_ARRAY_BUFFER, uiSize, Mesh.sFaces.pData, GL_STATIC_DRAW);
	glBindBuffer(GL_ARRAY_BUFFER, 0);

The drawing thread then does this (for simple meshes):

	glBindVertexArrayOES(puiVAO); THROWS ERROR!
	for(unsigned int i = 0; i < modScene.nNumMeshNode; ++i)
      	SPODMesh& Mesh = modScene.pMesh[i32MeshIndex];
          // bind the VBO for the mesh
      	glBindBuffer(GL_ARRAY_BUFFER, puiVbo[i32MeshIndex]);
      	// bind the index buffer, won't hurt if the handle is 0
          glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, puiIndexVbo[i32MeshIndex]);
      	// Set the vertex attribute offsets
      	glVertexAttribPointer(SNAVERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, Mesh.sVertex.nStride, Mesh.sVertex.pData);
          glVertexAttribPointer(SNANORMAL_ARRAY, 3, GL_FLOAT, GL_FALSE, Mesh.sNormals.nStride, Mesh.sNormals.pData);
          if(Mesh.nNumUVW) // Do we have texture co-ordinates?
          	glVertexAttribPointer(SNATEXCOORD_ARRAY, 2, GL_FLOAT, GL_FALSE, Mesh.psUVW[0].nStride, Mesh.psUVW[0].pData);
 		// Draw the Indexed Triangle list
 		glDrawElements(GL_TRIANGLES, Mesh.nNumFaces*3, GL_UNSIGNED_SHORT, 0);

Now the problem here is that the shared vertex data between my two contexts do not share VAO data (according to many sources), so how on earth do I build a VAO from the drawing mechanism after the vertex data has been set on the other thread and flushed ready for use on the rendering context? From what I have heard these VAO objects offer a big deal of efficiency boost by storing data on the graphics device so I am keen to find a fix.

Any clues, corrections or declarations of impossibility are welcome.


Migrating to GLKit Skybox Effect not working.

18 October 2011 - 06:15 AM

Hey all,

I have been migrating from OGLES2 Oolong to GLKit

Has anyone got a GLKSkyboxEffect to work? I am keen for an example of what people plug into the transforms, I have very little to go on.

Here is all code relating to the skybox effect.

glkSkyShader = [[GLKSkyboxEffect alloc] init];

glkSkyShader.textureCubeMap.name = [uzEngineState getVolWeather]->getCubeTexture(i);
[glkSkyShader setCenter:GLKVector3Make(0, 0,0)];
[glkSkyShader setXSize:SKYBOXSIZE];
[glkSkyShader setYSize:SKYBOXSIZE];
[glkSkyShader setZSize:SKYBOXSIZE];

Draw Loop:

glkSkyShader.transform.projectionMatrix = GLKMatrix4MakePerspective((float)CAMERAFOV, (float)460/(float)320, (float)1, (float)10);

glkSkyShader.transform.modelviewMatrix = GLKMatrix4MakeLookAt(3, 1, 0, 0, 0, 0, 0, -1, 0);

[glkSkyShader prepareToDraw];

[glkSkyShader draw];

Is there something you have to bind before you draw it? The resulting mess of pixels looks vaguely like a view frustum/one of my models. Below is the skybox and the model it looks like. The textures shown are from Oolong engine I do not own them.

Attached File  screenshot.jpg   8.68KB   43 downloads


Assigning classes

08 September 2011 - 04:41 AM


I am attempting to assign a copy of one of my classes to another copy of the same type so I can shuffle an array of this class.

First question, is there a special keyword that tells c++ compilers when copying a class to ignore a classmember such as a string stream or a Direct X texture pointer?

Second question, how does one overload an assignment operator in a way that allows members to be ignored?

Final question when are they going to fix this forums ability to show code!!!!! some irony in that copying fails here too. I cant even navigate my own post because the text cursor doesn't always decide to update (IE9)!




[/color][/size][/font][font="Consolas"][font="Consolas"][size="2"] ImageClass[/size][/font][/font]

[font="Consolas"][size="2"][font="Consolas"][size="2"] {







[/size][/font][font="Consolas"][color="#008000"][font="Consolas"][color="#008000"][font="Consolas"][size="2"][color="#008000"]//Default constructor needs to set these values.[/color][/size][/font][/color][/font][/color][/font]

[font="Consolas"][color="#008000"][font="Consolas"][color="#008000"][font="Consolas"][size="2"][color="#008000"][/color][/size][/font][/color][/font][/color][/font][font="Consolas"][size="2"][font="Consolas"][size="2"]    ImageClass();



[/size][/font][/size][/font]    std::string getLastErrorMessage();







[/size][/font][font="Consolas"][color="#008000"][font="Consolas"][color="#008000"][font="Consolas"][size="2"][color="#008000"]//Every class has these to allow extraction of errors.[/color][/size][/font][/color][/font][/color][/font]

[font="Consolas"][color="#008000"][font="Consolas"][color="#008000"][font="Consolas"][size="2"][color="#008000"][/color][/size][/font][/color][/font][/color][/font][font="Consolas"][size="2"][font="Consolas"][size="2"]    std::stringstream strStrError;

    std::string strError;



[/size][/font][size="2"][font="Consolas"][color="#0000ff"][font="Consolas"][color="#0000ff"][font="Consolas"][color="#0000ff"]bool[/color][/font][/color][/font][/color][/font][font="Consolas"][font="Consolas"] boolImageLive;[/font][/font][/size]



[/size][/font][size="2"][font="Consolas"][color="#0000ff"][font="Consolas"][color="#0000ff"][font="Consolas"][color="#0000ff"]bool[/color][/font][/color][/font][/color][/font][font="Consolas"][font="Consolas"] boolCatagoryImage;[/font][/font][/size]



[/size][/font][size="2"][font="Consolas"][color="#0000ff"][font="Consolas"][color="#0000ff"][font="Consolas"][color="#0000ff"]bool[/color][/font][/color][/font][/color][/font][font="Consolas"][font="Consolas"] boolCategoryImageOverlaid; [/font][/font][font="Consolas"][color="#008000"][font="Consolas"][color="#008000"][font="Consolas"][color="#008000"]//Used to draw the category image as pulsating when overlaid[/color][/font][/color][/font][/color][/font][/size]



[/size][/font][font="Consolas"][color="#008000"][font="Consolas"][color="#008000"][font="Consolas"][size="2"][color="#008000"]//Set by the game logic when starting up the scene[/color][/size][/font][/color][/font][/color][/font]

[font="Consolas"][color="#008000"][font="Consolas"][color="#008000"][font="Consolas"][size="2"][color="#008000"][/color][/size][/font][/color][/font][/color][/font][font="Consolas"][size="2"][font="Consolas"][size="2"]    std::string strImageDir;

    std::string strImageFormatlessName;



[/size][/font][font="Consolas"][color="#008000"][font="Consolas"][color="#008000"][font="Consolas"][size="2"][color="#008000"]//The image width and height is taken from the texture the position X and Y is in screen space as all drawing is set[/color][/size][/font][/color][/font][/color][/font]



[/size][/font][font="Consolas"][color="#008000"][font="Consolas"][color="#008000"][font="Consolas"][size="2"][color="#008000"]//to run in screen space.[/color][/size][/font][/color][/font][/color][/font]



[/size][/font][size="2"][font="Consolas"][color="#0000ff"][font="Consolas"][color="#0000ff"][font="Consolas"][color="#0000ff"]float[/color][/font][/color][/font][/color][/font][font="Consolas"][font="Consolas"] fltCenterPosX, fltCenterPosY, fltPreviousPosX, fltPreviousPosY, fltVelocityX, fltVelocityY;[/font][/font][/size]



[/size][/font][size="2"][font="Consolas"][color="#0000ff"][font="Consolas"][color="#0000ff"][font="Consolas"][color="#0000ff"]int[/color][/font][/color][/font][/color][/font][font="Consolas"][font="Consolas"] intWidth, intHeight, intImageOwner, intImageCatagory, intLastImageOwner; [/font][/font][font="Consolas"][color="#008000"][font="Consolas"][color="#008000"][font="Consolas"][color="#008000"]//Last image owner allows for inertia into category.[/color][/font][/color][/font][/color][/font][/size]

[font="Consolas"][color="#008000"][font="Consolas"][color="#008000"][font="Consolas"][size="2"][color="#008000"][/color][/size][/font][/color][/font][/color][/font][font="Consolas"][size="2"][font="Consolas"][size="2"]    IDirect3DTexture9* pd3dImageTexture;



Posted Image


I enjoy learning by example and have no idea how to get an assignment operator to ignore a variable I believe a class constructor copy hack might be plausible but I do not know the syntax.

This is what I want to do.
for (int i = 0; i < (MAXIMAGESPERLIBRARY - 1); i++) {

std::tr1::uniform_int <
int> unifintGenWidth(0, MAXIMAGESPERLIBRARY - i);

int intRandomFree = i + unifintGenWidth(mtRandGenerator);

ImageClass icTemp = icImages[i];

icImages[i] = icImages[intRandomFree];

icImages[r] = icTemp;


That is genuinley what it looks like AFTER I attempted to clean up all the broken formatting, I hope it is legible. I cant just use pointers to images because I need to actually move the memory, the textures are not initialised at this point so dont panic about any impact on Direct X, I have found a work around to copying the image I can randomise the selection process using the same for loop. I still want to know how you fix the problem of having classes with string stream in them, most of my classes do for ease in my error handling technique.

GL ES glGenTexture & glBindTexture problem

04 September 2011 - 02:51 PM


I am relatively new to GLES development and I have a serious problem. I have code that works when my program is initialised and when the program is minimised and restored, this code involved deleting and then recreating some objects. In the event a player tries to load a level my program attempts to destroy the existing scene and then rebuild a new one so that the displayed environment changes.

It is obvious that when the Glui variable holding a pointer to a texture is assigned in the recreated object that the assignment silently fails as the value is not changed. No glError is received. The program only detects the crash on glBindTexture, I have looked around and found the comment below which suggests that the problem is a matter of state. As GLES has no begin or end I had to assume this was relevant.

GL_INVALID_OPERATION is generated if texture was previously created with a target that doesn't match that of target.

If I do change the scene the program fails, but if I leave in the frozen scene where no objects can be drawn then restore the scene the same release and initialise code works correctly and just as on the first initialisation the texture ID's suggest that whatever relevant component is causing my problem is reset when the program loses focus. This is using Oolong Engine on the iOS, but the fundamental problem here appears to be GLES related. Is there some sort of contextual device reset I can call to force everything to reset as I want it too?

Here is a snippet of some code:

//The texture gen
glGenTextures(1, &m_pAPI->uTexture[dwTexID]);

/* Bind texture */
glBindTexture(GL_TEXTURE_2D, m_pAPI->uTexture[dwTexID]);

/* Default settings: bilinear */

/* Now load texture */
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, p8888);

I validated the issue by adding to the end of it.

if (glIsTexture(m_pAPI->uTexture[dwTexID]) != true)
printf("My suspicion was right!");

//The data is deleted with

glDeleteTextures(1, &m_pAPI->uTexture[dwTexID]);
delete AppDisplayText;

//The component that flags the error is on a flush that would allow text to be drawn

glBindTexture(GL_TEXTURE_2D, m_pAPI->uTexture[0]);

if (glGetError() == GL_INVALID_OPERATION)
_RPT0(_CRT_WARN,"Error while binding buffer for CDisplayText::Flush\n");

I have tried glFlush, glFinish, I have removed all drawing code from my application except for the text drawing class of the Oolong engine and still the problem persists, so the issue is unlikely to be around the class the entire instance of the class is destroyed before a new one is created. All the code executed when losing and restoring focus is the same code as when destroying and loading a new scene other than assuming some sort of higher level state in GL ES I have nothing to go on to try and fix this problem. Any ideas are appreciated.