OSL Image Manipulation: Difference between revisions
(→P) |
|||
(One intermediate revision by the same user not shown) | |||
Line 64: | Line 64: | ||
==== P ==== | ==== P ==== | ||
<code>P</code> contains the position of the center of the current pixel relative to the origin of the image data window. | <code>P</code> contains the position of the center of the current pixel relative to the origin of the image [https://www.gafferhq.org/documentation/{{latestGafferVersion}}/WorkingWithImages/AnatomyOfAnImage/index.html#data-window data window]. | ||
[[File:OslImageP.png|none|thumb|900x900px|Visualising the values of <code>P</code> as colours, the bottom left pixel has a value of (0.5, 0.5, 0) and the top right pixel a value of ( 3.5, 3.5, 0 ).]] | [[File:OslImageP.png|none|thumb|900x900px|Visualising the values of <code>P</code> as colours, the bottom left pixel has a value of (0.5, 0.5, 0) and the top right pixel a value of ( 3.5, 3.5, 0 ).]] | ||
==== u, v ==== | ==== u, v ==== | ||
<code>u</code> & <code>v</code> contain the position of the center of the current pixel remapped to 0-1 across the image display window. | <code>u</code> & <code>v</code> contain the position of the center of the current pixel remapped to 0-1 across the image [https://www.gafferhq.org/documentation/{{latestGafferVersion}}/WorkingWithImages/AnatomyOfAnImage/index.html#display-window display window]. | ||
[[File:OslImageUV.png|none|thumb|900x900px|Visualising the values of <code>u</code> & <code>v</code> as colours. The bottom left pixel has a value of ( 0.125, 0.125, 0 ) and the top right pixel a value of ( 0.875, 0.875, 0 ).]] | [[File:OslImageUV.png|none|thumb|900x900px|Visualising the values of <code>u</code> & <code>v</code> as colours. The bottom left pixel has a value of ( 0.125, 0.125, 0 ) and the top right pixel a value of ( 0.875, 0.875, 0 ).]] |
Latest revision as of 17:49, 11 August 2024
The OSLImage node allows the use of OpenShadingLanguage shaders to generate or modify pixel values in an image.

Shaders can be built from an existing library of OSL shaders loaded via the OSLShader node, and arbitrary shader code can be evaluated via the OSLCode node. An image manipulation shader could be built entirely from existing nodes, written in a single OSLCode node, or assembled from a combination of OSL shaders and OSLCode nodes.
Shaders are evaluated per pixel in the image and typically would read that pixel value from one or more channels in the image, compute a value from those inputs and then output a new value that would replace the input pixel in an existing channel or layer, or create a new channel or layer.

Writing channel data
Adding channels to OSLImage
Channels are written by adding inputs to the OSLImage node by clicking on the button in the Node Editor or by clicking or dragging a plug onto the
on the left of the node in the Graph Editor.


You can choose from common channel or layer names from the menu to write to RGB or RGBA layer, or to individual R, G, B, A channels.

You can also create arbitrary channels or layers via the Custom->Channel
, Custom->Layer
or Custom->LayerRGBA
menu items. The channel or layer name can then be customised by by editing the name of the plug in the Node Editor.

Behind the scenes, these actions are adding new child plugs to the `channels` plug of the OSLImage node.
The OSLImage node's channel inputs can either be a Color3fPlug or a FloatPlug, so choosing RGBA from the menu will create two plugs, a Color3fPlug for the RGB channels and a FloatPlug for the A channel.
Each channel or layer created provides an input connection ready to receive an OSL shader.
Disabling an output
Output layers and channels can be disabled by toggling their enabled
plug.

Removing an output
Previously created output layers and channels can be removed by right clicking on the plug and selecting Delete
from the context menu.

Reading channel data
Reading channels from shaders
The InChannel
OSL shader can be used to read a specific channel from the processed image.

The InLayer
OSL shader can be used to read the R, G, B channels of a specified image layer.

Reading channels in an OSLCode node
When writing an OSL shader in an OSLCode node, Gaffer provides inChannel( channelName, defaultValue )
and inLayer( layerName, defaultValue )
functions to access the value of a specific channel or layer for the current pixel.
// Get the value of the "R" channel, returning 0 if the channel does not exist.
float R = inChannel( "R", 0.0 );
// Get the values of the "R", "G", "B" channels, returning black if the layer doesn't exist
// Providing "" as the layer name will return a color containing the value of the R, G, B channels.
color RGB = inLayer( "", color( 0.0 ) );
// Get the values of the "diffuse.R", "diffuse.G", "diffuse.B" channels, returning white if the layer doesn't exist
color diffuse = inLayer( "diffuse", color( 1.0 ) );
Channels can also be accessed via OSL's getattribute function.
// Get the value of the "R" channel for the current pixel
float R;
getattribute( "R", R );
// Get the value of the "R" channel from the "diffuse" layer for the current pixel
float diffuseR;
getattribute( "diffuse.R", diffuseR );

Pixel Coordinates
When generating patterns, it's important to know where in the image the currently shaded pixel is located. OSLImage provides two builtin variables for locating the currently shaded pixel.
P
P
contains the position of the center of the current pixel relative to the origin of the image data window.

P
as colours, the bottom left pixel has a value of (0.5, 0.5, 0) and the top right pixel a value of ( 3.5, 3.5, 0 ).u, v
u
& v
contain the position of the center of the current pixel remapped to 0-1 across the image display window.

u
& v
as colours. The bottom left pixel has a value of ( 0.125, 0.125, 0 ) and the top right pixel a value of ( 0.875, 0.875, 0 ).