Example #1
0
def make(context_id, rpasses, shadowmap=False):

    is_disp = mat_utils.disp_linked(mat_state.output_node)

    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_attrib('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:
        rpdat = arm.utils.get_rp()
        if rpdat.arm_rp_displacement == 'Vertex':
            vert.add_uniform('mat4 W', '_worldMatrix')
            vert.add_uniform('mat3 N', '_normalMatrix')
            vert.write('vec3 wnormal = normalize(N * nor);')
            vert.write('vec3 wposition = vec4(W * spos).xyz;')
            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.write_attrib('texCoord = tex;')
            vert.write('wposition += wnormal * disp * 0.1;')
            if shadowmap:
                vert.add_uniform('mat4 LVP', '_lampViewProjectionMatrix')
                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 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, 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.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.1;')
                tese.write('gl_Position = LVP * vec4(wposition, 1.0);')
            else:
                tese.add_uniform('mat4 VP', '_viewProjectionMatrix')
                tese.write('wposition += wnormal * disp * 0.1;')
                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;')

    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
Example #2
0
def make_mesh_pass(rpass):
    con = {
        'name': rpass,
        'depth_write': True,
        'compare_mode': 'less',
        'cull_mode': 'clockwise'
    }

    con_mesh = mat_state.data.add_context(con)
    mat_state.con_mesh = con_mesh
    mat = con_mesh.material

    wrd = bpy.data.worlds['Arm']
    vert = con_mesh.make_vert()
    frag = con_mesh.make_frag()
    geom = None
    tesc = None
    tese = None

    vert.add_uniform('mat3 N', '_normalMatrix')
    vert.write_attrib('vec4 spos = vec4(pos.xyz, 1.0);')
    frag.ins = vert.outs

    frag.add_include('compiled.glsl')
    frag.add_uniform('vec3 sunDir', '_sunDirection')
    frag.add_uniform('vec3 sunCol', '_sunColor')
    frag.add_uniform('float envmapStrength', link='_envmapStrength')
    frag.write('float visibility = 1.0;')
    frag.write('float dotNL = max(dot(n, sunDir), 0.0);')

    is_shadows = '_ShadowMap' in wrd.world_defs
    if is_shadows:
        vert.add_out('vec4 lightPos')
        vert.add_uniform('mat4 LWVP', '_biasLightWorldViewProjectionMatrix')
        vert.write('lightPos = LWVP * spos;')
        frag.add_include('std/shadows.glsl')
        frag.add_uniform('sampler2DShadow shadowMap')
        frag.add_uniform('float shadowsBias', '_sunShadowsBias')
        frag.add_uniform('bool receiveShadow')
        frag.write('if (receiveShadow && lightPos.w > 0.0) {')
        frag.write('vec3 lPos = lightPos.xyz / lightPos.w;')
        frag.write('const vec2 smSize = shadowmapSize;')
        frag.write(
            'visibility *= PCF(shadowMap, lPos.xy, lPos.z - shadowsBias, smSize);'
        )
        frag.write('}')

    frag.write('vec3 basecol;')
    frag.write('float roughness;')
    frag.write('float metallic;')
    frag.write('float occlusion;')
    frag.write('float specular;')
    frag.write('float emission;')
    is_displacement = mat_utils.disp_linked(mat_state.output_node)
    arm_discard = mat_state.material.arm_discard
    if arm_discard:
        frag.write('float opacity;')
    cycles.parse(mat_state.nodes,
                 con_mesh,
                 vert,
                 frag,
                 geom,
                 tesc,
                 tese,
                 parse_opacity=arm_discard,
                 parse_displacement=is_displacement)

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

    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(
        f'vec3 shade = basecol * {cycles.to_vec3(mat.arm_celshade_shade_color)};'
    )

    s = mat.arm_celshade_shade_softness
    if s == 0.0:
        frag.write(
            'vec3 direct = mix(shade, basecol, step(0.5, dotNL)) * visibility * sunCol;'
        )
    else:
        frag.write(
            f'vec3 direct = mix(shade, basecol, smoothstep({0.5 - s}, {0.5 + s}, dotNL)) * visibility * sunCol;'
        )

    frag.write('vec3 indirect = basecol * envmapStrength;')
    frag.write('fragColor = vec4(direct + indirect, 1.0);')

    if '_LDR' in wrd.world_defs:
        frag.write('fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / 2.2));')

    if is_displacement:
        vert.add_uniform('mat4 W', link='_worldMatrix')
        vert.add_uniform('mat4 VP', link='_viewProjectionMatrix')
        vert.write('vec4 wpos = W * spos;')
        vert.write('wpos.xyz += wnormal * disp * 0.1;')
        vert.write('gl_Position = VP * wpos;')
    else:
        make_attrib.write_vertpos(vert)

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

    make_finalize.make(con_mesh)

    return con_mesh
Example #3
0
def make(context_id):
    con_decal = mat_state.data.add_context({ 'name': context_id, 'depth_write': False, 'compare_mode': 'less', 'cull_mode': 'clockwise',
        'blend_source': 'source_alpha',
        'blend_destination': 'inverse_source_alpha',
        'blend_operation': 'add',
        'color_write_alpha': False
    })

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

    vert.add_uniform('mat4 WVP', '_worldViewProjectionMatrix')
    vert.add_uniform('mat3 N', '_normalMatrix')
    vert.add_out('vec4 wvpposition')
    vert.add_out('vec3 wnormal')

    vert.write('wnormal = N * vec3(0.0, 0.0, 1.0);')
    vert.write('wvpposition = WVP * vec4(pos, 1.0);')
    vert.write('gl_Position = wvpposition;')
    
    frag.add_include('../../Shaders/compiled.glsl')
    frag.add_include('../../Shaders/std/gbuffer.glsl')
    frag.ins = vert.outs
    frag.add_uniform('sampler2D gbufferD')
    frag.add_uniform('mat4 invVP', '_inverseViewProjectionMatrix')
    frag.add_uniform('mat4 invW', '_inverseWorldMatrix')
    frag.add_uniform('vec3 eye', '_cameraPosition')
    frag.add_out('vec4[2] fragColor')

    frag.write_main_header('    vec3 n = normalize(wnormal);')

    frag.write_main_header('    vec2 screenPosition = wvpposition.xy / wvpposition.w;')
    frag.write_main_header('    vec2 depthCoord = screenPosition * 0.5 + 0.5;')
    frag.write_main_header('    float depth = texture(gbufferD, depthCoord).r * 2.0 - 1.0;')
    
    frag.write_main_header('    vec3 wpos = getPos2(invVP, depth, depthCoord);')
    frag.write_main_header('    vec4 mpos = invW * vec4(wpos, 1.0);')
    frag.write_main_header('    if (abs(mpos.x) > 1.0) discard;')
    frag.write_main_header('    if (abs(mpos.y) > 1.0) discard;')
    frag.write_main_header('    if (abs(mpos.z) > 1.0) discard;')
    
    frag.write_main_header('    vec3 vVec = normalize(eye - wpos);')
    frag.write_main_header('    vec2 texCoord = mpos.xy * 0.5 + 0.5;')

    frag.write('vec3 basecol;')
    frag.write('float roughness;')
    frag.write('float metallic;')
    frag.write('float occlusion;')
    cycles.parse(mat_state.nodes, con_decal, vert, frag, geom, tesc, tese, parse_opacity=False)

    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 cycles.basecol_texname == '':
        frag.write('const float alpha = 1.0;')
    else:
        frag.write('const float alpha = {0}.a;'.format(cycles.basecol_texname))

    frag.write('fragColor[0] = vec4(n.xy, packFloat(metallic, roughness), alpha);')
    frag.write('fragColor[1] = vec4(basecol.rgb, alpha);')

    return con_decal
Example #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

    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);')
Example #5
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, 1.0);')
    frag.ins = vert.outs
    vert.add_uniform('mat4 WVP', '_worldViewProjectionMatrix')
    vert.add_uniform('mat4 W', '_worldMatrix')
    vert.add_out('vec3 wposition')
    vert.write_attrib('wposition = vec4(W * spos).xyz;')
    vert.write('gl_Position = WVP * spos;')

    frag.add_include('compiled.glsl')
    frag.write('vec3 basecol;')
    frag.write('float roughness;')
    frag.write('float metallic;')
    frag.write('float occlusion;')
    cycles.parse(mat_state.nodes,
                 con_mesh,
                 vert,
                 frag,
                 geom,
                 tesc,
                 tese,
                 parse_opacity=False,
                 parse_displacement=False)

    if con_mesh.is_elem('tex'):
        vert.add_out('vec2 texCoord')
        vert.write_attrib('texCoord = tex;')

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

    vert.add_out('vec3 wnormal')
    write_norpos(con_mesh, vert)
    frag.write_attrib('vec3 n = normalize(wnormal);')

    frag.add_include('std/math.glsl')
    frag.add_include('std/brdf.glsl')
    frag.add_uniform('vec3 lightColor', '_lampColor')
    frag.add_uniform('vec3 lightDir', '_lampDirection')
    frag.add_uniform('vec3 lightPos', '_lampPosition')
    frag.add_uniform('float envmapStrength', link='_envmapStrength')

    is_shadows = not '_NoShadows' in wrd.world_defs

    frag.write('float visibility = 1.0;')
    frag.write('float dotNL = max(dot(n, lightDir), 0.0);')

    if is_shadows:
        vert.add_out('vec4 lampPos')
        vert.add_uniform('mat4 LWVP', '_biasLampWorldViewProjectionMatrix')
        vert.write('lampPos = LWVP * spos;')
        frag.add_include('std/shadows.glsl')
        frag.add_uniform('sampler2D shadowMap')
        frag.add_uniform('float shadowsBias', '_lampShadowsBias')
        frag.write('    if (lampPos.w > 0.0) {')
        frag.write('    vec3 lPos = lampPos.xyz / lampPos.w;')
        frag.write('    const float texelSize = 1.0 / shadowmapSize.x;')
        frag.write('    visibility = 0.0;')
        # TODO: CSM
        frag.write(
            '    visibility += float(texture(shadowMap, lPos.xy).r + shadowsBias > lPos.z);'
        )
        frag.write(
            '    visibility += float(texture(shadowMap, lPos.xy + vec2(texelSize, 0.0)).r + shadowsBias > lPos.z) * 0.5;'
        )
        frag.write(
            '    visibility += float(texture(shadowMap, lPos.xy + vec2(-texelSize, 0.0)).r + shadowsBias > lPos.z) * 0.25;'
        )
        frag.write(
            '    visibility += float(texture(shadowMap, lPos.xy + vec2(0.0, texelSize)).r + shadowsBias > lPos.z) * 0.5;'
        )
        frag.write(
            '    visibility += float(texture(shadowMap, lPos.xy + vec2(0.0, -texelSize)).r + shadowsBias > lPos.z) * 0.25;'
        )
        frag.write('    visibility /= 2.5;')
        frag.write('    visibility = max(visibility, 0.2);')
        # frag.write('    visibility = max(float(texture(shadowMap, lPos.xy).r + shadowsBias > lPos.z), 0.5);')
        frag.write('    }')

    frag.add_out('vec4 fragColor')
    blend = mat_state.material.arm_blending
    if blend:
        # frag.write('fragColor = vec4(basecol * visibility, 1.0);')
        frag.write('fragColor = vec4(basecol, 1.0);')
        return

    frag.write('vec3 direct = basecol * dotNL * lightColor;')
    # frag.write('direct += vec3(D_Approx(max(roughness, 0.3), dot(reflect(-vVec, n), lightDir)));')
    frag.write('direct *= attenuate(distance(wposition, lightPos));')

    if '_Irr' in wrd.world_defs:
        frag.add_include('std/shirr.glsl')
        frag.add_uniform('vec4 shirr[7]',
                         link='_envmapIrradiance',
                         included=True)
        env_str = 'shIrradiance(n)'
    else:
        env_str = '0.5'
    frag.write(
        'fragColor = vec4(direct * visibility + 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));')
Example #6
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

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

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

    make_mesh.make_finalize(con_depth)

    return con_depth
Example #7
0
def make_gi(context_id):
    con_voxel = mat_state.data.add_context({
        'name': context_id,
        'depth_write': False,
        'compare_mode': 'always',
        'cull_mode': 'none',
        'color_write_red': False,
        'color_write_green': False,
        'color_write_blue': False,
        'color_write_alpha': False,
        'conservative_raster': True
    })
    wrd = bpy.data.worlds['Arm']

    is_shadows = not '_NoShadows' in wrd.world_defs

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

    geom.ins = vert.outs
    frag.ins = geom.outs

    frag.add_include('../../Shaders/compiled.glsl')
    frag.add_include('../../Shaders/std/math.glsl')
    frag.add_include('../../Shaders/std/imageatomic.glsl')
    frag.write_header('#extension GL_ARB_shader_image_load_store : enable')

    rpdat = arm.utils.get_rp()
    if rpdat.rp_voxelgi_hdr:
        frag.add_uniform('layout(rgba16) image3D voxels')
    else:
        # frag.add_uniform('layout(rgba8) image3D voxels')
        frag.add_uniform('layout(r32ui) uimage3D voxels')

    frag.add_uniform('vec3 lightPos', '_lampPosition')
    frag.add_uniform('vec3 lightColor', '_lampColorVoxel')
    frag.add_uniform('int lightType', '_lampType')
    frag.add_uniform('vec3 lightDir', '_lampDirection')

    frag.write('if (abs(voxposition.z) > ' + rpdat.rp_voxelgi_resolution_z +
               ' || abs(voxposition.x) > 1 || abs(voxposition.y) > 1) return;')
    frag.write('vec3 wposition = voxposition * voxelgiHalfExtents;')
    if rpdat.arm_voxelgi_revoxelize and rpdat.arm_voxelgi_camera:
        frag.add_uniform('vec3 eyeSnap', '_cameraPositionSnap')
        frag.write('wposition += eyeSnap;')

    frag.write('float visibility = 1.0;')
    frag.write('vec3 lp = lightPos - wposition;')
    frag.write('vec3 l;')
    frag.write('if (lightType == 0) l = lightDir;')
    frag.write(
        'else { l = normalize(lp); visibility *= attenuate(distance(wposition, lightPos)); }'
    )

    frag.write('float dotNL = max(dot(wnormal, l), 0.0);')
    frag.write('if (dotNL == 0.0) return;')

    if is_shadows:
        frag.add_include('../../Shaders/std/shadows.glsl')
        frag.add_uniform('sampler2D shadowMap', included=True)
        frag.add_uniform('samplerCube shadowMapCube', included=True)
        frag.add_uniform('int lightShadow', '_lampCastShadow')
        frag.add_uniform('vec2 lightProj', '_lampPlaneProj')
        frag.add_uniform('float shadowsBias', '_lampShadowsBias')
        frag.write('if (lightShadow == 1 && lampPos.w > 0.0) {')
        frag.write('    vec3 lpos = lampPos.xyz / lampPos.w;')
        # frag.write('    if (lpos.x < 0.0 || lpos.y < 0.0 || lpos.x > 1.0 || lpos.y > 1.0) return;')
        # Note: shadowmap bound for sun lamp is tight behind the camera - can cause darkening no close surfaces
        frag.write(
            '    if (texture(shadowMap, lpos.xy).r < lpos.z - shadowsBias) visibility = 0.0;'
        )
        # frag.write('    visibility = PCF(lpos.xy, lpos.z - shadowsBias);')
        frag.write('}')
        frag.write(
            'else if (lightShadow == 2) visibility *= float(texture(shadowMapCube, -l).r + shadowsBias > lpToDepth(lp, lightProj));'
        )

    # frag.write('if (lightType == 2) {')
    # frag.write('    float spotEffect = dot(lightDir, l);')
    # frag.write('    if (spotEffect < spotlightData.x) {')
    # frag.write('        visibility *= smoothstep(spotlightData.y, spotlightData.x, spotEffect);')
    # frag.write('    }')
    # frag.write('}')

    # if '_PolyLight' in wrd.world_defs:
    #     frag.add_include('../../Shaders/std/ltc.glsl')
    #     frag.add_uniform('sampler2D sltcMat', link='_ltcMat')
    #     frag.add_uniform('sampler2D sltcMag', link='_ltcMag')
    #     frag.add_uniform('vec3 lampArea0', link='_lampArea0')
    #     frag.add_uniform('vec3 lampArea1', link='_lampArea1')
    #     frag.add_uniform('vec3 lampArea2', link='_lampArea2')
    #     frag.add_uniform('vec3 lampArea3', link='_lampArea3')
    #     frag.write('if (lightType == 3) {')
    #     frag.write('    float theta = acos(dotNV);')
    #     frag.write('    vec2 tuv = vec2(roughness, theta / (0.5 * PI));')
    #     frag.write('    tuv = tuv * LUT_SCALE + LUT_BIAS;')
    #     frag.write('    vec4 t = texture(sltcMat, tuv);')
    #     frag.write('    mat3 invM = mat3(vec3(1.0, 0.0, t.y), vec3(0.0, t.z, 0.0), vec3(t.w, 0.0, t.x));')
    #     frag.write('    float ltcspec = ltcEvaluate(n, vVec, dotNV, wposition, invM, lampArea0, lampArea1, lampArea2, lampArea3);')
    #     frag.write('    ltcspec *= texture(sltcMag, tuv).a;')
    #     frag.write('    float ltcdiff = ltcEvaluate(n, vVec, dotNV, wposition, mat3(1.0), lampArea0, lampArea1, lampArea2, lampArea3);')
    #     frag.write('    direct = albedo * ltcdiff + ltcspec;')
    #     frag.write('}')
    #     frag.write('else {')
    #     frag.tab += 1

    frag.write('vec3 basecol;')
    frag.write('float roughness;')  #
    frag.write('float metallic;')  #
    frag.write('float occlusion;')  #
    parse_opacity = rpdat.arm_voxelgi_refraction
    if parse_opacity:
        frag.write('float opacity;')
    frag.write('float dotNV = 0.0;')
    cycles.parse(mat_state.nodes,
                 con_voxel,
                 vert,
                 frag,
                 geom,
                 tesc,
                 tese,
                 parse_opacity=parse_opacity,
                 parse_displacement=False,
                 basecol_only=True)

    # Voxelized particles
    particle = mat_state.material.arm_particle
    if particle == 'gpu':
        # make_particle.write(vert, particle_info=cycles.particle_info)
        frag.write_pre = True
        frag.write('const float p_index = 0;')
        frag.write('const float p_age = 0;')
        frag.write('const float p_lifetime = 0;')
        frag.write('const vec3 p_location = vec3(0);')
        frag.write('const float p_size = 0;')
        frag.write('const vec3 p_velocity = vec3(0);')
        frag.write('const vec3 p_angular_velocity = vec3(0);')
        frag.write_pre = False

    if not frag.contains('vec3 n ='):
        frag.write_pre = True
        frag.write('vec3 n;')
        frag.write_pre = False

    export_mpos = frag.contains(
        'mposition') and not frag.contains('vec3 mposition')
    if export_mpos:
        vert.add_out('vec3 mpositionGeom')
        vert.write_pre = True
        vert.write('mpositionGeom = pos;')
        vert.write_pre = False

    vert.add_uniform('mat4 W', '_worldMatrix')
    vert.add_uniform('mat3 N', '_normalMatrix')

    vert.add_out('vec3 voxpositionGeom')
    vert.add_out('vec3 wnormalGeom')

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

    if con_voxel.is_elem('col'):
        vert.add_out('vec3 vcolorGeom')
        vert.write('vcolorGeom = col;')

    if con_voxel.is_elem('tex'):
        vert.add_out('vec2 texCoordGeom')
        vert.write('texCoordGeom = tex;')

    if rpdat.arm_voxelgi_revoxelize and rpdat.arm_voxelgi_camera:
        vert.add_uniform('vec3 eyeSnap', '_cameraPositionSnap')
        vert.write(
            'voxpositionGeom = (vec3(W * vec4(pos, 1.0)) - eyeSnap) / voxelgiHalfExtents;'
        )
    else:
        vert.write(
            'voxpositionGeom = vec3(W * vec4(pos, 1.0)) / voxelgiHalfExtents;')
    vert.write('wnormalGeom = normalize(N * nor);')
    # vert.write('gl_Position = vec4(0.0, 0.0, 0.0, 1.0);')

    if is_shadows:
        vert.add_out('vec4 lampPosGeom')
        if '_CSM' in wrd.world_defs:
            vert.add_include('../../Shaders/compiled.glsl')
            vert.add_include('../../Shaders/std/shadows.glsl')
            vert.add_uniform('vec4 casData[shadowmapCascades * 4 + 4]',
                             '_cascadeData',
                             included=True)
            # TODO: Using second cascade
            vert.write(
                'mat4 LWVP = mat4(casData[4 + 0], casData[4 + 1], casData[4 + 2], casData[4 + 3]);'
            )
        else:
            vert.add_uniform('mat4 LWVP', '_biasLampWorldViewProjectionMatrix')
        vert.write('lampPosGeom = LWVP * vec4(pos, 1.0);')

    geom.add_out('vec3 voxposition')
    geom.add_out('vec3 wnormal')
    if is_shadows:
        geom.add_out('vec4 lampPos')
    if con_voxel.is_elem('col'):
        geom.add_out('vec3 vcolor')
    if con_voxel.is_elem('tex'):
        geom.add_out('vec2 texCoord')
    if export_mpos:
        geom.add_out('vec3 mposition')

    geom.write('const vec3 p1 = voxpositionGeom[1] - voxpositionGeom[0];')
    geom.write('const vec3 p2 = voxpositionGeom[2] - voxpositionGeom[0];')
    geom.write('const vec3 p = abs(cross(p1, p2));')
    geom.write('for (uint i = 0; i < 3; ++i) {')
    geom.write('    voxposition = voxpositionGeom[i];')
    geom.write('    wnormal = wnormalGeom[i];')
    if is_shadows:
        geom.write('    lampPos = lampPosGeom[i];')
    if con_voxel.is_elem('col'):
        geom.write('    vcolor = vcolorGeom[i];')
    if con_voxel.is_elem('tex'):
        geom.write('    texCoord = texCoordGeom[i];')
    if export_mpos:
        geom.write('    mposition = mpositionGeom[i];')
    geom.write('    if (p.z > p.x && p.z > p.y) {')
    geom.write(
        '        gl_Position = vec4(voxposition.x, voxposition.y, 0.0, 1.0);')
    geom.write('    }')
    geom.write('    else if (p.x > p.y && p.x > p.z) {')
    geom.write(
        '        gl_Position = vec4(voxposition.y, voxposition.z, 0.0, 1.0);')
    geom.write('    }')
    geom.write('    else {')
    geom.write(
        '        gl_Position = vec4(voxposition.x, voxposition.z, 0.0, 1.0);')
    geom.write('    }')
    geom.write('    EmitVertex();')
    geom.write('}')
    geom.write('EndPrimitive();')

    if cycles.emission_found:
        frag.write('vec3 color = basecol;')
    else:
        frag.write('vec3 color = basecol * visibility * lightColor * dotNL;')
    frag.write('vec3 voxel = voxposition * 0.5 + 0.5;')

    if rpdat.arm_voxelgi_emission:
        frag.write(
            'color = min(color * 0.9, vec3(0.9)) + min(color / 200.0, 0.1);'
        )  # Higher range to allow emission

    frag.write('color = clamp(color, vec3(0.0), vec3(1.0));')

    if rpdat.rp_voxelgi_hdr:
        frag.write(
            'imageStore(voxels, ivec3(voxelgiResolution * voxel), vec4(color, 1.0));'
        )
    else:
        frag.write('uint val = convVec4ToRGBA8(vec4(color, 1.0) * 255);')
        frag.write(
            'imageAtomicMax(voxels, ivec3(voxelgiResolution * voxel), val);')

        # frag.write('imageStore(voxels, ivec3(voxelgiResolution * voxel), vec4(color, 1.0));')
        # frag.write('imageAtomicRGBA8Avg(voxels, ivec3(voxelgiResolution * voxel), vec4(color, 1.0));')

        # frag.write('ivec3 coords = ivec3(voxelgiResolution * voxel);')
        # if parse_opacity:
        #     frag.write('vec4 val = vec4(color, opacity);')
        # else:
        #     frag.write('vec4 val = vec4(color, 1.0);')
        # frag.write('val *= 255.0;')
        # frag.write('uint newVal = encUnsignedNibble(convVec4ToRGBA8(val), 1);')
        # frag.write('uint prevStoredVal = 0;')
        # frag.write('uint currStoredVal;')
        # # frag.write('int counter = 0;')
        # # frag.write('while ((currStoredVal = imageAtomicCompSwap(voxels, coords, prevStoredVal, newVal)) != prevStoredVal && counter < 16) {')
        # frag.write('while ((currStoredVal = imageAtomicCompSwap(voxels, coords, prevStoredVal, newVal)) != prevStoredVal) {')
        # frag.write('    vec4 rval = convRGBA8ToVec4(currStoredVal & 0xFEFEFEFE);')
        # frag.write('    uint n = decUnsignedNibble(currStoredVal);')
        # frag.write('    rval = rval * n + val;')
        # frag.write('    rval /= ++n;')
        # frag.write('    rval = round(rval / 2) * 2;')
        # frag.write('    newVal = encUnsignedNibble(convVec4ToRGBA8(rval), n);')
        # frag.write('    prevStoredVal = currStoredVal;')
        # # frag.write('    counter++;')
        # frag.write('}')

        # frag.write('val.rgb *= 255.0f;')
        # frag.write('uint newVal = convVec4ToRGBA8(val);')
        # frag.write('uint prevStoredVal = 0;')
        # frag.write('uint curStoredVal;')
        # frag.write('while ((curStoredVal = imageAtomicCompSwap(voxels, coords, prevStoredVal, newVal)) != prevStoredVal) {')
        # frag.write('    prevStoredVal = curStoredVal;')
        # frag.write('    vec4 rval = convRGBA8ToVec4(curStoredVal);')
        # frag.write('    rval.xyz = (rval.xyz * rval.w);')
        # frag.write('    vec4 curValF = rval + val;')
        # frag.write('    curValF.xyz /= (curValF.w);')
        # frag.write('    newVal = convVec4ToRGBA8(curValF);')
        # frag.write('}')

    return con_voxel
Example #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
    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);')
Example #9
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, 1.0);')
    frag.ins = vert.outs

    frag.add_include('compiled.glsl')
    frag.add_uniform('vec3 lightDir', '_lampDirection')
    frag.add_uniform('vec3 lightColor', '_lampColor')
    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 = not '_NoShadows' in wrd.world_defs

    if is_shadows:
        vert.add_out('vec4 lampPos')
        vert.add_uniform('mat4 LWVP', '_biasLampWorldViewProjectionMatrix')
        vert.write('lampPos = LWVP * spos;')
        frag.add_include('std/shadows.glsl')
        frag.add_uniform('sampler2D shadowMap')
        frag.add_uniform('float shadowsBias', '_lampShadowsBias')
        frag.add_uniform('bool receiveShadow')
        frag.write('    if (receiveShadow && lampPos.w > 0.0) {')
        frag.write('    vec3 lPos = lampPos.xyz / lampPos.w;')

        frag.write('    const vec2 smSize = shadowmapSize;')
        frag.write(
            '    visibility *= PCF(shadowMap, lPos.xy, lPos.z - shadowsBias, smSize);'
        )

        # frag.write('    const float texelSize = 1.0 / shadowmapSize.x;')
        # frag.write('    visibility = 0.0;')
        # frag.write('    visibility += float(texture(shadowMap, lPos.xy).r + shadowsBias > lPos.z);')
        # frag.write('    visibility += float(texture(shadowMap, lPos.xy + vec2(texelSize, 0.0)).r + shadowsBias > lPos.z) * 0.5;')
        # frag.write('    visibility += float(texture(shadowMap, lPos.xy + vec2(-texelSize, 0.0)).r + shadowsBias > lPos.z) * 0.25;')
        # frag.write('    visibility += float(texture(shadowMap, lPos.xy + vec2(0.0, texelSize)).r + shadowsBias > lPos.z) * 0.5;')
        # frag.write('    visibility += float(texture(shadowMap, lPos.xy + vec2(0.0, -texelSize)).r + shadowsBias > lPos.z) * 0.25;')
        # frag.write('    visibility /= 2.5;')
        frag.write('    }')

    frag.write('vec3 basecol;')
    frag.write('float roughness;')
    frag.write('float metallic;')
    frag.write('float occlusion;')
    frag.write('float specular;')
    arm_discard = mat_state.material.arm_discard
    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=False)

    make_mesh.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.write('texCoord = tex;')

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

    if con_mesh.is_elem('tang'):
        vert.add_out('mat3 TBN')
        make_mesh.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')
        make_mesh.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_mesh.make_finalize(con_mesh)

    return con_mesh
Example #10
0
def make_gi(context_id):
    con_voxel = mat_state.data.add_context({ 'name': context_id, 'depth_write': False, 'compare_mode': 'always', 'cull_mode': 'none', 'color_write_red': False, 'color_write_green': False, 'color_write_blue': False, 'color_write_alpha': False, 'conservative_raster': True })
    wrd = bpy.data.worlds['Arm']

    if '_NoShadows' in wrd.world_defs:
        is_shadows = False
    else:
        is_shadows = True

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

    geom.ins = vert.outs
    frag.ins = geom.outs


    frag.write('vec3 lp = lightPos - wposition * voxelgiDimensions;')
    frag.write('vec3 l = normalize(lp);')
    frag.write('float visibility = 1.0;')
    frag.add_include('../../Shaders/compiled.glsl')
    if is_shadows:
        frag.add_include('../../Shaders/std/shadows.glsl')
        frag.add_uniform('sampler2D shadowMap', included=True)
        frag.add_uniform('samplerCube shadowMapCube', included=True)
        frag.add_uniform('int lightShadow', '_lampCastShadow')
        frag.add_uniform('vec2 lightPlane', '_lampPlane')
        frag.add_uniform('float shadowsBias', '_lampShadowsBias')
        frag.write('if (lightShadow == 1 && lampPos.w > 0.0) {')
        frag.write('    vec3 lpos = lampPos.xyz / lampPos.w;')
        frag.write('    if (texture(shadowMap, lpos.xy).r < lpos.z - shadowsBias) visibility = 0.0;')
        frag.write('}')
        frag.write('else if (lightShadow == 2) visibility = float(texture(shadowMapCube, -l).r + shadowsBias > lpToDepth(lp, lightPlane));')
    else:
        frag.write('int lightShadow = 0;')

    frag.add_include('../../Shaders/std/math.glsl')
    frag.add_include('../../Shaders/std/imageatomic.glsl')
    frag.write_header('#extension GL_ARB_shader_image_load_store : enable')

    rpdat = arm.utils.get_rp()
    # if rpdat.rp_voxelgi_hdr:
        # frag.add_uniform('layout(RGBA16) image3D voxels')
    # else:
    # frag.add_uniform('layout(RGBA8) image3D voxels')
    frag.add_uniform('layout(r32ui) uimage3D voxels')

    frag.add_uniform('vec3 lightPos', '_lampPosition')
    frag.add_uniform('vec3 lightColor', '_lampColorVoxel')

    frag.write('if (!isInsideCube(wposition)) return;')

    frag.write('vec3 basecol;')
    frag.write('float roughness;') #
    frag.write('float metallic;') #
    frag.write('float occlusion;') #
    parse_opacity = rpdat.arm_voxelgi_refraction
    if parse_opacity:
        frag.write('float opacity;')
    frag.write_pre = True
    frag.write('mat3 TBN;') # TODO: discard, parse basecolor only
    frag.write_pre = False
    frag.write('float dotNV = 0.0;')
    frag.write('float dotNL = max(dot(wnormal, l), 0.0);')
    cycles.parse(mat_state.nodes, con_voxel, vert, frag, geom, tesc, tese, parse_opacity=parse_opacity, parse_displacement=False)

    if not frag.contains('vec3 n ='):
        frag.write_pre = True
        frag.write('vec3 n;')
        frag.write_pre = False

    if rpdat.arm_voxelgi_camera:
        vert.add_uniform('vec3 eye', '_cameraPosition')
    vert.add_uniform('mat4 W', '_worldMatrix')
    vert.add_uniform('mat3 N', '_normalMatrix')

    vert.add_out('vec3 wpositionGeom')
    vert.add_out('vec3 wnormalGeom')

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

    if con_voxel.is_elem('tex'):
        vert.add_out('vec2 texCoordGeom')
        vert.write('texCoordGeom = tex;')

    if rpdat.arm_voxelgi_camera:
        vert.write('const float step = voxelgiDimensions / voxelgiResolution;') # TODO: Pass as uniform
        vert.write('vec3 eyeSnap = ivec3(eye / step) * step;') # TODO: Pass as uniform
        vert.write('wpositionGeom = (vec3(W * vec4(pos, 1.0)) - eyeSnap) / voxelgiDimensions;')
    else: 
        vert.write('wpositionGeom = vec3(W * vec4(pos, 1.0)) / voxelgiDimensions;')
    vert.write('wnormalGeom = normalize(N * nor);')
    vert.write('gl_Position = vec4(0.0, 0.0, 0.0, 1.0);')

    if is_shadows:
        vert.add_out('vec4 lampPosGeom')
        vert.add_uniform('mat4 LWVP', '_biasLampWorldViewProjectionMatrix')
        vert.write('lampPosGeom = LWVP * vec4(pos, 1.0);')

    geom.add_out('vec3 wposition')
    geom.add_out('vec3 wnormal')
    if is_shadows:
        geom.add_out('vec4 lampPos')
    if con_voxel.is_elem('tex'):
        geom.add_out('vec2 texCoord')

    geom.write('const vec3 p1 = wpositionGeom[1] - wpositionGeom[0];')
    geom.write('const vec3 p2 = wpositionGeom[2] - wpositionGeom[0];')
    geom.write('const vec3 p = abs(cross(p1, p2));')
    geom.write('for (uint i = 0; i < 3; ++i) {')
    geom.write('    wposition = wpositionGeom[i];')
    geom.write('    wnormal = wnormalGeom[i];')
    if is_shadows:
        geom.write('    lampPos = lampPosGeom[i];')
    if con_voxel.is_elem('tex'):
        geom.write('    texCoord = texCoordGeom[i];')
    geom.write('    if (p.z > p.x && p.z > p.y) {')
    geom.write('        gl_Position = vec4(wposition.x, wposition.y, 0.0, 1.0);')
    geom.write('    }')
    geom.write('    else if (p.x > p.y && p.x > p.z) {')
    geom.write('        gl_Position = vec4(wposition.y, wposition.z, 0.0, 1.0);')
    geom.write('    }')
    geom.write('    else {')
    geom.write('        gl_Position = vec4(wposition.x, wposition.z, 0.0, 1.0);')
    geom.write('    }')
    geom.write('    EmitVertex();')
    geom.write('}')
    geom.write('EndPrimitive();')

    if cycles.emission_found:
        frag.write('vec3 color = basecol;')
    else:
        frag.write('vec3 color = basecol * visibility * lightColor * dotNL * attenuate(distance(wposition * voxelgiDimensions, lightPos));')
    frag.write('vec3 voxel = wposition * 0.5 + vec3(0.5);')

    if rpdat.arm_material_model == 'Cycles':
        frag.write('color = min(color * 0.9, vec3(0.9)) + min(color / 200.0, 0.1);') # Higher range to allow emission

    # if rpdat.rp_voxelgi_hdr:
        # frag.write('imageStore(voxels, ivec3(voxelgiResolution * voxel), vec4(color, 1.0));')
    # else:
    frag.write('color = clamp(color, vec3(0.0), vec3(1.0));')
    
    # frag.write('uint val = convVec4ToRGBA8(vec4(color, 1.0) * 255);')
    # frag.write('imageAtomicMax(voxels, ivec3(voxelgiResolution * voxel), val);')
    
    # frag.write('imageStore(voxels, ivec3(voxelgiResolution * voxel), vec4(color, 1.0));')
    # frag.write('imageAtomicRGBA8Avg(voxels, ivec3(voxelgiResolution * voxel), vec4(color, 1.0));')
        
    frag.write('ivec3 coords = ivec3(voxelgiResolution * voxel);')
    if parse_opacity:
        frag.write('vec4 val = vec4(color, opacity);')
    else:
        frag.write('vec4 val = vec4(color, 1.0);')
    frag.write('val *= 255.0;')
    frag.write('uint newVal = encUnsignedNibble(convVec4ToRGBA8(val), 1);')
    frag.write('uint prevStoredVal = 0;')
    frag.write('uint currStoredVal;')
    # frag.write('int counter = 0;')
    # frag.write('while ((currStoredVal = imageAtomicCompSwap(voxels, coords, prevStoredVal, newVal)) != prevStoredVal && counter < 16) {')
    frag.write('while ((currStoredVal = imageAtomicCompSwap(voxels, coords, prevStoredVal, newVal)) != prevStoredVal) {')
    frag.write('    vec4 rval = convRGBA8ToVec4(currStoredVal & 0xFEFEFEFE);')
    frag.write('    uint n = decUnsignedNibble(currStoredVal);')
    frag.write('    rval = rval * n + val;')
    frag.write('    rval /= ++n;')
    frag.write('    rval = round(rval / 2) * 2;')
    frag.write('    newVal = encUnsignedNibble(convVec4ToRGBA8(rval), n);')
    frag.write('    prevStoredVal = currStoredVal;')
    # frag.write('    counter++;')
    frag.write('}')

    # frag.write('val.rgb *= 255.0f;')
    # frag.write('uint newVal = convVec4ToRGBA8(val);')
    # frag.write('uint prevStoredVal = 0;')
    # frag.write('uint curStoredVal;')
    # frag.write('while ((curStoredVal = imageAtomicCompSwap(voxels, coords, prevStoredVal, newVal)) != prevStoredVal) {')
    # frag.write('    prevStoredVal = curStoredVal;')
    # frag.write('    vec4 rval = convRGBA8ToVec4(curStoredVal);')
    # frag.write('    rval.xyz = (rval.xyz * rval.w);')
    # frag.write('    vec4 curValF = rval + val;')
    # frag.write('    curValF.xyz /= (curValF.w);')
    # frag.write('    newVal = convVec4ToRGBA8(curValF);')
    # frag.write('}')

    return con_voxel
Example #11
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;')

        const = {}
        const['name'] = 'tessLevel'
        const['vec2'] = [
            mat_state.material.height_tess_inner,
            mat_state.material.height_tess_outer
        ]
        mat_state.bind_constants.append(const)
        tesc.add_uniform('vec2 tessLevel')
        make_tess.tesc_levels(tesc)
        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 = 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_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);')
Example #12
0
def make(context_id):
    con_voxel = mat_state.data.add_context({
        'name': context_id,
        'depth_write': False,
        'compare_mode': 'always',
        'cull_mode': 'none',
        'color_write_red': False,
        'color_write_green': False,
        'color_write_blue': False,
        'color_write_alpha': False,
        'conservative_raster': True
    })
    wrd = bpy.data.worlds['Arm']

    if '_NoShadows' in wrd.world_defs:
        is_shadows = False
    else:
        is_shadows = True

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

    geom.ins = vert.outs
    frag.ins = geom.outs

    frag.write('vec3 lp = lightPos - wposition * voxelgiDimensions.x;')
    frag.write('vec3 l = normalize(lp);')
    frag.write('float visibility = 1.0;')
    frag.add_include('../../Shaders/compiled.glsl')
    if is_shadows:
        frag.add_include('../../Shaders/std/shadows.glsl')
        frag.add_uniform('sampler2D shadowMap', included=True)
        frag.add_uniform('samplerCube shadowMapCube', included=True)
        frag.add_uniform('int lightShadow', '_lampCastShadow')
        frag.add_uniform('vec2 lightPlane', '_lampPlane')
        frag.add_uniform('float shadowsBias', '_lampShadowsBias')
        frag.write('if (lightShadow == 1 && lampPos.w > 0.0) {')
        frag.write('    vec3 lpos = lampPos.xyz / lampPos.w;')
        frag.write(
            '    if (texture(shadowMap, lpos.xy).r < lpos.z - shadowsBias) visibility = 0.0;'
        )
        frag.write('}')
        frag.write(
            'else if (lightShadow == 2) visibility = float(texture(shadowMapCube, -l).r + shadowsBias > lpToDepth(lp, lightPlane));'
        )
    else:
        frag.write('int lightShadow = 0;')

    frag.add_include('../../Shaders/std/math.glsl')
    frag.write_header('#extension GL_ARB_shader_image_load_store : enable')

    frag.add_uniform('layout(RGBA8) image3D voxels')
    frag.add_uniform('vec3 lightPos', '_lampPosition')
    frag.add_uniform('vec3 lightColor', '_lampColor')

    frag.write('if (!isInsideCube(wposition)) return;')

    frag.write('vec3 basecol;')
    frag.write('float roughness;')  #
    frag.write('float metallic;')  #
    frag.write('float occlusion;')  #
    # frag.write('float opacity;') #
    frag.write_pre = True
    frag.write('mat3 TBN;')  # TODO: discard, parse basecolor only
    frag.write_pre = False
    frag.write('float dotNV = 0.0;')
    frag.write('float dotNL = max(dot(wnormal, l), 0.0);')
    cycles.parse(mat_state.nodes,
                 con_voxel,
                 vert,
                 frag,
                 geom,
                 tesc,
                 tese,
                 parse_opacity=False,
                 parse_displacement=False)

    vert.add_uniform('mat4 W', '_worldMatrix')
    vert.add_uniform('mat3 N', '_normalMatrix')

    vert.add_out('vec3 wpositionGeom')
    vert.add_out('vec3 wnormalGeom')

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

    if con_voxel.is_elem('tex'):
        vert.add_out('vec2 texCoordGeom')
        vert.write('texCoordGeom = tex;')

    vert.write(
        'wpositionGeom = vec3(W * vec4(pos, 1.0)) / voxelgiDimensions.x;')
    vert.write('wnormalGeom = normalize(N * nor);')
    vert.write('gl_Position = vec4(0.0, 0.0, 0.0, 1.0);')

    if is_shadows:
        vert.add_out('vec4 lampPosGeom')
        vert.add_uniform('mat4 LWVP', '_biasLampWorldViewProjectionMatrix')
        vert.write('lampPosGeom = LWVP * vec4(pos, 1.0);')

    geom.add_out('vec3 wposition')
    geom.add_out('vec3 wnormal')
    if is_shadows:
        geom.add_out('vec4 lampPos')
    if con_voxel.is_elem('tex'):
        geom.add_out('vec2 texCoord')

    geom.write('const vec3 p1 = wpositionGeom[1] - wpositionGeom[0];')
    geom.write('const vec3 p2 = wpositionGeom[2] - wpositionGeom[0];')
    geom.write('const vec3 p = abs(cross(p1, p2));')
    geom.write('for (uint i = 0; i < 3; ++i) {')
    geom.write('    wposition = wpositionGeom[i];')
    geom.write('    wnormal = wnormalGeom[i];')
    if is_shadows:
        geom.write('    lampPos = lampPosGeom[i];')
    if con_voxel.is_elem('tex'):
        geom.write('    texCoord = texCoordGeom[i];')
    geom.write('    if (p.z > p.x && p.z > p.y) {')
    geom.write(
        '        gl_Position = vec4(wposition.x, wposition.y, 0.0, 1.0);')
    geom.write('    }')
    geom.write('    else if (p.x > p.y && p.x > p.z) {')
    geom.write(
        '        gl_Position = vec4(wposition.y, wposition.z, 0.0, 1.0);')
    geom.write('    }')
    geom.write('    else {')
    geom.write(
        '        gl_Position = vec4(wposition.x, wposition.z, 0.0, 1.0);')
    geom.write('    }')
    geom.write('    EmitVertex();')
    geom.write('}')
    geom.write('EndPrimitive();')

    frag.write('vec3 color;')
    frag.write(
        'if (lightShadow > 0) color = basecol * visibility * lightColor * dotNL * attenuate(distance(wposition * voxelgiDimensions.x, lightPos));'
    )
    frag.write('else color = (basecol - 1.0);'
               )  # Emission only when no lamp or shadowmap is present
    frag.write('vec3 voxel = wposition * 0.5 + vec3(0.5);')
    frag.write(
        'imageStore(voxels, ivec3(voxelgiResolution * voxel), vec4(color, 1.0));'
    )

    return con_voxel
Example #13
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, 1.0);')
    frag.ins = vert.outs

    write_vertpos(vert)

    frag.add_include('compiled.inc')
    frag.write('vec3 basecol;')
    frag.write('float roughness;')
    frag.write('float metallic;')
    frag.write('float occlusion;')
    frag.write('float specular;')

    arm_discard = mat_state.material.arm_discard
    blend = mat_state.material.arm_blending
    is_transluc = mat_utils.is_transluc(mat_state.material)
    parse_opacity = (blend and is_transluc) or arm_discard
    if parse_opacity:
        frag.write('float opacity;')

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

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

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

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

    if con_mesh.is_elem('tang'):
        vert.add_out('mat3 TBN')
        write_norpos(con_mesh, vert, declare=True)
        vert.write('vec3 tangent = normalize(N * tang);')
        vert.write('vec3 bitangent = normalize(cross(wnormal, tangent));')
        vert.write('TBN = mat3(tangent, bitangent, wnormal);')
    else:
        vert.add_out('vec3 wnormal')
        write_norpos(con_mesh, vert)
        frag.write_attrib('vec3 n = normalize(wnormal);')

    frag.add_include('std/math.glsl')
    frag.add_include('std/brdf.glsl')

    frag.add_out('vec4 fragColor')
    blend = mat_state.material.arm_blending
    if blend:
        if parse_opacity:
            frag.write('fragColor = vec4(basecol, opacity);')
        else:
            frag.write('fragColor = vec4(basecol, 1.0);')
        return

    is_shadows = '_ShadowMap' in wrd.world_defs
    frag.write('vec3 direct = vec3(0.0);')

    if '_Sun' in wrd.world_defs:
        frag.add_uniform('vec3 sunCol', '_sunColor')
        frag.add_uniform('vec3 sunDir', '_sunDirection')
        frag.write('float svisibility = 1.0;')
        frag.write('float sdotNL = max(dot(n, sunDir), 0.0);')
        if is_shadows:
            vert.add_out('vec4 lightPosition')
            vert.add_uniform('mat4 LWVP', '_biasLightWorldViewProjectionMatrix')
            vert.write('lightPosition = LWVP * spos;')            
            frag.add_uniform('sampler2D shadowMap')
            frag.add_uniform('float shadowsBias', '_sunShadowsBias')
            frag.write('if (lightPosition.w > 0.0) {')
            frag.write('    vec3 lPos = lightPosition.xyz / lightPosition.w;')
            frag.write('    const float texelSize = 1.0 / shadowmapSize.x;')
            frag.write('    svisibility = 0.0;')
            frag.write('    svisibility += float(texture(shadowMap, lPos.xy).r + shadowsBias > lPos.z);')
            frag.write('    svisibility += float(texture(shadowMap, lPos.xy + vec2(texelSize, 0.0)).r + shadowsBias > lPos.z) * 0.5;')
            frag.write('    svisibility += float(texture(shadowMap, lPos.xy + vec2(-texelSize, 0.0)).r + shadowsBias > lPos.z) * 0.25;')
            frag.write('    svisibility += float(texture(shadowMap, lPos.xy + vec2(0.0, texelSize)).r + shadowsBias > lPos.z) * 0.5;')
            frag.write('    svisibility += float(texture(shadowMap, lPos.xy + vec2(0.0, -texelSize)).r + shadowsBias > lPos.z) * 0.25;')
            frag.write('    svisibility /= 2.5;')
            frag.write('    svisibility = max(svisibility, 0.2);')
            # frag.write('    svisibility = max(float(texture(shadowMap, lPos.xy).r + shadowsBias > lPos.z), 0.5);')
            frag.write('}')
        frag.write('direct += basecol * sdotNL * sunCol * svisibility;')

    if '_SinglePoint' in wrd.world_defs:
        frag.add_uniform('vec3 pointPos', '_pointPosition')
        frag.add_uniform('vec3 pointCol', '_pointColor')
        frag.write('float visibility = 1.0;')
        frag.write('float dotNL = max(dot(n, pointPos - wposition), 0.0);')
        if is_shadows:
            vert.add_out('vec4 lightPosition')
            vert.add_uniform('mat4 LWVP', '_biasLightWorldViewProjectionMatrix')
            vert.write('lightPosition = LWVP * spos;')            
            frag.add_uniform('sampler2D shadowMap0')
            frag.add_uniform('float shadowsBias', '_lightShadowsBias')
            frag.write('if (lightPosition.w > 0.0) {')
            frag.write('    vec3 lPos = lightPosition.xyz / lightPosition.w;')
            frag.write('    const float texelSize = 1.0 / shadowmapSize.x;')
            frag.write('    visibility = 0.0;')
            frag.write('    visibility += float(texture(shadowMap0, lPos.xy).r + shadowsBias > lPos.z);')
            frag.write('    visibility += float(texture(shadowMap0, lPos.xy + vec2(texelSize, 0.0)).r + shadowsBias > lPos.z) * 0.5;')
            frag.write('    visibility += float(texture(shadowMap0, lPos.xy + vec2(-texelSize, 0.0)).r + shadowsBias > lPos.z) * 0.25;')
            frag.write('    visibility += float(texture(shadowMap0, lPos.xy + vec2(0.0, texelSize)).r + shadowsBias > lPos.z) * 0.5;')
            frag.write('    visibility += float(texture(shadowMap0, lPos.xy + vec2(0.0, -texelSize)).r + shadowsBias > lPos.z) * 0.25;')
            frag.write('    visibility /= 2.5;')
            frag.write('    visibility = max(visibility, 0.2);')
            frag.write('}')
        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', included=True)
        env_str = 'shIrradiance(n)'
    else:
        env_str = '0.5'

    frag.add_uniform('float envmapStrength', link='_envmapStrength')
    frag.write('fragColor = vec4(direct + basecol * {0} * envmapStrength, 1.0);'.format(env_str))

    if '_LDR' in wrd.world_defs:
        frag.write('fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / 2.2));')
Example #14
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('vec3 spotRight', link='_spotRight')
            frag.add_uniform('vec4 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));')
Example #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
Example #16
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));')
Example #17
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

    parse_custom_particle = (cycles.node_by_name(mat_state.nodes, 'ArmCustomParticleNode') is not None)

    if parse_opacity:
        frag.write('float opacity;')

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

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

    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));')
            if(con_depth.is_elem('ipos')):
                vert.write('wposition = vec4(W * spos).xyz;')
                if(con_depth.is_elem('irot')):
                    vert.write('wnormal = transpose(inverse(mirot)) * wnormal;')
            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:
            if (not parse_custom_particle):
                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
Example #18
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
            rid = rpdat.rp_renderer
            if rid == 'Deferred':
                vert.add_uniform('mat4 W', '_worldMatrix')
                vert.add_out('vec3 wposition')
                vert.write_attrib('wposition = vec4(W * spos).xyz;')
        else:  # Tessellation
            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_attrib('wposition = vec4(W * spos).xyz;')
            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;')
        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('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.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);')
Example #19
0
def make(context_id):

    vs = [{'name': 'pos', 'data': 'float3'}]
    con_decal = mat_state.data.add_context({ 'name': context_id, 'vertex_elements': vs, 'depth_write': False, 'compare_mode': 'less', 'cull_mode': 'clockwise',
        'blend_source': 'source_alpha',
        'blend_destination': 'inverse_source_alpha',
        'blend_operation': 'add',
        'color_writes_alpha': [False, False]
    })

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

    vert.add_uniform('mat4 WVP', '_worldViewProjectionMatrix')
    vert.add_uniform('mat3 N', '_normalMatrix')
    vert.add_out('vec4 wvpposition')
    vert.add_out('vec3 wnormal')

    vert.write('wnormal = N * vec3(0.0, 0.0, 1.0);')
    vert.write('wvpposition = WVP * vec4(pos.xyz, 1.0);')
    vert.write('gl_Position = wvpposition;')
    
    frag.add_include('compiled.inc')
    frag.add_include('std/gbuffer.glsl')
    frag.ins = vert.outs
    frag.add_uniform('sampler2D gbufferD')
    frag.add_uniform('mat4 invVP', '_inverseViewProjectionMatrix')
    frag.add_uniform('mat4 invW', '_inverseWorldMatrix')
    frag.add_out('vec4 fragColor[2]')

    frag.write_attrib('    vec3 n = normalize(wnormal);')

    frag.write_attrib('    vec2 screenPosition = wvpposition.xy / wvpposition.w;')
    frag.write_attrib('    vec2 depthCoord = screenPosition * 0.5 + 0.5;')
    frag.write_attrib('#ifdef HLSL')
    frag.write_attrib('    depthCoord.y = 1.0 - depthCoord.y;')
    frag.write_attrib('#endif')
    frag.write_attrib('    float depth = texture(gbufferD, depthCoord).r * 2.0 - 1.0;')
    
    frag.write_attrib('    vec3 wpos = getPos2(invVP, depth, depthCoord);')
    frag.write_attrib('    vec4 mpos = invW * vec4(wpos, 1.0);')
    frag.write_attrib('    if (abs(mpos.x) > 1.0) discard;')
    frag.write_attrib('    if (abs(mpos.y) > 1.0) discard;')
    frag.write_attrib('    if (abs(mpos.z) > 1.0) discard;')
    frag.write_attrib('    vec2 texCoord = mpos.xy * 0.5 + 0.5;')

    frag.write('vec3 basecol;')
    frag.write('float roughness;')
    frag.write('float metallic;')
    frag.write('float occlusion;')
    frag.write('float specular;')
    frag.write('float opacity;')
    cycles.parse(mat_state.nodes, con_decal, vert, frag, geom, tesc, tese)

    frag.write('n /= (abs(n.x) + abs(n.y) + abs(n.z));')
    frag.write('n.xy = n.z >= 0.0 ? n.xy : octahedronWrap(n.xy);')
    frag.write('fragColor[0] = vec4(n.xy, packFloat(metallic, roughness), opacity);')
    frag.write('fragColor[1] = vec4(basecol.rgb, opacity);')

    make_finalize.make(con_decal)

    return con_decal
Example #20
0
def make_rect(con_rect):
    wrd = bpy.data.worlds['Arm']
    vert = con_rect.make_vert()
    frag = con_rect.make_frag()

    vert.vstruct_as_vsin = False  # Rect structure is used instead

    vert.add_in('vec2 pos')
    vert.add_out('vec2 texCoordRect')
    vert.add_out('vec3 viewRay')
    vert.add_uniform('float materialID', link='_objectInfoMaterialIndex')
    vert.add_uniform('mat4 invVP', link='_inverseViewProjectionMatrix')
    vert.add_uniform('vec3 eye', link='_cameraPosition')
    vert.write('const vec2 madd = vec2(0.5, 0.5);')
    vert.write('texCoordRect = pos.xy * madd + madd;')
    vert.write('const float fstep = 1.0 / 16777216.0; // 24bit')
    # vert.write('const float fstep = 1.0 / 65536.0; // 16bit')
    vert.write(
        'gl_Position = vec4(pos.xy, (materialID * fstep) * 2.0 - 1.0, 1.0);')
    vert.write('vec4 v = vec4(pos.xy, 1.0, 1.0);')
    vert.write('v = vec4(invVP * v);')
    vert.write('v.xyz /= v.w;')
    vert.write('viewRay = v.xyz - eye;')

    frag.ins = vert.outs
    frag.add_out('vec4 fragColor')
    frag.add_include('compiled.inc')
    frag.add_include('std/brdf.glsl')
    frag.add_include('std/math.glsl')
    frag.add_include('std/gbuffer.glsl')
    frag.add_include('std/shirr.glsl')
    frag.add_include('std/shadows.glsl')

    frag.add_uniform('sampler2D gbuffer0')
    frag.add_uniform('sampler2D gbuffer1')
    frag.add_uniform('sampler2D gbuffer2')
    frag.add_uniform('sampler2D gbufferD')
    frag.add_uniform('sampler2D ssaotex')
    frag.add_uniform('sampler2D shadowMap')
    frag.add_uniform('sampler2D shadowMapCube')
    frag.add_uniform('mat4 LWVP', link='_biasLightWorldViewProjectionMatrix')
    frag.add_uniform('vec3 eye', link='_cameraPosition')
    frag.add_uniform('vec3 eyeLook', link='_cameraLook')
    frag.add_uniform('vec3 lightPos', link='_lightPosition')
    frag.add_uniform('vec3 lightColor', link='_lightColor')
    frag.add_uniform('int lightShadow', link='_lightCastShadow')
    frag.add_uniform('vec2 lightProj', link='_lightPlaneProj')
    frag.add_uniform('float shadowsBias', link='_lightShadowsBias')
    # TODO: ifdef
    frag.add_uniform('float envmapStrength', link='_envmapStrength')
    frag.add_uniform('vec4 shirr[7]', link='_envmapIrradiance', included=True)
    frag.add_uniform('sampler2D senvmapRadiance', link='_envmapRadiance')
    frag.add_uniform('sampler2D senvmapBrdf', link='_envmapBrdf')
    frag.add_uniform('int envmapNumMipmaps', link='_envmapNumMipmaps')

    frag.write_pre = True
    frag.write('vec4 g0 = texture(gbuffer0, texCoordRect);')
    frag.write('vec4 g1 = texture(gbuffer1, texCoordRect);')
    frag.write('vec4 g2 = texture(gbuffer2, texCoordRect);')
    frag.write('float depth = texture(gbufferD, texCoordRect).r * 2.0 - 1.0;')

    frag.write('vec3 n;')
    frag.write('n.z = 1.0 - abs(g0.x) - abs(g0.y);')
    frag.write('n.xy = n.z >= 0.0 ? g0.xy : octahedronWrap(g0.xy);')
    frag.write('n = normalize(n);')
    frag.write('vec2 texCoord = g0.zw;')
    frag.add_uniform('vec2 cameraProj', link='_cameraPlaneProj')
    frag.write(
        'vec3 wposition = getPos(eye, eyeLook, viewRay, depth, cameraProj);')
    frag.write('vec3 vVec = normalize(eye - wposition);')
    frag.write_pre = False

    frag.write('float dotNV = dot(n, vVec);')
    frag.write('vec3 lp = lightPos - wposition;')
    frag.write('vec3 l = normalize(lp);')
    frag.write('float dotNL = max(dot(n, l), 0.0);')
    frag.write('vec3 h = normalize(vVec + l);')
    frag.write('float dotNH = dot(n, h);')
    frag.write('float dotVH = dot(vVec, h);')
    frag.write('float visibility = 1.0;')

    frag.write('vec3 basecol;')
    frag.write('float roughness;')
    frag.write('float metallic;')
    frag.write('float occlusion;')
    frag.write('float specular;')

    mat_state.texture_grad = True
    cycles.parse(mat_state.nodes,
                 con_rect,
                 vert,
                 frag,
                 None,
                 None,
                 None,
                 parse_opacity=False,
                 parse_displacement=False)
    mat_state.texture_grad = False

    frag.write('vec3 albedo = surfaceAlbedo(basecol, metallic);')
    frag.write('vec3 f0 = surfaceF0(basecol, metallic);')

    # Shadows
    frag.write('if (lightShadow == 1) {')
    frag.write('    vec4 lPos = LWVP * vec4(wposition, 1.0);')
    frag.write('    lPos.xyz /= lPos.w;')
    frag.write(
        '    if (lPos.x > 0.0 && lPos.y > 0.0 && lPos.x < 1.0 && lPos.y < 1.0) visibility = PCF(lPos.xy, lPos.z - shadowsBias);;'
    )
    frag.write('}')
    frag.write('else if (lightShadow == 2) {')
    frag.write(
        '    visibility = PCFCube(shadowMapCube, lp, -l, shadowsBias, lightProj, n);'
    )
    frag.write('}')

    frag.write('visibility *= attenuate(distance(wposition, lightPos));')

    frag.write(
        'fragColor.rgb = lambertDiffuseBRDF(albedo, dotNL) + specularBRDF(f0, roughness, dotNL, dotNH, dotNV, dotVH) * specular;'
    )
    frag.write('fragColor.rgb *= lightColor;')
    frag.write('fragColor.rgb *= visibility;')

    # Env
    frag.write(
        'vec2 envBRDF = texture(senvmapBrdf, vec2(roughness, 1.0 - dotNV)).xy;'
    )
    frag.write('vec3 envl = shIrradiance(n) / PI;')

    frag.write('vec3 reflectionWorld = reflect(-vVec, n);')
    frag.write('float lod = getMipFromRoughness(roughness, envmapNumMipmaps);')
    frag.write(
        'vec3 prefilteredColor = textureLod(senvmapRadiance, envMapEquirect(reflectionWorld), lod).rgb;'
    )

    frag.write('envl.rgb *= albedo;')
    frag.write('envl.rgb += prefilteredColor * (f0 * envBRDF.x + envBRDF.y);')
    frag.write('envl.rgb *= texture(ssaotex, texCoordRect).r;')
    frag.write('envl.rgb *= envmapStrength * occlusion;')

    frag.write('fragColor.rgb += envl;')
Example #21
0
def make_gi(context_id):
    con_voxel = mat_state.data.add_context({ 'name': context_id, 'depth_write': False, 'compare_mode': 'always', 'cull_mode': 'none', 'color_write_red': False, 'color_write_green': False, 'color_write_blue': False, 'color_write_alpha': False, 'conservative_raster': True })
    wrd = bpy.data.worlds['Arm']

    vert = con_voxel.make_vert()
    frag = con_voxel.make_frag()
    geom = con_voxel.make_geom()
    tesc = None
    tese = None
    geom.ins = vert.outs
    frag.ins = geom.outs

    frag.add_include('compiled.inc')
    frag.add_include('std/math.glsl')
    frag.add_include('std/imageatomic.glsl')
    frag.add_include('std/gbuffer.glsl')
    frag.write_header('#extension GL_ARB_shader_image_load_store : enable')

    rpdat = arm.utils.get_rp()
    frag.add_uniform('layout(r32ui) uimage3D voxels')
    frag.add_uniform('layout(r32ui) uimage3D voxelsNor')

    frag.write('if (abs(voxposition.z) > ' + rpdat.rp_voxelgi_resolution_z + ' || abs(voxposition.x) > 1 || abs(voxposition.y) > 1) return;')
    frag.write('vec3 wposition = voxposition * voxelgiHalfExtents;')
    if rpdat.arm_voxelgi_revoxelize and rpdat.arm_voxelgi_camera:
        frag.add_uniform('vec3 eyeSnap', '_cameraPositionSnap')
        frag.write('wposition += eyeSnap;')

    frag.write('vec3 basecol;')
    frag.write('float roughness;') #
    frag.write('float metallic;') #
    frag.write('float occlusion;') #
    frag.write('float specular;') #
    parse_opacity = rpdat.arm_voxelgi_refraction
    if parse_opacity:
        frag.write('float opacity;')
    frag.write('float dotNV = 0.0;')
    cycles.parse(mat_state.nodes, con_voxel, vert, frag, geom, tesc, tese, parse_opacity=parse_opacity, parse_displacement=False, basecol_only=True)

    # Voxelized particles
    particle = mat_state.material.arm_particle_flag
    if particle and rpdat.arm_particles == 'GPU':
        # make_particle.write(vert, particle_info=cycles.particle_info)
        frag.write_pre = True
        frag.write('const float p_index = 0;')
        frag.write('const float p_age = 0;')
        frag.write('const float p_lifetime = 0;')
        frag.write('const vec3 p_location = vec3(0);')
        frag.write('const float p_size = 0;')
        frag.write('const vec3 p_velocity = vec3(0);')
        frag.write('const vec3 p_angular_velocity = vec3(0);')
        frag.write_pre = False

    if not frag.contains('vec3 n ='):
        frag.write_pre = True
        frag.write('vec3 n;')
        frag.write_pre = False

    export_mpos = frag.contains('mposition') and not frag.contains('vec3 mposition')
    if export_mpos:
        vert.add_out('vec3 mpositionGeom')
        vert.write_pre = True
        vert.write('mpositionGeom = pos;')
        vert.write_pre = False

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

    vert.add_uniform('mat4 W', '_worldMatrix')
    vert.add_uniform('mat3 N', '_normalMatrix')

    vert.add_out('vec3 voxpositionGeom')
    vert.add_out('vec3 wnormalGeom')

    vert.add_include('compiled.inc')

    if con_voxel.is_elem('col'):
        vert.add_out('vec3 vcolorGeom')
        vert.write('vcolorGeom = col;')

    if con_voxel.is_elem('tex'):
        vert.add_out('vec2 texCoordGeom')
        vert.write('texCoordGeom = tex;')

    if rpdat.arm_voxelgi_revoxelize and rpdat.arm_voxelgi_camera:
        vert.add_uniform('vec3 eyeSnap', '_cameraPositionSnap')
        vert.write('voxpositionGeom = (vec3(W * vec4(pos, 1.0)) - eyeSnap) / voxelgiHalfExtents;')
    else: 
        vert.write('voxpositionGeom = vec3(W * vec4(pos, 1.0)) / voxelgiHalfExtents;')
    vert.write('wnormalGeom = normalize(N * nor);')
    # vert.write('gl_Position = vec4(0.0, 0.0, 0.0, 1.0);')

    geom.add_out('vec3 voxposition')
    geom.add_out('vec3 wnormal')
    if con_voxel.is_elem('col'):
        geom.add_out('vec3 vcolor')
    if con_voxel.is_elem('tex'):
        geom.add_out('vec2 texCoord')
    if export_mpos:
        geom.add_out('vec3 mposition')
    if export_bpos:
        geom.add_out('vec3 bposition')

    geom.write('vec3 p1 = voxpositionGeom[1] - voxpositionGeom[0];')
    geom.write('vec3 p2 = voxpositionGeom[2] - voxpositionGeom[0];')
    geom.write('vec3 p = abs(cross(p1, p2));')
    geom.write('for (uint i = 0; i < 3; ++i) {')
    geom.write('    voxposition = voxpositionGeom[i];')
    geom.write('    wnormal = wnormalGeom[i];')
    if con_voxel.is_elem('col'):
        geom.write('    vcolor = vcolorGeom[i];')
    if con_voxel.is_elem('tex'):
        geom.write('    texCoord = texCoordGeom[i];')
    if export_mpos:
        geom.write('    mposition = mpositionGeom[i];')
    if export_bpos:
        geom.write('    bposition = bpositionGeom[i];')
    geom.write('    if (p.z > p.x && p.z > p.y) {')
    geom.write('        gl_Position = vec4(voxposition.x, voxposition.y, 0.0, 1.0);')
    geom.write('    }')
    geom.write('    else if (p.x > p.y && p.x > p.z) {')
    geom.write('        gl_Position = vec4(voxposition.y, voxposition.z, 0.0, 1.0);')
    geom.write('    }')
    geom.write('    else {')
    geom.write('        gl_Position = vec4(voxposition.x, voxposition.z, 0.0, 1.0);')
    geom.write('    }')
    geom.write('    EmitVertex();')
    geom.write('}')
    geom.write('EndPrimitive();')

    frag.write('vec3 voxel = voxposition * 0.5 + 0.5;')
    frag.write('uint val = convVec4ToRGBA8(vec4(basecol, 1.0) * 255);')
    frag.write('imageAtomicMax(voxels, ivec3(voxelgiResolution * voxel), val);')

    frag.write('val = encNor(wnormal);');
    frag.write('imageAtomicMax(voxelsNor, ivec3(voxelgiResolution * voxel), val);')
        
        # frag.write('imageStore(voxels, ivec3(voxelgiResolution * voxel), vec4(color, 1.0));')
        # frag.write('imageAtomicRGBA8Avg(voxels, ivec3(voxelgiResolution * voxel), vec4(color, 1.0));')
            
        # frag.write('ivec3 coords = ivec3(voxelgiResolution * voxel);')
        # if parse_opacity:
        #     frag.write('vec4 val = vec4(color, opacity);')
        # else:
        #     frag.write('vec4 val = vec4(color, 1.0);')
        # frag.write('val *= 255.0;')
        # frag.write('uint newVal = encUnsignedNibble(convVec4ToRGBA8(val), 1);')
        # frag.write('uint prevStoredVal = 0;')
        # frag.write('uint currStoredVal;')
        # # frag.write('int counter = 0;')
        # # frag.write('while ((currStoredVal = imageAtomicCompSwap(voxels, coords, prevStoredVal, newVal)) != prevStoredVal && counter < 16) {')
        # frag.write('while ((currStoredVal = imageAtomicCompSwap(voxels, coords, prevStoredVal, newVal)) != prevStoredVal) {')
        # frag.write('    vec4 rval = convRGBA8ToVec4(currStoredVal & 0xFEFEFEFE);')
        # frag.write('    uint n = decUnsignedNibble(currStoredVal);')
        # frag.write('    rval = rval * n + val;')
        # frag.write('    rval /= ++n;')
        # frag.write('    rval = round(rval / 2) * 2;')
        # frag.write('    newVal = encUnsignedNibble(convVec4ToRGBA8(rval), n);')
        # frag.write('    prevStoredVal = currStoredVal;')
        # # frag.write('    counter++;')
        # frag.write('}')

        # frag.write('val.rgb *= 255.0f;')
        # frag.write('uint newVal = convVec4ToRGBA8(val);')
        # frag.write('uint prevStoredVal = 0;')
        # frag.write('uint curStoredVal;')
        # frag.write('while ((curStoredVal = imageAtomicCompSwap(voxels, coords, prevStoredVal, newVal)) != prevStoredVal) {')
        # frag.write('    prevStoredVal = curStoredVal;')
        # frag.write('    vec4 rval = convRGBA8ToVec4(curStoredVal);')
        # frag.write('    rval.xyz = (rval.xyz * rval.w);')
        # frag.write('    vec4 curValF = rval + val;')
        # frag.write('    curValF.xyz /= (curValF.w);')
        # frag.write('    newVal = convVec4ToRGBA8(curValF);')
        # frag.write('}')

    return con_voxel
Example #22
0
def make_forward_restricted(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_main_header('vec4 spos = vec4(pos, 1.0);')
    frag.ins = vert.outs
    vert.add_uniform('mat4 WVP', '_worldViewProjectionMatrix')
    vert.write('gl_Position = WVP * spos;')

    frag.add_include('../../Shaders/compiled.glsl')
    frag.write('vec3 basecol;')
    cycles.parse(mat_state.nodes,
                 con_mesh,
                 vert,
                 frag,
                 geom,
                 tesc,
                 tese,
                 basecol_only=True,
                 parse_opacity=False,
                 parse_displacement=False)

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

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

    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

    frag.add_uniform('vec3 lightColor', '_lampColor')
    frag.add_uniform('vec3 lightDir', '_lampDirection')
    frag.add_uniform('float envmapStrength', link='_envmapStrength')

    if '_NoShadows' in wrd.world_defs:
        is_shadows = False
    else:
        is_shadows = True

    frag.write('float visibility = 1.0;')
    frag.write('float dotNL = dot(n, lightDir);')

    if is_shadows:
        vert.add_out('vec4 lampPos')
        vert.add_uniform('mat4 LWVP', '_biasLampWorldViewProjectionMatrix')
        vert.write('lampPos = LWVP * spos;')
        frag.add_include('../../Shaders/std/shadows.glsl')
        frag.add_uniform('sampler2D shadowMap', included=True)
        frag.add_uniform('float shadowsBias', '_lampShadowsBias')
        frag.write('    if (lampPos.w > 0.0) {')
        frag.write('    vec3 lpos = lampPos.xyz / lampPos.w;')
        # frag.write('    visibility *= PCF(lpos.xy, lpos.z - shadowsBias);')
        frag.write('    const float texelSize = 1.0 / shadowmapSize.x;')
        frag.write('    visibility = 0.0;')
        frag.write(
            '    visibility += float(texture(shadowMap, lpos.xy).r + shadowsBias > lpos.z);'
        )
        frag.write(
            '    visibility += float(texture(shadowMap, lpos.xy + vec2(texelSize, 0.0)).r + shadowsBias > lpos.z) * 0.5;'
        )
        frag.write(
            '    visibility += float(texture(shadowMap, lpos.xy + vec2(-texelSize, 0.0)).r + shadowsBias > lpos.z) * 0.25;'
        )
        frag.write(
            '    visibility += float(texture(shadowMap, lpos.xy + vec2(0.0, texelSize)).r + shadowsBias > lpos.z) * 0.5;'
        )
        frag.write(
            '    visibility += float(texture(shadowMap, lpos.xy + vec2(0.0, -texelSize)).r + shadowsBias > lpos.z) * 0.25;'
        )
        frag.write('    visibility /= 2.5;')
        frag.write('    visibility = max(visibility, 0.5);')
        # frag.write('    visibility = max(float(texture(shadowMap, lpos.xy).r + shadowsBias > lpos.z), 0.5);')
        frag.write('    }')

    frag.write('vec3 direct = basecol * max(dotNL, 0.1);')

    frag.add_out('vec4 fragColor')
    frag.write('fragColor = vec4(direct * lightColor * visibility, 1.0);')

    if '_LDR' in bpy.data.worlds['Arm'].rp_defs:
        frag.write('fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / 2.2));')
Example #23
0
def make_gi(context_id):
    con_voxel = mat_state.data.add_context({
        'name': context_id,
        'depth_write': False,
        'compare_mode': 'always',
        'cull_mode': 'none',
        'color_write_red': False,
        'color_write_green': False,
        'color_write_blue': False,
        'color_write_alpha': False,
        'conservative_raster': True
    })
    wrd = bpy.data.worlds['Arm']

    vert = con_voxel.make_vert()
    frag = con_voxel.make_frag()
    geom = con_voxel.make_geom()
    tesc = None
    tese = None
    geom.ins = vert.outs
    frag.ins = geom.outs

    frag.add_include('compiled.inc')
    frag.add_include('std/math.glsl')
    frag.add_include('std/imageatomic.glsl')
    frag.add_include('std/gbuffer.glsl')
    frag.write_header('#extension GL_ARB_shader_image_load_store : enable')

    rpdat = arm.utils.get_rp()
    if arm.utils.get_gapi() == 'direct3d11':
        for e in con_voxel.data['vertex_elements']:
            if e['name'] == 'nor':
                con_voxel.data['vertex_elements'].remove(e)
                break
        frag.add_uniform('layout(rgba8) writeonly image3D voxels')
    else:
        frag.add_uniform('layout(r32ui) uimage3D voxels')

    frag.write('if (abs(voxposition.z) > ' + rpdat.rp_voxelgi_resolution_z +
               ' || abs(voxposition.x) > 1 || abs(voxposition.y) > 1) return;')
    frag.write('vec3 wposition = voxposition * voxelgiHalfExtents;')
    if rpdat.arm_voxelgi_revoxelize and rpdat.arm_voxelgi_camera:
        frag.add_uniform('vec3 eyeSnap', '_cameraPositionSnap')
        frag.write('wposition += eyeSnap;')

    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;')  #
    frag.write('float dotNV = 0.0;')
    cycles.parse(mat_state.nodes,
                 con_voxel,
                 vert,
                 frag,
                 geom,
                 tesc,
                 tese,
                 parse_opacity=False,
                 parse_displacement=False,
                 basecol_only=True)

    # Voxelized particles
    particle = mat_state.material.arm_particle_flag
    if particle and rpdat.arm_particles == 'GPU':
        # make_particle.write(vert, particle_info=cycles.particle_info)
        frag.write_pre = True
        frag.write('const float p_index = 0;')
        frag.write('const float p_age = 0;')
        frag.write('const float p_lifetime = 0;')
        frag.write('const vec3 p_location = vec3(0);')
        frag.write('const float p_size = 0;')
        frag.write('const vec3 p_velocity = vec3(0);')
        frag.write('const vec3 p_angular_velocity = vec3(0);')
        frag.write_pre = False

    if not frag.contains('vec3 n ='):
        frag.write_pre = True
        frag.write('vec3 n;')
        frag.write_pre = False

    export_mpos = frag.contains(
        'mposition') and not frag.contains('vec3 mposition')
    if export_mpos:
        vert.add_out('vec3 mpositionGeom')
        vert.write_pre = True
        vert.write('mpositionGeom = pos;')
        vert.write_pre = False

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

    vert.add_uniform('mat4 W', '_worldMatrix')
    vert.add_out('vec3 voxpositionGeom')
    vert.add_include('compiled.inc')

    if con_voxel.is_elem('col'):
        vert.add_out('vec3 vcolorGeom')
        vert.write('vcolorGeom = col.rgb;')

    if con_voxel.is_elem('tex'):
        vert.add_out('vec2 texCoordGeom')
        vert.write('texCoordGeom = tex;')

    if rpdat.arm_voxelgi_revoxelize and rpdat.arm_voxelgi_camera:
        vert.add_uniform('vec3 eyeSnap', '_cameraPositionSnap')
        vert.write(
            'voxpositionGeom = (vec3(W * vec4(pos.xyz, 1.0)) - eyeSnap) / voxelgiHalfExtents;'
        )
    else:
        vert.write(
            'voxpositionGeom = vec3(W * vec4(pos.xyz, 1.0)) / voxelgiHalfExtents;'
        )
    vert.write('gl_Position = vec4(0.0, 0.0, 0.0, 1.0);')

    geom.add_out('vec3 voxposition')
    geom.add_out('vec4 lightPosition')
    if con_voxel.is_elem('col'):
        geom.add_out('vec3 vcolor')
    if con_voxel.is_elem('tex'):
        geom.add_out('vec2 texCoord')
    if export_mpos:
        geom.add_out('vec3 mposition')
    if export_bpos:
        geom.add_out('vec3 bposition')

    if arm.utils.get_gapi() == 'direct3d11':
        # No geom shader compiler for hlsl yet
        geom.noprocessing = True
        struct_input = 'struct SPIRV_Cross_Input {'
        struct_output = 'struct SPIRV_Cross_Output {'
        pos = 0
        if export_bpos:
            struct_input += ' float3 bpositionGeom : TEXCOORD' + str(pos) + ';'
            struct_output += ' float3 bposition : TEXCOORD' + str(pos) + ';'
            pos += 1
        struct_input += ' float3 lightPositionGeom : TEXCOORD' + str(pos) + ';'
        struct_output += ' float3 lightPosition : TEXCOORD' + str(pos) + ';'
        pos += 1
        if export_mpos:
            struct_input += ' float3 mpositionGeom : TEXCOORD' + str(pos) + ';'
            struct_output += ' float3 mposition : TEXCOORD' + str(pos) + ';'
            pos += 1
        if con_voxel.is_elem('tex'):
            struct_input += ' float2 texCoordGeom : TEXCOORD' + str(pos) + ';'
            struct_output += ' float2 texCoord : TEXCOORD' + str(pos) + ';'
            pos += 1
        if con_voxel.is_elem('col'):
            struct_input += ' float3 vcolorGeom : TEXCOORD' + str(pos) + ';'
            struct_output += ' float3 vcolor : TEXCOORD' + str(pos) + ';'
            pos += 1
        struct_input += ' float3 voxpositionGeom : TEXCOORD' + str(pos) + ';'
        struct_output += ' float3 voxposition : TEXCOORD' + str(pos) + ';'
        pos += 1
        struct_input += ' float4 gl_Position : SV_POSITION; };'
        struct_output += ' float4 gl_Position : SV_POSITION; };'
        geom.write(struct_input)
        geom.write(struct_output)
        geom.write('[maxvertexcount(3)]')
        geom.write(
            'void main(triangle SPIRV_Cross_Input stage_input[3], inout TriangleStream<SPIRV_Cross_Output> output) {'
        )
        geom.write(
            '  float3 p1 = stage_input[1].voxpositionGeom.xyz - stage_input[0].voxpositionGeom.xyz;'
        )
        geom.write(
            '  float3 p2 = stage_input[2].voxpositionGeom.xyz - stage_input[0].voxpositionGeom.xyz;'
        )
        geom.write('  float3 p = abs(cross(p1, p2));')
        geom.write('  for (int i = 0; i < 3; ++i) {')
        geom.write('    SPIRV_Cross_Output stage_output;')
        geom.write(
            '    stage_output.voxposition = stage_input[i].voxpositionGeom;')
        geom.write(
            '    stage_output.lightPosition = stage_input[i].lightPositionGeom;'
        )
        if con_voxel.is_elem('col'):
            geom.write('    stage_output.vcolor = stage_input[i].vcolorGeom;')
        if con_voxel.is_elem('tex'):
            geom.write(
                '    stage_output.texCoord = stage_input[i].texCoordGeom;')
        if export_mpos:
            geom.write(
                '    stage_output.mposition = stage_input[i].mpositionGeom;')
        if export_bpos:
            geom.write(
                '    stage_output.bposition = stage_input[i].bpositionGeom;')
        geom.write('    if (p.z > p.x && p.z > p.y) {')
        geom.write(
            '      stage_output.gl_Position = float4(stage_input[i].voxpositionGeom.x, stage_input[i].voxpositionGeom.y, 0.0, 1.0);'
        )
        geom.write('    }')
        geom.write('    else if (p.x > p.y && p.x > p.z) {')
        geom.write(
            '      stage_output.gl_Position = float4(stage_input[i].voxpositionGeom.y, stage_input[i].voxpositionGeom.z, 0.0, 1.0);'
        )
        geom.write('    }')
        geom.write('    else {')
        geom.write(
            '      stage_output.gl_Position = float4(stage_input[i].voxpositionGeom.x, stage_input[i].voxpositionGeom.z, 0.0, 1.0);'
        )
        geom.write('    }')
        geom.write('    output.Append(stage_output);')
        geom.write('  }')
        geom.write('}')
    else:
        geom.write('vec3 p1 = voxpositionGeom[1] - voxpositionGeom[0];')
        geom.write('vec3 p2 = voxpositionGeom[2] - voxpositionGeom[0];')
        geom.write('vec3 p = abs(cross(p1, p2));')
        geom.write('for (uint i = 0; i < 3; ++i) {')
        geom.write('    voxposition = voxpositionGeom[i];')
        geom.write('    lightPosition = lightPositionGeom[i];')
        if con_voxel.is_elem('col'):
            geom.write('    vcolor = vcolorGeom[i];')
        if con_voxel.is_elem('tex'):
            geom.write('    texCoord = texCoordGeom[i];')
        if export_mpos:
            geom.write('    mposition = mpositionGeom[i];')
        if export_bpos:
            geom.write('    bposition = bpositionGeom[i];')
        geom.write('    if (p.z > p.x && p.z > p.y) {')
        geom.write(
            '        gl_Position = vec4(voxposition.x, voxposition.y, 0.0, 1.0);'
        )
        geom.write('    }')
        geom.write('    else if (p.x > p.y && p.x > p.z) {')
        geom.write(
            '        gl_Position = vec4(voxposition.y, voxposition.z, 0.0, 1.0);'
        )
        geom.write('    }')
        geom.write('    else {')
        geom.write(
            '        gl_Position = vec4(voxposition.x, voxposition.z, 0.0, 1.0);'
        )
        geom.write('    }')
        geom.write('    EmitVertex();')
        geom.write('}')
        geom.write('EndPrimitive();')

    if '_Sun' in wrd.world_defs and '_ShadowMap' in wrd.world_defs:
        vert.add_out('vec4 lightPositionGeom')
        vert.add_uniform('mat4 LWVP',
                         link='_biasLightWorldViewProjectionMatrix')
        vert.write('lightPositionGeom = LWVP * vec4(pos.xyz, 1.0);')
        frag.add_uniform('sampler2DShadow shadowMap')
        frag.add_uniform('float shadowsBias', link='_sunShadowsBias')
        frag.write('float visibility = 1.0;')
        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(
                'visibility = shadowTestCascade(shadowMap, eye, wposition, shadowsBias);'
            )
        else:
            frag.write('if (lightPosition.w > 0.0) {')
            frag.write('    vec3 lPos = lightPosition.xyz / lightPosition.w;')
            frag.write(
                '    visibility = texture(shadowMap, vec3(lPos.xy, lPos.z - shadowsBias)).r;'
            )
            frag.write('}')
        frag.add_uniform('vec3 sunCol', link="_sunColor")
        frag.write('basecol *= visibility * sunCol;')
    else:
        print(
            'Armory Warning: Voxel GI requires sun light and enabled shadows')
        vert.add_out('vec4 lightPositionGeom')
        frag.write('basecol = vec3(0.0);')

    frag.write('vec3 voxel = voxposition * 0.5 + 0.5;')
    if arm.utils.get_gapi() == 'direct3d11':
        frag.write(
            'imageStore(voxels, ivec3(voxelgiResolution * voxel), vec4(min(basecol, vec3(1.0)), 1.0));'
        )
    else:
        frag.write(
            'uint val = convVec4ToRGBA8(vec4(min(basecol, vec3(1.0)), 1.0));')
        frag.write(
            'imageAtomicMax(voxels, ivec3(voxelgiResolution * voxel), val);')

    return con_voxel