OIIO image reader plugin that runs OSL shaders to make the image dynamically#531
Conversation
I'm starting to imagine reasons for an app to have multiple "renderers" using different RendererServices subclasses. Each one should be allowed to hold a distinct TextureSystem, which it couldn't before. The only obvious way to do this is holding the pointer in the RS object itself.
|
Very cool! How many loose ends are left? Is it possible to access textures in these types of plugins (not to mention the possibility of having texture calls that invoke this loader recursively ...)? |
|
The one-day version was very rough -- read_scanline only (now it can do scanline, scanlines, tile, or tiles), the parameter parsing/setting was crude and could only handle simple int or float (now accepts types so you could set points, colors, arrays, strings, whatever), had no error handling and would crash if you specified things wrong (now is reasonably stable and will even bubble up most error messages properly), did not support the MIP=1 flag to make it look mipmapped. All the loose ends on my original list got tied up by the time I submitted the PR. You can access textures in these plugins, that seems to be fine. (But I urge you not to make a texture name that causes infinite recursion!) I think the only think I haven't tested, maybe I'll get to it today, is fully trying to make one of these special names for the renderer itself, and make sure that all works. |
|
LGTM |
OIIO (and any app that uses it to read images) not only can read many
image formats, but if it doesn't know a format internally, it will look
for a plug-in that can read the format. But it's just a black box, it
doesn't HAVE to actually read an image from disk. It could do something
procedural.
So... I wrote an OIIO image reading plugin that executes OSL code to
procedurally generate image pixels as needed. It can do some fun tricks.
Generate an image by running a compiled OSL shader:
shader ramp (
color topleft = color(0,0,0),
color topright = color(1,0,0),
color bottomleft = color(0,1,0),
color bottomright = color(1,1,1),
output color result = 0,
output float alpha = 1
)
{
result = topleft*(1-u)*(1-v) + topright*u*(1-v) +
bottomleft*(1-u)*v + bottomright*u*v;
}
$ oslc ramp.osl
$ oiiotool ramp.oso -o ramp.exr
You can generate directly into an iv window (or any other app that
uses OIIO to read):
iv ramp.oso
A ".oslgroup" file can contain the serialization of an entire shading
network:
oiiotool network.oslgroup -o complex.exr
URI notation can be used to set shader parameters:
oiiotool "fBm.oso?frequency=4&octaves=4&point offset=0,1,0" -o noise.exr
URI notation also to control the resolution of the "image", or to make
it look tiled rather than scanline, or even to make it behave like it's
MIP-mapped:
iv "fBm.oso?octaves=4?RES=512x512&MIP=1&TILE=64x64"
".oslbody" signifies a snipped of OSL that will be pasted into
OSL shader boilerplate, compiled from memory, and JITed on the fly:
iv "result = noise (u*5, v*5);.oslbody"
Not just a single expression, you could write a whole program if you
want:
iv "int octaves=8; float freq=2,amp=0.5; for (int i = 0; i < octaves; ++i, amp /=2, freq*=2)result += amp*(color)snoise(freq*u,freq*v); result += 0.5; .oslbody?RES=512x512"
Yeah, crazy.
|
Haha, tested this in our renderer and it DOES work! Though you do need to make it look mipped and tiled or the renderer is instructed to reject it as an error. Chris et al, alter test_0693/test.ass from to and it actually works! |
OIIO (and any app that uses it to read images) not only can read many image formats, but if it doesn't know a format internally, it will look for a plug-in that can read the format. But it's just a black box, it doesn't HAVE to actually read an image from disk. It could do something procedural.
So... I wrote an OIIO image reading plugin that executes OSL code to procedurally generate image pixels as needed. It can do some fun tricks.
Generate an image by running a compiled OSL shader:
You can generate directly into an iv window (or any other app that uses OIIO to read):
A ".oslgroup" file can contain the serialization of an entire shading network:
URI notation can be used to set shader parameters:
URI notation also to control the resolution of the "image", or to make it look tiled rather than scanline, or even to make it behave like it's MIP-mapped:
".oslbody" signifies a snipped of OSL that will be pasted into OSL shader boilerplate, compiled from memory, and JITed on the fly:
Not just a single expression, you could write a whole program if you want:
Yeah, crazy.