armory/blender/nodes_renderpath.py

879 lines
29 KiB
Python
Raw Normal View History

2016-01-26 14:36:55 +01:00
import bpy
from bpy.types import NodeTree, Node, NodeSocket
from bpy.props import *
2016-10-27 01:11:11 +02:00
import armutils
2016-05-18 01:34:21 +02:00
2016-01-26 14:36:55 +01:00
class CGPipelineTree(NodeTree):
2016-09-23 00:34:42 +02:00
'''Render path nodes'''
2016-07-10 00:51:39 +02:00
bl_idname = 'CGPipelineTreeType'
2016-08-11 22:24:45 +02:00
bl_label = 'Render Path Node Tree'
2016-08-21 00:16:13 +02:00
bl_icon = 'SCENE'
2016-01-26 14:36:55 +01:00
class CGPipelineTreeNode:
2016-07-10 00:51:39 +02:00
@classmethod
def poll(cls, ntree):
return ntree.bl_idname == 'CGPipelineTreeType'
# Prebuilt
class QuadPassNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Full-screen quad pass node'''
2016-07-10 00:51:39 +02:00
bl_idname = 'QuadPassNodeType'
bl_label = 'Quad Pass'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
self.inputs.new('NodeSocketShader', "Target")
self.inputs.new('NodeSocketString', "Shader Context")
self.inputs.new('NodeSocketShader', "Bind 1")
self.inputs.new('NodeSocketString', "Constant")
self.inputs.new('NodeSocketShader', "Bind 2")
self.inputs.new('NodeSocketString', "Constant")
self.inputs.new('NodeSocketShader', "Bind 3")
self.inputs.new('NodeSocketString', "Constant")
self.outputs.new('NodeSocketShader', "Stage")
class SSAOPassNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Screen-space ambient occlusion node'''
2016-07-10 00:51:39 +02:00
bl_idname = 'SSAOPassNodeType'
bl_label = 'SSAO'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
self.inputs.new('NodeSocketShader', "Target")
2016-08-07 01:43:21 +02:00
self.inputs.new('NodeSocketShader', "A")
self.inputs.new('NodeSocketShader', "GBufferD")
self.inputs.new('NodeSocketShader', "GBuffer0")
self.outputs.new('NodeSocketShader', "Stage")
2016-08-09 23:51:40 +02:00
class SSAOReprojectPassNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Screen-space ambient occlusion reprojection node'''
2016-08-09 23:51:40 +02:00
bl_idname = 'SSAOReprojectPassNodeType'
bl_label = 'SSAO Reproject'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
self.inputs.new('NodeSocketShader', "Target")
self.inputs.new('NodeSocketShader', "Last")
self.inputs.new('NodeSocketShader', "Depth")
self.inputs.new('NodeSocketShader', "Normals")
self.inputs.new('NodeSocketShader', "Velocity")
self.outputs.new('NodeSocketShader', "Stage")
2016-08-07 01:43:21 +02:00
class ApplySSAOPassNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Apply screen-space ambient occlusion node'''
2016-08-07 01:43:21 +02:00
bl_idname = 'ApplySSAOPassNodeType'
bl_label = 'Apply SSAO'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
self.inputs.new('NodeSocketShader', "Target")
self.inputs.new('NodeSocketShader', "A")
self.inputs.new('NodeSocketShader', "B")
2016-07-10 00:51:39 +02:00
self.inputs.new('NodeSocketShader', "GBufferD")
self.inputs.new('NodeSocketShader', "GBuffer0")
self.outputs.new('NodeSocketShader', "Stage")
class SSRPassNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Screen-space reflections node'''
2016-07-10 00:51:39 +02:00
bl_idname = 'SSRPassNodeType'
bl_label = 'SSR'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
self.inputs.new('NodeSocketShader', "Target")
self.inputs.new('NodeSocketShader', "A")
self.inputs.new('NodeSocketShader', "B")
self.inputs.new('NodeSocketShader', "Color")
2016-08-07 01:43:21 +02:00
self.inputs.new('NodeSocketShader', "GBufferD")
self.inputs.new('NodeSocketShader', "GBuffer0")
2016-07-10 00:51:39 +02:00
self.outputs.new('NodeSocketShader', "Stage")
class BloomPassNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Bloom node'''
2016-07-10 00:51:39 +02:00
bl_idname = 'BloomPassNodeType'
bl_label = 'Bloom'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
self.inputs.new('NodeSocketShader', "Target")
self.inputs.new('NodeSocketShader', "A")
self.inputs.new('NodeSocketShader', "B")
self.inputs.new('NodeSocketShader', "Color")
self.outputs.new('NodeSocketShader', "Stage")
class MotionBlurPassNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Motion blur node'''
2016-07-10 00:51:39 +02:00
bl_idname = 'MotionBlurPassNodeType'
bl_label = 'Motion Blur'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
self.inputs.new('NodeSocketShader', "Target")
self.inputs.new('NodeSocketShader', "Color")
self.inputs.new('NodeSocketShader', "GBufferD")
self.inputs.new('NodeSocketShader', "GBuffer0")
self.outputs.new('NodeSocketShader', "Stage")
2016-07-31 23:25:33 +02:00
class MotionBlurVelocityPassNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Motion blur using velocity node'''
2016-07-31 23:25:33 +02:00
bl_idname = 'MotionBlurVelocityPassNodeType'
bl_label = 'Motion Blur Velocity'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
self.inputs.new('NodeSocketShader', "Target")
self.inputs.new('NodeSocketShader', "Color")
self.inputs.new('NodeSocketShader', "GBuffer0")
self.inputs.new('NodeSocketShader', "Velocity")
self.outputs.new('NodeSocketShader', "Stage")
2016-07-24 19:15:36 +02:00
class CopyPassNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Copy to render target node'''
2016-07-24 19:15:36 +02:00
bl_idname = 'CopyPassNodeType'
bl_label = 'Copy'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
self.inputs.new('NodeSocketShader', "Target")
self.inputs.new('NodeSocketShader', "Color")
self.outputs.new('NodeSocketShader', "Stage")
2016-08-07 01:43:21 +02:00
class BlendPassNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Blend to target node'''
2016-08-07 01:43:21 +02:00
bl_idname = 'BlendPassNodeType'
bl_label = 'Blend'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
self.inputs.new('NodeSocketShader', "Target")
self.inputs.new('NodeSocketShader', "Color")
self.outputs.new('NodeSocketShader', "Stage")
class CombinePassNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Add two render targets node'''
2016-08-07 01:43:21 +02:00
bl_idname = 'CombinePassNodeType'
bl_label = 'Combine'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
self.inputs.new('NodeSocketShader', "Target")
self.inputs.new('NodeSocketShader', "A")
self.inputs.new('NodeSocketShader', "B")
self.outputs.new('NodeSocketShader', "Stage")
2016-07-24 19:15:36 +02:00
class BlurBasicPassNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Blur node'''
2016-07-24 19:15:36 +02:00
bl_idname = 'BlurBasicPassNodeType'
bl_label = 'Blur Basic'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
self.inputs.new('NodeSocketShader', "In/Out")
self.inputs.new('NodeSocketShader', "Temp")
self.outputs.new('NodeSocketShader', "Stage")
class DebugNormalsPassNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''View normals node'''
2016-07-24 19:15:36 +02:00
bl_idname = 'DebugNormalsPassNodeType'
bl_label = 'Debug Normals'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
self.inputs.new('NodeSocketShader', "Target")
self.inputs.new('NodeSocketShader', "Color")
self.outputs.new('NodeSocketShader', "Stage")
2016-07-10 00:51:39 +02:00
class FXAAPassNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''FXAA anti-aliasing node'''
2016-07-10 00:51:39 +02:00
bl_idname = 'FXAAPassNodeType'
bl_label = 'FXAA'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
self.inputs.new('NodeSocketShader', "Target")
self.inputs.new('NodeSocketShader', "Color")
self.outputs.new('NodeSocketShader', "Stage")
class SMAAPassNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Subpixel morphological anti-aliasing node'''
2016-07-10 00:51:39 +02:00
bl_idname = 'SMAAPassNodeType'
bl_label = 'SMAA'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
self.inputs.new('NodeSocketShader', "Target")
self.inputs.new('NodeSocketShader', "Edges Target")
self.inputs.new('NodeSocketShader', "Blend Target")
self.inputs.new('NodeSocketShader', "Color")
2016-07-31 23:25:33 +02:00
self.inputs.new('NodeSocketShader', "Velocity")
2016-07-10 00:51:39 +02:00
self.outputs.new('NodeSocketShader', "Stage")
2016-07-28 13:21:27 +02:00
class TAAPassNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Temporal anti-aliasing node'''
2016-07-28 13:21:27 +02:00
bl_idname = 'TAAPassNodeType'
bl_label = 'TAA'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
self.inputs.new('NodeSocketShader', "Target")
self.inputs.new('NodeSocketShader', "Color")
self.inputs.new('NodeSocketShader', "Last Color")
self.inputs.new('NodeSocketShader', "Velocity")
self.outputs.new('NodeSocketShader', "Stage")
2016-07-10 00:51:39 +02:00
class SSSPassNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Subsurface scattering node'''
2016-07-10 00:51:39 +02:00
bl_idname = 'SSSPassNodeType'
bl_label = 'SSS'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
self.inputs.new('NodeSocketShader', "Target In")
self.inputs.new('NodeSocketShader', "Target Out")
self.inputs.new('NodeSocketShader', "Color")
self.inputs.new('NodeSocketShader', "GBufferD")
self.inputs.new('NodeSocketShader', "GBuffer0")
self.outputs.new('NodeSocketShader', "Stage")
class WaterPassNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Ocean node'''
2016-07-10 00:51:39 +02:00
bl_idname = 'WaterPassNodeType'
bl_label = 'Water'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
self.inputs.new('NodeSocketShader', "Target")
self.inputs.new('NodeSocketShader', "Color")
self.inputs.new('NodeSocketShader', "GBufferD")
self.outputs.new('NodeSocketShader', "Stage")
class DeferredLightPassNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Deferred light node'''
2016-07-10 00:51:39 +02:00
bl_idname = 'DeferredLightPassNodeType'
bl_label = 'Deferred Light'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
self.inputs.new('NodeSocketShader', "Target")
self.inputs.new('NodeSocketShader', "GBuffer")
self.inputs.new('NodeSocketShader', "Shadow Map")
self.outputs.new('NodeSocketShader', "Stage")
2016-08-09 23:51:40 +02:00
class DeferredIndirectPassNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Deferred indirect lighting node'''
2016-08-09 23:51:40 +02:00
bl_idname = 'DeferredIndirectPassNodeType'
bl_label = 'Deferred Indirect'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
self.inputs.new('NodeSocketShader', "Target")
self.inputs.new('NodeSocketShader', "GBuffer")
self.inputs.new('NodeSocketShader', "SSAO")
2016-10-09 16:06:18 +02:00
# Testing voxels
# self.inputs.new('NodeSocketShader', "Voxels")
2016-08-09 23:51:40 +02:00
self.outputs.new('NodeSocketShader', "Stage")
2016-08-31 00:46:10 +02:00
class VolumetricLightPassNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Volumetric light node'''
2016-08-31 00:46:10 +02:00
bl_idname = 'VolumetricLightPassNodeType'
bl_label = 'Volumetric Light'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
self.inputs.new('NodeSocketShader', "Target")
self.inputs.new('NodeSocketShader', "A")
self.inputs.new('NodeSocketShader', "B")
self.inputs.new('NodeSocketShader', "Normals")
self.inputs.new('NodeSocketShader', "Depth")
self.inputs.new('NodeSocketShader', "Shadow Map")
self.outputs.new('NodeSocketShader', "Stage")
2016-07-10 00:51:39 +02:00
class TranslucentResolvePassNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Translucent resolve node'''
2016-07-10 00:51:39 +02:00
bl_idname = 'TranslucentResolvePassNodeType'
bl_label = 'Translucent Resolve'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
self.inputs.new('NodeSocketShader', "Target")
self.inputs.new('NodeSocketShader', "Translucent GBuffer")
self.outputs.new('NodeSocketShader', "Stage")
# Render path
2016-08-25 00:26:01 +02:00
class DrawMeshesNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Draw meshes of specified context node'''
2016-08-25 00:26:01 +02:00
bl_idname = 'DrawMeshesNodeType'
bl_label = 'Draw Meshes'
2016-07-10 00:51:39 +02:00
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
self.inputs.new('NodeSocketString', "Context")
self.inputs.new('NodeSocketString', "Order")
self.inputs[2].default_value = 'front_to_back'
2016-07-10 00:51:39 +02:00
self.outputs.new('NodeSocketShader', "Stage")
2016-05-18 01:34:21 +02:00
class DrawDecalsNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Draw decals node'''
2016-07-10 00:51:39 +02:00
bl_idname = 'DrawDecalsNodeType'
bl_label = 'Draw Decals'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
self.inputs.new('NodeSocketString', "Context")
self.outputs.new('NodeSocketShader', "Stage")
2016-01-26 14:36:55 +01:00
class ClearTargetNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Clear current target node'''
2016-07-10 00:51:39 +02:00
bl_idname = 'ClearTargetNodeType'
bl_label = 'Clear Target'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
self.inputs.new('NodeSocketBool', "Color")
self.inputs.new('NodeSocketColor', "Value")
self.inputs.new('NodeSocketBool', "Depth")
self.inputs.new('NodeSocketFloat', "Value")
self.inputs[4].default_value = 1.0
self.inputs.new('NodeSocketBool', "Stencil")
self.inputs.new('NodeSocketInt', "Value")
self.outputs.new('NodeSocketShader', "Stage")
2016-10-09 16:06:18 +02:00
class GenerateMipmapsNode(Node, CGPipelineTreeNode):
'''Generate mipmaps node'''
bl_idname = 'GenerateMipmapsNodeType'
bl_label = 'Generate Mipmaps'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
self.inputs.new('NodeSocketShader', "Target")
self.outputs.new('NodeSocketShader', "Stage")
class BeginNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Start render path node'''
2016-07-10 00:51:39 +02:00
bl_idname = 'BeginNodeType'
bl_label = 'Begin'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketString', "ID")
2016-08-25 00:26:01 +02:00
self.inputs.new('NodeSocketString', "Mesh")
2016-07-10 00:51:39 +02:00
self.inputs.new('NodeSocketString', "Shadows")
self.inputs.new('NodeSocketString', "Translucent")
2016-07-21 11:22:34 +02:00
self.inputs.new('NodeSocketString', "Overlay")
2016-07-12 12:03:43 +02:00
self.inputs.new('NodeSocketBool', "HDR Space")
2016-07-21 11:22:34 +02:00
self.inputs[5].default_value = True
2016-07-10 00:51:39 +02:00
self.outputs.new('NodeSocketShader', "Stage")
2016-01-26 14:36:55 +01:00
class SetTargetNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Set render target node'''
2016-07-10 00:51:39 +02:00
bl_idname = 'SetTargetNodeType'
bl_label = 'Set Target'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
self.inputs.new('NodeSocketShader', "Target")
self.outputs.new('NodeSocketShader', "Stage")
2016-10-09 16:06:18 +02:00
class SetViewportNode(Node, CGPipelineTreeNode):
'''Set viewport size node'''
bl_idname = 'SetViewportNodeType'
bl_label = 'Set Viewport'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
self.inputs.new('NodeSocketInt', "Width")
self.inputs.new('NodeSocketInt', "Height")
self.outputs.new('NodeSocketShader', "Stage")
2016-01-26 14:36:55 +01:00
class TargetNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Create new render target node'''
2016-07-10 00:51:39 +02:00
bl_idname = 'TargetNodeType'
bl_label = 'Target'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketString', "ID")
self.inputs.new('NodeSocketInt', "Width")
self.inputs.new('NodeSocketInt', "Height")
self.inputs.new('NodeSocketShader', "Depth Buffer")
self.inputs.new('NodeSocketString', "Format")
self.inputs.new('NodeSocketBool', "Ping Pong")
self.outputs.new('NodeSocketShader', "Target")
2016-11-07 16:11:35 +01:00
class ShadowMapNode(Node, CGPipelineTreeNode):
'''Create new shadow map target node'''
bl_idname = 'ShadowMapNodeType'
bl_label = 'Shadow Map'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketString', "ID")
self.inputs.new('NodeSocketInt', "Width")
self.inputs.new('NodeSocketInt', "Height")
self.inputs.new('NodeSocketString', "Format")
self.outputs.new('NodeSocketShader', "Target")
2016-10-09 16:06:18 +02:00
class ImageNode(Node, CGPipelineTreeNode):
'''Create new image node'''
bl_idname = 'ImageNodeType'
bl_label = 'Image'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketString', "ID")
self.inputs.new('NodeSocketInt', "Width")
self.inputs.new('NodeSocketInt', "Height")
self.inputs.new('NodeSocketString', "Format")
self.outputs.new('NodeSocketShader', "Target")
class Image3DNode(Node, CGPipelineTreeNode):
'''Create new 3D image node'''
bl_idname = 'Image3DNodeType'
bl_label = 'Image 3D'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketString', "ID")
self.inputs.new('NodeSocketInt', "Width")
self.inputs.new('NodeSocketInt', "Height")
self.inputs.new('NodeSocketInt', "Depth")
self.inputs.new('NodeSocketString', "Format")
self.outputs.new('NodeSocketShader', "Target")
2016-06-26 12:11:51 +02:00
class TargetArrayNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Create target array node'''
2016-07-10 00:51:39 +02:00
bl_idname = 'TargetArrayNodeType'
bl_label = 'Target Array'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Target")
self.inputs.new('NodeSocketInt', "Instances")
self.outputs.new('NodeSocketShader', "Targets")
class DepthBufferNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Create depth buffer node'''
2016-07-10 00:51:39 +02:00
bl_idname = 'DepthBufferNodeType'
bl_label = 'Depth Buffer'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketString', "ID")
self.inputs.new('NodeSocketBool', "Stencil")
self.outputs.new('NodeSocketShader', "Target")
class GBufferNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Create gbuffer node'''
2016-07-10 00:51:39 +02:00
bl_idname = 'GBufferNodeType'
bl_label = 'GBuffer'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Target 0")
self.inputs.new('NodeSocketShader', "Target 1")
self.inputs.new('NodeSocketShader', "Target 2")
self.inputs.new('NodeSocketShader', "Target 3")
self.inputs.new('NodeSocketShader', "Target 4")
self.outputs.new('NodeSocketShader', "Targets")
2016-01-26 14:36:55 +01:00
class FramebufferNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Reference framebuffer node'''
2016-07-10 00:51:39 +02:00
bl_idname = 'FramebufferNodeType'
bl_label = 'Framebuffer'
bl_icon = 'SOUND'
def init(self, context):
self.outputs.new('NodeSocketShader', "Target")
2016-01-26 14:36:55 +01:00
class BindTargetNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Bind render target node'''
2016-07-10 00:51:39 +02:00
bl_idname = 'BindTargetNodeType'
bl_label = 'Bind Target'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
self.inputs.new('NodeSocketShader', "Target")
self.inputs.new('NodeSocketString', "Constant")
2016-01-26 14:36:55 +01:00
2016-07-10 00:51:39 +02:00
self.outputs.new('NodeSocketShader', "Stage")
2016-01-26 14:36:55 +01:00
2016-04-15 00:02:32 +02:00
class DrawMaterialQuadNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Draw full-screen quad using material node'''
2016-07-10 00:51:39 +02:00
bl_idname = 'DrawMaterialQuadNodeType'
bl_label = 'Draw Material Quad'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
self.inputs.new('NodeSocketString', "Material Context")
self.outputs.new('NodeSocketShader', "Stage")
2016-01-26 14:36:55 +01:00
class DrawQuadNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Draw full-screen quad using shader node'''
2016-07-10 00:51:39 +02:00
bl_idname = 'DrawQuadNodeType'
bl_label = 'Draw Quad'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
self.inputs.new('NodeSocketString', "Shader Context")
2016-01-26 14:36:55 +01:00
2016-07-10 00:51:39 +02:00
self.outputs.new('NodeSocketShader', "Stage")
2016-01-26 14:36:55 +01:00
2016-05-05 19:50:03 +02:00
class CallFunctionNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Call Haxe function node'''
2016-07-10 00:51:39 +02:00
bl_idname = 'CallFunctionNodeType'
bl_label = 'Call Function'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
self.inputs.new('NodeSocketString', "Function")
self.outputs.new('NodeSocketShader', "Stage")
2016-05-05 19:50:03 +02:00
class BranchFunctionNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Branch on Haxe function result node'''
2016-07-10 00:51:39 +02:00
bl_idname = 'BranchFunctionNodeType'
bl_label = 'Branch Function'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
self.inputs.new('NodeSocketString', "Function")
self.outputs.new('NodeSocketShader', "True")
self.outputs.new('NodeSocketShader', "False")
2016-05-05 19:50:03 +02:00
class MergeStagesNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Join stages node'''
2016-07-10 00:51:39 +02:00
bl_idname = 'MergeStagesNodeType'
bl_label = 'Merge Stages'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
self.inputs.new('NodeSocketShader', "Stage")
2016-05-05 19:50:03 +02:00
2016-07-10 00:51:39 +02:00
self.outputs.new('NodeSocketShader', "Stage")
2016-05-05 19:50:03 +02:00
2016-06-26 12:11:51 +02:00
class LoopStagesNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Loop nested stages node'''
2016-07-10 00:51:39 +02:00
bl_idname = 'LoopStagesNodeType'
bl_label = 'Loop Stages'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
self.inputs.new('NodeSocketInt', "From")
self.inputs.new('NodeSocketInt', "To")
self.outputs.new('NodeSocketShader', "Complete")
self.outputs.new('NodeSocketShader', "Loop")
2016-08-25 00:26:01 +02:00
class LoopLampsNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Loop nested stages node'''
2016-08-25 00:26:01 +02:00
bl_idname = 'LoopLampsNodeType'
bl_label = 'Loop Lamps'
2016-07-10 00:51:39 +02:00
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
2016-06-26 12:11:51 +02:00
2016-07-10 00:51:39 +02:00
self.outputs.new('NodeSocketShader', "Complete")
self.outputs.new('NodeSocketShader', "Loop")
2016-06-26 12:11:51 +02:00
2016-08-10 17:46:16 +02:00
class DrawStereoNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Draw nested stages twice node'''
2016-08-10 17:46:16 +02:00
bl_idname = 'DrawStereoNodeType'
bl_label = 'Draw Stereo'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
self.outputs.new('NodeSocketShader', "Complete")
self.outputs.new('NodeSocketShader', "Per Eye")
2016-02-08 14:58:55 +01:00
class DrawWorldNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Draw world skydome node'''
2016-07-10 00:51:39 +02:00
bl_idname = 'DrawWorldNodeType'
bl_label = 'Draw World'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
2016-07-21 11:22:34 +02:00
# self.inputs.new('NodeSocketShader', "Depth")
2016-02-08 14:58:55 +01:00
2016-07-10 00:51:39 +02:00
self.outputs.new('NodeSocketShader', "Stage")
2016-02-08 14:58:55 +01:00
2016-06-22 12:21:15 +02:00
class DrawCompositorNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Draw compositor node'''
2016-07-10 00:51:39 +02:00
bl_idname = 'DrawCompositorNodeType'
bl_label = 'Draw Compositor'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
self.inputs.new('NodeSocketShader', "Target")
self.inputs.new('NodeSocketShader', "Color")
2016-08-15 23:45:03 +02:00
self.inputs.new('NodeSocketShader', "Depth")
2016-08-09 23:51:40 +02:00
self.inputs.new('NodeSocketShader', "Normals")
2016-07-10 00:51:39 +02:00
self.outputs.new('NodeSocketShader', "Stage")
2016-07-12 12:03:43 +02:00
class DrawCompositorWithFXAANode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Draw compositor with FXAA included node'''
2016-07-12 12:03:43 +02:00
bl_idname = 'DrawCompositorWithFXAANodeType'
bl_label = 'Draw Compositor + FXAA'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
self.inputs.new('NodeSocketShader', "Target")
self.inputs.new('NodeSocketShader', "Color")
2016-08-15 23:45:03 +02:00
self.inputs.new('NodeSocketShader', "Depth")
2016-08-09 23:51:40 +02:00
self.inputs.new('NodeSocketShader', "Normals")
2016-07-12 12:03:43 +02:00
self.outputs.new('NodeSocketShader', "Stage")
2016-09-30 23:24:18 +02:00
class DrawGreasePencilNode(Node, CGPipelineTreeNode):
'''Draw grease pencil node'''
bl_idname = 'DrawGreasePencilNodeType'
bl_label = 'Draw Grease Pencil'
bl_icon = 'SOUND'
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
2016-10-02 19:52:40 +02:00
self.inputs.new('NodeSocketString', "Context")
2016-09-30 23:24:18 +02:00
self.outputs.new('NodeSocketShader', "Stage")
2016-04-20 23:11:25 +02:00
# Constant nodes
2016-05-18 01:34:21 +02:00
class ScreenNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Reference screen dimensions node'''
2016-07-10 00:51:39 +02:00
bl_idname = 'ScreenNodeType'
bl_label = 'Screen'
bl_icon = 'SOUND'
def init(self, context):
self.outputs.new('NodeSocketInt', "Width")
self.outputs.new('NodeSocketInt', "Height")
self.inputs.new('NodeSocketFloat', "Scale")
self.inputs[0].default_value = 1.0
class BackgroundColorNode(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Reference world background color node'''
2016-07-10 00:51:39 +02:00
bl_idname = 'BackgroundColorNodeType'
bl_label = 'Background Color'
bl_icon = 'SOUND'
def init(self, context):
self.outputs.new('NodeSocketInt', "Color")
2016-08-25 00:26:01 +02:00
class LampCount(Node, CGPipelineTreeNode):
2016-09-23 00:34:42 +02:00
'''Reference number of visible lamps in scene node'''
2016-08-25 00:26:01 +02:00
bl_idname = 'LampCountNodeType'
bl_label = 'Lamp Count'
2016-07-10 00:51:39 +02:00
bl_icon = 'SOUND'
def init(self, context):
self.outputs.new('NodeSocketInt', "Count")
2016-06-26 12:11:51 +02:00
2016-01-26 14:36:55 +01:00
### Node Categories ###
import nodeitems_utils
from nodeitems_utils import NodeCategory, NodeItem
2016-08-11 22:24:45 +02:00
class MyCommandNodeCategory(NodeCategory):
2016-07-10 00:51:39 +02:00
@classmethod
def poll(cls, context):
return context.space_data.tree_type == 'CGPipelineTreeType'
2016-01-26 14:36:55 +01:00
class MyTargetNodeCategory(NodeCategory):
2016-07-10 00:51:39 +02:00
@classmethod
def poll(cls, context):
return context.space_data.tree_type == 'CGPipelineTreeType'
2016-04-15 20:19:39 +02:00
class MyPassNodeCategory(NodeCategory):
2016-07-10 00:51:39 +02:00
@classmethod
def poll(cls, context):
return context.space_data.tree_type == 'CGPipelineTreeType'
2016-04-20 23:11:25 +02:00
class MyConstantNodeCategory(NodeCategory):
2016-07-10 00:51:39 +02:00
@classmethod
def poll(cls, context):
return context.space_data.tree_type == 'CGPipelineTreeType'
2016-04-15 20:19:39 +02:00
2016-05-05 19:50:03 +02:00
class MyLogicNodeCategory(NodeCategory):
2016-07-10 00:51:39 +02:00
@classmethod
def poll(cls, context):
return context.space_data.tree_type == 'CGPipelineTreeType'
2016-05-05 19:50:03 +02:00
2016-01-26 14:36:55 +01:00
node_categories = [
2016-08-11 22:24:45 +02:00
MyCommandNodeCategory("COMMANDNODES", "Command", items=[
2016-07-10 00:51:39 +02:00
NodeItem("BeginNodeType"),
2016-08-25 00:26:01 +02:00
NodeItem("DrawMeshesNodeType"),
2016-07-10 00:51:39 +02:00
NodeItem("DrawDecalsNodeType"),
NodeItem("ClearTargetNodeType"),
2016-10-09 16:06:18 +02:00
NodeItem("GenerateMipmapsNodeType"),
2016-07-10 00:51:39 +02:00
NodeItem("SetTargetNodeType"),
2016-10-09 16:06:18 +02:00
NodeItem("SetViewportNodeType"),
2016-07-10 00:51:39 +02:00
NodeItem("BindTargetNodeType"),
NodeItem("DrawMaterialQuadNodeType"),
NodeItem("DrawQuadNodeType"),
NodeItem("DrawWorldNodeType"),
NodeItem("DrawCompositorNodeType"),
2016-07-12 12:03:43 +02:00
NodeItem("DrawCompositorWithFXAANodeType"),
2016-09-30 23:24:18 +02:00
NodeItem("DrawGreasePencilNodeType"),
2016-07-10 00:51:39 +02:00
]),
MyTargetNodeCategory("TARGETNODES", "Target", items=[
NodeItem("TargetNodeType"),
2016-11-07 16:11:35 +01:00
NodeItem("ShadowMapNodeType"),
2016-10-09 16:06:18 +02:00
NodeItem("ImageNodeType"),
NodeItem("Image3DNodeType"),
2016-07-10 00:51:39 +02:00
NodeItem("TargetArrayNodeType"),
NodeItem("DepthBufferNodeType"),
NodeItem("GBufferNodeType"),
NodeItem("FramebufferNodeType"),
]),
MyPassNodeCategory("PREBUILTNODES", "Prebuilt", items=[
NodeItem("QuadPassNodeType"),
NodeItem("SSAOPassNodeType"),
2016-08-09 23:51:40 +02:00
NodeItem("SSAOReprojectPassNodeType"),
2016-08-07 01:43:21 +02:00
NodeItem("ApplySSAOPassNodeType"),
2016-07-10 00:51:39 +02:00
NodeItem("SSRPassNodeType"),
NodeItem("BloomPassNodeType"),
NodeItem("MotionBlurPassNodeType"),
2016-07-31 23:25:33 +02:00
NodeItem("MotionBlurVelocityPassNodeType"),
2016-07-24 19:15:36 +02:00
NodeItem("CopyPassNodeType"),
2016-08-07 01:43:21 +02:00
NodeItem("BlendPassNodeType"),
NodeItem("CombinePassNodeType"),
2016-07-24 19:15:36 +02:00
NodeItem("BlurBasicPassNodeType"),
NodeItem("DebugNormalsPassNodeType"),
2016-07-10 00:51:39 +02:00
NodeItem("FXAAPassNodeType"),
NodeItem("SMAAPassNodeType"),
2016-07-28 13:21:27 +02:00
NodeItem("TAAPassNodeType"),
2016-07-10 00:51:39 +02:00
NodeItem("SSSPassNodeType"),
NodeItem("WaterPassNodeType"),
NodeItem("DeferredLightPassNodeType"),
2016-08-09 23:51:40 +02:00
NodeItem("DeferredIndirectPassNodeType"),
2016-08-31 00:46:10 +02:00
NodeItem("VolumetricLightPassNodeType"),
2016-07-10 00:51:39 +02:00
NodeItem("TranslucentResolvePassNodeType"),
]),
MyConstantNodeCategory("CONSTANTNODES", "Constant", items=[
NodeItem("ScreenNodeType"),
NodeItem("BackgroundColorNodeType"),
2016-08-25 00:26:01 +02:00
NodeItem("LampCountNodeType"),
2016-07-10 00:51:39 +02:00
]),
MyLogicNodeCategory("LOGICNODES", "Logic", items=[
NodeItem("CallFunctionNodeType"),
NodeItem("BranchFunctionNodeType"),
NodeItem("MergeStagesNodeType"),
NodeItem("LoopStagesNodeType"),
2016-08-25 00:26:01 +02:00
NodeItem("LoopLampsNodeType"),
2016-08-10 17:46:16 +02:00
NodeItem("DrawStereoNodeType"),
2016-07-10 00:51:39 +02:00
]),
2016-04-15 20:19:39 +02:00
]
2016-08-15 01:59:49 +02:00
# Handling node data
2016-02-08 12:03:20 +01:00
def reload_blend_data():
2016-08-11 22:24:45 +02:00
if bpy.data.node_groups.get('forward_path') == None:
2016-07-10 00:51:39 +02:00
load_library()
pass
2016-02-08 12:03:20 +01:00
def load_library():
2016-10-27 01:11:11 +02:00
sdk_path = armutils.get_sdk_path()
2016-07-10 00:51:39 +02:00
data_path = sdk_path + '/armory/blender/data/data.blend'
2016-10-15 12:17:33 +02:00
data_names = ['forward_path', 'forward_path_low', 'deferred_path', 'deferred_path_low', 'deferred_path_high', 'hybrid_path', 'vr_path', 'pathtrace_path', 'grease_pencil_path', 'Armory PBR']
2016-07-10 00:51:39 +02:00
2016-10-15 12:17:33 +02:00
# Remove old
for name in data_names:
if name in bpy.data.node_groups and name != 'Armory PBR':
bpy.data.node_groups.remove(bpy.data.node_groups[name], do_unlink=True)
# Import
data_refs = data_names.copy()
2016-07-10 00:51:39 +02:00
with bpy.data.libraries.load(data_path, link=False) as (data_from, data_to):
2016-10-15 12:17:33 +02:00
data_to.node_groups = data_refs
for ref in data_refs:
ref.use_fake_user = True
# bpy.data.node_groups[name].use_fake_user = True
2016-01-28 13:21:51 +01:00
2016-01-26 14:36:55 +01:00
def register():
2016-07-10 00:51:39 +02:00
bpy.utils.register_module(__name__)
try:
nodeitems_utils.register_node_categories("CG_PIPELINE_NODES", node_categories)
2016-11-25 11:29:26 +01:00
reload_blend_data()
2016-07-10 00:51:39 +02:00
except:
pass
2016-01-26 14:36:55 +01:00
def unregister():
2016-07-10 00:51:39 +02:00
nodeitems_utils.unregister_node_categories("CG_PIPELINE_NODES")
bpy.utils.unregister_module(__name__)