2016-01-26 14:36:55 +01:00
import bpy
from bpy . types import NodeTree , Node , NodeSocket
from bpy . props import *
import os
import sys
import json
2016-02-08 12:03:20 +01:00
import platform
import subprocess
2016-06-22 12:21:15 +02:00
import nodes_compositor
2016-07-17 23:29:30 +02:00
from utils import to_hex
2016-07-19 19:42:46 +02:00
import assets
2016-07-20 17:33:17 +02:00
import utils
2016-05-18 01:34:21 +02:00
2016-01-26 14:36:55 +01:00
class CGPipelineTree ( NodeTree ) :
2016-08-11 22:24:45 +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-07-10 00:51:39 +02:00
bl_icon = ' GAME '
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 ) :
''' A custom node '''
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 " )
def copy ( self , node ) :
print ( " Copying from node " , node )
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
class SSAOPassNode ( Node , CGPipelineTreeNode ) :
''' A custom node '''
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 " )
def copy ( self , node ) :
print ( " Copying from node " , node )
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
2016-08-09 23:51:40 +02:00
class SSAOReprojectPassNode ( Node , CGPipelineTreeNode ) :
''' A custom node '''
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 " )
def copy ( self , node ) :
print ( " Copying from node " , node )
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
2016-08-07 01:43:21 +02:00
class ApplySSAOPassNode ( Node , CGPipelineTreeNode ) :
''' A custom node '''
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 " )
def copy ( self , node ) :
print ( " Copying from node " , node )
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
class SSRPassNode ( Node , CGPipelineTreeNode ) :
''' A custom node '''
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 " )
def copy ( self , node ) :
print ( " Copying from node " , node )
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
class BloomPassNode ( Node , CGPipelineTreeNode ) :
''' A custom node '''
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 " )
def copy ( self , node ) :
print ( " Copying from node " , node )
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
class MotionBlurPassNode ( Node , CGPipelineTreeNode ) :
''' A custom node '''
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 " )
def copy ( self , node ) :
print ( " Copying from node " , node )
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
2016-07-31 23:25:33 +02:00
class MotionBlurVelocityPassNode ( Node , CGPipelineTreeNode ) :
''' A custom node '''
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 " )
def copy ( self , node ) :
print ( " Copying from node " , node )
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
2016-07-24 19:15:36 +02:00
class CopyPassNode ( Node , CGPipelineTreeNode ) :
''' A custom node '''
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 " )
def copy ( self , node ) :
print ( " Copying from node " , node )
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
2016-08-07 01:43:21 +02:00
class BlendPassNode ( Node , CGPipelineTreeNode ) :
''' A custom node '''
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 " )
def copy ( self , node ) :
print ( " Copying from node " , node )
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
class CombinePassNode ( Node , CGPipelineTreeNode ) :
''' A custom node '''
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 " )
def copy ( self , node ) :
print ( " Copying from node " , node )
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
2016-07-24 19:15:36 +02:00
class BlurBasicPassNode ( Node , CGPipelineTreeNode ) :
''' A custom node '''
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 " )
def copy ( self , node ) :
print ( " Copying from node " , node )
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
class DebugNormalsPassNode ( Node , CGPipelineTreeNode ) :
''' A custom node '''
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 " )
def copy ( self , node ) :
print ( " Copying from node " , node )
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
2016-07-10 00:51:39 +02:00
class FXAAPassNode ( Node , CGPipelineTreeNode ) :
''' A custom node '''
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 " )
def copy ( self , node ) :
print ( " Copying from node " , node )
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
class SMAAPassNode ( Node , CGPipelineTreeNode ) :
''' A custom node '''
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 " )
def copy ( self , node ) :
print ( " Copying from node " , node )
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
2016-07-28 13:21:27 +02:00
class TAAPassNode ( Node , CGPipelineTreeNode ) :
''' A custom node '''
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 " )
def copy ( self , node ) :
print ( " Copying from node " , node )
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
2016-07-10 00:51:39 +02:00
class SSSPassNode ( Node , CGPipelineTreeNode ) :
''' A custom node '''
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 " )
def copy ( self , node ) :
print ( " Copying from node " , node )
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
class WaterPassNode ( Node , CGPipelineTreeNode ) :
''' A custom node '''
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 " )
def copy ( self , node ) :
print ( " Copying from node " , node )
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
class DeferredLightPassNode ( Node , CGPipelineTreeNode ) :
''' A custom node '''
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 " )
def copy ( self , node ) :
print ( " Copying from node " , node )
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
2016-08-09 23:51:40 +02:00
class DeferredIndirectPassNode ( Node , CGPipelineTreeNode ) :
''' A custom node '''
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 " )
self . outputs . new ( ' NodeSocketShader ' , " Stage " )
def copy ( self , node ) :
print ( " Copying from node " , node )
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
2016-07-10 00:51:39 +02:00
class TranslucentResolvePassNode ( Node , CGPipelineTreeNode ) :
''' A custom node '''
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 " )
def copy ( self , node ) :
print ( " Copying from node " , node )
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
# Pipeline
2016-01-26 14:36:55 +01:00
class DrawGeometryNode ( Node , CGPipelineTreeNode ) :
2016-07-10 00:51:39 +02:00
''' A custom node '''
bl_idname = ' DrawGeometryNodeType '
bl_label = ' Draw Geometry '
bl_icon = ' SOUND '
def init ( self , context ) :
self . inputs . new ( ' NodeSocketShader ' , " Stage " )
self . inputs . new ( ' NodeSocketString ' , " Context " )
2016-07-18 20:28:52 +02:00
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 " )
def copy ( self , node ) :
print ( " Copying from node " , node )
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
2016-05-18 01:34:21 +02:00
class DrawDecalsNode ( Node , CGPipelineTreeNode ) :
2016-07-10 00:51:39 +02:00
''' A custom node '''
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 " )
def copy ( self , node ) :
print ( " Copying from node " , node )
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
2016-01-26 14:36:55 +01:00
class ClearTargetNode ( Node , CGPipelineTreeNode ) :
2016-07-10 00:51:39 +02:00
''' A custom node '''
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 " )
def copy ( self , node ) :
print ( " Copying from node " , node )
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
2016-04-18 01:16:51 +02:00
class BeginNode ( Node , CGPipelineTreeNode ) :
2016-07-10 00:51:39 +02:00
''' A custom node '''
bl_idname = ' BeginNodeType '
bl_label = ' Begin '
bl_icon = ' SOUND '
def init ( self , context ) :
self . inputs . new ( ' NodeSocketString ' , " ID " )
self . inputs . new ( ' NodeSocketString ' , " Geometry " )
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 " )
def copy ( self , node ) :
print ( " Copying from node " , node )
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
2016-01-26 14:36:55 +01:00
class SetTargetNode ( Node , CGPipelineTreeNode ) :
2016-07-10 00:51:39 +02:00
''' A custom node '''
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 " )
def copy ( self , node ) :
print ( " Copying from node " , node )
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
2016-01-26 14:36:55 +01:00
class TargetNode ( Node , CGPipelineTreeNode ) :
2016-07-10 00:51:39 +02:00
''' A custom node '''
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 " )
def copy ( self , node ) :
print ( " Copying from node " , node )
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
2016-06-03 17:18:38 +02:00
2016-06-26 12:11:51 +02:00
class TargetArrayNode ( Node , CGPipelineTreeNode ) :
2016-07-10 00:51:39 +02:00
''' A custom node '''
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 " )
def copy ( self , node ) :
print ( " Copying from node " , node )
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
class DepthBufferNode ( Node , CGPipelineTreeNode ) :
''' A custom node '''
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 " )
def copy ( self , node ) :
print ( " Copying from node " , node )
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
2016-04-18 01:16:51 +02:00
2016-05-25 00:13:44 +02:00
class GBufferNode ( Node , CGPipelineTreeNode ) :
2016-07-10 00:51:39 +02:00
''' A custom node '''
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 " )
def copy ( self , node ) :
print ( " Copying from node " , node )
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
2016-01-26 14:36:55 +01:00
class FramebufferNode ( Node , CGPipelineTreeNode ) :
2016-07-10 00:51:39 +02:00
''' A custom node '''
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
2016-07-10 00:51:39 +02:00
def copy ( self , node ) :
print ( " Copying from node " , node )
2016-01-26 14:36:55 +01:00
2016-07-10 00:51:39 +02:00
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
2016-01-26 14:36:55 +01:00
class BindTargetNode ( Node , CGPipelineTreeNode ) :
2016-07-10 00:51:39 +02:00
''' A custom node '''
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-07-10 00:51:39 +02:00
def copy ( self , node ) :
print ( " Copying from node " , node )
2016-01-26 14:36:55 +01:00
2016-07-10 00:51:39 +02:00
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
2016-01-26 14:36:55 +01:00
2016-04-15 00:02:32 +02:00
class DrawMaterialQuadNode ( Node , CGPipelineTreeNode ) :
2016-07-10 00:51:39 +02:00
''' A custom node '''
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 " )
def copy ( self , node ) :
print ( " Copying from node " , node )
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
2016-01-26 14:36:55 +01:00
class DrawQuadNode ( Node , CGPipelineTreeNode ) :
2016-07-10 00:51:39 +02:00
''' A custom node '''
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-07-10 00:51:39 +02:00
def copy ( self , node ) :
print ( " Copying from node " , node )
2016-01-26 14:36:55 +01:00
2016-07-10 00:51:39 +02:00
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
2016-05-05 19:50:03 +02:00
class CallFunctionNode ( Node , CGPipelineTreeNode ) :
2016-07-10 00:51:39 +02:00
''' A custom node '''
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 " )
def copy ( self , node ) :
print ( " Copying from node " , node )
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
2016-05-05 19:50:03 +02:00
class BranchFunctionNode ( Node , CGPipelineTreeNode ) :
2016-07-10 00:51:39 +02:00
''' A custom node '''
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 " )
def copy ( self , node ) :
print ( " Copying from node " , node )
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
2016-05-05 19:50:03 +02:00
class MergeStagesNode ( Node , CGPipelineTreeNode ) :
2016-07-10 00:51:39 +02:00
''' A custom node '''
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-07-10 00:51:39 +02:00
def copy ( self , node ) :
print ( " Copying from node " , node )
2016-05-05 19:50:03 +02:00
2016-07-10 00:51:39 +02:00
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
2016-06-26 12:11:51 +02:00
class LoopStagesNode ( Node , CGPipelineTreeNode ) :
2016-07-10 00:51:39 +02:00
''' A custom node '''
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 " )
def copy ( self , node ) :
print ( " Copying from node " , node )
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
2016-06-26 12:11:51 +02:00
class LoopLightsNode ( Node , CGPipelineTreeNode ) :
2016-07-10 00:51:39 +02:00
''' A custom node '''
bl_idname = ' LoopLightsNodeType '
bl_label = ' Loop Lights '
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-07-10 00:51:39 +02:00
def copy ( self , node ) :
print ( " Copying from node " , node )
2016-06-26 12:11:51 +02:00
2016-07-10 00:51:39 +02:00
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
2016-06-26 12:11:51 +02:00
2016-08-10 17:46:16 +02:00
class DrawStereoNode ( Node , CGPipelineTreeNode ) :
''' A custom node '''
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 " )
def copy ( self , node ) :
print ( " Copying from node " , node )
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
2016-02-08 14:58:55 +01:00
class DrawWorldNode ( Node , CGPipelineTreeNode ) :
2016-07-10 00:51:39 +02:00
''' A custom node '''
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-07-10 00:51:39 +02:00
def copy ( self , node ) :
print ( " Copying from node " , node )
2016-02-08 14:58:55 +01:00
2016-07-10 00:51:39 +02:00
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
2016-01-26 14:36:55 +01:00
2016-06-22 12:21:15 +02:00
class DrawCompositorNode ( Node , CGPipelineTreeNode ) :
2016-07-10 00:51:39 +02:00
''' A custom node '''
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-09 23:51:40 +02:00
self . inputs . new ( ' NodeSocketShader ' , " Normals " )
2016-07-10 00:51:39 +02:00
self . outputs . new ( ' NodeSocketShader ' , " Stage " )
def copy ( self , node ) :
print ( " Copying from node " , node )
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
2016-07-12 12:03:43 +02:00
class DrawCompositorWithFXAANode ( Node , CGPipelineTreeNode ) :
''' A custom node '''
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-09 23:51:40 +02:00
self . inputs . new ( ' NodeSocketShader ' , " Normals " )
2016-07-12 12:03:43 +02:00
self . outputs . new ( ' NodeSocketShader ' , " Stage " )
def copy ( self , node ) :
print ( " Copying from node " , node )
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
2016-04-15 20:19:39 +02:00
2016-04-20 23:11:25 +02:00
# Constant nodes
2016-05-18 01:34:21 +02:00
class ScreenNode ( Node , CGPipelineTreeNode ) :
2016-07-10 00:51:39 +02:00
''' A custom node '''
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
def copy ( self , node ) :
print ( " Copying from node " , node )
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
class BackgroundColorNode ( Node , CGPipelineTreeNode ) :
''' A custom node '''
bl_idname = ' BackgroundColorNodeType '
bl_label = ' Background Color '
bl_icon = ' SOUND '
def init ( self , context ) :
self . outputs . new ( ' NodeSocketInt ' , " Color " )
def copy ( self , node ) :
print ( " Copying from node " , node )
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
2016-06-26 12:11:51 +02:00
class LightCount ( Node , CGPipelineTreeNode ) :
2016-07-10 00:51:39 +02:00
''' A custom node '''
bl_idname = ' LightCountNodeType '
bl_label = ' Light Count '
bl_icon = ' SOUND '
def init ( self , context ) :
self . outputs . new ( ' NodeSocketInt ' , " Count " )
2016-06-26 12:11:51 +02:00
2016-07-10 00:51:39 +02:00
def copy ( self , node ) :
print ( " Copying from node " , node )
2016-06-26 12:11:51 +02:00
2016-07-10 00:51:39 +02:00
def free ( self ) :
print ( " Removing node " , self , " , Goodbye! " )
2016-04-20 23:11:25 +02:00
2016-01-26 14:36:55 +01:00
### Node Categories ###
# Node categories are a python system for automatically
# extending the Add menu, toolbar panels and search operator.
# For more examples see release/scripts/startup/nodeitems_builtins.py
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
2016-05-25 00:13:44 +02: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-05-25 00:13:44 +02:00
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 " ) ,
NodeItem ( " DrawGeometryNodeType " ) ,
NodeItem ( " DrawDecalsNodeType " ) ,
NodeItem ( " ClearTargetNodeType " ) ,
NodeItem ( " SetTargetNodeType " ) ,
NodeItem ( " BindTargetNodeType " ) ,
NodeItem ( " DrawMaterialQuadNodeType " ) ,
NodeItem ( " DrawQuadNodeType " ) ,
NodeItem ( " DrawWorldNodeType " ) ,
NodeItem ( " DrawCompositorNodeType " ) ,
2016-07-12 12:03:43 +02:00
NodeItem ( " DrawCompositorWithFXAANodeType " ) ,
2016-07-10 00:51:39 +02:00
] ) ,
MyTargetNodeCategory ( " TARGETNODES " , " Target " , items = [
NodeItem ( " TargetNodeType " ) ,
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-07-10 00:51:39 +02:00
NodeItem ( " TranslucentResolvePassNodeType " ) ,
] ) ,
MyConstantNodeCategory ( " CONSTANTNODES " , " Constant " , items = [
NodeItem ( " ScreenNodeType " ) ,
NodeItem ( " BackgroundColorNodeType " ) ,
NodeItem ( " LightCountNodeType " ) ,
] ) ,
MyLogicNodeCategory ( " LOGICNODES " , " Logic " , items = [
NodeItem ( " CallFunctionNodeType " ) ,
NodeItem ( " BranchFunctionNodeType " ) ,
NodeItem ( " MergeStagesNodeType " ) ,
NodeItem ( " LoopStagesNodeType " ) ,
NodeItem ( " LoopLightsNodeType " ) ,
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-05-25 00:13:44 +02:00
2016-01-26 14:36:55 +01:00
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-07-10 00:51:39 +02:00
user_preferences = bpy . context . user_preferences
addon_prefs = user_preferences . addons [ ' armory ' ] . preferences
sdk_path = addon_prefs . sdk_path
data_path = sdk_path + ' /armory/blender/data/data.blend '
with bpy . data . libraries . load ( data_path , link = False ) as ( data_from , data_to ) :
2016-08-11 22:24:45 +02:00
data_to . node_groups = [ ' forward_path ' , ' forward_path_low ' , ' deferred_path ' , ' deferred_path_low ' , ' deferred_path_high ' , ' hybrid_path ' , ' vr_path ' , ' pathtrace_path ' , ' Armory PBR ' ]
2016-07-10 00:51:39 +02:00
# TODO: cannot use for loop
# TODO: import pbr group separately, no need for fake user
2016-08-11 22:24:45 +02:00
bpy . data . node_groups [ ' forward_path ' ] . use_fake_user = True
bpy . data . node_groups [ ' forward_path_low ' ] . use_fake_user = True
bpy . data . node_groups [ ' deferred_path ' ] . use_fake_user = True
bpy . data . node_groups [ ' deferred_path_low ' ] . use_fake_user = True
bpy . data . node_groups [ ' deferred_path_high ' ] . use_fake_user = True
bpy . data . node_groups [ ' hybrid_path ' ] . use_fake_user = True
bpy . data . node_groups [ ' vr_path ' ] . use_fake_user = True
bpy . data . node_groups [ ' pathtrace_path ' ] . use_fake_user = True
2016-07-27 14:25:01 +02:00
bpy . data . node_groups [ ' Armory PBR ' ] . 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 )
reload_blend_data ( )
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__ )
2016-01-26 14:36:55 +01:00
2016-07-10 00:51:39 +02:00
def buildNodeTrees ( shader_references , asset_references , assets_path ) :
s = bpy . data . filepath . split ( os . path . sep )
s . pop ( )
fp = os . path . sep . join ( s )
os . chdir ( fp )
# Make sure Assets dir exists
2016-07-19 19:42:46 +02:00
if not os . path . exists ( ' compiled/Assets/pipelines ' ) :
os . makedirs ( ' compiled/Assets/pipelines ' )
2016-07-10 00:51:39 +02:00
buildNodeTrees . assets_path = assets_path
buildNodeTrees . linked_assets = [ ]
# Always include
buildNodeTrees . linked_assets . append ( buildNodeTrees . assets_path + ' brdf.png ' )
# Export selected pipeline
node_group = bpy . data . node_groups [ bpy . data . cameras [ 0 ] . pipeline_path ]
buildNodeTree ( node_group , shader_references , asset_references )
return buildNodeTrees . linked_assets
2016-01-26 14:36:55 +01:00
2016-03-15 11:29:53 +01:00
def buildNodeTree ( node_group , shader_references , asset_references ) :
2016-07-20 17:33:17 +02:00
output = { }
res = { }
output [ ' pipeline_resources ' ] = [ res ]
2016-07-10 00:51:39 +02:00
2016-07-19 19:42:46 +02:00
path = ' compiled/Assets/pipelines/ '
2016-07-10 00:51:39 +02:00
node_group_name = node_group . name . replace ( ' . ' , ' _ ' )
rn = getRootNode ( node_group )
if rn == None :
return
2016-07-28 13:21:27 +02:00
2016-07-20 17:33:17 +02:00
res [ ' id ' ] = node_group_name
2016-08-09 23:51:40 +02:00
# Store main context names
res [ ' geometry_context ' ] = bpy . data . cameras [ 0 ] . geometry_context
res [ ' shadows_context ' ] = bpy . data . cameras [ 0 ] . shadows_context
2016-08-04 22:38:56 +02:00
res [ ' render_targets ' ] , res [ ' depth_buffers ' ] = preprocess_pipeline ( rn , node_group )
2016-07-20 17:33:17 +02:00
res [ ' stages ' ] = [ ]
2016-07-10 00:51:39 +02:00
2016-07-20 17:33:17 +02:00
buildNode ( res [ ' stages ' ] , rn , node_group , shader_references , asset_references )
2016-07-10 00:51:39 +02:00
2016-07-20 17:33:17 +02:00
asset_path = path + node_group_name + ' .arm '
utils . write_arm ( asset_path , output )
2016-07-19 19:42:46 +02:00
assets . add ( asset_path )
2016-01-26 14:36:55 +01:00
2016-08-09 23:51:40 +02:00
def make_set_target ( stage , node_group , node , currentNode = None , target_index = 1 , viewport_scale = 1.0 ) :
2016-07-10 00:51:39 +02:00
if currentNode == None :
currentNode = node
2016-07-20 17:33:17 +02:00
stage [ ' command ' ] = ' set_target '
2016-08-09 23:51:40 +02:00
# First param is viewport scale
if len ( stage [ ' params ' ] ) == 0 :
stage [ ' params ' ] . append ( viewport_scale )
2016-07-10 00:51:39 +02:00
currentNode = findNodeByLink ( node_group , currentNode , currentNode . inputs [ target_index ] )
if currentNode . bl_idname == ' TargetNodeType ' :
targetId = currentNode . inputs [ 0 ] . default_value
2016-07-20 17:33:17 +02:00
stage [ ' params ' ] . append ( targetId )
2016-07-10 00:51:39 +02:00
# Store current target size
buildNode . last_set_target_w = currentNode . inputs [ 1 ] . default_value
buildNode . last_set_target_h = currentNode . inputs [ 2 ] . default_value
elif currentNode . bl_idname == ' GBufferNodeType ' :
# Set all linked targets
for i in range ( 0 , 5 ) :
if currentNode . inputs [ i ] . is_linked :
make_set_target ( stage , node_group , node , currentNode , target_index = i )
elif currentNode . bl_idname == ' NodeReroute ' :
make_set_target ( stage , node_group , node , currentNode , target_index = 0 )
else : # Framebuffer
targetId = ' '
2016-07-20 17:33:17 +02:00
stage [ ' params ' ] . append ( targetId )
2016-07-10 00:51:39 +02:00
def make_clear_target ( stage , color_val = None , depth_val = None , stencil_val = None ) :
2016-07-20 17:33:17 +02:00
stage [ ' command ' ] = ' clear_target '
2016-07-10 00:51:39 +02:00
if color_val != None :
2016-07-20 17:33:17 +02:00
stage [ ' params ' ] . append ( ' color ' )
stage [ ' params ' ] . append ( str ( to_hex ( color_val ) ) )
2016-07-10 00:51:39 +02:00
if depth_val != None :
2016-07-20 17:33:17 +02:00
stage [ ' params ' ] . append ( ' depth ' )
stage [ ' params ' ] . append ( str ( depth_val ) )
2016-07-10 00:51:39 +02:00
if stencil_val != None :
2016-07-20 17:33:17 +02:00
stage [ ' params ' ] . append ( ' stencil ' )
stage [ ' params ' ] . append ( str ( stencil_val ) )
2016-04-15 20:19:39 +02:00
def make_draw_geometry ( stage , node_group , node ) :
2016-07-20 17:33:17 +02:00
stage [ ' command ' ] = ' draw_geometry '
2016-07-18 20:28:52 +02:00
# Context
2016-07-10 00:51:39 +02:00
context = node . inputs [ 1 ] . default_value
# Store shadowmap size
if context == bpy . data . cameras [ 0 ] . shadows_context :
2016-07-19 19:42:46 +02:00
bpy . data . worlds [ 0 ] . shadowmap_size = buildNode . last_set_target_w
2016-07-20 17:33:17 +02:00
stage [ ' params ' ] . append ( context )
2016-07-18 20:28:52 +02:00
# Order
order = node . inputs [ 2 ] . default_value
2016-07-20 17:33:17 +02:00
stage [ ' params ' ] . append ( order )
2016-07-10 00:51:39 +02:00
2016-05-18 01:34:21 +02:00
def make_draw_decals ( stage , node_group , node , shader_references , asset_references ) :
2016-07-20 17:33:17 +02:00
stage [ ' command ' ] = ' draw_decals '
2016-07-10 00:51:39 +02:00
context = node . inputs [ 1 ] . default_value
2016-07-20 17:33:17 +02:00
stage [ ' params ' ] . append ( context ) # Context
2016-07-10 00:51:39 +02:00
bpy . data . cameras [ 0 ] . last_decal_context = context
def make_bind_target ( stage , node_group , node , constant_name , currentNode = None , target_index = 1 ) :
if currentNode == None :
currentNode = node
2016-07-20 17:33:17 +02:00
stage [ ' command ' ] = ' bind_target '
2016-07-10 00:51:39 +02:00
link = findLink ( node_group , currentNode , currentNode . inputs [ target_index ] )
currentNode = link . from_node
if currentNode . bl_idname == ' NodeReroute ' :
make_bind_target ( stage , node_group , node , constant_name , currentNode = currentNode , target_index = 0 )
elif currentNode . bl_idname == ' GBufferNodeType ' :
for i in range ( 0 , 5 ) :
if currentNode . inputs [ i ] . is_linked :
targetNode = findNodeByLink ( node_group , currentNode , currentNode . inputs [ i ] )
targetId = targetNode . inputs [ 0 ] . default_value
# if i == 0 and targetNode.inputs[3].default_value == True: # Depth
if targetNode . inputs [ 3 ] . is_linked : # Depth
db_node = findNodeByLink ( node_group , targetNode , targetNode . inputs [ 3 ] )
db_id = db_node . inputs [ 0 ] . default_value
2016-07-20 17:33:17 +02:00
stage [ ' params ' ] . append ( ' _ ' + db_id )
stage [ ' params ' ] . append ( constant_name + ' D ' )
stage [ ' params ' ] . append ( targetId ) # Color buffer
stage [ ' params ' ] . append ( constant_name + str ( i ) )
2016-07-10 00:51:39 +02:00
elif currentNode . bl_idname == ' TargetNodeType ' :
targetId = currentNode . inputs [ 0 ] . default_value
2016-07-20 17:33:17 +02:00
stage [ ' params ' ] . append ( targetId )
stage [ ' params ' ] . append ( constant_name )
2016-07-10 00:51:39 +02:00
elif currentNode . bl_idname == ' DepthBufferNodeType ' :
targetId = ' _ ' + currentNode . inputs [ 0 ] . default_value
2016-07-20 17:33:17 +02:00
stage [ ' params ' ] . append ( targetId )
stage [ ' params ' ] . append ( constant_name )
2016-04-15 20:19:39 +02:00
def make_draw_material_quad ( stage , node_group , node , shader_references , asset_references , context_index = 1 ) :
2016-07-20 17:33:17 +02:00
stage [ ' command ' ] = ' draw_material_quad '
2016-07-10 00:51:39 +02:00
material_context = node . inputs [ context_index ] . default_value
2016-07-20 17:33:17 +02:00
stage [ ' params ' ] . append ( material_context )
2016-07-10 00:51:39 +02:00
# Include resource and shaders
shader_context = node . inputs [ context_index ] . default_value
scon = shader_context . split ( ' / ' )
dir_name = scon [ 2 ]
# No world defs for material passes
res_name = scon [ 2 ]
2016-07-20 17:33:17 +02:00
asset_references . append ( ' compiled/ShaderResources/ ' + dir_name + ' / ' + res_name + ' .arm ' )
2016-07-10 00:51:39 +02:00
shader_references . append ( ' compiled/Shaders/ ' + dir_name + ' / ' + res_name )
def make_draw_quad ( stage , node_group , node , shader_references , asset_references , context_index = 1 , shader_context = None ) :
2016-07-20 17:33:17 +02:00
stage [ ' command ' ] = ' draw_shader_quad '
2016-07-10 00:51:39 +02:00
# Append world defs to get proper context
world_defs = bpy . data . worlds [ 0 ] . world_defs
if shader_context == None :
shader_context = node . inputs [ context_index ] . default_value
scon = shader_context . split ( ' / ' )
2016-07-20 17:33:17 +02:00
stage [ ' params ' ] . append ( scon [ 0 ] + world_defs + ' / ' + scon [ 1 ] + world_defs + ' / ' + scon [ 2 ] )
2016-07-10 00:51:39 +02:00
# Include resource and shaders
dir_name = scon [ 0 ]
# Append world defs
res_name = scon [ 1 ] + world_defs
2016-07-20 17:33:17 +02:00
asset_references . append ( ' compiled/ShaderResources/ ' + dir_name + ' / ' + res_name + ' .arm ' )
2016-07-10 00:51:39 +02:00
shader_references . append ( ' compiled/Shaders/ ' + dir_name + ' / ' + res_name )
2016-04-15 20:19:39 +02:00
2016-07-20 01:14:28 +02:00
def make_draw_world ( stage , node_group , node , shader_references , asset_references , dome = True ) :
if dome :
2016-07-20 17:33:17 +02:00
stage [ ' command ' ] = ' draw_skydome '
2016-07-20 01:14:28 +02:00
else :
2016-07-20 17:33:17 +02:00
stage [ ' command ' ] = ' draw_material_quad '
2016-07-10 00:51:39 +02:00
wname = bpy . data . worlds [ 0 ] . name
2016-07-20 17:33:17 +02:00
stage [ ' params ' ] . append ( wname + ' _material/ ' + wname + ' _material/env_map ' ) # Only one world for now
2016-07-12 00:09:02 +02:00
# Link assets
if ' _EnvClouds ' in bpy . data . worlds [ 0 ] . world_defs :
buildNodeTrees . linked_assets . append ( buildNodeTrees . assets_path + ' noise256.png ' )
2016-04-15 20:19:39 +02:00
2016-07-12 12:03:43 +02:00
def make_draw_compositor ( stage , node_group , node , shader_references , asset_references , with_fxaa = False ) :
2016-07-10 00:51:39 +02:00
scon = ' compositor_pass '
world_defs = bpy . data . worlds [ 0 ] . world_defs
compositor_defs = nodes_compositor . parse_defs ( bpy . data . scenes [ 0 ] . node_tree ) # Thrown in scene 0 for now
2016-07-12 12:03:43 +02:00
if with_fxaa : # FXAA directly in compositor, useful for forward path
compositor_defs + = ' _CompFXAA '
2016-07-10 00:51:39 +02:00
defs = world_defs + compositor_defs
res_name = scon + defs
2016-07-20 17:33:17 +02:00
stage [ ' command ' ] = ' draw_shader_quad '
stage [ ' params ' ] . append ( res_name + ' / ' + res_name + ' / ' + scon )
2016-07-10 00:51:39 +02:00
# Include resource and shaders
2016-07-20 17:33:17 +02:00
asset_references . append ( ' compiled/ShaderResources/ ' + scon + ' / ' + res_name + ' .arm ' )
2016-07-10 00:51:39 +02:00
shader_references . append ( ' compiled/Shaders/ ' + scon + ' / ' + res_name )
# Link assets
buildNodeTrees . linked_assets . append ( buildNodeTrees . assets_path + ' noise256.png ' )
2016-06-22 12:21:15 +02:00
2016-05-05 19:50:03 +02:00
def make_call_function ( stage , node_group , node ) :
2016-07-20 17:33:17 +02:00
stage [ ' command ' ] = ' call_function '
stage [ ' params ' ] . append ( node . inputs [ 1 ] . default_value )
2016-05-05 19:50:03 +02:00
def make_branch_function ( stage , node_group , node ) :
2016-07-10 00:51:39 +02:00
make_call_function ( stage , node_group , node )
def process_call_function ( stage , stages , node , node_group , shader_references , asset_references ) :
# Step till merge node
2016-07-20 17:33:17 +02:00
stage [ ' returns_true ' ] = [ ]
2016-07-10 00:51:39 +02:00
if node . outputs [ 0 ] . is_linked :
stageNode = findNodeByLinkFrom ( node_group , node , node . outputs [ 0 ] )
2016-07-20 17:33:17 +02:00
buildNode ( stage [ ' returns_true ' ] , stageNode , node_group , shader_references , asset_references )
2016-07-10 00:51:39 +02:00
2016-07-20 17:33:17 +02:00
stage [ ' returns_false ' ] = [ ]
2016-07-10 00:51:39 +02:00
if node . outputs [ 1 ] . is_linked :
stageNode = findNodeByLinkFrom ( node_group , node , node . outputs [ 1 ] )
2016-07-20 17:33:17 +02:00
margeNode = buildNode ( stage [ ' returns_false ' ] , stageNode , node_group , shader_references , asset_references )
2016-07-10 00:51:39 +02:00
# Continue using top level stages after merge node
afterMergeNode = findNodeByLinkFrom ( node_group , margeNode , margeNode . outputs [ 0 ] )
buildNode ( stages , afterMergeNode , node_group , shader_references , asset_references )
2016-08-09 23:51:40 +02:00
def make_quad_pass ( stages , node_group , node , shader_references , asset_references , target_index = 1 , bind_target_indices = [ 3 , 5 , 7 ] , bind_target_constants = None , shader_context = None , viewport_scale = 1.0 , with_clear = False ) :
2016-07-10 00:51:39 +02:00
# Set target
if target_index != None and node . inputs [ target_index ] . is_linked :
2016-07-20 17:33:17 +02:00
stage = { }
stage [ ' params ' ] = [ ]
2016-08-09 23:51:40 +02:00
make_set_target ( stage , node_group , node , target_index = target_index , viewport_scale = viewport_scale )
stages . append ( stage )
# Optinal clear
if with_clear :
stage = { }
stage [ ' params ' ] = [ ]
make_clear_target ( stage , color_val = [ 0.0 , 0.0 , 0.0 , 1.0 ] )
2016-07-10 00:51:39 +02:00
stages . append ( stage )
# Bind targets
2016-07-20 17:33:17 +02:00
stage = { }
stage [ ' params ' ] = [ ]
2016-07-10 00:51:39 +02:00
buildNode . last_bind_target = stage
bind_target_used = False
for i in range ( 0 , len ( bind_target_indices ) ) :
index = bind_target_indices [ i ]
if node . inputs [ index ] . is_linked :
bind_target_used = True
if bind_target_constants == None :
constant_name = node . inputs [ index + 1 ] . default_value
else :
constant_name = bind_target_constants [ i ]
make_bind_target ( stage , node_group , node , constant_name , target_index = index )
if bind_target_used :
stages . append ( stage )
2016-07-20 17:33:17 +02:00
stage = { }
stage [ ' params ' ] = [ ]
2016-07-10 00:51:39 +02:00
# Draw quad
make_draw_quad ( stage , node_group , node , shader_references , asset_references , context_index = 2 , shader_context = shader_context )
stages . append ( stage )
def make_ssao_pass ( stages , node_group , node , shader_references , asset_references ) :
2016-08-09 23:51:40 +02:00
make_quad_pass ( stages , node_group , node , shader_references , asset_references , target_index = 1 , bind_target_indices = [ 3 , 4 ] , bind_target_constants = [ ' gbufferD ' , ' gbuffer0 ' ] , shader_context = ' ssao_pass/ssao_pass/ssao_pass ' , viewport_scale = bpy . data . worlds [ 0 ] . generate_ssao_texture_scale )
make_quad_pass ( stages , node_group , node , shader_references , asset_references , target_index = 2 , bind_target_indices = [ 1 , 4 ] , bind_target_constants = [ ' tex ' , ' gbuffer0 ' ] , shader_context = ' blur_edge_pass/blur_edge_pass/blur_edge_pass_x ' , viewport_scale = bpy . data . worlds [ 0 ] . generate_ssao_texture_scale )
make_quad_pass ( stages , node_group , node , shader_references , asset_references , target_index = 1 , bind_target_indices = [ 2 , 4 ] , bind_target_constants = [ ' tex ' , ' gbuffer0 ' ] , shader_context = ' blur_edge_pass/blur_edge_pass/blur_edge_pass_y ' )
buildNodeTrees . linked_assets . append ( buildNodeTrees . assets_path + ' noise8.png ' )
def make_ssao_reproject_pass ( stages , node_group , node , shader_references , asset_references ) :
make_quad_pass ( stages , node_group , node , shader_references , asset_references , target_index = 1 , bind_target_indices = [ 3 , 4 , 2 , 5 ] , bind_target_constants = [ ' gbufferD ' , ' gbuffer0 ' , ' slast ' , ' sveloc ' ] , shader_context = ' ssao_reproject_pass/ssao_reproject_pass/ssao_reproject_pass ' )
2016-08-07 01:43:21 +02:00
make_quad_pass ( stages , node_group , node , shader_references , asset_references , target_index = 2 , bind_target_indices = [ 1 , 4 ] , bind_target_constants = [ ' tex ' , ' gbuffer0 ' ] , shader_context = ' blur_edge_pass/blur_edge_pass/blur_edge_pass_x ' )
2016-07-10 00:51:39 +02:00
make_quad_pass ( stages , node_group , node , shader_references , asset_references , target_index = 1 , bind_target_indices = [ 2 , 4 ] , bind_target_constants = [ ' tex ' , ' gbuffer0 ' ] , shader_context = ' blur_edge_pass/blur_edge_pass/blur_edge_pass_y ' )
buildNodeTrees . linked_assets . append ( buildNodeTrees . assets_path + ' noise8.png ' )
2016-08-07 01:43:21 +02:00
def make_apply_ssao_pass ( stages , node_group , node , shader_references , asset_references ) :
make_quad_pass ( stages , node_group , node , shader_references , asset_references , target_index = 2 , bind_target_indices = [ 4 , 5 ] , bind_target_constants = [ ' gbufferD ' , ' gbuffer0 ' ] , shader_context = ' ssao_pass/ssao_pass/ssao_pass ' )
make_quad_pass ( stages , node_group , node , shader_references , asset_references , target_index = 3 , bind_target_indices = [ 2 , 5 ] , bind_target_constants = [ ' tex ' , ' gbuffer0 ' ] , shader_context = ' blur_edge_pass/blur_edge_pass/blur_edge_pass_x ' )
make_quad_pass ( stages , node_group , node , shader_references , asset_references , target_index = 1 , bind_target_indices = [ 3 , 5 ] , bind_target_constants = [ ' tex ' , ' gbuffer0 ' ] , shader_context = ' blur_edge_pass/blur_edge_pass/blur_edge_pass_y_blend ' )
buildNodeTrees . linked_assets . append ( buildNodeTrees . assets_path + ' noise8.png ' )
2016-07-10 00:51:39 +02:00
def make_ssr_pass ( stages , node_group , node , shader_references , asset_references ) :
2016-08-09 23:51:40 +02:00
make_quad_pass ( stages , node_group , node , shader_references , asset_references , target_index = 2 , bind_target_indices = [ 4 , 5 , 6 ] , bind_target_constants = [ ' tex ' , ' gbufferD ' , ' gbuffer0 ' ] , shader_context = ' ssr_pass/ssr_pass/ssr_pass ' , viewport_scale = bpy . data . worlds [ 0 ] . generate_ssr_texture_scale )
make_quad_pass ( stages , node_group , node , shader_references , asset_references , target_index = 3 , bind_target_indices = [ 2 , 6 ] , bind_target_constants = [ ' tex ' , ' gbuffer0 ' ] , shader_context = ' blur_adaptive_pass/blur_adaptive_pass/blur_adaptive_pass_x ' , viewport_scale = bpy . data . worlds [ 0 ] . generate_ssr_texture_scale , with_clear = True ) # Have to clear to prevent artefacts, potentially because of viewport scale
2016-08-07 23:12:14 +02:00
make_quad_pass ( stages , node_group , node , shader_references , asset_references , target_index = 1 , bind_target_indices = [ 3 , 6 ] , bind_target_constants = [ ' tex ' , ' gbuffer0 ' ] , shader_context = ' blur_adaptive_pass/blur_adaptive_pass/blur_adaptive_pass_y3_blend ' )
2016-07-10 00:51:39 +02:00
def make_bloom_pass ( stages , node_group , node , shader_references , asset_references ) :
make_quad_pass ( stages , node_group , node , shader_references , asset_references , target_index = 2 , bind_target_indices = [ 4 ] , bind_target_constants = [ ' tex ' ] , shader_context = ' bloom_pass/bloom_pass/bloom_pass ' )
make_quad_pass ( stages , node_group , node , shader_references , asset_references , target_index = 3 , bind_target_indices = [ 2 ] , bind_target_constants = [ ' tex ' ] , shader_context = ' blur_gaus_pass/blur_gaus_pass/blur_gaus_pass_x ' )
2016-08-07 01:43:21 +02:00
make_quad_pass ( stages , node_group , node , shader_references , asset_references , target_index = 1 , bind_target_indices = [ 3 ] , bind_target_constants = [ ' tex ' ] , shader_context = ' blur_gaus_pass/blur_gaus_pass/blur_gaus_pass_y_blend ' )
2016-07-10 00:51:39 +02:00
def make_motion_blur_pass ( stages , node_group , node , shader_references , asset_references ) :
make_quad_pass ( stages , node_group , node , shader_references , asset_references , target_index = 1 , bind_target_indices = [ 2 , 3 , 4 ] , bind_target_constants = [ ' tex ' , ' gbufferD ' , ' gbuffer0 ' ] , shader_context = ' motion_blur_pass/motion_blur_pass/motion_blur_pass ' )
2016-07-31 23:25:33 +02:00
def make_motion_blur_velocity_pass ( stages , node_group , node , shader_references , asset_references ) :
2016-08-01 10:55:13 +02:00
make_quad_pass ( stages , node_group , node , shader_references , asset_references , target_index = 1 , bind_target_indices = [ 2 , 3 , 4 ] , bind_target_constants = [ ' tex ' , ' gbuffer0 ' , ' sveloc ' ] , shader_context = ' motion_blur_veloc_pass/motion_blur_veloc_pass/motion_blur_veloc_pass ' )
2016-07-31 23:25:33 +02:00
2016-07-24 19:15:36 +02:00
def make_copy_pass ( stages , node_group , node , shader_references , asset_references ) :
make_quad_pass ( stages , node_group , node , shader_references , asset_references , target_index = 1 , bind_target_indices = [ 2 ] , bind_target_constants = [ ' tex ' ] , shader_context = ' copy_pass/copy_pass/copy_pass ' )
2016-08-07 01:43:21 +02:00
def make_blend_pass ( stages , node_group , node , shader_references , asset_references ) :
make_quad_pass ( stages , node_group , node , shader_references , asset_references , target_index = 1 , bind_target_indices = [ 2 ] , bind_target_constants = [ ' tex ' ] , shader_context = ' blend_pass/blend_pass/blend_pass ' )
def make_combine_pass ( stages , node_group , node , shader_references , asset_references ) :
make_quad_pass ( stages , node_group , node , shader_references , asset_references , target_index = 1 , bind_target_indices = [ 2 , 3 ] , bind_target_constants = [ ' tex ' , ' tex2 ' ] , shader_context = ' combine_pass/combine_pass/combine_pass ' )
2016-07-24 19:15:36 +02:00
def make_blur_basic_pass ( stages , node_group , node , shader_references , asset_references ) :
make_quad_pass ( stages , node_group , node , shader_references , asset_references , target_index = 2 , bind_target_indices = [ 1 ] , bind_target_constants = [ ' tex ' ] , shader_context = ' blur_pass/blur_pass/blur_pass_x ' )
make_quad_pass ( stages , node_group , node , shader_references , asset_references , target_index = 1 , bind_target_indices = [ 2 ] , bind_target_constants = [ ' tex ' ] , shader_context = ' blur_pass/blur_pass/blur_pass_y ' )
def make_debug_normals_pass ( stages , node_group , node , shader_references , asset_references ) :
make_quad_pass ( stages , node_group , node , shader_references , asset_references , target_index = 1 , bind_target_indices = [ 2 ] , bind_target_constants = [ ' tex ' ] , shader_context = ' debug_normals_pass/debug_normals_pass/debug_normals_pass ' )
2016-07-10 00:51:39 +02:00
def make_fxaa_pass ( stages , node_group , node , shader_references , asset_references ) :
make_quad_pass ( stages , node_group , node , shader_references , asset_references , target_index = 1 , bind_target_indices = [ 2 ] , bind_target_constants = [ ' tex ' ] , shader_context = ' fxaa_pass/fxaa_pass/fxaa_pass ' )
def make_smaa_pass ( stages , node_group , node , shader_references , asset_references ) :
2016-07-20 17:33:17 +02:00
stage = { }
stage [ ' params ' ] = [ ]
2016-07-10 00:51:39 +02:00
make_set_target ( stage , node_group , node , target_index = 2 )
stages . append ( stage )
2016-07-20 17:33:17 +02:00
stage = { }
stage [ ' params ' ] = [ ]
2016-07-10 00:51:39 +02:00
make_clear_target ( stage , color_val = [ 0.0 , 0.0 , 0.0 , 0.0 ] )
stages . append ( stage )
make_quad_pass ( stages , node_group , node , shader_references , asset_references , target_index = None , bind_target_indices = [ 4 ] , bind_target_constants = [ ' colorTex ' ] , shader_context = ' smaa_edge_detect/smaa_edge_detect/smaa_edge_detect ' )
2016-07-20 17:33:17 +02:00
stage = { }
stage [ ' params ' ] = [ ]
2016-07-10 00:51:39 +02:00
make_set_target ( stage , node_group , node , target_index = 3 )
stages . append ( stage )
2016-07-20 17:33:17 +02:00
stage = { }
stage [ ' params ' ] = [ ]
2016-07-10 00:51:39 +02:00
make_clear_target ( stage , color_val = [ 0.0 , 0.0 , 0.0 , 0.0 ] )
stages . append ( stage )
make_quad_pass ( stages , node_group , node , shader_references , asset_references , target_index = None , bind_target_indices = [ 2 ] , bind_target_constants = [ ' edgesTex ' ] , shader_context = ' smaa_blend_weight/smaa_blend_weight/smaa_blend_weight ' )
2016-07-31 23:25:33 +02:00
make_quad_pass ( stages , node_group , node , shader_references , asset_references , target_index = 1 , bind_target_indices = [ 4 , 3 , 5 ] , bind_target_constants = [ ' colorTex ' , ' blendTex ' , ' sveloc ' ] , shader_context = ' smaa_neighborhood_blend/smaa_neighborhood_blend/smaa_neighborhood_blend ' )
2016-07-10 00:51:39 +02:00
buildNodeTrees . linked_assets . append ( buildNodeTrees . assets_path + ' smaa_area.png ' )
buildNodeTrees . linked_assets . append ( buildNodeTrees . assets_path + ' smaa_search.png ' )
2016-07-28 13:21:27 +02:00
def make_taa_pass ( stages , node_group , node , shader_references , asset_references ) :
2016-07-31 23:25:33 +02:00
make_quad_pass ( stages , node_group , node , shader_references , asset_references , target_index = 1 , bind_target_indices = [ 2 , 3 , 4 ] , bind_target_constants = [ ' tex ' , ' tex2 ' , ' sveloc ' ] , shader_context = ' taa_pass/taa_pass/taa_pass ' )
2016-07-28 13:21:27 +02:00
2016-07-10 00:51:39 +02:00
def make_sss_pass ( stages , node_group , node , shader_references , asset_references ) :
make_quad_pass ( stages , node_group , node , shader_references , asset_references , target_index = 1 , bind_target_indices = [ 3 , 4 , 5 ] , bind_target_constants = [ ' tex ' , ' gbufferD ' , ' gbuffer0 ' ] , shader_context = ' sss_pass/sss_pass/sss_pass_x ' )
make_quad_pass ( stages , node_group , node , shader_references , asset_references , target_index = 2 , bind_target_indices = [ 3 , 4 , 5 ] , bind_target_constants = [ ' tex ' , ' gbufferD ' , ' gbuffer0 ' ] , shader_context = ' sss_pass/sss_pass/sss_pass_y ' )
def make_water_pass ( stages , node_group , node , shader_references , asset_references ) :
2016-07-17 20:29:53 +02:00
make_quad_pass ( stages , node_group , node , shader_references , asset_references , target_index = 1 , bind_target_indices = [ 2 , 3 ] , bind_target_constants = [ ' tex ' , ' gbufferD ' ] , shader_context = ' water_pass/water_pass/water_pass ' )
2016-07-10 00:51:39 +02:00
def make_deferred_light_pass ( stages , node_group , node , shader_references , asset_references ) :
2016-08-09 23:51:40 +02:00
# make_quad_pass(stages, node_group, node, shader_references, asset_references, target_index=1, bind_target_indices=[2, 3], bind_target_constants=['gbuffer', 'shadowMap'], shader_context='deferred_light/deferred_light/deferred_light')
# Draw light volume - TODO: properly generate stage
make_quad_pass ( stages , node_group , node , shader_references , asset_references , target_index = 1 , bind_target_indices = [ 2 , 3 ] , bind_target_constants = [ ' gbuffer ' , ' shadowMap ' ] , shader_context = ' deferred_light/deferred_light/deferred_light ' )
stages [ - 1 ] [ ' command ' ] = ' draw_light_volume '
def make_deferred_indirect_pass ( stages , node_group , node , shader_references , asset_references ) :
make_quad_pass ( stages , node_group , node , shader_references , asset_references , target_index = 1 , bind_target_indices = [ 2 , 3 ] , bind_target_constants = [ ' gbuffer ' , ' ssaotex ' ] , shader_context = ' deferred_indirect/deferred_indirect/deferred_indirect ' )
2016-07-10 00:51:39 +02:00
def make_translucent_resolve_pass ( stages , node_group , node , shader_references , asset_references ) :
make_quad_pass ( stages , node_group , node , shader_references , asset_references , target_index = 1 , bind_target_indices = [ 2 ] , bind_target_constants = [ ' gbuffer ' ] , shader_context = ' translucent_resolve/translucent_resolve/translucent_resolve ' )
2016-05-05 19:50:03 +02:00
# Returns merge node
2016-07-10 00:51:39 +02:00
def buildNode ( stages , node , node_group , shader_references , asset_references ) :
2016-07-20 17:33:17 +02:00
stage = { }
stage [ ' params ' ] = [ ]
2016-07-10 00:51:39 +02:00
append_stage = True
if node . bl_idname == ' MergeStagesNodeType ' :
return node
elif node . bl_idname == ' SetTargetNodeType ' :
buildNode . last_bind_target = None
make_set_target ( stage , node_group , node )
elif node . bl_idname == ' ClearTargetNodeType ' :
color_val = None
depth_val = None
stencil_val = None
if node . inputs [ 1 ] . default_value == True :
if node . inputs [ 2 ] . is_linked : # Assume background color node is linked
color_val = bpy . data . cameras [ 0 ] . world_envtex_color
else :
color_val = node . inputs [ 2 ] . default_value
if node . inputs [ 3 ] . default_value == True :
depth_val = node . inputs [ 4 ] . default_value
if node . inputs [ 5 ] . default_value == True :
stencil_val = node . inputs [ 6 ] . default_value
make_clear_target ( stage , color_val = color_val , depth_val = depth_val , stencil_val = stencil_val )
elif node . bl_idname == ' DrawGeometryNodeType ' :
make_draw_geometry ( stage , node_group , node )
elif node . bl_idname == ' DrawDecalsNodeType ' :
make_draw_decals ( stage , node_group , node , shader_references , asset_references )
elif node . bl_idname == ' BindTargetNodeType ' :
if buildNode . last_bind_target is not None :
stage = buildNode . last_bind_target
append_stage = False
buildNode . last_bind_target = stage
constant_name = node . inputs [ 2 ] . default_value
make_bind_target ( stage , node_group , node , constant_name )
elif node . bl_idname == ' DrawMaterialQuadNodeType ' :
make_draw_material_quad ( stage , node_group , node , shader_references , asset_references )
elif node . bl_idname == ' DrawQuadNodeType ' :
make_draw_quad ( stage , node_group , node , shader_references , asset_references )
elif node . bl_idname == ' DrawWorldNodeType ' :
2016-07-20 01:14:28 +02:00
# Bind depth for quad
# if node.inputs[1].is_linked:
2016-07-20 17:33:17 +02:00
# stage = {}
# stage['params'] = []
2016-07-20 01:14:28 +02:00
# buildNode.last_bind_target = stage
# if node.inputs[1].is_linked:
# make_bind_target(stage, node_group, node, target_index=1, constant_name='gbufferD')
# stages.append(stage)
2016-07-20 17:33:17 +02:00
stage = { }
stage [ ' params ' ] = [ ]
2016-07-20 01:14:28 +02:00
# Draw quad
# make_draw_world(stage, node_group, node, shader_references, asset_references, dome=False)
# Draw dome
make_draw_world ( stage , node_group , node , shader_references , asset_references , dome = True )
2016-07-10 00:51:39 +02:00
2016-07-12 12:03:43 +02:00
elif node . bl_idname == ' DrawCompositorNodeType ' or node . bl_idname == ' DrawCompositorWithFXAANodeType ' :
2016-07-10 00:51:39 +02:00
# Set target
if node . inputs [ 1 ] . is_linked :
make_set_target ( stage , node_group , node )
stages . append ( stage )
# Bind targets
if node . inputs [ 2 ] . is_linked or node . inputs [ 3 ] . is_linked :
2016-07-20 17:33:17 +02:00
stage = { }
stage [ ' params ' ] = [ ]
2016-07-10 00:51:39 +02:00
buildNode . last_bind_target = stage
if node . inputs [ 2 ] . is_linked :
make_bind_target ( stage , node_group , node , target_index = 2 , constant_name = ' tex ' )
if node . inputs [ 3 ] . is_linked :
2016-08-09 23:51:40 +02:00
make_bind_target ( stage , node_group , node , target_index = 3 , constant_name = ' gbuffer0 ' )
2016-07-10 00:51:39 +02:00
stages . append ( stage )
# Draw quad
2016-07-20 17:33:17 +02:00
stage = { }
stage [ ' params ' ] = [ ]
2016-07-12 12:03:43 +02:00
with_fxaa = node . bl_idname == ' DrawCompositorWithFXAANodeType '
make_draw_compositor ( stage , node_group , node , shader_references , asset_references , with_fxaa = with_fxaa )
2016-07-10 00:51:39 +02:00
elif node . bl_idname == ' BranchFunctionNodeType ' :
make_branch_function ( stage , node_group , node )
stages . append ( stage )
process_call_function ( stage , stages , node , node_group , shader_references , asset_references )
return
elif node . bl_idname == ' LoopStagesNodeType ' :
# Just repeats the commands
append_stage = False
if node . outputs [ 1 ] . is_linked :
count = node . inputs [ 2 ] . default_value
for i in range ( 0 , count ) :
loopNode = findNodeByLinkFrom ( node_group , node , node . outputs [ 1 ] )
buildNode ( stages , loopNode , node_group , shader_references , asset_references )
elif node . bl_idname == ' LoopLightsNodeType ' :
append_stage = False
2016-07-20 17:33:17 +02:00
stage [ ' command ' ] = ' loop_lights '
2016-07-10 00:51:39 +02:00
stages . append ( stage )
2016-07-20 17:33:17 +02:00
stage [ ' returns_true ' ] = [ ]
2016-07-10 00:51:39 +02:00
if node . outputs [ 1 ] . is_linked :
loopNode = findNodeByLinkFrom ( node_group , node , node . outputs [ 1 ] )
2016-07-20 17:33:17 +02:00
buildNode ( stage [ ' returns_true ' ] , loopNode , node_group , shader_references , asset_references )
2016-07-10 00:51:39 +02:00
2016-08-10 17:46:16 +02:00
elif node . bl_idname == ' DrawStereoNodeType ' :
append_stage = False
stage [ ' command ' ] = ' draw_stereo '
stages . append ( stage )
stage [ ' returns_true ' ] = [ ]
if node . outputs [ 1 ] . is_linked :
loopNode = findNodeByLinkFrom ( node_group , node , node . outputs [ 1 ] )
buildNode ( stage [ ' returns_true ' ] , loopNode , node_group , shader_references , asset_references )
2016-07-10 00:51:39 +02:00
elif node . bl_idname == ' CallFunctionNodeType ' :
make_call_function ( stage , node_group , node )
elif node . bl_idname == ' QuadPassNodeType ' :
make_quad_pass ( stages , node_group , node , shader_references , asset_references )
append_stage = False
elif node . bl_idname == ' SSAOPassNodeType ' :
make_ssao_pass ( stages , node_group , node , shader_references , asset_references )
append_stage = False
2016-08-09 23:51:40 +02:00
elif node . bl_idname == ' SSAOReprojectPassNodeType ' :
make_ssao_reproject_pass ( stages , node_group , node , shader_references , asset_references )
append_stage = False
2016-08-07 01:43:21 +02:00
elif node . bl_idname == ' ApplySSAOPassNodeType ' :
make_apply_ssao_pass ( stages , node_group , node , shader_references , asset_references )
append_stage = False
2016-07-10 00:51:39 +02:00
elif node . bl_idname == ' SSRPassNodeType ' :
make_ssr_pass ( stages , node_group , node , shader_references , asset_references )
append_stage = False
elif node . bl_idname == ' BloomPassNodeType ' :
make_bloom_pass ( stages , node_group , node , shader_references , asset_references )
append_stage = False
elif node . bl_idname == ' MotionBlurPassNodeType ' :
make_motion_blur_pass ( stages , node_group , node , shader_references , asset_references )
append_stage = False
2016-07-31 23:25:33 +02:00
elif node . bl_idname == ' MotionBlurVelocityPassNodeType ' :
make_motion_blur_velocity_pass ( stages , node_group , node , shader_references , asset_references )
append_stage = False
2016-07-24 19:15:36 +02:00
elif node . bl_idname == ' CopyPassNodeType ' :
make_copy_pass ( stages , node_group , node , shader_references , asset_references )
append_stage = False
2016-08-07 01:43:21 +02:00
elif node . bl_idname == ' BlendPassNodeType ' :
make_blend_pass ( stages , node_group , node , shader_references , asset_references )
append_stage = False
elif node . bl_idname == ' CombinePassNodeType ' :
make_combine_pass ( stages , node_group , node , shader_references , asset_references )
append_stage = False
2016-07-24 19:15:36 +02:00
elif node . bl_idname == ' BlurBasicPassNodeType ' :
make_blur_basic_pass ( stages , node_group , node , shader_references , asset_references )
append_stage = False
elif node . bl_idname == ' DebugNormalsPassNodeType ' :
make_debug_normals_pass ( stages , node_group , node , shader_references , asset_references )
append_stage = False
2016-07-10 00:51:39 +02:00
elif node . bl_idname == ' FXAAPassNodeType ' :
make_fxaa_pass ( stages , node_group , node , shader_references , asset_references )
append_stage = False
elif node . bl_idname == ' SMAAPassNodeType ' :
make_smaa_pass ( stages , node_group , node , shader_references , asset_references )
append_stage = False
2016-07-28 13:21:27 +02:00
elif node . bl_idname == ' TAAPassNodeType ' :
make_taa_pass ( stages , node_group , node , shader_references , asset_references )
append_stage = False
2016-07-10 00:51:39 +02:00
elif node . bl_idname == ' SSSPassNodeType ' :
make_sss_pass ( stages , node_group , node , shader_references , asset_references )
append_stage = False
elif node . bl_idname == ' WaterPassNodeType ' :
make_water_pass ( stages , node_group , node , shader_references , asset_references )
append_stage = False
elif node . bl_idname == ' DeferredLightPassNodeType ' :
make_deferred_light_pass ( stages , node_group , node , shader_references , asset_references )
append_stage = False
2016-08-09 23:51:40 +02:00
elif node . bl_idname == ' DeferredIndirectPassNodeType ' :
make_deferred_indirect_pass ( stages , node_group , node , shader_references , asset_references )
append_stage = False
2016-07-10 00:51:39 +02:00
elif node . bl_idname == ' TranslucentResolvePassNodeType ' :
make_translucent_resolve_pass ( stages , node_group , node , shader_references , asset_references )
append_stage = False
if append_stage :
stages . append ( stage )
# Build next stage
if node . outputs [ 0 ] . is_linked :
stageNode = findNodeByLinkFrom ( node_group , node , node . outputs [ 0 ] )
buildNode ( stages , stageNode , node_group , shader_references , asset_references )
# Used to merge bind target nodes into one stage
buildNode . last_bind_target = None
# Used to determine shadowmap size
buildNode . last_set_target_w = 0
buildNode . last_set_target_h = 0
2016-01-26 14:36:55 +01:00
def findNodeByLink ( node_group , to_node , inp ) :
2016-07-10 00:51:39 +02:00
for link in node_group . links :
if link . to_node == to_node and link . to_socket == inp :
return link . from_node
2016-05-25 00:13:44 +02:00
def findLink ( node_group , to_node , inp ) :
2016-07-10 00:51:39 +02:00
for link in node_group . links :
if link . to_node == to_node and link . to_socket == inp :
return link
2016-04-15 20:19:39 +02:00
def findNodeByLinkFrom ( node_group , from_node , outp ) :
2016-07-10 00:51:39 +02:00
for link in node_group . links :
if link . from_node == from_node and link . from_socket == outp :
return link . to_node
2016-07-28 13:21:27 +02:00
2016-01-26 14:36:55 +01:00
def getRootNode ( node_group ) :
2016-07-28 22:38:11 +02:00
# Find first node linked to begin node
2016-07-28 13:21:27 +02:00
rn = None
2016-07-10 00:51:39 +02:00
for n in node_group . nodes :
if n . bl_idname == ' BeginNodeType ' :
# Store contexts
bpy . data . cameras [ 0 ] . pipeline_id = n . inputs [ 0 ] . default_value
2016-08-07 01:43:21 +02:00
geometry_contexts = n . inputs [ 1 ] . default_value . split ( ' , ' )
bpy . data . cameras [ 0 ] . geometry_context = geometry_contexts [ 0 ]
if len ( geometry_contexts ) > 1 :
bpy . data . cameras [ 0 ] . geometry_context_empty = geometry_contexts [ 1 ]
2016-07-10 00:51:39 +02:00
bpy . data . cameras [ 0 ] . shadows_context = n . inputs [ 2 ] . default_value
bpy . data . cameras [ 0 ] . translucent_context = n . inputs [ 3 ] . default_value
2016-07-21 11:22:34 +02:00
bpy . data . cameras [ 0 ] . overlay_context = n . inputs [ 4 ] . default_value
if n . inputs [ 5 ] . default_value == False : # No HDR space lighting, append def
2016-07-12 12:03:43 +02:00
bpy . data . worlds [ 0 ] . world_defs + = ' _LDR '
2016-07-28 13:21:27 +02:00
rn = findNodeByLinkFrom ( node_group , n , n . outputs [ 0 ] )
2016-07-28 22:38:11 +02:00
break
2016-07-28 13:21:27 +02:00
return rn
2016-01-26 14:36:55 +01:00
2016-08-04 22:38:56 +02:00
def preprocess_pipeline ( root_node , node_group ) :
2016-07-10 00:51:39 +02:00
render_targets = [ ]
depth_buffers = [ ]
2016-08-04 22:38:56 +02:00
preprocess_pipeline . velocity_def_added = False
bpy . data . cameras [ 0 ] . pipeline_passes = ' '
traverse_pipeline ( root_node , node_group , render_targets , depth_buffers )
2016-07-10 00:51:39 +02:00
return render_targets , depth_buffers
2016-08-04 22:38:56 +02:00
def traverse_pipeline ( node , node_group , render_targets , depth_buffers ) :
# Gather linked draw geometry contexts
if node . bl_idname == ' DrawGeometryNodeType ' :
if bpy . data . cameras [ 0 ] . pipeline_passes != ' ' :
bpy . data . cameras [ 0 ] . pipeline_passes + = ' _ ' # Separator
bpy . data . cameras [ 0 ] . pipeline_passes + = node . inputs [ 1 ] . default_value
2016-07-28 22:38:11 +02:00
# Gather defs from linked nodes
2016-08-09 23:51:40 +02:00
if node . bl_idname == ' TAAPassNodeType ' or node . bl_idname == ' MotionBlurVelocityPassNodeType ' or node . bl_idname == ' SSAOReprojectPassNodeType ' :
2016-08-04 22:38:56 +02:00
if preprocess_pipeline . velocity_def_added == False :
2016-08-01 10:55:13 +02:00
assets . add_khafile_def ( ' WITH_VELOC ' )
bpy . data . worlds [ 0 ] . world_defs + = ' _Veloc '
2016-08-04 22:38:56 +02:00
preprocess_pipeline . velocity_def_added = True
2016-08-09 23:51:40 +02:00
if node . bl_idname == ' TAAPassNodeType ' :
assets . add_khafile_def ( ' WITH_TAA ' )
# bpy.data.worlds[0].world_defs += '_TAA'
2016-07-31 23:25:33 +02:00
elif node . bl_idname == ' SMAAPassNodeType ' :
bpy . data . worlds [ 0 ] . world_defs + = ' _SMAA '
2016-07-28 22:38:11 +02:00
2016-08-11 22:24:45 +02:00
elif node . bl_idname == ' SSAOPassNodeType ' :
if bpy . data . worlds [ 0 ] . generate_ssao : # SSAO enabled
bpy . data . worlds [ 0 ] . world_defs + = ' _SSAO '
2016-08-10 17:46:16 +02:00
elif node . bl_idname == ' DrawStereoNodeType ' :
assets . add_khafile_def ( ' WITH_VR ' )
bpy . data . worlds [ 0 ] . world_defs + = ' _VR '
2016-07-10 00:51:39 +02:00
# Collect render targets
2016-07-12 12:03:43 +02:00
if node . bl_idname == ' SetTargetNodeType ' or node . bl_idname == ' QuadPassNodeType ' or node . bl_idname == ' DrawCompositorNodeType ' or node . bl_idname == ' DrawCompositorWithFXAANodeType ' :
2016-07-10 00:51:39 +02:00
if node . inputs [ 1 ] . is_linked :
tnode = findNodeByLink ( node_group , node , node . inputs [ 1 ] )
parse_render_target ( tnode , node_group , render_targets , depth_buffers )
# Traverse loops
2016-08-10 17:46:16 +02:00
elif node . bl_idname == ' LoopStagesNodeType ' or node . bl_idname == ' LoopLightsNodeType ' or node . bl_idname == ' DrawStereoNodeType ' :
2016-07-10 00:51:39 +02:00
if node . outputs [ 1 ] . is_linked :
loop_node = findNodeByLinkFrom ( node_group , node , node . outputs [ 1 ] )
2016-08-04 22:38:56 +02:00
traverse_pipeline ( loop_node , node_group , render_targets , depth_buffers )
2016-07-10 00:51:39 +02:00
# Prebuilt
2016-08-09 23:51:40 +02:00
elif node . bl_idname == ' MotionBlurPassNodeType ' or node . bl_idname == ' MotionBlurVelocityPassNodeType ' or node . bl_idname == ' CopyPassNodeType ' or node . bl_idname == ' BlendPassNodeType ' or node . bl_idname == ' CombinePassNodeType ' or node . bl_idname == ' DebugNormalsPassNodeType ' or node . bl_idname == ' FXAAPassNodeType ' or node . bl_idname == ' TAAPassNodeType ' or node . bl_idname == ' WaterPassNodeType ' or node . bl_idname == ' DeferredLightPassNodeType ' or node . bl_idname == ' DeferredIndirectPassNodeType ' or node . bl_idname == ' TranslucentResolvePassNodeType ' :
2016-07-10 00:51:39 +02:00
if node . inputs [ 1 ] . is_linked :
tnode = findNodeByLink ( node_group , node , node . inputs [ 1 ] )
parse_render_target ( tnode , node_group , render_targets , depth_buffers )
2016-08-07 01:43:21 +02:00
elif node . bl_idname == ' SSRPassNodeType ' or node . bl_idname == ' ApplySSAOPassNodeType ' or node . bl_idname == ' BloomPassNodeType ' or node . bl_idname == ' SMAAPassNodeType ' :
2016-07-10 00:51:39 +02:00
for i in range ( 1 , 4 ) :
if node . inputs [ i ] . is_linked :
tnode = findNodeByLink ( node_group , node , node . inputs [ i ] )
parse_render_target ( tnode , node_group , render_targets , depth_buffers )
2016-08-09 23:51:40 +02:00
elif node . bl_idname == ' SSAOPassNodeType ' or node . bl_idname == ' SSAOReprojectPassNodeType ' or node . bl_idname == ' SSSPassNodeType ' or node . bl_idname == ' BlurBasicPassNodeType ' :
2016-07-10 00:51:39 +02:00
for i in range ( 1 , 3 ) :
if node . inputs [ i ] . is_linked :
tnode = findNodeByLink ( node_group , node , node . inputs [ i ] )
parse_render_target ( tnode , node_group , render_targets , depth_buffers )
# Next stage
if node . outputs [ 0 ] . is_linked :
stagenode = findNodeByLinkFrom ( node_group , node , node . outputs [ 0 ] )
2016-08-04 22:38:56 +02:00
traverse_pipeline ( stagenode , node_group , render_targets , depth_buffers )
2016-07-10 00:51:39 +02:00
2016-06-07 09:38:49 +02:00
def parse_render_target ( node , node_group , render_targets , depth_buffers ) :
2016-07-10 00:51:39 +02:00
if node . bl_idname == ' NodeReroute ' :
tnode = findNodeByLink ( node_group , node , node . inputs [ 0 ] )
parse_render_target ( tnode , node_group , render_targets , depth_buffers )
elif node . bl_idname == ' TargetNodeType ' :
# Target already exists
id = node . inputs [ 0 ] . default_value
for t in render_targets :
2016-07-20 17:33:17 +02:00
if t [ ' id ' ] == id :
2016-07-10 00:51:39 +02:00
return
depth_buffer_id = None
if node . inputs [ 3 ] . is_linked :
# Find depth buffer
depth_node = findNodeByLink ( node_group , node , node . inputs [ 3 ] )
depth_buffer_id = depth_node . inputs [ 0 ] . default_value
# Append depth buffer
found = False
for db in depth_buffers :
2016-07-20 17:33:17 +02:00
if db [ ' id ' ] == depth_buffer_id :
2016-07-10 00:51:39 +02:00
found = True
break
if found == False :
2016-07-20 17:33:17 +02:00
db = { }
db [ ' id ' ] = depth_buffer_id
db [ ' stencil_buffer ' ] = depth_node . inputs [ 1 ] . default_value
2016-07-10 00:51:39 +02:00
depth_buffers . append ( db )
# Get scale
scale = 1.0
if node . inputs [ 1 ] . is_linked :
size_node = findNodeByLink ( node_group , node , node . inputs [ 1 ] )
2016-08-09 23:51:40 +02:00
while size_node . bl_idname == ' NodeReroute ' : # Step through reroutes
size_node = findNodeByLink ( node_group , size_node , size_node . inputs [ 0 ] )
2016-07-10 00:51:39 +02:00
scale = size_node . inputs [ 0 ] . default_value
# Append target
target = make_render_target ( node , scale , depth_buffer_id = depth_buffer_id )
render_targets . append ( target )
elif node . bl_idname == ' GBufferNodeType ' :
for i in range ( 0 , 5 ) :
if node . inputs [ i ] . is_linked :
n = findNodeByLink ( node_group , node , node . inputs [ i ] )
parse_render_target ( n , node_group , render_targets , depth_buffers )
2016-06-07 09:38:49 +02:00
2016-06-30 13:22:05 +02:00
def make_render_target ( n , scale , depth_buffer_id = None ) :
2016-07-20 17:33:17 +02:00
target = { }
target [ ' id ' ] = n . inputs [ 0 ] . default_value
target [ ' width ' ] = n . inputs [ 1 ] . default_value
target [ ' height ' ] = n . inputs [ 2 ] . default_value
target [ ' format ' ] = n . inputs [ 4 ] . default_value
target [ ' ping_pong ' ] = n . inputs [ 5 ] . default_value
2016-07-10 00:51:39 +02:00
if scale != 1.0 :
2016-07-20 17:33:17 +02:00
target [ ' scale ' ] = scale
2016-07-10 00:51:39 +02:00
if depth_buffer_id != None :
2016-07-20 17:33:17 +02:00
target [ ' depth_buffer ' ] = depth_buffer_id
2016-07-10 00:51:39 +02:00
return target