@@ -410,20 +410,28 @@ class ShaderNodeBsdfVelvet(RuleNodeParser):
410410 # inputs: Color, Sigma
411411
412412 nodes = {
413+ "ONE_MINUS_SIGMA" : {
414+ "type" : "-" ,
415+ "params" : {
416+ pyrpr .MATERIAL_INPUT_COLOR0 : 1.0 ,
417+ pyrpr .MATERIAL_INPUT_COLOR1 : "inputs.Sigma" ,
418+ }
419+ },
420+
413421 "BSDF" : {
414422 "type" : pyrpr .MATERIAL_NODE_UBERV2 ,
415423 "params" : {
416424 pyrpr .MATERIAL_INPUT_UBER_DIFFUSE_COLOR : "inputs.Color" ,
417- pyrpr .MATERIAL_INPUT_UBER_DIFFUSE_WEIGHT : "inputs.Sigma " ,
425+ pyrpr .MATERIAL_INPUT_UBER_DIFFUSE_WEIGHT : "nodes.ONE_MINUS_SIGMA " ,
418426 pyrpr .MATERIAL_INPUT_UBER_DIFFUSE_NORMAL : "normal:inputs.Normal" ,
427+ pyrpr .MATERIAL_INPUT_UBER_DIFFUSE_ROUGHNESS : 1.0 ,
419428 pyrpr .MATERIAL_INPUT_UBER_REFLECTION_WEIGHT : 0.0 ,
420- pyrpr .MATERIAL_INPUT_UBER_SHEEN_WEIGHT : 1.0 ,
421- pyrpr .MATERIAL_INPUT_UBER_SHEEN_TINT : "inputs.Sigma" ,
429+ pyrpr .MATERIAL_INPUT_UBER_SHEEN_WEIGHT : "inputs.Sigma" ,
430+ pyrpr .MATERIAL_INPUT_UBER_SHEEN_TINT : 1.0 ,
422431 pyrpr .MATERIAL_INPUT_UBER_SHEEN : "inputs.Color"
423432 }
424433 }
425434 }
426- # TODO: Has to be fixed, probably diffuse is not needed here
427435
428436
429437class ShaderNodeEmission (RuleNodeParser ):
@@ -861,28 +869,37 @@ def export(self):
861869 base_color = self .get_input_value ('Color' )
862870
863871 rotation_angle = self .get_input_value ('Offset' )
864- roughness_u = self .get_input_value ('RoughnessU' )
865- roughness_v = self .get_input_value ('RoughnessV' )
872+ roughness_u = self .get_input_value ('RoughnessU' ). clamp ( 0.001 , 1.0 )
873+ roughness_v = self .get_input_value ('RoughnessV' ). clamp ( 0.001 , 1.0 )
866874
867875 # TODO: use Tangent input
868876
869877 # Treat reflection as WARD shader
870878 if component == 'Reflection' :
871- rpr_node = self .create_node (pyrpr .MATERIAL_NODE_WARD )
872- rpr_node .set_input (pyrpr .MATERIAL_INPUT_ROUGHNESS_X , roughness_u )
873- rpr_node .set_input (pyrpr .MATERIAL_INPUT_ROUGHNESS_Y , roughness_v )
874- rpr_node .set_input (pyrpr .MATERIAL_INPUT_ROTATION , rotation_angle )
875- rpr_node .set_input (pyrpr .MATERIAL_INPUT_COLOR , base_color )
879+ rpr_node = self ._create_ward_node (base_color , roughness_u , roughness_v , rotation_angle )
880+ else :
881+ roughness = (roughness_u + roughness_v ) * 0.5
882+ rpr_node = self ._create_transmission_node (base_color , roughness )
883+
884+ return rpr_node
885+
886+ def export_rpr2 (self ):
887+ component = self .node .component
888+ base_color = self .get_input_value ('Color' )
889+
890+ rotation_angle = self .get_input_value ('Offset' )
891+ roughness_u = self .get_input_value ('RoughnessU' ).clamp (0.001 , 1.0 )
892+ roughness_v = self .get_input_value ('RoughnessV' ).clamp (0.001 , 1.0 )
893+
894+ # Treat reflection as and Uber shader with anisotropic reflection
895+ if component == 'Reflection' :
896+ rotation_angle = 0.5 - rotation_angle % math .pi # fit angle to the range [-0.5..+0.5]
876897
898+ rpr_node = self ._create_aniso_reflection_node (base_color , roughness_u , roughness_v ,
899+ rotation_angle )
877900 else :
878- rpr_node = self .create_node (pyrpr .MATERIAL_NODE_UBERV2 , {
879- pyrpr .MATERIAL_INPUT_UBER_DIFFUSE_WEIGHT : 0.0 ,
880- pyrpr .MATERIAL_INPUT_UBER_DIFFUSE_COLOR : base_color ,
881- pyrpr .MATERIAL_INPUT_UBER_DIFFUSE_ROUGHNESS : 1.0 ,
882- pyrpr .MATERIAL_INPUT_UBER_REFLECTION_WEIGHT : 0.0 ,
883- pyrpr .MATERIAL_INPUT_UBER_BACKSCATTER_WEIGHT : 1.0 ,
884- pyrpr .MATERIAL_INPUT_UBER_BACKSCATTER_COLOR : base_color ,
885- })
901+ roughness = (roughness_u + roughness_v ) * 0.5
902+ rpr_node = self ._create_transmission_node (base_color , roughness )
886903
887904 return rpr_node
888905
@@ -894,7 +911,7 @@ def export_hybrid(self):
894911
895912 rpr_node = self .create_node (pyrpr .MATERIAL_NODE_UBERV2 )
896913 rpr_node .set_input (pyrpr .MATERIAL_INPUT_UBER_DIFFUSE_WEIGHT , 0.0 )
897-
914+
898915 if component == 'Reflection' :
899916 rpr_node .set_input (pyrpr .MATERIAL_INPUT_UBER_REFLECTION_WEIGHT , 1.0 )
900917 rpr_node .set_input (pyrpr .MATERIAL_INPUT_UBER_REFLECTION_COLOR , color )
@@ -904,6 +921,53 @@ def export_hybrid(self):
904921
905922 return rpr_node
906923
924+ def _create_ward_node (self , base_color , roughness_u , roughness_v , rotation_angle ):
925+ rpr_node = self .create_node (pyrpr .MATERIAL_NODE_WARD )
926+ rpr_node .set_input (pyrpr .MATERIAL_INPUT_ROUGHNESS_X , roughness_u )
927+ rpr_node .set_input (pyrpr .MATERIAL_INPUT_ROUGHNESS_Y , roughness_v )
928+ rpr_node .set_input (pyrpr .MATERIAL_INPUT_ROTATION , rotation_angle )
929+ rpr_node .set_input (pyrpr .MATERIAL_INPUT_COLOR , base_color )
930+ return rpr_node
931+
932+ def _create_aniso_reflection_node (self , base_color , roughness_u , roughness_v , rotation_angle ):
933+ rotation_angle = 0.5 - rotation_angle % math .pi # fit angle to the range [-0.5..+0.5]
934+
935+ rough_max = roughness_v .max (roughness_u )
936+ rough_min = roughness_v .min (roughness_u )
937+
938+ anisotropy = 0
939+ if not roughness_u .data == roughness_v .data :
940+ anisotropy = (rough_max - rough_min ).clamp (0.001 , 1.0 ) # limit anisotropy amount
941+
942+ # a rough approximation of reflection roughness
943+ rough_med = (roughness_u + roughness_v ) * 0.5
944+ rough_aniso = (rough_min + rough_med ) * 0.5
945+
946+ rpr_node = self .create_node (pyrpr .MATERIAL_NODE_UBERV2 )
947+ rpr_node .set_input (pyrpr .MATERIAL_INPUT_UBER_DIFFUSE_WEIGHT , 0.0 )
948+
949+ rpr_node .set_input (pyrpr .MATERIAL_INPUT_UBER_REFLECTION_WEIGHT , 1.0 )
950+ rpr_node .set_input (pyrpr .MATERIAL_INPUT_UBER_REFLECTION_COLOR , base_color )
951+ rpr_node .set_input (pyrpr .MATERIAL_INPUT_UBER_REFLECTION_ROUGHNESS , rough_aniso )
952+ rpr_node .set_input (pyrpr .MATERIAL_INPUT_UBER_REFLECTION_ANISOTROPY , anisotropy )
953+ rpr_node .set_input (pyrpr .MATERIAL_INPUT_UBER_REFLECTION_ANISOTROPY_ROTATION , rotation_angle )
954+ rpr_node .set_input (pyrpr .MATERIAL_INPUT_UBER_REFLECTION_MODE ,
955+ pyrpr .UBER_MATERIAL_IOR_MODE_METALNESS )
956+ rpr_node .set_input (pyrpr .MATERIAL_INPUT_UBER_REFLECTION_METALNESS , 1.0 )
957+
958+ return rpr_node
959+
960+ def _create_transmission_node (self , base_color , roughness ):
961+ rpr_node = self .create_node (pyrpr .MATERIAL_NODE_UBERV2 , {
962+ pyrpr .MATERIAL_INPUT_UBER_DIFFUSE_WEIGHT : 0.0 ,
963+ pyrpr .MATERIAL_INPUT_UBER_DIFFUSE_COLOR : base_color ,
964+ pyrpr .MATERIAL_INPUT_UBER_DIFFUSE_ROUGHNESS : roughness ,
965+ pyrpr .MATERIAL_INPUT_UBER_REFLECTION_WEIGHT : 0.0 ,
966+ pyrpr .MATERIAL_INPUT_UBER_BACKSCATTER_WEIGHT : 1.0 ,
967+ pyrpr .MATERIAL_INPUT_UBER_BACKSCATTER_COLOR : base_color ,
968+ })
969+ return rpr_node
970+
907971
908972class ShaderNodeNewGeometry (RuleNodeParser ):
909973 # outputs: Position, Normal, Tangent, True Normal, Incoming, Parametric, Backfacing, Pointiness
0 commit comments