2020-10-05 01:36:33 +02:00
|
|
|
import bpy
|
|
|
|
|
2020-10-23 16:40:02 +02:00
|
|
|
import arm.log as log
|
2020-10-08 21:03:14 +02:00
|
|
|
import arm.material.cycles as c
|
2020-10-05 01:36:33 +02:00
|
|
|
import arm.material.cycles_functions as c_functions
|
2020-10-08 21:03:14 +02:00
|
|
|
from arm.material.parser_state import ParserState
|
2020-10-05 23:37:48 +02:00
|
|
|
from arm.material.shader import floatstr, vec3str
|
2020-10-05 01:36:33 +02:00
|
|
|
|
|
|
|
|
2020-10-08 21:03:14 +02:00
|
|
|
def parse_brightcontrast(node: bpy.types.ShaderNodeBrightContrast, out_socket: bpy.types.NodeSocket, state: ParserState) -> vec3str:
|
|
|
|
out_col = c.parse_vector_input(node.inputs[0])
|
|
|
|
bright = c.parse_value_input(node.inputs[1])
|
|
|
|
contr = c.parse_value_input(node.inputs[2])
|
2020-10-05 01:36:33 +02:00
|
|
|
|
2020-10-08 21:03:14 +02:00
|
|
|
state.curshader.add_function(c_functions.str_brightcontrast)
|
2020-10-05 01:36:33 +02:00
|
|
|
|
|
|
|
return 'brightcontrast({0}, {1}, {2})'.format(out_col, bright, contr)
|
|
|
|
|
|
|
|
|
2020-10-08 21:03:14 +02:00
|
|
|
def parse_gamma(node: bpy.types.ShaderNodeGamma, out_socket: bpy.types.NodeSocket, state: ParserState) -> vec3str:
|
|
|
|
out_col = c.parse_vector_input(node.inputs[0])
|
|
|
|
gamma = c.parse_value_input(node.inputs[1])
|
2020-10-05 01:36:33 +02:00
|
|
|
|
|
|
|
return 'pow({0}, vec3({1}))'.format(out_col, gamma)
|
|
|
|
|
|
|
|
|
2020-10-08 21:03:14 +02:00
|
|
|
def parse_huesat(node: bpy.types.ShaderNodeHueSaturation, out_socket: bpy.types.NodeSocket, state: ParserState) -> vec3str:
|
|
|
|
state.curshader.add_function(c_functions.str_hue_sat)
|
|
|
|
hue = c.parse_value_input(node.inputs[0])
|
|
|
|
sat = c.parse_value_input(node.inputs[1])
|
|
|
|
val = c.parse_value_input(node.inputs[2])
|
|
|
|
fac = c.parse_value_input(node.inputs[3])
|
|
|
|
col = c.parse_vector_input(node.inputs[4])
|
2020-10-05 01:36:33 +02:00
|
|
|
|
|
|
|
return f'hue_sat({col}, vec4({hue}-0.5, {sat}, {val}, 1.0-{fac}))'
|
|
|
|
|
|
|
|
|
2020-10-08 21:03:14 +02:00
|
|
|
def parse_invert(node: bpy.types.ShaderNodeInvert, out_socket: bpy.types.NodeSocket, state: ParserState) -> vec3str:
|
|
|
|
fac = c.parse_value_input(node.inputs[0])
|
|
|
|
out_col = c.parse_vector_input(node.inputs[1])
|
2020-10-05 01:36:33 +02:00
|
|
|
|
|
|
|
return f'mix({out_col}, vec3(1.0) - ({out_col}), {fac})'
|
|
|
|
|
|
|
|
|
2020-10-08 21:03:14 +02:00
|
|
|
def parse_mixrgb(node: bpy.types.ShaderNodeMixRGB, out_socket: bpy.types.NodeSocket, state: ParserState) -> vec3str:
|
|
|
|
col1 = c.parse_vector_input(node.inputs[1])
|
|
|
|
col2 = c.parse_vector_input(node.inputs[2])
|
2020-10-23 16:40:02 +02:00
|
|
|
|
|
|
|
# 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?
|
|
|
|
|
2020-10-05 01:36:33 +02:00
|
|
|
blend = node.blend_type
|
|
|
|
if blend == 'MIX':
|
2020-10-23 16:40:02 +02:00
|
|
|
out_col = 'mix({0}, {1}, {2})'.format(col1, col2, fac)
|
2020-10-05 01:36:33 +02:00
|
|
|
elif blend == 'ADD':
|
2020-10-23 16:40:02 +02:00
|
|
|
out_col = 'mix({0}, {0} + {1}, {2})'.format(col1, col2, fac)
|
2020-10-05 01:36:33 +02:00
|
|
|
elif blend == 'MULTIPLY':
|
2020-10-23 16:40:02 +02:00
|
|
|
out_col = 'mix({0}, {0} * {1}, {2})'.format(col1, col2, fac)
|
2020-10-05 01:36:33 +02:00
|
|
|
elif blend == 'SUBTRACT':
|
2020-10-23 16:40:02 +02:00
|
|
|
out_col = 'mix({0}, {0} - {1}, {2})'.format(col1, col2, fac)
|
2020-10-05 01:36:33 +02:00
|
|
|
elif blend == 'SCREEN':
|
2020-10-23 16:40:02 +02:00
|
|
|
out_col = '(vec3(1.0) - (vec3(1.0 - {2}) + {2} * (vec3(1.0) - {1})) * (vec3(1.0) - {0}))'.format(col1, col2, fac)
|
2020-10-05 01:36:33 +02:00
|
|
|
elif blend == 'DIVIDE':
|
2020-10-23 16:40:02 +02:00
|
|
|
out_col = '(vec3((1.0 - {2}) * {0} + {2} * {0} / {1}))'.format(col1, col2, fac)
|
2020-10-05 01:36:33 +02:00
|
|
|
elif blend == 'DIFFERENCE':
|
2020-10-23 16:40:02 +02:00
|
|
|
out_col = 'mix({0}, abs({0} - {1}), {2})'.format(col1, col2, fac)
|
2020-10-05 01:36:33 +02:00
|
|
|
elif blend == 'DARKEN':
|
2020-10-23 16:40:02 +02:00
|
|
|
out_col = 'min({0}, {1} * {2})'.format(col1, col2, fac)
|
2020-10-05 01:36:33 +02:00
|
|
|
elif blend == 'LIGHTEN':
|
2020-10-23 16:40:02 +02:00
|
|
|
out_col = 'max({0}, {1} * {2})'.format(col1, col2, fac)
|
2020-10-05 01:36:33 +02:00
|
|
|
elif blend == 'OVERLAY':
|
2020-10-23 16:40:02 +02:00
|
|
|
out_col = 'mix({0}, {1}, {2})'.format(col1, col2, fac) # Revert to mix
|
2020-10-05 01:36:33 +02:00
|
|
|
elif blend == 'DODGE':
|
2020-10-23 16:40:02 +02:00
|
|
|
out_col = 'mix({0}, {1}, {2})'.format(col1, col2, fac) # Revert to mix
|
2020-10-05 01:36:33 +02:00
|
|
|
elif blend == 'BURN':
|
2020-10-23 16:40:02 +02:00
|
|
|
out_col = 'mix({0}, {1}, {2})'.format(col1, col2, fac) # Revert to mix
|
2020-10-05 01:36:33 +02:00
|
|
|
elif blend == 'HUE':
|
2020-10-23 16:40:02 +02:00
|
|
|
out_col = 'mix({0}, {1}, {2})'.format(col1, col2, fac) # Revert to mix
|
2020-10-05 01:36:33 +02:00
|
|
|
elif blend == 'SATURATION':
|
2020-10-23 16:40:02 +02:00
|
|
|
out_col = 'mix({0}, {1}, {2})'.format(col1, col2, fac) # Revert to mix
|
2020-10-05 01:36:33 +02:00
|
|
|
elif blend == 'VALUE':
|
2020-10-23 16:40:02 +02:00
|
|
|
out_col = 'mix({0}, {1}, {2})'.format(col1, col2, fac) # Revert to mix
|
2020-10-05 01:36:33 +02:00
|
|
|
elif blend == 'COLOR':
|
2020-10-23 16:40:02 +02:00
|
|
|
out_col = 'mix({0}, {1}, {2})'.format(col1, col2, fac) # Revert to mix
|
2020-10-05 01:36:33 +02:00
|
|
|
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':
|
2020-10-23 16:40:02 +02:00
|
|
|
out_col = 'mix({0}, {1}, {2})'.format(col1, col2, fac) # Revert to mix
|
2020-10-05 01:36:33 +02:00
|
|
|
# out_col = '({0} + {2} * (2.0 * ({1} - vec3(0.5))))'.format(col1, col2, fac_var)
|
2020-10-23 16:40:02 +02:00
|
|
|
else:
|
|
|
|
log.warn(f'MixRGB node: unsupported blend type {node.blend_type}.')
|
|
|
|
return col1
|
|
|
|
|
2020-10-05 01:36:33 +02:00
|
|
|
if node.use_clamp:
|
|
|
|
return 'clamp({0}, vec3(0.0), vec3(1.0))'.format(out_col)
|
|
|
|
return out_col
|
|
|
|
|
|
|
|
|
2020-10-08 21:03:14 +02:00
|
|
|
def parse_curvergb(node: bpy.types.ShaderNodeRGBCurve, out_socket: bpy.types.NodeSocket, state: ParserState) -> vec3str:
|
|
|
|
fac = c.parse_value_input(node.inputs[0])
|
|
|
|
vec = c.parse_vector_input(node.inputs[1])
|
2020-10-05 01:36:33 +02:00
|
|
|
curves = node.mapping.curves
|
2020-10-08 21:03:14 +02:00
|
|
|
name = c.node_name(node.name)
|
2020-10-05 01:36:33 +02:00
|
|
|
# mapping.curves[0].points[0].handle_type
|
|
|
|
return '(sqrt(vec3({0}, {1}, {2}) * vec3({4}, {5}, {6})) * {3})'.format(
|
2020-10-08 21:03:14 +02:00
|
|
|
c.vector_curve(name + '0', vec + '.x', curves[0].points), c.vector_curve(name + '1', vec + '.y', curves[1].points), c.vector_curve(name + '2', vec + '.z', curves[2].points), fac,
|
|
|
|
c.vector_curve(name + '3a', vec + '.x', curves[3].points), c.vector_curve(name + '3b', vec + '.y', curves[3].points), c.vector_curve(name + '3c', vec + '.z', curves[3].points))
|
2020-10-05 23:37:48 +02:00
|
|
|
|
|
|
|
|
2020-10-08 21:03:14 +02:00
|
|
|
def parse_lightfalloff(node: bpy.types.ShaderNodeLightFalloff, out_socket: bpy.types.NodeSocket, state: ParserState) -> floatstr:
|
2020-10-23 16:23:56 +02:00
|
|
|
# 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'])
|