Beispiel #1
0
def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
    global is_displacement
    wrd = bpy.data.worlds['Arm']

    arm_discard = mat_state.material.arm_discard
    make_base(con_mesh, parse_opacity=(parse_opacity or arm_discard))

    blend = mat_state.material.arm_blending

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

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

    if blend:
        frag.add_out('vec4 fragColor[1]')
        if parse_opacity:
            frag.write('fragColor[0] = vec4(basecol, opacity);')
        else:
            # frag.write('fragColor[0] = vec4(basecol * lightCol * visibility, 1.0);')
            frag.write('fragColor[0] = vec4(basecol, 1.0);')
        # TODO: Fade out fragments near depth buffer here
        return

    frag.write_attrib('vec3 vVec = normalize(eyeDir);')
    frag.write_attrib('float dotNV = max(dot(n, vVec), 0.0);')

    sh = tese if tese is not None else vert
    sh.add_out('vec3 eyeDir')
    sh.add_uniform('vec3 eye', '_cameraPosition')
    sh.write('eyeDir = eye - wposition;')

    frag.add_include('std/light.glsl')
    is_shadows = '_ShadowMap' in wrd.world_defs
    is_shadows_atlas = '_ShadowMapAtlas' in wrd.world_defs
    is_single_atlas = is_shadows_atlas and '_SingleAtlas' in wrd.world_defs
    shadowmap_sun = 'shadowMap'
    if is_shadows_atlas:
        shadowmap_sun = 'shadowMapAtlasSun' if not is_single_atlas else 'shadowMapAtlas'
        frag.add_uniform('vec2 smSizeUniform', '_shadowMapSize', included=True)

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

    if '_Brdf' in wrd.world_defs:
        frag.add_uniform('sampler2D senvmapBrdf', link='$brdf.png')
        frag.write(
            'vec2 envBRDF = texture(senvmapBrdf, vec2(roughness, 1.0 - dotNV)).xy;'
        )

    if '_Irr' in wrd.world_defs:
        frag.add_include('std/shirr.glsl')
        frag.add_uniform('vec4 shirr[7]', link='_envmapIrradiance')
        frag.write('vec3 indirect = shIrradiance(n, shirr);')
        if '_EnvTex' in wrd.world_defs:
            frag.write('indirect /= PI;')
        frag.write('indirect *= albedo;')
        if '_Rad' in wrd.world_defs:
            frag.add_uniform('sampler2D senvmapRadiance',
                             link='_envmapRadiance')
            frag.add_uniform('int envmapNumMipmaps', link='_envmapNumMipmaps')
            frag.write('vec3 reflectionWorld = reflect(-vVec, n);')
            frag.write(
                'float lod = getMipFromRoughness(roughness, envmapNumMipmaps);'
            )
            frag.write(
                'vec3 prefilteredColor = textureLod(senvmapRadiance, envMapEquirect(reflectionWorld), lod).rgb;'
            )
            if '_EnvLDR' in wrd.world_defs:
                frag.write(
                    'prefilteredColor = pow(prefilteredColor, vec3(2.2));')
            frag.write(
                'indirect += prefilteredColor * (f0 * envBRDF.x + envBRDF.y) * 1.5;'
            )
        elif '_EnvCol' in wrd.world_defs:
            frag.add_uniform('vec3 backgroundCol', link='_backgroundCol')
            frag.write('indirect += backgroundCol * f0;')
    else:
        frag.write('vec3 indirect = albedo;')
    frag.write('indirect *= occlusion;')

    frag.add_uniform('float envmapStrength', link='_envmapStrength')
    frag.write('indirect *= envmapStrength;')

    if '_VoxelAOvar' in wrd.world_defs:
        frag.add_include('std/conetrace.glsl')
        frag.add_uniform('sampler3D voxels')
        if '_VoxelGICam' in wrd.world_defs:
            frag.add_uniform('vec3 eyeSnap', link='_cameraPositionSnap')
            frag.write(
                'vec3 voxpos = (wposition - eyeSnap) / voxelgiHalfExtents;')
        else:
            frag.write('vec3 voxpos = wposition / voxelgiHalfExtents;')
        frag.write('indirect *= vec3(1.0 - traceAO(voxpos, n, voxels));')

    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('vec3 sh = normalize(vVec + sunDir);')
        frag.write('float sdotNL = dot(n, sunDir);')
        frag.write('float sdotNH = dot(n, sh);')
        frag.write('float sdotVH = dot(vVec, sh);')
        if is_shadows:
            frag.add_uniform('bool receiveShadow')
            frag.add_uniform(f'sampler2DShadow {shadowmap_sun}', top=True)
            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:
                if tese is not None:
                    tese.add_out('vec4 lightPosition')
                    tese.add_uniform('mat4 LVP',
                                     '_biasLightViewProjectionMatrix')
                    tese.write('lightPosition = LVP * vec4(wposition, 1.0);')
                else:
                    if is_displacement:
                        vert.add_out('vec4 lightPosition')
                        vert.add_uniform('mat4 LVP',
                                         '_biasLightViewProjectionMatrix')
                        vert.write(
                            'lightPosition = LVP * vec4(wposition, 1.0);')
                    else:
                        vert.add_out('vec4 lightPosition')
                        vert.add_uniform(
                            'mat4 LWVP',
                            '_biasLightWorldViewProjectionMatrixSun')
                        vert.write('lightPosition = LWVP * spos;')
                frag.write('vec3 lPos = lightPosition.xyz / lightPosition.w;')
                frag.write('const vec2 smSize = shadowmapSize;')
                frag.write(
                    f'svisibility = PCF({shadowmap_sun}, lPos.xy, lPos.z - shadowsBias, smSize);'
                )
            frag.write('}')  # receiveShadow
        if '_VoxelShadow' in wrd.world_defs and '_VoxelAOvar' in wrd.world_defs:
            frag.write(
                'svisibility *= 1.0 - traceShadow(voxels, voxpos, sunDir);')
        frag.write(
            'direct += (lambertDiffuseBRDF(albedo, sdotNL) + specularBRDF(f0, roughness, sdotNL, sdotNH, dotNV, sdotVH) * specular) * sunCol * svisibility;'
        )
        # sun

    if '_SinglePoint' in wrd.world_defs:
        frag.add_uniform('vec3 pointPos', link='_pointPosition')
        frag.add_uniform('vec3 pointCol', link='_pointColor')
        if '_Spot' in wrd.world_defs:
            frag.add_uniform('vec3 spotDir', link='_spotDirection')
            frag.add_uniform('vec2 spotData', link='_spotData')
        if is_shadows:
            frag.add_uniform('bool receiveShadow')
            frag.add_uniform('float pointBias', link='_pointShadowsBias')
            if '_Spot' in wrd.world_defs:
                # Skip world matrix, already in world-space
                frag.add_uniform(
                    'mat4 LWVPSpot[1]',
                    link='_biasLightViewProjectionMatrixSpotArray',
                    included=True)
                frag.add_uniform('sampler2DShadow shadowMapSpot[1]',
                                 included=True)
            else:
                frag.add_uniform('vec2 lightProj',
                                 link='_lightPlaneProj',
                                 included=True)
                frag.add_uniform('samplerCubeShadow shadowMapPoint[1]',
                                 included=True)
        frag.write('direct += sampleLight(')
        frag.write(
            '  wposition, n, vVec, dotNV, pointPos, pointCol, albedo, roughness, specular, f0'
        )
        if is_shadows:
            frag.write('  , 0, pointBias, receiveShadow')
        if '_Spot' in wrd.world_defs:
            frag.write('  , true, spotData.x, spotData.y, spotDir')
        if '_VoxelShadow' in wrd.world_defs and '_VoxelAOvar' in wrd.world_defs:
            frag.write('  , voxels, voxpos')
        frag.write(');')

    if '_Clusters' in wrd.world_defs:
        make_cluster.write(vert, frag)

    if '_Emission' in wrd.world_defs:
        frag.write('if (emission > 0.0) {')
        frag.write('    direct = vec3(0.0);')
        frag.write('    indirect += basecol * emission;')
        frag.write('}')
Beispiel #2
0
def make_forward_base(con_mesh, parse_opacity=False):
    global is_displacement
    wrd = bpy.data.worlds['Arm']

    arm_discard = mat_state.material.arm_discard
    make_base(con_mesh, parse_opacity=(parse_opacity or arm_discard))

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

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

    blend = mat_state.material.arm_blending
    if blend:
        frag.add_out('vec4 fragColor')
        if parse_opacity:
            frag.write('fragColor = vec4(basecol, opacity);')
        else:
            # frag.write('fragColor = vec4(basecol * lightCol * visibility, 1.0);')
            frag.write('fragColor = vec4(basecol, 1.0);')
        # TODO: Fade out fragments near depth buffer here
        return

    frag.write_init("""
    vec3 vVec = normalize(eyeDir);
    float dotNV = max(dot(n, vVec), 0.0);
""")

    sh = tese if tese != None else vert
    sh.add_out('vec3 eyeDir')
    sh.add_uniform('vec3 eye', '_cameraPosition')
    sh.write('eyeDir = eye - wposition;')

    frag.add_include('std/light.glsl')
    is_shadows = '_ShadowMap' in wrd.world_defs

    frag.write('vec3 albedo = surfaceAlbedo(basecol, metallic);')
    frag.write('vec3 f0 = surfaceF0(basecol, metallic);')
    frag.write('vec3 direct = vec3(0.0);')
    frag.add_uniform('bool receiveShadow')

    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('vec3 sh = normalize(vVec + sunDir);')
        frag.write('float sdotNL = dot(n, sunDir);')
        frag.write('float sdotNH = dot(n, sh);')
        frag.write('float sdotVH = dot(vVec, sh);')
        if is_shadows:
            frag.add_uniform('sampler2D shadowMap')
            frag.add_uniform('float shadowsBias', '_sunShadowsBias')
            frag.write('if (receiveShadow) {')
            if '_CSM' in wrd.world_defs:
                frag.add_uniform('vec4 casData[shadowmapCascades * 4 + 4]', '_cascadeData', included=True)
                frag.add_uniform('vec3 eye', '_cameraPosition')
                frag.write('vec2 smSize;')
                frag.write('vec3 lPos;')
                frag.write('int casi;')
                frag.write('int casindex;')
                frag.write('mat4 LWVP = getCascadeMat(distance(eye, wposition), casi, casindex);')
                frag.write('vec4 lightPosition = LWVP * vec4(wposition, 1.0);')
                frag.write('lPos = lightPosition.xyz / lightPosition.w;')
                frag.write('smSize = shadowmapSize * vec2(shadowmapCascades, 1.0);')
            else:
                if tese != None:
                    tese.add_out('vec4 lightPosition')
                    tese.add_uniform('mat4 LVP', '_biasLightViewProjectionMatrix')
                    tese.write('lightPosition = LVP * vec4(wposition, 1.0);')
                else:
                    if is_displacement:
                        vert.add_out('vec4 lightPosition')
                        vert.add_uniform('mat4 LVP', '_biasLightViewProjectionMatrix')
                        vert.write('lightPosition = LVP * vec4(wposition, 1.0);')
                    else:
                        vert.add_out('vec4 lightPosition')
                        vert.add_uniform('mat4 LWVP', '_biasLightWorldViewProjectionMatrix')
                        vert.write('lightPosition = LWVP * spos;')
                frag.write('vec3 lPos = lightPosition.xyz / lightPosition.w;')
                frag.write('const vec2 smSize = shadowmapSize;')
            frag.write('svisibility = PCF(shadowMap, lPos.xy, lPos.z - shadowsBias, smSize);')
            frag.write('}') # receiveShadow
        # is_shadows
        frag.write('direct += (lambertDiffuseBRDF(albedo, sdotNL) + specularBRDF(f0, roughness, sdotNL, sdotNH, dotNV, sdotVH) * specular) * sunCol * svisibility;')
        # sun

    if '_SinglePoint' in wrd.world_defs:
        frag.add_uniform('vec3 pointPos', link='_pointPosition')
        frag.add_uniform('vec3 pointCol', link='_pointColor')
        if is_shadows:
            frag.add_uniform('vec2 lightProj', link='_lightPlaneProj', included=True)
            frag.add_uniform('samplerCube shadowMap0', included=True)
            frag.add_uniform('float pointBias', link='_pointShadowsBias')
        if '_Spot' in wrd.world_defs:
            frag.add_uniform('vec3 spotDir', link='_spotDirection')
            frag.add_uniform('vec2 spotData', link='_spotData')
            if is_shadows:
                frag.add_uniform('sampler2D shadowMapSpot0', included=True)
        frag.write('direct += sampleLight(')
        frag.write('  wposition, n, vVec, dotNV, pointPos, pointCol, albedo, roughness, specular, f0')
        if is_shadows:
            frag.write('  , pointBias')
        if '_Spot' in wrd.world_defs:
            frag.write('  , true, spotData.x, spotData.y, spotDir')
        frag.write(');')

    if '_Clusters' in wrd.world_defs:
        make_cluster.write(vert, frag)

    if '_Brdf' in wrd.world_defs:
        frag.add_uniform('sampler2D senvmapBrdf', link='_envmapBrdf')
        frag.write('vec2 envBRDF = texture(senvmapBrdf, vec2(roughness, 1.0 - dotNV)).xy;')

    if '_Irr' in wrd.world_defs:
        frag.add_include('std/shirr.glsl')
        frag.add_uniform('vec4 shirr[7]', link='_envmapIrradiance', included=True)
        frag.write('vec3 indirect = shIrradiance(n);')
        if '_EnvTex' in wrd.world_defs:
            frag.write('indirect /= PI;')
        frag.write('indirect *= albedo;')
        if '_Rad' in wrd.world_defs:
            frag.add_uniform('sampler2D senvmapRadiance', link='_envmapRadiance')
            frag.add_uniform('int envmapNumMipmaps', link='_envmapNumMipmaps')
            frag.write('vec3 reflectionWorld = reflect(-vVec, n);')
            frag.write('float lod = getMipFromRoughness(roughness, envmapNumMipmaps);')
            frag.write('vec3 prefilteredColor = textureLod(senvmapRadiance, envMapEquirect(reflectionWorld), lod).rgb;')
            if '_EnvLDR' in wrd.world_defs:
                frag.write('prefilteredColor = pow(prefilteredColor, vec3(2.2));')
            frag.write('indirect += prefilteredColor * (f0 * envBRDF.x + envBRDF.y) * 1.5;')
        elif '_EnvCol' in wrd.world_defs:
            frag.add_uniform('vec3 backgroundCol', link='_backgroundCol')
            frag.write('indirect += backgroundCol * f0;')
    else:
        frag.write('vec3 indirect = albedo;')
    frag.write('indirect *= occlusion;')

    frag.add_uniform('float envmapStrength', link='_envmapStrength')
    frag.write('indirect *= envmapStrength;')

    if '_VoxelGI' in wrd.world_defs or '_VoxelAO' in wrd.world_defs:
        frag.add_include('std/conetrace.glsl')
        frag.add_uniform('sampler3D voxels')
        if '_VoxelGICam' in wrd.world_defs:
            frag.add_uniform('vec3 eyeSnap', link='_cameraPositionSnap')
            frag.write('vec3 voxpos = (wposition - eyeSnap) / voxelgiHalfExtents;')
        else:
            frag.write('vec3 voxpos = wposition / voxelgiHalfExtents;')
        if '_VoxelAO' in wrd.world_defs:
            frag.write('indirect *= vec3(1.0 - traceAO(voxpos, n, voxels));')
            # frag.write('indirect = vec3(1.0 - traceAO(voxpos, n, voxels));') # AO view
        else:
            frag.write('vec4 indirectDiffuse = traceDiffuse(voxpos, n, voxels);')
            frag.write('indirect = indirect * voxelgiEnv + vec3(indirectDiffuse.rgb * voxelgiDiff * basecol);')
            frag.write('if (specular > 0.0) {')
            frag.write('vec3 indirectSpecular = traceSpecular(voxels, voxpos, n, vVec, roughness);')
            frag.write('indirectSpecular *= f0 * envBRDF.x + envBRDF.y;')
            frag.write('indirect += indirectSpecular * voxelgiSpec * specular;')
            frag.write('}')
Beispiel #3
0
def make_forward_mobile(con_mesh):
    wrd = bpy.data.worlds['Arm']
    vert = con_mesh.make_vert()
    frag = con_mesh.make_frag()
    geom = None
    tesc = None
    tese = None

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

    frag.add_include('compiled.inc')
    frag.write('vec3 basecol;')
    frag.write('float roughness;')
    frag.write('float metallic;')
    frag.write('float occlusion;')
    frag.write('float specular;')
    if '_Emission' in wrd.world_defs:
        frag.write('float emission;')

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

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

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

    make_attrib.write_tex_coords(con_mesh, vert, frag, tese)

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

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

    make_attrib.write_vertpos(vert)

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

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

    is_shadows = '_ShadowMap' in wrd.world_defs
    is_shadows_atlas = '_ShadowMapAtlas' in wrd.world_defs
    shadowmap_sun = 'shadowMap'
    if is_shadows_atlas:
        is_single_atlas = '_SingleAtlas' in wrd.world_defs
        shadowmap_sun = 'shadowMapAtlasSun' if not is_single_atlas else 'shadowMapAtlas'
        frag.add_uniform('vec2 smSizeUniform', '_shadowMapSize', included=True)
    frag.write('vec3 direct = vec3(0.0);')

    if '_Sun' in wrd.world_defs:
        frag.add_uniform('vec3 sunCol', '_sunColor')
        frag.add_uniform('vec3 sunDir', '_sunDirection')
        frag.write('float svisibility = 1.0;')
        frag.write('float sdotNL = max(dot(n, sunDir), 0.0);')
        if is_shadows:
            vert.add_out('vec4 lightPosition')
            vert.add_uniform('mat4 LWVP',
                             '_biasLightWorldViewProjectionMatrixSun')
            vert.write('lightPosition = LWVP * spos;')
            frag.add_uniform('bool receiveShadow')
            frag.add_uniform(f'sampler2DShadow {shadowmap_sun}')
            frag.add_uniform('float shadowsBias', '_sunShadowsBias')

            frag.write('if (receiveShadow) {')
            if '_CSM' in wrd.world_defs:
                frag.add_include('std/shadows.glsl')
                frag.add_uniform('vec4 casData[shadowmapCascades * 4 + 4]',
                                 '_cascadeData',
                                 included=True)
                frag.add_uniform('vec3 eye', '_cameraPosition')
                frag.write(
                    f'svisibility = shadowTestCascade({shadowmap_sun}, eye, wposition + n * shadowsBias * 10, shadowsBias);'
                )
            else:
                frag.write('if (lightPosition.w > 0.0) {')
                frag.write(
                    '    vec3 lPos = lightPosition.xyz / lightPosition.w;')
                if '_Legacy' in wrd.world_defs:
                    frag.write(
                        f'    svisibility = float(texture({shadowmap_sun}, vec2(lPos.xy)).r > lPos.z - shadowsBias);'
                    )
                else:
                    frag.write(
                        f'    svisibility = texture({shadowmap_sun}, vec3(lPos.xy, lPos.z - shadowsBias)).r;'
                    )
                frag.write('}')
            frag.write('}')  # receiveShadow
        frag.write('direct += basecol * sdotNL * sunCol * svisibility;')

    if '_SinglePoint' in wrd.world_defs:
        frag.add_uniform('vec3 pointPos', '_pointPosition')
        frag.add_uniform('vec3 pointCol', '_pointColor')
        if '_Spot' in wrd.world_defs:
            frag.add_uniform('vec3 spotDir', link='_spotDirection')
            frag.add_uniform('vec2 spotData', link='_spotData')
        frag.write('float visibility = 1.0;')
        frag.write('vec3 ld = pointPos - wposition;')
        frag.write('vec3 l = normalize(ld);')
        frag.write('float dotNL = max(dot(n, l), 0.0);')
        if is_shadows:
            frag.add_uniform('bool receiveShadow')
            frag.add_uniform('float pointBias', link='_pointShadowsBias')
            frag.add_include('std/shadows.glsl')

            frag.write('if (receiveShadow) {')
            if '_Spot' in wrd.world_defs:
                vert.add_out('vec4 spotPosition')
                vert.add_uniform(
                    'mat4 LWVPSpotArray[1]',
                    link='_biasLightWorldViewProjectionMatrixSpotArray')
                vert.write('spotPosition = LWVPSpotArray[0] * spos;')
                frag.add_uniform('sampler2DShadow shadowMapSpot[1]')
                frag.write('if (spotPosition.w > 0.0) {')
                frag.write(
                    '    vec3 lPos = spotPosition.xyz / spotPosition.w;')
                if '_Legacy' in wrd.world_defs:
                    frag.write(
                        '    visibility = float(texture(shadowMapSpot[0], vec2(lPos.xy)).r > lPos.z - pointBias);'
                    )
                else:
                    frag.write(
                        '    visibility = texture(shadowMapSpot[0], vec3(lPos.xy, lPos.z - pointBias)).r;'
                    )
                frag.write('}')
            else:
                frag.add_uniform('vec2 lightProj', link='_lightPlaneProj')
                frag.add_uniform('samplerCubeShadow shadowMapPoint[1]')
                frag.write('const float s = shadowmapCubePcfSize;'
                           )  # TODO: incorrect...
                frag.write(
                    'float compare = lpToDepth(ld, lightProj) - pointBias * 1.5;'
                )
                frag.write('#ifdef _InvY')
                frag.write('l.y = -l.y;')
                frag.write('#endif')
                if '_Legacy' in wrd.world_defs:
                    frag.write(
                        'visibility = float(texture(shadowMapPoint[0], vec3(-l + n * pointBias * 20)).r > compare);'
                    )
                else:
                    frag.write(
                        'visibility = texture(shadowMapPoint[0], vec4(-l + n * pointBias * 20, compare)).r;'
                    )
            frag.write('}')  # receiveShadow

        frag.write(
            'direct += basecol * dotNL * pointCol * attenuate(distance(wposition, pointPos)) * visibility;'
        )

    if '_Clusters' in wrd.world_defs:
        frag.add_include('std/light_mobile.glsl')
        frag.write('vec3 albedo = basecol;')
        frag.write('vec3 f0 = surfaceF0(basecol, metallic);')
        make_cluster.write(vert, frag)

    if '_Irr' in wrd.world_defs:
        frag.add_include('std/shirr.glsl')
        frag.add_uniform('vec4 shirr[7]', link='_envmapIrradiance')
        env_str = 'shIrradiance(n, shirr)'
    else:
        env_str = '0.5'

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

    if '_LDR' in wrd.world_defs:
        frag.write('fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / 2.2));')
Beispiel #4
0
def make_forward_mobile(con_mesh):
    wrd = bpy.data.worlds['Arm']
    vert = con_mesh.make_vert()
    frag = con_mesh.make_frag()
    geom = None
    tesc = None
    tese = None

    vert.add_uniform('mat3 N', '_normalMatrix')
    vert.write_attrib('vec4 spos = vec4(pos, 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));')