/// <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); } }
public void Start() { this.master = this.GetComponent<TressFX> (); this.mat = new Material (this.shader); }
/// <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); }
/// <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 (); }
/// <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; } }
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"); }