Exemple #1
0
def make_finalize(con_mesh):
    vert = con_mesh.vert
    frag = con_mesh.frag
    geom = con_mesh.geom
    tesc = con_mesh.tesc
    tese = con_mesh.tese

    # Additional values referenced in cycles
    # TODO: enable from cycles.py
    if frag.contains('dotNV') and not frag.contains('float dotNV'):
        frag.write_init('float dotNV = max(dot(n, vVec), 0.0);')
    
    write_wpos = False
    if frag.contains('vVec') and not frag.contains('vec3 vVec'):
        if is_displacement:
            tese.add_out('vec3 eyeDir')
            tese.add_uniform('vec3 eye', '_cameraPosition')
            tese.write('eyeDir = eye - wposition;')

        else:
            if not vert.contains('wposition'):
                write_wpos = True
            vert.add_out('vec3 eyeDir')
            vert.add_uniform('vec3 eye', '_cameraPosition')
            vert.write('eyeDir = eye - wposition;')
        frag.write_attrib('vec3 vVec = normalize(eyeDir);')
    
    export_wpos = False
    if frag.contains('wposition') and not frag.contains('vec3 wposition'):
        if not is_displacement: # Displacement always outputs wposition
            export_wpos = True
    
    if export_wpos:
        vert.add_uniform('mat4 W', '_worldMatrix')
        vert.add_out('vec3 wposition')
        vert.write_pre = True
        vert.write('wposition = vec4(W * spos).xyz;')
        vert.write_pre = False
    elif write_wpos:
        vert.add_uniform('mat4 W', '_worldMatrix')
        vert.write_pre = True
        vert.write('vec3 wposition = vec4(W * spos).xyz;')
        vert.write_pre = False

    frag_mpos = frag.contains('mposition') and not frag.contains('vec3 mposition')
    if frag_mpos:
        vert.add_out('vec3 mposition')
        vert.write_pre = True
        vert.write('mposition = spos.xyz;')
        vert.write_pre = False
    
    if tese != None:
        if frag_mpos:
            make_tess.interpolate(tese, 'mposition', 3, declare_out=True)
        elif tese.contains('mposition') and not tese.contains('vec3 mposition'):
            vert.add_out('vec3 mposition')
            vert.write_pre = True
            vert.write('mposition = spos.xyz;')
            vert.write_pre = False
            make_tess.interpolate(tese, 'mposition', 3, declare_out=False)
Exemple #2
0
def make_deferred(con_mesh):
    wrd = bpy.data.worlds['Arm']
    make_base(con_mesh, parse_opacity=False)

    frag = con_mesh.frag
    vert = con_mesh.vert
    tese = con_mesh.tese

    if '_Veloc' in wrd.rp_defs:
        frag.add_out('vec4[3] fragColor')
        if tese == None:
            vert.add_uniform('mat4 prevWVP',
                             link='_prevWorldViewProjectionMatrix')
            vert.add_out('vec4 wvpposition')
            vert.add_out('vec4 prevwvpposition')
            vert.write('wvpposition = gl_Position;')
            vert.write('prevwvpposition = prevWVP * spos;')
        else:
            vert.add_uniform('mat4 prevW', link='_prevWorldMatrix')
            vert.add_out('vec3 prevwposition')
            vert.write('prevwposition = vec4(prevW * spos).xyz;')
            tese.add_out('vec4 wvpposition')
            tese.add_out('vec4 prevwvpposition')
            tese.add_uniform('mat4 prevVP', '_prevViewProjectionMatrix')
            tese.write('wvpposition = gl_Position;')
            make_tess.interpolate(tese, 'prevwposition', 3)
            tese.write('prevwvpposition = prevVP * vec4(prevwposition, 1.0);')
    else:
        frag.add_out('vec4[2] fragColor')

    # Pack gbuffer
    frag.add_include('../../Shaders/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);')
    # TODO: store_depth
    frag.write(
        'fragColor[0] = vec4(n.xy, packFloat(metallic, roughness), 1.0 - gl_FragCoord.z);'
    )
    if '_SSS' in wrd.rp_defs:
        frag.add_uniform('int materialID')
        frag.write(
            'fragColor[1] = vec4(basecol.rgb, materialID + clamp(occlusion, 0.0, 1.0 - 0.001));'
        )
    else:
        frag.write('fragColor[1] = vec4(basecol.rgb, occlusion);')

    if '_Veloc' in wrd.rp_defs:
        frag.write('vec2 posa = (wvpposition.xy / wvpposition.w) * 0.5 + 0.5;')
        frag.write(
            'vec2 posb = (prevwvpposition.xy / prevwvpposition.w) * 0.5 + 0.5;'
        )
        frag.write('fragColor[2].rg = vec2(posa - posb);')

    return con_mesh
Exemple #3
0
def write_tex_coords(con_mesh: ShaderContext, vert: Shader, frag: Shader,
                     tese: Optional[Shader]):
    rpdat = arm.utils.get_rp()

    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:
            if mat_state.material.arm_particle_flag and rpdat.arm_particles == 'On':
                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 is not 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 is not None:
            tese.write_pre = True
            make_tess.interpolate(tese,
                                  'texCoord1',
                                  2,
                                  declare_out=frag.contains('texCoord1'))
            tese.write_pre = False
Exemple #4
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);')
Exemple #5
0
def make_deferred(con_mesh, rpasses):
    wrd = bpy.data.worlds['Arm']
    rpdat = arm.utils.get_rp()

    arm_discard = mat_state.material.arm_discard
    parse_opacity = arm_discard or 'translucent' in rpasses

    make_base(con_mesh, parse_opacity=parse_opacity)

    frag = con_mesh.frag
    vert = con_mesh.vert
    tese = con_mesh.tese

    if parse_opacity:
        if arm_discard:
            opac = mat_state.material.arm_discard_opacity
        else:
            opac = '0.9999'  # 1.0 - eps
        frag.write('if (opacity < {0}) discard;'.format(opac))

    gapi = arm.utils.get_gapi()
    if '_gbuffer2' in wrd.world_defs:
        frag.add_out('vec4 fragColor[3]')
        if '_Veloc' in wrd.world_defs:
            if tese == None:
                vert.add_uniform('mat4 prevWVP',
                                 link='_prevWorldViewProjectionMatrix')
                vert.add_out('vec4 wvpposition')
                vert.add_out('vec4 prevwvpposition')
                vert.write('wvpposition = gl_Position;')
                if is_displacement:
                    vert.add_uniform('mat4 invW', link='_inverseWorldMatrix')
                    vert.write(
                        'prevwvpposition = prevWVP * (invW * vec4(wposition, 1.0));'
                    )
                else:
                    vert.write('prevwvpposition = prevWVP * spos;')
            else:
                tese.add_out('vec4 wvpposition')
                tese.add_out('vec4 prevwvpposition')
                tese.write('wvpposition = gl_Position;')
                if is_displacement:
                    tese.add_uniform('mat4 invW', link='_inverseWorldMatrix')
                    tese.add_uniform('mat4 prevWVP',
                                     '_prevWorldViewProjectionMatrix')
                    tese.write(
                        'prevwvpposition = prevWVP * (invW * vec4(wposition, 1.0));'
                    )
                else:
                    vert.add_uniform('mat4 prevW', link='_prevWorldMatrix')
                    vert.add_out('vec3 prevwposition')
                    vert.write('prevwposition = vec4(prevW * spos).xyz;')
                    tese.add_uniform('mat4 prevVP',
                                     '_prevViewProjectionMatrix')
                    make_tess.interpolate(tese, 'prevwposition', 3)
                    tese.write(
                        'prevwvpposition = prevVP * vec4(prevwposition, 1.0);')
    else:
        frag.add_out('vec4 fragColor[2]')

    # Pack gbuffer
    frag.add_include('std/gbuffer.glsl')

    if mat_state.material.arm_two_sided:
        frag.write('if (!gl_FrontFacing) n *= -1;'
                   )  # Flip normal when drawing back-face

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

    if '_Emission' in wrd.world_defs or '_SSS' in wrd.world_defs or '_Hair' in wrd.world_defs:
        frag.write('uint matid = 0;')
        if '_Emission' in wrd.world_defs:
            frag.write('if (emission > 0) { basecol *= emission; matid = 1; }')
        if '_SSS' in wrd.world_defs or '_Hair' in wrd.world_defs:
            frag.add_uniform('int materialID')
            frag.write('if (materialID == 2) matid = 2;')
    else:
        frag.write('const uint matid = 0;')

    frag.write(
        'fragColor[0] = vec4(n.xy, roughness, packFloatInt16(metallic, matid));'
    )
    frag.write(
        'fragColor[1] = vec4(basecol, packFloat2(occlusion, specular));')

    if '_gbuffer2' in wrd.world_defs:
        if '_Veloc' in wrd.world_defs:
            frag.write(
                'vec2 posa = (wvpposition.xy / wvpposition.w) * 0.5 + 0.5;')
            frag.write(
                'vec2 posb = (prevwvpposition.xy / prevwvpposition.w) * 0.5 + 0.5;'
            )
            frag.write('fragColor[2].rg = vec2(posa - posb);')

        if mat_state.material.arm_ignore_irradiance:
            frag.write('fragColor[2].b = 1.0;')

    return con_mesh
Exemple #6
0
def make_deferred(con_mesh):
    wrd = bpy.data.worlds['Arm']
    rpdat = arm.utils.get_rp()

    arm_discard = mat_state.material.arm_discard
    parse_opacity = arm_discard or rpdat.arm_voxelgi_refraction

    make_base(con_mesh, parse_opacity=parse_opacity)

    frag = con_mesh.frag
    vert = con_mesh.vert
    tese = con_mesh.tese

    if arm_discard:
        opac = mat_state.material.arm_discard_opacity
        frag.write('if (opacity < {0}) discard;'.format(opac))

    gapi = arm.utils.get_gapi()
    if '_gbuffer2' in wrd.world_defs:
        frag.add_out('vec4[3] fragColor')
        if '_Veloc' in wrd.world_defs:
            if tese == None:
                vert.add_uniform('mat4 prevWVP',
                                 link='_prevWorldViewProjectionMatrix')
                vert.add_out('vec4 wvpposition')
                vert.add_out('vec4 prevwvpposition')
                vert.write('wvpposition = gl_Position;')
                vert.write('prevwvpposition = prevWVP * spos;')
            else:
                vert.add_uniform('mat4 prevW', link='_prevWorldMatrix')
                vert.add_out('vec3 prevwposition')
                vert.write('prevwposition = vec4(prevW * spos).xyz;')
                tese.add_out('vec4 wvpposition')
                tese.add_out('vec4 prevwvpposition')
                tese.add_uniform('mat4 prevVP', '_prevViewProjectionMatrix')
                tese.write('wvpposition = gl_Position;')
                make_tess.interpolate(tese, 'prevwposition', 3)
                tese.write(
                    'prevwvpposition = prevVP * vec4(prevwposition, 1.0);')
    elif gapi.startswith('direct3d'):
        vert.add_out('vec4 wvpposition')
        vert.write('wvpposition = gl_Position;')
        frag.add_out('vec4[2] fragColor')
    else:
        frag.add_out('vec4[2] fragColor')

    # Pack gbuffer
    frag.add_include('std/gbuffer.glsl')

    if mat_state.material.arm_two_sided:
        frag.write('if (!gl_FrontFacing) n *= -1;'
                   )  # Flip normal when drawing back-face

    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);')
    # TODO: store_depth
    if gapi.startswith('direct3d'):
        frag.write(
            'fragColor[0] = vec4(n.xy, packFloat(metallic, roughness), 1.0 - ((wvpposition.z / wvpposition.w) * 0.5 + 0.5));'
        )
    else:
        frag.write(
            'fragColor[0] = vec4(n.xy, packFloat(metallic, roughness), 1.0 - gl_FragCoord.z);'
        )
    frag.write(
        'fragColor[1] = vec4(basecol.rgb, packFloat2(occlusion, specular));')

    if '_gbuffer2' in wrd.world_defs:
        if '_Veloc' in wrd.world_defs:
            frag.write(
                'vec2 posa = (wvpposition.xy / wvpposition.w) * 0.5 + 0.5;')
            frag.write(
                'vec2 posb = (prevwvpposition.xy / prevwvpposition.w) * 0.5 + 0.5;'
            )
            frag.write('fragColor[2].rg = vec2(posa - posb);')
        if rpdat.arm_voxelgi_refraction:
            frag.write('fragColor[2].b = opacity;')
        if '_SSS' in wrd.world_defs or '_Hair' in wrd.world_defs:
            frag.add_uniform('int materialID')
            frag.write('fragColor[2].a = materialID;')

    return con_mesh
Exemple #7
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, 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.glsl')

    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:
        write_vertpos(vert)

    if con_mesh.is_elem('tex'):
        vert.add_out('vec2 texCoord')
        if mat_state.material.arm_tilesheet_mat:
            if mat_state.material.arm_particle == 'gpu':
                make_particle.write_tilesheet(vert)
            else:
                vert.add_uniform('vec2 tilesheetOffset', '_tilesheetOffset')
                vert.write_attrib('texCoord = tex + tilesheetOffset;')
        else:
            vert.write_attrib('texCoord = tex;')

        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.write_attrib('texCoord1 = tex1;')
        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')
            vert.add_out('vec3 wtangent')
            write_norpos(con_mesh, vert)
            vert.write('wtangent = normalize(N * tang);')
            tese.add_out('mat3 TBN')
            make_tess.interpolate(tese, 'wtangent', 3, normalize=True)
            tese.write(
                'vec3 wbitangent = normalize(cross(wnormal, wtangent));')
            tese.write('TBN = mat3(wtangent, wbitangent, wnormal);')
        else:
            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);')

    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);')
Exemple #8
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_main_header('    vec4 spos = vec4(pos, 1.0);')

    vattr_written = False
    is_displacement = mat_utils.disp_linked(mat_state.output_node)
    if is_displacement:
        tesc = con_mesh.make_tesc()
        tese = con_mesh.make_tese()
        tesc.ins = vert.outs
        tese.ins = tesc.outs
        frag.ins = tese.outs

        vert.add_uniform('mat4 W', '_worldMatrix')
        vert.add_out('vec3 wposition')
        vert.write('wposition = vec4(W * spos).xyz;')
        make_tess.tesc_levels(tesc, mat_state.material.arm_tess_inner,
                              mat_state.material.arm_tess_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('../../Shaders/compiled.glsl')

    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;')
        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:
        billboard = mat_state.material.arm_billboard
        particle = mat_state.material.arm_particle
        wrd = bpy.data.worlds['Arm']
        # Particles
        if particle != 'off':
            if particle == 'gpu':
                make_particle.write(vert, particle_info=cycles.particle_info)
            # Billboards
            if billboard == 'spherical':
                vert.add_uniform('mat4 WV', '_worldViewMatrix')
                vert.add_uniform('mat4 P', '_projectionMatrix')
                vert.write(
                    'gl_Position = P * (WV * vec4(0.0, 0.0, spos.z, 1.0) + vec4(spos.x, spos.y, 0.0, 0.0));'
                )
            else:
                vert.add_uniform('mat4 WVP', '_worldViewProjectionMatrix')
                vert.write('gl_Position = WVP * spos;')
        else:
            # Billboards
            if billboard == 'spherical':
                vert.add_uniform('mat4 WVP',
                                 '_worldViewProjectionMatrixSphere')
            elif billboard == 'cylindrical':
                vert.add_uniform('mat4 WVP',
                                 '_worldViewProjectionMatrixCylinder')
            else:  # off
                vert.add_uniform('mat4 WVP', '_worldViewProjectionMatrix')
            vert.write('gl_Position = WVP * spos;')

    if con_mesh.is_elem('tex'):
        vert.add_out('vec2 texCoord')
        if mat_state.material.arm_tilesheet_mat:
            if mat_state.material.arm_particle == 'gpu':
                make_particle.write_tilesheet(vert)
            else:
                vert.add_uniform('vec2 tilesheetOffset', '_tilesheetOffset')
                vert.write('texCoord = tex + tilesheetOffset;')
        else:
            vert.write('texCoord = tex;')

        if tese != None:
            # TODO: also includes texCoord1
            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.write('texCoord1 = tex1;')
        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('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')
            vert.add_out('vec3 wtangent')
            write_norpos(con_mesh, vert)
            vert.write('wtangent = normalize(N * tang);')
            tese.add_out('mat3 TBN')
            make_tess.interpolate(tese, 'wtangent', 3, normalize=True)
            tese.write(
                'vec3 wbitangent = normalize(cross(wnormal, wtangent));')
            tese.write('TBN = mat3(wtangent, wbitangent, wnormal);')
        else:
            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.prepend_header('vec3 n = normalize(wnormal);')

    if tese != None:
        tese.add_uniform('mat4 VP', '_viewProjectionMatrix')
        # TODO: Sample disp at neightbour points to calc normal
        tese.write('wposition += wnormal * disp * 0.2;')
        tese.write('gl_Position = VP * vec4(wposition, 1.0);')
def make(context_id, rpasses):

    is_disp = mat_utils.disp_linked(
        mat_state.output_node) and mat_state.material.height_tess_shadows

    vs = [{'name': 'pos', 'size': 3}]
    if is_disp:
        vs.append({'name': 'nor', 'size': 3})

    con_shadowmap = mat_state.data.add_context({
        'name': context_id,
        'vertex_structure': vs,
        'depth_write': True,
        'compare_mode': 'less',
        'cull_mode': 'clockwise',
        'color_write_red': False,
        'color_write_green': False,
        'color_write_blue': False,
        'color_write_alpha': False
    })

    vert = con_shadowmap.make_vert()
    frag = con_shadowmap.make_frag()
    geom = None
    tesc = None
    tese = None

    gapi = arm.utils.get_gapi()
    if gapi == 'direct3d9':
        frag.add_out(
            'vec4 fragColor'
        )  # Definition requred for d3d9 - pixel shader must minimally write all four components of COLOR0
    vert.write_main_header('vec4 spos = vec4(pos, 1.0);')

    parse_opacity = 'translucent' in rpasses or mat_state.material.discard_transparent
    if parse_opacity:
        frag.write('vec3 n;')  # Discard at compile time
        frag.write('float dotNV;')
        frag.write('float opacity;')

    if con_shadowmap.is_elem('bone'):
        make_skin.skin_pos(vert)

    if con_shadowmap.is_elem('off'):
        vert.write('spos.xyz += off;')

    if is_disp:
        tesc = con_shadowmap.make_tesc()
        tese = con_shadowmap.make_tese()
        tesc.ins = vert.outs
        tese.ins = tesc.outs
        frag.ins = tese.outs

        vert.add_out('vec3 wposition')
        vert.add_out('vec3 wnormal')
        vert.add_uniform('mat4 W', '_worldMatrix')
        vert.add_uniform('mat3 N', '_normalMatrix')
        vert.write('wnormal = normalize(N * nor);')
        vert.write('wposition = vec4(W * spos).xyz;')

        const = {}
        const['name'] = 'tessLevel'
        const['vec2'] = [
            mat_state.material.height_tess_shadows_inner,
            mat_state.material.height_tess_shadows_outer
        ]
        mat_state.bind_constants.append(const)
        tesc.add_uniform('vec2 tessLevel')
        make_tess.tesc_levels(tesc)

        make_tess.interpolate(tese, 'wposition', 3)
        make_tess.interpolate(tese, 'wnormal', 3, normalize=True)

        cycles.parse(mat_state.nodes,
                     con_shadowmap,
                     vert,
                     frag,
                     geom,
                     tesc,
                     tese,
                     parse_surface=False,
                     parse_opacity=parse_opacity)

        if con_shadowmap.is_elem('tex'):
            vert.add_out('vec2 texCoord')
            vert.write('texCoord = tex;')
            tese.write_pre = True
            make_tess.interpolate(tese,
                                  'texCoord',
                                  2,
                                  declare_out=frag.contains('texCoord'))
            tese.write_pre = False

        if con_shadowmap.is_elem('tex1'):
            vert.add_out('vec2 texCoord1')
            vert.write('texCoord1 = tex1;')
            tese.write_pre = True
            make_tess.interpolate(tese,
                                  'texCoord1',
                                  2,
                                  declare_out=frag.contains('texCoord1'))
            tese.write_pre = False

        if con_shadowmap.is_elem('col'):
            vert.add_out('vec3 vcolor')
            vert.write('vcolor = col;')
            tese.write_pre = True
            make_tess.interpolate(tese,
                                  'vcolor',
                                  3,
                                  declare_out=frag.contains('vcolor'))
            tese.write_pre = False

        tese.add_uniform('mat4 LVP', '_lampViewProjectionMatrix')
        tese.write('wposition += wnormal * disp * 0.2;')
        tese.write('gl_Position = LVP * vec4(wposition, 1.0);')
    # No displacement
    else:
        frag.ins = vert.outs
        vert.add_uniform('mat4 LWVP', '_lampWorldViewProjectionMatrix')
        vert.write('gl_Position = LWVP * spos;')

        if parse_opacity:
            cycles.parse(mat_state.nodes,
                         con_shadowmap,
                         vert,
                         frag,
                         geom,
                         tesc,
                         tese,
                         parse_surface=False,
                         parse_opacity=True)

            if con_shadowmap.is_elem('tex'):
                vert.add_out('vec2 texCoord')
                vert.write('texCoord = tex;')

            if con_shadowmap.is_elem('tex1'):
                vert.add_out('vec2 texCoord1')
                vert.write('texCoord1 = tex1;')

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

    # TODO: interleaved buffer has to match vertex structure of mesh context
    if not bpy.data.worlds['Arm'].arm_deinterleaved_buffers:
        con_shadowmap.add_elem('nor', 3)
        if mat_state.material.export_uvs:
            con_shadowmap.add_elem('tex', 2)

    # TODO: pass vbuf with proper struct
    if gapi.startswith('direct3d') and bpy.data.worlds[
            'Arm'].arm_deinterleaved_buffers == False:
        vert.write('vec3 t1 = nor; // TODO: Temp for d3d')
        if con_shadowmap.is_elem('tex'):
            vert.write('vec2 t2 = tex; // TODO: Temp for d3d')

    if parse_opacity:
        opac = mat_state.material.discard_transparent_opacity_shadows
        frag.write('if (opacity < {0}) discard;'.format(opac))

    # frag.write('fragColor = vec4(0.0);')

    make_mesh.make_finalize(con_shadowmap)

    return con_shadowmap
Exemple #10
0
def make(context_id, rpasses, shadowmap=False):

    is_disp = mat_utils.disp_linked(mat_state.output_node)

    vs = [{'name': 'pos', 'data': 'short4norm'}]
    if is_disp:
        vs.append({'name': 'nor', 'data': 'short2norm'})

    con_depth = mat_state.data.add_context({
        'name': context_id,
        'vertex_elements': vs,
        'depth_write': True,
        'compare_mode': 'less',
        'cull_mode': 'clockwise',
        'color_writes_red': [False],
        'color_writes_green': [False],
        'color_writes_blue': [False],
        'color_writes_alpha': [False]
    })

    vert = con_depth.make_vert()
    frag = con_depth.make_frag()
    geom = None
    tesc = None
    tese = None

    vert.write_attrib('vec4 spos = vec4(pos.xyz, 1.0);')

    parse_opacity = 'translucent' in rpasses or mat_state.material.arm_discard
    if parse_opacity:
        frag.write('vec3 n;')  # Discard at compile time
        frag.write('float dotNV;')
        frag.write('float opacity;')

    if con_depth.is_elem('bone'):
        make_skin.skin_pos(vert)

    if con_depth.is_elem('ipos'):
        make_inst.inst_pos(con_depth, vert)

    rpdat = arm.utils.get_rp()
    if mat_state.material.arm_particle_flag and rpdat.arm_particles == 'On':
        make_particle.write(vert, shadowmap=shadowmap)

    if is_disp:
        if rpdat.arm_rp_displacement == 'Vertex':
            frag.ins = vert.outs
            vert.add_uniform('mat3 N', '_normalMatrix')
            vert.write('vec3 wnormal = normalize(N * vec3(nor.xy, pos.w));')
            cycles.parse(mat_state.nodes,
                         con_depth,
                         vert,
                         frag,
                         geom,
                         tesc,
                         tese,
                         parse_surface=False,
                         parse_opacity=parse_opacity)
            if con_depth.is_elem('tex'):
                vert.add_out('vec2 texCoord')  ## vs only, remove out
                vert.add_uniform('float texUnpack', link='_texUnpack')
                vert.write_attrib('texCoord = tex * texUnpack;')
            if con_depth.is_elem('tex1'):
                vert.add_out('vec2 texCoord1')  ## vs only, remove out
                vert.add_uniform('float texUnpack', link='_texUnpack')
                vert.write_attrib('texCoord1 = tex1 * texUnpack;')
            if con_depth.is_elem('col'):
                vert.add_out('vec3 vcolor')
                vert.write_attrib('vcolor = col.rgb;')
            vert.write('wposition += wnormal * disp;')
            if shadowmap:
                vert.add_uniform('mat4 LVP', '_lightViewProjectionMatrix')
                vert.write('gl_Position = LVP * vec4(wposition, 1.0);')
            else:
                vert.add_uniform('mat4 VP', '_viewProjectionMatrix')
                vert.write('gl_Position = VP * vec4(wposition, 1.0);')

        else:  # Tessellation
            tesc = con_depth.make_tesc()
            tese = con_depth.make_tese()
            tesc.ins = vert.outs
            tese.ins = tesc.outs
            frag.ins = tese.outs

            vert.add_out('vec3 wnormal')
            vert.add_uniform('mat3 N', '_normalMatrix')
            vert.write('wnormal = normalize(N * vec3(nor.xy, pos.w));')

            make_tess.tesc_levels(tesc, rpdat.arm_tess_shadows_inner,
                                  rpdat.arm_tess_shadows_outer)
            make_tess.interpolate(tese, 'wposition', 3)
            make_tess.interpolate(tese, 'wnormal', 3, normalize=True)

            cycles.parse(mat_state.nodes,
                         con_depth,
                         vert,
                         frag,
                         geom,
                         tesc,
                         tese,
                         parse_surface=False,
                         parse_opacity=parse_opacity)

            if con_depth.is_elem('tex'):
                vert.add_out('vec2 texCoord')
                vert.add_uniform('float texUnpack', link='_texUnpack')
                vert.write('texCoord = tex * texUnpack;')
                tese.write_pre = True
                make_tess.interpolate(tese,
                                      'texCoord',
                                      2,
                                      declare_out=frag.contains('texCoord'))
                tese.write_pre = False

            if con_depth.is_elem('tex1'):
                vert.add_out('vec2 texCoord1')
                vert.write('texCoord1 = tex1;')
                tese.write_pre = True
                make_tess.interpolate(tese,
                                      'texCoord1',
                                      2,
                                      declare_out=frag.contains('texCoord1'))
                tese.write_pre = False

            if con_depth.is_elem('col'):
                vert.add_out('vec3 vcolor')
                vert.write('vcolor = col.rgb;')
                tese.write_pre = True
                make_tess.interpolate(tese,
                                      'vcolor',
                                      3,
                                      declare_out=frag.contains('vcolor'))
                tese.write_pre = False

            if shadowmap:
                tese.add_uniform('mat4 LVP', '_lightViewProjectionMatrix')
                tese.write('wposition += wnormal * disp;')
                tese.write('gl_Position = LVP * vec4(wposition, 1.0);')
            else:
                tese.add_uniform('mat4 VP', '_viewProjectionMatrix')
                tese.write('wposition += wnormal * disp;')
                tese.write('gl_Position = VP * vec4(wposition, 1.0);')
    # No displacement
    else:
        frag.ins = vert.outs
        billboard = mat_state.material.arm_billboard
        if shadowmap:
            if billboard == 'spherical':
                vert.add_uniform('mat4 LWVP',
                                 '_lightWorldViewProjectionMatrixSphere')
            elif billboard == 'cylindrical':
                vert.add_uniform('mat4 LWVP',
                                 '_lightWorldViewProjectionMatrixCylinder')
            else:  # off
                vert.add_uniform('mat4 LWVP',
                                 '_lightWorldViewProjectionMatrix')
            vert.write('gl_Position = LWVP * spos;')
        else:
            if billboard == 'spherical':
                vert.add_uniform('mat4 WVP',
                                 '_worldViewProjectionMatrixSphere')
            elif billboard == 'cylindrical':
                vert.add_uniform('mat4 WVP',
                                 '_worldViewProjectionMatrixCylinder')
            else:  # off
                vert.add_uniform('mat4 WVP', '_worldViewProjectionMatrix')
            vert.write('gl_Position = WVP * spos;')

        if parse_opacity:
            cycles.parse(mat_state.nodes,
                         con_depth,
                         vert,
                         frag,
                         geom,
                         tesc,
                         tese,
                         parse_surface=False,
                         parse_opacity=True)

            if con_depth.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_depth.is_elem('tex1'):
                vert.add_out('vec2 texCoord1')
                vert.write('texCoord1 = tex1;')

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

    if parse_opacity:
        if mat_state.material.arm_discard:
            opac = mat_state.material.arm_discard_opacity_shadows
        else:
            opac = '1.0'
        frag.write('if (opacity < {0}) discard;'.format(opac))

    make_finalize.make(con_depth)

    assets.vs_equal(con_depth, assets.shader_cons['depth_vert'])
    assets.fs_equal(con_depth, assets.shader_cons['depth_frag'])

    return con_depth
Exemple #11
0
def make(con_mesh):
    vert = con_mesh.vert
    frag = con_mesh.frag
    geom = con_mesh.geom
    tesc = con_mesh.tesc
    tese = con_mesh.tese

    # Additional values referenced in cycles
    # TODO: enable from cycles.py
    if frag.contains('dotNV') and not frag.contains('float dotNV'):
        frag.write_init('float dotNV = max(dot(n, vVec), 0.0);')

    write_wpos = False
    if frag.contains('vVec') and not frag.contains('vec3 vVec'):
        if tese != None:
            tese.add_out('vec3 eyeDir')
            tese.add_uniform('vec3 eye', '_cameraPosition')
            tese.write('eyeDir = eye - wposition;')

        else:
            if not vert.contains('wposition'):
                write_wpos = True
            vert.add_out('vec3 eyeDir')
            vert.add_uniform('vec3 eye', '_cameraPosition')
            vert.write('eyeDir = eye - wposition;')
        frag.write_attrib('vec3 vVec = normalize(eyeDir);')

    export_wpos = False
    if frag.contains('wposition') and not frag.contains('vec3 wposition'):
        export_wpos = True
    if tese != None:
        export_wpos = True
    if vert.contains('wposition'):
        write_wpos = True

    if export_wpos:
        vert.add_uniform('mat4 W', '_worldMatrix')
        vert.add_out('vec3 wposition')
        vert.write_attrib('wposition = vec4(W * spos).xyz;')
    elif write_wpos:
        vert.add_uniform('mat4 W', '_worldMatrix')
        vert.write_attrib('vec3 wposition = vec4(W * spos).xyz;')

    frag_mpos = (
        frag.contains('mposition')
        and not frag.contains('vec3 mposition')) or vert.contains('mposition')
    if frag_mpos:
        vert.add_out('vec3 mposition')
        vert.write_attrib('mposition = spos.xyz;')

    if tese != None:
        if frag_mpos:
            make_tess.interpolate(tese, 'mposition', 3, declare_out=True)
        elif tese.contains(
                'mposition') and not tese.contains('vec3 mposition'):
            vert.add_out('vec3 mposition')
            vert.write_pre = True
            vert.write('mposition = spos.xyz;')
            vert.write_pre = False
            make_tess.interpolate(tese, 'mposition', 3, declare_out=False)

    frag_bpos = (
        frag.contains('bposition')
        and not frag.contains('vec3 bposition')) or vert.contains('bposition')
    if frag_bpos:
        vert.add_out('vec3 bposition')
        vert.add_uniform('vec3 dim', link='_dim')
        vert.add_uniform('vec3 hdim', link='_halfDim')
        vert.write_pre = True
        vert.write('bposition = (spos.xyz + hdim) / dim;')
        vert.write_pre = False

    if tese != None:
        if frag_bpos:
            make_tess.interpolate(tese, 'bposition', 3, declare_out=True)
        elif tese.contains(
                'bposition') and not tese.contains('vec3 bposition'):
            vert.add_out('vec3 bposition')
            vert.write_pre = True
            vert.write('bposition = spos.xyz;')
            vert.write_pre = False
            make_tess.interpolate(tese, 'bposition', 3, declare_out=False)

    frag_wtan = (
        frag.contains('wtangent')
        and not frag.contains('vec3 wtangent')) or vert.contains('wtangent')
    if frag_wtan:
        # Indicate we want tang attrib in finalizer to prevent TBN generation
        con_mesh.add_elem('tex', 'short2norm')
        con_mesh.add_elem('tang', 'short4norm')
        vert.add_out('vec3 wtangent')
        vert.write_pre = True
        vert.write('wtangent = normalize(N * tang.xyz);')
        vert.write_pre = False

    if tese != None:
        if frag_wtan:
            make_tess.interpolate(tese, 'wtangent', 3, declare_out=True)
        elif tese.contains('wtangent') and not tese.contains('vec3 wtangent'):
            vert.add_out('vec3 wtangent')
            vert.write_pre = True
            vert.write('wtangent = normalize(N * tang.xyz);')
            vert.write_pre = False
            make_tess.interpolate(tese, 'wtangent', 3, declare_out=False)

    if frag.contains('vVecCam'):
        vert.add_out('vec3 eyeDirCam')
        vert.add_uniform('mat4 WV', '_worldViewMatrix')
        vert.write('eyeDirCam = vec4(WV * spos).xyz; eyeDirCam.z *= -1;')
        frag.write_attrib('vec3 vVecCam = normalize(eyeDirCam);')
Exemple #12
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_main_header('vec4 spos = vec4(pos, 1.0);')

    if mat_utils.disp_linked(mat_state.output_node):
        is_displacement = True
        tesc = con_mesh.make_tesc()
        tese = con_mesh.make_tese()
        tesc.ins = vert.outs
        tese.ins = tesc.outs
        frag.ins = tese.outs

        vert.add_uniform('mat4 W', '_worldMatrix')
        vert.add_out('vec3 wposition')
        vert.write('wposition = vec4(W * spos).xyz;')
        make_tess.tesc_levels(tesc, mat_state.material.arm_tess_inner,
                              mat_state.material.arm_tess_outer)
        make_tess.interpolate(tese, 'wposition', 3, declare_out=True)
        make_tess.interpolate(tese,
                              'wnormal',
                              3,
                              declare_out=True,
                              normalize=True)
    # No displacement
    else:
        is_displacement = False
        frag.ins = vert.outs
        written = False
        if write_vertex_attribs != None:
            written = write_vertex_attribs(vert)
        if written == False:
            vert.add_uniform('mat4 WVP', '_worldViewProjectionMatrix')
            vert.write('gl_Position = WVP * spos;')

    frag.add_include('../../Shaders/compiled.glsl')

    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;')
        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 con_mesh.is_elem('tex'):
        vert.add_out('vec2 texCoord')
        vert.write('texCoord = tex;')
        if tese != None:
            # TODO: also includes texCoord1
            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.write('texCoord1 = tex1;')
        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('vcolor = pow(col, vec3(2.2));')
        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')
            vert.add_out('vec3 wtangent')
            write_norpos(con_mesh, vert)
            vert.write('wtangent = normalize(N * tang);')
            tese.add_out('mat3 TBN')
            make_tess.interpolate(tese, 'wtangent', 3, normalize=True)
            tese.write(
                'vec3 wbitangent = normalize(cross(wnormal, wtangent));')
            tese.write('TBN = mat3(wtangent, wbitangent, wnormal);')
        else:
            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_pre = True
        frag.write_main_header('vec3 n = normalize(wnormal);')
        frag.write_pre = False

    if tese != None:
        tese.add_uniform('mat4 VP', '_viewProjectionMatrix')
        # TODO: Sample disp at neightbour points to calc normal
        tese.write('wposition += wnormal * disp * 0.2;')
        tese.write('gl_Position = VP * vec4(wposition, 1.0);')
Exemple #13
0
def make(context_id, rpasses, shadowmap=False):

    is_disp = mat_utils.disp_linked(
        mat_state.output_node) and mat_state.material.arm_tess_shadows

    vs = [{'name': 'pos', 'size': 3}]
    if is_disp:
        vs.append({'name': 'nor', 'size': 3})

    con_depth = mat_state.data.add_context({
        'name': context_id,
        'vertex_structure': vs,
        'depth_write': True,
        'compare_mode': 'less',
        'cull_mode': 'clockwise',
        'color_write_red': False,
        'color_write_green': False,
        'color_write_blue': False,
        'color_write_alpha': False
    })

    vert = con_depth.make_vert()
    frag = con_depth.make_frag()
    geom = None
    tesc = None
    tese = None

    vert.write_main_header('vec4 spos = vec4(pos, 1.0);')

    parse_opacity = 'translucent' in rpasses or mat_state.material.arm_discard
    if parse_opacity:
        frag.write('vec3 n;')  # Discard at compile time
        frag.write('float dotNV;')
        frag.write('float opacity;')

    if con_depth.is_elem('bone'):
        make_skin.skin_pos(vert)

    if con_depth.is_elem('off'):
        vert.write('spos.xyz += off;')

    wrd = bpy.data.worlds['Arm']
    if mat_state.material.arm_particle == 'gpu':
        make_particle.write(vert)

    if is_disp:
        tesc = con_depth.make_tesc()
        tese = con_depth.make_tese()
        tesc.ins = vert.outs
        tese.ins = tesc.outs
        frag.ins = tese.outs

        vert.add_out('vec3 wposition')
        vert.add_out('vec3 wnormal')
        vert.add_uniform('mat4 W', '_worldMatrix')
        vert.add_uniform('mat3 N', '_normalMatrix')
        vert.write('wnormal = normalize(N * nor);')
        vert.write('wposition = vec4(W * spos).xyz;')

        make_tess.tesc_levels(tesc, mat_state.material.arm_tess_shadows_inner,
                              mat_state.material.arm_tess_shadows_outer)
        make_tess.interpolate(tese, 'wposition', 3)
        make_tess.interpolate(tese, 'wnormal', 3, normalize=True)

        cycles.parse(mat_state.nodes,
                     con_depth,
                     vert,
                     frag,
                     geom,
                     tesc,
                     tese,
                     parse_surface=False,
                     parse_opacity=parse_opacity)

        if con_depth.is_elem('tex'):
            vert.add_out('vec2 texCoord')
            vert.write('texCoord = tex;')
            tese.write_pre = True
            make_tess.interpolate(tese,
                                  'texCoord',
                                  2,
                                  declare_out=frag.contains('texCoord'))
            tese.write_pre = False

        if con_depth.is_elem('tex1'):
            vert.add_out('vec2 texCoord1')
            vert.write('texCoord1 = tex1;')
            tese.write_pre = True
            make_tess.interpolate(tese,
                                  'texCoord1',
                                  2,
                                  declare_out=frag.contains('texCoord1'))
            tese.write_pre = False

        if con_depth.is_elem('col'):
            vert.add_out('vec3 vcolor')
            vert.write('vcolor = col;')
            tese.write_pre = True
            make_tess.interpolate(tese,
                                  'vcolor',
                                  3,
                                  declare_out=frag.contains('vcolor'))
            tese.write_pre = False

        if shadowmap:
            tese.add_uniform('mat4 LVP', '_lampViewProjectionMatrix')
            tese.write('wposition += wnormal * disp * 0.2;')
            tese.write('gl_Position = LVP * vec4(wposition, 1.0);')
        else:
            tese.add_uniform('mat4 VP', '_viewProjectionMatrix')
            tese.write('wposition += wnormal * disp * 0.2;')
            tese.write('gl_Position = VP * vec4(wposition, 1.0);')
    # No displacement
    else:
        frag.ins = vert.outs
        billboard = mat_state.material.arm_billboard
        if shadowmap:
            if billboard == 'spherical':
                vert.add_uniform('mat4 LWVP',
                                 '_lampWorldViewProjectionMatrixSphere')
            elif billboard == 'cylindrical':
                vert.add_uniform('mat4 LWVP',
                                 '_lampWorldViewProjectionMatrixCylinder')
            else:  # off
                vert.add_uniform('mat4 LWVP', '_lampWorldViewProjectionMatrix')
            vert.write('gl_Position = LWVP * spos;')
        else:
            if billboard == 'spherical':
                vert.add_uniform('mat4 WVP',
                                 '_worldViewProjectionMatrixSphere')
            elif billboard == 'cylindrical':
                vert.add_uniform('mat4 WVP',
                                 '_worldViewProjectionMatrixCylinder')
            else:  # off
                vert.add_uniform('mat4 WVP', '_worldViewProjectionMatrix')
            vert.write('gl_Position = WVP * spos;')

        if parse_opacity:
            cycles.parse(mat_state.nodes,
                         con_depth,
                         vert,
                         frag,
                         geom,
                         tesc,
                         tese,
                         parse_surface=False,
                         parse_opacity=True)

            if con_depth.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_depth.is_elem('tex1'):
                vert.add_out('vec2 texCoord1')
                vert.write('texCoord1 = tex1;')

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

    # TODO: interleaved buffer has to match vertex structure of mesh context
    if not bpy.data.worlds['Arm'].arm_deinterleaved_buffers:
        con_depth.add_elem('nor', 3)
        if mat_state.con_mesh != None:
            if mat_state.con_mesh.is_elem('tex'):
                con_depth.add_elem('tex', 2)
            if mat_state.con_mesh.is_elem('tex1'):
                con_depth.add_elem('tex1', 2)
            if mat_state.con_mesh.is_elem('col'):
                con_depth.add_elem('col', 3)
            if mat_state.con_mesh.is_elem('tang'):
                con_depth.add_elem('tang', 4)

    # TODO: pass vbuf with proper struct
    gapi = arm.utils.get_gapi()
    if gapi.startswith('direct3d') and bpy.data.worlds[
            'Arm'].arm_deinterleaved_buffers == False:
        vert.write('vec3 t1 = nor; // TODO: Temp for d3d')
        if con_depth.is_elem('tex'):
            vert.write('vec2 t2 = tex; // TODO: Temp for d3d')

    if parse_opacity:
        opac = mat_state.material.arm_discard_opacity_shadows
        frag.write('if (opacity < {0}) discard;'.format(opac))

    make_mesh.make_finalize(con_depth)

    assets.vs_equal(con_depth, assets.shader_cons['depth_vert'])
    assets.fs_equal(con_depth, assets.shader_cons['depth_frag'])

    return con_depth
Exemple #14
0
def make(con_mesh: ShaderContext):
    vert = con_mesh.vert
    frag = con_mesh.frag
    geom = con_mesh.geom
    tesc = con_mesh.tesc
    tese = con_mesh.tese

    # Additional values referenced in cycles
    # TODO: enable from cycles.py
    if frag.contains('dotNV') and not frag.contains('float dotNV'):
        frag.write_init('float dotNV = max(dot(n, vVec), 0.0);')

        # n is not always defined yet (in some shadowmap shaders e.g.)
        if not frag.contains('vec3 n'):
            vert.add_out('vec3 wnormal')
            vert.add_uniform('mat3 N', '_normalMatrix')
            vert.write_attrib('wnormal = normalize(N * vec3(nor.xy, pos.w));')
            frag.write_attrib('vec3 n = normalize(wnormal);')

            # If not yet added, add nor vertex data
            vertex_elems = con_mesh.data['vertex_elements']
            has_normals = False
            for elem in vertex_elems:
                if elem['name'] == 'nor':
                    has_normals = True
                    break
            if not has_normals:
                vertex_elems.append({'name': 'nor', 'data': 'short2norm'})

    write_wpos = False
    if frag.contains('vVec') and not frag.contains('vec3 vVec'):
        if tese is not None:
            tese.add_out('vec3 eyeDir')
            tese.add_uniform('vec3 eye', '_cameraPosition')
            tese.write('eyeDir = eye - wposition;')

        else:
            if not vert.contains('wposition'):
                write_wpos = True
            vert.add_out('vec3 eyeDir')
            vert.add_uniform('vec3 eye', '_cameraPosition')
            vert.write('eyeDir = eye - wposition;')
        frag.write_attrib('vec3 vVec = normalize(eyeDir);')

    export_wpos = False
    if frag.contains('wposition') and not frag.contains('vec3 wposition'):
        export_wpos = True
    if tese is not None:
        export_wpos = True
    if vert.contains('wposition'):
        write_wpos = True

    if export_wpos:
        vert.add_uniform('mat4 W', '_worldMatrix')
        vert.add_out('vec3 wposition')
        vert.write_attrib('wposition = vec4(W * spos).xyz;')
    elif write_wpos:
        vert.add_uniform('mat4 W', '_worldMatrix')
        vert.write_attrib('vec3 wposition = vec4(W * spos).xyz;')

    frag_mpos = (
        frag.contains('mposition')
        and not frag.contains('vec3 mposition')) or vert.contains('mposition')
    if frag_mpos:
        vert.add_out('vec3 mposition')
        vert.add_uniform('float posUnpack', link='_posUnpack')
        vert.write_attrib('mposition = spos.xyz * posUnpack;')

    if tese is not None:
        if frag_mpos:
            make_tess.interpolate(tese, 'mposition', 3, declare_out=True)
        elif tese.contains(
                'mposition') and not tese.contains('vec3 mposition'):
            vert.add_out('vec3 mposition')
            vert.write_pre = True
            vert.add_uniform('float posUnpack', link='_posUnpack')
            vert.write('mposition = spos.xyz * posUnpack;')
            vert.write_pre = False
            make_tess.interpolate(tese, 'mposition', 3, declare_out=False)

    frag_bpos = (
        frag.contains('bposition')
        and not frag.contains('vec3 bposition')) or vert.contains('bposition')
    if frag_bpos:
        vert.add_out('vec3 bposition')
        vert.add_uniform('vec3 dim', link='_dim')
        vert.add_uniform('vec3 hdim', link='_halfDim')
        vert.add_uniform('float posUnpack', link='_posUnpack')
        vert.write_attrib('bposition = (spos.xyz * posUnpack + hdim) / dim;')
        vert.write_attrib('if (dim.z == 0) bposition.z = 0;')
        vert.write_attrib('if (dim.y == 0) bposition.y = 0;')
        vert.write_attrib('if (dim.x == 0) bposition.x = 0;')

    if tese is not None:
        if frag_bpos:
            make_tess.interpolate(tese, 'bposition', 3, declare_out=True)
        elif tese.contains(
                'bposition') and not tese.contains('vec3 bposition'):
            vert.add_out('vec3 bposition')
            vert.add_uniform('vec3 dim', link='_dim')
            vert.add_uniform('vec3 hdim', link='_halfDim')
            vert.add_uniform('float posUnpack', link='_posUnpack')
            vert.write_attrib(
                'bposition = (spos.xyz * posUnpack + hdim) / dim;')
            make_tess.interpolate(tese, 'bposition', 3, declare_out=False)

    frag_wtan = (
        frag.contains('wtangent')
        and not frag.contains('vec3 wtangent')) or vert.contains('wtangent')
    if frag_wtan:
        # Indicate we want tang attrib in finalizer to prevent TBN generation
        con_mesh.add_elem('tex', 'short2norm')
        con_mesh.add_elem('tang', 'short4norm')
        vert.add_out('vec3 wtangent')
        vert.write_pre = True
        vert.write('wtangent = normalize(N * tang.xyz);')
        vert.write_pre = False

    if tese is not None:
        if frag_wtan:
            make_tess.interpolate(tese, 'wtangent', 3, declare_out=True)
        elif tese.contains('wtangent') and not tese.contains('vec3 wtangent'):
            vert.add_out('vec3 wtangent')
            vert.write_pre = True
            vert.write('wtangent = normalize(N * tang.xyz);')
            vert.write_pre = False
            make_tess.interpolate(tese, 'wtangent', 3, declare_out=False)

    if frag.contains('vVecCam'):
        vert.add_out('vec3 eyeDirCam')
        vert.add_uniform('mat4 WV', '_worldViewMatrix')
        vert.write('eyeDirCam = vec4(WV * spos).xyz; eyeDirCam.z *= -1;')
        frag.write_attrib('vec3 vVecCam = normalize(eyeDirCam);')

    if frag.contains('nAttr'):
        vert.add_out('vec3 nAttr')
        vert.write_attrib('nAttr = vec3(nor.xy, pos.w);')

    wrd = bpy.data.worlds['Arm']
    if '_Legacy' in wrd.world_defs:
        frag.replace('sampler2DShadow', 'sampler2D')
        frag.replace('samplerCubeShadow', 'samplerCube')
Exemple #15
0
def make(context_id, rpasses):
    con_shadowmap = mat_state.data.add_context({
        'name': context_id,
        'depth_write': True,
        'compare_mode': 'less',
        'cull_mode': 'clockwise',
        'color_write_red': False,
        'color_write_green': False,
        'color_write_blue': False,
        'color_write_alpha': False
    })

    vert = con_shadowmap.make_vert()
    frag = con_shadowmap.make_frag()
    geom = None
    tesc = None
    tese = None

    # frag.add_out('vec4 fragColor')
    vert.write_main_header('vec4 spos = vec4(pos, 1.0);')

    # TODO: pass vbuf with proper struct
    vert.write('vec3 t1 = nor; // TODO: Temp for d3d')
    if mat_state.data.is_elem('tex'):
        vert.write('vec2 t2 = tex; // TODO: Temp for d3d')

    parse_opacity = 'translucent' in rpasses
    if parse_opacity:
        frag.write('vec3 n;')  # Discard at compile time
        frag.write('float dotNV;')
        frag.write('float opacity;')

    if mat_state.data.is_elem('bone'):
        make_skin.skin_pos(vert)

    if mat_state.data.is_elem('off'):
        vert.write('spos.xyz += off;')

    if mat_utils.disp_linked(
            mat_state.output_node) and mat_state.material.height_tess_shadows:
        tesc = con_shadowmap.make_tesc()
        tese = con_shadowmap.make_tese()
        tesc.ins = vert.outs
        tese.ins = tesc.outs
        frag.ins = tese.outs

        vert.add_out('vec3 wposition')
        vert.add_out('vec3 wnormal')
        vert.add_uniform('mat4 W', '_worldMatrix')
        vert.add_uniform('mat3 N', '_normalMatrix')
        vert.write('wnormal = normalize(N * nor);')
        vert.write('wposition = vec4(W * spos).xyz;')

        const = {}
        const['name'] = 'tessLevel'
        const['vec2'] = [
            mat_state.material.height_tess_shadows_inner,
            mat_state.material.height_tess_shadows_outer
        ]
        mat_state.bind_constants.append(const)
        tesc.add_uniform('vec2 tessLevel')
        make_tess.tesc_levels(tesc)

        make_tess.interpolate(tese, 'wposition', 3)
        make_tess.interpolate(tese, 'wnormal', 3, normalize=True)

        cycles.parse(mat_state.nodes,
                     vert,
                     frag,
                     geom,
                     tesc,
                     tese,
                     parse_surface=False,
                     parse_opacity=parse_opacity)

        if mat_state.data.is_elem('tex'):
            vert.add_out('vec2 texCoord')
            vert.write('texCoord = tex;')
            tese.write_pre = True
            make_tess.interpolate(tese,
                                  'texCoord',
                                  2,
                                  declare_out=frag.contains('texCoord'))
            tese.write_pre = False

        if mat_state.data.is_elem('tex1'):
            vert.add_out('vec2 texCoord1')
            vert.write('texCoord1 = tex1;')
            tese.write_pre = True
            make_tess.interpolate(tese,
                                  'texCoord1',
                                  2,
                                  declare_out=frag.contains('texCoord1'))
            tese.write_pre = False

        if mat_state.data.is_elem('col'):
            vert.add_out('vec3 vcolor')
            vert.write('vcolor = col;')
            tese.write_pre = True
            make_tess.interpolate(tese,
                                  'vcolor',
                                  3,
                                  declare_out=frag.contains('vcolor'))
            tese.write_pre = False

        tese.add_uniform('mat4 LVP', '_lampViewProjectionMatrix')
        tese.write('wposition += wnormal * disp * 0.2;')
        tese.write('gl_Position = LVP * vec4(wposition, 1.0);')
    # No displacement
    else:
        frag.ins = vert.outs
        vert.add_uniform('mat4 LWVP', '_lampWorldViewProjectionMatrix')
        vert.write('gl_Position = LWVP * spos;')

        if parse_opacity:
            cycles.parse(mat_state.nodes,
                         vert,
                         frag,
                         geom,
                         tesc,
                         tese,
                         parse_surface=False,
                         parse_opacity=True)

            if mat_state.data.is_elem('tex'):
                vert.add_out('vec2 texCoord')
                vert.write('texCoord = tex;')

            if mat_state.data.is_elem('tex1'):
                vert.add_out('vec2 texCoord1')
                vert.write('texCoord1 = tex1;')

            if mat_state.data.is_elem('col'):
                vert.add_out('vec3 vcolor')
                vert.write('vcolor = col;')

    if parse_opacity:
        frag.write('if (opacity < 0.5) discard;')

    # frag.write('fragColor = vec4(0.0);')

    make_mesh.make_finalize(con_shadowmap)

    return con_shadowmap