WFP

GDNet+ Basic
  • Content count

    117
  • Joined

  • Last visited

Community Reputation

2784 Excellent

Personal Information

Social

  • Twitter
    @willp_tweets

Recent Profile Visitors

7342 profile views
  1. The root signature is what controls visibility and register assignment in D3D12. In your specific case for constant buffers, the D3D12_ROOT_DESCRIPTOR contains a ShaderRegister variable for you to fill out that will match what you type in your shader code as cbuffer MyCB: register(b#). For example, if you set ShaderRegister to 5, then you would declare cbuffer MyCB: register(b5). The D3D12_ROOT_PARAMETER (of which the root descriptor is a unioned member of) has a ShaderVisibility member that controls which stages of the pipeline the parameter is visible to. You can either set the visibility to ALL, or to individual stages and use duplicate (with different stage) entries in the root signature. See here: https://msdn.microsoft.com/en-us/library/windows/desktop/dn913202(v=vs.85).aspx#visibility In your case, you can give your shared constant buffers ALL visibility and set them once using SetGraphicsRootConstantBufferView, or you can give your shared constant buffers duplicate entries with specific visibilities (VERTEX and PIXEL) and set them each with separate calls to SetGraphicsRootConstantBufferView. The link above mentions this, but some hardware handles ALL differently and is less efficient than setting individual stages, while other hardware will have no extra cost for setting ALL. Keep in mind general best practices for root signatures when deciding on a route - keep the root signature as small as possible, with items that change more frequently towards the beginning. Root constant descriptors take 2 DWORDS each, so can start to grow your root signature quickly if you're not mindful. More documentation that you might find helpful: https://msdn.microsoft.com/en-us/library/windows/desktop/dn859357(v=vs.85).aspx https://msdn.microsoft.com/en-us/library/windows/desktop/dn986747(v=vs.85).aspx https://msdn.microsoft.com/en-us/library/windows/desktop/dn879476(v=vs.85).aspx https://msdn.microsoft.com/en-us/library/windows/desktop/dn879482(v=vs.85).aspx
  2. Yes to the first part, not exactly (but close) to the bulleted question. If you can swing it, you should consider using the same or similar allocators for the same command lists. For example, let's say you're doing deferred rendering and are drawing some number of items. Your pass to fill the gbuffer may take (for example's sake) 200 calls to various functions on the command list, which are written to the allocator. Your shadowmap pass has to be run for each shadow-casting light, so you'll have somewhere in the neighborhood of 200 * numLights entries in the command list, and therefore that allocator. If in a subsequent frame, you use the allocator you initially used for the gbuffer pass for the shadow map pass, that allocator will grow to the worst-case scenario size, i.e., the size required by the shadowmap pass. If instead you keep that allocator designated for gbuffer stuff only, it'll only be sized enough for your worst-case gbuffer pass, so could save on your overall memory budget. To answer whether you need to know the size of the command list before calling CreateCommandList, not precisely, but it's helpful to have some idea of how the command list will be used so you have a ballpark idea of how it will affect the allocator bound to it. Keep them to a minimum, but don't dig yourself into a hole. You can reuse an existing command list to write into a separate allocator than the one you initially created it with while the initial allocator's content is being consumed by the GPU. You still must set and track your fence values to be sure that the GPU is done with the allocator you're about to reset and reuse. You should create enough to cover your maximum latency, but if it comes down to it, you still must be able to block and wait for the GPU to finish it's work if all the command allocators are occupied. This is like the pool of allocators @galop1n mentioned in his post.
  3. Any chance the working directory is being changed? Can you post your log / crash output here? Could you add a log statement before compiling the shaders (in the loadAndCompileShaderFile function) to print out the working directory?
  4. The "Sky" is too short!

    You could use them, or keep your sky dome and in the vertex shader do something like: //... some code posH = mul(inputPos, viewProjMtx); // this is your SV_Position output posH.z = posH.w; // when the divide by w occurs, this will make the depth 1.0 (far plane) //... whatever else You could also just use a full-screen triangle or quad and use the same "push it to the far plane" logic. Then in the pixel shader, color it based off the y component of a view ray (a ray from starting at the camera and extending out into the scene) - all depends on how fancy you want to get. If you stick with the dome, make sure you only transform it by the camera's position, and not rotation - otherwise the entire sky will spin as the camera spins.
  5. This warning usually means that the resource you're using in **SetShaderResources is bound as a render target. The D3D11 runtime will remove it for you and give you a warning, but for correctness (warning-free output) you should either overwrite what's bound to the output merger before setting the shader resources OMSetRenderTargets(1, &newRTV, nullptr); or clear what's currently bound by setting it to null: OMSetRenderTargets(0, nullptr, nullptr);
  6. The "Sky" is too short!

    To expand just a bit on Kylotan's accurate response - in your specific application, what does a "unit" mean? In other words, is the value "1 unit" representative of 1 meter, 1 centimeter, or some other value altogether? If 1 unit = 1 cm, then a sky 1000 units away would be 10 meters away. Alternatively, if your app takes place entirely on the ground and the sky is supposed to look infinitely far away, you could always force the geometry to the far plane in the vertex shader and have its position transform with the camera position to give the illusion that it's so far away it doesn't move when the camera moves a bit.
  7. I won't have time to do a full install and all that, but if you can grab a capture with RenderDoc (or a few captures with different deficiencies showing), I might be able to step through the shader that way and see what could be going on. Can't promise when I'll have a lot of focused time to sit down with it, but I'll try to as soon as I can.
  8. Admittedly, I've done very little with stereo rendering, but perhaps this offset needs to be accounted for in your vertex shader? float4 stereo = StereoParams.Load(0); float separation = stereo.x * (leftEye ? -1 : 1); float convergence = stereo.y; viewPosition.x += separation * convergence * inverseProj._m00; The view ray you create in the vertex shader may need to be adjusted similarly to align correctly. Just kinda guessing at the moment
  9. For thoroughness's sake, would you mind switching them back to non-negated versions and seeing if that helps? Could you also test with the original rayLength code? Does the game use a right- or left-handed coordinate system?
  10. Is there a particular reason you're negating these values? traceScreenSpaceRay(-rayOriginVS, -rayDirectionVS
  11. Crap! Sorry again for the delay, let's see if we can get you sorted out If this is a full-screen pass, I would suggest trying the position reconstruction from my other post and see how that works out for you. Also - are you sure that the water surface is written to the depth buffer? If the game draws it as a transparent surface, it may disable writes when drawing it. That would mean you're actually using the land surface underneath the water as the reflection start point. I would first try using the projected view ray I mentioned and see if that gets you anywhere: o10 = mul(modelView, v0.xyzw); //viewPosition o10 = float4(o10.xy / o10.z, 1.0f, o10.w); If you're doing the SSR as part of the water shader itself, i.e. at the same time as drawing the transformed water geometry, you should be able to calculate the view space position and pass it through to the pixel shader, then use that value directly instead of combining it with a linearized depth value. Let me know if any of that helps.
  12. At first glance, this seems incorrect to me: float3 rayOriginVS = viewPosition * linearizeDepth(depth); Can you tell me what value you're storing in viewPosition? In my implementation, that line describes a ray from the camera projected all the way to the far clip plane. In the vertex shader: // project the view-space position to the far plane vertexOut.viewRay = float3(posV.xy / posV.z, 1.0f); Using that multiplied by linearized depth lets you reconstruct view-space position in the pixel shader, which is what you need for rayOriginVS. MJP's entire series is a great resource on reconstructing position from depth, but the last post, https://mynameismjp.wordpress.com/2010/09/05/position-from-depth-3/, is closest to what I use for most cases. I don't own/haven't played the game, so this is strictly a guess, but to me it looks like the rocks (as well as the boat and fisherman in it) are billboarded sprites. If that's the case, there's a good chance they aren't even being written to the depth buffer, which means there would be nothing for the ray-tracing step to detect. Are you able to pull a linearized version of the depth buffer that shows what is and isn't actually stored in it? That could be really helpful for debugging . P.S. I think you might be the same person that was asking about this (Dirt 3 mod + 3DMigoto) on my blog post on glossy reflections. Sorry I never got back to you - to be completely honest, I got really busy with a few things around then and forgot over time.
  13. Yeah, I think something with the site updates may have messed up the gallery link. You can find them by going to my profile and clicking the Albums tab, or use this link:
  14. On mobile right now, but briefly - the HLSL compiler will spit out the same intermediate bytecode regardless of what your system specs are. When your application calls a D3D function to load the shader from the pre-compiled bytecode, it will be compiled again in a vendor-specific way before actually being used. So to answer your question - you can compile a shader on one machine with a dedicated GPU and run it on another machine with an integrated GPU just fine.
  15. Passes are typically ran sequentially. If you ran 100 passes, the instructions would get executed serially just like any other instruction. Looking at it at a bit of a finer grain - the CPU instructions will get executed serially, and move along. At some point in the future the commands that the CPU generates and sends to the GPU will get executed in the order sent. Your program should be no more or less prone to freezing while processing a loop of 100 render passes than it would be a loop of anything else.