Full BSDF
This commit is contained in:
@ -74,8 +74,6 @@ 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
|
||||
@ -156,6 +154,8 @@ def make_base(con_mesh, parse_opacity):
|
||||
vert.add_out('vec3 wnormal')
|
||||
make_attrib.write_norpos(con_mesh, vert)
|
||||
frag.write_attrib('vec3 n = normalize(wnormal);')
|
||||
if '_ClearCoat' in wrd.world_defs:
|
||||
frag.write_attrib('vec3 nCoat = vec3(0.0, 0.0, 0.0);')
|
||||
|
||||
if mat_state.material.lnx_two_sided:
|
||||
frag.write('if (!gl_FrontFacing) n *= -1;') # Flip normal when drawing back-face
|
||||
@ -254,16 +254,13 @@ 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
|
||||
ext_brdf_defs = ('_ClearCoat', '_Sheen', '_Anisotropy', '_Subsurface', '_Transmission')
|
||||
ext_brdf_defs = ('_ClearCoat', '_Sheen', '_Anisotropy', '_SSS', '_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:
|
||||
if is_shadeless or has_ext_brdf:
|
||||
frag.write('uint matid = 0;')
|
||||
if is_shadeless:
|
||||
frag.write('matid = 1;')
|
||||
frag.write('basecol = emissionCol;')
|
||||
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);')
|
||||
@ -283,6 +280,14 @@ def make_deferred(con_mesh, rpasses):
|
||||
if mat_state.material.lnx_ignore_irradiance:
|
||||
frag.write('fragColor[GBUF_IDX_2].b = 1.0;')
|
||||
|
||||
if '_Anisotropy' in wrd.world_defs:
|
||||
frag.write('#ifdef _Anisotropy')
|
||||
if con_mesh.is_elem('tang'):
|
||||
frag.write('fragColor[GBUF_IDX_2].a = encodeTangent(TBN[0], normalize(wnormal));')
|
||||
else:
|
||||
frag.write('fragColor[GBUF_IDX_2].a = -1.0;')
|
||||
frag.write('#endif')
|
||||
|
||||
# Even if the material doesn't use emission we need to write to the
|
||||
# emission buffer (if used) to prevent undefined behaviour
|
||||
frag.write('#ifdef _EmissionShaded')
|
||||
@ -290,14 +295,21 @@ def make_deferred(con_mesh, rpasses):
|
||||
frag.write('#endif')
|
||||
|
||||
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);')
|
||||
frag.write('fragColor[GBUF_IDX_REFRACTION] = vec4(packIOR(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);')
|
||||
if '_ClearCoat' in wrd.world_defs:
|
||||
frag.write('#ifdef _ClearCoat')
|
||||
frag.write('if (dot(nCoat, nCoat) > 0.0) {')
|
||||
frag.write(' vec3 nCoatNorm = normalize(nCoat);')
|
||||
frag.write(' nCoatNorm /= (abs(nCoatNorm.x) + abs(nCoatNorm.y) + abs(nCoatNorm.z));')
|
||||
frag.write(' nCoatNorm.xy = nCoatNorm.z >= 0.0 ? nCoatNorm.xy : octahedronWrap(nCoatNorm.xy);')
|
||||
frag.write(' fragColor[GBUF_IDX_COAT_NORMAL] = vec4(nCoatNorm.xy, 0.0, 0.0);')
|
||||
frag.write('} else {')
|
||||
frag.write(' vec3 nNorm = normalize(n);')
|
||||
frag.write(' nNorm /= (abs(nNorm.x) + abs(nNorm.y) + abs(nNorm.z));')
|
||||
frag.write(' nNorm.xy = nNorm.z >= 0.0 ? nNorm.xy : octahedronWrap(nNorm.xy);')
|
||||
frag.write(' fragColor[GBUF_IDX_COAT_NORMAL] = vec4(nNorm.xy, 0.0, 0.0);')
|
||||
frag.write('}')
|
||||
frag.write('#endif')
|
||||
|
||||
return con_mesh
|
||||
@ -403,6 +415,9 @@ def make_forward_mobile(con_mesh):
|
||||
frag.add_include('std/shadows.glsl')
|
||||
frag.add_uniform('vec4 casData[shadowmapCascades * 4 + 4]', '_cascadeData', included=True)
|
||||
frag.add_uniform('vec3 eye', '_cameraPosition')
|
||||
if is_shadows_atlas:
|
||||
frag.add_uniform('vec4 tileBoundsSunArray[maxLights * shadowmapCascades]', '_tileBoundsSunArray', included=True)
|
||||
frag.write('tileBounds = tileBoundsSunArray[0];')
|
||||
frag.write(f'svisibility = shadowTestCascade({shadowmap_sun}, eye, wposition + n * shadowsBias * 10, shadowsBias, opacity != 1.0);')
|
||||
else:
|
||||
frag.write('if (lightPosition.w > 0.0) {')
|
||||
@ -582,7 +597,7 @@ def make_forward(con_mesh):
|
||||
frag.write('fragColor[0] = vec4(direct + indirect, packFloat2(occlusion, specular));')
|
||||
frag.write('fragColor[1] = vec4(n.xy, roughness, metallic);')
|
||||
if rpdat.rp_ss_refraction or rpdat.lnx_voxelgi_refract:
|
||||
frag.write(f'fragColor[2] = vec4(1.0, 0.0, 0.0, 1.0);')
|
||||
frag.write(f'fragColor[2] = vec4(packIOR(1.0), 0.0, 0.0, 1.0);')
|
||||
|
||||
else:
|
||||
frag.add_out('vec4 fragColor[1]')
|
||||
@ -683,6 +698,8 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
|
||||
|
||||
frag.write('vec3 albedo = surfaceAlbedo(basecol, metallic);')
|
||||
frag.write('vec3 f0 = surfaceF0(basecol, metallic);')
|
||||
if '_ExtBRDF' in wrd.world_defs:
|
||||
frag.write('f0 = mix(f0, basecol, specularTint);')
|
||||
|
||||
if '_Brdf' in wrd.world_defs:
|
||||
frag.add_uniform('sampler2D senvmapBrdf', link='$brdf.png')
|
||||
@ -752,6 +769,18 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
|
||||
frag.write('}')
|
||||
frag.write('vec3 direct = vec3(0.0);')
|
||||
|
||||
if '_ExtBRDF' in wrd.world_defs:
|
||||
frag.write('#ifdef _ExtBRDF')
|
||||
if '_Sheen' in wrd.world_defs:
|
||||
frag.write('brdf_sheenWeight = sheenAttenuation(sheen, sheenRough, sheenTint, dotNV);')
|
||||
if '_ClearCoat' in wrd.world_defs:
|
||||
frag.write('brdf_coatWeight = coatAttenuation(clearcoat, coatIOR, nCoat, vVec);')
|
||||
frag.write('brdf_coatTintAbsorb = coatTintAttenuation(clearcoat, coatTint, nCoat, vVec);')
|
||||
frag.write('brdf_coatF0 = (coatIOR - 1.0) / (coatIOR + 1.0); brdf_coatF0 = brdf_coatF0 * brdf_coatF0;')
|
||||
if '_Transmission' in wrd.world_defs:
|
||||
frag.write('brdf_transmissionF0 = (ior - 1.0) / (ior + 1.0); brdf_transmissionF0 = brdf_transmissionF0 * brdf_transmissionF0;')
|
||||
frag.write('#endif')
|
||||
|
||||
if '_Sun' in wrd.world_defs:
|
||||
frag.add_uniform('vec3 sunCol', '_sunColor')
|
||||
frag.add_uniform('vec3 sunDir', '_sunDirection')
|
||||
@ -771,6 +800,9 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
|
||||
frag.add_include('std/shadows.glsl')
|
||||
frag.add_uniform('vec4 casData[shadowmapCascades * 4 + 4]', '_cascadeData', included=True)
|
||||
frag.add_uniform('vec3 eye', '_cameraPosition')
|
||||
if is_shadows_atlas:
|
||||
frag.add_uniform('vec4 tileBoundsSunArray[maxLights * shadowmapCascades]', '_tileBoundsSunArray', included=True)
|
||||
frag.write('tileBounds = tileBoundsSunArray[0];')
|
||||
frag.write(f'svisibility = shadowTestCascade({shadowmap_sun},')
|
||||
if is_transparent_shadows:
|
||||
frag.write(f'{shadowmap_sun_tr},')
|
||||
@ -804,7 +836,21 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
|
||||
if '_VoxelShadow' in wrd.world_defs:
|
||||
frag.write('svisibility *= (1.0 - traceShadow(wposition, n, voxels, voxelsSDF, sunDir, clipmaps, gl_FragCoord.xy, velocity).r) * voxelgiShad;')
|
||||
frag.write('}') # receiveShadow
|
||||
frag.write('direct += (lambertDiffuseBRDF(albedo, sdotNL) + specularBRDF(f0, roughness, sdotNL, sdotNH, dotNV, sdotVH) * specular) * sunCol * svisibility;')
|
||||
if '_ExtBRDF' in wrd.world_defs:
|
||||
frag.write('float sunLayerWeight;')
|
||||
frag.write('vec3 sdirect = applyExtBRDFLayers(')
|
||||
frag.write(' lambertDiffuseBRDF(albedo, sdotNL) + specularBRDF(f0, roughness, sdotNL, sdotNH, dotNV, sdotVH) * specular,')
|
||||
frag.write(' albedo, f0, roughness, sdotNL, dotNV, sdotNH, sdotVH, n, sunDir, vVec, sh')
|
||||
if '_ClearCoat' in wrd.world_defs:
|
||||
frag.write(', clearcoat, clearcoatRough, coatIOR, coatTint, nCoat')
|
||||
if '_Sheen' in wrd.world_defs:
|
||||
frag.write(', sheen, sheenRough, sheenTint')
|
||||
if '_Transmission' in wrd.world_defs:
|
||||
frag.write(', transmission, transmissionRough, ior, thinWall')
|
||||
frag.write(', sunLayerWeight);')
|
||||
frag.write('direct += sdirect * sunCol * svisibility;')
|
||||
else:
|
||||
frag.write('direct += (lambertDiffuseBRDF(albedo, sdotNL) + specularBRDF(f0, roughness, sdotNL, sdotNH, dotNV, sdotVH) * specular) * sunCol * svisibility;')
|
||||
# sun
|
||||
|
||||
if '_SinglePoint' in wrd.world_defs:
|
||||
@ -846,13 +892,13 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
|
||||
frag.add_uniform('vec3 eye', '_cameraPosition')
|
||||
frag.write(', gbufferD, invVP, eye')
|
||||
if '_ClearCoat' in wrd.world_defs:
|
||||
frag.write(', clearcoat, clearcoatRough, coatIOR, coatTint')
|
||||
frag.write(', clearcoat, clearcoatRough, coatIOR, coatTint, nCoat')
|
||||
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 '_SSS' in wrd.world_defs:
|
||||
frag.write(', subsurface, subsurfaceColor, subsurfaceRadius * subsurfaceScale, subsurfaceAnisotropy')
|
||||
if '_Transmission' in wrd.world_defs:
|
||||
frag.write(', transmission, transmissionRough, ior, thinWall')
|
||||
frag.write(');')
|
||||
@ -867,7 +913,7 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
|
||||
|
||||
if '_VoxelRefract' in wrd.world_defs and parse_opacity:
|
||||
frag.write('if (opacity < 1.0) {')
|
||||
frag.write(' vec3 refraction = traceRefraction(wposition, n, voxels, voxelsSDF, vVec, ior, roughness * roughness, clipmaps, gl_FragCoord.xy, velocity, opacity).rgb * (1.0 - F) * voxelgiRefr;')
|
||||
frag.write(' vec3 refraction = traceRefraction(wposition, n, voxels, voxelsSDF, vVec, ior, roughness * roughness, clipmaps, gl_FragCoord.xy, velocity, opacity).rgb * (1.0 - F);')
|
||||
frag.write(' indirect = mix(refraction, indirect, opacity);')
|
||||
frag.write(' direct = mix(refraction, direct, opacity);')
|
||||
frag.write('}')
|
||||
@ -882,25 +928,27 @@ def _write_material_attribs_default(frag: shader.Shader, parse_opacity: bool):
|
||||
# by the shader compiler
|
||||
frag.write('vec3 emissionCol;')
|
||||
# Extended BRDF parameters
|
||||
frag.write('float subsurface = 0.0;')
|
||||
frag.write('vec3 subsurfaceRadius = vec3(0.0);')
|
||||
frag.write('vec3 subsurfaceColor = vec3(0.8);')
|
||||
frag.write('vec3 specularTint = vec3(1.0);')
|
||||
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);')
|
||||
frag.write('float subsurface;')
|
||||
frag.write('vec3 subsurfaceRadius;')
|
||||
frag.write('vec3 subsurfaceColor;')
|
||||
frag.write('vec3 specularTint;')
|
||||
frag.write('float anisotropy;')
|
||||
frag.write('float anisoRot;')
|
||||
frag.write('float sheen;')
|
||||
frag.write('float sheenRough;')
|
||||
frag.write('vec3 sheenTint;')
|
||||
frag.write('float clearcoat;')
|
||||
frag.write('float clearcoatRough;')
|
||||
frag.write('float transmission;')
|
||||
frag.write('float transmissionRough;')
|
||||
frag.write('float thinWall;')
|
||||
frag.write('vec3 tangent;')
|
||||
frag.write('float subsurfaceScale;')
|
||||
frag.write('float subsurfaceAnisotropy;')
|
||||
frag.write('float coatIOR;')
|
||||
frag.write('vec3 coatTint;')
|
||||
frag.write('float ior = 1.45;')
|
||||
if parse_opacity:
|
||||
frag.write('float opacity;')
|
||||
frag.write('float ior = 1.45;')
|
||||
else:
|
||||
frag.write('float opacity = 1.0;')
|
||||
|
||||
Reference in New Issue
Block a user