Improve restricted materials

This commit is contained in:
Lubos Lenco 2017-09-09 13:46:32 +02:00
parent 12cf45a4ed
commit 70c30c308f
5 changed files with 41 additions and 20 deletions

View file

@ -91,3 +91,28 @@ float wardSpecular(vec3 N, vec3 H, float dotNL, float dotNV, float dotNH, vec3 f
float theta = (pow(dotXH/shinyParallel, 2.0) + pow(dotYH/shinyPerpendicular, 2.0)) / (1.0 + dotNH);
return clamp(coeff * exp(-2.0 * theta), 0.0, 1.0);
}
// https://www.unrealengine.com/en-US/blog/physically-based-shading-on-mobile
// vec3 EnvBRDFApprox(vec3 SpecularColor, float Roughness, float NoV) {
// const vec4 c0 = { -1, -0.0275, -0.572, 0.022 };
// const vec4 c1 = { 1, 0.0425, 1.04, -0.04 };
// vec4 r = Roughness * c0 + c1;
// float a004 = min( r.x * r.x, exp2( -9.28 * NoV ) ) * r.x + r.y;
// vec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw;
// return SpecularColor * AB.x + AB.y;
// }
// float EnvBRDFApproxNonmetal(float Roughness, float NoV) {
// // Same as EnvBRDFApprox( 0.04, Roughness, NoV )
// const vec2 c0 = { -1, -0.0275 };
// const vec2 c1 = { 1, 0.0425 };
// vec2 r = Roughness * c0 + c1;
// return min( r.x * r.x, exp2( -9.28 * NoV ) ) * r.x + r.y;
// }
float D_Approx(const float Roughness, const float RoL) {
float a = Roughness * Roughness;
float a2 = a * a;
float rcp_a2 = 1.0 / a2;//rcp(a2);
// 0.5 / ln(2), 0.275 / ln(2)
float c = 0.72134752 * rcp_a2 + 0.39674113;
return rcp_a2 * exp2( c * RoL - c );
}

View file

@ -306,7 +306,7 @@ class Shader {
}
public function contains(s:String):Bool {
return (main.indexOf(s) >= 0 || main_pre.indexOf(s) >= 0 || ins.indexOf(s) >= 0);
return (main.indexOf(s) >= 0 || main_pre.indexOf(s) >= 0 || main_header.indexOf(s) >= 0 || ins.indexOf(s) >= 0);
}
public function prepend(s:String) {

View file

@ -20,12 +20,12 @@ import arm.material.cycles_state as c_state
basecol_texname = ''
emission_found = False
def parse(nodes, con, vert, frag, geom, tesc, tese, parse_surface=True, parse_opacity=True, parse_displacement=True, basecol_only=False):
def parse(nodes, con, vert, frag, geom, tesc, tese, parse_surface=True, parse_opacity=True, parse_displacement=True):
output_node = node_by_type(nodes, 'OUTPUT_MATERIAL')
if output_node != None:
parse_output(output_node, con, vert, frag, geom, tesc, tese, parse_surface, parse_opacity, parse_displacement, basecol_only)
parse_output(output_node, con, vert, frag, geom, tesc, tese, parse_surface, parse_opacity, parse_displacement)
def parse_output(node, _con, _vert, _frag, _geom, _tesc, _tese, _parse_surface, _parse_opacity, _parse_displacement, _basecol_only):
def parse_output(node, _con, _vert, _frag, _geom, _tesc, _tese, _parse_surface, _parse_opacity, _parse_displacement):
global parsed # Compute nodes only once
global parents
global normal_written # Normal socket is linked on shader node - overwrite fs normal
@ -40,7 +40,6 @@ def parse_output(node, _con, _vert, _frag, _geom, _tesc, _tese, _parse_surface,
global parse_opacity
global parsing_basecol
global parse_teximage_vector
global basecol_only
global basecol_texname
global emission_found
con = _con
@ -53,7 +52,6 @@ def parse_output(node, _con, _vert, _frag, _geom, _tesc, _tese, _parse_surface,
parse_opacity = _parse_opacity
parsing_basecol = False
parse_teximage_vector = True
basecol_only = _basecol_only
basecol_texname = ''
emission_found = False
@ -63,18 +61,13 @@ def parse_output(node, _con, _vert, _frag, _geom, _tesc, _tese, _parse_surface,
parents = []
normal_written = False
curshader = frag
if basecol_only:
frag.lock = True
out_basecol, out_roughness, out_metallic, out_occlusion, out_opacity = parse_shader_input(node.inputs[0])
if parse_surface:
frag.lock = False
frag.write('basecol = {0};'.format(out_basecol))
if not basecol_only:
frag.write('roughness = {0};'.format(out_roughness))
frag.write('metallic = {0};'.format(out_metallic))
frag.write('occlusion = {0};'.format(out_occlusion))
frag.write('roughness = {0};'.format(out_roughness))
frag.write('metallic = {0};'.format(out_metallic))
frag.write('occlusion = {0};'.format(out_occlusion))
if parse_opacity:
frag.write('opacity = {0};'.format(out_opacity))
@ -147,11 +140,8 @@ def write_normal(inp):
def parsing_basecolor(b):
global parsing_basecol
global basecol_only
global curshader
parsing_basecol = b
if basecol_only:
curshader.lock = not b
def parse_shader(node, socket):
global parsing_basecol

View file

@ -51,10 +51,11 @@ def make_finalize(con_mesh):
tese.write('eyeDir = eye - wposition;')
else:
if not vert.contains('wposition'):
write_wpos = True
vert.add_out('vec3 eyeDir')
vert.add_uniform('vec3 eye', '_cameraPosition')
vert.write('eyeDir = eye - wposition;')
write_wpos = True
frag.prepend('vec3 vVec = normalize(eyeDir);')
export_wpos = False
@ -335,7 +336,10 @@ def make_forward_restricted(con_mesh):
frag.add_include('../../Shaders/compiled.glsl')
frag.write('vec3 basecol;')
cycles.parse(mat_state.nodes, con_mesh, vert, frag, geom, tesc, tese, basecol_only=True, parse_opacity=False, parse_displacement=False)
frag.write('float roughness;')
frag.write('float metallic;')
frag.write('float occlusion;')
cycles.parse(mat_state.nodes, con_mesh, vert, frag, geom, tesc, tese, parse_opacity=False, parse_displacement=False)
if con_mesh.is_elem('tex'):
vert.add_out('vec2 texCoord')
@ -352,6 +356,7 @@ def make_forward_restricted(con_mesh):
frag.write_pre = False
frag.add_include('../../Shaders/std/math.glsl')
frag.add_include('../../Shaders/std/brdf.glsl')
frag.add_uniform('vec3 lightColor', '_lampColor')
frag.add_uniform('vec3 lightDir', '_lampDirection')
frag.add_uniform('vec3 lightPos', '_lampPosition')
@ -388,6 +393,7 @@ def make_forward_restricted(con_mesh):
frag.write(' }')
frag.write('vec3 direct = basecol * dotNL * lightColor;')
frag.write('direct += vec3(D_Approx(max(roughness, 0.1), dot(reflect(-vVec, n), lightDir)));')
frag.write('direct *= attenuate(distance(wposition, lightPos));')
frag.add_out('vec4 fragColor')

View file

@ -56,7 +56,7 @@ class Shader:
self.functions[fname] = s
def contains(self, s):
return (s in self.main or s in self.main_pre or s in self.ins)
return (s in self.main or s in self.main_pre or s in self.main_header or s in self.ins)
def prepend(self, s):
self.main_pre = s + '\n' + self.main_pre