Jump to content

  • Log In with Google      Sign In   
  • Create Account

Banner advertising on our site currently available from just $5!

1. Learn about the promo. 2. Sign up for GDNet+. 3. Set up your advert!


Member Since 25 Oct 2011
Offline Last Active Jul 04 2015 06:46 AM

#5230309 How to calculate Lumens?

Posted by Tsus on 21 May 2015 - 03:55 PM

@Hodgman: I have this vague feeling that it's not my place to correct you, but since you asked...



A candela is roughly the brightness of a candle, measured in watts per steradian (solid angle).

You're mixing photometric and radiometric terminology, here.

Candela (cd) is the unit of luminous intensity (photometric).

The equivalent radiometric quantity is radiant intensity and it's unit is watts per steradian.



A lumen is candelas per solid angle.


Candela is lumen per solid angle.



You use this unit of measurement for lumimance (or the equivelent radiometric unit for radiance).


The unit of luminance (photometric) is: cd/m²




If I'm not totally mistaken, you can just plug the photometric units into the rendering equation.

For some reason the (English) rendering literature often uses the radiometric names for the quantities (radiance, irradiance, ...), but is using photometric units (lumen, candela, ...), which is totally confusing.


The radiometric units are used in radiation physics. The photometric units are used whenever the human perception is concerned.

(They just differ in the way how they weight light of different wavelengths. If you're not working with spectral lighting effects, you don't really need to care.)


The dot product formula you posted earlier is the photometric way of mixing RGB values into some luminance value (the weighting is according to the spectral response curves of the "average" eye).

#5099013 Depth stencil state issue

Posted by Tsus on 05 October 2013 - 01:55 PM



The black depth channel is somewhat expected, due to the non-linear distribution of the z-values. Right beside the combobox where you selected the "depth" channel, you have a gray bar that allows you to filter the range displayed linearly. There are tiny triangles (top-left at the bar, and bottom-right). These are the lower and upper bounds. You can move them around, so that you have the lower bound around 0.95. That should show you something.


On the top left of the window is a small "save" icon. You could save the PIXrun and upload it, so that we might have a look.

Best, Tsus

#5098987 Depth stencil state issue

Posted by Tsus on 05 October 2013 - 12:07 PM

Ok. So, with all resources being successfully created and no errors in the output window during draw calls, it's time to use a graphics debugger like PIX.
PIX is contained in the DxSDK and allows you to capture the draw calls and states for a frame (every time you hit F12).
When clicking on a draw call in the list presented to you in PIX, the vertices of the triangles are shown before and after transformation.
If you do a right click on the rendering output you can debug individual pixels and see, why fragments were discarded.

Also, you can dig into the states bound at a draw call.
Hopefully, this sheds some light on the matter.

#5098959 Depth stencil state issue

Posted by Tsus on 05 October 2013 - 09:40 AM

Hi eltharynd,

Usually, CPU access flags are not required for the depth buffer.

Try to turn on the debug layer, as eppo suggested. D3D will most probably tell you what is wrong. The behavior you described sounds like invalid parameters. Pass the flag D3D11_CREATE_DEVICE_DEBUG into the Flags parameter of the D3D11CreateDevice call.

Could you check that all your mDevice->Create... methods return S_OK?
If not, the debug layer will tell you in the Output window of visual studio, why the Create-method failed.
(If you run in Debug mode with F5, not Ctrl+F5.)

Clearing structs with ZeroMemory is a good practice (in my eyes). Could you do it for the depth stencil desc, too? (Just to be safe.)

ZeroMemory (&dsDesc, sizeof(D3D11_DEPTH_STENCIL_DESC));

Also, you have some copy paste error when clearing the depth stencil view desc. It should go:

ZeroMemory (&depthStencilViewDesc, sizeof(D3D11_DEPTH_STENCIL_VIEW_DESC));

Just to be safe, set a rasterizer state. Whenever you move code around, you don't want to depend on states of some previous code block.

ZeroMemory(&rsDesc, sizeof(D3D11_RASTERIZER_DESC));
rsDesc.CullMode = D3D11_CULL_BACK;
rsDesc.DepthBias = 0;
rsDesc.DepthBiasClamp = 0;
rsDesc.FillMode = D3D11_FILL_SOLID;
rsDesc.AntialiasedLineEnable = false;
rsDesc.DepthClipEnable = true;
rsDesc.FrontCounterClockwise = true;
rsDesc.MultisampleEnable = true;
rsDesc.ScissorEnable = false;
rsDesc.SlopeScaledDepthBias = 0;
if (FAILED(mDevice->CreateRasterizerState(&rsDesc, &mRsBackfaceCulling))) return false;

Then, later:


And don't worry. You'll figure it out.

Best, Tsus

#5098902 Depth stencil state issue

Posted by Tsus on 05 October 2013 - 04:13 AM

Hi eltharynd!

If you don't need the stencil test, you probably want to disable it.

dsDesc.StencilEnabled = false;

In this case, you can put full precision into the depth value by using a full float for it:

depthTexDesc.Format = DXGI_FORMAT_D32_FLOAT;

Currently, your depth testing function permits all fragments to be written. Instead, let only fragments through that have a smaller depth value.


It might be just due to copy-pasting into the browser, but did you use the correct depth stencil view description, when creating the depth stencil view? (2nd argument changed)

mDevice->CreateDepthStencilView(depthStencilTexture, &depthStencilViewDesc, &mDepthStencilView);

I guess you did, but for completeness I'm just saying it: You bound your depth buffer like so, right?

ID3D11RenderTargetView* rtvs[] = { mRenderTargetView_Backbuffer };
ImmediateContext->OMSetRenderTargets(1, rtvs, mDepthStencilView);

Do you clear the depth stencil view before drawing?

mImmediateContext->ClearDepthStencilView(mDepthStencilView, D3D11_CLEAR_DEPTH, 1, 0);

Also, were all your resources successfully created? (That is, they are not NULL?)

Best, Tsus

#5055508 OIT with weighted average

Posted by Tsus on 21 April 2013 - 08:54 AM



Your suggestion is already the solution. So, yeah, you got it right. I'll summarize the steps briefly for you:

Your transparent rendering would happen in the rendering loop after the deferred pass:

  1. Fill your deferred buffer (color, depth, …)
  2. Do the deferred lighting
  3. Render the transparent objects

For the last step, do the following:

  1. Disable depth writing (glDepthMask) -> we want no transparent object to be culled by other transparent objects
  2. Enable depth test (glDepthTest) -> compare with your deferred depth buffer (cull by opaque geometry)
  3. Use additive blending (source: GL_ONE, dest: GL_ONE)
  4. Bind two new render targets; let’s call them AccumColors (four (half) float components) and AccumCount (single float component)
  5. Render the transparent objects into those two targets (explained in a moment)
  6. Bind deferred color buffer as render target
  7. Disable depth test (glDepthTest)
  8. Use back-to-front blending (source: GL_ONE_MINUS_SRC_ALPHA, dest: GL_SRC_ALPHA)
  9. Bind AccumColor and AccumCount as textures
  10. Full screen pass: compute the average color/transparency (explained in a moment) and blend with the deferred color buffer

The idea is to compute the average of the colors, weighted by their transparencies. For blending with the background, we additionally need the average opacity. (FYI: I assume that alpha = 1 means opaque, and alpha = 0 means transparent)


Step 5 computes the sums. This is what the fragment shader does:

Input: vec3 color, float alpha
  AccumColor = vec4(color*alpha, alpha);  // color multiplied (=weighted) with alpha!
  AccumCount = 1;


Step 10 compute the average color. Again, the fragment shader:

Input: vec4 AccumColor, float AccumCount

if (AccumCount < 0.00001 || AccumColor.w < 0.00001)
  discard;  // nothing here; discard the fragment.
  vec4 avgColor = vec4(
  AccumColor.xyz / AccumColor.w,    // weighted average color
  AccumColor.w / AccumCount);        // average alpha
  // the alpha, used to blend with the background is computed by assuming 
  // that all transparent layers have the average alpha:
  float dstAlpha = 1-pow(max(0,1-avgColor.w), AccumCount);
  // write out the average color and the alpha, used for compositing
  result = vec4 (avgColor.xyz, dstAlpha);

Hope that gives some insights. smile.png

Best regards!


#5042893 D3D11 - RenderTargetView at slot 0 is not compatable with the DepthStencilView

Posted by Tsus on 13 March 2013 - 05:01 PM


Your render target view (that views the texture to render into) and your depth stencil view (the corresponding depth buffer) have different multi-sampling settings.
When using multi-sampling, every pixel needs to store extra data for the sub-samples (their depth and the coverage bits). Each texture resource is prepared for one certain multi-sampling setting and to make them work together, both the color texture and the depth buffer (after all, it’s just another texture) need the same setting. You can have resources with different settings, but you can only bind them together, if their settings coincide.

If you disable multi-sampling, it would be:

sampleDesc.Count = 1;
sampleDesc.Quality = 0;

High-quality 4x MSAA (for instance) is achieved by setting:

sampleDesc.Count = 4;
sampleDesc.Quality = 16.

Keep in mind that MSAA comes at a cost. If you don’t need it, try to avoid it. Also, combining multi-sampled with single-sampled textures requires you to convert one into the other. (I'd advise you to first familarize yourself with the rendering to textures, before working with multi-sampling)


Okay, so try to set in your default texture (system class):

texd.SampleDesc.Count = 1; 

and make sure that your view dimensions are set to the single-sampled types, e.g.,

for the depth stencil view: D3D11_DSV_DIMENSION_TEXTURE2D  (not: D3D11_DSV_DIMENSION_TEXTURE2DMS).


#5014047 (Order Independent) Transparency

Posted by Tsus on 24 December 2012 - 05:10 PM



What you ended up using is called „alpha test“ and is not truly a solution to the blending of many transparent objects, though it is a common hack to avoid the problem.

Whenever you really need to approach true order-independent transparency, there are a number of methods:

  • Depth peeling [Everitt 01, Bavoil & Myers 08] (Requires to know the number of layers, but was used quite often in research papers. Also works on Dx9.)
  • Concurrent linked list construction [Yang et al. 10, Yakiimo 10]-> do not look into the DxSDK sample (OIT11). Last time I looked, it was poorly implemented (didn’t use shared memory at all).  Check the version of Yakiimo. He implemented it faster, even with multi-sampling. This technique grew more useful by the recent advances of the graphics hardware. Requires Dx11.
  • Stochastic transparency [Enderton et al. 10] (also rather a research thingy. It can handle an arbitrary number of layers, but consumes much performance to get it frame-to-frame coherent). Needs Dx 10.1 if I recall correctly, as it works on the coverage mask.
  • The list goes on... stencil routing etc... (Look into the related work of the papers I linked, if you want to learn more.)

AFAIK, true order-independent transparency was yet too expensive for games. (If someone knows a game that used OIT, please let me know!) It is easier to work around it or just sort the transparent objects by depth. (Of course, this doesn’t work in all cases, but you can tell your artist to circumvent the ugly cases.)
I’m creating technical demos and prototypes, so I can afford to use the concurrent linked list construction.


Best regards!

PS: Links don't seem to work at the moment, so I post the URLs.

Everitt 01: http://gamedevs.org/uploads/interactive-order-independent-transparency.pdf

Baviol & Myers 08: http://developer.download.nvidia.com/SDK/10/opengl/src/dual_depth_peeling/doc/DualDepthPeeling.pdf

Yang et al. 10: http://onlinelibrary.wiley.com/doi/10.1111/j.1467-8659.2010.01725.x/abstract

Yakiimo 10: http://www.yakiimo3d.com/2010/07/19/dx11-order-independent-transparency/

Enderton et al. 10: http://www.enderton.org/eric/pub/StochasticTransparency_I3D2010.pdf

#5013374 Efficient Rendering of Hundreds of Billboards

Posted by Tsus on 22 December 2012 - 04:26 AM


You’re using XNA, right?
A common trick to render many billboards (if you don’t have geometry shaders available) is to send four vertices with identical position to the vertex shader and to expand the quad in view space, by offsetting each of the vertices using their texture coordinates. (The texture coordinate identifies in which corner to move the vertex.) This way, you don't need to calculate rotation matrices on the CPU (or the GPU). Thus you don't have to set additional effect constants and therefore you don't need to call Apply for every single billboard, but only if the texture changes. (So, batching, i.e. sorting per material, would be a good idea.)

Even better, you can render all billboards that share the same texture with a single draw call, by throwing all billboards into a single vertex buffer.
See here, for an example (Section 1.2).

Best regards!

PS: You do not necessarily need a quad. You could also use a single right triangle that covers the whole quad. (Of course, some area would be unused.) If you go down this road, you trade input assembler load against rasterizer load. You would need to profile to see what's better in your situation. For starters I would suggest to use quads, since they are more intuitive.

#5005264 Linestrip with GeometryShader

Posted by Tsus on 29 November 2012 - 05:19 AM

Hi Helgon,

The primitive topology that is specified at the input assembler defines the primitives fed into the pipeline (D3D11_PRIMITIVE_TOPOLOGY_X). The topology needs to match the type you specified at the input struct of the geometry shader:
void GS(point VertexOut gin[1],
			inout LineStream<GeoOut> stream)

void GS(line VertexOut gin[2],
			inout LineStream<GeoOut> stream)
This would require a D3D11_PRIMITIVE_TOPOLOGY_LINE{LIST|STRIP}. Note that you now have two vertices coming in (gin[2]).
The output topology is defined by the geometry shader’s output stream, i.e. LineStream. Input and output topologies don’t necessarily have to coincide.

Jason suggested to use a line strip as input, as it allows you to fake the connections between your lines. (See the attachment for a small example.)

Best regards!

Attached Files

#5004170 Geometry shader, but why ?

Posted by Tsus on 26 November 2012 - 04:31 AM

Ok, since we’re on the geometry shader's right to exist... Posted Image

Also the geometry shader allows you to dynamically insert new primitives into an existing vertex stream. Consider a particle system in which a few “launch particles” are emitted that explode after a certain time, creating multiple new “secondary particles”. By using Stream Output (steered by the geometry shader stage) you can feed the vertex data back into a vertex buffer and use it in the next frame. (See DirectXSDK, "GSParticles".)

A second -- very important -- thing about stream output is that a geometry shader always “inserts” primitives into the stream (not just appends at the end). Imagine you have a line, consisting of multiple particles. (Now comes a flow visualization example. Posted Image) If you transport (aka advect) the particles in some sort of vector field (like a fluid or turbulent air), you can use the geometry shader to refine the line segments, if two adjacent vertices (A and B) are transported too far apart. (Which is basically just inserting a new vertex between A and B.) The important thing is: the topology is preserved. You still have a point list that can be rendered as a line strip, because the order still fits since the new vertex sits between A and B in the output stream. Doing this with compute shaders is rather cumbersome. Therefore, I often use the Geometry Shader in GPGPU applications (whenever I need to “insert” data into a stream).

Alright, and to talk about spheres... You could as well generate a viewport-aligned quad in your geometry shader that covers the sphere and do an analytic ray cast onto the sphere in the pixel shader to calculate the position and normal, discarding everything outside of the sphere. If you have many spheres with varying level of detail that should be rendered in a single draw call, this approach might not be so demanding for the tessellator.

#5003917 Counting the depth complexity / Get the stencilRef

Posted by Tsus on 25 November 2012 - 04:17 AM

Hi Helgon,

What do you want to count? Both back and front faces? Probably just front faces, right? If so, try to set:
colorDepth.DepthEnable = true;
colorDepth.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; // disable writes
colorDepth.DepthFunc = D3D11_COMPARISON_ALWAYS;
colorDepth.StencilEnable = true;
colorDepth.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK; // enable
colorDepth.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK; // enable
colorDepth.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
colorDepth.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;
colorDepth.FrontFace.StencilPassOp = D3D11_STENCIL_OP_INCR; // also count fragments that didn't pass the depth test
colorDepth.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
colorDepth.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;  // set to INCR, if you want to count both, back and front faces
colorDepth.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; // set to INCR, if you want to count both, back and front faces. (counts fragments that didn't pass the depth test)
colorDepth.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
colorDepth.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;

StencilFailOp is executed if the stencil test fails (it will never, since we set StencilFunc to always). StencilDepthFailOp happens if the stencil test passes and the depth test fails. The StencilPassOp operation is used when both tests pass. On frontfaces we increment, on backfaces we do nothing.

If you want to read the stencil value in the shader, then you need three depth stencil views, all viewing the same texture.
The first is used for rendering into it. Therefore, use the format DXGI_FORMAT_D24_UNORM_S8_UINT. Bind it to the OM, when you render the scene (OMSetRenderTargets).
The second SRV is bound to the OM, when you want to read the stencil buffer. Again, use the format DXGI_FORMAT_D24_UNORM_S8_UINT, but additionally set the flag D3D11_DSV_READ_ONLY_STENCIL. (Additionally, set a depthStencilState that disables stencil write operations, i.e., StencilWriteMask = 0)
The third SRV is bound to the PS (PSSetShaderResources). Now, use the format DXGI_FORMAT_X24_TYPELESS_G8_UINT.
In the shader code it is used like this:
Texture2D<uint> txStencil : register (t0); // set the corresponding register
float4 PSStencil(float4 pos: SV_Position) : SV_Target
  uint stencil = txStencil.Load(int3(pos.xy, 0));

  // debug output
  if (stencil == 1) return float4(0,1,0,1);
  else return float4(0,0,0,0);

Hope that helps! Posted Image
Best regards!

#4998140 XNA

Posted by Tsus on 06 November 2012 - 12:25 PM


The standard sample site is: xbox.create.msdn.com/en-US/education/catalog/
I would also recommend to look around here: www.riemers.net/
A selection of books can be found here on gamedev (including some on XNA): www.gamedev.net/page/books/index.html/_/technical/directx-8/

Best regards!

#4998005 Program exits at Direct3D initialization (D3D11CreateDevice)

Posted by Tsus on 06 November 2012 - 06:47 AM

Hi Nick,

Using a default adapter doesn't work for me either. Perhaps just try to iterate the adapters. (In case you have multiple graphics cards, try to build a device on each and see which one has the best feature level.)

bool D3D::CreateDevice()
	// Get the factory, so we can iterate the adapters and later build a swap chain.
	if(FAILED(CreateDXGIFactory(__uuidof(IDXGIFactory) ,(void**)&_Factory)))
		_Factory = NULL;
	UINT createDeviceFlags = 0;
#ifdef _DEBUG
	createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
	D3D_DRIVER_TYPE driverTypes[] =
	UINT numDriverTypes = sizeof( driverTypes ) / sizeof( driverTypes[0] );
	unsigned int numFeatureLevels = 3;

	// Iterate the driver types (chose the first one that works. -> possible to use software fallback)
	for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ )
		_DriverType = driverTypes[driverTypeIndex];
		// Iterate the adapters
		for ( UINT i = 0;
			_Factory->EnumAdapters(i, &_Adapter) != DXGI_ERROR_NOT_FOUND;
		++i )
			// Try to create a device
			hr = D3D11CreateDevice(_Adapter, _DriverType, NULL, createDeviceFlags, featureLevels, numFeatureLevels,	  D3D11_SDK_VERSION,  &_Device, &_FeatureLevel, &_ImmediateContext);
			if (SUCCEEDED(hr)) // pick the first that works (this is not necessarily the best one!)
		if( SUCCEEDED( hr ) )
	return true;

As for the debug info: do you have built the effect framework on debug and release, and link the correct version respectively?

Best regards,

#4980605 Parentheses in HLSL cause light attenuation function to not work correctly?

Posted by Tsus on 16 September 2012 - 05:19 AM

Nice! I should put in area lights. It looks so much better. Posted Image
Btw, I’ve used stochastic progressive photon mapping for the image above, implemented on the GPU using stochastic spatial hashing. So, a consistent rendering, too. Posted Image