Jump to content

  • Log In with Google      Sign In   
  • Create Account

We need your feedback on a survey! Each completed response supports our community and gives you a chance to win a $25 Amazon gift card!


Member Since 08 Apr 2011
Offline Last Active Yesterday, 07:13 PM

Topics I've Started

Is this correct sRGB conversion?

22 December 2014 - 03:25 PM

I feel like I don't have my sRGB correct.


Here's my pipeline when rendering:

  1. Draw into Gbuffer. Color textures are read in as DXGI_FORMAT_R8G8B8A8_UNORM_SRGB and written to DXGI_FORMAT_R16G16B16A16_UNORM 
  2. Perform ambient, directional and point lighting into an intermediate texture which is DXGI_FORMAT_R16G16B16A16_UNORM with additive blending (see below)
  3. Lastly perform fullscreen pass with render target DXGI_FORMAT_R8G8B8A8_UNORM_SRGB that writes to the backbuffer texture which is DXGI_FORMAT_R8G8B8A8_UNORM

The additive blending for lighting:

D3D11_BLEND_DESC blendDesc;
ZeroMemory(&blendDesc, sizeof(D3D11_BLEND_DESC));
blendDesc.RenderTarget[0].BlendEnable = true;
blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE;
blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_ONE;
blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ONE;
blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
DXCALL(device->CreateBlendState(&blendDesc, &mAdditiveBlending));

Here's an example:


This image is [0.5, 0, 0]:


Attached File  test_red.png   3.3KB   0 downloads


After running through the pipeline and multiplying it with 0.5f ambient lighting, the result is [0.36, 0, 0]. Has sRGB been applied correctly in this case?


What puzzles me is that everything is simply so bright. For example the picture below was taken with only 0.05f ambient lighting:


Attached File  test.png   926.47KB   0 downloads


Is this correct? Am I doing something obviously wrong?

Terrain tesselation and collision

16 December 2014 - 05:37 AM

I'm having issues wrapping my head around how tesselation and collision can work. My understanding of terrain tesselation is based on the nvidia demo/whitepaper: https://developer.nvidia.com/sites/default/files/akamai/gamedev/files/sdk/11/TerrainTessellation_WhitePaper.pdf


For example, an animated character moving across a (heavily) tesselated terrain such as in the demo. Given that tesselation is a shader technique, how can the two ever work together?


EDIT: Also if the tesselation is the result of shaders, how on earth do you apply lighting and shadows to it?


09 December 2014 - 10:44 AM

The system I have now works fine, but I feel it could be done in a better, more efficient way.
From the frustrum culling stage prior I get back a list of meshes that are visible. For each mesh, I construct a "renderable" unit and push them back onto my version of a renderqueue (just a vector as it stands). The renderqueue persists for the lifetime of the engine, but it is cleared every frame.
The renderer then iterates the renderqueue and draws each mesh.
Each renderable contains all the data needed and is a struct like this:
struct Renderable
    MeshID mMesh;
    Mat4 mWorldMatrix;
  float mTextureTilingFactor;

  TextureID mDiffuseTexture;
    TextureID mNormalTexture;
    float mSpecularFactor;

Same is done for each point / directional light, but with other data.


I feel like maybe this could get optimized in some way. Any suggestions?


sRGB and deferred rendering

09 December 2014 - 07:14 AM

Got a few questions regarding sRGB in a deferred rendering setup.

  1. Is it safe to assume all diffuse textures are in sRGB format? And that normal/bump maps are not? Meaning, all diffuse textures should be DXGI_FORMAT_R8G8B8A8_UNORM_SRGB to enable automatic sRGB->linear conversion when reading them?
  2. As I understand it, the swapchains backbuffer needs to be sRGB to enable automatic conversion linear->sRGB. Does both the backbuffers texture and its render target need to be sRGB, or only one of them?
  3. I do additive blending for each light pass during the shading stage. To work in linear space means I need an intermediate texture (such as DXGI_FORMAT_R16G16B16A16_UNORM) to accumulate the color right? Right now I just accumulate color in my backbuffer, but if I declare it sRGB it would convert all color linear->sRGB before blending, and so it would just blend in sRGB....?
  4. After accumulating the color in my intermediate buffer, I need to copy its texture to the backbuffer before swapchain->present(). Does a context->CopyResource() intermediate->backbuffer automatically perform sRGB conversion? I assume not; if so then is a fullscreen pass the best solution?

Thanks for any help on this issue.

AABB box intersection test

27 November 2014 - 05:43 AM

I'm trying to get view frustrum culling working. I found a neat, cheap way in an article to test if an AABB intersects the view frustrum: https://fgiesen.wordpress.com/2010/10/17/view-frustum-culling/ method5


I don't particullarly care if a model is partially inside the view frustrum (not yet anyway - maybe its more important later on?) so it just tests if its in or not.


Also I keep the AABB in object space and use world-view-projection matrix to retrieve the planes.


The issue I have is that it never reports that the AAB isn't in the frustrum - no matter how I orient myself, the AABB is always inside or partially inside. Are there any obvious bugs?

float signum(float val)
    if (val > 0.0f) return 1.0f;
    if (val < 0.0f) return -1.0f;

    return 0.0f;

FrustrumPlanes GetFrustrumPlanes(const Mat4& WVPMatrix)
    FrustrumPlanes ret;

    ret[0] = WVPMatrix[3] + WVPMatrix[0];
    ret[1] = WVPMatrix[3] - WVPMatrix[0];
    ret[2] = WVPMatrix[3] - WVPMatrix[1];
    ret[3] = WVPMatrix[3] + WVPMatrix[1];
    ret[4] = WVPMatrix[2];
    ret[5] = WVPMatrix[3] - WVPMatrix[2];

    for (Plane& plane : ret)
        plane = glm::normalize(plane);

    return ret;

bool DoesAABBIntersectViewFrustrum(const Vec3& aabbCenter, const Vec3& aabbExtent, const Mat4& WVPMatrix)
    FrustrumPlanes planes = GetFrustrumPlanes(WVPMatrix);

    for (const Plane& plane : planes)
        Vec3 signFlip(signum(plane.x), signum(plane.y), signum(plane.z));
        if (glm::dot(aabbCenter + aabbExtent * signFlip, Vec3(plane)) > -plane.w)
            return true;

    return false;