예제 #1
0
    /// <summary>
    /// This function will generate the vertice and strand index buffers used for initializing TressFX.
    /// </summary>
    public void Start()
    {
        // Declare lists for vertices and strand indices which will get passed to TressFX
        List <TressFXStrand> strands = new List <TressFXStrand>();

        int vertexCount = 0;

        // Load all hair files
        for (int i = 0; i < this.hairs.Length; i++)
        {
            Debug.Log("Loading hair " + i);
            vertexCount += this.LoadHairTFX(this.hairs[i].hairModel.text, strands, i);
        }

        // Tress fx loaded!
        TressFX tressFx = this.GetComponent <TressFX>();

        if (tressFx != null)
        {
            tressFx.Initialize(strands.ToArray(), vertexCount, this.hairs.Length);
        }
    }
예제 #2
0
 public void Start()
 {
     this.master = this.GetComponent<TressFX> ();
     this.mat = new Material (this.shader);
 }
예제 #3
0
    /// <summary>
    /// This loads the kernel ids from the compute buffer and also sets it's TressFX master.
    /// </summary>
    public void Initialize(float[] hairRestLengths, Vector3[] referenceVectors, int[] verticesOffsets,
                           Quaternion[] localRotations, Quaternion[] globalRotations)
    {
        this.master = this.GetComponent <TressFX>();

        // Initialize config values
        this.globalStiffness = new float[this.master.hairData.Length];
        this.globalStiffnessMatchingRange = new float[this.master.hairData.Length];
        this.localStiffness  = new float[this.master.hairData.Length];
        this.damping         = new float[this.master.hairData.Length];
        this.lastModelMatrix = Matrix4x4.TRS(this.transform.position, this.transform.rotation, Vector3.one);

        // Load config
        for (int i = 0; i < this.master.hairData.Length; i++)
        {
            this.globalStiffness[i] = this.master.hairData[i].globalStiffness;
            this.globalStiffnessMatchingRange[i] = this.master.hairData[i].globalStiffnessMatchingRange;

            // 1.0 for stiffness makes things unstable sometimes.
            if (this.localStiffness[i] >= 0.95f)
            {
                this.localStiffness[i] = 0.95f;
            }

            this.localStiffness[i] = this.master.hairData[i].localStiffness;


            this.damping[i] = this.master.hairData[i].damping;
        }

        if (this.master == null)
        {
            Debug.LogError("TressFXSimulation doesnt have a master (TressFX)!");
        }

        // Initialize compute shader kernels
        this.IntegrationAndGlobalShapeConstraintsKernelId = this.HairSimulationShader.FindKernel("IntegrationAndGlobalShapeConstraints");
        this.LocalShapeConstraintsKernelId    = this.HairSimulationShader.FindKernel("LocalShapeConstraints");
        this.LengthConstraintsAndWindKernelId = this.HairSimulationShader.FindKernel("LengthConstraintsAndWind");
        this.CollisionAndTangentsKernelId     = this.HairSimulationShader.FindKernel("CollisionAndTangents");
        this.SkipSimulationKernelId           = this.HairSimulationShader.FindKernel("SkipSimulateHair");


        // Set length buffer
        this.hairLengthsBuffer = new ComputeBuffer(hairRestLengths.Length, 4);
        this.hairLengthsBuffer.SetData(hairRestLengths);

        // Set rotation buffers
        this.globalRotationBuffer = new ComputeBuffer(globalRotations.Length, 16);
        this.localRotationBuffer  = new ComputeBuffer(localRotations.Length, 16);

        this.globalRotationBuffer.SetData(globalRotations);
        this.localRotationBuffer.SetData(localRotations);

        // Set reference buffers
        this.referenceBuffer = new ComputeBuffer(referenceVectors.Length, 12);
        this.referenceBuffer.SetData(referenceVectors);

        // Set offset buffer
        this.verticeOffsetBuffer = new ComputeBuffer(verticesOffsets.Length, 4);
        this.verticeOffsetBuffer.SetData(verticesOffsets);

        // Generate config buffer
        TressFXHairConfig[] hairConfig = new TressFXHairConfig[this.globalStiffness.Length];

        for (int i = 0; i < this.globalStiffness.Length; i++)
        {
            hairConfig[i] = new TressFXHairConfig();
            hairConfig[i].globalStiffness = this.globalStiffness[i];
            hairConfig[i].globalStiffnessMatchingRange = this.globalStiffnessMatchingRange[i];
            hairConfig[i].localStiffness = this.localStiffness[i];
            hairConfig[i].damping        = this.damping[i];
        }

        this.configBuffer = new ComputeBuffer(hairConfig.Length, 16);
        this.configBuffer.SetData(hairConfig);

        // Initialize simulation
        this.InitializeColliders();
        this.SetResources();
        Vector3 pos = this.transform.position;

        this.transform.position = Vector3.zero;
        this.HairSimulationShader.Dispatch(this.SkipSimulationKernelId, this.master.vertexCount, 1, 1);

        this.transform.position = pos;
        this.HairSimulationShader.Dispatch(this.SkipSimulationKernelId, this.master.vertexCount, 1, 1);
    }
예제 #4
0
    /// <summary>
    /// Start this instance.
    /// Initializes the hair material and all other resources.
    /// </summary>
    public void Start()
    {
        this.hairMaterial = new Material (this.hairShader);

        // Get TressFX master
        this.master = this.GetComponent<TressFX> ();

        // Set triangle indices buffer
        this.g_TriangleIndicesBuffer = new ComputeBuffer (this.master.hairData.m_TriangleIndices.Length, 4);
        this.g_TriangleIndicesBuffer.SetData (this.master.hairData.m_TriangleIndices);

        // Initialize linked list
        this.LinkedListHead = new RenderTexture (Screen.width, Screen.height, 0, RenderTextureFormat.ARGB32);
        this.LinkedListHead.filterMode = FilterMode.Point;
        this.LinkedListHead.enableRandomWrite = true;
        this.LinkedListHead.hideFlags = HideFlags.HideAndDontSave;
        this.LinkedListHead.Create ();

        this.LinkedList = new ComputeBuffer (this.totalHairLayers * Screen.width * Screen.height, 24, ComputeBufferType.Counter);

        // Generate triangle meshes
        this.triangleMeshes = this.GenerateTriangleMeshes ();

        // Create render bounds
        this.renderingBounds = new Bounds (this.master.hairData.m_bSphere.center, new Vector3(this.master.hairData.m_bSphere.radius, this.master.hairData.m_bSphere.radius, this.master.hairData.m_bSphere.radius));

        // Initialize fragment sorter
        this.finalRenderTexture = new RenderTexture (Screen.width, Screen.height, 0, RenderTextureFormat.ARGB32);
        this.finalRenderTexture.filterMode = FilterMode.Point;
        this.finalRenderTexture.enableRandomWrite = true;
        this.finalRenderTexture.hideFlags = HideFlags.HideAndDontSave;
        this.finalRenderTexture.Create ();

        this.SortFragmentsKernelId = this.fragmentSortingShader.FindKernel ("SortFragments");

        // Initialize shadow material
        this.shadowMaterial = new Material (this.shadowShader);

        this.lineMeshes = this.GenerateLineMeshes ();
    }
예제 #5
0
    /// <summary>
    /// Initialize this instance.
    /// Generates the l
    /// </summary>
    public virtual void Initialize()
    {
        this.master = this.gameObject.GetComponent <TressFX> ();

        // Get materials
        this.hairMaterial = new Material[this.master.hairData.Length];
        for (int i = 0; i < this.hairMaterial.Length; i++)
        {
            this.hairMaterial[i] = this.master.hairData[i].hairMaterial;
        }

        // Calculate mesh bounds
        Vector3 addedVertices    = Vector3.zero;
        float   highestXDistance = 0;
        float   highestYDistance = 0;
        float   highestZDistance = 0;
        float   lowestXDistance  = 100;
        float   lowestYDistance  = 100;
        float   lowestZDistance  = 100;
        int     vertices         = 0;
        int     indexCounter     = 0;
        int     lineIndexCounter = 0;
        int     vertexCounter    = 0;

        MeshBuilder meshBuilder     = new MeshBuilder(MeshTopology.Triangles);
        MeshBuilder lineMeshBuilder = new MeshBuilder(MeshTopology.Lines);

        // Initialize meshes list
        List <Mesh[]> meshList = new List <Mesh[]>();

        int lastHairId = 0;

        // Add all vertices to a vector for calculating the center point
        for (int sI = 0; sI < this.master.strands.Length; sI++)
        {
            List <Vector3> meshVertices     = new List <Vector3>();
            List <Vector2> meshUvs          = new List <Vector2>();
            List <int>     meshIndices      = new List <int>();
            List <Vector3> lineMeshVertices = new List <Vector3>();
            List <int>     lineMeshIndices  = new List <int>();
            List <Vector2> lineMeshUvs      = new List <Vector2>();

            // Reset index counter?
            if (!meshBuilder.HasSpace(this.master.strands[sI].vertices.Length * 6))
            {
                indexCounter = 0;
            }
            if (!lineMeshBuilder.HasSpace(this.master.strands[sI].vertices.Length))
            {
                lineIndexCounter = 0;
            }

            if (lastHairId != this.master.strands[sI].hairId)
            {
                indexCounter = 0;
                meshList.Add(meshBuilder.GetMeshes());
                meshBuilder = new MeshBuilder(MeshTopology.Triangles);
            }

            for (int vI = 0; vI < this.master.strands[sI].vertices.Length; vI++)
            {
                Vector3 vertexPos = this.master.strands[sI].vertices[vI].pos;
                addedVertices += vertexPos;

                // Highest distances
                if (Mathf.Abs(vertexPos.x) > highestXDistance)
                {
                    highestXDistance = Mathf.Abs(vertexPos.x);
                }
                if (Mathf.Abs(vertexPos.y) > highestYDistance)
                {
                    highestYDistance = Mathf.Abs(vertexPos.y);
                }
                if (Mathf.Abs(vertexPos.z) > highestZDistance)
                {
                    highestZDistance = Mathf.Abs(vertexPos.z);
                }

                // Lowest dists
                if (Mathf.Abs(vertexPos.x) < lowestXDistance)
                {
                    lowestXDistance = Mathf.Abs(vertexPos.x);
                }
                if (Mathf.Abs(vertexPos.y) < lowestYDistance)
                {
                    lowestYDistance = Mathf.Abs(vertexPos.y);
                }
                if (Mathf.Abs(vertexPos.z) < lowestZDistance)
                {
                    lowestZDistance = Mathf.Abs(vertexPos.z);
                }

                // Add mesh data
                Vector3[] triangleVertices = new Vector3[] { new Vector3(vertexCounter, 0, 0), new Vector3(vertexCounter + 1, 0, 0), new Vector3(vertexCounter + 2, 0, 0), new Vector3(vertexCounter + 3, 0, 0), new Vector3(vertexCounter + 4, 0, 0), new Vector3(vertexCounter + 5, 0, 0) };

                for (int i = 0; i < triangleVertices.Length; i++)
                {
                    int localVertexId = this.master.MapTriangleIndexIdToStrandVertexId((int)triangleVertices[i].x);

                    // ... No comment
                    if (localVertexId >= this.master.strands[sI].vertices.Length)
                    {
                        localVertexId = this.master.strands[sI].vertices.Length - 1;
                    }

                    meshUvs.Add(new Vector2(this.master.strands[sI].vertices[localVertexId].texcoords.x, this.master.strands[sI].vertices[localVertexId].texcoords.y));
                }

                meshVertices.AddRange(triangleVertices);
                meshIndices.AddRange(new int[] { indexCounter, indexCounter + 1, indexCounter + 2, indexCounter + 3, indexCounter + 4, indexCounter + 5 });

                lineMeshVertices.Add(new Vector3(vertices, 0, 0));
                lineMeshUvs.Add(new Vector2(this.master.strands[sI].vertices[vI].texcoords.x, this.master.strands[sI].vertices[vI].texcoords.y));

                if (/*vI == 0 || */ this.master.strands[sI].vertices.Length - 1 == vI)
                {
                    // First or last index, so only one index
                    lineMeshIndices.AddRange(new int[] { lineIndexCounter - 1, lineIndexCounter });
                }
                else
                {
                    lineMeshIndices.AddRange(new int[] { lineIndexCounter, lineIndexCounter + 1 });
                }

                indexCounter  += 6;
                vertexCounter += 6;
                lastHairId     = this.master.strands[sI].hairId;

                lineIndexCounter++;
                vertices++;
            }

            // Add to mesh builder
            meshBuilder.AddVertices(meshVertices.ToArray(), meshIndices.ToArray(), meshUvs.ToArray());
            lineMeshBuilder.AddVertices(lineMeshVertices.ToArray(), lineMeshIndices.ToArray(), lineMeshUvs.ToArray());
        }

        this.meshBounds = new Bounds((addedVertices / vertices), new Vector3((highestXDistance - lowestXDistance), (highestYDistance - lowestYDistance), (highestZDistance - lowestZDistance)));

        // Initialize mesh rendering
        meshList.Add(meshBuilder.GetMeshes());
        this.lineMeshes = lineMeshBuilder.GetMeshes();
        this.meshes     = meshList;

        for (int i = 0; i < this.meshes.Count; i++)
        {
            for (int j = 0; j < this.meshes[i].Length; j++)
            {
                this.meshes[i][j].bounds = this.meshBounds;
            }
        }

        for (int i = 0; i < this.lineMeshes.Length; i++)
        {
            this.lineMeshes[i].bounds = this.meshBounds;
        }
    }
예제 #6
0
    public void Start()
    {
        // No shader? :-(
        if (this.simulationShader == null)
        {
            Debug.LogError ("No simulation shader attached to TressFXSimulation :-'(");
            this.enabled = false;
            return;
        }

        // Get master
        this.master = this.GetComponent<TressFX> ();

        if (this.master == null)
        {
            Debug.LogError ("No TressFX intance attached to TressFXSimulation's gameobject :'-(");
            this.enabled = false;
            return;
        }

        if (this.master.hairData.hairPartConfig.Length > maxHairSections)
        {
            Debug.LogError ("TressFX mesh has more hair sections than allowed :'-(");
            this.enabled = false;
            return;
        }

        // Get Kernel Ids
        this.IntegrationAndGlobalShapeConstraintsKernelId = this.simulationShader.FindKernel ("IntegrationAndGlobalShapeConstraints");
        this.LocalShapeConstraintsKernelId = this.simulationShader.FindKernel ("LocalShapeConstraints");
        this.LocalShapeConstraintsWithIterationKernelId = this.simulationShader.FindKernel ("LocalShapeConstraintsWithIteration");
        this.LengthConstriantsWindAndCollisionKernelId = this.simulationShader.FindKernel ("LengthConstriantsWindAndCollision");
        this.UpdateFollowHairVerticesKernelId = this.simulationShader.FindKernel ("UpdateFollowHairVertices");
        this.PrepareFollowHairBeforeTurningIntoGuideKernelId = this.simulationShader.FindKernel ("PrepareFollowHairBeforeTurningIntoGuide");
    }