#!/usr/bin/python3 # Copyright (C) 2009-2018, Panagiotis Christopoulos Charitos and contributors. # All rights reserved. # Code licensed under the BSD License. # http://www.anki3d.org/LICENSE import os import argparse # Template template_xml = """ vert %vertInputs% frag %fragInputs% """ # Input type INPUT_NONE = 0 INPUT_TEXTURE = 1 INPUT_CONST = 2 INPUT_VALUE = 3 # non-const INPUT_COUNT = 4 # Variables DIFFUSE = 0 SPECULAR = 1 ROUGHNESS = 2 METALLIC = 3 NORMAL = 4 EMISSION = 5 SUBSURFACE = 6 HEIGHT = 7 VARIABLE_COUNT = 8 allowed_permutations = [ [INPUT_TEXTURE, INPUT_CONST], [INPUT_TEXTURE, INPUT_CONST], [INPUT_TEXTURE, INPUT_CONST], [INPUT_TEXTURE, INPUT_CONST], [INPUT_TEXTURE, INPUT_NONE], [INPUT_TEXTURE, INPUT_CONST], [INPUT_CONST], [INPUT_NONE, INPUT_TEXTURE]] def parse_commandline(): """ Parse the command line arguments """ parser = argparse.ArgumentParser(description = "Create shader program permutations", formatter_class = argparse.ArgumentDefaultsHelpFormatter) parser.add_argument("-o", "--output-dir", required = True, help = "specify the output directory") args = parser.parse_args() return args.output_dir def spin_wheel(wheel): """ Spin the wheel """ done = False start = VARIABLE_COUNT - 1 while True: if start == -1: done = True break wheel[start] += 1 if wheel[start] >= INPUT_COUNT: wheel[start] = INPUT_NONE start = start - 1 else: break return done def mutate(wheel): """ Create the mutation's source """ parallax = wheel[HEIGHT] == INPUT_TEXTURE # Vert input & source if parallax: vert_inputs = """ mat4mvp mat3normalMat0 mat4modelViewMat0 """ vert_src = """#if COLOR positionUvNormalTangent(mvp, normalMat); parallax(vodelViewMat); #else ANKI_WRITE_POSITION(mvp * vec4(in_position, 1.0)); #endif """ else: vert_inputs = """ mat4mvp mat3normalMat0 """ vert_src = """#if COLOR positionUvNormalTangent(mvp, normalMat); #else ANKI_WRITE_POSITION(mvp * vec4(in_position, 1.0)); #endif """ # Frag inputs & source & filename frag_ins = "" frag_src = "#if COLOR\n" fname = "ms_" if parallax: frag_ins += "\t\t\t\tfloatheightMapScale10\n" frag_src += "vec2 uv = computeTextureCoordParallax(heightTex, in_uv, heightMapScale);\n" else: frag_src += "vec2 uv = in_uv;\n" if wheel[DIFFUSE] == INPUT_TEXTURE: frag_ins += "\t\t\t\tsampler2DdiffTex0\n" frag_src += "vec3 diffColor = texture(diffTex, uv).rgb;\n" fname += "difft_" elif wheel[DIFFUSE] == INPUT_CONST: frag_ins += "\t\t\t\tvec3diffColor10\n" fname += "diffc_" else: assert 0 if wheel[SPECULAR] == INPUT_TEXTURE: frag_ins += "\t\t\t\tsampler2DspecTex0\n" frag_src += "vec3 specColor = texture(specTex, uv).rgb;\n" fname += "spect_" elif wheel[SPECULAR] == INPUT_CONST: frag_ins += "\t\t\t\tvec3specColor10\n" fname += "specc_" else: assert 0 if wheel[ROUGHNESS] == INPUT_TEXTURE: frag_ins += "\t\t\t\tsampler2DroughnessTex0\n" frag_src += "float roughness = texture(roughnessTex, uv).r;\n" fname += "rought_" elif wheel[ROUGHNESS] == INPUT_CONST: frag_ins += "\t\t\t\tfloatroughness10\n" fname += "roughc_" else: assert 0 if wheel[METALLIC] == INPUT_TEXTURE: frag_ins += "\t\t\t\tsampler2DmetallicTex0\n" frag_src += "float metallic = texture(metallicTex, uv).r;\n" fname += "metalt_" elif wheel[METALLIC] == INPUT_CONST: frag_ins += "\t\t\t\tfloatmetallic10\n" fname += "metalc_" else: assert 0 if wheel[NORMAL] == INPUT_TEXTURE: frag_ins += "\t\t\t\tsampler2DnormalTex0\n" frag_src += "vec3 normal = readNormalFromTexture(normalTex, uv);\n" fname += "normalt_" elif wheel[NORMAL] == INPUT_NONE: frag_src += "vec3 normal = in_normal;\n" fname += "normal0_" else: assert 0 if wheel[EMISSION] == INPUT_TEXTURE: frag_ins += "\t\t\t\tsampler2DemissionTex0\n" frag_src += "vec3 emission = texture(emissionTex, uv).rgb;\n" fname += "emist_" elif wheel[EMISSION] == INPUT_CONST: frag_ins += "\t\t\t\tvec3emission10\n" fname += "emisc_" else: assert 0 if wheel[SUBSURFACE] == INPUT_CONST: frag_ins += "\t\t\t\tfloatsubsurface10\n" fname += "subsc_" else: assert 0 if wheel[HEIGHT] == INPUT_NONE: # nothing fname += "par0" elif wheel[HEIGHT] == INPUT_TEXTURE: frag_ins += "\t\t\t\tsampler2DheightTex0\n" fname += "par1" else: assert 0 frag_src += "writeRts(diffColor, normal, specColor, roughness, subsurface, emission, metallic);\n" frag_src += "#endif\n" xml = template_xml xml = xml.replace("%vertInputs%", vert_inputs) xml = xml.replace("%vertSrc%", vert_src) xml = xml.replace("%fragInputs%", frag_ins) xml = xml.replace("%fragSrc%", frag_src) return (xml, fname) def main(): """ Main function """ out_dir = parse_commandline() wheel = [INPUT_NONE, INPUT_NONE, INPUT_NONE, INPUT_NONE, INPUT_NONE, INPUT_NONE, INPUT_NONE, INPUT_NONE] while(not spin_wheel(wheel)): if wheel[DIFFUSE] in allowed_permutations[DIFFUSE] \ and wheel[SPECULAR] in allowed_permutations[SPECULAR] \ and wheel[ROUGHNESS] in allowed_permutations[ROUGHNESS] \ and wheel[METALLIC] in allowed_permutations[METALLIC] \ and wheel[NORMAL] in allowed_permutations[NORMAL] \ and wheel[EMISSION] in allowed_permutations[EMISSION] \ and wheel[SUBSURFACE] in allowed_permutations[SUBSURFACE] \ and wheel[HEIGHT] in allowed_permutations[HEIGHT]: (xml, fname) = mutate(wheel) file = open(fname + ".ankiprog", "w") file.write(xml) if __name__ == "__main__": main()