Hello OSL
.start
Also, now I am calculating the dot product of the Viewing and Normal vectors only once. But, I did not find that much of difference in render time. Should test it on larger scenes.
That's it for now. If you want to get started with OSL concepts, I recommend you to read OSL Introduction document and also SIGGRAPH 2012 Course: Practical Physically Based Shading in Film and Game Production
Once I gain more understanding of OSL, I will write detailed tutorials covering various aspects of shader authoring using OSL.
On recompiling the shader from the script node, the following message was printed in the konsole.
On choosing an axis value of 3 from the script node, the following error was printed in the konsole.
.end
satishgoda at gmail dot com
About
I finally got my hands on writing Open Shading Language (OSL) shaders after reading the OSL language specification.I am really blown away by the seamless integration of OSL with Blender Cycles Rendering Engine. I wrote two shaders today.
And the OSL code that was attached to the Script node is below. This shaders basically outputs a color.
Following is an excerpt from the OSL language specification.
What the script is doing is give us the ability to choose one axis and paint all vertices on the negative axis to red and green otherwise.
OSL Script #1
Before writing my first script, I implemented a simple idea using existing nodes. You can see the node network in the image belowAnd the OSL code that was attached to the Script node is below. This shaders basically outputs a color.
#include "stdosl.h"
shader this_or_that(
color This = color(1,0,0),
color That = color(0,1,0),
int axis = 0,
output color ThisOrThat = color(1,1,1)
)
{
point Position = P;
if (Position[axis] < 0) {
ThisOrThat = This;
} else {
ThisOrThat = That;
}
}In the preceding code, P is the position of the point being shaded and is a Global variable (a.k.a. Graphics state variable).
Following is an excerpt from the OSL language specification.
Global variables (sometimes called graphics state variables) contain the basic information that the renderer knows about the point being shaded, such as position, surface orientation, and default surface color. You need not declare these variables; they are simply available by default in your shader. Global variables available in shaders are: P, I, N, Ng, u, v, dPdu, dPdv, Ps, time, dtime, dPdtime and Ci.
What the script is doing is give us the ability to choose one axis and paint all vertices on the negative axis to red and green otherwise.
OSL Script #2
Also, thanks to a nice and simple script by an user on BlenderArtists, I modified that script as follows.- Ability to receive Shading (N) or Geometric (Ng) Normal as input, so that that shading can be changed accordingly.
- And some minor refactoring to suit my programming style.
#include "stdosl.h"
shader toon_shader(
normal Normal = N,
color Highlight = 1,
float HighAngle = 10.0,
float HighBoost = 1,
float Mid = 0.5,
float MidAngle = 65.0,
float Shadow = 0.25,
output color Color = Highlight * Shadow
)
{
float highValue = cos(radians(clamp(HighAngle, 0, 90)));
float midValue = cos(radians(clamp(MidAngle, 0, 90)));
if(abs(dot(-I, Normal)) > midValue) {
Color = Highlight * Mid;
}
if(abs(dot(-I, Normal)) > highValue) {
Color = Highlight * HighBoost;
}
}
OSL Script #2 - Refactor
In the osl code from previous section, on interchanging the order of evaluation of lines that calculate the Highlight and Midtone, the highlight in my render vanished. I asked around on the BlenderArtists forums and realized the mistake I made. Following is the modified shader
#include "stdosl.h"
shader toon_shader(
normal Normal = N,
color Highlight = 1,
float HighAngle = 10.0,
float HighBoost = 1,
float Mid = 0.5,
float MidAngle = 65.0,
float Shadow = 0.25,
output color Color = color(1, 0, 0)
)
{
float highValue = cos(radians(clamp(HighAngle, 0, 90)));
float midValue = cos(radians(clamp(MidAngle, 0, 90)));
float scalar = abs(dot(-I, Normal));
if( scalar > highValue ) {
Color = Highlight * HighBoost;
} else if( scalar > midValue ) {
Color = Highlight * Mid;
} else {
Color = Highlight * Shadow;
}
}
Also, now I am calculating the dot product of the Viewing and Normal vectors only once. But, I did not find that much of difference in render time. Should test it on larger scenes.
That's it for now. If you want to get started with OSL concepts, I recommend you to read OSL Introduction document and also SIGGRAPH 2012 Course: Practical Physically Based Shading in Film and Game Production
Once I gain more understanding of OSL, I will write detailed tutorials covering various aspects of shader authoring using OSL.
Behind The Scenes
This section contains some technical details that I noticed while recompiling the shaders and/or when there were script errors.
On recompiling the shader from the script node, the following message was printed in the konsole.
Info: OSL shader compilation succeeded
ERROR: Index [3] out of range [0..2]: /usr/scratch/tmp5j47fg.osl:12
So I went searching for the file /usr/scratch/tmp5j47fg.osl but to no avail. Instead I found /usr/scratch/tmp9wzu0u.oso
OpenShadingLanguage 1.00On my windows machine at home, I got the following results on errors in my shader
# Compiled by oslc 1.3.0
shader this_or_that
param color This 1 0 0 %read{4,4} %write{2147483647,-1}
param color That 0 1 0 %read{5,5} %write{2147483647,-1}
param int axis 0 %read{1,1} %write{2147483647,-1}
oparam color ThisOrThat 1 1 1 %read{2147483647,-1} %write{4,5}
global point P %read{0,0} %write{2147483647,-1}
local point Position %read{1,1} %write{0,0}
temp float $tmp1 %read{2,2} %write{1,1}
const int $const1 0 %read{2,2} %write{2147483647,-1}
temp int $tmp2 %read{3,3} %write{2,2}
code ___main___
# /usr/scratch/tmp5j47fg.osl:10
# point Position = P;
assign Position P %filename{"/usr/scratch/tmp5j47fg.osl"} %line{10} %argrw{"wr"}
# /usr/scratch/tmp5j47fg.osl:12
# if (Position[axis] < 0) {
compref $tmp1 Position axis %line{12} %argrw{"wrr"}
lt $tmp2 $tmp1 $const1 %argrw{"wrr"}
if $tmp2 5 6 %argrw{"r"}
# /usr/scratch/tmp5j47fg.osl:13
# ThisOrThat = This;
assign ThisOrThat This %line{13} %argrw{"wr"}
# /usr/scratch/tmp5j47fg.osl:15
# ThisOrThat = That;
assign ThisOrThat That %line{15} %argrw{"wr"}
end
c:\\users\\lenovo\\appdata\\local\\temp\\tmpsu9usf.osl:12: error: shader parameter 'Color' MUST have a default initializerAnother error
Error: OSL script compilation failed, see console for errors
error: No shader function defined
Error: OSL script compilation failed, see console for errors
References
- OSL
- http://opensource.imageworks.com/?p=osl
- http://code.google.com/p/openshadinglanguage/
- https://github.com/imageworks/OpenShadingLanguage/
- Blender Cycles
- http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles
- http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/OSL
- OpenShading
- Community
Related Posts
.end
satishgoda at gmail dot com
Added a link to SIGGRAPH 2012 Course: Practical Physically Based Shading in Film and Game Production
ReplyDeletehttp://blog.selfshadow.com/publications/s2012-shading-course/
Refactored the node network and the osl code as well and updated the post.
ReplyDeleteAdded a behind the scenes section
ReplyDeleteIt's really a great and helpful piece of info. I'm glad that you just shared this useful information with us. Please keep us up to date like this. Thank you for sharing.
ReplyDelete