<div dir="ltr"><div><div><div><div><div><div>Hi Brecht,<br><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>The other part is how you map from the big grid to 
the tiles. The simplest solution is to use a two level grid, and that's 
what I suggest to do. To get an idea, this is how such a data structure 
and associated lookup function would work:</div><div><a href="https://developer.blender.org/P692" target="_blank">https://developer.blender.org/<wbr>P692</a></div></blockquote><br></div>Thanks for the advice to use a double pointer for the grid! The only solution I could think of to keep track of active tile coordinates was to use map, which yes, is painfully inefficient.<br><br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">RNA is not the right place to convert a dense grid to a sparse grid, it's going to be more complicated than it needs to be.<br></blockquote><br></div>You're right, after some more reading, it seems like the best place to insert the conversion should be somewhere in <i>render/image.cpp</i>. The declaration of the grid should be something like:<br><br></div><div>// <i>in ImageManager::device_load_image()<br></i></div><div>else if(/* type of image is volume */) {<br>    device_vector<VolumeTile*> *tex_img = new device_vector<VolumeTile*>(...);<br>    if(!file_load_image<TypeDesc::FLOAT, VolumeTile>(img, type, texture_limit, *tex_img)) { /* ... */ }<br>    // ...<br>}<br><br></div><div>Since <i>ImageManager</i> only stores images as <i>device_memory</i>, <i>device_vector<VolumeTile*></i> can act as the VolumeGrid class from your example while also being compatible with ImageManager. This also minimizes the amount of dedicated code needed. I will then write some helper functions for it e.g. init, iteration, lookup. Memory handling in theory should already be handled by the existing class in so I do not think I will need to make any modifications to <i>device/device_memory.h</i>.<br></div><br></div>For loading in particular, <i>ImageManager::file_load_image</i> in <i>render/image.cpp</i> will need to be significantly modified to load the volume into the device vector, and the conversion function inserted here somwhere after the image is loaded. I have begun to make edits and I have some more questions about this function (is this the right place to ask?)<br><br></div>1. What are components? Do volumes ever have >4 components? (since there is more processing if components > 4)<br></div>2. In the function, after the image is loaded, there seems to be a lot of pixel value changing, e.g.<br>            for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {<br>                pixels[i*4+2] = (pixels[i*4+2]*pixels[i*4+3])/255;<br>                pixels[i*4+1] = (pixels[i*4+1]*pixels[i*4+3])/255;<br>                pixels[i*4+0] = (pixels[i*4+0]*pixels[i*4+3])/255;<br>                pixels[i*4+3] = alpha_one;<br>            }<br><div><div>but the kind of changing is conditional on the components? What is the purpose of this part of the code? (in the latest master commit, this code is in lines 576-651 of <i>render/image.cpp</i>)<br></div><div><br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="background-color:rgb(255,255,255);text-align:start;text-indent:0px;text-decoration-style:initial;text-decoration-color:initial"><font face="monospace, monospace">kernel/kernels/cpu/kernel_cpu_<wbr>image.h<br></font></div><div style="background-color:rgb(255,255,255);text-align:start;text-indent:0px;text-decoration-style:initial;text-decoration-color:initial"><font face="monospace, monospace">kernel/kernels/cuda/kernel_cud<wbr>a_image.h<br></font></div><div style="background-color:rgb(255,255,255);text-align:start;text-indent:0px;text-decoration-style:initial;text-decoration-color:initial"><font face="monospace, monospace">kernel/kernels/opencl/kernel_o<wbr>pencl_image.h</font></div><div><br>Lukas or I can help you figure out a design for the data structures, 
since the whole GPU and device memory aspect is rather complicated. We 
can start with a CPU implementation first but it should be along the 
right direction. </div></blockquote><br><div>I will also have a look at these after image loading is functional. Thanks for the tip! Unfortunately, I am not familiar with GPU programming. Generally, what differences will need to be handled? I had heard that GPUs are not very good at handling pointers and double precision arithmetic. So do you think using <i>device_vector<VolumeTile*></i> rather than a dedicated class is alright?<br><br></div><div>I have some code written but generally I don't like to make commits unless there is a whole feature fully implemented, I am too obsessed with clean git histories :P . Would everyone rather I make commits of incomplete code to show progress, or would it be alright for me to only commit once a feature is mostly complete and functional?<br></div><div><br></div><div>Best regards,<br></div><div>Geraldine<br></div><div><div><div><div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, May 21, 2018 at 8:23 AM, Brecht Van Lommel <span dir="ltr"><<a href="mailto:brechtvanlommel@gmail.com" target="_blank">brechtvanlommel@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><span class="gmail-"><div class="gmail_quote">On Sun, May 20, 2018 at 7:11 PM, Geraldine Chua <span dir="ltr"><<a href="mailto:chua.gsk@gmail.com" target="_blank">chua.gsk@gmail.com</a>></span> wrote:<br></div></span><div class="gmail_quote"><span class="gmail-"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><div># Texture saving and loading<br><br>For the most part, it seems like hashtables are the most efficient way to store sparse data sets. In order to optimize volume texture storage, I traced the top-most relevant code to `ImageManager::file_load_image<wbr>` in `render/image.cpp`. It appears that smoke data specifically is retrieved through the custom functions in `~/blender/makesrna/intern/rna<wbr>_smoke.c` rather than using OIIO. Thus, I can implement here a simple conversion of the volume grid into a map of <coordinates, voxel value> pairs. All parent functions will also need to be modified to be compatible with a map object instead of a vector/array.<br></div></div></div></blockquote><div><br></div></span><div><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><coordinates, voxel value> pairs are not an efficient way to store and sample sparse volume data. If you have just a float (or half float) density grid the coordinates can take up 3x more space than the voxel values. Further hash tables will cause cache misses which is not good for rendering performance.</span></div><div><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><br></span></div><div>The intention for the GSoC project was to use sparse 3D tiles, which are also used in OpenVDB and most other volume rendering or simulation software. What you do is split up the big 3D grid into smaller tiles of 8x8x8 voxels. If a tile contains no data its voxel values are not stored. The code in mesh_volume.c already detects empty 8x8x8 tiles for creating bounds, so some of that code can perhaps be reused.</div><div><br></div><div>The other part is how you map from the big grid to the tiles. The simplest solution is to use a two level grid, and that's what I suggest to do. To get an idea, this is how such a data structure and associated lookup function would work:</div><div><a href="https://developer.blender.org/P692" target="_blank">https://developer.blender.org/<wbr>P692</a><br></div><div><br></div>In practice it will be a bit different to make it work well for GPUs.<span class="gmail-"><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><div># To-do next week<br><br>* Modify the `rna_SmokeModifier_*_grid_get` functions to optionally recieve a thresholding value and return an array of coordinates + values of all active voxels.<br>* Modify callers of `rna_SmokeModifier_*_grid_get` to properly interpret and manipulate the new array type.<br></div></div></div></blockquote><div><br></div></span><div><div style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial">RNA is not the right place to convert a dense grid to a sparse grid, it's going to be more complicated than it needs to be. It will be good if Blender itself supports sparse grids in the future, but when it does there will be no need for thresholding in RNA, rather it would be exposing existing tiled data.</div></div><div style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial"><br></div><div style="text-decoration-style:initial;text-decoration-color:initial"><div style="background-color:rgb(255,255,255);color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-transform:none;white-space:normal;word-spacing:0px;text-align:start;text-indent:0px;text-decoration-style:initial;text-decoration-color:initial">Most of the work for Cycles is supporting tiled 3D image storage and sampling. That means changing mostly the following files :</div><div style="background-color:rgb(255,255,255);color:rgb(34,34,34);font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-transform:none;white-space:normal;word-spacing:0px;text-align:start;text-indent:0px;text-decoration-style:initial;text-decoration-color:initial"><font face="monospace, monospace">render/image.cpp</font></div><div style="background-color:rgb(255,255,255);color:rgb(34,34,34);font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-transform:none;white-space:normal;word-spacing:0px;text-align:start;text-indent:0px;text-decoration-style:initial;text-decoration-color:initial"><font face="monospace, monospace">render/image.h</font></div><div style="background-color:rgb(255,255,255);color:rgb(34,34,34);font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-transform:none;white-space:normal;word-spacing:0px;text-align:start;text-indent:0px;text-decoration-style:initial;text-decoration-color:initial"><font face="monospace, monospace">device/device_memory.h</font></div><div style="background-color:rgb(255,255,255);text-align:start;text-indent:0px;text-decoration-style:initial;text-decoration-color:initial"><font face="monospace, monospace">kernel/kernels/cpu/kernel_cpu_<wbr>image.h<br></font></div><div style="background-color:rgb(255,255,255);text-align:start;text-indent:0px;text-decoration-style:initial;text-decoration-color:initial"><font face="monospace, monospace">kernel/kernels/cuda/kernel_cud<wbr>a_image.h<br></font></div><div style="background-color:rgb(255,255,255);text-align:start;text-indent:0px;text-decoration-style:initial;text-decoration-color:initial"><font face="monospace, monospace">kernel/kernels/opencl/kernel_o<wbr>pencl_image.h</font></div><div style="background-color:rgb(255,255,255);text-align:start;text-indent:0px;text-decoration-style:initial;text-decoration-color:initial"><font face="monospace, monospace"><br></font></div>Lukas or I can help you figure out a design for the data structures, since the whole GPU and device memory aspect is rather complicated. We can start with a CPU implementation first but it should be along the right direction.</div><span class="gmail-"><div style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial"> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><div>* Create a git branch for code changes.<br>* Make comparison tests on memory performance.<br>* If have time, move on to importing OpenVDB files. <br></div></div></div></blockquote><div><br></div></span><div>You can do either OpenVDB import first, or do tiled 3D images first, but both will take at least some weeks to finish fully.</div><div><br></div></div></div></div>
<br>-- <br>
Soc-2018-dev mailing list<br>
<a href="mailto:Soc-2018-dev@blender.org">Soc-2018-dev@blender.org</a><br>
<a href="https://lists.blender.org/mailman/listinfo/soc-2018-dev" rel="noreferrer" target="_blank">https://lists.blender.org/<wbr>mailman/listinfo/soc-2018-dev</a><br>
<br></blockquote></div><br></div></div></div></div></div></div></div></div>