Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 08 Apr 2011
Offline Last Active Today, 05:27 AM

Topics I've Started

Jumping over to DirectX?

23 June 2014 - 08:46 AM

I've done some progress on learning OpenGL (models, textures, lights, point light/directional cascaded shadow maps, deferred rendering with msaa) and I'm pondering whether to make the jump over to DirectX.



  1. API design. As my rendering pipeline gets more complex, structuring all the various state calls into something easily understandable yet fast gets increasingly annoying, especially under some form of OOP. Is this the case for DirectX aswell? Is there a big difference?
  2. Debugging tools. AFAIK, Visual studio has built in performance and debugging tools for directx, while doing the same for opengl has proven so far to be a nightmare. There is gDEbugger (and CodeXL) but they simply don't work/crash, probably something with the window framework I'm using (GLFW 3) and it's OpenGL context switches. I work in windows under Visual studio anyway, so tight integration with debugging tools seems too good to be true.


  1. Supporting frameworks. I'm using GLEW for loading OpenGL, GLFW 3 for window management and GLM for math stuff. I have to say they are some of the best libraries I have used; my main issue with jumping to DirectX would be that I would have to get equivalent frameworks for that, and some searching has yielded basically NOTHING.
  2. Tutorials/references. The majority of what I have found seems to be OpenGL focused - DirectX guides seems kinda lackluster. Is this true?

Anyone mind chiming in with some feedback?


Deferred shading and MSAA

16 June 2014 - 04:50 AM

I'm trying to tackle MSAA in deferred shading.

Here' my current deferred shading pipeline:

Code :
1. Geometry stage - Render geometry to textures (position/normals/diffuse)
2. Shading stage - all output is rendered & blended into a "final texture"
  2.1 Render ambient light
  2.2 Render directional lights and shadows
  2.3 Render point lights and shadows
3. BlitFramebuffer() on the final texture
4. Swapbuffers and repeat 1.

In 2.1, 2.2 and 2.3 I need to read gbuffer textures (position/normals/diffuse) to do the lighting and shadowing.

My question is now, how do I most effectively accomplish MSAA (or any other form of good AA)? Do I have to read a number of samples in all the 3 shading passes (2.1, 2.2 and 2.3: sounds expensive!) or what? Is there any hardware support on can use?

Cascaded shadow mapping and potential shadow casters

08 June 2014 - 01:35 PM

I'm doing cascaded shadow maps for directional lights and I'm running into angles where shadows are simply cut. I believe this is due to parts of models not being fit inside the frustrums


1.. I'm sure this is a common problem but I'm not sure where to start; I assume I need to increase the frustrum sizes if there is an object in the field of view?


2. How do you deal with really, really tall objects? Won't the shadowmap resolution gets screwed if you have to fit it into the frustrum?


3. How do you deal with objects behind the player which might cast shadows still?


EDIT: maybe this fits better in "Graphics programming and theory", if a mod could move it there

Omnidirectional shadow mapping

03 May 2014 - 08:29 AM

I've recently finished directional shadow mapping, and now I'm doing the same for point lights. I run into problems though, for some reason the shadows seem to the "mirrored", i.e on wrong side of the meshes.


Here's the fragment shader for the lighting stage:

layout(std140) uniform UnifPointLight                                                                                                   
	mat4 mWVPMatrix;                                                                                                                    
	vec4 mLightColor;                                                                                                                   
	vec4 mLightPos;                                                                                                                     
	vec4 mGamma;                                                                                                                        
	vec2 mScreenSize;                                                                                                                   
	float mLightIntensity;                                                                                                              
	float mMaxDistance;                                                                                                                 
} UnifPointLightPass;                                                                                                                   
layout (binding = 2) uniform sampler2D unifPositionTexture;                                                                             
layout (binding = 3) uniform sampler2D unifNormalTexture;                                                                               
layout (binding = 4) uniform sampler2D unifDiffuseTexture;                                                                              
layout (binding = 7) uniform samplerCube unifShadowmap;                                                                                 
out vec4 fragColor;                                                                                                                     
float VectorToDepthValue(vec3 Vec)                                                                                                      
	vec3 AbsVec = abs(Vec);                                                                                                             
	float LocalZcomp = max(AbsVec.x, max(AbsVec.y, AbsVec.z));                                                                          
	const float f = 100.0;                                                                                                              
	const float n = 0.1;                                                                                                                
	float NormZComp = (f + n) / (f - n) - (2 * f*n) / (f - n) / LocalZcomp;                                                             
	return (NormZComp + 1.0) * 0.5;                                                                                                     
void main()                                                                                                                             
	vec2 texcoord = gl_FragCoord.xy / UnifPointLightPass.mScreenSize;                                                                   
	vec3 worldPos = texture(unifPositionTexture, texcoord).xyz;                                                                         
	vec3 normal   = texture(unifNormalTexture, texcoord).xyz;                                                                           
	vec3 diffuse  = texture(unifDiffuseTexture, texcoord).xyz;                                                                          
	normal        = normalize(normal);                                                                                                  
	vec3 positionDiff = (UnifPointLightPass.mLightPos.xyz - worldPos);                                                                  
	float storedDepth = texture(unifShadowmap, positionDiff);                                                                           
	float visibility = 0.0;                                                                                                             
	if (storedDepth + 0.0001 > VectorToDepthValue(positionDiff))                                                                        
		   visibility = 1.0;                                                                                                            
	float dist = length(positionDiff);                                                                                                  
	float attenuation = clamp(1.0 - dist*dist * (1 / (UnifPointLightPass.mMaxDistance * UnifPointLightPass.mMaxDistance)), 0.0, 1.0);   
	attenuation *= attenuation;                                                                                                         
	vec3 lightDir = normalize(positionDiff);                                                                                            
	float angleNormal = clamp(dot(normalize(normal), lightDir), 0, 1);                                                                  
	fragColor = vec4(diffuse, 1.0) * visibility * (angleNormal * attenuation * UnifPointLightPass.mLightIntensity * UnifPointLightPass.mLightColor);                                                   

The shadowing part is based largely on other answers on stackoverflow and seems reasonable; but my gut tells me the "positionDiff" should be negated? For example if my point light is (7, 0, 0) and a cube is (9, 0, 0), positionDiff would be (-2, 0, 0) and thus sampling the wrong face of the cubemap?


Any suggestions?


Shadowsampler comparison

14 April 2014 - 04:59 AM

Doing cascaded shadow mapping, and I need some confirmation I am doing the right thing. The shadow mapping works (mostly) but on a few angles the shadows vanish.


The sampler is setup like this:


GLCALL(glGenSamplers(1, &mTextureSampler));
GLCALL(glSamplerParameteri(mTextureSampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
GLCALL(glSamplerParameteri(mTextureSampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
GLCALL(glSamplerParameteri(mTextureSampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
GLCALL(glSamplerParameteri(mTextureSampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
GLCALL(glSamplerParameteri(mTextureSampler, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE));
GLCALL(glBindSampler(OpenGLTexture::TEXTURE_UNIT_SHADOW_DIRECTIONAL, mTextureSampler));

I do depth comparison rather than distance comparison; my depth textures thus contain depth values.


vec4 projCoords = UnifDirLightPass.mVPMatrix[index] * vec4(worldPos, 1.0);                                                  
projCoords.w    = projCoords.z - DEPTH_BIAS;                                                                                
projCoords.z    = float(index);                                                                                             
float visibilty = texture(unifShadowTexture, projCoords);                                                                   

float angleNormal = clamp(dot(normal, UnifDirLightPass.mLightDir.xyz), 0, 1);                                               

fragColor = vec4(diffuse, 1.0) * visibilty * angleNormal * UnifDirLightPass.mLightColor;                                    

"unifShadowTexture" is of type "sampler2DarrayShadow", and "UnifDirLightPass.mVPMatrix[]" contains the bias * lightProj * lightView matrix for each split.



1. By having MIN/MAG filtering to GL_LINEAR, shouldn't I also have visibility = 0.5 for some samples? All I see is either 0.0 or 1.0.


2. Is the comparison in texture() valid? I believe I read somewhere that depth values aren't stored linearly, does this create a problem when I try to compare it against bias * lightProj * lightView * worldPosition?


3. For what reason would you use distance comparison (= writing the squared distance to the depth texture) over depth comparison for shadow mapping? It just seems like extra computations?


4. I am using shadow samplers, which gives me 0.0 or 1.0 values. How can I accomplish soft shadows with this for directional and point lights with such binary values to work with?


5. Why would you not use shadow samplers over normal samplers in shadow mapping?