From 5b7617f3f004b0785ba7e43c736845d00c97828a Mon Sep 17 00:00:00 2001 From: Lubos Lenco Date: Mon, 8 Feb 2016 14:58:55 +0100 Subject: [PATCH] Parse world nodes --- Assets/env_map.json | 42 ------------------ Assets/env_material.json | 21 --------- Sources/Shaders/env_map.frag.glsl | 23 ---------- Sources/Shaders/env_map.vert.glsl | 72 ------------------------------- blender/armory.py | 2 +- blender/nodes_pipeline.py | 23 ++++++++++ blender/nodes_world.py | 61 ++++++++++++++++++++++++++ blender/project.py | 2 + blender/start.py | 3 ++ blender/write_data.py | 6 ++- 10 files changed, 95 insertions(+), 160 deletions(-) delete mode 100644 Assets/env_map.json delete mode 100644 Assets/env_material.json delete mode 100644 Sources/Shaders/env_map.frag.glsl delete mode 100644 Sources/Shaders/env_map.vert.glsl create mode 100755 blender/nodes_world.py diff --git a/Assets/env_map.json b/Assets/env_map.json deleted file mode 100644 index 7dd901c7..00000000 --- a/Assets/env_map.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "shader_resources": [ - { - "contexts": [ - { - "blend_destination": "blend_zero", - "blend_source": "blend_one", - "compare_mode": "always", - "constants": [ - { - "id": "V", - "link": "_viewMatrix", - "type": "mat4" - }, - { - "id": "P", - "link": "_projectionMatrix", - "type": "mat4" - } - ], - "cull_mode": "none", - "depth_write": false, - "fragment_shader": "env_map.frag", - "id": "env_map", - "texture_units": [ - { - "id": "envmap" - } - ], - "vertex_shader": "env_map.vert" - } - ], - "id": "env_map", - "vertex_structure": [ - { - "name": "pos", - "size": 2 - } - ] - } - ] -} \ No newline at end of file diff --git a/Assets/env_material.json b/Assets/env_material.json deleted file mode 100644 index abf73fcb..00000000 --- a/Assets/env_material.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "material_resources": [ - { - "id": "env_material", - "shader": "env_map/env_map", - "cast_shadow": true, - "contexts": [ - { - "id": "env_map", - "bind_constants": [], - "bind_textures": [ - { - "id": "envmap", - "name": "envmap" - } - ] - } - ] - } - ] -} diff --git a/Sources/Shaders/env_map.frag.glsl b/Sources/Shaders/env_map.frag.glsl deleted file mode 100644 index d669e9ee..00000000 --- a/Sources/Shaders/env_map.frag.glsl +++ /dev/null @@ -1,23 +0,0 @@ -#version 450 - -#ifdef GL_ES -precision mediump float; -#endif - -#define PI 3.1415926 -#define TwoPI (2.0 * PI) - -uniform sampler2D envmap; - -in vec3 normal; - -vec2 envMapEquirect(vec3 normal) { - float phi = acos(normal.z); - float theta = atan(normal.x, normal.y) + PI; - return vec2(theta / TwoPI, phi / PI); -} - -void main() { - vec3 n = normalize(normal); - gl_FragColor = texture(envmap, envMapEquirect(n)); -} diff --git a/Sources/Shaders/env_map.vert.glsl b/Sources/Shaders/env_map.vert.glsl deleted file mode 100644 index 51fe19d8..00000000 --- a/Sources/Shaders/env_map.vert.glsl +++ /dev/null @@ -1,72 +0,0 @@ -#version 450 - -#ifdef GL_ES -precision highp float; -#endif - -uniform mat4 V; -uniform mat4 P; - -in vec2 pos; - -out vec3 normal; - -mat3 transpose_(mat3 m) { - return mat3(m[0][0], m[1][0], m[2][0], - m[0][1], m[1][1], m[2][1], - m[0][2], m[1][2], m[2][2]); -} - -mat4 inverse_(mat4 m) { - float - a00 = m[0][0], a01 = m[0][1], a02 = m[0][2], a03 = m[0][3], - a10 = m[1][0], a11 = m[1][1], a12 = m[1][2], a13 = m[1][3], - a20 = m[2][0], a21 = m[2][1], a22 = m[2][2], a23 = m[2][3], - a30 = m[3][0], a31 = m[3][1], a32 = m[3][2], a33 = m[3][3], - - b00 = a00 * a11 - a01 * a10, - b01 = a00 * a12 - a02 * a10, - b02 = a00 * a13 - a03 * a10, - b03 = a01 * a12 - a02 * a11, - b04 = a01 * a13 - a03 * a11, - b05 = a02 * a13 - a03 * a12, - b06 = a20 * a31 - a21 * a30, - b07 = a20 * a32 - a22 * a30, - b08 = a20 * a33 - a23 * a30, - b09 = a21 * a32 - a22 * a31, - b10 = a21 * a33 - a23 * a31, - b11 = a22 * a33 - a23 * a32, - - det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; - - return mat4( - a11 * b11 - a12 * b10 + a13 * b09, - a02 * b10 - a01 * b11 - a03 * b09, - a31 * b05 - a32 * b04 + a33 * b03, - a22 * b04 - a21 * b05 - a23 * b03, - a12 * b08 - a10 * b11 - a13 * b07, - a00 * b11 - a02 * b08 + a03 * b07, - a32 * b02 - a30 * b05 - a33 * b01, - a20 * b05 - a22 * b02 + a23 * b01, - a10 * b10 - a11 * b08 + a13 * b06, - a01 * b08 - a00 * b10 - a03 * b06, - a30 * b04 - a31 * b02 + a33 * b00, - a21 * b02 - a20 * b04 - a23 * b00, - a11 * b07 - a10 * b09 - a12 * b06, - a00 * b09 - a01 * b07 + a02 * b06, - a31 * b01 - a30 * b03 - a32 * b00, - a20 * b03 - a21 * b01 + a22 * b00) / det; -} - -void main() { - - mat4 invP = inverse_(P); - mat3 invMV = transpose_(mat3(V)); - - vec4 p = vec4(pos.xy, 0.0, 1.0); - vec3 unprojected = (invP * p).xyz; - - normal = invMV * unprojected; - - gl_Position = vec4(pos.xy, 0.0, 1.0); -} diff --git a/blender/armory.py b/blender/armory.py index 4fa4ba52..31820e36 100644 --- a/blender/armory.py +++ b/blender/armory.py @@ -2190,7 +2190,7 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper): defs.append('_Texturing') tex = Object() tex.id = 'salbedo' - tex.name = albedo_node.image.name.split('.', 1)[0] # Remove extension + tex.name = albedo_node.image.name.rsplit('.', 1)[0] # Remove extension c.bind_textures.append(tex) elif albedo_node.type == 'ATTRIBUTE': # Assume vcols for now defs.append('_VCols') diff --git a/blender/nodes_pipeline.py b/blender/nodes_pipeline.py index cf12906e..b3ce28fe 100755 --- a/blender/nodes_pipeline.py +++ b/blender/nodes_pipeline.py @@ -146,6 +146,23 @@ class DrawQuadNode(Node, CGPipelineTreeNode): def free(self): print("Removing node ", self, ", Goodbye!") + +class DrawWorldNode(Node, CGPipelineTreeNode): + '''A custom node''' + bl_idname = 'DrawWorldNodeType' + bl_label = 'Draw World' + bl_icon = 'SOUND' + + def init(self, context): + self.inputs.new('NodeSocketShader', "Stage") + + self.outputs.new('NodeSocketShader', "Stage") + + def copy(self, node): + print("Copying from node ", node) + + def free(self): + print("Removing node ", self, ", Goodbye!") ### Node Categories ### # Node categories are a python system for automatically @@ -167,6 +184,7 @@ node_categories = [ NodeItem("SetTargetNodeType"), NodeItem("BindTargetNodeType"), NodeItem("DrawQuadNodeType"), + NodeItem("DrawWorldNodeType"), NodeItem("TargetNodeType"), NodeItem("FramebufferNodeType"), ]), @@ -286,6 +304,11 @@ def buildNode(res, node, node_group): stage.command = 'draw_quad' stage.params.append(node.inputs[1].default_value) # Material context + elif node.bl_idname == 'DrawWorldNodeType': + stage.command = 'draw_quad' + wname = bpy.data.worlds[0].name + stage.params.append(wname + '_material/' + wname + '_material/env_map') # Only one world for now + res.stages.append(stage) # Build next stage diff --git a/blender/nodes_world.py b/blender/nodes_world.py new file mode 100755 index 00000000..912cef01 --- /dev/null +++ b/blender/nodes_world.py @@ -0,0 +1,61 @@ +import bpy +from bpy.types import NodeTree, Node, NodeSocket +from bpy.props import * +import os +import sys +import json + +def register(): + pass + #bpy.utils.register_module(__name__) + +def unregister(): + pass + #bpy.utils.unregister_module(__name__) + +# Generating world resources +class Object: + def to_JSON(self): + # return json.dumps(self, default=lambda o: o.__dict__, separators=(',',':')) + return json.dumps(self, default=lambda o: o.__dict__, sort_keys=True, indent=4) + +def buildNodeTrees(): + s = bpy.data.filepath.split(os.path.sep) + s.pop() + fp = os.path.sep.join(s) + os.chdir(fp) + + # Make sure Assets dir exists + if not os.path.exists('Assets/generated/materials'): + os.makedirs('Assets/generated/materials') + + # Export world nodes + for world in bpy.data.worlds: + buildNodeTree(world.name, world.node_tree) + +def buildNodeTree(world_name, node_group): + output = Object() + res = Object() + output.material_resources = [res] + + path = 'Assets/generated/materials/' + material_name = world_name.replace('.', '_') + '_material' + + res.id = material_name + res.shader = 'env_map/env_map' + context = Object() + res.contexts = [context] + + context.id = 'env_map' + context.bind_constants = [] + texture = Object() + context.bind_textures = [texture] + + texture.id = 'envmap' + texture.name = '' + for node in node_group.nodes: + if node.bl_idname == 'ShaderNodeTexEnvironment': # Just look for env texture for now + texture.name = node.image.name.rsplit('.', 1)[0] # Remove extension + + with open(path + material_name + '.json', 'w') as f: + f.write(output.to_JSON()) diff --git a/blender/project.py b/blender/project.py index 9488cd52..3936730d 100755 --- a/blender/project.py +++ b/blender/project.py @@ -11,6 +11,7 @@ import webbrowser import write_data import nodes_logic import nodes_pipeline +import nodes_world from armory import ArmoryExporter def defaultSettings(): @@ -163,6 +164,7 @@ def buildProject(self, build_type=0): # Auto-build nodes # TODO: only if needed nodes_logic.buildNodeTrees() nodes_pipeline.buildNodeTrees() + nodes_world.buildNodeTrees() # Set dir s = bpy.data.filepath.split(os.path.sep) diff --git a/blender/start.py b/blender/start.py index 8f3c3025..b25b6414 100755 --- a/blender/start.py +++ b/blender/start.py @@ -1,6 +1,7 @@ import project import nodes_logic import nodes_pipeline +import nodes_world import armory import traits_animation import traits_params @@ -11,6 +12,7 @@ def register(): project.register() nodes_logic.register() nodes_pipeline.register() + nodes_world.register() armory.register() traits_animation.register() traits_params.register() @@ -21,6 +23,7 @@ def unregister(): project.unregister() nodes_logic.unregister() nodes_pipeline.unregister() + nodes_world.unregister() armory.unregister() traits_animation.unregister() traits_params.unregister() diff --git a/blender/write_data.py b/blender/write_data.py index 09ba56e2..ef351c7f 100644 --- a/blender/write_data.py +++ b/blender/write_data.py @@ -17,7 +17,6 @@ project.addShaders('Sources/Shaders/**'); project.addAssets('Assets/**'); project.addLibrary('cyclesgame'); -project.addAssets('Libraries/cyclesgame/Assets/**'); """) for ref in shader_references: @@ -33,6 +32,11 @@ project.addAssets('Libraries/cyclesgame/Assets/**'); defs = '_' + defsarr[1] f.write("project.addShaders('compiled/Shaders/" + base_name + "" + 'shadowmap' + defs + ".frag.glsl');\n") f.write("project.addShaders('compiled/Shaders/" + base_name + "" + 'shadowmap' + defs + ".vert.glsl');\n") + + # TODO: include env map only when used by world nodes + f.write("project.addAssets('compiled/ShaderResources/env_map/env_map.json');\n") + f.write("project.addShaders('compiled/Shaders/env_map/env_map.frag.glsl');\n") + f.write("project.addShaders('compiled/Shaders/env_map/env_map.vert.glsl');\n") if bpy.data.worlds[0]['CGPhysics'] != 0: f.write("\nproject.addDefine('WITH_PHYSICS')\n")