Esempio n. 1
0
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);')
Esempio n. 2
0
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_elements']:
        if e['name'] == 'nor':
            con_mesh.data['vertex_elements'].remove(e)
            break

    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,
                 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')
        vert.add_uniform('float texUnpack', link='_texUnpack')
        if mat_state.material.arm_tilesheet_flag:
            vert.add_uniform('vec2 tilesheetOffset', '_tilesheetOffset')
            vert.write('texCoord = tex * texUnpack + tilesheetOffset;')
        else:
            vert.write('texCoord = tex * texUnpack;')

    if con_mesh.is_elem('col'):
        vert.add_out('vec3 vcolor')
        vert.write('vcolor = col.rgb;')

    make_attrib.write_norpos(con_mesh, vert, write_nor=False)
    make_attrib.write_vertpos(vert)

    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));')
Esempio n. 3
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

    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 lightDir', '_lightDirection')
    frag.add_uniform('vec3 lightColor', '_lightColor')
    frag.add_uniform('float envmapStrength', link='_envmapStrength')
    frag.write('float visibility = 1.0;')
    frag.write('float dotNL = max(dot(n, lightDir), 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', '_lightShadowsBias')
        frag.write('if (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;')
    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 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 * 0.1;')
        vert.write('gl_Position = VP * wpos;')
    else:
        make_attrib.write_vertpos(vert)

    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')
        vert.add_uniform('float texUnpack', link='_texUnpack')
        vert.write_attrib('texCoord = tex * texUnpack;')

    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('vec3 direct = basecol * step(0.5, dotNL) * visibility * lightColor;')
    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));')

    assets.vs_equal(con_mesh, assets.shader_cons['mesh_vert'])

    make_finalize.make(con_mesh)

    return con_mesh
Esempio n. 4
0
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));')
Esempio n. 5
0
def make_base(con_mesh, parse_opacity):
    global is_displacement
    global write_material_attribs
    global write_material_attribs_post
    global write_vertex_attribs

    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 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)

    if not is_displacement and not vattr_written:
        make_attrib.write_vertpos(vert)

    if con_mesh.is_elem('tex'):
        vert.add_out('vec2 texCoord')
        vert.add_uniform('float texUnpack', link='_texUnpack')
        if mat_state.material.arm_tilesheet_mat:
            if mat_state.material.arm_particle_flag and rpdat.arm_particles == 'GPU':
                make_particle.write_tilesheet(vert)
            else:
                vert.add_uniform('vec2 tilesheetOffset', '_tilesheetOffset')
                vert.write_attrib('texCoord = tex * texUnpack + tilesheetOffset;')
        else:
            vert.write_attrib('texCoord = tex * texUnpack;')

        if tese != None:
            tese.write_pre = True
            make_tess.interpolate(tese, 'texCoord', 2, declare_out=frag.contains('texCoord'))
            tese.write_pre = False

    if con_mesh.is_elem('tex1'):
        vert.add_out('vec2 texCoord1')
        vert.add_uniform('float texUnpack', link='_texUnpack')
        vert.write_attrib('texCoord1 = tex1 * texUnpack;')
        if tese != None:
            tese.write_pre = True
            make_tess.interpolate(tese, 'texCoord1', 2, declare_out=frag.contains('texCoord1'))
            tese.write_pre = False

    if con_mesh.is_elem('col'):
        vert.add_out('vec3 vcolor')
        vert.write_attrib('vcolor = col;')
        if tese != 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 != None:
            vert.add_out('vec3 wnormal')
            make_attrib.write_norpos(con_mesh, vert)
            tese.add_out('mat3 TBN')
            tese.write('vec3 wbitangent = normalize(cross(wnormal, wtangent));')
            tese.write('TBN = mat3(wtangent, wbitangent, wnormal);')
        else:
            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);')

    if is_displacement:
        if rpdat.arm_rp_displacement == 'Vertex':
            sh = vert
        else:
            sh = tese
        sh.add_uniform('mat4 VP', '_viewProjectionMatrix')
        sh.write('wposition += wnormal * disp * 0.1;')
        sh.write('gl_Position = VP * vec4(wposition, 1.0);')