...and generate a tile index that we can use to access our array of per-tile data.pic.twitter.com/RVDdmhh3R1
আপনি আপনার টুইটগুলিতে ওয়েব থেকে এবং তৃতীয়-পক্ষ অ্যাপ্লিকেশনগুলির মাধ্যমে অবস্থান তথ্য যেমন শহর বা সুনির্দিষ্ট অবস্থান যোগ করতে পারবেন। আপনার কাছে আপনার টুইটের অবস্থান ইতিহাস মোছার বিকল্প থাকবে। আরও জানুন
...and generate a tile index that we can use to access our array of per-tile data.pic.twitter.com/RVDdmhh3R1
It fits in a tweet! uint GetFragmentTileIndex() { vec2 v = floor(gl_FragCoord.xy / 32.0); return uint(v.y * 40.0 + v.x); }
The 40.0 is hardcoded for 1280x720, so it needs to be changed to either a uniform load, or a SPIRV specialization constant.
Next step is to load per-tile data. In this case just a random color I generate on the CPU side.pic.twitter.com/EAujuArfDZ
Article on Doom's renderer has nice pictures explaining how their clustered data structure works. (tiled in my case)http://www.adriancourreges.com/blog/2016/09/09/doom-2016-graphics-study/ …
This whole renderer is just under 10k lines of Vulkan code, so I'm starting to clean it up a bit.
It's super copy-pasty, but the repetition has really helped me learn and memorize #Vulkan.
I don't know if I'd recommend learning like this (I also read the whole spec!), but for me Vulkan now seems really easy and straightforward.
Next step is to correctly iterate over the lights using the tile data structure. I harcoded a blue/red light for each tile, in a pattern.pic.twitter.com/sf41VodBJJ
Now all that's left to get this working is to do real light-tile intersection tests. Gotto grab some books for this.
Some random animated lights to test with. Turns out 200 lights added to all tiles -> 5fps on my RX460.pic.twitter.com/goZoV5Hj3T
We need a list of lights per tile, but we'll instead generate a list of tile intersections per light, then invert this data structure.
Each tile forms an asymmetric frustum that starts at the camera position, and is capped by the near and far camera planes.
Iterating over each light, we'll do a sphere-frustum intersection for every tile. Later on, we'll narrow down the potential tiles to test.
For a frustum intersection test, we need to generate the 4 side planes. (near and far planes are easy, and the same for all tiles)
Fortunately this is easy. We know the corners of the tile on the screen, so putting those coordinates in clip space on the near plane,
then unprojecting with the inverse of the projection matrix gives us a point in camera space.
For each edge of the tile, plus the camera position (0 in camera space) we now have 3 points to generate the corresponding plane equation.
Ooops. I guess writing 3 pages of loops somehow didn't result in code that works on the first try.pic.twitter.com/suVS0fQlQT
Lucky I have a draw line feature handy to help me visualize the problem. Those tiles don't look right!pic.twitter.com/N3sFzENkTR
So it turns out that _mm_rcp_ss isn't all that precise :[
One _mm_rcp_ss in the matrix inverse code was introducing like 10% error! Holy shit there goes 3 hours of debugging :(
The tile should be in the bottom left corner of the screen. First image uses normal divide, 2nd image uses _mm_rcp_ss.pic.twitter.com/2aMcjl4WQU
I can't believe how much error there is! Anyway, moving on.
Woo, it seems to work! Tomorrow: more testing, debug visualize number of lights per tile, and explaining the algorithm.pic.twitter.com/zN2NYZuccq
Everything seems to work! Visualizing number of lights per tile:pic.twitter.com/vI0oH4Ibu6
Easy to spot mistakes when you can visualize the data. The tiles marked X should definitely not include that light.pic.twitter.com/JvEGLb53iT
This isn't a bug though, just a limitation of this culling algorithm giving false positives.
Since mobile GPU cycles are a scarce resource, I definitely want the best possible culling.
Implemented tighter culling by testing the sphere against the edges of the frustum.pic.twitter.com/Le6iigj4Na
টুইটার তার ক্ষমতার বাইরে চলে গেছে বা কোনো সাময়িক সমস্যার সম্মুখীন হয়েছে আবার চেষ্টা করুন বা আরও তথ্যের জন্য টুইটারের স্থিতি দেখুন।