space time varying color palettes
TRANSCRIPT
Sponsored by
Space Time Varying Color Palette
Bo ZHOU J Cube Inc. !Paolo Berto Durrante J Cube Inc. Polygon Pictures Inc.
Sponsored by SA2015.SIGGRAPH.ORG
Introduction
Sponsored by SA2015.SIGGRAPH.ORG
Toon Rendering
no PBR flat shading artistic design
Sponsored by SA2015.SIGGRAPH.ORG
Color Palette
color matrixobject index
semantics
Sponsored by SA2015.SIGGRAPH.ORG
Color Palette
column object index
row semantics
lit color shadow color 2nd shadow color outline color etc.
Sponsored by SA2015.SIGGRAPH.ORG
Color Palette
Daylight Night Jungle Sunset
Sponsored by SA2015.SIGGRAPH.ORG
Color Palette
advantage fast design reusable material/shading system independent
Sponsored by SA2015.SIGGRAPH.ORG
Color Palette
disadvantage static color predefined before rendering
Sponsored by SA2015.SIGGRAPH.ORG
Reality
Sponsored by SA2015.SIGGRAPH.ORG
Problem
Character was lit by both environment light and visual effect elements.
Sponsored by SA2015.SIGGRAPH.ORG
Typical Workflow
create 2 color plattes 1 according environment and 2 for vfx
generate masks from renderer fill the regions in post composition software
R = Lit, G = Shadow, Y = Specular
Object Id
Sponsored by SA2015.SIGGRAPH.ORG
Typical Workflow
disadvantage image was done in composition
software. extra overhead on disk usage
more masks not invertible
once geometry was changed, must regenerate the all masks
Sponsored by SA2015.SIGGRAPH.ORG
Goal
finish the image in renderer less disk usage maximal flexibility as manual switching the
color palette in composition software
Sponsored by SA2015.SIGGRAPH.ORG
Solution
Sponsored by SA2015.SIGGRAPH.ORG
Solution
DAG network a typed eventing network
time space position special light …
generate dynamic code for specific network independent from any renderer/software what we want is a set of colors outputed from the network constant statement will be optimised by compiler
Sponsored by SA2015.SIGGRAPH.ORG
Use Case
2 palettes, use the 1st between frame 1 - 4 but the rest associated with 2nd
Sponsored by SA2015.SIGGRAPH.ORG
Use Case
generated shader codeclass jcubeToon5_PalettesCoShader_1() { uniform float num_rows = 5 ; uniform float cell_size = 30 ; uniform float border_size = 2 ; ! public uniform float has_light_event = 0 ; ! uniform string color_palettes[2] = { "/Users/Bo/Documents/maya/projects/default/sourceimages/Palette_A.tif" , // file2 "/Users/Bo/Documents/maya/projects/default/sourceimages/Palette_B.tif" // file1 }; ! public void construct() { Gather( color_palettes[0] , cell_size , border_size , num_rows ) ; Gather( color_palettes[1] , cell_size , border_size , num_rows ) ; } ! ////////////////////////////////////////// public void surface( output color Ci , Oi ; output color outputs[5] ; uniform float float_index = - 1 ; color color_index = 0 ) { float choice = - 1 ; ! // jcubeToonNumericEvent1 // float jcubeToonNumericEvent1_outputs = - 1 ; uniform float jcubeToonNumericEvent1_first_term = 1.0 ; uniform float jcubeToonNumericEvent1_second_term = 4.0 ; uniform float jcubeToonNumericEvent1_if_palette = 0 ; // file2 uniform float jcubeToonNumericEvent1_else_palette = 1 ; // file1 if ( jcubeToonNumericEvent1_first_term > jcubeToonNumericEvent1_second_term ) { jcubeToonNumericEvent1_outputs = jcubeToonNumericEvent1_if_palette ; } else { jcubeToonNumericEvent1_outputs = jcubeToonNumericEvent1_else_palette ; } choice = jcubeToonNumericEvent1_outputs ; if ( float_index > - 1 ) { Search( color_palettes[choice] , float_index , outputs ) ; } else { Search( color_palettes[choice] , color_index , outputs ) ; } } }
Sponsored by SA2015.SIGGRAPH.ORG
Use Case
if (“P” in pCube1) if (time > 4) pick A else pick C else pick B
Sponsored by SA2015.SIGGRAPH.ORG
Use Caseclass jcubeToon5_PalettesCoShader_1() { uniform float num_rows = 5 ; uniform float cell_size = 30 ; uniform float border_size = 2 ; ! public uniform float has_light_event = 0 ; ! uniform string color_palettes[3] = { "/Users/Bo/Documents/maya/projects/default/sourceimages/Palette_C.tif" , // file3 "/Users/Bo/Documents/maya/projects/default/sourceimages/Palette_A.tif" , // file2 "/Users/Bo/Documents/maya/projects/default/sourceimages/Palette_B.tif" // file1 }; ! public void construct() { Gather( color_palettes[0] , cell_size , border_size , num_rows ) ; Gather( color_palettes[1] , cell_size , border_size , num_rows ) ; Gather( color_palettes[2] , cell_size , border_size , num_rows ) ; } ! float inside_box( uniform point box_min , box_max ; point x ) { if ( x[0] > box_min[0] && x[0] < box_max[0] ) if ( x[1] > box_min[1] && x[1] < box_max[1] ) if ( x[2] > box_min[2] && x[2] < box_max[2] ) return 1 ; return 0 ; } ! float inside_sphere( uniform point sphere_position ; uniform float sphere_radius ; point x ) { if ( distance( x , sphere_position ) < sphere_radius ) return 1 ; return 0 ; } ! float inside_cone( uniform point cone_position ; uniform vector cone_direction ; uniform float cone_angle ; point x ) { color a = transmission( cone_position , x , "samples" , 1 ) ; float b = step( cos( radians( cone_angle ) * 0.5 ) , normalize( x - cone_position ) . normalize( cone_direction ) ) ; return a[0] * b ; } ! ////////////////////////////////////////// public void surface( output color Ci , Oi ; output color outputs[5] ; uniform float float_index = - 1 ; color color_index = 0 ) { point Pw = transform( "current" , "world" , P ) ; ! float choice = - 1 ; ! // jcubeToonNumericEvent1 // float jcubeToonNumericEvent1_outputs = - 1 ; uniform float jcubeToonNumericEvent1_first_term = 1.0 ; uniform float jcubeToonNumericEvent1_second_term = 4.0 ; uniform float jcubeToonNumericEvent1_if_palette = 1 ; // file2 uniform float jcubeToonNumericEvent1_else_palette = 2 ; // file1 if ( jcubeToonNumericEvent1_first_term > jcubeToonNumericEvent1_second_term ) { jcubeToonNumericEvent1_outputs = jcubeToonNumericEvent1_if_palette ; } else { jcubeToonNumericEvent1_outputs = jcubeToonNumericEvent1_else_palette ; } // jcubeToonRegionEvent2 // float jcubeToonRegionEvent2_outputs = - 1 ; point jcubeToonRegionEvent2_Pw = Pw ; float jcubeToonRegionEvent2_in_palette = jcubeToonNumericEvent1_outputs ; // jcubeToonNumericEvent1 uniform float jcubeToonRegionEvent2_out_palette = 0 ; // file3 uniform point jcubeToonRegionEvent2_box_min = point(-0.14332814514636993, 8.197878287319327e-08, -5.021854877471924) ; uniform point jcubeToonRegionEvent2_box_max = point(2.2686707973480225, 7.261795997619629, -1.861090064048767) ; if ( inside_box( jcubeToonRegionEvent2_box_min , jcubeToonRegionEvent2_box_max , jcubeToonRegionEvent2_Pw ) > 0 ) { jcubeToonRegionEvent2_outputs = jcubeToonRegionEvent2_in_palette ; } else { jcubeToonRegionEvent2_outputs = jcubeToonRegionEvent2_out_palette ; } choice = jcubeToonRegionEvent2_outputs ; if ( float_index > - 1 ) { Search( color_palettes[choice] , float_index , outputs ) ; } else { Search( color_palettes[choice] , color_index , outputs ) ; } } }
Sorry, a bit long then :)
Sponsored by SA2015.SIGGRAPH.ORG
Renderer
to the RSL-like renderer (3Delight) generate coshader invoked by shader as a black box
to the DSO renderer (mental ray) generate LLVM JIT code directly executed by shader as part of
the shader
Sponsored by SA2015.SIGGRAPH.ORG
Conclusion
advantage reusable network for similar objects much less composition work cover all most any situations
space-varying or time-varying
Sponsored by SA2015.SIGGRAPH.ORG
Future
get rid of color palette completely web+databased solution abstract color palette
mapping semantics color to anything replace color in cell with texture stream over
network interactive feedback when changing palette
Sponsored by SA2015.SIGGRAPH.ORG
Thanks ! Q&A