Begin true material builder

This commit is contained in:
Lubos Lenco 2016-12-13 01:09:17 +01:00
parent 5eb7221953
commit f4898a130c
53 changed files with 759 additions and 107 deletions

View file

@ -173,10 +173,6 @@
"name": "lightColor",
"link": "_lampColor"
},
{
"name": "lightStrength",
"link": "_lampStrength"
},
{
"name": "eye",
"link": "_cameraPosition"
@ -366,10 +362,6 @@
"name": "lightColor",
"link": "_lampColor"
},
{
"name": "lightStrength",
"link": "_lampStrength"
},
{
"name": "spotlightCutoff",
"link": "_spotlampCutoff"
@ -399,10 +391,6 @@
"name": "lightColor",
"link": "_lampColor"
},
{
"name": "lightStrength",
"link": "_lampStrength"
},
{
"name": "shirr",
"link": "_envmapIrradiance"

View file

@ -120,7 +120,7 @@ void main() {
indirect += prefilteredColor * (f0 * envBRDF.x + envBRDF.y);
#endif
indirect = indirect * envmapStrength;// * lightColor * lightStrength;
indirect = indirect * envmapStrength;// * lightColor;
indirect = indirect * g1.a; // Occlusion
#ifdef _SSAO

View file

@ -53,7 +53,7 @@ uniform vec3 lightPos;
uniform vec3 lightDir;
uniform int lightType;
// uniform int lightIndex;
uniform float lightStrength;
uniform vec3 lightColor;
uniform float shadowsBias;
uniform float spotlightCutoff;
uniform float spotlightExponent;
@ -69,8 +69,6 @@ uniform vec3 eye;
#ifdef _LampColTex
uniform sampler2D texlampcolor;
#else
uniform vec3 lightColor;
#endif
// in vec2 texCoord;
@ -225,13 +223,11 @@ void main() {
// vec3 direct = diffuseBRDF(albedo, metrough.y, dotNV, dotNL, dotVH, dotLV) + wardSpecular(n, h, dotNL, dotNV, dotNH, fiberDirection, shinyParallel, shinyPerpendicular);
// #endif
direct *= lightStrength;
direct *= lightColor;
#ifdef _LampColTex
// direct *= texture(texlampcolor, envMapEquirect(l)).rgb;
direct *= pow(texture(texlampcolor, l.xy).rgb, vec3(2.2));
#else
direct *= lightColor;
direct *= pow(texture(texlampcolor, l.xy).rgb, vec3(2.2));
#endif
#ifdef _SSS

View file

@ -35,18 +35,13 @@
},
{
"name": "lightColor",
"link": "_lampColor",
"ifndef": ["_LampColTex"]
"link": "_lampColor"
},
{
"name": "texlampcolor",
"link": "_lampColorTexture",
"ifdef": ["_LampColTex"]
},
{
"name": "lightStrength",
"link": "_lampStrength"
},
{
"name": "shadowsBias",
"link": "_lampShadowsBias"

View file

@ -33,10 +33,6 @@
"name": "lightColor",
"link": "_lampColor"
},
{
"name": "lightStrength",
"link": "_lampStrength"
},
{
"name": "lightBias",
"link": "_lampBias"

View file

@ -39,10 +39,6 @@
"name": "lightColor",
"link": "_lampColor"
},
{
"name": "lightStrength",
"link": "_lampStrength"
},
{
"name": "shadowsBias",
"link": "_lampShadowsBias"
@ -188,10 +184,6 @@
"name": "lightColor",
"link": "_lampColor"
},
{
"name": "lightStrength",
"link": "_lampStrength"
},
{
"name": "shadowsBias",
"link": "_lampShadowsBias"
@ -331,10 +323,6 @@
"name": "lightColor",
"link": "_lampColor"
},
{
"name": "lightStrength",
"link": "_lampStrength"
},
{
"name": "eye",
"link": "_cameraPosition"
@ -479,10 +467,6 @@
"name": "lightColor",
"link": "_lampColor"
},
{
"name": "lightStrength",
"link": "_lampStrength"
},
{
"name": "spotlightCutoff",
"link": "_spotlampCutoff"
@ -512,10 +496,6 @@
"name": "lightColor",
"link": "_lampColor"
},
{
"name": "lightStrength",
"link": "_lampStrength"
},
{
"name": "shirr",
"link": "_envmapIrradiance"

View file

@ -76,7 +76,6 @@ uniform vec3 lightPos;
uniform vec3 lightDir;
uniform int lightType;
uniform vec3 lightColor;
uniform float lightStrength;
uniform float spotlightCutoff;
uniform float spotlightExponent;
uniform float shadowsBias;
@ -353,7 +352,7 @@ void main() {
}
#endif
direct = direct * lightColor * lightStrength;
direct = direct * lightColor;
#ifdef _VoxelGI
@ -401,7 +400,7 @@ void main() {
vec3 indirectSpecular = prefilteredColor * (f0 * envBRDF.x + envBRDF.y);
indirect += indirectSpecular;
#endif
indirect = indirect * envmapStrength;// * lightColor * lightStrength;
indirect = indirect * envmapStrength;// * lightColor;
#endif

View file

@ -44,10 +44,6 @@
"name": "lightColor",
"link": "_lampColor"
},
{
"name": "lightStrength",
"link": "_lampStrength"
},
{
"name": "shadowsBias",
"link": "_lampShadowsBias"
@ -154,10 +150,6 @@
"name": "lightColor",
"link": "_lampColor"
},
{
"name": "lightStrength",
"link": "_lampStrength"
},
{
"name": "shadowsBias",
"link": "_lampShadowsBias"
@ -257,10 +249,6 @@
"name": "lightColor",
"link": "_lampColor"
},
{
"name": "lightStrength",
"link": "_lampStrength"
},
{
"name": "eye",
"link": "_cameraPosition"
@ -469,10 +457,6 @@
"name": "lightColor",
"link": "_lampColor"
},
{
"name": "lightStrength",
"link": "_lampStrength"
},
{
"name": "spotlightCutoff",
"link": "_spotlampCutoff"
@ -502,10 +486,6 @@
"name": "lightColor",
"link": "_lampColor"
},
{
"name": "lightStrength",
"link": "_lampStrength"
},
{
"name": "shirr",
"link": "_envmapIrradiance"

View file

@ -77,7 +77,6 @@ uniform vec3 lightPos;
uniform vec3 lightDir;
uniform int lightType;
uniform vec3 lightColor;
uniform float lightStrength;
uniform float shadowsBias;
uniform float spotlightCutoff;
uniform float spotlightExponent;
@ -212,7 +211,7 @@ void main() {
}
}
direct = direct * lightColor * lightStrength;
direct = direct * lightColor;
// Indirect
vec3 indirectDiffuse = shIrradiance(n, 2.2) / PI;
@ -233,7 +232,7 @@ void main() {
vec3 indirectSpecular = prefilteredColor * (f0 * envBRDF.x + envBRDF.y);
indirect += indirectSpecular;
#endif
indirect = indirect * envmapStrength; // * lightColor * lightStrength;
indirect = indirect * envmapStrength; // * lightColor;
outputColor = vec4(vec3(direct * visibility + indirect), 1.0);
#ifdef _OccTex

View file

@ -65,7 +65,6 @@ uniform float envmapStrength;
uniform bool receiveShadow;
uniform vec3 lightDir;
uniform vec3 lightColor;
uniform float lightStrength;
in vec3 position;
#ifdef _Tex
@ -150,7 +149,7 @@ void main() {
#else
vec3 direct = lambertDiffuseBRDF(albedo, dotNL) + specularBRDF(f0, roughness, dotNL, dotNH, dotNV, dotVH);
#endif
direct = direct * lightColor * lightStrength;
direct = direct * lightColor;
// Indirect
vec3 indirectDiffuse = shIrradiance(n, 2.2) / PI;
@ -171,7 +170,7 @@ void main() {
vec3 indirectSpecular = prefilteredColor * (f0 * envBRDF.x + envBRDF.y);
indirect += indirectSpecular;
#endif
indirect = indirect * envmapStrength; // * lightColor * lightStrength;
indirect = indirect * envmapStrength; // * lightColor;
fragColor = vec4(vec3(direct * visibility + indirect), 1.0);
#ifdef _OccTex

View file

@ -74,7 +74,6 @@ uniform vec3 lightPos;
uniform vec3 lightDir;
uniform int lightType;
uniform vec3 lightColor;
uniform float lightStrength;
uniform float spotlightCutoff;
uniform float spotlightExponent;
uniform vec3 eye;
@ -194,7 +193,7 @@ void main() {
}
}
direct = direct * lightColor * lightStrength;
direct = direct * lightColor;
// Indirect
vec3 indirectDiffuse = shIrradiance(n, 2.2) / PI;
@ -215,7 +214,7 @@ void main() {
vec3 indirectSpecular = prefilteredColor * (f0 * envBRDF.x + envBRDF.y);
indirect += indirectSpecular;
#endif
indirect = indirect * envmapStrength;// * lightColor * lightStrength;
indirect = indirect * envmapStrength;// * lightColor;
vec4 premultipliedReflect = vec4(vec3(direct * visibility + indirect * occlusion), matColor.a);

View file

@ -21,7 +21,6 @@ uniform vec3 viewPos;
uniform vec3 lightPos;
uniform vec3 lightColor;
uniform float lightRadius;
uniform float lightStrength;
uniform float shadowsBias;
in vec4 wvpposition;

View file

@ -42,10 +42,6 @@
"name": "lightColor",
"link": "_lampColor"
},
{
"name": "lightStrength",
"link": "_lampStrength"
},
{
"name": "snoise",
"link": "_noise8"

View file

@ -22,6 +22,7 @@ import armutils
import subprocess
import log
import make_material
import material.make as make_material_full
import nodes
NodeTypeNode = 0
@ -2756,7 +2757,10 @@ class ArmoryExporter:
# Parse from material output
if decal_uv_layer == None:
make_material.parse(self, material, c, defs)
if wrd.arm_material_level == 'Restricted':
make_material.parse(self, material, c, defs)
else:
make_material_full.parse(self, material, c, defs)
o['contexts'].append(c)
# Decal attached, split material into two separate ones
# Mandatory starting point from mix node for now
@ -2928,7 +2932,10 @@ class ArmoryExporter:
with_tess = True
if wrd.voxelgi:
geom_context = 'voxel'
self.finalize_shader(o, defs, ArmoryExporter.renderpath_passes, with_tess=with_tess, geom_context=geom_context)
if wrd.arm_material_level == 'Restricted':
self.finalize_shader(o, defs, ArmoryExporter.renderpath_passes, with_tess=with_tess, geom_context=geom_context)
else:
self.finalize_shader_full(o, material, ArmoryExporter.renderpath_passes)
else:
# TODO: gather defs from vertex data when custom shader is used
o['shader'] = material.override_shader_name
@ -3111,7 +3118,17 @@ class ArmoryExporter:
po['volume'] = volume
po['volume_center'] = volume_center
return po
def finalize_shader_full(self, o, material, rpasses):
shader_data_name = material.name + '_data'
shader_data_path = 'build/compiled/ShaderRaws/' + material.name + '/' + shader_data_name + '.arm'
assets.add_shader_data(shader_data_path)
o['shader'] = shader_data_name + '/' + shader_data_name
for ren_pass in rpasses:
full_name = 'build/compiled/ShaderRaws/' + material.name + '/' + material.name + '_' + ren_pass
assets.add_shader(full_name + '.vert.glsl')
assets.add_shader(full_name + '.frag.glsl')
def finalize_shader(self, o, defs, renderpath_passes, with_tess=False, geom_context=None):
# Merge duplicates and sort
defs = sorted(list(set(defs)))

View file

@ -28,7 +28,7 @@ def compile_shader(raw_shaders_path, shader_name, defs):
fp = armutils.get_fp()
# Open json file
json_name = shader_name + '.shader.json'
json_name = shader_name + '.json'
base_name = json_name.split('.', 1)[0]
with open(json_name) as f:
json_file = f.read()
@ -43,6 +43,24 @@ def export_data(fp, sdk_path, is_play=False, is_publish=False, in_viewport=False
print('\nArmory v' + wrd.arm_version)
# Clean compiled variants if cache is disabled
if wrd.arm_cache_shaders == False:
if os.path.isdir('build/html5-resources'):
shutil.rmtree('build/html5-resources')
if os.path.isdir('build/krom-resources'):
shutil.rmtree('build/krom-resources')
if os.path.isdir('build/window/krom-resources'):
shutil.rmtree('build/window/krom-resources')
if os.path.isdir('build/compiled/Shaders'):
shutil.rmtree('build/compiled/Shaders')
if os.path.isdir('build/compiled/ShaderDatas'):
shutil.rmtree('build/compiled/ShaderDatas')
if os.path.isdir('build/compiled/ShaderRaws'):
shutil.rmtree('build/compiled/ShaderRaws')
# Remove shader datas if shaders were deleted
elif os.path.isdir('build/compiled/Shaders') == False and os.path.isdir('build/compiled/ShaderDatas') == True:
shutil.rmtree('build/compiled/ShaderDatas')
raw_shaders_path = sdk_path + 'armory/Shaders/'
assets_path = sdk_path + 'armory/Assets/'
export_physics = bpy.data.worlds['Arm'].arm_physics != 'Disabled'
@ -83,22 +101,6 @@ def export_data(fp, sdk_path, is_play=False, is_publish=False, in_viewport=False
if navigation_found == False:
export_navigation = False
# Clean compiled variants if cache is disabled
if wrd.arm_cache_shaders == False:
if os.path.isdir('build/html5-resources'):
shutil.rmtree('build/html5-resources')
if os.path.isdir('build/krom-resources'):
shutil.rmtree('build/krom-resources')
if os.path.isdir('build/window/krom-resources'):
shutil.rmtree('build/window/krom-resources')
if os.path.isdir('build/compiled/Shaders'):
shutil.rmtree('build/compiled/Shaders')
if os.path.isdir('build/compiled/ShaderDatas'):
shutil.rmtree('build/compiled/ShaderDatas')
# Remove shader datas if shaders were deleted
elif os.path.isdir('build/compiled/Shaders') == False and os.path.isdir('build/compiled/ShaderDatas') == True:
shutil.rmtree('build/compiled/ShaderDatas')
# Write referenced shader variants
for ref in assets.shader_datas:

0
blender/material/__init__.py Executable file
View file

64
blender/material/make.py Normal file
View file

@ -0,0 +1,64 @@
import armutils
import os
import exporter
from material.shader_data import ShaderData
import material.make_forward as make_forward
import material.state as state
def parse(self, material, mat_context, defs):
state.material = material
state.group = material.node_tree
state.nodes = state.group.nodes
state.links = state.group.links
state.mat_context = mat_context
state.defs = defs
state.path = armutils.get_fp() + '/build/compiled/ShaderRaws/' + material.name
if not os.path.exists(state.path):
os.makedirs(state.path)
state.data = ShaderData(material)
rid = exporter.ArmoryExporter.renderpath_id
if rid == 'forward':
parse_forward()
elif rid == 'deferred':
parse_deferred
# TODO: Merge finalize shader here..
armutils.write_arm(state.path + '/' + material.name + '_data.arm', state.data.get())
def parse_deferred():
pass
def parse_forward():
rpasses = exporter.ArmoryExporter.renderpath_passes
mesh_context_id = exporter.ArmoryExporter.mesh_context
shadows_context_id = exporter.ArmoryExporter.shadows_context
for rp in rpasses:
if rp == mesh_context_id:
con = make_forward.mesh(rp)
elif rp == shadows_context_id:
con = make_forward.shadows(rp)
else:
continue
write_shaders(con, rp)
def write_shaders(con, rp):
if con.vert != None:
with open(state.path + '/' + state.material.name + '_' + rp + '.vert.glsl', 'w') as f:
f.write(con.vert.get())
if con.frag != None:
with open(state.path + '/' + state.material.name + '_' + rp + '.frag.glsl', 'w') as f:
f.write(con.frag.get())
if con.geom != None:
with open(state.path + '/' + state.material.name + '_' + rp + '.geom.glsl', 'w') as f:
f.write(con.geom.get())
if con.tesc != None:
with open(state.path + '/' + state.material.name + '_' + rp + '.tesc.glsl', 'w') as f:
f.write(con.tesc.get())
if con.tese != None:
with open(state.path + '/' + state.material.name + '_' + rp + '.tese.glsl', 'w') as f:
f.write(con.tese.get())

View file

View file

@ -0,0 +1,478 @@
import material.state as state
def node_by_type(ntype):
for n in state.nodes:
if n.type == ntype:
return n
def mesh(context_id):
# global parsed
global frag
global vert
# global first_basecol # Do not multiply vals first time
# global first_roughness
# global first_metallic
# parsed = [] # Compute node only onces
# first_basecol = True
# first_roughness = True
# first_metallic = True
con_mesh = state.data.add_context({ 'name': context_id, 'depth_write': True, 'compare_mode': 'less', 'cull_mode': 'clockwise' })
vert = con_mesh.vert()
frag = con_mesh.frag()
vert.add_out('vec3 wnormal')
vert.add_out('vec3 wposition')
vert.add_out('vec3 eyeDir')
vert.add_uniform('mat4 W', '_worldMatrix')
vert.add_uniform('mat4 N', '_normalMatrix')
vert.add_uniform('mat4 WVP', '_worldViewProjectionMatrix')
vert.add_uniform('vec3 eye', '_cameraPosition')
vert.write('vec4 spos = vec4(pos, 1.0);')
vert.write('wnormal = normalize(mat3(N) * nor);')
vert.write('wposition = vec4(W * spos).xyz;')
vert.write('eyeDir = eye - wposition;')
vert.write('gl_Position = WVP * spos;')
frag.add_include('../../Shaders/compiled.glsl')
frag.add_include('../../Shaders/std/brdf.glsl')
frag.add_include('../../Shaders/std/math.glsl')
frag.add_include('../../Shaders/std/shirr.glsl')
frag.add_uniform('vec3 lightColor', '_lampColor')
frag.add_uniform('vec3 lightDir', '_lampDirection')
frag.add_uniform('vec3 lightPos', '_lampPosition')
frag.add_uniform('int lightType', '_lampType')
frag.add_uniform('float shirr[27]', link='_envmapIrradiance', included=True)
frag.add_uniform('float envmapStrength', link='_envmapStrength')
frag.add_uniform('sampler2D senvmapRadiance', link='_envmapRadiance')
frag.add_uniform('sampler2D senvmapBrdf', link='_envmapBrdf')
frag.add_uniform('int envmapNumMipmaps', link='_envmapNumMipmaps')
frag.write('vec3 n = normalize(wnormal);')
frag.write('vec3 l = lightType == 0 ? lightDir : normalize(lightPos - wposition);')
frag.write('vec3 v = normalize(eyeDir);')
frag.write('vec3 h = normalize(v + l);')
frag.write('float dotNL = dot(n, l);')
frag.write('float dotNV = dot(n, v);')
frag.write('float dotNH = dot(n, h);')
frag.write('float dotVH = dot(v, h);')
vert.add_out('vec4 lampPos')
vert.add_uniform('mat4 LWVP', '_lampWorldViewProjectionMatrix')
vert.write('lampPos = LWVP * spos;')
frag.add_include('../../Shaders/std/shadows.glsl')
frag.add_uniform('sampler2D shadowMap', included=True)
frag.add_uniform('bool receiveShadow')
frag.add_uniform('float shadowsBias', '_lampShadowsBias')
frag.write('float visibility = 1.0;')
frag.write('if (receiveShadow && lampPos.w > 0.0) {')
frag.tab += 1
frag.write('vec3 lpos = lampPos.xyz / lampPos.w;')
frag.write('lpos.xy = lpos.xy * 0.5 + 0.5;')
frag.write('visibility = PCF(lpos.xy, lpos.z - shadowsBias);')
frag.tab -= 1
frag.write('}')
frag.add_uniform('float spotlightCutoff', '_spotlampCutoff')
frag.add_uniform('float spotlightExponent', '_spotlampExponent')
frag.write('if (lightType == 2) {')
frag.tab += 1
frag.write('float spotEffect = dot(lightDir, l);')
frag.write('if (spotEffect < spotlightCutoff) {')
frag.tab += 1
frag.write('spotEffect = smoothstep(spotlightCutoff - spotlightExponent, spotlightCutoff, spotEffect);')
frag.write('visibility *= spotEffect;')
frag.tab -= 1
frag.write('}')
frag.tab -= 1
frag.write('}')
frag.write('vec3 basecol;')
frag.write('float roughness;')
frag.write('float metallic;')
# frag.write('float occlussion;')
output_node = node_by_type('OUTPUT_MATERIAL')
if output_node != None:
parse_output(output_node)
frag.write('vec3 albedo = surfaceAlbedo(basecol, metallic);')
frag.write('vec3 f0 = surfaceF0(basecol, metallic);')
frag.write('vec3 direct = lambertDiffuseBRDF(albedo, dotNL);')
frag.write('direct += specularBRDF(f0, roughness, dotNL, dotNH, dotNV, dotVH);')
frag.write('vec3 indirect = (shIrradiance(n, 2.2) / PI) * albedo;')
frag.write('vec3 reflectionWorld = reflect(-v, n);')
frag.write('float lod = getMipFromRoughness(roughness, envmapNumMipmaps);')
frag.write('vec3 prefilteredColor = textureLod(senvmapRadiance, envMapEquirect(reflectionWorld), lod).rgb;')
frag.write('vec2 envBRDF = texture(senvmapBrdf, vec2(roughness, 1.0 - dotNV)).xy;')
frag.write('indirect += prefilteredColor * (f0 * envBRDF.x + envBRDF.y);')
frag.write('fragColor = vec4(direct * lightColor * visibility + indirect * envmapStrength, 1.0);')
return con_mesh
def parse_output(node):
out_basecol, out_roughness, out_metallic = parse_shader_input(node.inputs[0])
frag.write('basecol = {0};'.format(out_basecol))
frag.write('roughness = {0};'.format(out_roughness))
frag.write('metallic = {0};'.format(out_metallic))
def parse_shader_input(inp):
if inp.is_linked:
return parse_shader(inp.links[0].from_node)
else:
out_basecol = 'vec3(0.0)'
out_roughness = '0.0'
out_metallic = '0.0'
return out_basecol, out_roughness, out_metallic
def parse_shader(node):
if node.type == 'REROUTE':
return parse_shader(node.inputs[0].links[0].from_node)
elif node.type == 'MIX_SHADER':
fac = parse_float_input(node.inputs[0])
bc1, rough1, met1 = parse_shader_input(node.inputs[1])
bc2, rough2, met2 = parse_shader_input(node.inputs[2])
out_basecol = '({0} * (1.0 - {2}) + {1} * {2})'.format(bc1, bc2, fac)
out_roughness = '({0} * (1.0 - {2}) + {1} * {2})'.format(rough1, rough2, fac)
out_metallic = '({0} * (1.0 - {2}) + {1} * {2})'.format(met1, met2, fac)
elif node.type == 'ADD_SHADER':
pass
elif node.type == 'BSDF_DIFFUSE':
out_basecol = parse_color_input(node.inputs[0])
out_roughness = parse_float_input(node.inputs[1])
out_metallic = '0.0'
elif node.type == 'BSDF_GLOSSY':
out_basecol = parse_color_input(node.inputs[0])
out_roughness = parse_float_input(node.inputs[1])
out_metallic = '1.0'
elif node.type == 'AMBIENT_OCCLUSION':
pass
elif node.type == 'BSDF_ANISOTROPIC':
pass
elif node.type == 'EMISSION':
pass
elif node.type == 'BSDF_GLASS':
pass
elif node.type == 'BSDF_HAIR':
pass
elif node.type == 'HOLDOUT':
pass
elif node.type == 'BSDF_REFRACTION':
pass
elif node.type == 'SUBSURFACE_SCATTERING':
pass
elif node.type == 'BSDF_TOON':
pass
elif node.type == 'BSDF_TRANSLUCENT':
pass
elif node.type == 'BSDF_TRANSPARENT':
pass
elif node.type == 'BSDF_VELVET':
pass
elif node.type == 'VOLUME_ABSORPTION':
pass
elif node.type == 'VOLUME_SCATTER':
pass
elif node.type == 'GROUP' and node.node_tree.name.startswith('Armory PBR'):
pass
else:
out_basecol = 'vec3(0.0)'
out_roughness = '0.0'
out_metallic = '0.0'
return out_basecol, out_roughness, out_metallic
def parse_color_input(inp):
if inp.is_linked:
parse_color(inp.links[0].from_node)
else:
return vec3(inp.default_value)
def parse_color(node):
if node.type == 'REROUTE':
return parse_color(node.inputs[0].links[0].from_node)
elif node.type == 'ATTRIBUTE':
pass
elif node.type == 'RGB':
pass
elif node.type == 'TEX_BRICK':
pass
elif node.type == 'TEX_CHECKER':
pass
elif node.type == 'TEX_ENVIRONMENT':
pass
elif node.type == 'TEX_GRADIENT':
pass
elif node.type == 'TEX_IMAGE':
pass
elif node.type == 'TEX_MAGIC':
pass
elif node.type == 'TEX_MUSGRAVE':
pass
elif node.type == 'TEX_NOISE':
pass
elif node.type == 'TEX_POINTDENSITY':
pass
elif node.type == 'TEX_SKY':
pass
elif node.type == 'TEX_VORONOI':
pass
elif node.type == 'TEX_WAVE':
pass
elif node.type == 'BRIGHTCONTRAST':
pass
elif node.type == 'GAMMA':
pass
elif node.type == 'HUE_SAT':
pass
elif node.type == 'INVERT':
pass
elif node.type == 'MIX_RGB':
pass
elif node.type == 'CURVE_RGB':
pass
elif node.type == 'BLACKBODY':
pass
elif node.type == 'VALTORGB':
pass
elif node.type == 'COMBHSV':
pass
elif node.type == 'COMBRGB':
pass
elif node.type == 'WAVELENGTH':
pass
def parse_vector_input(inp):
if inp.is_linked:
return parse_vector(inp.links[0].from_node)
else:
return vec3(inp.default_value)
def parse_vector(node):
if node.type == 'REROUTE':
return parse_vector(node.inputs[0].links[0].from_node)
elif node.type == 'ATTRIBUTE':
pass
elif node.type == 'CAMERA':
pass
elif node.type == 'NEW_GEOMETRY':
pass
elif node.type == 'HAIR_INFO':
pass
elif node.type == 'OBJECT_INFO':
pass
elif node.type == 'PARTICLE_INFO':
pass
elif node.type == 'TANGENT':
pass
elif node.type == 'TEX_COORD':
pass
elif node.type == 'UVMAP':
pass
elif node.type == 'BUMP':
pass
elif node.type == 'MAPPING':
pass
elif node.type == 'NORMAL':
pass
elif node.type == 'NORMAL_MAP':
pass
elif node.type == 'CURVE_VEC':
pass
elif node.type == 'VECT_TRANSFORM':
pass
elif node.type == 'COMBXYZ':
pass
elif node.type == 'VECT_MATH':
pass
def parse_float_input(inp):
if inp.is_linked:
return parse_float(inp.links[0].from_node)
else:
return vec1(inp.default_value)
def parse_float(node):
if node.type == 'REROUTE':
return parse_float(node.inputs[0].links[0].from_node)
if node.type == 'ATTRIBUTE':
pass
elif node.type == 'CAMERA':
pass
elif node.type == 'FRESNEL':
pass
elif node.type == 'NEW_GEOMETRY':
pass
elif node.type == 'HAIR_INFO':
pass
elif node.type == 'LAYER_WEIGHT':
pass
elif node.type == 'LIGHT_PATH':
pass
elif node.type == 'OBJECT_INFO':
pass
elif node.type == 'PARTICLE_INFO':
pass
elif node.type == 'VALUE':
return vec1(node.outputs[0].default_value)
elif node.type == 'WIREFRAME':
pass
elif node.type == 'TEX_BRICK':
pass
elif node.type == 'TEX_CHECKER':
pass
elif node.type == 'TEX_GRADIENT':
pass
elif node.type == 'TEX_IMAGE':
pass
elif node.type == 'TEX_MAGIC':
pass
elif node.type == 'TEX_MUSGRAVE':
pass
elif node.type == 'TEX_NOISE':
pass
elif node.type == 'TEX_POINTDENSITY':
pass
elif node.type == 'TEX_VORONOI':
pass
elif node.type == 'TEX_WAVE':
pass
elif node.type == 'LIGHT_FALLOFF':
pass
elif node.type == 'NORMAL':
pass
elif node.type == 'VALTORGB':
pass
elif node.type == 'MATH':
pass
elif node.type == 'RGBTOBW':
pass
elif node.type == 'SEPHSV':
pass
elif node.type == 'SEPRGB':
pass
elif node.type == 'SEPXYZ':
pass
elif node.type == 'VECT_MATH':
pass
def vec1(v):
return str(v)
def vec2(v):
return 'vec2({0}, {1})'.format(v[0], v[1])
def vec3(v):
return 'vec3({0}, {1}, {2})'.format(v[0], v[1], v[2])
def vec4(v):
return 'vec4({0}, {1}, {2}, {3})'.format(v[0], v[1], v[2], v[3])
def shadows(context_id):
con_shadowmap = state.data.add_context({ 'name': context_id, 'depth_write': True, 'compare_mode': 'less', 'cull_mode': 'clockwise' })
vert = con_shadowmap.vert()
vert.add_uniform('mat4 LWVP', '_lampWorldViewProjectionMatrix')
vert.write('gl_Position = LWVP * vec4(pos, 1.0);')
frag = con_shadowmap.frag()
frag.write('fragColor = vec4(0.0);')
return con_shadowmap

View file

@ -0,0 +1,51 @@
class Shader:
def __init__(self, context):
self.context = context
self.includes = []
self.ins = []
self.outs = []
self.uniforms = []
self.main = ''
self.tab = 1
def add_include(self, s):
self.includes.append(s)
def add_in(self, s):
self.ins.append(s)
def add_out(self, s):
self.outs.append(s)
def add_uniform(self, s, link=None, included=False):
ar = s.split(' ')
if ar[0] == 'sampler2D':
self.context.add_texture_unit(ar[0], ar[1], link=link)
else:
if ar[0] == 'float' and '[' in ar[1]:
ar[0] = 'floats'
ar[1] = ar[1].split('[', 1)[0]
self.context.add_constant(ar[0], ar[1], link=link)
if included == False:
self.uniforms.append(s)
def write(self, s):
self.main += '\t' * self.tab + s + '\n'
def get(self):
s = '#version 450\n'
for a in self.includes:
s += '#include "' + a + '"\n'
for a in self.ins:
s += 'in ' + a + ';\n'
for a in self.outs:
s += 'out ' + a + ';\n'
for a in self.uniforms:
s += 'uniform ' + a + ';\n'
s += 'void main() {\n'
s += self.main
s += '}\n'
return s

View file

@ -0,0 +1,101 @@
from material.shader import Shader
class ShaderData:
def __init__(self, material):
self.material = material
self.contexts = []
self.sd = {}
self.data = {}
self.data['shader_datas'] = [self.sd]
self.sd['name'] = material.name + '_data'
self.sd['vertex_structure'] = []
self.add_elem('pos', 3)
self.add_elem('nor', 3)
self.sd['contexts'] = []
def add_elem(self, name, size):
elem = { 'name': name, 'size': size }
self.sd['vertex_structure'].append(elem)
def add_context(self, props):
con = ShaderContext(self.material, self.sd, props)
self.sd['contexts'].append(con.get())
return con
def get(self):
return self.data
class ShaderContext:
def __init__(self, material, shader_data, props):
self.material = material
self.shader_data = shader_data
self.data = {}
self.data['name'] = props['name']
self.data['depth_write'] = props['depth_write']
self.data['compare_mode'] = props['compare_mode']
self.data['cull_mode'] = props['cull_mode']
self.data['texture_units'] = []
self.tunits = self.data['texture_units']
self.data['constants'] = []
self.constants = self.data['constants']
def get(self):
return self.data
def add_constant(self, ctype, name, link=None):
for c in self.constants:
if c['name'] == name:
return
c = { 'name': name, 'type': ctype }
if link != None:
c['link'] = link
self.constants.append(c)
def add_texture_unit(self, ctype, name, link=None):
for c in self.tunits:
if c['name'] == name:
return
c = { 'name': name }
if link != None:
c['link'] = link
self.tunits.append(c)
def vert(self):
self.data['vertex_shader'] = self.material.name + '_' + self.data['name'] + '.vert'
self.vert = Shader(self)
vs = self.shader_data['vertex_structure']
for e in vs:
self.vert.add_in('vec' + str(e['size']) + ' ' + e['name'])
return self.vert
def frag(self):
self.data['fragment_shader'] = self.material.name + '_' + self.data['name'] + '.frag'
self.frag = Shader(self)
self.frag.ins = self.vert.outs
self.frag.add_out('vec4 fragColor')
return self.frag
def geom(self):
self.data['geometry_shader'] = self.material.name + '_' + self.data['name'] + '.geom'
self.geom = Shader(self)
return self.geom
def tesc(self):
self.data['tesscontrol_shader'] = self.material.name + '_' + self.data['name'] + '.tesc'
self.tesc = Shader(self)
return self.tesc
def tese(self):
self.data['tesseval_shader'] = self.material.name + '_' + self.data['name'] + '.tese'
self.tese = Shader(self)
return self.tese

View file

@ -0,0 +1,8 @@
data = None
material = None
group = None
nodes = None
links = None
mat_context = None
defs = None
path = None

View file

@ -74,6 +74,10 @@ def init_properties():
bpy.types.World.arm_lod_advanced = BoolProperty(name="Advanced", default=False)
bpy.types.World.arm_lod_gen_levels = IntProperty(name="Levels", description="Number of levels to generate", default=3, min=1)
bpy.types.World.arm_lod_gen_ratio = FloatProperty(name="Decimate Ratio", description="Decimate ratio", default=0.8)
bpy.types.World.arm_material_level = EnumProperty(
items=[('Restricted', 'Restricted', 'Restricted'),
('Full', 'Full', 'Full')],
name="Materials", description="Node parser to use when building materials", default="Restricted")
bpy.types.World.arm_cache_shaders = BoolProperty(name="Cache Shaders", description="Do not rebuild existing shaders", default=True, update=assets.invalidate_shader_cache)
#bpy.types.World.arm_cache_envmaps = BoolProperty(name="Cache Envmaps", description="Do not remove prefiltered maps when cleaning project", default=True)
bpy.types.World.arm_play_live_patch = BoolProperty(name="Live Patching", description="Sync running player data to Blender", default=True)

View file

@ -383,6 +383,7 @@ class ArmoryBuildPanel(bpy.types.Panel):
layout.prop(wrd, 'arm_optimize_mesh')
layout.prop(wrd, 'arm_sampled_animation')
layout.prop(wrd, 'arm_deinterleaved_buffers')
layout.prop(wrd, 'arm_material_level')
layout.label('Libraries')
layout.prop(wrd, 'arm_physics')
layout.prop(wrd, 'arm_navigation')