Douglas
Douglas
  • 25
  • 462 338
Doubling the speed of my game's graphics [Voxel Devlog #18]
Online demo: github.com/DouglasDwyer/octo-release
Additional voxel models: drive.google.com/drive/folders/1lXTpIvv9BGtOaAVj0oaVUmOKiZ_cfWwE?usp=sharing
With some clever tricks, I've managed to halve the frame times in my voxel game engine! Join me as I explain three essential optimizations for voxel rendering. These optimizations include using DDA for traversal, bitwise masking to filter out potential intersections, and performing a low-resolution depth prepass. In addition, I talk about ray marching in general and discuss the other new features that I added to my engine this month.
Music used in the video:
Chris Doerksen - Perfect Parry
Corbyn Kites - Orbit
White Bat Audio - Athena
White Bat Audio - Chroma
Chris Doerksen - New Groove
Переглядів: 16 428

Відео

Adding ray tracing (back) to my game engine [Voxel Devlog #17]
Переглядів 78 тис.Місяць тому
Online demo: github.com/DouglasDwyer/octo-release Additional voxel models: drive.google.com/drive/folders/1lXTpIvv9BGtOaAVj0oaVUmOKiZ_cfWwE?usp=sharing It's time for another devlog, and the engine has undergone a ground-up rewrite! In this video, I showcase the new ray marched graphics. I discuss the drawbacks of rasterization and the importance of two attributes in voxel engines: per-voxel col...
How I tripled the render distance in my game engine [Voxel Devlog #16]
Переглядів 35 тис.4 місяці тому
Try CodeCrafters for free today: app.codecrafters.io/join?via=DouglasDwyer Online demo: github.com/DouglasDwyer/octo-release How do games render such vast swaths of the world? This video showcases the level-of-detail (LOD) system that I implemented in my voxel engine. The LOD system ensures that far-away objects are rendered using simplified meshes, allowing the graphics card to quickly churn t...
Adding ambient occlusion to my game engine [Voxel Devlog #15]
Переглядів 20 тис.5 місяців тому
Try CodeCrafters for free today: app.codecrafters.io/join?via=DouglasDwyer Online demo: github.com/DouglasDwyer/octo-release In this devlog, I talk about the journey of adding ambient occlusion to my voxel programming project. Ambient occlusion is a lighting effect which darkens the corners and crevices of objects to mimic real life. I review the existing approaches to AO and go over my attempt...
INSANE bug in my code from compiler optimization
Переглядів 17 тис.5 місяців тому
For this quick video, I explain an oversight in my code, and how it caused undefined behavior. The bug provides an excellent case study for how compiler optimizations work, and why relying on unsoundness is bad in practice! Music used in the video: Corbyn Kites - Dusk Drive Corbyn Kites - Birds
GORGEOUS, speedy terrain generation [Voxel Devlog #14]
Переглядів 10 тис.5 місяців тому
Try CodeCrafters for free today: app.codecrafters.io/join?via=DouglasDwyer Online demo: github.com/DouglasDwyer/octo-release During this devlog, I unveil my techniques for customizable, optimized voxel terrain generation. I discuss how it is accelerated using the GPU, describe how interval arithmetic is leveraged to predict when regions of the world are homogenous, and touch upon how to apply i...
How to code PONG w/ Rust and Geese
Переглядів 2 тис.8 місяців тому
This video provides a tutorial on using the Geese event framework to build Rust projects of any scale! Geese is an event system library that allows one to compose actors by building a dependency graph. We cover the common ways that Geese is used, including: • Creating a context • Raising events • Defining event systems • Listening for events • Declaring and accessing system dependencies Music u...
OPTIMIZING my physics engine [Voxel Devlog #13]
Переглядів 24 тис.9 місяців тому
Online demo: github.com/DouglasDwyer/octo-release In this video, I put the finishing touches on my physics system! I highlight the various performance improvements that I've made - including object despawning, object sleeping, and multithreading - and discuss their implementation. I also offer my thoughts on game engine architecture, and ask for your feedback. I worked harder than ever to creat...
Chopping trees DOWN [Voxel Devlog #12]
Переглядів 18 тис.11 місяців тому
Online demo: github.com/DouglasDwyer/octo-release During this devlog, I recount the trials and tribulations of physics coding. I explain how to tackle big problems in small steps by analyzing how a tree falls in my engine. This involves two parts: a depth-first connectivity search which works especially well on voxel octrees, and some rotational dynamics equations that took me weeks to perfect....
Making voxels MOVE with the separating axis test [Voxel Devlog #11]
Переглядів 14 тис.Рік тому
Online demo: github.com/DouglasDwyer/octo-release Geese event system: github.com/DouglasDwyer/geese In this devlog, I go through some of the tough decisions that I made regarding my voxel engine. I talk about the separating axis theorem, and how I leverage linearity to use it efficiently in voxel-versus-voxel collision detection. In addition, I showcase transparent voxels rendered using weighte...
Adding SNOW and MODEL IMPORTS [Voxel Devlog #10]
Переглядів 7 тис.Рік тому
Online demo: github.com/DouglasDwyer/octo-release Geese event system: github.com/DouglasDwyer/geese In this video, I demonstrate the typical development process for my voxel engine, and showcase the many improvements and new features! Specifically, I added interactive snow, voxel model imports, a titlescreen, cascaded shadows, a settings menu, and many bugfixes this month. The voxel model impor...
Codebase OVERHAUL, new EVENT SYSTEM, LODs, and MORE [Voxel Devlog #9]
Переглядів 9 тис.Рік тому
Online demo: github.com/DouglasDwyer/octo-release Geese event system: github.com/DouglasDwyer/geese This video details the voxel engine rewrite that I undertook over the past month. After overhauling my event system, I restructured the totality of my Rust codebase in order to achieve better modularity, extensibility, and performance. Along the way, I made myriad improvements to the codebase. No...
GPU-generated DISTANCE FIELDS [Voxel Devlog #8]
Переглядів 19 тис.Рік тому
Please check out the online demo: octoproject.tk/ In this video, I talk about my exploration into the use of dynamically-generated distance fields to accelerate voxel rendering. I provide a brief overview of how ray marching against a distance field is performed, and present some approaches to distance field generation from voxel volumes. Then, I talk about how the GPU rasterizer may be utilize...
The PERFECT voxel rendering pipeline (and online demo) [Voxel Devlog #7]
Переглядів 71 тис.Рік тому
Please check out the online demo: douglasdwyer.github.io/octo-release/ In this devlog, I describe how I moved my engine from a limited proof-of-concept to a fully-scalable piece of software. Specifically, I highlight the custom GPU memory allocator used for storing voxels, the algorithms used to convert voxel octrees to GPU data, and the culling techniques employed to draw even more objects ons...
Designing a FLEXIBLE game engine with Rust [Voxel Devlog #6]
Переглядів 7 тис.Рік тому
Designing a FLEXIBLE game engine with Rust [Voxel Devlog #6]
Adding MULTIPLAYER NETWORKING with WebRTC to my game engine [Voxel Devlog #5]
Переглядів 7 тис.Рік тому
Adding MULTIPLAYER NETWORKING with WebRTC to my game engine [Voxel Devlog #5]
Drawing MILLIONS of voxels on an integrated GPU with parallax ray marching [Voxel Devlog #4]
Переглядів 29 тис.2 роки тому
Drawing MILLIONS of voxels on an integrated GPU with parallax ray marching [Voxel Devlog #4]
Sparse voxel octree modification and benchmarking [Voxel Devlog #3]
Переглядів 10 тис.2 роки тому
Sparse voxel octree modification and benchmarking [Voxel Devlog #3]
Textures, lighting, and MUCH faster rendering [Voxel Devlog #2]
Переглядів 9 тис.2 роки тому
Textures, lighting, and MUCH faster rendering [Voxel Devlog #2]
Implementing sparse voxel octrees and the ray caster [Voxel Devlog #1]
Переглядів 23 тис.2 роки тому
Implementing sparse voxel octrees and the ray caster [Voxel Devlog #1]

КОМЕНТАРІ

  • @Irowned
    @Irowned День тому

    10:41 looks like when google street view doesn't load properly.

  • @GamerSaga
    @GamerSaga День тому

    what is the size of each voxel block in terms of pixels? and is each block one color?

  • @alaskandonut
    @alaskandonut 2 дні тому

    Very cool dude!

  • @seth111yta1
    @seth111yta1 2 дні тому

    As voxel engines advance and relative voxel size shrinks, is there an advantage to just rendering voxels as a point cloud with like face-camera colored squares or something? great work BTW and thank you for actually making browser demos

  • @olliveraira6122
    @olliveraira6122 4 дні тому

    12:50 How are you getting a rust function like that to execute on the GPU? Do you do all your GPU programming like this, or do you mix in some HLSL/GLSL?

    • @DouglasDwyer
      @DouglasDwyer 4 дні тому

      I think you may have the incorrect timestamp, but I use WebGPU as my graphics API and WGSL as my shading language. It may look a little similar to Rust, but it's separate :)

    • @olliveraira6122
      @olliveraira6122 3 дні тому

      @@DouglasDwyer oooo okay, never heard about GWSL before :) Timestamp was supposed to be 11:50

  • @slent2410
    @slent2410 6 днів тому

    So do you play on releasing this to the public once its completed or in a useable state?

    • @DouglasDwyer
      @DouglasDwyer 4 дні тому

      There's already a demo playable online! But yes, I hope to turn this into an actual game someday.

  • @reachmehere2194
    @reachmehere2194 10 днів тому

    8:56 so I’ve got a question, it’s my understanding that the bit mask stores whether or not something is there. How do you tell it “what” is there rather than just “something”? This is the part that I’ve been struggling in my own journey, is encoding the “what” along with the “where” because either are easy on their own. My initial guess was maybe you have a mask for each type of material?

    • @DouglasDwyer
      @DouglasDwyer 10 днів тому

      In my engine, each voxel is represented by a 32-bit integer. The 32-bit integers are stored in memory directly after the bitmask. The bitmask is used for ray traversal and compression.

  • @willvarlakov5436
    @willvarlakov5436 11 днів тому

    this is awesome bro it looks very interesting evokes nostalgic feelings for old childhood games

  • @victorwidell9751
    @victorwidell9751 13 днів тому

    The low resolution pre rendering pass was interesting. Would it help to do it multiple times? I imagine it could be done with each level of an octree.

  • @guigazalu
    @guigazalu 13 днів тому

    When resizing the screen, use something like ICBI / FCBI to upscale the image and get a almost high quality result!

  • @navarrejonathan4193
    @navarrejonathan4193 14 днів тому

    So you edit the lods when rendering ? I'm afraid it might cause lag spikes. If the player builds a whole city, and then teleports away to look at it from a distance, the engine will have to calculate all the changes at once. Instead, you could have your engine calculate the changes to lods while editing. It unfortunately means some changes will go back and forth (player unhappy with the result -> destroy their build and make something slightly different...), but the work of the engine will be smoothed over the time it takes to the player to edit, which should be long enough, right ? Also, if a specific lod receives no change, lower resolution lods don't either, I guess ?

    • @DouglasDwyer
      @DouglasDwyer 14 днів тому

      Not quite. The LODs are recalculated on the server thread (which is not tied to the game's framerate) when the client requests changed LODs, and the work is spread over the course of multiple server ticks. As such, there is no lag!

  • @adricklynn8882
    @adricklynn8882 15 днів тому

    Amazing work! Can't wait to see more

  • @ZYZZinVR
    @ZYZZinVR 17 днів тому

    just started my data structure/algorithms course and seeing why the efficiency can be so important even on personal projects is motivating

  • @yiwmsh4393
    @yiwmsh4393 19 днів тому

    The mountain top looks so distant to me, down here at the start of the trail, so I'm very thankful you're posting the pictures you took up there.

  • @Flobbled
    @Flobbled 19 днів тому

    Really cool stuff! The second optimization was genius!

  • @stevegta6830
    @stevegta6830 20 днів тому

    I've always loved voxel engine graphics. Great work on this :)

  • @Sovereing2027
    @Sovereing2027 21 день тому

    GJ

  • @platinumsun4632
    @platinumsun4632 22 дні тому

    Dude I really love the beam optimization. Looks so cool. Like out of an old 2.5d game.

  • @CSPciccionsstibilepippons
    @CSPciccionsstibilepippons 23 дні тому

    I tried the native demo today: with my Ryzen 3500u integrated GPU it runs at around 50 ms with default settings, but with 2x downscale it runs under 20 ms even with maximum lod bias and I can't even notice the difference in resolution 🎉🎉🎉

  • @detesla9575
    @detesla9575 25 днів тому

    On your style of talking in this video, you remind me of that Rabbi in Seinfeld who councils Elaine

  • @RyDawgE
    @RyDawgE 25 днів тому

    This is AWESOME!!!! Very inspirational

  • @MyKaosLife
    @MyKaosLife 26 днів тому

    Love this! I saw some other comments on further ways to optimize traversal & memory usage, but from now on the common term for the 4^3-tree models should obviously be the THC-tree model 😄

  • @bartomiejtudryk5649
    @bartomiejtudryk5649 27 днів тому

    gpu memory is slow? wtf are you talking about it may be slow to access from cpu, but not from gpu itself

  • @INT41O
    @INT41O 27 днів тому

    Do you upload the entire scene to the GPU memory at once? What if that does not fit, do you use any compression or out-of-core techniques?

    • @DouglasDwyer
      @DouglasDwyer 27 днів тому

      As described in the bricktree section of the video, I use a sparse data structure and only the surface voxels are uploaded to the GPU. Further, the world is infinite and broken into chunks, so only the chunks around the player are loaded into memory. Right now, the chunk radius is just a user setting, but maybe I can lower it automatically if memory runs out :)

  • @SpicyMelonYT
    @SpicyMelonYT 27 днів тому

    WEED MARCHING omg LOLOL

  • @WlliamBrown
    @WlliamBrown 27 днів тому

    This looks really awesome! I stumbled across your videos yesterday, and have viewed most of them. I have also been researching voxels with marching cubes, but it destroys precise environment manipulation. Have you considered applying marching cubes only within each of your 8x8x8 voxels?

    • @DouglasDwyer
      @DouglasDwyer 27 днів тому

      Thanks for watching! I prefer the look of smooth cubic voxels, so I'm not planning to integrate marching cubes at this time (it would also make ray traversal more complicated)

  • @deRNmEpRrMm
    @deRNmEpRrMm 28 днів тому

    Please stop using ray tracing and ray marching interchangeably.

  • @c0pi
    @c0pi 28 днів тому

    I recognize the place of the demo!! I had a pizza in that place. Nice!

  • @PhenixArcher
    @PhenixArcher 28 днів тому

    now we just need the leaves to crush

  • @trashman1358
    @trashman1358 29 днів тому

    First time I've come across your channel. I've always felt voxels are like a computer making graphics like (checks notes) a Post-Impressionist oil painter. The church and village at the end of the vid? Both facinate and excite my brain for reasons I simply can't fathom. Love, love, love voxels and if that's your engine? You've absolutely cracked it visual wise. Subscribed.

  • @Z_Z.t
    @Z_Z.t 29 днів тому

    10:48 isnt using simple rasterization with depth gonna give better depth values? (im aware about greed meshing)

  • @Z_Z.t
    @Z_Z.t 29 днів тому

    for DDA in different sized pow2 boxes just replace multiplication with bit shifts and integer arithmetics

  • @maxhascamera
    @maxhascamera 29 днів тому

    ua-cam.com/video/5vKyIioQAME/v-deo.html This guy made a binary voxel mesher

  • @NyanCoder
    @NyanCoder 29 днів тому

    Wow, that "low resolution" looks very interesting IMO. Idk why, but it reminds me ps1, and it's fascinating that it's all voxels. I think there would be a lot of cases of making use a such style. And it's true pixel-art (without shifting and rotating pixels)

  • @AndrewTSq
    @AndrewTSq 29 днів тому

    that looks amazing!

  • @Wizarth
    @Wizarth Місяць тому

    You mention that you ensure the beams never go far enough into the geometry hierarchy to miss a voxel that is smaller than the grid/pixel size. Do you adjust the depth based on distance from camera? I.E. does it go deeper into the hierarchy when closer to the camera?

    • @DouglasDwyer
      @DouglasDwyer 29 днів тому

      Yes, that's correct. The maximum distance that a ray can travel depends upon the size of the voxel (i.e. hierarchy depth) and the distance between adjacent rays. Adjacent rays "spread out" as they progress with a perspective camera, so that needs to be accounted for.

  • @0memega
    @0memega Місяць тому

    Before this, I didn't know you could even use DDA for raytracing. As I only used it for raycasting. Amazing video.

  • @Deniil2000
    @Deniil2000 Місяць тому

    you mentioned u32 and u64 in your video. are you writing this in Rust?

    • @DouglasDwyer
      @DouglasDwyer Місяць тому

      The project is written entirely in Rust and uses WebGPU as the graphics API.

  • @steluste
    @steluste Місяць тому

    Are you using any engine/framework such as Monogame or it's all from scratch? Also do you have a public repository of the project?

    • @DouglasDwyer
      @DouglasDwyer Місяць тому

      The project is written entirely from scratch in Rust and uses WebGPU as the graphics API. The project is not open-source at present, but many components of it (like the event system are networking system) are open-source on my GitHub!

  • @owendavies8227
    @owendavies8227 Місяць тому

    Wow, the beam optimization is absolutely genius.

  • @owendavies8227
    @owendavies8227 Місяць тому

    I guess for preserving DDA calculations between scales, if you're just going up or down a single level, the numbers would be 4 times greater or less with no other changes, and that could be performed just with bitshifting and nothing else, which would be pretty fast.

    • @owendavies8227
      @owendavies8227 Місяць тому

      I guess you could keep track of how many levels you are stepping between and do a bitshift of double the number of difference in levels of hierarchy, but it would probably be more computationally efficient just to do a double bitshift each time so you don't have to keep track of anything.

    • @DouglasDwyer
      @DouglasDwyer Місяць тому

      Unfortunately, I don't quite think that this works. With DDA, you store the distance along the ray to each plane of the current voxel. But if you move up/down tree levels, the planes may shift by non-uniform amounts. There are perhaps ways to update the plane positions based upon the initial and final voxel, but I don't know of any that are more efficient than just reinitializing DDA from scratch (which is equivalent to a ray-box intersection test).

    • @owendavies8227
      @owendavies8227 Місяць тому

      @@DouglasDwyer I am willing to believe I made some kind of mistake.

    • @owendavies8227
      @owendavies8227 25 днів тому

      ​@@DouglasDwyer I don't know if this would necessarily be faster, but you could, if nothing else, theoretically update the plane positions in linear time. If the axes are aligned to the voxel grid (which could be done with a matrix multiplication for the camera and ray just once in the beginning), it would mostly just be addition, subtraction and bitshifts to move the planes around.

  • @MatejVancoCG
    @MatejVancoCG Місяць тому

    Really cool. Thanks for such detailed explanation!

  • @A-200_Happy_Scribble
    @A-200_Happy_Scribble Місяць тому

    Teardown

  • @StylishHobo
    @StylishHobo Місяць тому

    Rather than your custom data structure. Have you considered using a k-d tree instead?

  • @paxcoder
    @paxcoder Місяць тому

    So down to 60ms? But it would have to be ⌊1000/60⌋ = 16ms to run at 60fps right?

    • @DouglasDwyer
      @DouglasDwyer Місяць тому

      Yep! As noted in the video, the benchmarks presented were on a very bad GPU (Intel UHD 750H). On any discrete card, the engine runs at a buttery-smooth 60 FPS - for example, the scenes in the video run at 4 ms (or 250 FPS) on my NVIDIA 1660 TI. It's possible to make the game run in realtime on the Intel GPU as well by lowering the resolution. But for benchmarking I wanted the frame times to be as big as possible, so I chose a worst case.

    • @paxcoder
      @paxcoder Місяць тому

      @@DouglasDwyer Too bad a discrete card is a requirement, as I'm afraid I only use integrated cards, but that is a whole lot of voxels there, so I guess it makes sense.

    • @DouglasDwyer
      @DouglasDwyer Місяць тому

      Discrete card is only a requirement for 1080p. If you play the game at a lower resolution, you can definitely hit 60 FPS on an iGPU. But don't take my word for it - try the demo and evaluate for yourself! There is an option in the settings menu to downscale the image resolution for better performance :)

    • @xezvcikgames1191
      @xezvcikgames1191 Місяць тому

      @@DouglasDwyer can you please show in pseudo-code how you do ensure low res wont step too far 11:06 ? i didnt quite get it, also what it would be like to trace more coarse lods in pre-pass, for example on CPU side? still could avoid a lot of traversal iterations. How do you even make sure its done in conservative manner? wont it require supercover dda or smth, hard to imagine tbh

  • @bcmpinc
    @bcmpinc Місяць тому

    About a decade ago I wrote a CPU based Voxel renderer using some algorithm that sort of combines the beam and DDA optimization. I managed to squeeze out an average of 10fps at 1024x768 on a single CPU core. I failed to port it to GPU only because that required some sorting which I could not implement efficiently using the glsl compute shader I was using and the GPU's at that time. If you're interested, my bcmpinc voxel-engine wordpress blog still exists. Feel free to contact me if you have questions.

    • @DouglasDwyer
      @DouglasDwyer Місяць тому

      Thanks for sharing - your blog looks like a great resource!

  • @phylliida
    @phylliida Місяць тому

    Ur videos are so good!! Always excited to see another one

  • @hexadeque1101
    @hexadeque1101 Місяць тому

    Here is my DDA on an octree implementation if it is helpful: I have basically a stack data structure holding the current node I'm looking at and its parents so that I can walk up the tree. The stack is initialized to just hold the root octree node. At the beginning of each DDA step in the loop, the current position (rayOrigin + rayDirection*distance) is guaranteed to be within the current octree node on the top of the stack, but the current node is not guaranteed to be a leaf node (the current position is inside one of its children). while (rayDepth < RENDER_DISTANCE) { Get the bottom most node containing the current position (the current node is now guaranteed to be a leaf node containing the current position) Check if the current node is a filled voxel. If so, the ray hit something Step the ray with DDA (the current position is no longer within the bounds of the current node) Walk up the nodes in the stack until the current position is within bounds of the current node (sets up for the first part of the loop for the next iteration) } Hopefully that made sense. If not, my actual code is in the replies.

    • @hexadeque1101
      @hexadeque1101 Місяць тому

      struct OctreeNode { uint data; // Basically an enum using the following constants uint[8] children; }; // Different materials are not implemented yet so full and empty are the only two states a voxel can be const uint EMPTY = 0; const uint FULL = 1; const uint PARTIAL = 2; // For parent nodes who have some full (or partial) children and some empty children struct Ray { bool hit; uvec3 position; ivec3 normal; float depth; }; layout(std430, binding = 1) buffer World { OctreeNode world[]; }; ... Ray castRay(vec3 rayOrigin, vec3 rayDirection) { ... // Ray box intersection on the size of the octree in case the ray starts outside the octree is omitted ray.position = uvec3(floor(rayOrigin)); ray.depth = 0; vec3 stepSize = vec3( sqrt(1 + (rayDirection.y*rayDirection.y + rayDirection.z*rayDirection.z) / (rayDirection.x*rayDirection.x)), sqrt(1 + (rayDirection.x*rayDirection.x + rayDirection.z*rayDirection.z) / (rayDirection.y*rayDirection.y)), sqrt(1 + (rayDirection.x*rayDirection.x + rayDirection.y*rayDirection.y) / (rayDirection.z*rayDirection.z)) ); ivec3 direction = ivec3(sign(rayDirection)); vec3 rayLength = mix(rayOrigin - ray.position, 1 - rayOrigin + ray.position, step(0.0, rayDirection)) * stepSize; // The stack is stored as an array indexed by currentLevel which is incremented every time we descend down the octree // It stores uints which are indices into the world array uint nodes[OCTREE_LEVELS + 1]; uint currentLevel = OCTREE_LEVELS; // Level 0 is an individual voxel nodes[currentLevel] = 0; // Root node is always index 0 uvec3 currentNodePosition = uvec3(0); while (ray.depth < RENDER_DISTANCE) { while (world[nodes[currentLevel]].data == PARTIAL) { currentLevel--; uint voxelWidth = uint(pow(2, currentLevel)); uvec3 center = currentNodePosition + uvec3(voxelWidth); uvec3 subnode = uvec3(greaterThanEqual(ray.position, center)); currentNodePosition += subnode * voxelWidth; nodes[currentLevel] = world[nodes[currentLevel + 1]].children[subnode.x + subnode.y * 2 + subnode.z * 4]; } if (world[nodes[currentLevel]].data == FULL) { ray.hit = true; return ray; } // DDA step + store hit info for if we hit something // Possible optimization: instead of taking one unit long steps, take steps proportional to the size of the current node. i.e. if the current node is empty and 4 voxels wide, step 4x the distance. I could not get that working at the moment, though, as it brings extra complications. :/ if (rayLength.x < rayLength.y && rayLength.x < rayLength.z) { ray.position.x += direction.x; ray.depth = rayLength.x; rayLength.x += stepSize.x; ray.normal = ivec3(1.0, 0.0, 0.0) * -ivec3(sign(rayDirection)); } else if (rayLength.y < rayLength.z) { ray.position.y += direction.y; ray.depth = rayLength.y; rayLength.y += stepSize.y; ray.normal = ivec3(0.0, 1.0, 0.0) * -ivec3(sign(rayDirection)); } else { ray.position.z += direction.z; ray.depth = rayLength.z; rayLength.z += stepSize.z; ray.normal = ivec3(0.0, 0.0, 1.0) * -ivec3(sign(rayDirection)); } // Bounds check if (ray.position.x < 0 || ray.position.y < 0 || ray.position.z < 0 || ray.position.x >= worldSize || ray.position.y >= worldSize || ray.position.z >= worldSize) { return ray; } // I was lazy and went all the way up to the root node every time and left only going up as far as necessary for "later" currentLevel = OCTREE_LEVELS; nodes[currentLevel] = 0; currentNodePosition = uvec3(0); } return ray; }

  • @R.Daneel
    @R.Daneel Місяць тому

    Wow. UA-cam compression isn't doing your grey background any favours! I can't tell from the video. Have to fallen down the SIMD rabbit-hole yet?

  • @amaryllis0
    @amaryllis0 Місяць тому

    Game looks great, i gotta second that the rotating backgrounds make me feel nauseous tho