def make_forward_mobile(con_mesh): wrd = bpy.data.worlds['Arm'] vert = con_mesh.make_vert() frag = con_mesh.make_frag() geom = None tesc = None tese = None vert.add_uniform('mat3 N', '_normalMatrix') vert.write_attrib('vec4 spos = vec4(pos.xyz, 1.0);') frag.ins = vert.outs frag.add_include('compiled.inc') frag.write('vec3 basecol;') frag.write('float roughness;') frag.write('float metallic;') frag.write('float occlusion;') frag.write('float specular;') if '_Emission' in wrd.world_defs: frag.write('float emission;') arm_discard = mat_state.material.arm_discard blend = mat_state.material.arm_blending is_transluc = mat_utils.is_transluc(mat_state.material) parse_opacity = (blend and is_transluc) or arm_discard if parse_opacity: frag.write('float opacity;') cycles.parse(mat_state.nodes, con_mesh, vert, frag, geom, tesc, tese, parse_opacity=parse_opacity, parse_displacement=False) if arm_discard: opac = mat_state.material.arm_discard_opacity frag.write('if (opacity < {0}) discard;'.format(opac)) make_attrib.write_tex_coords(con_mesh, vert, frag, tese) if con_mesh.is_elem('col'): vert.add_out('vec3 vcolor') vert.write('vcolor = col.rgb;') if con_mesh.is_elem('tang'): vert.add_out('mat3 TBN') make_attrib.write_norpos(con_mesh, vert, declare=True) vert.write('vec3 tangent = normalize(N * tang.xyz);') vert.write('vec3 bitangent = normalize(cross(wnormal, tangent));') vert.write('TBN = mat3(tangent, bitangent, wnormal);') else: vert.add_out('vec3 wnormal') make_attrib.write_norpos(con_mesh, vert) frag.write_attrib('vec3 n = normalize(wnormal);') make_attrib.write_vertpos(vert) frag.add_include('std/math.glsl') frag.add_include('std/brdf.glsl') frag.add_out('vec4 fragColor') blend = mat_state.material.arm_blending if blend: if parse_opacity: frag.write('fragColor = vec4(basecol, opacity);') else: frag.write('fragColor = vec4(basecol, 1.0);') return is_shadows = '_ShadowMap' in wrd.world_defs is_shadows_atlas = '_ShadowMapAtlas' in wrd.world_defs shadowmap_sun = 'shadowMap' if is_shadows_atlas: is_single_atlas = '_SingleAtlas' in wrd.world_defs shadowmap_sun = 'shadowMapAtlasSun' if not is_single_atlas else 'shadowMapAtlas' frag.add_uniform('vec2 smSizeUniform', '_shadowMapSize', included=True) frag.write('vec3 direct = vec3(0.0);') if '_Sun' in wrd.world_defs: frag.add_uniform('vec3 sunCol', '_sunColor') frag.add_uniform('vec3 sunDir', '_sunDirection') frag.write('float svisibility = 1.0;') frag.write('float sdotNL = max(dot(n, sunDir), 0.0);') if is_shadows: vert.add_out('vec4 lightPosition') vert.add_uniform('mat4 LWVP', '_biasLightWorldViewProjectionMatrixSun') vert.write('lightPosition = LWVP * spos;') frag.add_uniform('bool receiveShadow') frag.add_uniform(f'sampler2DShadow {shadowmap_sun}') frag.add_uniform('float shadowsBias', '_sunShadowsBias') frag.write('if (receiveShadow) {') if '_CSM' in wrd.world_defs: frag.add_include('std/shadows.glsl') frag.add_uniform('vec4 casData[shadowmapCascades * 4 + 4]', '_cascadeData', included=True) frag.add_uniform('vec3 eye', '_cameraPosition') frag.write( f'svisibility = shadowTestCascade({shadowmap_sun}, eye, wposition + n * shadowsBias * 10, shadowsBias);' ) else: frag.write('if (lightPosition.w > 0.0) {') frag.write( ' vec3 lPos = lightPosition.xyz / lightPosition.w;') if '_Legacy' in wrd.world_defs: frag.write( f' svisibility = float(texture({shadowmap_sun}, vec2(lPos.xy)).r > lPos.z - shadowsBias);' ) else: frag.write( f' svisibility = texture({shadowmap_sun}, vec3(lPos.xy, lPos.z - shadowsBias)).r;' ) frag.write('}') frag.write('}') # receiveShadow frag.write('direct += basecol * sdotNL * sunCol * svisibility;') if '_SinglePoint' in wrd.world_defs: frag.add_uniform('vec3 pointPos', '_pointPosition') frag.add_uniform('vec3 pointCol', '_pointColor') if '_Spot' in wrd.world_defs: frag.add_uniform('vec3 spotDir', link='_spotDirection') frag.add_uniform('vec2 spotData', link='_spotData') frag.write('float visibility = 1.0;') frag.write('vec3 ld = pointPos - wposition;') frag.write('vec3 l = normalize(ld);') frag.write('float dotNL = max(dot(n, l), 0.0);') if is_shadows: frag.add_uniform('bool receiveShadow') frag.add_uniform('float pointBias', link='_pointShadowsBias') frag.add_include('std/shadows.glsl') frag.write('if (receiveShadow) {') if '_Spot' in wrd.world_defs: vert.add_out('vec4 spotPosition') vert.add_uniform( 'mat4 LWVPSpotArray[1]', link='_biasLightWorldViewProjectionMatrixSpotArray') vert.write('spotPosition = LWVPSpotArray[0] * spos;') frag.add_uniform('sampler2DShadow shadowMapSpot[1]') frag.write('if (spotPosition.w > 0.0) {') frag.write( ' vec3 lPos = spotPosition.xyz / spotPosition.w;') if '_Legacy' in wrd.world_defs: frag.write( ' visibility = float(texture(shadowMapSpot[0], vec2(lPos.xy)).r > lPos.z - pointBias);' ) else: frag.write( ' visibility = texture(shadowMapSpot[0], vec3(lPos.xy, lPos.z - pointBias)).r;' ) frag.write('}') else: frag.add_uniform('vec2 lightProj', link='_lightPlaneProj') frag.add_uniform('samplerCubeShadow shadowMapPoint[1]') frag.write('const float s = shadowmapCubePcfSize;' ) # TODO: incorrect... frag.write( 'float compare = lpToDepth(ld, lightProj) - pointBias * 1.5;' ) frag.write('#ifdef _InvY') frag.write('l.y = -l.y;') frag.write('#endif') if '_Legacy' in wrd.world_defs: frag.write( 'visibility = float(texture(shadowMapPoint[0], vec3(-l + n * pointBias * 20)).r > compare);' ) else: frag.write( 'visibility = texture(shadowMapPoint[0], vec4(-l + n * pointBias * 20, compare)).r;' ) frag.write('}') # receiveShadow frag.write( 'direct += basecol * dotNL * pointCol * attenuate(distance(wposition, pointPos)) * visibility;' ) if '_Clusters' in wrd.world_defs: frag.add_include('std/light_mobile.glsl') frag.write('vec3 albedo = basecol;') frag.write('vec3 f0 = surfaceF0(basecol, metallic);') make_cluster.write(vert, frag) if '_Irr' in wrd.world_defs: frag.add_include('std/shirr.glsl') frag.add_uniform('vec4 shirr[7]', link='_envmapIrradiance') env_str = 'shIrradiance(n, shirr)' else: env_str = '0.5' frag.add_uniform('float envmapStrength', link='_envmapStrength') frag.write( 'fragColor = vec4(direct + basecol * {0} * envmapStrength, 1.0);'. format(env_str)) if '_LDR' in wrd.world_defs: frag.write('fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / 2.2));')
def make_base(con_mesh, parse_opacity): global is_displacement global write_material_attribs global write_material_attribs_post global write_vertex_attribs wrd = bpy.data.worlds['Arm'] vert = con_mesh.make_vert() frag = con_mesh.make_frag() geom = None tesc = None tese = None vert.add_uniform('mat3 N', '_normalMatrix') vert.write_attrib('vec4 spos = vec4(pos.xyz, 1.0);') vattr_written = False rpdat = arm.utils.get_rp() is_displacement = mat_utils.disp_linked(mat_state.output_node) if is_displacement: if rpdat.arm_rp_displacement == 'Vertex': frag.ins = vert.outs else: # Tessellation tesc = con_mesh.make_tesc() tese = con_mesh.make_tese() tesc.ins = vert.outs tese.ins = tesc.outs frag.ins = tese.outs make_tess.tesc_levels(tesc, rpdat.arm_tess_mesh_inner, rpdat.arm_tess_mesh_outer) make_tess.interpolate(tese, 'wposition', 3, declare_out=True) make_tess.interpolate(tese, 'wnormal', 3, declare_out=True, normalize=True) # No displacement else: frag.ins = vert.outs if write_vertex_attribs != None: vattr_written = write_vertex_attribs(vert) frag.add_include('compiled.inc') written = False if write_material_attribs != None: written = write_material_attribs(con_mesh, frag) if written == False: frag.write('vec3 basecol;') frag.write('float roughness;') frag.write('float metallic;') frag.write('float occlusion;') frag.write('float specular;') if '_Emission' in wrd.world_defs: frag.write('float emission;') if parse_opacity: frag.write('float opacity;') cycles.parse(mat_state.nodes, con_mesh, vert, frag, geom, tesc, tese, parse_opacity=parse_opacity) if write_material_attribs_post != None: write_material_attribs_post(con_mesh, frag) vert.add_out('vec3 wnormal') make_attrib.write_norpos(con_mesh, vert) frag.write_attrib('vec3 n = normalize(wnormal);') if not is_displacement and not vattr_written: make_attrib.write_vertpos(vert) make_attrib.write_tex_coords(con_mesh, vert, frag, tese) if con_mesh.is_elem('col'): vert.add_out('vec3 vcolor') vert.write_attrib('vcolor = col.rgb;') if tese is not None: tese.write_pre = True make_tess.interpolate(tese, 'vcolor', 3, declare_out=frag.contains('vcolor')) tese.write_pre = False if con_mesh.is_elem('tang'): if tese is not None: tese.add_out('mat3 TBN') tese.write_attrib( 'vec3 wbitangent = normalize(cross(wnormal, wtangent));') tese.write_attrib('TBN = mat3(wtangent, wbitangent, wnormal);') else: vert.add_out('mat3 TBN') vert.write_attrib('vec3 tangent = normalize(N * tang.xyz);') vert.write_attrib( 'vec3 bitangent = normalize(cross(wnormal, tangent));') vert.write_attrib('TBN = mat3(tangent, bitangent, wnormal);') if is_displacement: if rpdat.arm_rp_displacement == 'Vertex': sh = vert else: sh = tese if (con_mesh.is_elem('ipos')): vert.write('wposition = vec4(W * spos).xyz;') sh.add_uniform('mat4 VP', '_viewProjectionMatrix') sh.write('wposition += wnormal * disp;') sh.write('gl_Position = VP * vec4(wposition, 1.0);')
def make_mesh_pass(rpass): con = { 'name': rpass, 'depth_write': True, 'compare_mode': 'less', 'cull_mode': 'clockwise' } con_mesh = mat_state.data.add_context(con) mat_state.con_mesh = con_mesh mat = con_mesh.material wrd = bpy.data.worlds['Arm'] vert = con_mesh.make_vert() frag = con_mesh.make_frag() geom = None tesc = None tese = None vert.add_uniform('mat3 N', '_normalMatrix') vert.write_attrib('vec4 spos = vec4(pos.xyz, 1.0);') frag.ins = vert.outs frag.add_include('compiled.glsl') frag.add_uniform('vec3 sunDir', '_sunDirection') frag.add_uniform('vec3 sunCol', '_sunColor') frag.add_uniform('float envmapStrength', link='_envmapStrength') frag.write('float visibility = 1.0;') frag.write('float dotNL = max(dot(n, sunDir), 0.0);') is_shadows = '_ShadowMap' in wrd.world_defs if is_shadows: vert.add_out('vec4 lightPos') vert.add_uniform('mat4 LWVP', '_biasLightWorldViewProjectionMatrix') vert.write('lightPos = LWVP * spos;') frag.add_include('std/shadows.glsl') frag.add_uniform('sampler2DShadow shadowMap') frag.add_uniform('float shadowsBias', '_sunShadowsBias') frag.add_uniform('bool receiveShadow') frag.write('if (receiveShadow && lightPos.w > 0.0) {') frag.write('vec3 lPos = lightPos.xyz / lightPos.w;') frag.write('const vec2 smSize = shadowmapSize;') frag.write( 'visibility *= PCF(shadowMap, lPos.xy, lPos.z - shadowsBias, smSize);' ) frag.write('}') frag.write('vec3 basecol;') frag.write('float roughness;') frag.write('float metallic;') frag.write('float occlusion;') frag.write('float specular;') frag.write('float emission;') is_displacement = mat_utils.disp_linked(mat_state.output_node) arm_discard = mat_state.material.arm_discard if arm_discard: frag.write('float opacity;') cycles.parse(mat_state.nodes, con_mesh, vert, frag, geom, tesc, tese, parse_opacity=arm_discard, parse_displacement=is_displacement) if arm_discard: opac = mat_state.material.arm_discard_opacity frag.write('if (opacity < {0}) discard;'.format(opac)) make_attrib.write_tex_coords(con_mesh, vert, frag, tese) if con_mesh.is_elem('col'): vert.add_out('vec3 vcolor') vert.write_attrib('vcolor = col;') if con_mesh.is_elem('tang'): vert.add_out('mat3 TBN') make_attrib.write_norpos(con_mesh, vert, declare=True) vert.write('vec3 tangent = normalize(N * tang.xyz);') vert.write('vec3 bitangent = normalize(cross(wnormal, tangent));') vert.write('TBN = mat3(tangent, bitangent, wnormal);') else: vert.add_out('vec3 wnormal') make_attrib.write_norpos(con_mesh, vert) frag.write_attrib('vec3 n = normalize(wnormal);') frag.add_out('vec4 fragColor') frag.write( f'vec3 shade = basecol * {cycles.to_vec3(mat.arm_celshade_shade_color)};' ) s = mat.arm_celshade_shade_softness if s == 0.0: frag.write( 'vec3 direct = mix(shade, basecol, step(0.5, dotNL)) * visibility * sunCol;' ) else: frag.write( f'vec3 direct = mix(shade, basecol, smoothstep({0.5 - s}, {0.5 + s}, dotNL)) * visibility * sunCol;' ) frag.write('vec3 indirect = basecol * envmapStrength;') frag.write('fragColor = vec4(direct + indirect, 1.0);') if '_LDR' in wrd.world_defs: frag.write('fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / 2.2));') if is_displacement: vert.add_uniform('mat4 W', link='_worldMatrix') vert.add_uniform('mat4 VP', link='_viewProjectionMatrix') vert.write('vec4 wpos = W * spos;') vert.write('wpos.xyz += wnormal * disp;') vert.write('gl_Position = VP * wpos;') else: make_attrib.write_vertpos(vert) assets.vs_equal(con_mesh, assets.shader_cons['mesh_vert']) make_finalize.make(con_mesh) return con_mesh