Parse world nodes
This commit is contained in:
parent
574eae7f7b
commit
5b7617f3f0
|
@ -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
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -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"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -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));
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -2190,7 +2190,7 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper):
|
||||||
defs.append('_Texturing')
|
defs.append('_Texturing')
|
||||||
tex = Object()
|
tex = Object()
|
||||||
tex.id = 'salbedo'
|
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)
|
c.bind_textures.append(tex)
|
||||||
elif albedo_node.type == 'ATTRIBUTE': # Assume vcols for now
|
elif albedo_node.type == 'ATTRIBUTE': # Assume vcols for now
|
||||||
defs.append('_VCols')
|
defs.append('_VCols')
|
||||||
|
|
|
@ -146,6 +146,23 @@ class DrawQuadNode(Node, CGPipelineTreeNode):
|
||||||
|
|
||||||
def free(self):
|
def free(self):
|
||||||
print("Removing node ", self, ", Goodbye!")
|
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 ###
|
||||||
# Node categories are a python system for automatically
|
# Node categories are a python system for automatically
|
||||||
|
@ -167,6 +184,7 @@ node_categories = [
|
||||||
NodeItem("SetTargetNodeType"),
|
NodeItem("SetTargetNodeType"),
|
||||||
NodeItem("BindTargetNodeType"),
|
NodeItem("BindTargetNodeType"),
|
||||||
NodeItem("DrawQuadNodeType"),
|
NodeItem("DrawQuadNodeType"),
|
||||||
|
NodeItem("DrawWorldNodeType"),
|
||||||
NodeItem("TargetNodeType"),
|
NodeItem("TargetNodeType"),
|
||||||
NodeItem("FramebufferNodeType"),
|
NodeItem("FramebufferNodeType"),
|
||||||
]),
|
]),
|
||||||
|
@ -286,6 +304,11 @@ def buildNode(res, node, node_group):
|
||||||
stage.command = 'draw_quad'
|
stage.command = 'draw_quad'
|
||||||
stage.params.append(node.inputs[1].default_value) # Material context
|
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)
|
res.stages.append(stage)
|
||||||
|
|
||||||
# Build next stage
|
# Build next stage
|
||||||
|
|
61
blender/nodes_world.py
Executable file
61
blender/nodes_world.py
Executable file
|
@ -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())
|
|
@ -11,6 +11,7 @@ import webbrowser
|
||||||
import write_data
|
import write_data
|
||||||
import nodes_logic
|
import nodes_logic
|
||||||
import nodes_pipeline
|
import nodes_pipeline
|
||||||
|
import nodes_world
|
||||||
from armory import ArmoryExporter
|
from armory import ArmoryExporter
|
||||||
|
|
||||||
def defaultSettings():
|
def defaultSettings():
|
||||||
|
@ -163,6 +164,7 @@ def buildProject(self, build_type=0):
|
||||||
# Auto-build nodes # TODO: only if needed
|
# Auto-build nodes # TODO: only if needed
|
||||||
nodes_logic.buildNodeTrees()
|
nodes_logic.buildNodeTrees()
|
||||||
nodes_pipeline.buildNodeTrees()
|
nodes_pipeline.buildNodeTrees()
|
||||||
|
nodes_world.buildNodeTrees()
|
||||||
|
|
||||||
# Set dir
|
# Set dir
|
||||||
s = bpy.data.filepath.split(os.path.sep)
|
s = bpy.data.filepath.split(os.path.sep)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import project
|
import project
|
||||||
import nodes_logic
|
import nodes_logic
|
||||||
import nodes_pipeline
|
import nodes_pipeline
|
||||||
|
import nodes_world
|
||||||
import armory
|
import armory
|
||||||
import traits_animation
|
import traits_animation
|
||||||
import traits_params
|
import traits_params
|
||||||
|
@ -11,6 +12,7 @@ def register():
|
||||||
project.register()
|
project.register()
|
||||||
nodes_logic.register()
|
nodes_logic.register()
|
||||||
nodes_pipeline.register()
|
nodes_pipeline.register()
|
||||||
|
nodes_world.register()
|
||||||
armory.register()
|
armory.register()
|
||||||
traits_animation.register()
|
traits_animation.register()
|
||||||
traits_params.register()
|
traits_params.register()
|
||||||
|
@ -21,6 +23,7 @@ def unregister():
|
||||||
project.unregister()
|
project.unregister()
|
||||||
nodes_logic.unregister()
|
nodes_logic.unregister()
|
||||||
nodes_pipeline.unregister()
|
nodes_pipeline.unregister()
|
||||||
|
nodes_world.unregister()
|
||||||
armory.unregister()
|
armory.unregister()
|
||||||
traits_animation.unregister()
|
traits_animation.unregister()
|
||||||
traits_params.unregister()
|
traits_params.unregister()
|
||||||
|
|
|
@ -17,7 +17,6 @@ project.addShaders('Sources/Shaders/**');
|
||||||
project.addAssets('Assets/**');
|
project.addAssets('Assets/**');
|
||||||
|
|
||||||
project.addLibrary('cyclesgame');
|
project.addLibrary('cyclesgame');
|
||||||
project.addAssets('Libraries/cyclesgame/Assets/**');
|
|
||||||
""")
|
""")
|
||||||
|
|
||||||
for ref in shader_references:
|
for ref in shader_references:
|
||||||
|
@ -33,6 +32,11 @@ project.addAssets('Libraries/cyclesgame/Assets/**');
|
||||||
defs = '_' + defsarr[1]
|
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 + ".frag.glsl');\n")
|
||||||
f.write("project.addShaders('compiled/Shaders/" + base_name + "" + 'shadowmap' + defs + ".vert.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:
|
if bpy.data.worlds[0]['CGPhysics'] != 0:
|
||||||
f.write("\nproject.addDefine('WITH_PHYSICS')\n")
|
f.write("\nproject.addDefine('WITH_PHYSICS')\n")
|
||||||
|
|
Loading…
Reference in a new issue