Extend BRDF
This commit is contained in:
@ -2526,6 +2526,9 @@ class LeenkxExporter:
|
||||
decals_used = False
|
||||
sss_used = False
|
||||
|
||||
from lnx.material import mat_state
|
||||
mat_state.next_ext_mat_id = 3
|
||||
|
||||
for material in self.material_array:
|
||||
# If the material is unlinked, material becomes None
|
||||
if material is None:
|
||||
|
||||
@ -173,6 +173,9 @@ def add_world_defs():
|
||||
wrd.world_defs += '_Brdf'
|
||||
assets.add_khafile_def("lnx_brdf")
|
||||
|
||||
if '_Anisotropy' in wrd.world_defs:
|
||||
assets.add_khafile_def('lnx_anisotropy')
|
||||
|
||||
def build():
|
||||
rpdat = lnx.utils.get_rp()
|
||||
project_path = lnx.utils.get_fp()
|
||||
@ -510,4 +513,8 @@ def get_num_gbuffer_rts_deferred()-> int:
|
||||
found_refraction_flag = True
|
||||
else:
|
||||
num += 1
|
||||
|
||||
if '_Anisotropy' in wrd.world_defs:
|
||||
num += 1
|
||||
|
||||
return num
|
||||
|
||||
@ -188,6 +188,64 @@ def parse(nodes, con: ShaderContext,
|
||||
|
||||
# Make sure that individual functions in this module aren't called with an incorrect/old parser state, set it to
|
||||
# None so that it will raise exceptions when not set
|
||||
# store extended BRDF feature flags before destroying parser state
|
||||
import re as _re
|
||||
|
||||
def _extract_vec3(s):
|
||||
m = _re.match(r'vec3\s*\(\s*([^,\s\)]+)\s*\)', s)
|
||||
if m and ',' not in m.group(1):
|
||||
v = m.group(1)
|
||||
return v, v, v
|
||||
m = _re.match(r'vec3\s*\(\s*([^,\s]+)\s*,\s*([^,\s]+)\s*,\s*([^,\s\)]+)', s)
|
||||
if m:
|
||||
return m.group(1), m.group(2), m.group(3)
|
||||
return '1.0', '1.0', '1.0'
|
||||
|
||||
def _try_float(val_str, default=0.0):
|
||||
try:
|
||||
return float(val_str)
|
||||
except (ValueError, TypeError):
|
||||
return default
|
||||
|
||||
_sss_r, _sss_g, _sss_b = _extract_vec3(state.out_subsurface_radius)
|
||||
_sss_scale = state.out_subsurface_scale
|
||||
_sss_scale_f = _try_float(_sss_scale, 0.05)
|
||||
if _sss_scale_f != 1.0:
|
||||
_sss_r = str(_try_float(_sss_r, 1.0) * _sss_scale_f)
|
||||
_sss_g = str(_try_float(_sss_g, 0.2) * _sss_scale_f)
|
||||
_sss_b = str(_try_float(_sss_b, 0.1) * _sss_scale_f)
|
||||
|
||||
_sheen_tint_r, _sheen_tint_g, _sheen_tint_b = _extract_vec3(state.out_sheen_tint)
|
||||
_coat_tint_r, _coat_tint_g, _coat_tint_b = _extract_vec3(state.out_coat_tint)
|
||||
_sss_color_r, _sss_color_g, _sss_color_b = _extract_vec3(state.out_subsurface_color)
|
||||
|
||||
mat_state.features = {
|
||||
'clearcoat': state.out_clearcoat,
|
||||
'clearcoatRough': state.out_clearcoat_rough,
|
||||
'coatIOR': state.out_coat_ior,
|
||||
'coatTintR': _coat_tint_r,
|
||||
'coatTintG': _coat_tint_g,
|
||||
'coatTintB': _coat_tint_b,
|
||||
'sheen': state.out_sheen,
|
||||
'sheenRough': state.out_sheen_rough,
|
||||
'sheenTintR': _sheen_tint_r,
|
||||
'sheenTintG': _sheen_tint_g,
|
||||
'sheenTintB': _sheen_tint_b,
|
||||
'subsurface': state.out_subsurface,
|
||||
'subsurfaceAnisotropy': state.out_subsurface_anisotropy,
|
||||
'subsurfaceRadiusR': _sss_r,
|
||||
'subsurfaceRadiusG': _sss_g,
|
||||
'subsurfaceRadiusB': _sss_b,
|
||||
'subsurfaceColorR': _sss_color_r,
|
||||
'subsurfaceColorG': _sss_color_g,
|
||||
'subsurfaceColorB': _sss_color_b,
|
||||
'anisotropy': state.out_anisotropy,
|
||||
'anisoRot': state.out_aniso_rot,
|
||||
'transmission': state.out_transmission,
|
||||
'transmissionRough': state.out_transmission_rough,
|
||||
'ior': state.out_ior,
|
||||
'thinWall': state.out_thin_wall,
|
||||
}
|
||||
state = None
|
||||
|
||||
|
||||
@ -250,6 +308,10 @@ def parse_material_output(node: bpy.types.Node, custom_particle_node: bpy.types.
|
||||
curshader.write(f'transmissionRough = {outs[20]};')
|
||||
curshader.write(f'thinWall = {outs[21]};')
|
||||
curshader.write(f'tangent = {outs[22]};')
|
||||
curshader.write(f'subsurfaceScale = {outs[23]};')
|
||||
curshader.write(f'subsurfaceAnisotropy = {outs[24]};')
|
||||
curshader.write(f'coatIOR = {outs[25]};')
|
||||
curshader.write(f'coatTint = {outs[26]};')
|
||||
|
||||
if mat_state.emission_type == mat_state.EmissionType.SHADELESS:
|
||||
if '_EmissionShadeless' not in wrd.world_defs:
|
||||
|
||||
@ -55,6 +55,8 @@ else:
|
||||
TRANSMISSION_ROUGHNESS = 'Transmission Roughness'
|
||||
TANGENT = 'Tangent'
|
||||
THIN_WALL = 'Thin Wall'
|
||||
SUBSURFACE_SCALE = 'Subsurface Scale'
|
||||
SUBSURFACE_ANISOTROPY = 'Subsurface Anisotropy'
|
||||
|
||||
|
||||
def parse_mixshader(node: bpy.types.ShaderNodeMixShader, out_socket: NodeSocket, state: ParserState) -> None:
|
||||
@ -111,6 +113,10 @@ def parse_mixshader(node: bpy.types.ShaderNodeMixShader, out_socket: NodeSocket,
|
||||
state.out_transmission_rough = fm.format(o1[20], o2[20], fv[0], fv[1])
|
||||
state.out_thin_wall = fm.format(o1[21], o2[21], fv[0], fv[1])
|
||||
state.out_tangent = fm.format(o1[22], o2[22], fv[0], fv[1])
|
||||
state.out_subsurface_scale = fm.format(o1[23], o2[23], fv[0], fv[1])
|
||||
state.out_subsurface_anisotropy = fm.format(o1[24], o2[24], fv[0], fv[1])
|
||||
state.out_coat_ior = fm.format(o1[25], o2[25], fv[0], fv[1])
|
||||
state.out_coat_tint = fm.format(o1[26], o2[26], fv[0], fv[1])
|
||||
mat_state.emission_type = mat_state.EmissionType.get_effective_combination(ek1, ek2)
|
||||
if state.parse_opacity:
|
||||
fm = '{0} * {3} + {1} * {2}'
|
||||
@ -155,6 +161,10 @@ def parse_addshader(node: bpy.types.ShaderNodeAddShader, out_socket: NodeSocket,
|
||||
state.out_transmission_rough = am.format(o1[20], o2[20])
|
||||
state.out_thin_wall = am.format(o1[21], o2[21])
|
||||
state.out_tangent = am.format(o1[22], o2[22])
|
||||
state.out_subsurface_scale = am.format(o1[23], o2[23])
|
||||
state.out_subsurface_anisotropy = am.format(o1[24], o2[24])
|
||||
state.out_coat_ior = am.format(o1[25], o2[25])
|
||||
state.out_coat_tint = am.format(o1[26], o2[26])
|
||||
mat_state.emission_type = mat_state.EmissionType.get_effective_combination(ek1, ek2)
|
||||
if state.parse_opacity:
|
||||
am = '{0} * 0.5 + {1} * 0.5'
|
||||
@ -254,6 +264,14 @@ if bpy.app.version >= (4, 0, 0):
|
||||
if sss_radius_input is not None:
|
||||
state.out_subsurface_radius = c.parse_vector_input(sss_radius_input)
|
||||
|
||||
sss_scale_input = node.inputs.get(SUBSURFACE_SCALE)
|
||||
if sss_scale_input is not None:
|
||||
state.out_subsurface_scale = c.parse_value_input(sss_scale_input)
|
||||
|
||||
sss_aniso_input = node.inputs.get(SUBSURFACE_ANISOTROPY)
|
||||
if sss_aniso_input is not None:
|
||||
state.out_subsurface_anisotropy = c.parse_value_input(sss_aniso_input)
|
||||
|
||||
sss_color_input = node.inputs.get(SUBSURFACE_COLOR)
|
||||
if sss_color_input is not None:
|
||||
state.out_subsurface_color = c.parse_vector_input(sss_color_input)
|
||||
@ -307,6 +325,12 @@ if bpy.app.version >= (4, 0, 0):
|
||||
coat_rough_socket = node.inputs.get(CLEARCOAT_ROUGHNESS)
|
||||
if coat_rough_socket is not None:
|
||||
state.out_clearcoat_rough = c.parse_value_input(coat_rough_socket)
|
||||
coat_ior_socket = node.inputs.get(COAT_IOR)
|
||||
if coat_ior_socket is not None:
|
||||
state.out_coat_ior = c.parse_value_input(coat_ior_socket)
|
||||
coat_tint_socket = node.inputs.get(COAT_TINT)
|
||||
if coat_tint_socket is not None:
|
||||
state.out_coat_tint = c.parse_vector_input(coat_tint_socket)
|
||||
|
||||
trans_socket = node.inputs.get(TRANSMISSION)
|
||||
if trans_socket is not None:
|
||||
|
||||
@ -40,6 +40,8 @@ def parse(material: Material, mat_data, mat_users: Dict[Material, List[Object]],
|
||||
wrd = bpy.data.worlds['Lnx']
|
||||
rpdat = lnx.utils.get_rp()
|
||||
|
||||
mat_state.features = {}
|
||||
|
||||
# Texture caching for material batching
|
||||
batch_cached_textures = []
|
||||
|
||||
@ -120,6 +122,76 @@ def parse(material: Material, mat_data, mat_users: Dict[Material, List[Object]],
|
||||
const['intValue'] = 0
|
||||
c['bind_constants'].append(const)
|
||||
|
||||
# extended BRDF parameters as bind_constants
|
||||
if rpdat.rp_renderer == 'Deferred':
|
||||
feats = mat_state.features
|
||||
|
||||
def try_float(val_str, default=1.0):
|
||||
try:
|
||||
return float(val_str)
|
||||
except (ValueError, TypeError):
|
||||
return default
|
||||
|
||||
has_ext_brdf = False
|
||||
if feats.get('clearcoat', '0.0') not in ('0.0', '0', ''):
|
||||
c['bind_constants'].append({'name': 'clearcoat', 'floatValue': try_float(feats.get('clearcoat', '1.0'))})
|
||||
c['bind_constants'].append({'name': 'clearcoatRough', 'floatValue': try_float(feats.get('clearcoatRough', '0.03'), 0.03)})
|
||||
c['bind_constants'].append({'name': 'coatIOR', 'floatValue': try_float(feats.get('coatIOR', '1.5'), 1.5)})
|
||||
c['bind_constants'].append({'name': 'coatTintR', 'floatValue': try_float(feats.get('coatTintR', '1.0'), 1.0)})
|
||||
c['bind_constants'].append({'name': 'coatTintG', 'floatValue': try_float(feats.get('coatTintG', '1.0'), 1.0)})
|
||||
c['bind_constants'].append({'name': 'coatTintB', 'floatValue': try_float(feats.get('coatTintB', '1.0'), 1.0)})
|
||||
if '_ClearCoat' not in wrd.world_defs:
|
||||
wrd.world_defs += '_ClearCoat'
|
||||
has_ext_brdf = True
|
||||
if feats.get('sheen', '0.0') not in ('0.0', '0', ''):
|
||||
c['bind_constants'].append({'name': 'sheen', 'floatValue': try_float(feats.get('sheen', '1.0'))})
|
||||
c['bind_constants'].append({'name': 'sheenRough', 'floatValue': try_float(feats.get('sheenRough', '0.5'), 0.5)})
|
||||
c['bind_constants'].append({'name': 'sheenTintR', 'floatValue': try_float(feats.get('sheenTintR', '1.0'), 1.0)})
|
||||
c['bind_constants'].append({'name': 'sheenTintG', 'floatValue': try_float(feats.get('sheenTintG', '1.0'), 1.0)})
|
||||
c['bind_constants'].append({'name': 'sheenTintB', 'floatValue': try_float(feats.get('sheenTintB', '1.0'), 1.0)})
|
||||
if '_Sheen' not in wrd.world_defs:
|
||||
wrd.world_defs += '_Sheen'
|
||||
has_ext_brdf = True
|
||||
if feats.get('subsurface', '0.0') not in ('0.0', '0', '') and rpdat.rp_sss_state != 'Off' and not mat_uses_sss:
|
||||
c['bind_constants'].append({'name': 'subsurface', 'floatValue': try_float(feats.get('subsurface', '1.0'))})
|
||||
c['bind_constants'].append({'name': 'subsurfaceAnisotropy', 'floatValue': try_float(feats.get('subsurfaceAnisotropy', '0.0'), 0.0)})
|
||||
c['bind_constants'].append({'name': 'subsurfaceRadiusR', 'floatValue': try_float(feats.get('subsurfaceRadiusR', '1.0'), 1.0)})
|
||||
c['bind_constants'].append({'name': 'subsurfaceRadiusG', 'floatValue': try_float(feats.get('subsurfaceRadiusG', '0.2'), 0.2)})
|
||||
c['bind_constants'].append({'name': 'subsurfaceRadiusB', 'floatValue': try_float(feats.get('subsurfaceRadiusB', '0.1'), 0.1)})
|
||||
c['bind_constants'].append({'name': 'subsurfaceColorR', 'floatValue': try_float(feats.get('subsurfaceColorR', '0.8'), 0.8)})
|
||||
c['bind_constants'].append({'name': 'subsurfaceColorG', 'floatValue': try_float(feats.get('subsurfaceColorG', '0.8'), 0.8)})
|
||||
c['bind_constants'].append({'name': 'subsurfaceColorB', 'floatValue': try_float(feats.get('subsurfaceColorB', '0.8'), 0.8)})
|
||||
if '_Subsurface' not in wrd.world_defs:
|
||||
wrd.world_defs += '_Subsurface'
|
||||
has_ext_brdf = True
|
||||
if feats.get('anisotropy', '0.0') not in ('0.0', '0', ''):
|
||||
c['bind_constants'].append({'name': 'anisotropy', 'floatValue': try_float(feats.get('anisotropy', '1.0'))})
|
||||
c['bind_constants'].append({'name': 'anisoRot', 'floatValue': try_float(feats.get('anisoRot', '0.0'), 0.0)})
|
||||
if '_Anisotropy' not in wrd.world_defs:
|
||||
wrd.world_defs += '_Anisotropy'
|
||||
has_ext_brdf = True
|
||||
if feats.get('transmission', '0.0') not in ('0.0', '0', ''):
|
||||
c['bind_constants'].append({'name': 'transmission', 'floatValue': try_float(feats.get('transmission', '1.0'))})
|
||||
c['bind_constants'].append({'name': 'transmissionRough', 'floatValue': try_float(feats.get('transmissionRough', '0.0'), 0.0)})
|
||||
c['bind_constants'].append({'name': 'ior', 'floatValue': try_float(feats.get('ior', '1.45'), 1.45)})
|
||||
c['bind_constants'].append({'name': 'thinWall', 'floatValue': try_float(feats.get('thinWall', '0.0'), 0.0)})
|
||||
if '_Transmission' not in wrd.world_defs:
|
||||
wrd.world_defs += '_Transmission'
|
||||
has_ext_brdf = True
|
||||
|
||||
if has_ext_brdf and '_ExtBRDF' not in wrd.world_defs:
|
||||
wrd.world_defs += '_ExtBRDF'
|
||||
|
||||
# assign materialID for extended BRDF if not already set
|
||||
# coexist with Scene.hx for last materialID in bind_constants
|
||||
if has_ext_brdf and material.lnx_material_id == 0:
|
||||
if mat_state.next_ext_mat_id <= 15:
|
||||
ext_id = mat_state.next_ext_mat_id
|
||||
mat_state.next_ext_mat_id += 1
|
||||
c['bind_constants'].append({'name': 'materialID', 'intValue': ext_id})
|
||||
else:
|
||||
log.warn(f'material "{material.name}": extended BRDF material limit (15) exceeded, extended BRDF will be disabled for this material')
|
||||
|
||||
# TODO: Mesh only material batching
|
||||
if wrd.lnx_batch_materials:
|
||||
# Set textures uniforms
|
||||
|
||||
@ -111,6 +111,16 @@ def write(vert: shader.Shader, frag: shader.Shader):
|
||||
frag.add_uniform('mat4 invVP', '_inverseViewProjectionMatrix')
|
||||
frag.add_uniform('vec3 eye', '_cameraPosition')
|
||||
frag.write(', gbufferD, invVP, eye')
|
||||
if '_ClearCoat' in wrd.world_defs:
|
||||
frag.write(', clearcoat, clearcoatRough, coatIOR, coatTint')
|
||||
if '_Sheen' in wrd.world_defs:
|
||||
frag.write(', sheen, sheenRough, sheenTint')
|
||||
if '_Anisotropy' in wrd.world_defs:
|
||||
frag.write(', anisotropy, anisoRot, tangent')
|
||||
if '_Subsurface' in wrd.world_defs:
|
||||
frag.write(', subsurface, subsurfaceColor, subsurfaceRadius, subsurfaceAnisotropy')
|
||||
if '_Transmission' in wrd.world_defs:
|
||||
frag.write(', transmission, transmissionRough, ior, thinWall')
|
||||
frag.write(');')
|
||||
|
||||
frag.write('}') # for numLights
|
||||
|
||||
@ -74,6 +74,8 @@ def make(context_id, rpasses):
|
||||
con['color_attachments'] = [attachment_format, attachment_format]
|
||||
if '_gbuffer2' in wrd.world_defs:
|
||||
con['color_attachments'].append(attachment_format)
|
||||
if '_Anisotropy' in wrd.world_defs:
|
||||
con['color_attachments'].append('RGBA64')
|
||||
|
||||
con_mesh = mat_state.data.add_context(con)
|
||||
mat_state.con_mesh = con_mesh
|
||||
@ -252,7 +254,9 @@ def make_deferred(con_mesh, rpasses):
|
||||
frag.write('n.xy = n.z >= 0.0 ? n.xy : octahedronWrap(n.xy);')
|
||||
|
||||
is_shadeless = mat_state.emission_type == mat_state.EmissionType.SHADELESS
|
||||
if is_shadeless or '_SSS' in wrd.world_defs or '_Hair' in wrd.world_defs:
|
||||
ext_brdf_defs = ('_ClearCoat', '_Sheen', '_Anisotropy', '_Subsurface', '_Transmission')
|
||||
has_ext_brdf = any(d in wrd.world_defs for d in ext_brdf_defs)
|
||||
if is_shadeless or '_SSS' in wrd.world_defs or '_Hair' in wrd.world_defs or has_ext_brdf:
|
||||
frag.write('uint matid = 0;')
|
||||
if is_shadeless:
|
||||
frag.write('matid = 1;')
|
||||
@ -260,6 +264,9 @@ def make_deferred(con_mesh, rpasses):
|
||||
if '_SSS' in wrd.world_defs or '_Hair' in wrd.world_defs:
|
||||
frag.add_uniform('int materialID')
|
||||
frag.write('if (materialID == 2) matid = 2;')
|
||||
if has_ext_brdf:
|
||||
frag.add_uniform('int materialID')
|
||||
frag.write('if (materialID >= 3) matid = uint(materialID);')
|
||||
else:
|
||||
frag.write('const uint matid = 0;')
|
||||
|
||||
@ -285,6 +292,14 @@ def make_deferred(con_mesh, rpasses):
|
||||
if '_SSRefraction' in wrd.world_defs or '_VoxelRefract' in wrd.world_defs:
|
||||
frag.write('fragColor[GBUF_IDX_REFRACTION] = vec4(1.0, 0.0, 0.0, 1.0);')
|
||||
|
||||
if '_Anisotropy' in wrd.world_defs:
|
||||
frag.write('#ifdef _Anisotropy')
|
||||
if con_mesh.is_elem('tang'):
|
||||
frag.write('fragColor[GBUF_IDX_3] = vec4(normalize(TBN[0]), 0.0);')
|
||||
else:
|
||||
frag.write('fragColor[GBUF_IDX_3] = vec4(0.0, 0.0, 0.0, 0.0);')
|
||||
frag.write('#endif')
|
||||
|
||||
return con_mesh
|
||||
|
||||
|
||||
@ -830,6 +845,16 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
|
||||
frag.add_uniform('mat4 invVP', '_inverseViewProjectionMatrix')
|
||||
frag.add_uniform('vec3 eye', '_cameraPosition')
|
||||
frag.write(', gbufferD, invVP, eye')
|
||||
if '_ClearCoat' in wrd.world_defs:
|
||||
frag.write(', clearcoat, clearcoatRough, coatIOR, coatTint')
|
||||
if '_Sheen' in wrd.world_defs:
|
||||
frag.write(', sheen, sheenRough, sheenTint')
|
||||
if '_Anisotropy' in wrd.world_defs:
|
||||
frag.write(', anisotropy, anisoRot, tangent')
|
||||
if '_Subsurface' in wrd.world_defs:
|
||||
frag.write(', subsurface, subsurfaceColor, subsurfaceRadius, subsurfaceAnisotropy')
|
||||
if '_Transmission' in wrd.world_defs:
|
||||
frag.write(', transmission, transmissionRough, ior, thinWall')
|
||||
frag.write(');')
|
||||
|
||||
if '_Clusters' in wrd.world_defs:
|
||||
@ -872,6 +897,10 @@ def _write_material_attribs_default(frag: shader.Shader, parse_opacity: bool):
|
||||
frag.write('float transmissionRough = 0.0;')
|
||||
frag.write('float thinWall = 0.0;')
|
||||
frag.write('vec3 tangent = vec3(0.0);')
|
||||
frag.write('float subsurfaceScale = 0.05;')
|
||||
frag.write('float subsurfaceAnisotropy = 0.0;')
|
||||
frag.write('float coatIOR = 1.5;')
|
||||
frag.write('vec3 coatTint = vec3(1.0);')
|
||||
if parse_opacity:
|
||||
frag.write('float opacity;')
|
||||
frag.write('float ior = 1.45;')
|
||||
|
||||
@ -81,6 +81,25 @@ def make_gi(context_id):
|
||||
frag.write('float occlusion;') #
|
||||
frag.write('float specular;') #
|
||||
frag.write('vec3 emissionCol = vec3(0.0);')
|
||||
frag.write('vec3 specularTint = vec3(1.0);')
|
||||
frag.write('float subsurface = 0.0;')
|
||||
frag.write('vec3 subsurfaceRadius = vec3(0.0);')
|
||||
frag.write('vec3 subsurfaceColor = vec3(0.8);')
|
||||
frag.write('float anisotropy = 0.0;')
|
||||
frag.write('float anisoRot = 0.0;')
|
||||
frag.write('float sheen = 0.0;')
|
||||
frag.write('float sheenRough = 0.5;')
|
||||
frag.write('vec3 sheenTint = vec3(1.0);')
|
||||
frag.write('float clearcoat = 0.0;')
|
||||
frag.write('float clearcoatRough = 0.03;')
|
||||
frag.write('float transmission = 0.0;')
|
||||
frag.write('float transmissionRough = 0.0;')
|
||||
frag.write('float thinWall = 0.0;')
|
||||
frag.write('vec3 tangent = vec3(0.0);')
|
||||
frag.write('float subsurfaceScale = 0.05;')
|
||||
frag.write('float subsurfaceAnisotropy = 0.0;')
|
||||
frag.write('float coatIOR = 1.5;')
|
||||
frag.write('vec3 coatTint = vec3(1.0);')
|
||||
blend = mat_state.material.lnx_blending
|
||||
parse_opacity = blend or mat_utils.is_transluc(mat_state.material)
|
||||
if parse_opacity:
|
||||
@ -377,6 +396,16 @@ def make_gi(context_id):
|
||||
frag.write(', opacity != 1.0')
|
||||
if '_Spot' in wrd.world_defs:
|
||||
frag.write(', true, spotData.x, spotData.y, spotDir, spotData.zw, spotRight')
|
||||
if '_ClearCoat' in wrd.world_defs:
|
||||
frag.write(', clearcoat, clearcoatRough, coatIOR, coatTint')
|
||||
if '_Sheen' in wrd.world_defs:
|
||||
frag.write(', sheen, sheenRough, sheenTint')
|
||||
if '_Anisotropy' in wrd.world_defs:
|
||||
frag.write(', anisotropy, anisoRot, tangent')
|
||||
if '_Subsurface' in wrd.world_defs:
|
||||
frag.write(', subsurface, subsurfaceColor, subsurfaceRadius, subsurfaceAnisotropy')
|
||||
if '_Transmission' in wrd.world_defs:
|
||||
frag.write(', transmission, transmissionRough, ior, thinWall')
|
||||
frag.write(');')
|
||||
|
||||
if '_Clusters' in wrd.world_defs:
|
||||
@ -458,6 +487,16 @@ def make_gi(context_id):
|
||||
frag.write('\t, lightsArraySpot[li * 2].xyz') # spotDir
|
||||
frag.write('\t, vec2(lightsArray[li * 3].w, lightsArray[li * 3 + 1].w)') # scale
|
||||
frag.write('\t, lightsArraySpot[li * 2 + 1].xyz') # right
|
||||
if '_ClearCoat' in wrd.world_defs:
|
||||
frag.write('\t, clearcoat, clearcoatRough, coatIOR, coatTint')
|
||||
if '_Sheen' in wrd.world_defs:
|
||||
frag.write('\t, sheen, sheenRough, sheenTint')
|
||||
if '_Anisotropy' in wrd.world_defs:
|
||||
frag.write('\t, anisotropy, anisoRot, tangent')
|
||||
if '_Subsurface' in wrd.world_defs:
|
||||
frag.write('\t, subsurface, subsurfaceColor, subsurfaceRadius, subsurfaceAnisotropy')
|
||||
if '_Transmission' in wrd.world_defs:
|
||||
frag.write('\t, transmission, transmissionRough, ior, thinWall')
|
||||
frag.write(' );')
|
||||
frag.write('}')
|
||||
|
||||
|
||||
@ -39,3 +39,5 @@ con_mesh = None # Mesh context
|
||||
uses_instancing = False # Whether the current material has at least one user with instancing enabled
|
||||
emission_type = EmissionType.NO_EMISSION
|
||||
needs_sss = False
|
||||
features = {} # tracks extended BRDF features used by current material
|
||||
next_ext_mat_id = 3 # auto assigned materialID for extended BRDF
|
||||
|
||||
@ -114,6 +114,10 @@ class ParserState:
|
||||
self.out_transmission_rough: floatstr = '0.0'
|
||||
self.out_thin_wall: floatstr = '0.0'
|
||||
self.out_tangent: vec3str = 'vec3(0.0)'
|
||||
self.out_subsurface_scale: floatstr = '0.05'
|
||||
self.out_subsurface_anisotropy: floatstr = '0.0'
|
||||
self.out_coat_ior: floatstr = '1.5'
|
||||
self.out_coat_tint: vec3str = 'vec3(1.0)'
|
||||
|
||||
def reset_outs(self):
|
||||
"""Reset the shader output values to their default values."""
|
||||
@ -140,6 +144,10 @@ class ParserState:
|
||||
self.out_transmission_rough = '0.0'
|
||||
self.out_thin_wall = '0.0'
|
||||
self.out_tangent = 'vec3(0.0)'
|
||||
self.out_subsurface_scale = '0.05'
|
||||
self.out_subsurface_anisotropy = '0.0'
|
||||
self.out_coat_ior = '1.5'
|
||||
self.out_coat_tint = 'vec3(1.0)'
|
||||
|
||||
def get_outs(self) -> Tuple:
|
||||
"""Return the shader output values as a tuple."""
|
||||
@ -152,7 +160,9 @@ class ParserState:
|
||||
self.out_sheen, self.out_sheen_rough, self.out_sheen_tint,
|
||||
self.out_clearcoat, self.out_clearcoat_rough,
|
||||
self.out_transmission, self.out_transmission_rough,
|
||||
self.out_thin_wall, self.out_tangent)
|
||||
self.out_thin_wall, self.out_tangent,
|
||||
self.out_subsurface_scale, self.out_subsurface_anisotropy,
|
||||
self.out_coat_ior, self.out_coat_tint)
|
||||
|
||||
|
||||
def get_parser_pass_suffix(self) -> str:
|
||||
|
||||
@ -835,6 +835,18 @@ def write_compiledglsl(defs, make_variants):
|
||||
if '_SSRefraction' in wrd.world_defs or '_VoxelRefract' in wrd.world_defs:
|
||||
f.write(f'#define GBUF_IDX_REFRACTION {idx_refraction}\n')
|
||||
|
||||
idx_anisotropy = idx_refraction
|
||||
if '_Anisotropy' in wrd.world_defs:
|
||||
f.write(f'#define GBUF_IDX_3 {idx_anisotropy}\n')
|
||||
|
||||
ext_brdf_defs = ('_ClearCoat', '_Sheen', '_Anisotropy', '_Subsurface', '_Transmission')
|
||||
if any(d in wrd.world_defs for d in ext_brdf_defs):
|
||||
f.write('#ifndef _ExtBRDF\n')
|
||||
f.write('#define _ExtBRDF\n')
|
||||
f.write('#endif\n')
|
||||
f.write('#define MAX_MATERIALS 16\n')
|
||||
f.write('uniform vec4 materialParams[MAX_MATERIALS * 8];\n')
|
||||
|
||||
f.write("""#if defined(HLSL) || defined(METAL)
|
||||
#define _InvY
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user