Merge pull request #1951 from MoritzBrueckner/cycles-nodes
More cycles nodes + improvements
This commit is contained in:
commit
800498a78e
|
@ -1,5 +1,6 @@
|
|||
import bpy
|
||||
|
||||
import arm.log as log
|
||||
import arm.material.cycles as c
|
||||
import arm.material.cycles_functions as c_functions
|
||||
from arm.material.parser_state import ParserState
|
||||
|
@ -42,49 +43,60 @@ def parse_invert(node: bpy.types.ShaderNodeInvert, out_socket: bpy.types.NodeSoc
|
|||
|
||||
|
||||
def parse_mixrgb(node: bpy.types.ShaderNodeMixRGB, out_socket: bpy.types.NodeSocket, state: ParserState) -> vec3str:
|
||||
fac = c.parse_value_input(node.inputs[0])
|
||||
fac_var = c.node_name(node.name) + '_fac'
|
||||
state.curshader.write('float {0} = {1};'.format(fac_var, fac))
|
||||
col1 = c.parse_vector_input(node.inputs[1])
|
||||
col2 = c.parse_vector_input(node.inputs[2])
|
||||
|
||||
# Store factor in variable for linked factor input
|
||||
if node.inputs[0].is_linked:
|
||||
fac = c.node_name(node.name) + '_fac'
|
||||
state.curshader.write('float {0} = {1};'.format(fac, c.parse_value_input(node.inputs[0])))
|
||||
else:
|
||||
fac = c.parse_value_input(node.inputs[0])
|
||||
|
||||
# TODO: Do not mix if factor is constant 0.0 or 1.0?
|
||||
|
||||
blend = node.blend_type
|
||||
if blend == 'MIX':
|
||||
out_col = 'mix({0}, {1}, {2})'.format(col1, col2, fac_var)
|
||||
out_col = 'mix({0}, {1}, {2})'.format(col1, col2, fac)
|
||||
elif blend == 'ADD':
|
||||
out_col = 'mix({0}, {0} + {1}, {2})'.format(col1, col2, fac_var)
|
||||
out_col = 'mix({0}, {0} + {1}, {2})'.format(col1, col2, fac)
|
||||
elif blend == 'MULTIPLY':
|
||||
out_col = 'mix({0}, {0} * {1}, {2})'.format(col1, col2, fac_var)
|
||||
out_col = 'mix({0}, {0} * {1}, {2})'.format(col1, col2, fac)
|
||||
elif blend == 'SUBTRACT':
|
||||
out_col = 'mix({0}, {0} - {1}, {2})'.format(col1, col2, fac_var)
|
||||
out_col = 'mix({0}, {0} - {1}, {2})'.format(col1, col2, fac)
|
||||
elif blend == 'SCREEN':
|
||||
out_col = '(vec3(1.0) - (vec3(1.0 - {2}) + {2} * (vec3(1.0) - {1})) * (vec3(1.0) - {0}))'.format(col1, col2, fac_var)
|
||||
out_col = '(vec3(1.0) - (vec3(1.0 - {2}) + {2} * (vec3(1.0) - {1})) * (vec3(1.0) - {0}))'.format(col1, col2, fac)
|
||||
elif blend == 'DIVIDE':
|
||||
out_col = '(vec3((1.0 - {2}) * {0} + {2} * {0} / {1}))'.format(col1, col2, fac_var)
|
||||
out_col = '(vec3((1.0 - {2}) * {0} + {2} * {0} / {1}))'.format(col1, col2, fac)
|
||||
elif blend == 'DIFFERENCE':
|
||||
out_col = 'mix({0}, abs({0} - {1}), {2})'.format(col1, col2, fac_var)
|
||||
out_col = 'mix({0}, abs({0} - {1}), {2})'.format(col1, col2, fac)
|
||||
elif blend == 'DARKEN':
|
||||
out_col = 'min({0}, {1} * {2})'.format(col1, col2, fac_var)
|
||||
out_col = 'min({0}, {1} * {2})'.format(col1, col2, fac)
|
||||
elif blend == 'LIGHTEN':
|
||||
out_col = 'max({0}, {1} * {2})'.format(col1, col2, fac_var)
|
||||
out_col = 'max({0}, {1} * {2})'.format(col1, col2, fac)
|
||||
elif blend == 'OVERLAY':
|
||||
out_col = 'mix({0}, {1}, {2})'.format(col1, col2, fac_var) # Revert to mix
|
||||
out_col = 'mix({0}, {1}, {2})'.format(col1, col2, fac) # Revert to mix
|
||||
elif blend == 'DODGE':
|
||||
out_col = 'mix({0}, {1}, {2})'.format(col1, col2, fac_var) # Revert to mix
|
||||
out_col = 'mix({0}, {1}, {2})'.format(col1, col2, fac) # Revert to mix
|
||||
elif blend == 'BURN':
|
||||
out_col = 'mix({0}, {1}, {2})'.format(col1, col2, fac_var) # Revert to mix
|
||||
out_col = 'mix({0}, {1}, {2})'.format(col1, col2, fac) # Revert to mix
|
||||
elif blend == 'HUE':
|
||||
out_col = 'mix({0}, {1}, {2})'.format(col1, col2, fac_var) # Revert to mix
|
||||
out_col = 'mix({0}, {1}, {2})'.format(col1, col2, fac) # Revert to mix
|
||||
elif blend == 'SATURATION':
|
||||
out_col = 'mix({0}, {1}, {2})'.format(col1, col2, fac_var) # Revert to mix
|
||||
out_col = 'mix({0}, {1}, {2})'.format(col1, col2, fac) # Revert to mix
|
||||
elif blend == 'VALUE':
|
||||
out_col = 'mix({0}, {1}, {2})'.format(col1, col2, fac_var) # Revert to mix
|
||||
out_col = 'mix({0}, {1}, {2})'.format(col1, col2, fac) # Revert to mix
|
||||
elif blend == 'COLOR':
|
||||
out_col = 'mix({0}, {1}, {2})'.format(col1, col2, fac_var) # Revert to mix
|
||||
out_col = 'mix({0}, {1}, {2})'.format(col1, col2, fac) # Revert to mix
|
||||
elif blend == 'SOFT_LIGHT':
|
||||
out_col = '((1.0 - {2}) * {0} + {2} * ((vec3(1.0) - {0}) * {1} * {0} + {0} * (vec3(1.0) - (vec3(1.0) - {1}) * (vec3(1.0) - {0}))));'.format(col1, col2, fac)
|
||||
elif blend == 'LINEAR_LIGHT':
|
||||
out_col = 'mix({0}, {1}, {2})'.format(col1, col2, fac_var) # Revert to mix
|
||||
out_col = 'mix({0}, {1}, {2})'.format(col1, col2, fac) # Revert to mix
|
||||
# out_col = '({0} + {2} * (2.0 * ({1} - vec3(0.5))))'.format(col1, col2, fac_var)
|
||||
else:
|
||||
log.warn(f'MixRGB node: unsupported blend type {node.blend_type}.')
|
||||
return col1
|
||||
|
||||
if node.use_clamp:
|
||||
return 'clamp({0}, vec3(0.0), vec3(1.0))'.format(out_col)
|
||||
return out_col
|
||||
|
@ -102,6 +114,5 @@ def parse_curvergb(node: bpy.types.ShaderNodeRGBCurve, out_socket: bpy.types.Nod
|
|||
|
||||
|
||||
def parse_lightfalloff(node: bpy.types.ShaderNodeLightFalloff, out_socket: bpy.types.NodeSocket, state: ParserState) -> floatstr:
|
||||
# Constant, linear, quadratic
|
||||
# Shaders default to quadratic for now
|
||||
return '1.0'
|
||||
# https://github.com/blender/blender/blob/master/source/blender/gpu/shaders/material/gpu_shader_material_light_falloff.glsl
|
||||
return c.parse_value_input(node.inputs['Strength'])
|
||||
|
|
|
@ -316,9 +316,18 @@ def parse_rgbtobw(node: bpy.types.ShaderNodeRGBToBW, out_socket: bpy.types.NodeS
|
|||
return '((({0}.r * 0.3 + {0}.g * 0.59 + {0}.b * 0.11) / 3.0) * 2.5)'.format(col)
|
||||
|
||||
|
||||
def parse_sephsv(node: bpy.types.ShaderNodeSeparateHSV, out_socket: bpy.types.NodeSocket) -> floatstr:
|
||||
# TODO
|
||||
return '0.0'
|
||||
def parse_sephsv(node: bpy.types.ShaderNodeSeparateHSV, out_socket: bpy.types.NodeSocket, state: ParserState) -> floatstr:
|
||||
state.curshader.add_function(c_functions.str_hue_sat)
|
||||
|
||||
hsv_var = c.node_name(node.name) + '_hsv'
|
||||
state.curshader.write(f'const vec3 {hsv_var} = rgb_to_hsv({c.parse_vector_input(node.inputs["Color"])}.rgb);')
|
||||
|
||||
if out_socket == node.outputs[0]:
|
||||
return f'{hsv_var}.x'
|
||||
elif out_socket == node.outputs[1]:
|
||||
return f'{hsv_var}.y'
|
||||
elif out_socket == node.outputs[2]:
|
||||
return f'{hsv_var}.z'
|
||||
|
||||
|
||||
def parse_seprgb(node: bpy.types.ShaderNodeSeparateRGB, out_socket: bpy.types.NodeSocket, state: ParserState) -> floatstr:
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import bpy
|
||||
from typing import Union
|
||||
|
||||
import arm.log as log
|
||||
import arm.material.cycles as c
|
||||
import arm.material.cycles_functions as c_functions
|
||||
from arm.material.parser_state import ParserState, ParserContext
|
||||
|
@ -213,6 +214,8 @@ def parse_texcoord(node: bpy.types.ShaderNodeTexCoord, out_socket: bpy.types.Nod
|
|||
if out_socket == node.outputs[0]: # Generated - bounds
|
||||
return 'bposition'
|
||||
elif out_socket == node.outputs[1]: # Normal
|
||||
if state.context == ParserContext.WORLD:
|
||||
return '-n'
|
||||
return 'n'
|
||||
elif out_socket == node.outputs[2]: # UV
|
||||
state.con.add_elem('tex', 'short2norm')
|
||||
|
@ -272,28 +275,36 @@ def parse_layerweight(node: bpy.types.ShaderNodeLayerWeight, out_socket: bpy.typ
|
|||
|
||||
|
||||
def parse_lightpath(node: bpy.types.ShaderNodeLightPath, out_socket: bpy.types.NodeSocket, state: ParserState) -> floatstr:
|
||||
if out_socket == node.outputs[0]: # Is Camera Ray
|
||||
# https://github.com/blender/blender/blob/master/source/blender/gpu/shaders/material/gpu_shader_material_light_path.glsl
|
||||
if out_socket == node.outputs['Is Camera Ray']:
|
||||
return '1.0'
|
||||
elif out_socket == node.outputs[1]: # Is Shadow Ray
|
||||
elif out_socket == node.outputs['Is Shadow Ray']:
|
||||
return '0.0'
|
||||
elif out_socket == node.outputs[2]: # Is Diffuse Ray
|
||||
elif out_socket == node.outputs['Is Diffuse Ray']:
|
||||
return '1.0'
|
||||
elif out_socket == node.outputs[3]: # Is Glossy Ray
|
||||
elif out_socket == node.outputs['Is Glossy Ray']:
|
||||
return '1.0'
|
||||
elif out_socket == node.outputs[4]: # Is Singular Ray
|
||||
elif out_socket == node.outputs['Is Singular Ray']:
|
||||
return '0.0'
|
||||
elif out_socket == node.outputs[5]: # Is Reflection Ray
|
||||
elif out_socket == node.outputs['Is Reflection Ray']:
|
||||
return '0.0'
|
||||
elif out_socket == node.outputs[6]: # Is Transmission Ray
|
||||
elif out_socket == node.outputs['Is Transmission Ray']:
|
||||
return '0.0'
|
||||
elif out_socket == node.outputs[7]: # Ray Length
|
||||
elif out_socket == node.outputs['Ray Length']:
|
||||
return '1.0'
|
||||
elif out_socket == node.outputs['Ray Depth']:
|
||||
return '0.0'
|
||||
elif out_socket == node.outputs[8]: # Ray Depth
|
||||
elif out_socket == node.outputs['Diffuse Depth']:
|
||||
return '0.0'
|
||||
elif out_socket == node.outputs[9]: # Transparent Depth
|
||||
elif out_socket == node.outputs['Glossy Depth']:
|
||||
return '0.0'
|
||||
elif out_socket == node.outputs[10]: # Transmission Depth
|
||||
elif out_socket == node.outputs['Transparent Depth']:
|
||||
return '0.0'
|
||||
elif out_socket == node.outputs['Transmission Depth']:
|
||||
return '0.0'
|
||||
|
||||
log.warn(f'Light Path node: unsupported output {out_socket.identifier}.')
|
||||
return '0.0'
|
||||
|
||||
|
||||
def parse_value(node: bpy.types.ShaderNodeValue, out_socket: bpy.types.NodeSocket, state: ParserState) -> floatstr:
|
||||
|
|
|
@ -266,7 +266,8 @@ def parse_tex_noise(node: bpy.types.ShaderNodeTexNoise, out_socket: bpy.types.No
|
|||
|
||||
scale = c.parse_value_input(node.inputs[2])
|
||||
detail = c.parse_value_input(node.inputs[3])
|
||||
distortion = c.parse_value_input(node.inputs[4])#
|
||||
roughness = c.parse_value_input(node.inputs[4])
|
||||
distortion = c.parse_value_input(node.inputs[5])
|
||||
|
||||
# Color
|
||||
if out_socket == node.outputs[1]:
|
||||
|
|
|
@ -106,11 +106,14 @@ def parse_mapping(node: bpy.types.ShaderNodeMapping, out_socket: bpy.types.NodeS
|
|||
|
||||
|
||||
def parse_normal(node: bpy.types.ShaderNodeNormal, out_socket: bpy.types.NodeSocket, state: ParserState) -> Union[floatstr, vec3str]:
|
||||
if out_socket == node.outputs[0]:
|
||||
return c.to_vec3(node.outputs[0].default_value)
|
||||
elif out_socket == node.outputs[1]: # TODO: is parse_value path preferred?
|
||||
nor = c.parse_vector_input(node.inputs[0])
|
||||
return f'dot({c.to_vec3(node.outputs[0].default_value)}, {nor})'
|
||||
nor1 = c.to_vec3(node.outputs['Normal'].default_value)
|
||||
|
||||
if out_socket == node.outputs['Normal']:
|
||||
return nor1
|
||||
|
||||
elif out_socket == node.outputs['Dot']:
|
||||
nor2 = c.parse_vector_input(node.inputs["Normal"])
|
||||
return f'dot({nor1}, {nor2})'
|
||||
|
||||
|
||||
def parse_normalmap(node: bpy.types.ShaderNodeNormalMap, out_socket: bpy.types.NodeSocket, state: ParserState) -> vec3str:
|
||||
|
|
Loading…
Reference in a new issue