Material compiler fixes
This commit is contained in:
parent
083cebe60f
commit
0c4cc2fc70
|
@ -80,6 +80,7 @@ void main() {
|
|||
vec2 metrough = unpackFloat(g0.b);
|
||||
|
||||
vec4 g1 = texture(gbuffer1, texCoord); // Basecolor.rgb, spec/occ
|
||||
float spec = floor(g1.a) / 100.0;
|
||||
vec3 albedo = surfaceAlbedo(g1.rgb, metrough.x); // g1.rgb - basecolor
|
||||
|
||||
#ifdef _IndPos
|
||||
|
@ -109,11 +110,14 @@ void main() {
|
|||
#else
|
||||
vec4 indirectDiffuse = traceDiffuse(voxpos, n, voxels);
|
||||
#endif
|
||||
|
||||
vec3 indirectSpecular = traceSpecular(voxels, voxpos, n, v, metrough.y);
|
||||
indirectSpecular *= f0 * envBRDF.x + envBRDF.y;
|
||||
|
||||
fragColor.rgb = indirectDiffuse.rgb * voxelgiDiff * g1.rgb + indirectSpecular * voxelgiSpec;
|
||||
fragColor.rgb = indirectDiffuse.rgb * voxelgiDiff * g1.rgb;
|
||||
|
||||
if (spec > 0.0) {
|
||||
vec3 indirectSpecular = traceSpecular(voxels, voxpos, n, v, metrough.y);
|
||||
indirectSpecular *= f0 * envBRDF.x + envBRDF.y;
|
||||
fragColor.rgb += indirectSpecular * voxelgiSpec * spec;
|
||||
}
|
||||
|
||||
// if (!isInsideCube(voxpos)) fragColor = vec4(1.0); // Show bounds
|
||||
|
||||
|
@ -147,7 +151,7 @@ void main() {
|
|||
envl.rgb *= albedo;
|
||||
|
||||
#ifdef _Rad // Indirect specular
|
||||
envl.rgb += prefilteredColor * (f0 * envBRDF.x + envBRDF.y) * 1.5;
|
||||
envl.rgb += prefilteredColor * (f0 * envBRDF.x + envBRDF.y) * 1.5 * spec;
|
||||
#else
|
||||
#ifdef _EnvCol
|
||||
envl.rgb += backgroundCol * surfaceF0(g1.rgb, metrough.x); // f0
|
||||
|
|
|
@ -204,7 +204,7 @@ void main() {
|
|||
const float shinyPerpendicular = 0.1;
|
||||
const vec3 v = vec3(0.99146, 0.11664, 0.05832);
|
||||
vec3 T = abs(dot(n, v)) > 0.99999 ? cross(n, vec3(0.0, 1.0, 0.0)) : cross(n, v);
|
||||
fragColor.rgb = orenNayarDiffuseBRDF(albedo, metrough.y, dotNV, dotNL, dotVH) + wardSpecular(n, h, dotNL, dotNV, dotNH, T, shinyParallel, shinyPerpendicular);
|
||||
fragColor.rgb = orenNayarDiffuseBRDF(albedo, metrough.y, dotNV, dotNL, dotVH) + wardSpecular(n, h, dotNL, dotNV, dotNH, T, shinyParallel, shinyPerpendicular) * spec;
|
||||
}
|
||||
else fragColor.rgb = lambertDiffuseBRDF(albedo, dotNL) + specularBRDF(f0, metrough.y, dotNL, dotNH, dotNV, dotVH) * spec;
|
||||
#else
|
||||
|
|
|
@ -75,6 +75,7 @@ out vec4 fragColor;
|
|||
void main() {
|
||||
vec4 g0 = texture(gbuffer0, texCoord); // Normal.xy, metallic/roughness, depth
|
||||
vec4 g1 = texture(gbuffer1, texCoord); // Basecolor.rgb, spec/occ
|
||||
float spec = floor(g1.a) / 100.0;
|
||||
// float depth = texture(gbufferD, texCoord).r * 2.0 - 1.0; // 0 - 1 => -1 - 1
|
||||
// TODO: store_depth
|
||||
// TODO: Firefox throws feedback loop detected error, read depth from gbuffer0
|
||||
|
@ -136,14 +137,14 @@ void main() {
|
|||
const float shinyPerpendicular = 0.1;
|
||||
const vec3 v = vec3(0.99146, 0.11664, 0.05832);
|
||||
vec3 T = abs(dot(n, v)) > 0.99999 ? cross(n, vec3(0.0, 1.0, 0.0)) : cross(n, v);
|
||||
fragColor.rgb = orenNayarDiffuseBRDF(albedo, metrough.y, dotNV, dotNL, dotVH) + wardSpecular(n, h, dotNL, dotNV, dotNH, T, shinyParallel, shinyPerpendicular);
|
||||
fragColor.rgb = orenNayarDiffuseBRDF(albedo, metrough.y, dotNV, dotNL, dotVH) + wardSpecular(n, h, dotNL, dotNV, dotNH, T, shinyParallel, shinyPerpendicular) * spec;
|
||||
}
|
||||
else fragColor.rgb = lambertDiffuseBRDF(albedo, dotNL) + specularBRDF(f0, metrough.y, dotNL, dotNH, dotNV, dotVH);
|
||||
else fragColor.rgb = lambertDiffuseBRDF(albedo, dotNL) + specularBRDF(f0, metrough.y, dotNL, dotNH, dotNV, dotVH) * spec;
|
||||
#else
|
||||
#ifdef _OrenNayar
|
||||
fragColor.rgb = orenNayarDiffuseBRDF(albedo, metrough.y, dotNV, dotNL, dotVH) + specularBRDF(f0, metrough.y, dotNL, dotNH, dotNV, dotVH);
|
||||
fragColor.rgb = orenNayarDiffuseBRDF(albedo, metrough.y, dotNV, dotNL, dotVH) + specularBRDF(f0, metrough.y, dotNL, dotNH, dotNV, dotVH) * spec;
|
||||
#else
|
||||
fragColor.rgb = lambertDiffuseBRDF(albedo, dotNL) + specularBRDF(f0, metrough.y, dotNL, dotNH, dotNV, dotVH);
|
||||
fragColor.rgb = lambertDiffuseBRDF(albedo, dotNL) + specularBRDF(f0, metrough.y, dotNL, dotNH, dotNV, dotVH) * spec;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
uniform sampler2D tex;
|
||||
uniform sampler2D gbufferD;
|
||||
uniform sampler2D gbuffer0; // Normal, roughness
|
||||
uniform sampler2D gbuffer1; // basecol, spec
|
||||
uniform mat4 P;
|
||||
uniform mat4 tiV;
|
||||
uniform vec2 cameraProj;
|
||||
|
@ -129,6 +130,12 @@ void main() {
|
|||
fragColor.rgb = vec3(0.0);
|
||||
return;
|
||||
}
|
||||
|
||||
float spec = floor(texture(gbuffer1, texCoord).a) / 100.0;
|
||||
if (spec == 0.0) {
|
||||
fragColor.rgb = vec3(0.0);
|
||||
return;
|
||||
}
|
||||
|
||||
float d = texture(gbufferD, texCoord).r * 2.0 - 1.0;
|
||||
if (d == 1.0) {
|
||||
|
|
|
@ -715,6 +715,7 @@ class RenderPathDeferred {
|
|||
path.bindTarget("tex", "tex");
|
||||
path.bindTarget("_main", "gbufferD");
|
||||
path.bindTarget("gbuffer0", "gbuffer0");
|
||||
path.bindTarget("gbuffer1", "gbuffer1");
|
||||
path.drawShader("shader_datas/ssr_pass/ssr_pass");
|
||||
|
||||
path.setTarget(targetb);
|
||||
|
|
|
@ -143,10 +143,8 @@ def parse_input(inp):
|
|||
def parse_shader_input(inp):
|
||||
if inp.is_linked:
|
||||
l = inp.links[0]
|
||||
|
||||
if l.from_node.type == 'REROUTE':
|
||||
return parse_shader_input(l.from_node.inputs[0])
|
||||
|
||||
return parse_shader(l.from_node, l.from_socket)
|
||||
else:
|
||||
out_basecol = 'vec3(0.8)'
|
||||
|
@ -157,16 +155,6 @@ def parse_shader_input(inp):
|
|||
out_opacity = '1.0'
|
||||
return out_basecol, out_roughness, out_metallic, out_occlusion, out_specular, out_opacity
|
||||
|
||||
def write_normal(inp):
|
||||
if inp.is_linked:
|
||||
normal_res = parse_vector_input(inp)
|
||||
if normal_res != None:
|
||||
curshader.write('n = {0};'.format(normal_res))
|
||||
|
||||
def parsing_basecolor(b):
|
||||
global parsing_basecol
|
||||
parsing_basecol = b
|
||||
|
||||
def parse_shader(node, socket):
|
||||
global emission_found
|
||||
out_basecol = 'vec3(0.8)'
|
||||
|
@ -177,8 +165,7 @@ def parse_shader(node, socket):
|
|||
out_opacity = '1.0'
|
||||
|
||||
if node.type == 'GROUP':
|
||||
if node.node_tree.name.startswith('Armory PBR'):
|
||||
|
||||
if node.node_tree.name.startswith('Armory PBR'):
|
||||
if parse_surface:
|
||||
# Base color
|
||||
parsing_basecolor(True)
|
||||
|
@ -199,10 +186,8 @@ def parse_shader(node, socket):
|
|||
out_emission = parse_value_input(node.inputs[6])
|
||||
emission_found = True
|
||||
out_basecol = '({0} + vec3({1} * 100.0))'.format(out_basecol, out_emission)
|
||||
|
||||
if parse_opacity:
|
||||
out_opacity = parse_value_input(node.inputs[1])
|
||||
|
||||
else:
|
||||
return parse_group(node, socket)
|
||||
|
||||
|
@ -254,7 +239,7 @@ def parse_shader(node, socket):
|
|||
# subsurface = parse_vector_input(node.inputs[1])
|
||||
# subsurface_radius = parse_vector_input(node.inputs[2])
|
||||
# subsurface_color = parse_vector_input(node.inputs[3])
|
||||
# specular = parse_vector_input(node.inputs[5])
|
||||
out_specular = parse_value_input(node.inputs[5])
|
||||
# specular_tint = parse_vector_input(node.inputs[6])
|
||||
# aniso = parse_vector_input(node.inputs[8])
|
||||
# aniso_rot = parse_vector_input(node.inputs[9])
|
||||
|
@ -368,71 +353,20 @@ def parse_shader(node, socket):
|
|||
def parse_displacement_input(inp):
|
||||
if inp.is_linked:
|
||||
l = inp.links[0]
|
||||
|
||||
if l.from_node.type == 'REROUTE':
|
||||
return parse_displacement_input(l.from_node.inputs[0])
|
||||
|
||||
return parse_value_input(inp)
|
||||
else:
|
||||
return None
|
||||
|
||||
def res_var_name(node, socket):
|
||||
return node_name(node.name) + '_' + safesrc(socket.name) + '_res'
|
||||
|
||||
def write_result(l):
|
||||
res_var = res_var_name(l.from_node, l.from_socket)
|
||||
st = l.from_socket.type
|
||||
if res_var not in parsed:
|
||||
parsed[res_var] = 0
|
||||
if st == 'RGB' or st == 'RGBA':
|
||||
res = parse_rgb(l.from_node, l.from_socket)
|
||||
if res == None:
|
||||
return None
|
||||
curshader.write('vec3 {0} = {1};'.format(res_var, res))
|
||||
elif st == 'VECTOR':
|
||||
res = parse_vector(l.from_node, l.from_socket)
|
||||
if res == None:
|
||||
return None
|
||||
size = 3
|
||||
if isinstance(res, tuple):
|
||||
size = res[1]
|
||||
parsed[res_var] = size
|
||||
res = res[0]
|
||||
curshader.write('vec{2} {0} = {1};'.format(res_var, res, size))
|
||||
elif st == 'VALUE':
|
||||
res = parse_value(l.from_node, l.from_socket)
|
||||
if res == None:
|
||||
return None
|
||||
curshader.write('float {0} = {1};'.format(res_var, res))
|
||||
# Normal map already parsed, return
|
||||
elif l.from_node.type == 'NORMAL_MAP':
|
||||
return None
|
||||
return res_var
|
||||
|
||||
def glsl_type(t):
|
||||
if t == 'RGB' or t == 'RGBA' or t == 'VECTOR':
|
||||
return 'vec3'
|
||||
else:
|
||||
return 'float'
|
||||
|
||||
def to_uniform(inp):
|
||||
uname = safesrc(inp.node.name) + safesrc(inp.name)
|
||||
curshader.add_uniform(glsl_type(inp.type) + ' ' + uname)
|
||||
return uname
|
||||
|
||||
def parse_vector_input(inp, vec_size=None):
|
||||
def parse_vector_input(inp):
|
||||
if inp.is_linked:
|
||||
l = inp.links[0]
|
||||
|
||||
if l.from_node.type == 'REROUTE':
|
||||
return parse_vector_input(l.from_node.inputs[0], vec_size=vec_size)
|
||||
|
||||
return parse_vector_input(l.from_node.inputs[0])
|
||||
res_var = write_result(l)
|
||||
st = l.from_socket.type
|
||||
if st == 'RGB' or st == 'RGBA' or st == 'VECTOR':
|
||||
# Convert
|
||||
if vec_size == 3 and parsed[res_var] == 2:
|
||||
res_var = 'vec3({0}.xy, 0.0)'.format(res_var)
|
||||
return res_var
|
||||
else: # VALUE
|
||||
return 'vec3({0})'.format(res_var)
|
||||
|
@ -463,15 +397,23 @@ def parse_rgb(node, socket):
|
|||
return to_vec3(socket.default_value)
|
||||
|
||||
elif node.type == 'TEX_BRICK':
|
||||
# Pass through
|
||||
return to_vec3([0.0, 0.0, 0.0])
|
||||
curshader.add_function(c_functions.str_tex_brick)
|
||||
if node.inputs[0].is_linked:
|
||||
co = parse_vector_input(node.inputs[0])
|
||||
else:
|
||||
co = 'bposition'
|
||||
col1 = parse_vector_input(node.inputs[1])
|
||||
col2 = parse_vector_input(node.inputs[2])
|
||||
col3 = parse_vector_input(node.inputs[3])
|
||||
scale = parse_value_input(node.inputs[4])
|
||||
return 'tex_brick({0} * {4}, {1}, {2}, {3})'.format(co, col1, col2, col3, scale)
|
||||
|
||||
elif node.type == 'TEX_CHECKER':
|
||||
curshader.add_function(c_functions.str_tex_checker)
|
||||
if node.inputs[0].is_linked:
|
||||
co = parse_vector_input(node.inputs[0])
|
||||
else:
|
||||
co = 'mposition'
|
||||
co = 'bposition'
|
||||
col1 = parse_vector_input(node.inputs[1])
|
||||
col2 = parse_vector_input(node.inputs[2])
|
||||
scale = parse_value_input(node.inputs[3])
|
||||
|
@ -485,7 +427,7 @@ def parse_rgb(node, socket):
|
|||
if node.inputs[0].is_linked:
|
||||
co = parse_vector_input(node.inputs[0])
|
||||
else:
|
||||
co = 'mposition'
|
||||
co = 'bposition'
|
||||
grad = node.gradient_type
|
||||
if grad == 'LINEAR':
|
||||
f = '{0}.x'.format(co)
|
||||
|
@ -526,27 +468,35 @@ def parse_rgb(node, socket):
|
|||
return '{0}.rgb'.format(tex_store)
|
||||
|
||||
elif node.type == 'TEX_MAGIC':
|
||||
# Pass through
|
||||
return to_vec3([0.0, 0.0, 0.0])
|
||||
|
||||
elif node.type == 'TEX_MUSGRAVE':
|
||||
# Fall back to noise
|
||||
curshader.add_function(c_functions.str_tex_noise)
|
||||
curshader.add_function(c_functions.str_tex_magic)
|
||||
if node.inputs[0].is_linked:
|
||||
co = parse_vector_input(node.inputs[0])
|
||||
else:
|
||||
co = 'mposition'
|
||||
co = 'bposition'
|
||||
scale = parse_value_input(node.inputs[1])
|
||||
return 'vec3(tex_magic({0} * {1} * 4.0))'.format(co, scale)
|
||||
|
||||
elif node.type == 'TEX_MUSGRAVE':
|
||||
curshader.add_function(c_functions.str_tex_musgrave)
|
||||
if node.inputs[0].is_linked:
|
||||
co = parse_vector_input(node.inputs[0])
|
||||
else:
|
||||
co = 'bposition'
|
||||
scale = parse_value_input(node.inputs[1])
|
||||
# detail = parse_value_input(node.inputs[2])
|
||||
# distortion = parse_value_input(node.inputs[3])
|
||||
return 'vec3(tex_noise_f({0} * {1}))'.format(co, scale)
|
||||
return 'vec3(tex_musgrave_f({0} * {1} * 0.5))'.format(co, scale)
|
||||
|
||||
elif node.type == 'TEX_NOISE':
|
||||
curshader.add_function(c_functions.str_tex_noise)
|
||||
assets_add(get_sdk_path() + '/armory/Assets/' + 'noise256.png')
|
||||
assets_add_embedded_data('noise256.png')
|
||||
curshader.add_uniform('sampler2D snoise256', link='_noise256')
|
||||
curshader.add_function(c_functions.str_tex_noise)
|
||||
if node.inputs[0].is_linked:
|
||||
co = parse_vector_input(node.inputs[0])
|
||||
else:
|
||||
co = 'mposition'
|
||||
co = 'bposition'
|
||||
scale = parse_value_input(node.inputs[1])
|
||||
# detail = parse_value_input(node.inputs[2])
|
||||
# distortion = parse_value_input(node.inputs[3])
|
||||
|
@ -563,34 +513,33 @@ def parse_rgb(node, socket):
|
|||
|
||||
elif node.type == 'TEX_VORONOI':
|
||||
curshader.add_function(c_functions.str_tex_voronoi)
|
||||
assets_add(get_sdk_path() + '/armory/Assets/' + 'noise64.png')
|
||||
assets_add_embedded_data('noise64.png')
|
||||
curshader.add_uniform('sampler2D snoise', link='_noise64')
|
||||
assets_add(get_sdk_path() + '/armory/Assets/' + 'noise256.png')
|
||||
assets_add_embedded_data('noise256.png')
|
||||
curshader.add_uniform('sampler2D snoise256', link='_noise256')
|
||||
if node.inputs[0].is_linked:
|
||||
co = parse_vector_input(node.inputs[0])
|
||||
else:
|
||||
co = 'mposition'
|
||||
co = 'bposition'
|
||||
scale = parse_value_input(node.inputs[1])
|
||||
if node.coloring == 'INTENSITY':
|
||||
return 'vec3(tex_voronoi({0} / (1.0 / {1})).a)'.format(co, scale)
|
||||
return 'vec3(tex_voronoi({0} * {1}).a)'.format(co, scale)
|
||||
else: # CELLS
|
||||
return 'tex_voronoi({0} / (1.0 / {1})).rgb'.format(co, scale)
|
||||
return 'tex_voronoi({0} * {1}).rgb'.format(co, scale)
|
||||
|
||||
elif node.type == 'TEX_WAVE':
|
||||
# Pass through
|
||||
return to_vec3([0.0, 0.0, 0.0])
|
||||
curshader.add_function(c_functions.str_tex_wave)
|
||||
if node.inputs[0].is_linked:
|
||||
co = parse_vector_input(node.inputs[0])
|
||||
else:
|
||||
co = 'bposition'
|
||||
scale = parse_value_input(node.inputs[1])
|
||||
return 'vec3(tex_wave_f({0} * {1}))'.format(co, scale)
|
||||
|
||||
elif node.type == 'BRIGHTCONTRAST':
|
||||
out_col = parse_vector_input(node.inputs[0])
|
||||
bright = parse_value_input(node.inputs[1])
|
||||
contr = parse_value_input(node.inputs[2])
|
||||
curshader.add_function(\
|
||||
"""vec3 brightcontrast(const vec3 col, const float bright, const float contr) {
|
||||
float a = 1.0 + contr;
|
||||
float b = bright - contr * 0.5;
|
||||
return max(a * col + b, 0.0);
|
||||
}
|
||||
""")
|
||||
curshader.add_function(c_functions.str_brightcontrast)
|
||||
return 'brightcontrast({0}, {1}, {2})'.format(out_col, bright, contr)
|
||||
|
||||
elif node.type == 'GAMMA':
|
||||
|
@ -616,8 +565,8 @@ def parse_rgb(node, socket):
|
|||
fac = parse_value_input(node.inputs[0])
|
||||
fac_var = node_name(node.name) + '_fac'
|
||||
curshader.write('float {0} = {1};'.format(fac_var, fac))
|
||||
col1 = parse_vector_input(node.inputs[1], vec_size=3)
|
||||
col2 = parse_vector_input(node.inputs[2], vec_size=3)
|
||||
col1 = parse_vector_input(node.inputs[1])
|
||||
col2 = parse_vector_input(node.inputs[2])
|
||||
blend = node.blend_type
|
||||
if blend == 'MIX':
|
||||
out_col = 'mix({0}, {1}, {2})'.format(col1, col2, fac_var)
|
||||
|
@ -693,20 +642,6 @@ def parse_rgb(node, socket):
|
|||
return 'mix({0}, {1}, clamp(({2} - {3}) * (1.0 / (1.0 - {3})), 0.0, 1.0))'.format(to_vec3(elems[0].color), to_vec3(elems[1].color), fac, elems[0].position)
|
||||
|
||||
elif node.type == 'COMBHSV':
|
||||
# vec3 hsv2rgb(vec3 c) {
|
||||
# vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
||||
# vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
|
||||
# return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
||||
# }
|
||||
# vec3 rgb2hsv(vec3 c) {
|
||||
# vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
|
||||
# vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
|
||||
# vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
|
||||
|
||||
# float d = q.x - min(q.w, q.y);
|
||||
# float e = 1.0e-10;
|
||||
# return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
|
||||
# }
|
||||
# Pass constant
|
||||
return to_vec3([0.0, 0.0, 0.0])
|
||||
|
||||
|
@ -722,39 +657,6 @@ def parse_rgb(node, socket):
|
|||
# Roughly map to cycles - 450 to 600 nanometers
|
||||
return 'wavelength_to_rgb(({0} - 450.0) / 150.0)'.format(wl)
|
||||
|
||||
def store_var_name(node):
|
||||
return node_name(node.name) + '_store'
|
||||
|
||||
def texture_store(node, tex, tex_name, to_linear=False):
|
||||
global parsing_basecol
|
||||
global basecol_texname
|
||||
global sample_bump
|
||||
global sample_bump_res
|
||||
mat_bind_texture(tex)
|
||||
con.add_elem('tex', 2)
|
||||
curshader.add_uniform('sampler2D {0}'.format(tex_name))
|
||||
if node.inputs[0].is_linked:
|
||||
uv_name = parse_vector_input(node.inputs[0])
|
||||
else:
|
||||
uv_name = 'texCoord'
|
||||
tex_store = store_var_name(node)
|
||||
if mat_texture_grad():
|
||||
curshader.write('vec4 {0} = textureGrad({1}, {2}.xy, g2.xy, g2.zw);'.format(tex_store, tex_name, uv_name))
|
||||
else:
|
||||
curshader.write('vec4 {0} = texture({1}, {2}.xy);'.format(tex_store, tex_name, uv_name))
|
||||
if sample_bump:
|
||||
sample_bump_res = tex_store
|
||||
curshader.write('float {0}_1 = textureOffset({1}, {2}, ivec2(-2, 0)).r;'.format(tex_store, tex_name, uv_name))
|
||||
curshader.write('float {0}_2 = textureOffset({1}, {2}, ivec2(2, 0)).r;'.format(tex_store, tex_name, uv_name))
|
||||
curshader.write('float {0}_3 = textureOffset({1}, {2}, ivec2(0, -2)).r;'.format(tex_store, tex_name, uv_name))
|
||||
curshader.write('float {0}_4 = textureOffset({1}, {2}, ivec2(0, 2)).r;'.format(tex_store, tex_name, uv_name))
|
||||
sample_bump = False
|
||||
if to_linear:
|
||||
curshader.write('{0}.rgb = pow({0}.rgb, vec3(2.2));'.format(tex_store))
|
||||
if parsing_basecol:
|
||||
basecol_texname = tex_store
|
||||
return tex_store
|
||||
|
||||
def parse_vector(node, socket):
|
||||
global particle_info
|
||||
global sample_bump
|
||||
|
@ -778,8 +680,8 @@ def parse_vector(node, socket):
|
|||
# Second uvmap referenced
|
||||
if len(lays) > 1 and node.attribute_name == lays[1].name:
|
||||
con.add_elem('tex1', 2)
|
||||
return 'texCoord1', 2
|
||||
return 'texCoord', 2
|
||||
return 'vec3(texCoord1.xy, 0.0)'
|
||||
return 'vec3(texCoord.xy, 0.0)'
|
||||
|
||||
elif node.type == 'CAMERA':
|
||||
# View Vector
|
||||
|
@ -822,26 +724,26 @@ def parse_vector(node, socket):
|
|||
elif node.type == 'TEX_COORD':
|
||||
#obj = node.object
|
||||
#dupli = node.from_dupli
|
||||
if socket == node.outputs[0]: # Generated
|
||||
return 'vec2(0.0)', 2
|
||||
if socket == node.outputs[0]: # Generated - bounds
|
||||
return 'bposition'
|
||||
elif socket == node.outputs[1]: # Normal
|
||||
return 'vec2(0.0)', 2
|
||||
return 'n'
|
||||
elif socket == node.outputs[2]: # UV
|
||||
con.add_elem('tex', 2)
|
||||
return 'texCoord', 2
|
||||
return 'vec3(texCoord.x, 1.0 - texCoord.y, 0.0)'
|
||||
elif socket == node.outputs[3]: # Object
|
||||
return 'vec2(0.0)', 2
|
||||
return 'mposition'
|
||||
elif socket == node.outputs[4]: # Camera
|
||||
return 'vec2(0.0)', 2
|
||||
return 'vec3(0.0)' # 'vposition'
|
||||
elif socket == node.outputs[5]: # Window
|
||||
return 'vec2(0.0)', 2
|
||||
return 'vec3(0.0)' # 'wvpposition'
|
||||
elif socket == node.outputs[6]: # Reflection
|
||||
return 'vec2(0.0)', 2
|
||||
return 'vec3(0.0)'
|
||||
|
||||
elif node.type == 'UVMAP':
|
||||
#map = node.uv_map
|
||||
#dupli = node.from_dupli
|
||||
return 'vec2(0.0)', 2
|
||||
return 'vec3(0.0)'
|
||||
|
||||
elif node.type == 'BUMP':
|
||||
# Interpolation strength
|
||||
|
@ -872,22 +774,22 @@ def parse_vector(node, socket):
|
|||
# ZYX rotation, Z axis for now..
|
||||
if node.rotation[2] != 0.0:
|
||||
a = node.rotation[2]
|
||||
out = 'vec2({0}.x * {1} - (1.0 - {0}.y) * {2}, 1.0 - ({0}.x * {2} + (1.0 - {0}.y) * {1}))'.format(out, math.cos(a), math.sin(a))
|
||||
out = 'vec3({0}.x * {1} - (1.0 - {0}.y) * {2}, 1.0 - ({0}.x * {2} + (1.0 - {0}.y) * {1}), 0.0)'.format(out, math.cos(a), math.sin(a))
|
||||
# if node.rotation[1] != 0.0:
|
||||
# a = node.rotation[1]
|
||||
# out = 'vec2({0}.x * {1} - {0}.z * {2}, {0}.x * {2} + {0}.z * {1})'.format(out, math.cos(a), math.sin(a))
|
||||
# out = 'vec3({0}.x * {1} - {0}.z * {2}, {0}.x * {2} + {0}.z * {1}, 0.0)'.format(out, math.cos(a), math.sin(a))
|
||||
# if node.rotation[0] != 0.0:
|
||||
# a = node.rotation[0]
|
||||
# out = 'vec2({0}.y * {1} - {0}.z * {2}, {0}.y * {2} + {0}.z * {1})'.format(out, math.cos(a), math.sin(a))
|
||||
# out = 'vec3({0}.y * {1} - {0}.z * {2}, {0}.y * {2} + {0}.z * {1}, 0.0)'.format(out, math.cos(a), math.sin(a))
|
||||
if node.scale[0] != 1.0 or node.scale[1] != 1.0 or node.scale[2] != 1.0:
|
||||
out = '({0} * vec2({1}, {2}))'.format(out, node.scale[0], node.scale[1])
|
||||
out = '({0} * vec3({1}, {2}, {3}))'.format(out, node.scale[0], node.scale[1], node.scale[2])
|
||||
if node.translation[0] != 0.0 or node.translation[1] != 0.0 or node.translation[2] != 0.0:
|
||||
out = '({0} + vec2({1}, {2}))'.format(out, node.translation[0], node.translation[1])
|
||||
out = '({0} + vec3({1}, {2}, {3}))'.format(out, node.translation[0], node.translation[1], node.translation[2])
|
||||
if node.use_min:
|
||||
out = 'max({0}, vec2({1}, {2}))'.format(out, node.min[0], node.min[1])
|
||||
out = 'max({0}, vec3({1}, {2}, {3}))'.format(out, node.min[0], node.min[1])
|
||||
if node.use_max:
|
||||
out = 'min({0}, vec2({1}, {2}))'.format(out, node.max[0], node.max[1])
|
||||
return out, 2
|
||||
out = 'min({0}, vec3({1}, {2}, {3}))'.format(out, node.max[0], node.max[1])
|
||||
return out
|
||||
|
||||
elif node.type == 'NORMAL':
|
||||
if socket == node.outputs[0]:
|
||||
|
@ -1107,25 +1009,47 @@ def parse_value(node, socket):
|
|||
return '0.0'
|
||||
|
||||
elif node.type == 'TEX_BRICK':
|
||||
return '0.0'
|
||||
curshader.add_function(c_functions.str_tex_brick)
|
||||
if node.inputs[0].is_linked:
|
||||
co = parse_vector_input(node.inputs[0])
|
||||
else:
|
||||
co = 'bposition'
|
||||
scale = parse_value_input(node.inputs[4])
|
||||
return 'tex_brick_f({0} * {1})'.format(co, scale)
|
||||
|
||||
elif node.type == 'TEX_CHECKER':
|
||||
# TODO: do not recompute when color socket is also connected
|
||||
curshader.add_function(c_functions.str_tex_checker)
|
||||
if node.inputs[0].is_linked:
|
||||
co = parse_vector_input(node.inputs[0])
|
||||
else:
|
||||
co = 'mposition'
|
||||
col1 = parse_vector_input(node.inputs[1])
|
||||
col2 = parse_vector_input(node.inputs[2])
|
||||
co = 'bposition'
|
||||
scale = parse_value_input(node.inputs[3])
|
||||
res = 'tex_checker({0}, {1}, {2}, {3}).r'.format(co, col1, col2, scale)
|
||||
res = 'tex_checker_f({0}, {1}).r'.format(co, scale)
|
||||
if sample_bump:
|
||||
write_bump(node, res)
|
||||
return res
|
||||
|
||||
elif node.type == 'TEX_GRADIENT':
|
||||
return '0.0'
|
||||
if node.inputs[0].is_linked:
|
||||
co = parse_vector_input(node.inputs[0])
|
||||
else:
|
||||
co = 'bposition'
|
||||
grad = node.gradient_type
|
||||
if grad == 'LINEAR':
|
||||
f = '{0}.x'.format(co)
|
||||
elif grad == 'QUADRATIC':
|
||||
f = '0.0'
|
||||
elif grad == 'EASING':
|
||||
f = '0.0'
|
||||
elif grad == 'DIAGONAL':
|
||||
f = '({0}.x + {0}.y) * 0.5'.format(co)
|
||||
elif grad == 'RADIAL':
|
||||
f = 'atan({0}.y, {0}.x) / PI2 + 0.5'.format(co)
|
||||
elif grad == 'QUADRATIC_SPHERE':
|
||||
f = '0.0'
|
||||
elif grad == 'SPHERICAL':
|
||||
f = 'max(1.0 - sqrt({0}.x * {0}.x + {0}.y * {0}.y + {0}.z * {0}.z), 0.0)'.format(co)
|
||||
return '(clamp({0}, 0.0, 1.0))'.format(f)
|
||||
|
||||
elif node.type == 'TEX_IMAGE':
|
||||
# Already fetched
|
||||
|
@ -1144,26 +1068,35 @@ def parse_value(node, socket):
|
|||
return '{0}.a'.format(tex_store)
|
||||
|
||||
elif node.type == 'TEX_MAGIC':
|
||||
return '0.0'
|
||||
curshader.add_function(c_functions.str_tex_magic)
|
||||
if node.inputs[0].is_linked:
|
||||
co = parse_vector_input(node.inputs[0])
|
||||
else:
|
||||
co = 'bposition'
|
||||
scale = parse_value_input(node.inputs[1])
|
||||
return 'tex_magic_f({0} * {1} * 4.0)'.format(co, scale)
|
||||
|
||||
elif node.type == 'TEX_MUSGRAVE':
|
||||
# Fall back to noise
|
||||
curshader.add_function(c_functions.str_tex_noise)
|
||||
curshader.add_function(c_functions.str_tex_musgrave)
|
||||
if node.inputs[0].is_linked:
|
||||
co = parse_vector_input(node.inputs[0])
|
||||
else:
|
||||
co = 'mposition'
|
||||
co = 'bposition'
|
||||
scale = parse_value_input(node.inputs[1])
|
||||
# detail = parse_value_input(node.inputs[2])
|
||||
# distortion = parse_value_input(node.inputs[3])
|
||||
return 'tex_noise_f({0} * {1})'.format(co, scale)
|
||||
return 'tex_musgrave_f({0} * {1} * 0.5)'.format(co, scale)
|
||||
|
||||
elif node.type == 'TEX_NOISE':
|
||||
curshader.add_function(c_functions.str_tex_noise)
|
||||
assets_add(get_sdk_path() + '/armory/Assets/' + 'noise256.png')
|
||||
assets_add_embedded_data('noise256.png')
|
||||
curshader.add_uniform('sampler2D snoise256', link='_noise256')
|
||||
if node.inputs[0].is_linked:
|
||||
co = parse_vector_input(node.inputs[0])
|
||||
else:
|
||||
co = 'mposition'
|
||||
co = 'bposition'
|
||||
scale = parse_value_input(node.inputs[1])
|
||||
# detail = parse_value_input(node.inputs[2])
|
||||
# distortion = parse_value_input(node.inputs[3])
|
||||
|
@ -1177,21 +1110,27 @@ def parse_value(node, socket):
|
|||
|
||||
elif node.type == 'TEX_VORONOI':
|
||||
curshader.add_function(c_functions.str_tex_voronoi)
|
||||
assets_add(get_sdk_path() + '/armory/Assets/' + 'noise64.png')
|
||||
assets_add_embedded_data('noise64.png')
|
||||
curshader.add_uniform('sampler2D snoise', link='_noise64')
|
||||
assets_add(get_sdk_path() + '/armory/Assets/' + 'noise256.png')
|
||||
assets_add_embedded_data('noise256.png')
|
||||
curshader.add_uniform('sampler2D snoise256', link='_noise256')
|
||||
if node.inputs[0].is_linked:
|
||||
co = parse_vector_input(node.inputs[0])
|
||||
else:
|
||||
co = 'mposition'
|
||||
co = 'bposition'
|
||||
scale = parse_value_input(node.inputs[1])
|
||||
if node.coloring == 'INTENSITY':
|
||||
return 'tex_voronoi({0} * (1.0 / {1})).a'.format(co, scale)
|
||||
return 'tex_voronoi({0} * {1}).a'.format(co, scale)
|
||||
else: # CELLS
|
||||
return 'tex_voronoi({0} * (1.0 / {1})).r'.format(co, scale)
|
||||
return 'tex_voronoi({0} * {1}).r'.format(co, scale)
|
||||
|
||||
elif node.type == 'TEX_WAVE':
|
||||
return '0.0'
|
||||
curshader.add_function(c_functions.str_tex_wave)
|
||||
if node.inputs[0].is_linked:
|
||||
co = parse_vector_input(node.inputs[0])
|
||||
else:
|
||||
co = 'bposition'
|
||||
scale = parse_value_input(node.inputs[1])
|
||||
return 'tex_wave_f({0} * {1})'.format(co, scale)
|
||||
|
||||
elif node.type == 'LIGHT_FALLOFF':
|
||||
# Constant, linear, quadratic
|
||||
|
@ -1288,6 +1227,90 @@ def parse_value(node, socket):
|
|||
else:
|
||||
return '0.0'
|
||||
|
||||
##
|
||||
|
||||
def write_normal(inp):
|
||||
if inp.is_linked:
|
||||
normal_res = parse_vector_input(inp)
|
||||
if normal_res != None:
|
||||
curshader.write('n = {0};'.format(normal_res))
|
||||
|
||||
def parsing_basecolor(b):
|
||||
global parsing_basecol
|
||||
parsing_basecol = b
|
||||
|
||||
def res_var_name(node, socket):
|
||||
return node_name(node.name) + '_' + safesrc(socket.name) + '_res'
|
||||
|
||||
def write_result(l):
|
||||
res_var = res_var_name(l.from_node, l.from_socket)
|
||||
st = l.from_socket.type
|
||||
if res_var not in parsed:
|
||||
parsed[res_var] = True
|
||||
if st == 'RGB' or st == 'RGBA':
|
||||
res = parse_rgb(l.from_node, l.from_socket)
|
||||
if res == None:
|
||||
return None
|
||||
curshader.write('vec3 {0} = {1};'.format(res_var, res))
|
||||
elif st == 'VECTOR':
|
||||
res = parse_vector(l.from_node, l.from_socket)
|
||||
if res == None:
|
||||
return None
|
||||
curshader.write('vec3 {0} = {1};'.format(res_var, res))
|
||||
elif st == 'VALUE':
|
||||
res = parse_value(l.from_node, l.from_socket)
|
||||
if res == None:
|
||||
return None
|
||||
curshader.write('float {0} = {1};'.format(res_var, res))
|
||||
# Normal map already parsed, return
|
||||
elif l.from_node.type == 'NORMAL_MAP':
|
||||
return None
|
||||
return res_var
|
||||
|
||||
def glsl_type(t):
|
||||
if t == 'RGB' or t == 'RGBA' or t == 'VECTOR':
|
||||
return 'vec3'
|
||||
else:
|
||||
return 'float'
|
||||
|
||||
def to_uniform(inp):
|
||||
uname = safesrc(inp.node.name) + safesrc(inp.name)
|
||||
curshader.add_uniform(glsl_type(inp.type) + ' ' + uname)
|
||||
return uname
|
||||
|
||||
def store_var_name(node):
|
||||
return node_name(node.name) + '_store'
|
||||
|
||||
def texture_store(node, tex, tex_name, to_linear=False):
|
||||
global parsing_basecol
|
||||
global basecol_texname
|
||||
global sample_bump
|
||||
global sample_bump_res
|
||||
mat_bind_texture(tex)
|
||||
con.add_elem('tex', 2)
|
||||
curshader.add_uniform('sampler2D {0}'.format(tex_name))
|
||||
if node.inputs[0].is_linked:
|
||||
uv_name = parse_vector_input(node.inputs[0])
|
||||
else:
|
||||
uv_name = 'texCoord'
|
||||
tex_store = store_var_name(node)
|
||||
if mat_texture_grad():
|
||||
curshader.write('vec4 {0} = textureGrad({1}, {2}.xy, g2.xy, g2.zw);'.format(tex_store, tex_name, uv_name))
|
||||
else:
|
||||
curshader.write('vec4 {0} = texture({1}, {2}.xy);'.format(tex_store, tex_name, uv_name))
|
||||
if sample_bump:
|
||||
sample_bump_res = tex_store
|
||||
curshader.write('float {0}_1 = textureOffset({1}, {2}.xy, ivec2(-2, 0)).r;'.format(tex_store, tex_name, uv_name))
|
||||
curshader.write('float {0}_2 = textureOffset({1}, {2}.xy, ivec2(2, 0)).r;'.format(tex_store, tex_name, uv_name))
|
||||
curshader.write('float {0}_3 = textureOffset({1}, {2}.xy, ivec2(0, -2)).r;'.format(tex_store, tex_name, uv_name))
|
||||
curshader.write('float {0}_4 = textureOffset({1}, {2}.xy, ivec2(0, 2)).r;'.format(tex_store, tex_name, uv_name))
|
||||
sample_bump = False
|
||||
if to_linear:
|
||||
curshader.write('{0}.rgb = pow({0}.rgb, vec3(2.2));'.format(tex_store))
|
||||
if parsing_basecol:
|
||||
basecol_texname = tex_store
|
||||
return tex_store
|
||||
|
||||
def write_bump(node, res):
|
||||
global sample_bump
|
||||
global sample_bump_res
|
||||
|
@ -1311,15 +1334,9 @@ def write_bump(node, res):
|
|||
def to_vec1(v):
|
||||
return str(v)
|
||||
|
||||
def to_vec2(v):
|
||||
return 'vec2({0}, {1})'.format(v[0], v[1])
|
||||
|
||||
def to_vec3(v):
|
||||
return 'vec3({0}, {1}, {2})'.format(v[0], v[1], v[2])
|
||||
|
||||
def to_vec4(v):
|
||||
return 'vec4({0}, {1}, {2}, {3})'.format(v[0], v[1], v[2], v[3])
|
||||
|
||||
def node_by_type(nodes, ntype):
|
||||
for n in nodes:
|
||||
if n.type == ntype:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
str_tex_checker = """vec3 tex_checker(const vec3 co, const vec3 col1, const vec3 col2, const float scale) {
|
||||
vec3 p = co * scale;
|
||||
vec3 p = (co) * scale;
|
||||
// Prevent precision issues on unit coordinates
|
||||
//p.x = (p.x + 0.000001) * 0.999999;
|
||||
//p.y = (p.y + 0.000001) * 0.999999;
|
||||
|
@ -10,20 +10,18 @@ str_tex_checker = """vec3 tex_checker(const vec3 co, const vec3 col1, const vec3
|
|||
bool check = ((mod(xi, 2.0) == mod(yi, 2.0)) == bool(mod(zi, 2.0)));
|
||||
return check ? col1 : col2;
|
||||
}
|
||||
vec3 tex_checker(const vec2 co, const vec3 col1, const vec3 col2, const float scale) {
|
||||
return tex_checker(vec3(co.x, co.y, 1.0), col1, col2, scale);
|
||||
float tex_checker_f(const vec3 co, const float scale) {
|
||||
vec3 p = (co) * scale;
|
||||
float xi = abs(floor(p.x));
|
||||
float yi = abs(floor(p.y));
|
||||
float zi = abs(floor(p.z));
|
||||
return float((mod(xi, 2.0) == mod(yi, 2.0)) == bool(mod(zi, 2.0)));
|
||||
}
|
||||
"""
|
||||
|
||||
# Created by inigo quilez - iq/2013
|
||||
# License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
|
||||
str_tex_voronoi = """//vec3 hash(vec3 x) {
|
||||
//return texture(snoise, (x.xy + vec2(3.0, 1.0) * x.z + 0.5) / 64.0, -100.0).xyz;
|
||||
//x = vec3(dot(x, vec3(127.1, 311.7, 74.7)),
|
||||
// dot(x, vec3(269.5, 183.3, 246.1)),
|
||||
// dot(x, vec3(113.5, 271.9, 124.6)));
|
||||
//return fract(sin(x) * 43758.5453123);
|
||||
//}
|
||||
str_tex_voronoi = """
|
||||
vec4 tex_voronoi(const vec3 x) {
|
||||
vec3 p = floor(x);
|
||||
vec3 f = fract(x);
|
||||
|
@ -34,9 +32,7 @@ vec4 tex_voronoi(const vec3 x) {
|
|||
for (int i = -1; i <= 1; i++) {
|
||||
vec3 b = vec3(float(i), float(j), float(k));
|
||||
vec3 pb = p + b;
|
||||
//vec3 r = vec3(b) - f + texture(snoise, (pb.xy + vec2(3.0, 1.0) * pb.z + 0.5) / 64.0, -100.0).xyz; // No bias in tese
|
||||
vec3 r = vec3(b) - f + texture(snoise, (pb.xy + vec2(3.0, 1.0) * pb.z + 0.5) / 64.0).xyz;
|
||||
//vec3 r = vec3(b) - f + hash(p + b);
|
||||
vec3 r = vec3(b) - f + texture(snoise256, (pb.xy + vec2(3.0, 1.0) * pb.z + 0.5) / 256.0).xyz;
|
||||
float d = dot(r, r);
|
||||
if (d < res) {
|
||||
id = dot(p + b, vec3(1.0, 57.0, 113.0));
|
||||
|
@ -46,36 +42,34 @@ vec4 tex_voronoi(const vec3 x) {
|
|||
vec3 col = 0.5 + 0.5 * cos(id * 0.35 + vec3(0.0, 1.0, 2.0));
|
||||
return vec4(col, sqrt(res));
|
||||
}
|
||||
vec4 tex_voronoi(const vec2 x) {
|
||||
return tex_voronoi(vec3(x.x, x.y, 1.0));
|
||||
"""
|
||||
|
||||
# Based on https://www.shadertoy.com/view/4sfGzS
|
||||
# Copyright © 2013 Inigo Quilez
|
||||
# The MIT License - Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
str_tex_noise = """
|
||||
float tex_noise_f(const vec3 x) {
|
||||
vec3 p = floor(x);
|
||||
vec3 f = fract(x);
|
||||
f = f * f * (3.0 - 2.0 * f);
|
||||
vec2 uv = (p.xy + vec2(37.0, 17.0) * p.z) + f.xy;
|
||||
vec2 rg = texture(snoise256, (uv + 0.5) / 256.0).yx;
|
||||
return mix(rg.x, rg.y, f.z);
|
||||
}
|
||||
float tex_noise(vec3 p) {
|
||||
p *= 1.25;
|
||||
float f = 0.5 * tex_noise_f(p); p *= 2.01;
|
||||
f += 0.25 * tex_noise_f(p); p *= 2.02;
|
||||
f += 0.125 * tex_noise_f(p); p *= 2.03;
|
||||
f += 0.0625 * tex_noise_f(p); p *= 2.01;
|
||||
return 1.0 - f;
|
||||
}
|
||||
"""
|
||||
|
||||
# str_tex_noise = """
|
||||
# float tex_noise_f(const vec3 x) {
|
||||
# vec3 p = floor(x);
|
||||
# vec3 f = fract(x);
|
||||
# f = f * f * (3.0 - 2.0 * f);
|
||||
# vec2 uv = (p.xy + vec2(37.0, 17.0) * p.z) + f.xy;
|
||||
# vec2 rg = texture(snoisea, (uv + 0.5) / 64.0, -100.0).yx;
|
||||
# return mix(rg.x, rg.y, f.z);
|
||||
# }
|
||||
# float tex_noise(vec3 q) {
|
||||
# //return fract(sin(dot(q.xy, vec2(12.9898,78.233))) * 43758.5453);
|
||||
# q *= 2.0; // Match to Cycles
|
||||
# const mat3 m = mat3(0.00, 0.80, 0.60, -0.80, 0.36, -0.48, -0.60, -0.48, 0.64);
|
||||
# float f = 0.5000 * tex_noise_f(q); q = m * q * 2.01;
|
||||
# f += 0.2500 * tex_noise_f(q); q = m * q * 2.02;
|
||||
# f += 0.1250 * tex_noise_f(q); q = m * q * 2.03;
|
||||
# f += 0.0625 * tex_noise_f(q); q = m * q * 2.01;
|
||||
# return pow(f, 3.0);
|
||||
# }
|
||||
# """
|
||||
# Created by Nikita Miropolskiy, nikat/2013
|
||||
# Based on noise created by Nikita Miropolskiy, nikat/2013
|
||||
# Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
|
||||
str_tex_noise = """
|
||||
str_tex_musgrave = """
|
||||
vec3 random3(const vec3 c) {
|
||||
// Might not be precise on lowp floats
|
||||
float j = 4096.0 * sin(dot(c, vec3(17.0, 59.4, 15.0)));
|
||||
vec3 r;
|
||||
r.z = fract(512.0 * j);
|
||||
|
@ -85,7 +79,7 @@ vec3 random3(const vec3 c) {
|
|||
r.y = fract(512.0 * j);
|
||||
return r - 0.5;
|
||||
}
|
||||
float tex_noise_f(const vec3 p) {
|
||||
float tex_musgrave_f(const vec3 p) {
|
||||
const float F3 = 0.3333333;
|
||||
const float G3 = 0.1666667;
|
||||
vec3 s = floor(p + dot(p, vec3(F3)));
|
||||
|
@ -111,15 +105,6 @@ float tex_noise_f(const vec3 p) {
|
|||
d *= w;
|
||||
return clamp(dot(d, vec4(52.0)), 0.0, 1.0);
|
||||
}
|
||||
float tex_noise(const vec3 p) {
|
||||
return 0.5333333 * tex_noise_f(0.5 * p)
|
||||
+ 0.2666667 * tex_noise_f(p)
|
||||
+ 0.1333333 * tex_noise_f(2.0 * p)
|
||||
+ 0.0666667 * tex_noise_f(4.0 * p);
|
||||
}
|
||||
float tex_noise(const vec2 p) {
|
||||
return tex_noise(vec3(p.x, p.y, 1.0));
|
||||
}
|
||||
"""
|
||||
|
||||
str_hsv_to_rgb = """
|
||||
|
@ -149,3 +134,47 @@ vec3 wavelength_to_rgb(const float t) {
|
|||
return 1.0 - r * r;
|
||||
}
|
||||
"""
|
||||
|
||||
str_tex_magic = """
|
||||
vec3 tex_magic(const vec3 p) {
|
||||
float a = 1.0 - (sin(p.x) + sin(p.y));
|
||||
float b = 1.0 - sin(p.x - p.y);
|
||||
float c = 1.0 - sin(p.x + p.y);
|
||||
return vec3(a, b, c);
|
||||
}
|
||||
float tex_magic_f(const vec3 p) {
|
||||
vec3 c = tex_magic(p);
|
||||
return (c.x + c.y + c.z) / 3.0;
|
||||
}
|
||||
"""
|
||||
|
||||
str_tex_brick = """
|
||||
vec3 tex_brick(vec3 p, const vec3 c1, const vec3 c2, const vec3 c3) {
|
||||
p /= vec3(0.9, 0.49, 0.49) / 2;
|
||||
if (fract(p.y * 0.5) > 0.5) p.x += 0.5;
|
||||
p = fract(p);
|
||||
vec3 b = step(p, vec3(0.95, 0.9, 0.9));
|
||||
return mix(c3, c1, b.x * b.y * b.z);
|
||||
}
|
||||
float tex_brick_f(vec3 p) {
|
||||
p /= vec3(0.9, 0.49, 0.49) / 2;
|
||||
if (fract(p.y * 0.5) > 0.5) p.x += 0.5;
|
||||
p = fract(p);
|
||||
vec3 b = step(p, vec3(0.95, 0.9, 0.9));
|
||||
return mix(1.0, 0.0, b.x * b.y * b.z);
|
||||
}
|
||||
"""
|
||||
|
||||
str_tex_wave = """
|
||||
float tex_wave_f(const vec3 p) {
|
||||
return 1.0 - sin((p.x + p.y) * 10.0);
|
||||
}
|
||||
"""
|
||||
|
||||
str_brightcontrast = """
|
||||
vec3 brightcontrast(const vec3 col, const float bright, const float contr) {
|
||||
float a = 1.0 + contr;
|
||||
float b = bright - contr * 0.5;
|
||||
return max(a * col + b, 0.0);
|
||||
}
|
||||
"""
|
||||
|
|
|
@ -90,21 +90,15 @@ def make_finalize(con_mesh):
|
|||
if export_wpos:
|
||||
vert.add_uniform('mat4 W', '_worldMatrix')
|
||||
vert.add_out('vec3 wposition')
|
||||
vert.write_pre = True
|
||||
vert.write_attrib('wposition = vec4(W * spos).xyz;')
|
||||
vert.write_pre = False
|
||||
elif write_wpos:
|
||||
vert.add_uniform('mat4 W', '_worldMatrix')
|
||||
vert.write_pre = True
|
||||
vert.write_attrib('vec3 wposition = vec4(W * spos).xyz;')
|
||||
vert.write_pre = False
|
||||
|
||||
frag_mpos = frag.contains('mposition') and not frag.contains('vec3 mposition')
|
||||
frag_mpos = frag.contains('mposition') and not frag.contains('vec3 mposition') or vert.contains('mposition')
|
||||
if frag_mpos:
|
||||
vert.add_out('vec3 mposition')
|
||||
vert.write_pre = True
|
||||
vert.write('mposition = spos.xyz;')
|
||||
vert.write_pre = False
|
||||
vert.write_attrib('mposition = spos.xyz;')
|
||||
|
||||
if tese != None:
|
||||
if frag_mpos:
|
||||
|
@ -116,6 +110,25 @@ def make_finalize(con_mesh):
|
|||
vert.write_pre = False
|
||||
make_tess.interpolate(tese, 'mposition', 3, declare_out=False)
|
||||
|
||||
frag_bpos = frag.contains('bposition') and not frag.contains('vec3 bposition') or vert.contains('bposition')
|
||||
if frag_bpos:
|
||||
vert.add_out('vec3 bposition')
|
||||
vert.add_uniform('vec3 dim', link='_dim')
|
||||
vert.add_uniform('vec3 hdim', link='_halfDim')
|
||||
vert.write_pre = True
|
||||
vert.write('bposition = (spos.xyz + hdim) / dim;')
|
||||
vert.write_pre = False
|
||||
|
||||
if tese != None:
|
||||
if frag_bpos:
|
||||
make_tess.interpolate(tese, 'bposition', 3, declare_out=True)
|
||||
elif tese.contains('bposition') and not tese.contains('vec3 bposition'):
|
||||
vert.add_out('vec3 bposition')
|
||||
vert.write_pre = True
|
||||
vert.write('bposition = spos.xyz;')
|
||||
vert.write_pre = False
|
||||
make_tess.interpolate(tese, 'bposition', 3, declare_out=False)
|
||||
|
||||
def make_base(con_mesh, parse_opacity):
|
||||
global is_displacement
|
||||
global write_material_attribs
|
||||
|
@ -738,6 +751,9 @@ def make_forward_base(con_mesh, parse_opacity=False):
|
|||
# frag.write('indirect = vec3(1.0 - traceAO(voxpos, n, voxels));') # AO view
|
||||
else:
|
||||
frag.write('vec4 indirectDiffuse = traceDiffuse(voxpos, n, voxels);')
|
||||
frag.write('indirect = indirect * voxelgiEnv + vec3(indirectDiffuse.rgb * voxelgiDiff * basecol);')
|
||||
frag.write('if (specular > 0.0) {')
|
||||
frag.write('vec3 indirectSpecular = traceSpecular(voxels, voxpos, n, vVec, roughness);')
|
||||
frag.write('indirectSpecular *= f0 * envBRDF.x + envBRDF.y;')
|
||||
frag.write('indirect = indirect * voxelgiEnv + vec3(indirectDiffuse.rgb * voxelgiDiff * basecol + indirectSpecular * voxelgiSpec);')
|
||||
frag.write('indirect += indirectSpecular * voxelgiSpec * specular;')
|
||||
frag.write('}')
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import arm.material.cycles as cycles
|
||||
import arm.material.mat_state as mat_state
|
||||
import arm.material.make_mesh as make_mesh
|
||||
import arm.assets as assets
|
||||
|
||||
def make(context_id):
|
||||
con_transluc = mat_state.data.add_context({ 'name': context_id, 'depth_write': False, 'compare_mode': 'less', 'cull_mode': 'clockwise', \
|
||||
|
@ -30,4 +31,9 @@ def make(context_id):
|
|||
frag.write('fragColor[0] = vec4(premultipliedReflect.rgb * w, premultipliedReflect.a);')
|
||||
frag.write('fragColor[1] = vec4(premultipliedReflect.a * w, 0.0, 0.0, 1.0);')
|
||||
|
||||
make_mesh.make_finalize(con_transluc)
|
||||
|
||||
# assets.vs_equal(con_transluc, assets.shader_cons['transluc_vert']) # shader_cons has no transluc yet
|
||||
# assets.fs_equal(con_transluc, assets.shader_cons['transluc_frag'])
|
||||
|
||||
return con_transluc
|
||||
|
|
|
@ -85,6 +85,15 @@ def make_gi(context_id):
|
|||
vert.write('mpositionGeom = pos;')
|
||||
vert.write_pre = False
|
||||
|
||||
export_bpos = frag.contains('bposition') and not frag.contains('vec3 bposition')
|
||||
if export_bpos:
|
||||
vert.add_out('vec3 bpositionGeom')
|
||||
vert.add_uniform('vec3 dim', link='_dim')
|
||||
vert.add_uniform('vec3 hdim', link='_halfDim')
|
||||
vert.write_pre = True
|
||||
vert.write('bpositionGeom = (pos.xyz + hdim) / dim;')
|
||||
vert.write_pre = False
|
||||
|
||||
vert.add_uniform('mat4 W', '_worldMatrix')
|
||||
vert.add_uniform('mat3 N', '_normalMatrix')
|
||||
|
||||
|
@ -117,6 +126,8 @@ def make_gi(context_id):
|
|||
geom.add_out('vec2 texCoord')
|
||||
if export_mpos:
|
||||
geom.add_out('vec3 mposition')
|
||||
if export_bpos:
|
||||
geom.add_out('vec3 bposition')
|
||||
|
||||
geom.write('vec3 p1 = voxpositionGeom[1] - voxpositionGeom[0];')
|
||||
geom.write('vec3 p2 = voxpositionGeom[2] - voxpositionGeom[0];')
|
||||
|
@ -130,6 +141,8 @@ def make_gi(context_id):
|
|||
geom.write(' texCoord = texCoordGeom[i];')
|
||||
if export_mpos:
|
||||
geom.write(' mposition = mpositionGeom[i];')
|
||||
if export_bpos:
|
||||
geom.write(' bposition = bpositionGeom[i];')
|
||||
geom.write(' if (p.z > p.x && p.z > p.y) {')
|
||||
geom.write(' gl_Position = vec4(voxposition.x, voxposition.y, 0.0, 1.0);')
|
||||
geom.write(' }')
|
||||
|
|
Binary file not shown.
Loading…
Reference in a new issue