public void Process() { stopwatch.Start(); if (neoFurAsset.mesh != lastRebuiltMeshSource) { hasPreviousLocalToWorldMatrix = false; Rebuild(); } //Any new filters that havent been rebuilt at least once need to be rebuilt. foreach (var filter in filterList) { if (!filter.hasRebuildOnce) { filter.Rebuild(); } } Shader.SetGlobalFloat("_NeoFur_DeltaTime", neoFurAsset.deltaTime); Shader.SetGlobalTexture("_NeoFur_PositionTexture", positionTexture); Shader.SetGlobalTexture("_NeoFur_NormalTexture", normalTexture); Shader.SetGlobalTexture("_NeoFur_TangentTexture", tangentTexture); Shader.SetGlobalTexture("_NeoFur_PreviousPositionTexture", previousPositionTexture); Matrix4x4 localToWorldMatrix = neoFurAsset.renderer.localToWorldMatrix; Matrix4x4 worldToLocalMatrix = neoFurAsset.renderer.worldToLocalMatrix; Shader.SetGlobalMatrix("_NeoFur_LocalToWorldMatrix", localToWorldMatrix); Shader.SetGlobalMatrix("_NeoFur_PreviousLocalToWorldMatrix", previousLocalToWorldMatrix); Shader.SetGlobalMatrix("_NeoFur_WorldToLocalMatrix", worldToLocalMatrix); Shader.SetGlobalFloat("_NeoFur_ShellDistance", neoFurAsset.ShellDistanceInMeters); VertexProcessorUtility.CopyTexture(positionTexture, previousPositionTexture); VertexProcessorUtility.CopyTexture(basePositionTextureResource.value, positionTexture); VertexProcessorUtility.CopyTexture(baseNormalTextureResource.value, normalTexture); VertexProcessorUtility.CopyTexture(baseTangentTextureResource.value, tangentTexture); foreach (var filter in filterList) { filter.Process(); } previousLocalToWorldMatrix = localToWorldMatrix; stopwatch.Stop(); lastProcessTime = (float)((double)stopwatch.ElapsedTicks / System.Diagnostics.Stopwatch.Frequency); stopwatch.Reset(); averageProcessTime = Mathf.Lerp(averageProcessTime, lastProcessTime, 0.01f); }
public void Rebuild() { DestroyResources(); if (!neoFurAsset.mesh) { return; } baseResourceKey = neoFurAsset.mesh.GetInstanceID().ToString() + "_" + neoFurAsset.data.furSubMeshIndex; optimizedVertexMapResource = VertexProcessorCache.GetResource <List <int> >(baseResourceKey + "_OptimizedVertexMapResource"); if (optimizedVertexMapResource.value == null) { optimizedVertexMapResource.value = new List <int>(neoFurAsset.mesh.vertexCount); } unpackedMeshResource = VertexProcessorCache.GetResource <UnpackedMesh>(baseResourceKey + "_UnpackedMesh"); if (unpackedMeshResource.value == null) { optimizedVertexMapResource.value.Clear(); unpackedMeshResource.value = VertexProcessorUtility.CreateOptimizedMesh(neoFurAsset.mesh, neoFurAsset.data.furSubMeshIndex, optimizedVertexMapResource.value); } int width; int height; VertexProcessorUtility.CalculateVertexTextureSize(unpackedMeshResource.value.vertices.Length, out width, out height); basePositionTextureResource = VertexProcessorCache.GetResource <Texture2D>(baseResourceKey + "_BasePositionTexture"); if (basePositionTextureResource.value == null) { basePositionTextureResource.value = new Texture2D(width, height, VertexProcessorUtility.float4TextureFormat, false); basePositionTextureResource.value.filterMode = FilterMode.Point; } baseNormalTextureResource = VertexProcessorCache.GetResource <Texture2D>(baseResourceKey + "_BaseNormalTexture"); if (baseNormalTextureResource.value == null) { baseNormalTextureResource.value = new Texture2D(width, height, VertexProcessorUtility.float4TextureFormat, false); baseNormalTextureResource.value.filterMode = FilterMode.Point; } baseTangentTextureResource = VertexProcessorCache.GetResource <Texture2D>(baseResourceKey + "_BaseTangentTexture"); if (baseTangentTextureResource.value == null) { baseTangentTextureResource.value = new Texture2D(width, height, VertexProcessorUtility.float4TextureFormat, false); baseTangentTextureResource.value.filterMode = FilterMode.Point; } positionTexture = new RenderTexture(width, height, 0, VertexProcessorUtility.float4RenderTextureFormat); positionTexture.filterMode = FilterMode.Point; positionTexture.Create(); normalTexture = new RenderTexture(width, height, 0, VertexProcessorUtility.float4RenderTextureFormat); normalTexture.filterMode = FilterMode.Point; normalTexture.Create(); tangentTexture = new RenderTexture(width, height, 0, VertexProcessorUtility.float4RenderTextureFormat); tangentTexture.filterMode = FilterMode.Point; tangentTexture.Create(); previousPositionTexture = new RenderTexture(width, height, 0, VertexProcessorUtility.float4RenderTextureFormat); previousPositionTexture.filterMode = FilterMode.Point; previousPositionTexture.Create(); //Vector3[] vertices = mesh.vertices; //Vector3[] normals = mesh.normals; //Vector4[] tangents = mesh.tangents; //Vector2[] uv1 = mesh.uv2; if (unpackedMeshResource.value.uv1s == null || unpackedMeshResource.value.uv1s.Length == 0) { unpackedMeshResource.value.uv1s = new Vector2[unpackedMeshResource.value.vertices.Length]; } Color[] positionPixels = new Color[width * height]; Color[] normalPixels = new Color[width * height]; Color[] tangentPixels = new Color[width * height]; /* * // get CPs and add to dictionary * for (int i = 0; i < unpackedMesh.vertices.Length; i++) * { * if (!vec3ToVertIndexMap.ContainsKey(unpackedMesh.vertices[i])) * { * vec3ToVertIndexMap.Add(unpackedMesh.vertices[i], i); * } * } * * cpIndexToVertIndex = new int[vec3ToVertIndexMap.Count]; * * { * int i = 0; * * foreach (var item in vec3ToVertIndexMap) * { * cpIndexToVertIndex[i] = item.Value; ++i; * } * } */ for (int i = 0; i < unpackedMeshResource.value.vertices.Length; i++) { int y = i / width; int x = i % width; Vector3 vertex = unpackedMeshResource.value.vertices[i]; Vector3 normal = unpackedMeshResource.value.normals[i]; Vector4 tangent = unpackedMeshResource.value.tangents[i]; Color positionColor = new Color(vertex.x, vertex.y, vertex.z, 1); Color normalColor = new Color(normal.x, normal.y, normal.z, 1); Color tangentColor = new Color(tangent.x, tangent.y, tangent.z, 1); positionPixels[i] = positionColor; normalPixels[i] = normalColor; tangentPixels[i] = tangentColor; unpackedMeshResource.value.uv1s[i] = new Vector2((x + 0.5f) / width, (y + 0.5f) / height); } meshResource = VertexProcessorCache.GetResource <Mesh>(baseResourceKey + "_Mesh"); if (meshResource.value == null) { meshResource.value = unpackedMeshResource.value.ToMesh(); meshResource.value.hideFlags = HideFlags.DontSave; meshResource.value.bounds = neoFurAsset.mesh.bounds; } basePositionTextureResource.value.SetPixels(positionPixels); baseNormalTextureResource.value.SetPixels(normalPixels); baseTangentTextureResource.value.SetPixels(tangentPixels); basePositionTextureResource.value.Apply(); baseNormalTextureResource.value.Apply(); baseTangentTextureResource.value.Apply(); //All filters need to be rebuilt. foreach (var filter in filterList) { filter.Rebuild(); } lastRebuiltMeshSource = neoFurAsset.mesh; }