Jump to content
  • Advertisement


  • Content Count

  • Joined

  • Last visited

  • Days Won


ChuckNovice last won the day on August 7 2018

ChuckNovice had the most liked content!

Community Reputation

153 Neutral

About ChuckNovice

  • Rank

Personal Information

  • Role
  • Interests

Recent Profile Visitors

2382 profile views
  1. Mmmm there might be more to change than I thought. You are doing only one light per pass, reading your whole GBuffer everytime and you got a different shader for each type of light? The sunlight and the red/green point lights should all be done in the same shader. For that to work you should have an array of all your lights passed to your shader so you can easily loop in all of them in one single pass. On my side all the lights are stored in one big array as a linked list no matter if it's a point light, directional light or spot light. Each light points to the next one of the same type within the collection. Here the relevant parts of my shader. It's in HLSL but still give the big picture : //--------------------------------------------------------------------------------------- // Defines the data structure of a light projection. //--------------------------------------------------------------------------------------- struct LightProjection { // 64 bytes pack float4x4 ViewProjection; // 16 bytes pack float Near; float Far; float2 ShadowMapTileSize; // 16 bytes pack float3 ShadowMapTileOffset; bool HasShadowMap; }; //--------------------------------------------------------------------------------------- // Defines the data structure of a light. //--------------------------------------------------------------------------------------- struct Light { // 16 bytes pack float3 Position; float FalloffStart; // 16 bytes pack float3 Direction; float FalloffEnd; // 16 bytes pack float3 Color; float SpotAngle; // 96 aligned pack LightProjection Projection; // 16 bytes pack bool Enabled; float ShadowBias; int ShadowQuality; int Next; }; StructuredBuffer<Light> _dynamicLights : register(t0); // collection of dynamic lights. //-------------------------------------------------- // The part of the shader that handle the light/shadow //-------------------------------------------------- int dynamicDirectionalLightIndex = FrameConstantBuffer.DynamicDirectionalLightStartIndex; int dynamicPointLightIndex = FrameConstantBuffer.DynamicPointLightStartIndex; Light light; float3 accumulatedLight; // loop through the directional lights. while (dynamicDirectionalLightIndex != -1) { light = _dynamicLights[dynamicDirectionalLightIndex]; accumulatedLight += ComputeDirectionalLight(light, attributes); dynamicDirectionalLightIndex = light.Next; } // loop through the point lights. while (dynamicPointLightIndex != -1) { light = _dynamicLights[dynamicPointLightIndex]; accumulatedLight += ComputePointLight(light, attributes); dynamicPointLightIndex = light.Next; } In this example, ComputeDirectionalLight and ComputePointLight both check the shadow map of the current light and immediately return 0, 0, 0 if it's shadowed before trying to calculate the light contribution which make it that easy to get the result that you saw in the screenshot of my previous post.
  2. Isn't the "sunlight" already calculated just like any of your other lights in your lighting shader? The problem you're having will remain if you "combine" the shadow and light only at the end as some lights still need to contribute to the pixel color even if it's in the shadow of another one. You're entering a whole world of patch and hacks if you want to get it working this way. The simplest way to fix it is to bring your ShadowCalculation function and the shadow map in your lighting shader and drop the combine process. My engine also has a deferred pipeline and a light is a light, no matter if it's a directional light for the sun or an orange point light to make a fire look more real. Light and shadow are both calculated during the same pass which make that particular problem very easy to solve. In this screenshot the orange light doesn't cast shadow and it work even if we are in the shadow of another light.
  3. Here's a simple way to see it that would fix your problem. A pixel may be affected by many source of light and each light may or may not have a shadow map. You should iterate through all the lights that affect your pixel and accumulate their contribution which you seem to be doing already as I see two light properly mixing up together in your screenshot. However you should also join your shadow calculation process to this. If you organized your data in a way that you can identify which light each shadow map are attached to, you should easily be able to skip the light calculation if the pixel is in the shadow of the current light but let the loop continue and other lights contribute to the final pixel color. EDIT: Looking at your code I see that you may have added too many step to your deferred renderer. Light and shadow should be done in the same pass. Not only will you avoid doing an expensive light calculation if the pixel is shadowed but you'll also fix these kind of problem.
  4. If you're purely talking about the reflection direction, I would be tempted to say that the magic simply happen with your normal map as long as the normals don't all point perfectly in the same direction.
  5. What you described is exactly what the vertex shader does. You have the responsibility to determine the screen position of each vertex in that shader which also means that you are free to displace them on the fly however you like. You don't need to reupload vertex data everytime.
  6. ChuckNovice

    Weird depth buffer values

    It still shouldn't be causing this problem. Please post your near/far values as requested by vinterberg. A too small near value will screw up your depth precision. Better to fix the problem at the source than patching it.
  7. ChuckNovice

    Multithreaded Rendering

    Yes Present() is the last command that you queue at the end of a frame to display the generated image to the screen so when it happens it mean that all previous commands have been executed.
  8. ChuckNovice

    Multithreaded Rendering

    By presentation you mean the framegraph thing or calls to Present()?
  9. ChuckNovice

    Multithreaded Rendering

    Just to clear up some possible confusion. When I say that you are guaranteed that the frame is done processing, I am assuming a proper usage of the frame latency of the swapchain. A swapchain that is configured for triple buffering with a frame latency of 2 will allow you to have 2 pending Present() operations before conveniently blocking the waitable object that it gives you.
  10. ChuckNovice

    Multithreaded Rendering

    DirectX 12 here but the same should apply. I am not an expert either and still discovering things from that API but what I ended up doing is as already discussed. One instance of a cache per swapchain buffer with a command pool in each cache instance. The way your swapchain rotate guarantee that the current cache you're playing with is done executing on the GPU. Command buffers are pushed / popped in a stack and I assign them the frame they were used in when popping them from the stack. The stack is therefore sorted from the most recently used to the least recently used command buffer and I know for which frame they were last used which make it easy to clean up things efficiently. One instance of that stack exists for every classification of command buffer. In my case I allow specifying a light / medium or large command buffer when getting one from the pool so I can approximately reuse the same size. However what helped me the most regarding multithreading is using a more modular approach as described in this presentation : https://www.gdcvault.com/play/1024612/FrameGraph-Extensible-Rendering-Architecture-in A framegraph basically describes every operations that should be done to render a frame and is aware of every used resource to generate the frame which helps with resource states transitions / split barriers etc... Every module within a framegraph are responsible of a precise task and take specific inputs / outputs (Depth pass / GBuffer pass / Light pass / Post processing / Downsampling module / Others useful tasks...) to feed one or many command lists that they receive from the framegraph. From the point of view of the framegraph it becomes much easier to determine how many command list to create and what can be tasked in parallel.
  11. ChuckNovice

    UpdateTileMappings with multiple heaps?

    I got it to work. Turn out I was simply sampling from the wrong array slice of my texture array. I got one more question regarding this. I'm unable to visualize reserved resources with PIX. They don't seem to be supported yet. How do you guys debug yours? I would've expected to be able to see my reserved resource as specified by the tile mapping.
  12. ChuckNovice

    UpdateTileMappings with multiple heaps?

    So the right way actually is to call UpdateTileMappings multiple times? Thanks, I will concentrate my efforts on figuring out what went wrong when I tried it.
  13. According to the documentation we should be able to bind the tiles of a reserved resource to more than one heap but I haven't found a way to achieve this. "with the one key difference that D3D12 allows a reserved resource to have tiles from multiple heaps" https://docs.microsoft.com/en-us/windows/desktop/api/d3d12/nf-d3d12-id3d12commandqueue-updatetilemappings UpdateTileMappings only accept one heap as parameter and calling it multiple times with a different heap override the whole mapping with the last call unless I screwed up somewhere else? Can someone explain it in greater detail than this documentation?
  14. ChuckNovice

    G-Buffer 2 Channel Normal

    Interesting page. It motivated me to try some of these methods. The one that preserved the best quality in my project was Method #7: Stereographic Projection. Most of the others ended up having few noticeable artifacts in the negative values when zooming in. I'm curious to hear about other people's result.
  15. The question is too general. Start with this sample to get the basics. When all this will be clear for you you can move to loading textures etc... https://github.com/sharpdx/SharpDX-Samples/tree/master/Desktop/Direct3D11/MiniTri
  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!