Parse world nodes

This commit is contained in:
Lubos Lenco 2016-02-08 14:58:55 +01:00
parent 574eae7f7b
commit 5b7617f3f0
10 changed files with 95 additions and 160 deletions

View file

@ -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
}
]
}
]
}

View file

@ -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"
}
]
}
]
}
]
}

View file

@ -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));
}

View file

@ -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);
}

View file

@ -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')

View file

@ -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

61
blender/nodes_world.py Executable file
View 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())

View file

@ -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)

View file

@ -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()

View file

@ -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")