[video output=day434 member=cmuratori stream_platform=twitch stream_username=handmade_hero project=code title="Replacing the Pseudo-random Number Generator" vod_platform=youtube id=OlSYfj8VZi0 annotator=Miblo]
[0:01][Recap and set the stage for the day investigating the variance (flicker) in the :lighting][:rendering :run]
[4:15][Read through and describe our usage of photons per second in the :lighting code][:rendering :research]
[8:28][Make ComputeLightPropagation() consider the approximate location of the moon (i.e. directly up in Z) when applying its colour][:lighting :rendering]
[9:27][:Run the game to see that underside surfaces are black][:lighting :rendering]
[10:10][Temporarily increase the MoonColor brightness in ComputeLightPropagation()][:lighting :rendering]
[10:19][See that brighter moon and admire the character of the scene][:lighting :rendering :run]
[12:42][Remove the SkyColor, GroundColor and SunDirection from ComputeLightPropagation()][:lighting :rendering]
[13:06][Transferring light as photons per second][:blackboard :lighting :rendering]
[16:02][Complete sample, if sampling every single photon hit by an infinite number of rays][:blackboard :lighting :rendering :statistics]
[19:39][Our actual sample, casting 64 rays with temporal antialiasing filtering, and questions to consider][:blackboard :lighting :rendering :statistics]
[30:31][Consider explicitly accumulating all :lighting points and only averaging at the end][:lighting :rendering :research]
[33:12][Rename Emit to LastPPS and Direction to LastDirection, and add SampleCount in lighting_point_state, to enable ComputeLightPropagation() to accumulate all :lighting points directly without doing temporal blending?][:rendering]
[39:02][:Run the game to see a totally stable :lighting solution][:rendering]
[40:42][Introduce the notion of a fixed LIGHT_TEST_ACCUMULATION_COUNT, to make the light converge over this many iterations of the :lighting routine][:rendering]
[48:38][Add a key to toggle the converging :lighting accumulation in UpdateAndRenderWorld()][:"input handling" :rendering]
[49:27][:Run the game and try toggling the :lighting accumulation][:rendering]
[49:45][Enable LightingTest() to map the :lighting points back][:rendering]
[51:37][:Run the game to try toggling the :lighting convergence][:rendering]
[52:26][Make LightingTest() cap the AccumulationCount][:lighting :rendering]
[53:03][:Run the game to see our "converged" :lighting getting brighter, and investigate why][:rendering :run]
[55:23][Correctly make LightingTest() cap the AccumulationCount][:lighting :rendering]
[55:36][:Run the game and admire our converged :lighting solution][:rendering]
[56:37][@insobot][56 minutes into the main stream. 50 until Q&A. (based on NOTE)]
[56:42][Toggle the :lighting accumulation and consider how to address the oscillation][:lighting :rendering :run]
[59:52][Increase LIGHT_TEST_ACCUMULATION_COUNT from 256 to 1024][:lighting :rendering]
[1:00:03][Consider working on the hemisphere sampling][:lighting :rendering :run :statistics]
[1:02:15][Add :"debug visualisation" of the rays in LightingTest()][:lighting :rendering :statistics]
[1:06:43][:Run the game and check out the :"debug visualisation" of our rays, to see that there is some clumping][:lighting :rendering :statistics]
[1:07:42][Determine to improve the random number generation[ref
    site=Wikipedia
    page=Xorshift
    url=https://en.wikipedia.org/wiki/Xorshift][ref
        site=random.org
        url=https://random.org]][:prng :research :statistics]
[1:12:33][Recommend Melissa O'Neill's[ref
    site="Melissa O'Neill's Homepage"
    url=https://www.cs.hmc.edu/~oneill/index.html] PCG[ref
        author="Melissa E. O'Neill"
        title="PCG: A Family of Simple Fast Space-Efficient Statistically Good Algorithms for Random Number Generation"
        url=http://www.pcg-random.org/pdf/hmc-cs-2014-0905.pdf]][:prng :research]
[1:16:59][Consider the difficulty of performing PCG in SIMD, due to the absence of lane shifting until AVX-512[ref
    site=Intel
    page="Intel Intrinsics Guide"
    url=https://software.intel.com/sites/landingpage/IntrinsicsGuide/]][:optimisation :prng :research]
[1:21:39][Switch RandomNextUInt32() to perform xorshift][:prng]
[1:23:19][:Run the game to see an unexpected distribution][:"debug visualisation" :prng]
[1:23:47][Make RandomUnilateral() produce up to U32Max points of randomness][:prng]
[1:24:45][:Run the game to see a more expected, if still slightly clumpy, distribution][:"debug visualisation" :prng]
[1:26:46][Excise the old random number table in favour of xorshift][:prng]
[1:27:15][Take another look at the random distribution][:prng :run]
[1:27:43][LightingTest()][:lighting :prng :rendering :statistics]
[1:29:07][Weighted sampling][:blackboard :lighting :rendering :statistics]
[1:30:36][Start to make LightingTest() perform an inverse square-root mapping][:lighting :prng :rendering :statistics]
[1:31:39][:Run the game to see a more upward-facing distribution][:"debug visualisation" :prng]
[1:31:59][Continue to work on the upward-facing sampling equation in LightingTest()][:lighting :prng :rendering :statistics]
[1:33:58][Upward-biased sampling equation][:blackboard :mathematics :statistics]
[1:34:26][Fix the sampling equation in LightingTest()][:lighting :prng :rendering :statistics]
[1:34:42][:Run the game to see a more fully distributed upward-facing distribution][:"debug visualisation" :prng]
[1:35:39][Enable the rays to be randomly cast over time][:lighting :prng :rendering :statistics]
[1:36:58][:Run the game to see our randomly cast rays][:"debug visualisation" :prng]
[1:37:22][Switch our random number generator to operate in SIMD by default, introducing f32_4x versions of << and >>][:mathematics :optimisation :prng]
[1:43:11][Arithmetic vs logical shifting][:mathematics :speech]
[1:45:43][Introduce ShiftRight4X() and ShiftLeft4X() in lieu of f32_4x shift operators[ref
    site=Intel
    page="Intel Intrinsics Guide"
    url=https://software.intel.com/sites/landingpage/IntrinsicsGuide/]][:mathematics :optimisation]
[1:53:59][Step through RandomNextU324X() to watch what it does][:prng :run]
[1:58:18][Make RandomNextU324X() perform ShiftLeft4X() inline][:prng]
[2:00:07][Step in to RandomNextU324X() and inspect its values][:prng :run]
[2:00:47][:Owl of Shame Moment: It wasn't doing a lane-based shift[ref
    site=Intel
    page="Intel Intrinsics Guide"
    url=https://software.intel.com/sites/landingpage/IntrinsicsGuide/]][:prng :speech]
[2:01:50][Make ShiftRight4X() and ShiftLeft4X() use _mm_srli_epi32 and _mm_slli_epi32 respectively][:mathematics :optimisation :owl :programming]
[2:02:37][Step back through RandomNextU324X() to see that its values look reasonable][:owl :prng :run]
[2:03:35][:Run the game to see our ray distribution, with unexpectedly flicker-free :lighting][:owl :prng :rendering :statistics]
[2:06:11][Make U32_4x() pick the correct slice for RandomSeed()][:optimisation :owl :prng :programming]
[2:07:11][:Run the game to see our flicker back][:lighting :owl :rendering]
[2:08:43][Switch all our _mm_set*() calls to be _mm_setr*()][:optimisation :owl :programming]
[2:09:19][:Run the game and note the ordering of the _mm_set*() intrinsics[ref
    site=Intel
    page="Intel Intrinsics Guide"
    url=https://software.intel.com/sites/landingpage/IntrinsicsGuide/]][:optimisation :owl :research]
[2:10:56][Enable RandomBilateral_4x() to operate directly in SIMD, and introduce RandomUnilateral_4x() and U32ToF32()[ref
    site=Intel
    page="Intel Intrinsics Guide"
    url=https://software.intel.com/sites/landingpage/IntrinsicsGuide/]][:optimisation :owl :prng :programming]
[2:19:23][Consider negative and positive numbers in twos complement][:mathematics :owl :speech]
[2:21:47][Continue to implement RandomBilateral_4x()][:optimisation :owl :prng :programming]
[2:22:46][:Run the game and consider stopping here for today][:owl :prng]
[2:23:32][Q&A][:speech]
[2:24:00][@vateferfout][Q: Is there a drawback to implementing your f32_4x type as an union between __m18 and __m128i?][:optimisation]
[2:25:12][@vaualbus][Q: There is not windows functions for random number generation?][:prng]
[2:25:51][@vkar2][Q: You can still try my idea, keep one subray fixed, make 3 random][:prng :statistics]
[2:26:12][@n30sh4d0w][Q: So what does bilaterial vs. unilaterial mean?][:statistics]
[2:26:32][@vateferfout][Q: Doesn't relying on biased sampling instead of angular fall-off means that you could oversample if you use bilateral sampling?][:statistics]
[2:26:54][Sample distribution][:blackboard :statistics]
[2:28:58][@desuused][Q: Would it be reasonable to seed your :PRNG with RNG provided by OS?]
[2:29:44][@joshthebrawler][@handmade_hero I'm trying to start from the beginning of [~hero Handmade Hero] including the Intro to C videos, but you use visual studio 2013 express in it. Is it okay to use visual studio 2017 express windows instead, or are there too many differences and I should use the 2013 version?]
[2:30:38][@ingenero][Q: Can your current implementation of :lighting turn a surface into a mirror? Are the sample points too sparse to do that effectively, or does it not really work like that at all? I'm trying to wrap my mind around how it all works][:rendering]
[2:31:27][Using the "eye" vector to estimate perceived reflectance of surfaces][:blackboard :lighting :rendering]
[2:36:21][@longboolean][Q: You mentioned a few times that later on during world generation we will do a better job of adding sample points. Are theses sample points limited to static terrain or do you have ideas about how to handle terrain that can be in motion or altered in some other way?][:"procedural generation"]
[2:37:17][@vateferfout][Q: What I meant with the question is that if a surface B is nearly above surface A but perpendicular to it, there is a risk of a lot of rays originating from A could hit B and thus contribute a lot even though the angular falloff would prevent that][:lighting :rendering :statistics]
[2:37:41][Angular falloff][:blackboard :lighting :rendering]
[2:38:43][@vateferfout][Q: I'm talking about bilateral sampling][:statistics]
[2:39:43][@n30sh4d0w][Actually you're not 100% true in terms of the diagram, but your concept is true. The geometric concept of rays actually breaks down for caves or any cone (it's the infinite reflection problem). Conceptually though you are right. Normal objects are not mirrors. You actually have to use nonlinear optics and a geometric diagram to fully describe the lightening going into a cave][:lighting :rendering]
[2:40:58][Computing reflected light sources around corners][:blackboard :lighting :rendering]
[2:43:16][@n30sh4d0w][You can google The Illumination Problem - Numberphile for a full video on the topic][:lighting :rendering]
[2:48:07][We are good to go][:speech]
[/video]
