Jump to content

  • Log In with Google      Sign In   
  • Create Account

Interested in a FREE copy of HTML5 game maker Construct 2?

We'll be giving away three Personal Edition licences in next Tuesday's GDNet Direct email newsletter!

Sign up from the right-hand sidebar on our homepage and read Tuesday's newsletter for details!


TiagoCosta

Member Since 26 Nov 2008
Offline Last Active Yesterday, 05:24 PM

#5193092 Sampling the depth buffer in a shader in DX11

Posted by TiagoCosta on 16 November 2014 - 08:25 AM

D3D11_TEXTURE2D_DESC depthStencilDesc;

depthStencilDesc.Width = mRenderWindow->getClientAreaWidth();
depthStencilDesc.Height = mRenderWindow->getClientAreaHeight();
depthStencilDesc.MipLevels = 1;
depthStencilDesc.ArraySize = 1;
depthStencilDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
depthStencilDesc.SampleDesc.Count = 1;
depthStencilDesc.SampleDesc.Quality = 0;
depthStencilDesc.Usage = D3D11_USAGE_DEFAULT;
depthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
depthStencilDesc.CPUAccessFlags = 0; 
depthStencilDesc.MiscFlags = 0;

VERIFY(mD3DDevice->CreateTexture2D(&depthStencilDesc, 0, &mDepthStencilBuffer));
VERIFY(mD3DDevice->CreateDepthStencilView(mDepthStencilBuffer, 0, &mDepthStencilView));
 
1. Since I don't need to write to the depth buffer as I read from it in a shader, do I need to make any changes to the creation code above, or is it enough for me to unbind the depth buffer before binding it as a shader resource view?

 

 
First you have to change the Texture2D format to a typeless format (DXGI_FORMAT_R24G8_TYPELESS) and add the D3D11_BIND_SHADER_RESOURCE bind flag to the texture desc. 
Then create a Depth Stencil View with the format DXGI_FORMAT_D24_UNORM_S8_UINT and a Shader Resource View with the format DXGI_FORMAT_R24_UNORM_X8_TYPELESS.
 

D3D11_TEXTURE2D_DESC depthStencilDesc;

depthStencilDesc.Width = mRenderWindow->getClientAreaWidth();
depthStencilDesc.Height = mRenderWindow->getClientAreaHeight();
depthStencilDesc.MipLevels = 1;
depthStencilDesc.ArraySize = 1;
depthStencilDesc.Format = DXGI_FORMAT_R24G8_TYPELESS;
depthStencilDesc.SampleDesc.Count = 1;
depthStencilDesc.SampleDesc.Quality = 0;
depthStencilDesc.Usage = D3D11_USAGE_DEFAULT;
depthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
depthStencilDesc.CPUAccessFlags = 0;
depthStencilDesc.MiscFlags = 0;

D3D11_DEPTH_STENCIL_VIEW_DESC dsv_desc;
dsv_desc.Flags = 0;
dsv_desc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT ;
dsv_desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
dsv_desc.Texture2D.MipSlice = 0;

D3D11_SHADER_RESOURCE_VIEW_DESC sr_desc;
sr_desc.Format                    = DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
sr_desc.ViewDimenstion            = D3D11_SRV_DIMENSION_TEXTURE2D;
sr_desc.Texture2D.MostDetailedMip = 0;
sr_desc.Texture2D.MipLevels       = -1;

ID3D11ShaderResourceView* mShaderResourceView = nullptr;

VERIFY(mD3DDevice->CreateTexture2D(&depthStencilDesc, 0, &mDepthStencilBuffer));
VERIFY(mD3DDevice->CreateDepthStencilView(mDepthStencilBuffer, &dsv_desc, &mDepthStencilView));
VERIFY(mD3DDevice->CreateDepthStencilView(mDepthStencilBuffer, &sr_desc, &mShaderResourceView));

 
 

2. Can I bind the mDepthStencilView as a shader resource view directly? Up till this point I have not sampled the depth buffer directly, only let the API use it in the depth test, so I have never thought of using it as an explicit shader input until now.


No. You have to use the shader resource view created using the code above.
 

3. Since the format is DXGI_FORMAT_D24_UNORM_S8_UINT, that means that there are 24bits for the depth, right? How do I turn those into the floating point depth value between 0 and 1 in the pixel shader? Is there a special sampler I need to create or do I sample the xyz values and somehow combine those into a single value using bitwise operations in the shader?

 
The shader resource view associated with the depth texture uses the format DXGI_FORMAT_R24_UNORM_X8_TYPELESS, so when you sample the Texture2D in the pixel shader the RED channel will contain "the floating point depth value between 0 and 1".




#5189140 How Can I Make This Scene Look Better

Posted by TiagoCosta on 25 October 2014 - 05:08 PM

First of all, add a light bulb cool.png .

 

Then,

 

-Shadows (like you said);

-Ambient occlusion (SSAO at the very least, or better (and more complex) if you have the time)

 

And some post processing:

-Bloom (for some glare when looking directly at the light bulb) dont go crazy with it though... just a subtle effect

-Maybe some lens flares (for a sci-fi look use anamorphic lens flares rolleyes.gif )




#5188566 what's the principle behind the shader debugger?

Posted by TiagoCosta on 22 October 2014 - 12:22 PM

Renderdoc is open source and includes a shader debugger. Might be a good starting point for you.




#5187986 how to make a 3D Objbect move in circle?

Posted by TiagoCosta on 19 October 2014 - 08:29 AM

You're resetting the angle to 0 every update, that's why it doesn't change. Move angle to the class definition and only initialize it to 0 in the constructor.
 

class Lazer
{
    [...]
    float angle;
};

Laser::Laser() : angle(0.0f)
{
    [...]
}

void Lazer::UpdateLazer(float dt)
{
    angle += dt*D3DX_PI / 4; //rotate 45 degrees per seconds

    [...]
}



#5187980 how to make a 3D Objbect move in circle?

Posted by TiagoCosta on 19 October 2014 - 07:49 AM

image001.gif
 
Follow this image. p is the radius, θ (theta) azimuthal angle, and φ (phi) polar angle.
The angles are in radians.
 
So if you want the object to move in a circle on the xy-plane:
Set the φ to π/2 (pi/2) and update θ each frame:
 



void Object::UpdateObject(float dt)
{
    angle += dt*PI/4; //rotate 45 degrees per seconds

    if(angle > 2*PI)
       angle -= 2*PI;

    ObjectPos = getPositionInSphere(sphere_center, radius, angle ,PI/2);
    D3DXMatrixTranslation(&matTrans, ObjectPos.x, ObjectPos.y, ObjectPos.z);

    [...]
}

EDIT #1: 

BTW, you might have to switch the coordinates in the function getPositionInSphere if you're using a different coordinate system.
 
For the typical D3D left-hand coordinate system:

Vector3 getPositionInSphereD3D(Vector3 sphere_center, float radius, float theta, float phi)
{
    return Vector3(sphere_center.x + radius * sin(phi) * sin(theta),
                   sphere_center.y + radius * cos(phi),
                   sphere_center.z + radius * sin(phi) * cos(theta));
}

 
EDIT #2:
 
Since you only want to move in a circle (phi is constant PI/2), the function turns into polar coordinates:
 

Vector3 getPositionInCircleD3D(Vector3 sphere_center, float radius, float theta)
{
    return Vector3(sphere_center.x + radius * sin(theta),
                   sphere_center.y,
                   sphere_center.z + radius * cos(theta));
}



#5187839 Help! GS StreamOutput..

Posted by TiagoCosta on 18 October 2014 - 09:35 AM

You can stream output a PointStream (more info here), so it can be one float4 per GS invocation.

 

EDIT:

 

I think I misunderstood your question...

 

You want to send a triangle/line stream to the rasterizer and stream output to a PointStream in the same geometry shader right?

 

From the docs:

 

 

When using multiple output streams, all streams must contain points, and up to one output stream can be sent to the rasterizer. More commonly, an application will not rasterize any stream.

 

So, unless there's a trick that I don't know, I think you'll have to use two passes, one to stream output points, and a second to rasterize triangles or lines.

 

This is how particle systems are implemented using the geometry shader. 1st update each particle in the GS and stream output, and then use a different GS that expands the particles to quads and sends them to the pixel shader.




#5186469 Multiple windows and views - help me understand Direct3D11 a little better?

Posted by TiagoCosta on 12 October 2014 - 07:30 AM

* Do I need a separate device per view that I'm rendering? Or only per window? Or do I only need one device for all windows? (I'm guessing: one device in total)

 

I've never used multiple windows, but I think you can use the same device for all windows. However you need to create a separate swap chain for each window. More info here

 

* Do I need a separate swap chain per view? (I'm guessing I need one per view because each represents a flat rendered end result)

 

You only need one swap chain per window (multiple views inside the same window share the same swap chain)


* If I only need one device, should I still be creating one device context per view?

 

Not necessarily. Multiple device contexts are used to generate command lists, etc.


* What is the relationship between the device context and the swap chain?

 

From the docs:

 

A device context contains the circumstance or setting in which a device is used. More specifically, a device context is used to set pipeline state and generate rendering commands using the resources owned by a device.

 

So I don't think there is any special relationship.


* Should I be rendering each view to a texture and then arranging the views in a "flat" 3D scene that simply defines the positions of each view?

 

Unless you're doing some special composition, you can draw directly to each swap chain back buffer (render target), and use multiple viewports to arrange the views.

 

Overview:

 

-Create a device (and immediate context).

-Create one swap chain for each window (using the appropriate descs)

-For each window:

    -Set window's swap chain's backbuffer as render target

    -For each view inside window:

        -Set the viewport desc

        -Render view contents

 

If you need to do a composition of the views more complex than simple viewports then create offscreen render targets and render to those instead, and then render them to the backbuffer.




#5186070 Rendering engine design

Posted by TiagoCosta on 09 October 2014 - 03:19 PM

Do you know some open source (preferably using OpenGL) rendering engines that are reasonably small (to read the code easily), but good enough to take as example to start with?

 

Check out Horde3D (OpenGL). It's a small and easy to read open source rendering engine (supports both forward and deferred rendering and uses a (limited) data-driven architecture). So it should be a good starting point.

 

I'm also releasing my small open source engine in a couple of weeks cool.png




#5185990 Generate Billboards from Tesselation Shaders possible?

Posted by TiagoCosta on 09 October 2014 - 08:14 AM

if I'm correct if I use CopyStructureCount(g_pIndirectArg,0,bufferWithParticles), the function will copy the particle amount to the slot [0] which contains the VertexCountPerInstance instead of the desired InstanceCount.

 

So change the second argument of CopyStructureCount, DstAlignedByteOffset (Offset from the start of pDstBuffer to write 32-bit UINT structure count), to 4 ( size of VertexCountPerInstance). 

This way the number of particles will be copied to the correct location.

CopyStructureCount(g_pIndirectArg, 4,bufferWithParticles)



#5185302 Forward+ Rendering - best way to updating light buffer ?

Posted by TiagoCosta on 06 October 2014 - 09:31 AM

I would guess releasing/recreating it would not be a good idea

 

You guessed right!

 

Simply create a ID3D11Buffer with D3D11_USAGE_DYNAMIC flag , large enough to hold the data of the maximum number of lights you'll need (512, 1024, 2048?), and update it using MAP_DISCARD every frame (or using a dirty flag when the lights change).

And pass the number of active lights in a cbuffer to the shader.

 

Since you're probably updating the light buffer once per frame this shouldn't be a bottleneck.

 

If you really need a more dynamic max number of lights try to reduce the number of times you release/create a buffer by doubling/halving it's size every time you resize it or something like that.




#5185104 Two Questions about DirectX 11 (XMVECTOR & Creating Input Layouts)

Posted by TiagoCosta on 05 October 2014 - 05:36 AM

About 1st question, Yes, I mean the reason for passing arguments by value and reference instead of using pointers.

 

What advantage would pointers have over references?

 

IMO, functions should only use pointers as arguments when the arguments might be NULL (or arrays, etc), otherwise use references.

 

Does it make sense to calculate XMVector3Cross(v1, nullptr)? References make it clear that the function expects two valid vectors, removes the need to check if the arguments are valid and prevents exceptions.




#5182522 What kind of performance to expect from real-time particle sorting?

Posted by TiagoCosta on 23 September 2014 - 05:28 PM

Have you tried Bitonic sort? And if you can use compute shaders this talk gives details on how to implement bitonic sort using Compute shaders.

 

I haven't used it myself but it might be useful to you.




#5179086 Help with GPU Pro 5 Hi-Z Screen Space Reflections

Posted by TiagoCosta on 09 September 2014 - 08:29 AM

1) Seems as if the author moved away from using spheres aligned with the traced cone (using cubes). I wonder why (better coverage of the cone most likely)


I don't think so. He still uses spheres. He uses the sphere's center (texture coordinates) and radius (mip level) to sample the color/visibility buffers. In the video he is drawing the texels (pink squares) used over the cone (if you pause the video you can actually see the cone behind some of the squares). I'm not sure what the color on the squares mean though... My guess would be that it is the weight based on visibility and trilinear interpolation that he mentions in the article.
 

2) The cone angle varies!!! Meaning the glossiness term drives the side of the opposite length of the triangle (as opposed to the actual cone angle)?! See as the reflected point gets closer to the character the cone angle widens dramatically. I wonder if I mis-understood the article or if the author is using a different approach in the video...

 

I don't know about that either. I think that the angle should stay the same (assuming that the glossiness of the ground is constant) as the reflection gets closer to the object and the cone should get smaller.




#5178975 Help with GPU Pro 5 Hi-Z Screen Space Reflections

Posted by TiagoCosta on 08 September 2014 - 06:06 PM

Here's an example of the case that needs to be solved. (note: you can see the color values that will be fetched by each sphere, the bigger the sphere, the blurrier the fetch). This is the case where a reflection approaches an edge. On the top image the ray hits the sphere, and on the bottom image, the ray hits the background and all of the contribution comes from the edge sphere (so the reflection result is the blurred sky). The question is how should the weight of each of those spheres be set so that there is a smooth transition between the left and the right reflection?

 

Are you weighting the spheres using the visibility buffer? The article mentions 3 weighting methods: basic averaging, distance-based weighting, and hierarchical pre-integrated visibility buffer weighting.


ct2.jpg
ct3.jpg

 

Btw, shouldn't each of those circles have a solid color (single texture fetch)?




#5178922 Help with GPU Pro 5 Hi-Z Screen Space Reflections

Posted by TiagoCosta on 08 September 2014 - 01:10 PM

Hi Tiago, not sure if you saw my post #18 but I proposed the same solution. I think it's probably what was intended.

 

Yes, I missed that post! Do you have any idea how the 37.5% was calculated? By applying the modified pre integration pass, Mip 2 should also have 50% visibility, however I'm not sure if it is correct

 

Anyway the formula on post #21 is probably incorrect because it should only calculate the percentage of empty volume between the coarser cell's min and max z, right?






PARTNERS