def make(context_id): con = { 'name': context_id, 'depth_write': True, 'compare_mode': 'less', 'cull_mode': 'clockwise' } mat = mat_state.material blend = mat.arm_blending if blend: con['blend_source'] = mat.arm_blending_source con['blend_destination'] = mat.arm_blending_destination con['blend_operation'] = mat.arm_blending_operation con['alpha_blend_source'] = mat.arm_blending_source_alpha con['alpha_blend_destination'] = mat.arm_blending_destination_alpha con['alpha_blend_operation'] = mat.arm_blending_operation_alpha con_overlay = mat_state.data.add_context(con) arm_discard = mat.arm_discard is_transluc = mat_utils.is_transluc(mat) parse_opacity = (blend and is_transluc) or arm_discard make_mesh.make_base(con_overlay, parse_opacity=parse_opacity) frag = con_overlay.frag if arm_discard: opac = mat.arm_discard_opacity frag.write('if (opacity < {0}) discard;'.format(opac)) frag.add_out('vec4 fragColor') if blend and parse_opacity: frag.write('fragColor = vec4(basecol, opacity);') else: frag.write('fragColor = vec4(basecol, 1.0);') frag.write('fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / 2.2));') return con_overlay
def make_forward_solid(con_mesh): wrd = bpy.data.worlds['Arm'] vert = con_mesh.make_vert() frag = con_mesh.make_frag() geom = None tesc = None tese = None for e in con_mesh.data['vertex_structure']: if e['name'] == 'nor': con_mesh.data['vertex_structure'].remove(e) break vert.write_attrib('vec4 spos = vec4(pos, 1.0);') frag.ins = vert.outs write_vertpos(vert) 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;') 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, basecol_only=True) if arm_discard: opac = mat_state.material.arm_discard_opacity frag.write('if (opacity < {0}) discard;'.format(opac)) if con_mesh.is_elem('tex'): vert.add_out('vec2 texCoord') if mat_state.material.arm_tilesheet_mat: vert.add_uniform('vec2 tilesheetOffset', '_tilesheetOffset') vert.write('texCoord = tex + tilesheetOffset;') else: vert.write('texCoord = tex;') if con_mesh.is_elem('col'): vert.add_out('vec3 vcolor') vert.write('vcolor = col;') write_norpos(con_mesh, vert, write_nor=False) frag.add_out('vec4 fragColor') if blend and parse_opacity: frag.write('fragColor = vec4(basecol, opacity);') else: frag.write('fragColor = vec4(basecol, 1.0);') if '_LDR' in wrd.world_defs: frag.write('fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / 2.2));')
def make_forward(con_mesh): wrd = bpy.data.worlds['Arm'] rpdat = arm.utils.get_rp() blend = mat_state.material.arm_blending parse_opacity = blend or mat_utils.is_transluc(mat_state.material) make_forward_base(con_mesh, parse_opacity=parse_opacity) frag = con_mesh.frag if '_LTC' in wrd.world_defs: frag.add_uniform('vec3 lightArea0', '_lightArea0', included=True) frag.add_uniform('vec3 lightArea1', '_lightArea1', included=True) frag.add_uniform('vec3 lightArea2', '_lightArea2', included=True) frag.add_uniform('vec3 lightArea3', '_lightArea3', included=True) frag.add_uniform('sampler2D sltcMat', '_ltcMat', included=True) frag.add_uniform('sampler2D sltcMag', '_ltcMag', included=True) if '_ShadowMap' in wrd.world_defs: if '_SinglePoint' in wrd.world_defs: frag.add_uniform('mat4 LWVPSpot[0]', link='_biasLightViewProjectionMatrixSpot0', included=True) frag.add_uniform('sampler2DShadow shadowMapSpot[1]', included=True) if '_Clusters' in wrd.world_defs: frag.add_uniform( 'mat4 LWVPSpotArray[4]', link='_biasLightWorldViewProjectionMatrixSpotArray', included=True) frag.add_uniform('sampler2DShadow shadowMapSpot[4]', included=True) if not blend: mrt = rpdat.rp_ssr if mrt: # Store light gbuffer for post-processing frag.add_out('vec4 fragColor[2]') frag.add_include('std/gbuffer.glsl') frag.write('n /= (abs(n.x) + abs(n.y) + abs(n.z));') frag.write('n.xy = n.z >= 0.0 ? n.xy : octahedronWrap(n.xy);') frag.write( 'fragColor[0] = vec4(direct + indirect, packFloat2(occlusion, specular));' ) frag.write('fragColor[1] = vec4(n.xy, roughness, metallic);') else: frag.add_out('vec4 fragColor[1]') frag.write('fragColor[0] = vec4(direct + indirect, 1.0);') if '_LDR' in wrd.world_defs: frag.add_include('std/tonemap.glsl') frag.write('fragColor[0].rgb = tonemapFilmic(fragColor[0].rgb);') # Particle opacity if mat_state.material.arm_particle_flag and arm.utils.get_rp( ).arm_particles == 'On' and mat_state.material.arm_particle_fade: frag.write('fragColor[0].rgb *= p_fade;')
def make_forward(con_mesh): wrd = bpy.data.worlds['Arm'] blend = mat_state.material.arm_blending parse_opacity = blend and mat_utils.is_transluc(mat_state.material) make_forward_base(con_mesh, parse_opacity=parse_opacity) frag = con_mesh.frag if not blend: frag.add_out('vec4 fragColor') frag.write('fragColor = vec4(direct + indirect, 1.0);') if '_LDR' in wrd.world_defs: frag.add_include('std/tonemap.glsl') frag.write('fragColor.rgb = tonemapFilmic(fragColor.rgb);') # frag.write('fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / 2.2));') # Particle opacity if mat_state.material.arm_particle_flag and arm.utils.get_rp().arm_particles == 'GPU' and mat_state.material.arm_particle_fade: frag.write('fragColor.rgb *= p_fade;')
def make_forward(con_mesh): wrd = bpy.data.worlds['Arm'] rpdat = arm.utils.get_rp() blend = mat_state.material.arm_blending parse_opacity = blend or mat_utils.is_transluc(mat_state.material) make_forward_base(con_mesh, parse_opacity=parse_opacity) frag = con_mesh.frag if not blend: mrt = rpdat.rp_ssr if mrt: # Store light gbuffer for post-processing frag.add_out('vec4 fragColor[2]') frag.add_include('std/gbuffer.glsl') frag.write('n /= (abs(n.x) + abs(n.y) + abs(n.z));') frag.write('n.xy = n.z >= 0.0 ? n.xy : octahedronWrap(n.xy);') frag.write( 'fragColor[0] = vec4(direct + indirect, packFloat2(occlusion, specular));' ) frag.write( 'fragColor[1] = vec4(n.xy, packFloat(metallic, roughness), 1.0);' ) else: frag.add_out('vec4 fragColor[1]') frag.write('fragColor[0] = vec4(direct + indirect, 1.0);') if '_LDR' in wrd.world_defs: frag.add_include('std/tonemap.glsl') frag.write('fragColor[0].rgb = tonemapFilmic(fragColor[0].rgb);') # Particle opacity if mat_state.material.arm_particle_flag and arm.utils.get_rp( ).arm_particles == 'GPU' and mat_state.material.arm_particle_fade: frag.write('fragColor[0].rgb *= p_fade;')
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_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, 1.0);') frag.ins = vert.outs write_vertpos(vert) 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;') 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)) if con_mesh.is_elem('tex'): vert.add_out('vec2 texCoord') if mat_state.material.arm_tilesheet_mat: vert.add_uniform('vec2 tilesheetOffset', '_tilesheetOffset') vert.write('texCoord = tex + tilesheetOffset;') else: vert.write('texCoord = tex;') if con_mesh.is_elem('col'): vert.add_out('vec3 vcolor') vert.write('vcolor = col;') if con_mesh.is_elem('tang'): vert.add_out('mat3 TBN') write_norpos(con_mesh, vert, declare=True) vert.write('vec3 tangent = normalize(N * tang);') vert.write('vec3 bitangent = normalize(cross(wnormal, tangent));') vert.write('TBN = mat3(tangent, bitangent, wnormal);') else: vert.add_out('vec3 wnormal') write_norpos(con_mesh, vert) frag.write_attrib('vec3 n = normalize(wnormal);') 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 if is_shadows: frag.add_include('std/shadows.glsl') 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', '_biasLightWorldViewProjectionMatrix') vert.write('lightPosition = LWVP * spos;') frag.add_uniform('sampler2D shadowMap') frag.add_uniform('float shadowsBias', '_sunShadowsBias') frag.write('if (lightPosition.w > 0.0) {') frag.write(' vec3 lPos = lightPosition.xyz / lightPosition.w;') frag.write(' const float texelSize = 1.0 / shadowmapSize.x;') frag.write(' svisibility = 0.0;') frag.write( ' svisibility += float(texture(shadowMap, lPos.xy).r + shadowsBias > lPos.z);' ) frag.write( ' svisibility += float(texture(shadowMap, lPos.xy + vec2(texelSize, 0.0)).r + shadowsBias > lPos.z) * 0.5;' ) frag.write( ' svisibility += float(texture(shadowMap, lPos.xy + vec2(-texelSize, 0.0)).r + shadowsBias > lPos.z) * 0.25;' ) frag.write( ' svisibility += float(texture(shadowMap, lPos.xy + vec2(0.0, texelSize)).r + shadowsBias > lPos.z) * 0.5;' ) frag.write( ' svisibility += float(texture(shadowMap, lPos.xy + vec2(0.0, -texelSize)).r + shadowsBias > lPos.z) * 0.25;' ) frag.write(' svisibility /= 2.5;') frag.write(' svisibility = max(svisibility, 0.2);') # frag.write(' svisibility = max(float(texture(shadowMap, lPos.xy).r + shadowsBias > lPos.z), 0.5);') frag.write('}') frag.write('direct += basecol * sdotNL * sunCol * svisibility;') if '_Clusters' in wrd.world_defs and '_Sun' not in wrd.world_defs: frag.add_include('std/clusters.glsl') frag.add_uniform('vec3 lightPos', '_lightPosition') frag.add_uniform('vec3 lightCol', '_lightColor') frag.add_uniform('vec3 lightDir', '_lightDirection') frag.write('float visibility = 1.0;') frag.write('float dotNL = max(dot(n, lightDir), 0.0);') if is_shadows: vert.add_out('vec4 lightPosition') vert.add_uniform('mat4 LWVP', '_biasLightWorldViewProjectionMatrix') vert.write('lightPosition = LWVP * spos;') frag.add_uniform('sampler2D shadowMap0') frag.add_uniform('float shadowsBias', '_lightShadowsBias') frag.write('if (lightPosition.w > 0.0) {') frag.write(' vec3 lPos = lightPosition.xyz / lightPosition.w;') frag.write(' const float texelSize = 1.0 / shadowmapSize.x;') frag.write(' visibility = 0.0;') frag.write( ' visibility += float(texture(shadowMap0, lPos.xy).r + shadowsBias > lPos.z);' ) frag.write( ' visibility += float(texture(shadowMap0, lPos.xy + vec2(texelSize, 0.0)).r + shadowsBias > lPos.z) * 0.5;' ) frag.write( ' visibility += float(texture(shadowMap0, lPos.xy + vec2(-texelSize, 0.0)).r + shadowsBias > lPos.z) * 0.25;' ) frag.write( ' visibility += float(texture(shadowMap0, lPos.xy + vec2(0.0, texelSize)).r + shadowsBias > lPos.z) * 0.5;' ) frag.write( ' visibility += float(texture(shadowMap0, lPos.xy + vec2(0.0, -texelSize)).r + shadowsBias > lPos.z) * 0.25;' ) frag.write(' visibility /= 2.5;') frag.write(' visibility = max(visibility, 0.2);') # frag.write(' visibility = max(float(texture(shadowMap0, lPos.xy).r + shadowsBias > lPos.z), 0.5);') frag.write('}') frag.write( 'direct += basecol * dotNL * lightCol * attenuate(distance(wposition, lightPos)) * visibility;' ) # frag.write('direct += vec3(D_Approx(max(roughness, 0.3), dot(reflect(-vVec, n), lightDir)));') if '_Irr' in wrd.world_defs: frag.add_include('std/shirr.glsl') frag.add_uniform('vec4 shirr[7]', link='_envmapIrradiance', included=True) env_str = 'shIrradiance(n)' 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));')