Hi guys,
I am looking forward to make a OSL that would allow to visualize fields as paraview would do such as this :
I am going to start with extruded meshes (3D) (X Y Z values of cells are identical on each line/row…). The OSL i have done so far is this :
float get_color_value(float x, float y, float z)
{
float X_values[3] = {0 ,1 ,2};
float Y_values[3] = {0, 1, 2};
float Z_values[3] = {0, 1, 2};
float flux_value[27] = {0, 1, 2 .....};
int x_step = 0 ;
int y_step = 0 ;
int z_step = 0 ;
for(int i = 0; i < 41; i++){
if (x > X_values[i])
{
x_step = i ;
}
}
for(int i = 0; i < 41; i++){
if (z > Z_values[i])
{
z_step = i ;
}
}
float color_value = flux_value[z_step*2+x_step];
return color_value;
}
shader source_shader(
float x=0.,
float y=0.,
float z=0.,
int log_output = 1,
output float factor = 0.)
{
factor_value = get_color_value(x, y, z);
}
It works fine, but it from what i understand, it is building back the array « flux_value » at every call. It works fine for a 1k cells mesh, but is not optimal and wouldn’t work on a 1M cells array for example.
I have a few questions about that :
OSL are coded in C, right ?
Is that C environement created at every call, or could i store the array in a global variable there ?
Is there a way to read an array created in the python and stored in the bpy.types.Scene.variables ?
Can we make the OSL communicate with an external process which would do this array reading ?
Can Cycles store those value to pick them up when turning the view instead of recalculating the same points over and over ?
OSL is not directly C, the environment is… well it’s the shader for one pixel… executed whenever the shader units are ready to do so… on the GPU… so it doesn’t communicate very well… with anyprocess of the CPU… the complete shader (with data) is loaded in VRAM and the executed…
You may look for more info at the official Github page…
Since i was thinking about this the other day here is also somekind of further explanation (maybe not accurate or not furth enough ):
For any image processing someone will do some like:
for Y in 0 to YMAX
for X in 0 to XMAX
do_something_with(color(x,y))
rof
rof
In OSL the outer loop will be done “magically” and the processing units of the GPU are directly feed with:
do_something_with(color(x,y))
That’s for example the reason why blurring images isn’t that easy in shader languages. In the first example you can remember the neighbours by just adding some variable assignments and do the processing afterwards (well not sooo easy) but in the shaders languages you don’t know who the neighbours are… they are processed by a different GPU unit and because the all do it in parallel (well only if you have as much units as pixels but in groups of) it would cost you an immense overhead of interprocess communication… so you have to process those neigbours in this unit… so blurring cost much more in GPU-shaders as in CPU (but the GPU is faster so in the end…)
So almost an additional NO to you question…
(Doing interprocess communication on GPU with other computing languages especially using CUDA etc for exmplae for cry pto and chain bla bla or AI is something completely different… and i don’t know much about this )
I’m just starting looking into OSL, so take my answer with a grain of salt.
But first, are you sure you need OSL ? what about using Geometry node , or pure python ?
You can store colors as vertex colors on face, cubes, maybe even points and rendered as point cloud ( I’m pretty sure cycles can do that).
I don’t think OSL can read easily some array value stored in the scene but I’m just scratching the surface of what it can do.
Not sure to understand your question and the next one, OSL might be coded in C, but the language is OSL, that looks like C but isn’t.
Pretty sure it comes with it’s own compiler. Probably in the OSL documentation it’s written how to create global variables that aren’t initialised at each shader evaluation. But as said I’m not sure OSL is the best way to go for what you want to do, which is data visualization right ?
. the optimizations in OSL has resulted in CPU results that can in some instances exceed GPU.
in the sources there is blender/intern/cycles/kernel/osl/osl_shader.cpp (and more) and almost all shader nodes does have osl sources blender/intern/cycles/kernel/shaders/*.osl …
@Okidoki , you made quite clear the lack of communication between the OSL and its surrounding. Indeed it seems it is entirely CPU based. But that’s great for me, as it would only be used on machines that have good CPUs. That reference to the source code might actually help me considering what they do in shaderdata_to_shaderglobals, i will dig a bit into it to see if we can also access to that OSLThreadData *tdata thing.
@sozap , well i don’t know if i need OSL, i need it to work, i am opened to any way to achieve it in a performant way. I have only tried arrays so far and not geometry node, do you have much experience into it? Arrays don’t enjoy much having a 100100100 for a cube, i expect OSL to manage that better, i haven’t tried yet, i wanted to clear my fifth question before, so be sure of what i was doing. Do you think that geometry nodes can deal with that? (i need to be able to see through, so it would certainly be in volume shaders.
I think i don’t get your point… initially i forgot that OSL isn’t on GPU and though you want to use it (silly me)… additionally a search: data visualization by graphic shaders gives dozen of results and now you want to use CPU anyway… so why don’t just use the C-language ?? (or Matlab or … anything what is ) i mean you have to read you X,Y,Z data from a file anyway…
You maybe do overthinking this… ?? There are dozen of solutions to present data…
So just make a program to process your data in a convienent way to to a simple shader rendering … for example your min max value [-0.132,0.125] → ?? I do not see any specialities to cahnge some paramters fro the rendering yet (if you wanna make some interactive thingy)…
@Secrop Maybe indeed that would be cleaner than writing it directly
@Okidoki Yes i may be overthinking it. Indeed Paraview does the trick. But it would let see either the field and the geometry around if it worked. Display the fields would only be a feature of the package
It’s hard to really advice you because I don’t really get what you’re trying to achieve,
GN will allow you to generate the geometry, but you may get the same issue about reading values.
Indeed storing them in a texture as Secrop pointed out might be much more simple in both case.
Hum, you want to use a volume shader to handle a voxel grid ?
At least if that doesn’t work in OSL you might try generating a point cloud and assign colors to vertexs, needs testing but I’m pretty sure cycles can render that.