Overview of OSL Shaders in Octane

Forums: Overview of OSL Shaders in Octane
A forum where development builds are posted for testing by the community.
Forum rules
NOTE: The software in this forum is not %100 reliable, they are development builds and are meant for testing by experienced octane users. If you are a new octane user, we recommend to use the current stable release from the 'Commercial Product News & Releases' forum.

Overview of OSL Shaders in Octane

Postby abstrax » Fri Nov 03, 2017 1:11 pm

abstrax Fri Nov 03, 2017 1:11 pm
EDIT: This description has been deprecated by this online help: https://docs.otoy.com/osl/



Overview of OSL Shaders in Octane

This guide describes working with OSL shaders in Octane. OSL shaders allow for custom procedural textures, custom texture mappings and custom cameras. The plan is to provide this information in the manual, but that hasn't been finished yet.

An OSL shader can define a number of inputs, and it can contain additional information to format these inputs in user interfaces. This is a simple example of a Mandelbrot shader:

Code: Select all
shader Mandelbrot(
    output color c = 0,
    int maxcount = 10
        [[int min=1, int max=20000, int sliderexponent=4,
          string label = "Max iterations",
          string description =
            "Maximal amount of iterations (z = z² + c)"]],
    int outputScale = 10000
        [[int min=1, int max=20000, int sliderexponent=4,
          string label = "Iterations scale factor",
          string description =
            "Scale factor, iteration count mapped to almost white"]],
    float gamma = 1.0
        [[string label = "Gamma", float min=0.1, float max=10]],
    point proj = point(u, v, 0)
        [[string label = "Projection"]],
    matrix xform = 1
        [[string label = "UV transform"]]
    )
{
    // safety check: max count should not be arbitrarily high:
    int maxcount2 = min(maxcount, 20000);
    // get a point. This implements the usual UV transform + projection inputs
    // of Octane texture nodes
    point p = transform(1/xform, proj);
    float cx = p[0];
    float cy = p[1];
   
    // Iterations
    float x = cx;
    float y = cy;
    int count = 0;
    while (x*x + y*y < 4 && count < maxcount2)
    {
        count += 1;
        // z = z² + c
        float x2 = x*x - y*y + cx;
        y = 2*x*y + cy;
        x = x2;
    }

    // output value: 1.0 if the iteration doesn't diverge, < 1.0 otherwise
    if (count < maxcount)
    {
        float h = (float)count;
        c = pow(h / outputScale, gamma);
        c = min(c, .99);
    }
    else
    {
        c = 1.0;
    }
}


After compiling this texture can be rendered like any other Octane texture:

OSL mandelbrot.jpg


The OSL standard is available from Sony Pictures Imageworks via GitHub. Octane currently is using version 1.8:
https://github.com/imageworks/OpenShadi ... gespec.pdf

WARNING:
When using OSL, you should ensure shaders never lock up or run for exceedingly long times. This may cause the system to freeze, or to reset the display driver.


WARNING:
Some operations, like out-of-bounds array access, may cause kernel crashes.



Supported features of OSL

Octane supports only a subset of the OSL standard, plus a few extensions to use features specific to Octane.

Unsupported features

  • Point cloud functions
  • Dictionary lookup functions
  • Message passing is generally not supported, except for the built-ins listed under "Octane extensions" (see below).
  • Derivatives
  • trace(). For AO like effects, you can add a color input and connect the input pin to a dirt node.
  • Material shaders and closure variables
  • wavelength color(). Use _gaussian() instead.
  • struct variable types
  • The global variables Ps and dPdt

Partially supported features

  • noise() doesn't support 4D noise, and doesn't support the "simplex" and "gabor" noise types
  • The global variable time always has a value between 0 and 1, and represents the time within a subframe.
  • getmessage() and gettextureinfo() must have string literals as attribute names.


Supported OSL shader types

Octane supports 3 OSL node types. Each has its own requirements regarding the signature of the OSL shader.


Texture

A texture shader must have one output of type color.

Code: Select all
shader OslTexture(
    output color c = 0)
{
    c = color(0.7, 0.7, 0.7);
}



Projection

A projection shader must have one output of a point-like type. All global variables have the same meaning as within texture shaders. The output value specifies a texture coordinate.

Code: Select all
shader OslProjection(
    output point uvw = 0)
{
    uvw = point(u, v, 0);
}



Camera

The following is a minimal implementation of a perspective camera. It takes into account the aspect ratio of the image

Code: Select all
shader OslCamera(
    output point  pos  = P,
    output vector dir  = 0,
    output float  tMax = 1.0/0.0)
{
    float pa;
    int res[2];
    getattribute("camera:pixelaspect", pa);
    getattribute("camera:resolution", res);
    float aspect = pa * res[1] / res[0];

    vector right = cross(I, N);
    dir = I + right * (u - .5) + N * (v - .5) * aspect;
}


Output variables

A camera shader has 3 outputs representing a ray (note that the names are arbitrary):

point pos = Ray position:
This is often set to P, but it may be set to other points to implement depth of field, or a near clipping plane

vector dir = Ray direction:
The render engine will take care of normalizing this vector if needed.

float tMax = Maximum ray tracing depth:
Measured along the direction of dir. May be used to implement a far clipping plane.
Set to 1.0/0.0 (infinity) to disable far clipping.

If tMax is 0, or if dir has 0 length, the returned ray is considered invalid, and the renderer will not perform any path tracing for this sample.

Accessing the camera position

Like other camera types, OSL camera nodes have static input pins which define the position and orientation of the camera. It is not mandatory for your camera shader to use this position, but if it does your camera automatically supports motion blur and stereo rendering.

camera_coordinate_system.png
camera_coordinate_system.png (6.29 KiB) Viewed 10628 times


Within camera shaders, the position and orientation of the camera is available via the standard global variables defined by OSL:

point P: Camera position
vector I: Camera direction (sometimes called *forward*)
normal N: vector, perpendicular to I
float u, float v: Coordinates on the film plane, mapped to the unit square. (0, 0) is at the bottom-left corner. These coordinates can be fetched via getattribute("hit:uv", uv) and via the UV projection node.

Alternatively, the camera position is also available via the "camera" coordinate space. This is usually an orthonormal coordinate space. Without transform the camera is looking along the -Z axis with the +Y axis as up-vector, i.e. the axes are defined as:

+X: Right vector
+Y: Up vector
–Z: Camera direction

Using this the last line of the example above may be written as:

Code: Select all
dir = vector("camera", 1.0, (v - .5) * aspect, (u - .5));



Supported input types for OSL nodes

Conceptually an OSL shader corresponds to a node in our node system. Input parameters will show up as input pins on the OSL texture/projection/camera node. There is 1 or more output parameters corresponding to the output value of the node (see "Supported OSL Shader Types" below).

The types in OSL code correspond to the following Octane pin types:

color: Texture
point: Projection (UV, spherical, cylindrical…)
vector / normal: Float (X, Y, Z)
matrix: Transform
float: Float (1D-value)
int: Int (1D-value) or Bool
string: Filename, String or Enum. See "String handling" below.

If an input has a constant value as default value, the corresponding input pin will have that value as default value as well.

Input meta data

OSL supports shader metadata to encode hints about the meaning of input parameters. Octane will use some of this metadata to change the appearance or ranges of input pins.

Code: Select all
    float FocalLength = 1
      [[ string label = "Focal length",
         float min = 0.1,
         float max = 1000,
         float sliderexponent = 4]],


Metadata for all inputs

string widget: Choose which type of widget to use. The possible values depend on the input type (see below).
string label: Override the name shown in the node inspector (normally the variable name is shown)
string help: Provides a tool tip for the pin when you hover your mouse over the pin
string page: Can be used to group pins into categories

Metadata for int and float inputs

float/int min, max: Specify the minimum and maximum values for a float or int input (note that there's no guarantee that the actual value for the variable in the shader is inside these bounds)
float/int slidermin, slidermax: Allows you to specify a more narrow value range for the sliders. Users may still enter values outside this range (but within min / max) using right mouse button drag, and by typing a value.
float/int sensitivity: Allows you to specify the steps for a float/int type variable
float/int sliderexponent: sets up the skew factor for the slider. In Octane, only linear (sliderexponent == 1) and logarithmic (sliderexponent > 1) are supported

Metadata for int inputs

string widget = "checkBox": show a checkbox instead of a slider. The input value will be 0 or 1.
string widget = "boolean": synonym for checkBox
string widget = "mapper" / string options: Use a combo box. Options are separated by pipe characters, the keys and value by a colon, e.g.: "option one:1|option two:2|option three:3"

Metadata for matrix inputs

int dim: set to either 2 or 3, specifies if the matrix should be shown as a 2D or 3D transform

Metadata for string inputs

string widget = "popup" / string options: Use a combo box. Options are separated by pipe characters, e.g. "option one|option two|option three"
int editable: If 1, this allows entering string values in a combo box which are not in the list of options

INFO:
File name inputs are always displayed as a file input, regardless of any given metadata.



Color handling in OSL shaders

Octane is a spectral renderer, so it handles the color variable type in a somewhat non-standard way.

Spectrum and RGB

Depending on what returned a given color value, a color variable may be represented internally as RGB or as a spectral color. When expressions use both RGB colors and spectral colors, the RGB colors will be converted to spectral colors.

Code: Select all
// a will be an RGB color
color a = 1;
// b will be an RGB color
color b = {1, 0.5, 0};
// c will be a spectral color
color c = _gaussian(1, 0.5, 0.01);

// adding two RGB colors results in another RGB color
color d = a + b
// adding a spectral color to another color always results in
// a spectral color


In practice, most colors will end up being represented as RGB colors. The main exceptions are blackbody and Gaussian spectra.

RGB colors support element access (using []) and casting to point-like types. For spectral colors this can be done only approximately, and the result will have poor color fidelity. The compiler will emit a warning if this happens.


String handling in OSL shaders

Supported operations on string values

Octane considers strings to be opaque values, and supports only a limited set of operations:

  • assignment (string b = a;)
  • check for equality (a == b, a != b)
  • using strings as arguments in functions and shaders

None of the standard string functions defined by OSL are supported.

Types of string variables

Octane roughly distinguishes between 3 types of string variables:

  • file names: These are strings which are passed into image sampling functions, like texture().
  • enum values: These are strings which are passed into functions which take a well-defined set of possible values, like raytype() or noise().
  • other strings: Strings which are not used for either of the above, or which are used for multiple types of enums.

The Octane OSL compiler will use static code analysis to determine how each string variable is used. If a variable is used as both an enum value and file name a compiler error is raised.

Using strings as shader inputs

Octane will represent the three types above with different widgets:

  • A file name is always shown as a file input, and any metadata is ignored.
  • Enum values will by default be represented by an Enum input pin.
  • Other string values will by default be represented by an Enum input pin.

String literals in texture() calls

If the argument of a texture call is a constant string, the compiler will generate a file name input and use the literal value as the default value. This allows loading OSL code which contains file names, and ensures any referenced files will be packed when a scene is exported to ORBX.


Octane-specific features and extensions

INFO
Some of these functions and string constants may change since 3.08 is not yet finalized.


List of intrinsic functions

Using intrinsics defined by Octane requires including <octane-oslintrin.h>.

_evaluateDelayed()

Code: Select all
color _evaluateDelayed(
    color inputVar,
    float texU,
    float texV)


Evaluates an input, and make texU and texV available during that evaluation. inputVar must be a color input variable for the OSL shader. See "Using delayed input textures" below.

_gaussian()

Code: Select all
color _gaussian(
    float mean,
    float sigma)


Return a Gaussian spectrum, normalized so that the maximal value is 1.0. The useful ranges for the inputs are:

  • mean: 380nm – 720 nm
  • sigma: 0 – 250 nm

The returned color is represented as a spectrum.

_squareSpectrum()

Code: Select all
color _squareSpectrum(
    float begin,
    float end)


Return a spectrum which is 1.0 between begin and end, and 0.0 otherwise.

_triangularSpectrum()

Code: Select all
color _triangularSpectrum(
    float mean,
    float spread)


Return a triangular spectrum which is 1.0 at mean, and which reaches 0 at mean +/- spread.

_spectrum()

Code: Select all
color _spectrum(
    float a,
    float b,
    float c,
    float d)


Makes a spectral color. The 4 inputs correspond to the intensities at the wavelengths returned by getattribute("color:wavelengths", wl).

wavelength_color()

wavelength_color(float wavelength) returns a spectrum consisting of a narrow band around wavelength. Colors returned for wavelengths outside (390, 700) will be close to black.

Octane 3.08 converts this call to _triangularSpectrum(wavelength, 30.0).

blackbody()

blackbody(kelvins) has the same meaning as in standard OSL, but returns a spectral color.

_hueshift()

Code: Select all
color _hueshift(
    color c,
    float shift)


Shifts the hue of the given color. This is a circular shift, shift = 6 represents a full circle. The returned color is represented in the same way as the c argument.

For RGB colors, 1 will shift red to yellow, while 2 will shift red to green.

For spectral colors, colors will be shifted to lower or higher wavelengths. Octane samples only a limited number of wavelengths, so color fidelity will be rather low.


List of string values

Global attributes

Attribute names used by the getattribute() function. Must be passed in as strings literals. It must be possible to assign from the corresponding
output type to the output variable. In this context float[2] may be assigned to a point or other vector-like type.

Some of these values are also available via intrinsic functions, these are mentioned in the Meaning column.

  • "camera:resolution" -> int[2]:
    Film resolution
  • "camera:pixelaspect" -> float:
    Aspect ratio of a single pixel
  • "camera:projection" -> string:
    Camera type
  • "camera:fov" -> float or float[2]:
    Horizontal field of view, or (if an array is given) horizontal and vertical field of view
  • "camera:clip_near" -> float:
    Near clipping plane
  • "camera:clip_far" -> float:
    Far clipping plane
  • "camera:clip" -> float[2]:
    Near and far clipping plane
  • "camera:distortion" -> float:
    Distortion (thin lens camera)
  • "camera:dofrandom" -> float[2]:
    Camera shaders only: random numbers used for DOF sampling
  • "color:wavelengths" -> float[4]:
    Wavelengths in nanometres in our current sample. Contains 4 values as of Octane 3.08.
  • "hit:obj-seed" -> int:
    Object layer random seed value, provides a random but deterministic value for each object.
  • "hit:instance-id" -> int:
    Instance ID provided by the user, eg. the A_INSTANCE_IDS attribute on the scatter node.<br>Intrinsic function: int _getinstanceid();
  • "hit:uv" -> float[2]:
    UV coordinates. The arrayindex input value may be used to select one 1 of 3 UV channels provided by Octane.<br>Intrinsic function: point _getuv(int index);
  • "hit:w" -> float:
    W coordinate, value which increases along hair strands.
  • "pixel:pos" -> int[2]:
    Pixel coordinate on the film plane

Texture attributes

Similar to getattribute(), but returns properties of specific image textures.

  • "exists" -> int:
    0 or 1, indicates if this texture was loaded successfully.
  • "resolution" -> int[2]:
    Returns the resolution of this image
  • "channels" -> int:
    Image channel type

Noise types

First input argument of the noise() function. A pair of string indicate unsigned and signed variants.

  • "uperlin", "perlin": Perlin noise
  • "noise", "snoise": Default noise type (Perlin)
  • "cell": Cell noise (constant value for each unit cell)
  • "circular", "scircular": Worley noise (F1)
  • "chips", "schips": Worley noise (F2 - F1)
  • "voronoi", "svoronoi": Voronoi noise

Ray types

Input argument of the raytype() function.

  • "camera": Camera ray
  • "shadow": Shadow ray
  • "AO": Ambient occlusion
  • "diffuse": Diffuse
  • "glossy", "reflection": Specular reflection
  • "refraction": Refraction

Coordinate spaces

Used in functions like transform() and matrix()

  • "common": Standard coordinate space, (world space)
  • "world": World space
  • "object": Object space
  • "shader": Synonym for object space
  • "camera": Camera space

  • "rgb": sRGB color space
  • "hsv": HSV color space, based on sRGB
  • "hsl": HSL color space, based on sRGB
  • "XYZ": CIE XYZ color space
  • "xyY": CIE xyY color space

Camera projection types

Returned from getattribute("camera:projection", type)

  • "spherical": Panoramic camera, spherical mode
  • "cylindrical": Panoramic camera, cylindrical mode
  • "cube": Panoramic camera, cube mapping mode
  • "cube:+x": Panoramic camera, cube mapping, +X face
  • "cube:-x": Panoramic camera, cube mapping, -X face
  • "cube:+y": Panoramic camera, cube mapping, +Y face
  • "cube:-y": Panoramic camera, cube mapping, -X face
  • "cube:+z": Panoramic camera, cube mapping, +Z face
  • "cube:-z": Panoramic camera, cube mapping, -Z face
  • "perspective": Thin lens camera
  • "orthographic": Thin lens camera, orthographic mode
  • "baking": Baking camera
  • "custom": OSL camera or Custom camera

Image texture wrapping mode

Used as optional wrap argument for texture() calls.

  • "black": Render black outside of the standard UV space.
  • "white": Render white outside of the standard UV space.
  • "clamp": Clamp the UV coordinates to [0 .. 1].
  • "mirror": Mirror image outside of the standard UV space to generate a seamless texture.
  • "periodic": Repeat the image texture outside of the standard UV space.


Using delayed input texture evaluation

Consider a simple use case: a texture shader which randomly picks one of four input textures for each UV tile.

Code: Select all
shader Texture(
    color col1 = color(1, 0, 0),
    color col2 = color(0, 1, 0),
    color col3 = color(0, 0, 1),
    color col4 = color(1, 1, 1),
    output color c = 0)
{
    int index = (int) floor(4 * noise("cell", u, v));

    // random index
    if (index == 0) { c = col1; }
    if (index == 1) { c = col2; }
    if (index == 2) { c = col3; }
    if (index == 3) { c = col4; }
}


tiles.png
tiles.png (282.47 KiB) Viewed 10628 times


Prior to evaluating this texture, the 4 texture inputs col1 to col4 are evaluated, but only one of them is needed to calculate the output value. This is inefficient if there’s a large amount of different tiles.

Delayed evaluation

In Octane you can use the intrinsic function _evaluateDelayed() to get around this:

Code: Select all
#include <octane-oslintrin.h>
shader Texture(
    color col1 = color(1, 0, 0),
    color col2 = color(0, 1, 0),
    color col3 = color(0, 0, 1),
    color col4 = color(1, 1, 1),
    output color c = 0)
{
    int index = (int) floor(4 * noise("cell", u, v));

    // random index
    if (index == 0) { c = _evaluateDelayed(col1, u, v); }
    if (index == 1) { c = _evaluateDelayed(col2, u, v); }
    if (index == 2) { c = _evaluateDelayed(col3, u, v); }
    if (index == 3) { c = _evaluateDelayed(col4, u, v); }
}


Using this intrinsic function will suppress the evaluation of those inputs before the shader runs.
Instead the inputs are evaluated on demand. Now only 1 input is evaluated.

Custom UV mapping

Apart from the input variable, there are two more arguments, which let you control the UV mapping
of the input texture. To use this UV map change the Projection input of any node connected to
this input to an OSL UV projection node.

We can modify our example so the input tiles are rotated randomly at 90° intervals.

Code: Select all
#include <octane-oslintrin.h>
shader Texture(
    color col1 = color(1, 0, 0),
    color col2 = color(0, 1, 0),
    color col3 = color(0, 0, 1),
    color col4 = color(1, 1, 1),
    output color c = 0)
{
    int rnd = (int) floor(16 * noise("cell", u, v));

    // random rotation
    float u2 = (rnd & 1) ? u : v;
    float v2 = (rnd & 1) ? v : -u;
    u2 = (rnd & 2) ? -u2 : u2;
    v2 = (rnd & 2) ? -v2 : v2;

    // random index
    int index = rnd >> 2;
    if (index == 0) { c = _evaluateDelayed(col1, u2, v2); }
    if (index == 1) { c = _evaluateDelayed(col2, u2, v2); }
    if (index == 2) { c = _evaluateDelayed(col3, u2, v2); }
    if (index == 3) { c = _evaluateDelayed(col4, u2, v2); }
}


tiles-rotated.png
tiles-rotated.png (282.48 KiB) Viewed 10628 times


INFO:
To use the custom UV coordinates in another OSL node connected via a delayed input, give it a point input and connect a OSL UV Projection node to the corresponding input pin.



Examples

In the archive below you can find 4 small set of OSL texture / camera examples all created by Roeland:

osl_examples.orbx
(74.09 KiB) Downloaded 440 times


osl_example1_isovoronoi.png


osl_example2_circular_anisotropy.png


osl_example3_mandelbrot.png


osl_example4_fisheye_camera.png
In theory there is no difference between theory and practice. In practice there is. - Yogi Berra
User avatar
abstrax
OctaneRender Team
OctaneRender Team
 
Posts: 5484
Joined: Tue May 18, 2010 11:01 am
Location: Auckland, New Zealand

Re: overview of OSL Shaders in Octane

Postby calus » Fri Nov 03, 2017 3:44 pm

calus Fri Nov 03, 2017 3:44 pm
Can you comment on unsupported OSL features ?

Is your intention to support closure/ OSl surface and volume materials, or did you give up on this ?

what about Light Path Expressions, OSL passes ?
Pascal ANDRE
calus
Licensed Customer
Licensed Customer
 
Posts: 1308
Joined: Sat May 22, 2010 9:31 am
Location: Paris

Re: overview of OSL Shaders in Octane

Postby Goldorak » Fri Nov 03, 2017 5:25 pm

Goldorak Fri Nov 03, 2017 5:25 pm
calus wrote:Can you comment on unsupported OSL features ?

Is your intention to support closure/ OSl surface and volume materials, or did you give up on this ?

We did the work (we have a 3.10 test build with closures), but it was clear the approach in 3.08 is simpler for normal users’ worflow. We’ll revisit all this and MDL after 3.09..

what about Light Path Expressions, OSL passes ?


We’ll continue to add extensions to OSL - but in an artists friendly way. 3.08 is just a first step.
User avatar
Goldorak
OctaneRender Team
OctaneRender Team
 
Posts: 2321
Joined: Sun Apr 22, 2012 8:09 pm

Re: overview of OSL Shaders in Octane

Postby VVG » Sat Nov 04, 2017 9:50 am

VVG Sat Nov 04, 2017 9:50 am
sorry for the nub OSL question

Cycles 4D OSL shader pack
http://manual.cycles4d.net/html/scriptpack.htm

compatible with octane OSL?
Win 10x64, AMD 1950x 16C/32T, RAM 32Gb, RTX 3060x3
Octane-for-C4D(R23.110)2021.x.x, Cycles4D, Centileo. Nvidia 472.47 STUDIO
VVG
Licensed Customer
Licensed Customer
 
Posts: 301
Joined: Sat May 07, 2016 2:34 pm

Re: overview of OSL Shaders in Octane

Postby aoktar » Sat Nov 04, 2017 10:24 am

aoktar Sat Nov 04, 2017 10:24 am
VVG wrote:sorry for the nub OSL question

Cycles 4D OSL shader pack
http://manual.cycles4d.net/html/scriptpack.htm

compatible with octane OSL?

Yes and no! Propably they need to be adopted because current limitations of osl in Octane. Some of them (textures) will work directly or after modifications and material scripts will not work.
Octane For Cinema 4D developer / 3d generalist

3930k / 16gb / 780ti + 1070/1080 / psu 1600w / numerous hw
User avatar
aoktar
Octane Plugin Developer
Octane Plugin Developer
 
Posts: 15970
Joined: Tue Mar 23, 2010 8:28 pm
Location: Türkiye

Re: overview of OSL Shaders in Octane

Postby calus » Tue Nov 07, 2017 12:34 pm

calus Tue Nov 07, 2017 12:34 pm
Trying to translate the Maya builtin texture nodes to OSL,
but in Maya every texture nodes have a color and a float output, the second output is for alpha, and this is very handy.

OSL camera nodes already supports multi output, so please remove the arbitrary limitation of 1 output for OSL texture node in Octane !
Pascal ANDRE
calus
Licensed Customer
Licensed Customer
 
Posts: 1308
Joined: Sat May 22, 2010 9:31 am
Location: Paris

Re: overview of OSL Shaders in Octane

Postby calus » Tue Nov 07, 2017 3:14 pm

calus Tue Nov 07, 2017 3:14 pm
Oh Abstrax my bad :oops: , I totaly missed this in the 3.08 t4 release post :
abstrax wrote:...
Now, anything programmable requires you to be able to compile some code into machine code during runtime. Turns out that this is a fairly tricky problem to solve for GPUs and although we got it working for complete OSL materials we couldn't get the compile times short enough, which broke the interactivity of Octane. We also had to restructure more stuff in the render kernels which had a negative effect on the render performance, too.
Running out of ideas how to improve the situation substantially, we tried to reduce the scope to OSL textures only and tried a couple fairly different approaches and one of them worked pretty well, eventually resulting in this release.
...
So when will full OSL material support arrive? We honestly don't know yet. Before we will give OSL materials a second try, we will probably look into MDL support first since it seems to be more suitable for a path tracer like Octane and its support in the industry has grown a lot in the last couple of years. After MDL we will look into OSL material support again and hope to make it work, but we can't make any guarantees here.


So you had already explained everything very well about OSL materials with maybe no future,
then OSL might not be the way to go for my project > complete translation of all Maya nodes (at the momment only 5% of the Maya nodes are supported by OctaneForMaya).

That's a shame because OSL is so much more fun than MDL, but ok let's have a look at MDL again then ;)
Pascal ANDRE
calus
Licensed Customer
Licensed Customer
 
Posts: 1308
Joined: Sat May 22, 2010 9:31 am
Location: Paris

Re: overview of OSL Shaders in Octane

Postby J.C » Tue Nov 07, 2017 4:25 pm

J.C Tue Nov 07, 2017 4:25 pm
Hi,

Is it possible to fix the script below to work with Octane?
https://docs.chaosgroup.com/display/OSL ... normal+map

There is a general error "Compilation failed" without pointing what is wrong.
CPU – i9 13900KF, 128GB RAM, GPU – RTX 4090
System – Windows 11
My Behance portfolio, Blender plugin FB support group
J.C
Licensed Customer
Licensed Customer
 
Posts: 1723
Joined: Thu May 13, 2010 6:35 pm
Location: Wrocław

Re: overview of OSL Shaders in Octane

Postby calus » Tue Nov 07, 2017 5:12 pm

calus Tue Nov 07, 2017 5:12 pm
J.C wrote:Hi,

Is it possible to fix the script below to work with Octane?
https://docs.chaosgroup.com/display/OSL ... normal+map

There is a general error "Compilation failed" without pointing what is wrong.

this is because OSL texture node only support 1 output for the moment :(
You need to disable the alpha output like this :

Code: Select all
shader
flakes
(
    float flake_scale = 10.0 [[ string description = "Smaller values zoom into the flake map, larger values zoom out" ]],
    float flake_size = 0.5 [[ string description = "Relative size of the flakes" ]],
    float flake_size_variance = 0.0 [[ string description = "0.0 makes all flakes the same size, 1.0 assigns random size between 0 and the given flake size" ]],
    float flake_normal_orientation = 0.0 [[ string description = "Blend between the flake normals (0.0) and the surface normal (1.0)" ]],
     
    output color result = 1.0
//    output float alpha  = 1.0
)
{
    float safe_flake_size_variance = clamp(flake_size_variance, 0.1, 1.0);
    vector cellCenters[9] = {
        vector( 0.5,  0.5,  0.0),
        vector( 1.5,  0.5,  0.0),
        vector( 1.5,  1.5,  0.0),
        vector( 0.5,  1.5,  0.0),
        vector(-0.5,  1.5,  0.0),
        vector(-0.5,  0.5,  0.0),
        vector(-0.5, -0.5,  0.0),
        vector( 0.5, -0.5,  0.0),
        vector( 1.5, -0.5,  0.0)
    };
     
    point position = vector(u, v, 0.0);
    position = flake_scale * position;
     
    point base = floor(position);
     
    point nearestCell = point(0.0, 0.0, 1.0);
    int nearestCellIndex = -1;
    for(int cellIndex = 0; cellIndex < 9; ++cellIndex)   {
        point cellCenter = base + cellCenters[cellIndex];
         
        vector centerOffset = cellnoise(cellCenter) * 2.0 - 1.0;
        centerOffset[2] *= safe_flake_size_variance;
        centerOffset = normalize(centerOffset);
         
        cellCenter += 0.5 * centerOffset;
        float cellDistance = distance(position, cellCenter);
        if(cellDistance < flake_size && cellCenter[2] < nearestCell[2]) {
            nearestCell = cellCenter;
            nearestCellIndex = cellIndex;
        }
    }
     
    result = color(0.5, 0.5, 1.0);
//    alpha = 0.0;
     
    if (nearestCellIndex != -1) {
        vector randomNormal = cellnoise(base + cellCenters[nearestCellIndex] + vector(0.0, 0.0, 1.5));
        randomNormal = 2.0 * randomNormal - 1.0;
        randomNormal = faceforward(randomNormal, I, randomNormal);
        randomNormal = normalize(mix(randomNormal, vector(0.0, 0.0, 1.0), flake_normal_orientation));
         
        result = color(0.5*randomNormal[0]+0.5, 0.5*randomNormal[1]+0.5, randomNormal[2]);
//        alpha = 1.0;
    }
}
Pascal ANDRE
calus
Licensed Customer
Licensed Customer
 
Posts: 1308
Joined: Sat May 22, 2010 9:31 am
Location: Paris

Re: overview of OSL Shaders in Octane

Postby J.C » Tue Nov 07, 2017 9:03 pm

J.C Tue Nov 07, 2017 9:03 pm
Thanks calus. This compiles now but it does not work as advertised by Chaos group. The flakes does not scale. I just can see some two big triangles.
CPU – i9 13900KF, 128GB RAM, GPU – RTX 4090
System – Windows 11
My Behance portfolio, Blender plugin FB support group
J.C
Licensed Customer
Licensed Customer
 
Posts: 1723
Joined: Thu May 13, 2010 6:35 pm
Location: Wrocław
Next

Return to Development Build Releases


Who is online

Users browsing this forum: No registered users and 9 guests

Sun Apr 28, 2024 3:01 pm [ UTC ]