diff --git a/Shaders/blend_pass/blend_pass.shader.json b/Shaders/blend_pass/blend_pass.json similarity index 100% rename from Shaders/blend_pass/blend_pass.shader.json rename to Shaders/blend_pass/blend_pass.json diff --git a/Shaders/bloom_pass/bloom_pass.shader.json b/Shaders/bloom_pass/bloom_pass.json similarity index 100% rename from Shaders/bloom_pass/bloom_pass.shader.json rename to Shaders/bloom_pass/bloom_pass.json diff --git a/Shaders/blur_adaptive_pass/blur_adaptive_pass.shader.json b/Shaders/blur_adaptive_pass/blur_adaptive_pass.json similarity index 100% rename from Shaders/blur_adaptive_pass/blur_adaptive_pass.shader.json rename to Shaders/blur_adaptive_pass/blur_adaptive_pass.json diff --git a/Shaders/blur_edge_pass/blur_edge_pass.shader.json b/Shaders/blur_edge_pass/blur_edge_pass.json similarity index 100% rename from Shaders/blur_edge_pass/blur_edge_pass.shader.json rename to Shaders/blur_edge_pass/blur_edge_pass.json diff --git a/Shaders/blur_gaus_pass/blur_gaus_pass.shader.json b/Shaders/blur_gaus_pass/blur_gaus_pass.json similarity index 100% rename from Shaders/blur_gaus_pass/blur_gaus_pass.shader.json rename to Shaders/blur_gaus_pass/blur_gaus_pass.json diff --git a/Shaders/blur_pass/blur_pass.shader.json b/Shaders/blur_pass/blur_pass.json similarity index 100% rename from Shaders/blur_pass/blur_pass.shader.json rename to Shaders/blur_pass/blur_pass.json diff --git a/Shaders/combine_pass/combine_pass.shader.json b/Shaders/combine_pass/combine_pass.json similarity index 100% rename from Shaders/combine_pass/combine_pass.shader.json rename to Shaders/combine_pass/combine_pass.json diff --git a/Shaders/compositor_pass/compositor_pass.shader.json b/Shaders/compositor_pass/compositor_pass.json similarity index 100% rename from Shaders/compositor_pass/compositor_pass.shader.json rename to Shaders/compositor_pass/compositor_pass.json diff --git a/Shaders/copy_pass/copy_pass.shader.json b/Shaders/copy_pass/copy_pass.json similarity index 100% rename from Shaders/copy_pass/copy_pass.shader.json rename to Shaders/copy_pass/copy_pass.json diff --git a/Shaders/debug_normals/debug_normals.shader.json b/Shaders/debug_normals/debug_normals.json similarity index 100% rename from Shaders/debug_normals/debug_normals.shader.json rename to Shaders/debug_normals/debug_normals.json diff --git a/Shaders/debug_velocity/debug_velocity.shader.json b/Shaders/debug_velocity/debug_velocity.json similarity index 100% rename from Shaders/debug_velocity/debug_velocity.shader.json rename to Shaders/debug_velocity/debug_velocity.json diff --git a/Shaders/deferred/deferred.shader.json b/Shaders/deferred/deferred.json similarity index 97% rename from Shaders/deferred/deferred.shader.json rename to Shaders/deferred/deferred.json index 95d04492..821c32f7 100755 --- a/Shaders/deferred/deferred.shader.json +++ b/Shaders/deferred/deferred.json @@ -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" diff --git a/Shaders/deferred_indirect/deferred_indirect.frag.glsl b/Shaders/deferred_indirect/deferred_indirect.frag.glsl index ddc0c0e8..af274c68 100644 --- a/Shaders/deferred_indirect/deferred_indirect.frag.glsl +++ b/Shaders/deferred_indirect/deferred_indirect.frag.glsl @@ -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 diff --git a/Shaders/deferred_indirect/deferred_indirect.shader.json b/Shaders/deferred_indirect/deferred_indirect.json similarity index 100% rename from Shaders/deferred_indirect/deferred_indirect.shader.json rename to Shaders/deferred_indirect/deferred_indirect.json diff --git a/Shaders/deferred_light/deferred_light.frag.glsl b/Shaders/deferred_light/deferred_light.frag.glsl index a7772c54..33a9ef0c 100644 --- a/Shaders/deferred_light/deferred_light.frag.glsl +++ b/Shaders/deferred_light/deferred_light.frag.glsl @@ -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 diff --git a/Shaders/deferred_light/deferred_light.shader.json b/Shaders/deferred_light/deferred_light.json similarity index 95% rename from Shaders/deferred_light/deferred_light.shader.json rename to Shaders/deferred_light/deferred_light.json index a4f996cd..c282afaa 100755 --- a/Shaders/deferred_light/deferred_light.shader.json +++ b/Shaders/deferred_light/deferred_light.json @@ -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" diff --git a/Shaders/deferred_light/deferred_light_quad.shader.json b/Shaders/deferred_light/deferred_light_quad.json similarity index 96% rename from Shaders/deferred_light/deferred_light_quad.shader.json rename to Shaders/deferred_light/deferred_light_quad.json index 60403819..0d909382 100755 --- a/Shaders/deferred_light/deferred_light_quad.shader.json +++ b/Shaders/deferred_light/deferred_light_quad.json @@ -33,10 +33,6 @@ "name": "lightColor", "link": "_lampColor" }, - { - "name": "lightStrength", - "link": "_lampStrength" - }, { "name": "lightBias", "link": "_lampBias" diff --git a/Shaders/forward/forward.shader.json b/Shaders/forward/forward.json similarity index 96% rename from Shaders/forward/forward.shader.json rename to Shaders/forward/forward.json index b20dde9a..a49a7115 100755 --- a/Shaders/forward/forward.shader.json +++ b/Shaders/forward/forward.json @@ -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" diff --git a/Shaders/forward/mesh.frag.glsl b/Shaders/forward/mesh.frag.glsl index a96e857c..7a4475cb 100644 --- a/Shaders/forward/mesh.frag.glsl +++ b/Shaders/forward/mesh.frag.glsl @@ -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 diff --git a/Shaders/fxaa_pass/fxaa_pass.shader.json b/Shaders/fxaa_pass/fxaa_pass.json similarity index 100% rename from Shaders/fxaa_pass/fxaa_pass.shader.json rename to Shaders/fxaa_pass/fxaa_pass.json diff --git a/Shaders/grease_pencil/grease_pencil.shader.json b/Shaders/grease_pencil/grease_pencil.json similarity index 100% rename from Shaders/grease_pencil/grease_pencil.shader.json rename to Shaders/grease_pencil/grease_pencil.json diff --git a/Shaders/hybrid/hybrid.shader.json b/Shaders/hybrid/hybrid.json similarity index 96% rename from Shaders/hybrid/hybrid.shader.json rename to Shaders/hybrid/hybrid.json index afaa17f5..a1d034c3 100755 --- a/Shaders/hybrid/hybrid.shader.json +++ b/Shaders/hybrid/hybrid.json @@ -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" diff --git a/Shaders/hybrid/mesh.frag.glsl b/Shaders/hybrid/mesh.frag.glsl index e0bec305..4e683b9e 100644 --- a/Shaders/hybrid/mesh.frag.glsl +++ b/Shaders/hybrid/mesh.frag.glsl @@ -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 diff --git a/Shaders/include/overlay.frag.glsl b/Shaders/include/overlay.frag.glsl index 91b72826..36bc4b1d 100755 --- a/Shaders/include/overlay.frag.glsl +++ b/Shaders/include/overlay.frag.glsl @@ -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 diff --git a/Shaders/include/translucent.frag.glsl b/Shaders/include/translucent.frag.glsl index b73bfd9a..0248a0cf 100755 --- a/Shaders/include/translucent.frag.glsl +++ b/Shaders/include/translucent.frag.glsl @@ -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); diff --git a/Shaders/motion_blur_pass/motion_blur_pass.shader.json b/Shaders/motion_blur_pass/motion_blur_pass.json similarity index 100% rename from Shaders/motion_blur_pass/motion_blur_pass.shader.json rename to Shaders/motion_blur_pass/motion_blur_pass.json diff --git a/Shaders/motion_blur_veloc_pass/motion_blur_veloc_pass.shader.json b/Shaders/motion_blur_veloc_pass/motion_blur_veloc_pass.json similarity index 100% rename from Shaders/motion_blur_veloc_pass/motion_blur_veloc_pass.shader.json rename to Shaders/motion_blur_veloc_pass/motion_blur_veloc_pass.json diff --git a/Shaders/pt_trace_pass/pt_trace_pass.shader.json b/Shaders/pt_trace_pass/pt_trace_pass.json similarity index 100% rename from Shaders/pt_trace_pass/pt_trace_pass.shader.json rename to Shaders/pt_trace_pass/pt_trace_pass.json diff --git a/Shaders/smaa_blend_weight/smaa_blend_weight.shader.json b/Shaders/smaa_blend_weight/smaa_blend_weight.json similarity index 100% rename from Shaders/smaa_blend_weight/smaa_blend_weight.shader.json rename to Shaders/smaa_blend_weight/smaa_blend_weight.json diff --git a/Shaders/smaa_edge_detect/smaa_edge_detect.shader.json b/Shaders/smaa_edge_detect/smaa_edge_detect.json similarity index 100% rename from Shaders/smaa_edge_detect/smaa_edge_detect.shader.json rename to Shaders/smaa_edge_detect/smaa_edge_detect.json diff --git a/Shaders/smaa_neighborhood_blend/smaa_neighborhood_blend.shader.json b/Shaders/smaa_neighborhood_blend/smaa_neighborhood_blend.json similarity index 100% rename from Shaders/smaa_neighborhood_blend/smaa_neighborhood_blend.shader.json rename to Shaders/smaa_neighborhood_blend/smaa_neighborhood_blend.json diff --git a/Shaders/ssao_pass/ssao_pass.shader.json b/Shaders/ssao_pass/ssao_pass.json similarity index 100% rename from Shaders/ssao_pass/ssao_pass.shader.json rename to Shaders/ssao_pass/ssao_pass.json diff --git a/Shaders/ssao_reproject_pass/ssao_reproject_pass.shader.json b/Shaders/ssao_reproject_pass/ssao_reproject_pass.json similarity index 100% rename from Shaders/ssao_reproject_pass/ssao_reproject_pass.shader.json rename to Shaders/ssao_reproject_pass/ssao_reproject_pass.json diff --git a/Shaders/ssdo_pass/ssdo_pass.shader.json b/Shaders/ssdo_pass/ssdo_pass.json similarity index 100% rename from Shaders/ssdo_pass/ssdo_pass.shader.json rename to Shaders/ssdo_pass/ssdo_pass.json diff --git a/Shaders/ssr_pass/ssr_pass.shader.json b/Shaders/ssr_pass/ssr_pass.json similarity index 100% rename from Shaders/ssr_pass/ssr_pass.shader.json rename to Shaders/ssr_pass/ssr_pass.json diff --git a/Shaders/sss_pass/sss_pass.shader.json b/Shaders/sss_pass/sss_pass.json similarity index 100% rename from Shaders/sss_pass/sss_pass.shader.json rename to Shaders/sss_pass/sss_pass.json diff --git a/Shaders/taa_pass/taa_pass.shader.json b/Shaders/taa_pass/taa_pass.json similarity index 100% rename from Shaders/taa_pass/taa_pass.shader.json rename to Shaders/taa_pass/taa_pass.json diff --git a/Shaders/translucent_resolve/translucent_resolve.shader.json b/Shaders/translucent_resolve/translucent_resolve.json similarity index 100% rename from Shaders/translucent_resolve/translucent_resolve.shader.json rename to Shaders/translucent_resolve/translucent_resolve.json diff --git a/Shaders/volumetric_light/volumetric_light.frag.glsl b/Shaders/volumetric_light/volumetric_light.frag.glsl index da0a7581..f949e026 100644 --- a/Shaders/volumetric_light/volumetric_light.frag.glsl +++ b/Shaders/volumetric_light/volumetric_light.frag.glsl @@ -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; diff --git a/Shaders/volumetric_light/volumetric_light.shader.json b/Shaders/volumetric_light/volumetric_light.json similarity index 93% rename from Shaders/volumetric_light/volumetric_light.shader.json rename to Shaders/volumetric_light/volumetric_light.json index 8f57b5bf..3e1a4037 100755 --- a/Shaders/volumetric_light/volumetric_light.shader.json +++ b/Shaders/volumetric_light/volumetric_light.json @@ -42,10 +42,6 @@ "name": "lightColor", "link": "_lampColor" }, - { - "name": "lightStrength", - "link": "_lampStrength" - }, { "name": "snoise", "link": "_noise8" diff --git a/Shaders/water_pass/water_pass.shader.json b/Shaders/water_pass/water_pass.json similarity index 100% rename from Shaders/water_pass/water_pass.shader.json rename to Shaders/water_pass/water_pass.json diff --git a/Shaders/world/world.shader.json b/Shaders/world/world.json similarity index 100% rename from Shaders/world/world.shader.json rename to Shaders/world/world.json diff --git a/blender/exporter.py b/blender/exporter.py index 7da7b283..35d0b362 100755 --- a/blender/exporter.py +++ b/blender/exporter.py @@ -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))) diff --git a/blender/make.py b/blender/make.py index e926a948..87519745 100755 --- a/blender/make.py +++ b/blender/make.py @@ -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: diff --git a/blender/material/__init__.py b/blender/material/__init__.py new file mode 100755 index 00000000..e69de29b diff --git a/blender/material/make.py b/blender/material/make.py new file mode 100644 index 00000000..d75ddf14 --- /dev/null +++ b/blender/material/make.py @@ -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()) diff --git a/blender/material/make_cycles.py b/blender/material/make_cycles.py new file mode 100644 index 00000000..e69de29b diff --git a/blender/material/make_forward.py b/blender/material/make_forward.py new file mode 100644 index 00000000..0c0bc2bc --- /dev/null +++ b/blender/material/make_forward.py @@ -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 + \ No newline at end of file diff --git a/blender/material/shader.py b/blender/material/shader.py new file mode 100644 index 00000000..16613ed8 --- /dev/null +++ b/blender/material/shader.py @@ -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 diff --git a/blender/material/shader_data.py b/blender/material/shader_data.py new file mode 100644 index 00000000..e4760142 --- /dev/null +++ b/blender/material/shader_data.py @@ -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 diff --git a/blender/material/state.py b/blender/material/state.py new file mode 100644 index 00000000..d845fdd1 --- /dev/null +++ b/blender/material/state.py @@ -0,0 +1,8 @@ +data = None +material = None +group = None +nodes = None +links = None +mat_context = None +defs = None +path = None diff --git a/blender/props.py b/blender/props.py index 077727e6..cae52c4f 100755 --- a/blender/props.py +++ b/blender/props.py @@ -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) diff --git a/blender/props_ui.py b/blender/props_ui.py index 05597a3e..bfb392fb 100644 --- a/blender/props_ui.py +++ b/blender/props_ui.py @@ -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')