coshaders & shader objects

Upload: rendermanuser

Post on 14-Apr-2018

228 views

Category:

Documents


0 download

TRANSCRIPT

  • 7/29/2019 CoShaders & Shader Objects

    1/5

    CoShaders & Shader Objects

    Traditional RenderMan shaders are split into 4 main types: Surface, Displacement, Light and Volume.

    With Prman version 13.5, Pixar introduced the concept of co shader and shader objects to expand the pipeline ofshading your scenes

    Shader objects are shaders which can be treated like objects in a programming environment. They can keep values in

    member variables, which can be used elsewhere in the shader ie in both a displacement and surface shading routine.This for example removes the need for some message passing CoShaders are shaders with no defined type. They cancontain more than one shading model - i.e a single shader can contain both displacement and surface information.

    So for a look of displacement and surface shading, we would normally have to have 2 separate shaders, and apply themboth to our geometry in the scene.

    Shader Objects

    Unfortunately, Shader objects havent been fully implemented into RM Studio just yet, but this is a very simpleintroduction to them.

    In this example, I am going to build up a simple class based shader, which has both displacements and surface shadinginformation.

    Here is the basic structure for a shader object:

    class ShaderObjects(/* parameters */){ publicvoid displacement(output point P; output normal N)

    { /* DISPLACEMENT CODE */

    }

    publicvoid surface(output color Ci, Oi){

    /* SHADER CODE */}

    }

    You can see the class definition, and both the displacement and surface calls. The class section is where we will set ourparameter values for controlling the shader.

    So lets take a look at the displacements. Because we want to control a few parameters, we will specify them in theshader objects parameter list.

    The uniform floats: texfreq and dispmult are for the pattern frequency and amount of displacement applied

    First we set our normal and texture coordinates

    Then calculate our pattern

    Store the depth in our variable Disp and then apply the displacements

    class ShaderObject(uniform float texfreq = 1, DMult = 0.01){

    publicvoid displacement(output point P; output normal N){

    varying float Disp = 0; float tt = mod(t * texfreq,1); float ss = mod(s * texfreq,1);

    varying float vstripes = smoothstep(0.2,0.25,tt) - smoothstep(0.750,0.8,tt);varying float hstripes = smoothstep(0.2,0.25,ss) - smoothstep(0.750,0.8,ss);

    P += normalize(N) * DMult * max(vstripes,hstripes);Disp = max(vstripes,hstripes);N = calculatenormal(P);

    }

    publicvoid surface(output color Ci, Oi){

    varying normal n = 0;

  • 7/29/2019 CoShaders & Shader Objects

    2/5

    n = normalize(N);

    normal nf = faceforward(n, I);color diffusecolor = diffuse(nf);Oi = Os;Ci = Oi * Cs * diffusecolor;

    }}

    We can save this file as coshader.sl and compile it with the shader executable.

    Next take a look at the ribfile:

    Display "ShaderObjects" "it" "rgba"Format 640 480 1Projection "perspective" "fov" 40ShadingRate 1Translate 0 0 3Rotate -30 1 0 0Rotate 0 0 1 0Scale 1 1 -1WorldBegin

    LightSource "pointlight" 1 "intensity" 45 "from" [5 5 5]Color 0.341 0.266 0.184Surface "plastic"Displacement "dented"Attribute "bound" "displacement" [0.1]Sphere 1 -1 1 360

    WorldEnd

    This contains the standard method for assigning surface and displacement shaders to an object, in this case a simplesphere. So we need to modify it to work with the class based shader we have just compiled.

    So instead of separate surface and displacement calls, we simple replace them with a single surface call.

    Display " ShaderObjects" "it" "rgba"Format 640 480 1

    Projection "perspective" "fov" 40ShadingRate 1Translate 0 0 3Rotate -30 1 0 0Rotate 0 0 1 0Scale 1 1 -1WorldBegin

    LightSource "pointlight" 1 "intensity" 45 "from" [5 5 5]Color 0.341 0.266 0.184

    Surface "ShaderObject" "DMult" 0.025

    Attribute "bound" "displacement" [0.1]Sphere 1 -1 1 360

    WorldEnd

    If you render this ribfile, by running prman shaderobjects.rib you will see a simple sphere with our displacement shaderassigned.

  • 7/29/2019 CoShaders & Shader Objects

    3/5

    Lets go back to the rib file, and set a bigger value for the texture repeats. After the surface call, add texfreq 16.:

    Surface "ShaderObject" "DMult" 0.025 "texfreq" 16

    We can now see the repeating pattern has increased.

    Lets add a surface shader to this shaderobject. Place the Kd declaration in the parameters for the diffuse. Next add thesurface code into the surface section

    class ShaderObject(float Kd = 1;uniform float texfreq = 1, DMult = 0.01){

    publicvoid displacement(output point P; output normal N){

    varying float Disp = 0; float tt = mod(t * texfreq,1); float ss = mod(s * texfreq,1);

    varying float vstripes = smoothstep(0.2,0.25,tt) - smoothstep(0.750,0.8,tt);varying float hstripes = smoothstep(0.2,0.25,ss) - smoothstep(0.750,0.8,ss);

    P += normalize(N) * DMult * max(vstripes,hstripes);Disp = max(vstripes,hstripes);N = calculatenormal(P);

    }

    publicvoid surface(output color Ci, Oi)

    {varying normal n = 0;n = normalize(N);normal nf = faceforward(n, I);

  • 7/29/2019 CoShaders & Shader Objects

    4/5

    color surfcolor = Cs;surfcolor = color(0,0,1);color diffusecolor = Kd * diffuse(nf);Oi = Os;Ci = Oi * surfcolor * diffusecolor;

    }}

    Now when you render, you can see our single shader, has both displacement and surface data computed.

    The real power of these shader objects, is their ability to share data between them, so information from the displacementroutine can be used within the surface shading component for example. Lets change our surface shader based ondisplacements. I want to have the pits in the displacement to be coloured red, and the extruded parts to be blue. To dothis previously, we would have to use message passing, now we can simply set the variables we wish to use before thepublic calls.

    Add varying float variables for Disp and Base. We will compare these two values later to see if the surface has beendisplaced or not.

    In the displacement shader, make DISP equal to the max value of the pattern

    We can now take this DISP value from the displacement shader object, and use it in the surface shader object, by usingthe following IF condition.

    class ShaderObject(float Kd = 1; uniform float texfreq = 16, DMult = 0.01){

    varying float Base = 0;varying float Disp = 0;varying normal n = 0;

    publicvoid displacement(output point P; output normal N) {

    float tt = mod(t * texfreq,1);

    float ss = mod(s * texfreq,1);

    varying float vstripes = smoothstep(0.2,0.25,tt) - smoothstep(0.750,0.8,tt);varying float hstripes = smoothstep(0.2,0.25,ss) - smoothstep(0.750,0.8,ss);P += normalize(N) * DMult * max(vstripes,hstripes);Disp = max(vstripes,hstripes);N = calculatenormal(P);

    }

    publicvoid surface(output color Ci, Oi) {

    n = normalize(N);normal nf = faceforward(n, I);color surfcolor = Cs;surfcolor = color(0,0,1);color diffusecolor = Kd * diffuse(nf);

    Oi = Os;Ci = Oi * surfcolor * diffusecolor;

    }}

  • 7/29/2019 CoShaders & Shader Objects

    5/5

    Now when we render, you can see the red and blue areas shaded, as the displacement shader passes its information tothe surface shader.