Example #1
0
    MaterialConstant ExtractMaterialData(Renderer _renderer, Material _mat)
    {
        MaterialConstant data = new MaterialConstant();

        data._Color               = _mat.color.linear;
        data._CustomSpecColor     = _mat.GetColor("_CustomSpecColor").linear;
        data._MainTex_ST          = new Vector4(_mat.mainTextureScale.x, _mat.mainTextureScale.y, _mat.mainTextureOffset.x, _mat.mainTextureOffset.y);
        data._EmissionColor       = _mat.GetColor("_EmissionColor").linear; // emission need to use linear, since it is HDR
        data._AlphaTestOn         = (_mat.renderQueue == (int)RenderQueue.AlphaTest) ? 1f : 0f;
        data._Cutoff              = _mat.GetFloat("_Cutoff");
        data._UseMetallicMap      = _mat.GetTexture("_MetallicGlossMap") ? 1f : 0f;
        data._GlossMapScale       = _mat.GetFloat("_GlossMapScale");
        data._Metallic            = _mat.GetFloat("_Metallic");
        data._Glossiness          = _mat.GetFloat("_Glossiness");
        data._AlphaAsColorMask    = _mat.GetFloat("_AlphaAsColorMask");
        data._AlbedoAsMask        = _mat.GetFloat("_AlbedoAsMask");
        data._BumpScale           = _mat.GetFloat("_BumpScale");
        data._ReflectionSmooth    = _mat.GetFloat("_ReflectionSmooth");
        data._OcclusionStrength   = _mat.GetFloat("_OcclusionStrength");
        data._SkyIntensity        = _mat.GetFloat("_SkyIntensity");
        data._AlbedoAlphaEmission = _mat.GetFloat("_AlbedoAlphaEmission");
        data._UseBumpMap          = _mat.GetTexture("_BumpMap") ? 1f : 0f;
        data._UseReflectionMask   = _mat.GetTexture("_ReflectionMask") ? 1f : 0f;
        data._SpecHighLightOff    = 1f - _mat.GetFloat("_SpecularHighlights");

        return(data);
    }
    public void CacheMaterial(Material _mat, MaterialConstant _mc)
    {
        int id = _mat.GetInstanceID();

        if (!materialCache.ContainsKey(id))
        {
            materialCache.Add(id, _mat);
        }
    }
    /// <summary>
    /// get material constant
    /// </summary>
    /// <param name="_mat"> mat </param>
    /// <returns> material constant </returns>
    public MaterialConstant GetMaterialConstant(Material _mat)
    {
        MaterialConstant mc = new MaterialConstant();

        // get diffuse
        int dummy = 0;

        SetupTexAndSampler(_mat, "_MainTex", ref mc._DiffuseIndex, ref mc._SamplerIndex, whiteTex);
        SetupTexAndSampler(_mat, "_SpecGlossMap", ref mc._SpecularIndex, ref dummy, blackTex);
        SetupTexAndSampler(_mat, "_OcclusionMap", ref mc._OcclusionIndex, ref dummy, whiteTex);
        SetupTexAndSampler(_mat, "_EmissionMap", ref mc._EmissionIndex, ref dummy, blackTex);
        SetupTexAndSampler(_mat, "_BumpMap", ref mc._NormalIndex, ref dummy, blackTex);
        SetupTexAndSampler(_mat, "_DetailMask", ref mc._DetailMaskIndex, ref dummy, whiteTex);
        SetupTexAndSampler(_mat, "_DetailAlbedoMap", ref mc._DetailAlbedoIndex, ref dummy, whiteTex);
        SetupTexAndSampler(_mat, "_DetailNormalMap", ref mc._DetailNormalIndex, ref dummy, blackTex);

        mc._MainTex_ST         = new Vector4(_mat.mainTextureScale.x, _mat.mainTextureScale.y, _mat.mainTextureOffset.x, _mat.mainTextureOffset.y);
        mc._DetailAlbedoMap_ST = new Vector4(_mat.GetTextureScale("_DetailAlbedoMap").x, _mat.GetTextureScale("_DetailAlbedoMap").y
                                             , _mat.GetTextureOffset("_DetailAlbedoMap").x, _mat.GetTextureOffset("_DetailAlbedoMap").y);
        if (_mat.HasProperty("_Cutoff"))
        {
            mc._CutOff = _mat.GetFloat("_Cutoff");
            if (_mat.renderQueue < 2226)
            {
                mc._CutOff = 0;
            }
        }

        // property
        mc._Color             = _mat.color.linear;
        mc._SpecColor         = _mat.GetColor("_SpecColor").linear;
        mc._Smoothness        = _mat.GetFloat("_Glossiness");
        mc._OcclusionStrength = _mat.GetFloat("_OcclusionStrength");
        mc._EmissionColor     = _mat.GetColor("_EmissionColor").linear;
        mc._BumpScale         = _mat.GetFloat("_BumpScale");
        mc._DetailBumpScale   = _mat.GetFloat("_DetailNormalMapScale");
        mc._DetailUV          = _mat.GetFloat("_UVSec");
        mc._ReflectionCount   = _mat.GetInt("_ReflectionCount");

        bool isCutOff      = (_mat.renderQueue <= (int)RenderQueue.GeometryLast) && (_mat.renderQueue >= 2226);
        bool isTransparent = (_mat.renderQueue > (int)RenderQueue.GeometryLast);

        if (isCutOff)
        {
            mc._RenderQueue = 1;
        }
        else if (isTransparent)
        {
            mc._RenderQueue = 2;
        }
        else
        {
            mc._RenderQueue = 0;
        }

        return(mc);
    }
    public void ExtractMaterialData(Material _mat, int _rendererID)
    {
        int  cullMode      = (_mat.HasProperty("_CullMode")) ? (int)_mat.GetFloat("_CullMode") : 2;
        int  srcBlend      = (_mat.HasProperty("_SrcBlend")) ? (int)_mat.GetFloat("_SrcBlend") : 1;
        int  dstBlend      = (_mat.HasProperty("_DstBlend")) ? (int)_mat.GetFloat("_DstBlend") : 0;
        bool isCutOff      = (_mat.renderQueue <= (int)RenderQueue.GeometryLast) && (_mat.renderQueue >= 2226);
        bool isTransparent = (_mat.renderQueue > (int)RenderQueue.GeometryLast);

        List <string> macro = new List <string>();

        if (isCutOff)
        {
            macro.Add("_CUTOFF_ON");
        }

        if (isTransparent)
        {
            macro.Add("_TRANSPARENT_ON");
        }

        AddTexKeyword(_mat, ref macro, "_SpecGlossMap", "_SPEC_GLOSS_MAP");
        AddTexKeyword(_mat, ref macro, "_BumpMap", "_NORMAL_MAP");
        AddTexKeyword(_mat, ref macro, "_DetailAlbedoMap", "_DETAIL_MAP");
        AddTexKeyword(_mat, ref macro, "_DetailNormalMap", "_DETAIL_NORMAL_MAP");

        bool shouldEmissionBeEnabled = (_mat.globalIlluminationFlags & MaterialGlobalIlluminationFlags.EmissiveIsBlack) == 0;

        if (shouldEmissionBeEnabled)
        {
            macro.Add("_EMISSION");
        }

        if (_mat.GetFloat("_UseFresnel") > 0)
        {
            macro.Add("_FRESNEL_EFFECT");
        }

        AddNativeMaterial(_rendererID, _mat.GetInstanceID(), _mat.renderQueue, cullMode, srcBlend, dstBlend, "ForwardPass.hlsl", macro.Count, macro.ToArray());
        macro.Clear();

        // cache and update props
        if (!HasMaterial(_mat))
        {
            MaterialConstant mc = GetMaterialConstant(_mat);
            UpdateNativeMaterialProp(_mat.GetInstanceID(), (uint)matConstantSize, mc);
            CacheMaterial(_mat, mc);
        }
    }
Example #5
0
 static extern void UpdateNativeMaterialProp(int _instanceID, uint _byteSize, MaterialConstant _mc);
Example #6
0
    void CacheMesh()
    {
        materialProps = new Dictionary <int, MaterialConstant>();

        // create default texture
        whiteTexture      = new Texture2D(16, 16, TextureFormat.ARGB32, true);
        whiteTexture.name = "White Texture";

        Color[] c = new Color[256];
        for (int i = 0; i < 256; i++)
        {
            c[i] = Color.white;
        }
        whiteTexture.SetPixels(c);
        whiteTexture.Apply(true, true);

        for (int i = 0; i < renderGroup.Count; i++)
        {
            for (int j = 0; j < renderGroup[i].renderers.Count; j++)
            {
                Renderer renderer = renderGroup[i].renderers[j];

                if (HasTransparent(renderer))
                {
                    // skip model contains transparent object
                    continue;
                }

                MeshFilter mf = renderer.GetComponent <MeshFilter>();
                if (!mf || mf.sharedMesh.vertexBufferCount > 1)
                {
                    continue;
                }
                Mesh staticMesh = mf.sharedMesh;

                uint[] indexCount = new uint[staticMesh.subMeshCount];
                uint[] indexStart = new uint[staticMesh.subMeshCount];
                int[]  baseVertex = new int[staticMesh.subMeshCount];

                for (int k = 0; k < staticMesh.subMeshCount; k++)
                {
                    indexCount[k] = staticMesh.GetIndexCount(k);
                    indexStart[k] = staticMesh.GetIndexStart(k);
                    baseVertex[k] = (int)staticMesh.GetBaseVertex(k);
                }

                // add 1st vertex buffer only
                // add stride-56 mesh only (position+normal+uv0+uv1+tangent = 56 bytes)
                if (!AddMesh(staticMesh.GetInstanceID(), staticMesh.GetNativeVertexBufferPtr(0), staticMesh.GetNativeIndexBufferPtr(), staticMesh.vertexCount, staticMesh.subMeshCount, VertexStride, indexCount, indexStart, baseVertex))
                {
                    continue;
                }

                // add material if add mesh successfully
                if (renderer && renderer.enabled)
                {
                    int[] matId = new int[staticMesh.subMeshCount];

                    for (int k = 0; k < staticMesh.subMeshCount; k++)
                    {
                        // add used material id
                        matId[k] = renderer.sharedMaterials[k].GetInstanceID();
                        if (materialProps.ContainsKey(renderer.sharedMaterials[k].GetInstanceID()))
                        {
                            continue;
                        }

                        // extract material data
                        MaterialConstant data = ExtractMaterialData(renderer, renderer.sharedMaterials[k]);
                        Material         mat  = renderer.sharedMaterials[k];

                        // add texture to native, total in 8
                        List <int> texId = new List <int>();
                        texId.Add(ExtractTexture(mat.GetTexture("_MainTex") as Texture2D));
                        texId.Add(ExtractTexture(mat.GetTexture("_BumpMap") as Texture2D));
                        texId.Add(ExtractTexture(mat.GetTexture("_MetallicGlossMap") as Texture2D));
                        texId.Add(ExtractTexture(mat.GetTexture("_ReflectionMask") as Texture2D));
                        texId.Add(ExtractTexture(mat.GetTexture("_OcclusionMap") as Texture2D));
                        texId.Add(ExtractTexture(mat.GetTexture("_EmissionMap") as Texture2D));

                        int  queue    = (renderer.sharedMaterials[k].renderQueue == (int)RenderQueue.Geometry) ? 0 : 1;
                        bool matValid = AddMaterial(renderer.sharedMaterials[k].GetInstanceID(), Marshal.SizeOf(typeof(MaterialConstant)), texId.Count, queue, texId.ToArray());
                        texId.Clear();

                        if (matValid)
                        {
                            materialProps.Add(renderer.sharedMaterials[k].GetInstanceID(), data);
                        }
                        else
                        {
                            Debug.LogError("Add material failed.");
                        }
                    }

                    // extract lightmap here since it is used by renderer not materials
                    bool         hasLightMap  = renderer.lightmapIndex >= 0 && renderer.lightmapIndex < LightmapSettings.lightmaps.Length;
                    LightmapData lightMapData = (hasLightMap) ? LightmapSettings.lightmaps[renderer.lightmapIndex] : new LightmapData();
                    int[]        lightmapId   = new int[2];
                    lightmapId[0] = ExtractTexture(lightMapData.lightmapColor);
                    lightmapId[1] = ExtractTexture(lightMapData.shadowMask);

                    AddRenderer(Matrix4x4ToFloat16(renderer.localToWorldMatrix)
                                , Matrix4x4ToFloat16(renderer.worldToLocalMatrix)
                                , VectorToFloat4(renderer.lightmapScaleOffset)
                                , renderer.GetInstanceID()
                                , staticMesh.GetInstanceID()
                                , matId
                                , lightmapId
                                , i);

                    renderer.gameObject.layer = LayerMask.NameToLayer("NativeRenderer"); // mark as native renderer
                }
            }
        }
    }