Jump to content

  • Log In with Google      Sign In   
  • Create Account

WFP

Member Since 23 Mar 2013
Offline Last Active Yesterday, 09:32 PM

#5288830 Resource barrier pre and post states

Posted by WFP on 26 April 2016 - 03:55 PM

Subresources can be in different states, but the rules still apply when setting resource barriers in that the before and after states must be correct.  So for example, you could set mip level 0 to a shader resource and mip level 1 as a render target.  See the documentation for D3D12_RESOURCE_TRANSITION_BARRIER, specifically the Subresource member.




#5287869 [D3D12] About CommandList, CommandQueue and CommandAllocator

Posted by WFP on 20 April 2016 - 06:24 PM

You can definitely re-use command lists, as well as command allocators, albeit at different paces.

 

You can think of a command list as providing the interface to write instructions to the command allocator.  The command allocator is basically just a chunk of memory that lives somewhere.  It doesn't really matter exactly where - that's for the driver implementer to decide.  When you submit a command list to the command queue, you're basically saying "this is the next chunk of work for the GPU to complete and here's the chunk of memory that contains all the instructions".  Even if the GPU immediately takes that work on (it probably won't), you still need that chunk of memory containing the instructions to be available the entire time they're being processed and executed.

 

So for command lists, you can reset them as soon as you have submitted them to the command queue and immediately begin to reuse them, because all you're really resetting is the command allocator they're using.  However, you must not reset the command allocator that's just been submitted until you are completely sure that all GPU work has completed.  Once you're sure the GPU has finished working on the tasks submitted to it, then you're free to cycle back and reset/reuse that allocator.

 

I'd recommend searching this site for ID3D12Fence.  I'm sure I've seen a few posts over the past few months that have touched on this topic and show how to synchronize command list and allocator usage across multiple frames.  To get you started, though, you'll need to think in terms of having enough allocators to cover however many frames of latency you'll be working with.




#5274753 [DX12] Constant Buffer Packing

Posted by WFP on 07 February 2016 - 09:31 AM

You seem to have discovered for yourself, and Krzysztof mentioned, how arrays are stored in HLSL constant buffers.  A possible solution to this would be to just halve your sample count and use the full float4 for storage.  Your example would turn into:

static const int SampleCount = 64;

struct OffsetData
{
    float4 Samples[SampleCount];
};

Then just index into it for the value you want:

[unroll]
for(uint i = 0; i < SampleCount; ++i)
{
	[unroll]
	for(uint j = 0; j < 4; ++j)
	{

		float currentDataPoint = Samples[i][j];
	}
}

You can update that loop to extract the float2 value if that's what you're after, the approach is essentially the same.

 

Edit:  Here's some documentation.  It's for SM4, but I'm almost positive it hasn't changed since https://msdn.microsoft.com/en-us/library/windows/desktop/bb509632(v=vs.85).aspx




#5272417 [D3D12] Command Allocator / Command List usage

Posted by WFP on 23 January 2016 - 07:18 PM

It's OK to reset the command list immediately after submitting it as long as you use a different allocator or wait for a GPU signal that the submitted work has completed.

ID3D12CommandAllocator* pAlloc1, pAlloc2;
ID3D12GraphicsCommandList* pCmdList;

// later on
pCmdList->Reset(pAlloc1, nullptr);
// record some commands
pCommandQueue->ExecuteCommandLists(1, &pCmdList);
pCommandQueue->Signal(pFence, fenceValue);

// now you can reset the command list, but use pAlloc2 since pAlloc1 will still be executing
pCmdList->Reset(pAlloc2, nullptr);


After submitting the command list the second time (after recording into pAlloc2), you need to check the fence value set after the first submission to make sure it has completed before resetting with pAlloc1.  You can use more allocators to avoid the likeliness of actually blocking on a fence very often if at all, but allocators only ever increase in size, so the largest batch of commands submitted to one is how much memory that allocator will consume until it's destroyed (COM destroyed through Release, not Reset).

 


Command Allocator Reset: It seems as though this is literally destroying the contents of the heap, which may have command list data active on the GPU.

 

Kind of.  That's exactly why you'd want to ensure the job is done executing before resetting the command allocator, but it's likely more of a pointer reset to the beginning of the allocator's memory than any type of expensive deconstruction.

 


How does the memory ownership work between the command allocator and command list? Is the allocator doing implicit double (or more?) buffering on a command list reset?

 

The allocator owns the memory.  The command list is your interface to write into that memory, but it doesn't actually own it.  You've probably deduced from the previous parts of the post that the allocator does no additional buffering (double or otherwise), so again, that's why you want to ensure your work is done (fence) before resetting an allocator.




#5271344 HLSL Bilinear Filtering ?

Posted by WFP on 15 January 2016 - 03:45 PM


Doesn't D3D11_FILTER_MIN_MAG_MIP_LINEAR enable trilinear filtering

 

Yes, that's correct.  As long as the samples are from non-fractional mip levels, the result is the same as bilinear filtering.  In the use case above, you could also use D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT for the same result.




#5269324 Questions About Blur Effect

Posted by WFP on 04 January 2016 - 08:52 PM

Adam_42's way to increase the blur is one approach.  Another approach is to simply run the result of the first blur pass through the blur technique again.  In pseudo-code it would look something like this:

int numPasses = 3;
for(int i = 0; i < numPasses; ++i)
{
    setInputImage(imageToBlur);
    setRenderTarget(tempBuffer);
    blurVertical();
    setInputImage(tempBuffer);
    setRenderTarget(imageToBlur);
    blurHorizontal();
}

If you were using a 7-tap blur in your shader and ran it through that loop 3 times, you would have the same result as running a 21-tap blur.




#5269323 Subsurface Scattering - Transmittance

Posted by WFP on 04 January 2016 - 08:43 PM

Unfortunately I haven't used either of the other approaches, so I won't be able to be too much help there.  If you render the front and back faces, you should be able to calculate the thickness of the geometry and use that as a replacement for the thickness value you'd get from the shadow map.  The difference, though, is that using that value won't account for other occluders in the scene that would otherwise obstruct the light and diminish or cancel the transmittance effect.




#5269195 Questions About Blur Effect

Posted by WFP on 04 January 2016 - 08:47 AM

I'm not positive but my first guess is that it's because of the additional space you're taking between blur taps. Try it by just taking neighboring pixels and not using the below value. You can just set it to 1.0f for testing before removing it.

float blur = 20.0f; // The higher the more blurry

I'm on mobile at the moment, so I'll try to get to your other questions later if no one else has yet.


#5269029 Subsurface Scattering - Transmittance

Posted by WFP on 03 January 2016 - 11:31 AM

There shouldn't be any issue using the technique in a forward shading path.  You just apply it at the same time you draw and light your geometry.  If it's not already, add the world position as an output from the vertex shader / input to the pixel shader.  This way you don't even need to reconstruct it, you can use the interpolated value that gets generated from the rasterizer as the same value you'd be getting from reconstruction in a deferred setup.  You'll still need to access to your light's view-projection matrix and shadow map for sampling.  The steps are the same as above, minus position reconstruction, once you get to the pixel shader.

 

I'm not sure I'm interpreting Aras's comment correctly from the link you posted, but if he's saying that the shadow map isn't accessible, there might not be a good way to do this as it's a key part of the technique.  I'd be surprised if there wasn't some way to customize the pipeline though to provide the shadow map.  This is where my limited knowledge of Unity isn't helping.




#5269020 Subsurface Scattering - Transmittance

Posted by WFP on 03 January 2016 - 10:55 AM

I haven't worked with Unity so I'm not sure on some of its details, but from your description it sounds like you're using a deferred shading pipeline.  You should still have all you need to get the transmittance effect working.

 

From my description above, PWS comes from reconstructing the world space position from the depth buffer at a given pixel, or sampling it directly from a buffer that stores position - whichever Unity uses.  If you have access to that and the light's view-projection matrix, which should be included somewhere in a constant buffer as long as the shadow map is being applied to the light, you should have everything you need.  You shouldn't need any off-screen information for this effect.




#5269015 Questions About Blur Effect

Posted by WFP on 03 January 2016 - 10:42 AM

You need to do this as two separate passes, one horizontal then one vertical (or vice versa).  What you currently have is blurring each pixel in a cross shape instead of as the full area around the pixel.

 

In other words, your current setup is blurring like below for each pixel, where the middle pixel (P) is the current one.  Separating these into two passes and blurring the first pass into a temporary buffer to be used as the input for the second pass will give you a blur that includes the pixels in the area surrounding the center point, also.

        *
        *
        *
        *
********P*******
        *
        *
        *
        *



#5268923 Subsurface Scattering - Transmittance

Posted by WFP on 02 January 2016 - 08:44 PM

Hi and welcome,

 

It's been a while since I implemented this effect, so I may be a bit hazy on some details.  Basically what's happening is this.

 

  1. You have a world space position (PWS).  Nothing too special here, just a plain world space position.
  2. You transform position PWS by the light's view-projection matrix (PLVP).  This is similar to what you do for shadow mapping, but in this case instead of transforming a vertex, you're transforming the exact pixel's world space value.
  3. You then need to transform PLVP into texture space.  You can do this manually, or just add the texture space transform to the light's view-projection matrix, because the only component of PLVP that we need is the z-component (depth).
  4. Divide PLVP.xy by PLVP.w and use that as the texture coordinate to sample your shadow map (D1).
  5. Extract the z-component from PLVP (D2).
  6. In the implementation I followed (and the one you cited) they store their shadow maps linearly.  I don't do this, so I reconstruct their linear depth.  D1 and D2 both need to have linear depth.  If your shadow map is stored linearly, you can just multiply each by the far plane used in the light's projection matrix, otherwise you can use projection values to reconstruct them.  See MJP's post if you're unclear on what values to use:  https://mynameismjp.wordpress.com/2010/09/05/position-from-depth-3/
  7. Now that you have both values linearized, you can take the absolute value of their difference to find the distance between the depths DIST = abs(D1 - D2).

The rest of the effect is based on the scale, weights, and variances values that are generally defined per-kernel.  They will vary from material to material, but the code provided should give you all you need for using them properly.

 

The links below are a little more recent than the one you posted and include the transmittance function as part of the larger solution.

 

https://cg.tuwien.ac.at/~zsolnai/gfx/separable-subsurface-scattering-with-activision-blizzard/

http://www.iryoku.com/stare-into-the-future




#5267854 Debug slow using D3D11_CREATE_DEVICE_DEBUG

Posted by WFP on 24 December 2015 - 06:33 PM

Yes, the documentation for it even states to expect an app with the layer enabled to be substantially slower:  https://msdn.microsoft.com/en-us/library/windows/desktop/ff476881(v=vs.85).aspx#Debug




#5267825 Screen-Space Reflection, enough or mix needed ?

Posted by WFP on 24 December 2015 - 01:58 PM

The other commenters have pretty much mentioned this already, but there is very limited information in screen space, so yes you need something to fallback to when using screen space reflections.  In Matias's example, you'd want to use something like planar reflections on the mirror surface to reflect the scene since the data would otherwise not be present.

 

I'm not sure how self-promotion is looked at around here, but I wrote this blog post a while back that is pretty relevant to what you're trying to learn about.  Specifically, search for the word "fallback" - you'll see that it's brought up a lot!  Screen space reflections can look good, but they can also have jarring discontinuities that can ruin the bigger picture.  Using parallax-corrected environment maps can help.  You'll need to blend between ray hits and misses from your SSR for the transition between SSR and fallback not to be too noticeable.




#5259639 PBR Metalness equation

Posted by WFP on 29 October 2015 - 04:46 PM


If a material is 100% reflective, the diffuse doesn't matter right?

 

No.  What's stored in the diffuse texture always matters, it just means different things in different cases.  In the setup you're trying to use, if a material is 100% metal, the value in the diffuse texture is re-purposed to be the F0 value.  Otherwise, for non-metal (dielectric) materials you hard-code F0 to ~0.03-~0.04 for most materials (see Hodgman's comment), and the value in the diffuse texture is the diffuse color you're used to.  I haven't used Marmoset, but from seeing what a few other places are doing, the 0 to 1 mapping for F0 will probably do something like change the value from ~0.01 to ~0.08.

 

I think what you're referring to as reflectiveness is what most people refer to as roughness (or shininess).  This is stored in its own texture and is used alongside the others to control how shiny the surface is - this is what controls the specular highlights for direct lighting, and the mip selection for indirect lighting.  It is used as part of a larger equation to control surface appearance.

 

Most approaches use the following (or close variations) as the starting point of textures using physically based rendering.

 

Diffuse (or Base Color):  for dielectrics, exactly what's in the texture.  for metals, the f0 value

Metal:  0 - dielectric.  1 - metal.

Roughness:  how rough the microsurfaces along the geometry are (alternatively, this can be Shininess, which is just 1.0 - roughness)

Normal:  plain old normal map

 

There are a few variations to the above that different engines use, but that should give you the gist of where values are coming from.

 

As far as finding actual code used for PBR (btw, you need to read this stuff - start with the Physics of Math and Shading presentation and go from there):

 

http://blog.selfshadow.com/publications/s2013-shading-course/

http://blog.selfshadow.com/2014/08/12/physically-based-shading-at-siggraph-2014/

http://blog.selfshadow.com/publications/s2015-shading-course/






PARTNERS