示例#1
0
        private void ProcessBoneWeights()
        {
            // bake bone matrices
            if (_tempColorBuffer == null || _tempColorBuffer.Length != bones.Length * 4)
            {
                _tempColorBuffer  = new Color[bones.Length * 4];
                _tempMatrixBuffer = new Matrix4x4[bones.Length];
            }
            for (int i = 0; i < bindPoses.Length; ++i)
            {
                Matrix4x4 bindPose     = bindPoses[i];
                Matrix4x4 boneMatrix   = bones[i].localToWorldMatrix;
                Matrix4x4 outputMatrix = localTransformInverse * boneMatrix * bindPose;
                _tempMatrixBuffer[i] = outputMatrix;
            }
            VertexProcessorUtility.MatrixArrayToColorArray(_tempMatrixBuffer, _tempColorBuffer);

            boneMatrixTexture.SetPixels(_tempColorBuffer);

            boneMatrixTexture.Apply();

            // set texture
            boneMaterial.SetTexture("_NeoFur_BoneMatrixTexture", boneMatrixTexture);
        }
示例#2
0
        protected override void OnProcess()
        {
            base.OnProcess();

            physicsMaterial.SetTexture("_NeoFur_PhysicsPositionTexture", positionTexture);
            physicsMaterial.SetTexture("_NeoFur_PhysicsVelocityTexture", velocityTexture);
            physicsMaterial.SetTexture("_NeoFur_PhysicsGuideTexture", guideTextureResource.value);

            physicsMaterial.SetVector("_NeoFur_PhysicsGravityVector", Physics.gravity * processor.neoFurAsset.physParams.GravityInfluence);

            physicsMaterial.SetFloat("_NeoFur_SpringLengthStiffness", processor.neoFurAsset.physParams.SpringLengthStiffnessInUnityUnits * 10);
            physicsMaterial.SetFloat("_NeoFur_SpringAngleStiffness", processor.neoFurAsset.physParams.SpringLengthStiffnessInUnityUnits * 10);

            physicsMaterial.SetFloat("_NeoFur_SpringMultiplyer", processor.neoFurAsset.physParams.SpringDampeningMultiplier);
            physicsMaterial.SetFloat("_NeoFur_AirResistanceMultiplyer", processor.neoFurAsset.physParams.AirResistanceMultiplier);

            Vector4 constraints = new Vector4(processor.neoFurAsset.physParams.MinStretchDistanceMultiplier, processor.neoFurAsset.physParams.MaxStretchDistanceMultiplier, processor.neoFurAsset.physParams.MaxRotationFromNormal);

            physicsMaterial.SetVector("_NeoFur_MinMaxConstraints", constraints);

            RenderTexture positionSwap = RenderTexture.GetTemporary(positionTexture.width, positionTexture.height, positionTexture.depth, positionTexture.format);

            positionSwap.filterMode = FilterMode.Point;

            RenderTexture velocitySwap = RenderTexture.GetTemporary(velocityTexture.width, velocityTexture.height, velocityTexture.depth, velocityTexture.format);

            velocitySwap.filterMode = FilterMode.Point;

            //TODO: We could support multiple wind sources. Like how we support multiple radial forces
            FakeWind wind = processor.neoFurAsset.mFakeWind;

            if (wind != null)
            {
                Vector3 windVector = wind.GetDirection() * wind.GetForce();
                physicsMaterial.SetVector("_NeoFur_WindVector", windVector);
                physicsMaterial.SetFloat("_NeoFur_WindGustFactor", wind.GetGustFactor());
                physicsMaterial.SetFloat("_NeoFur_WindInfluence", processor.neoFurAsset.physParams.WindInfluence);
                Graphics.Blit(null, velocityTexture, physicsMaterial, windPassIndex);
            }

            if (radialForces.Count > 0)
            {
                physicsMaterial.SetFloat("_NeoFur_RadialForceInfluence", processor.neoFurAsset.physParams.RadialForceInfluence);
                foreach (var force in radialForces)
                {
                    physicsMaterial.SetVector("_NeoFur_RadialForcePosition", force.Origin);
                    physicsMaterial.SetFloat("_NeoFur_RadialForceRadius", force.Radius);
                    physicsMaterial.SetFloat("_NeoFur_RadialForcePower", force.Strength);

                    Graphics.Blit(null, velocityTexture, physicsMaterial, radialForcePassIndex);
                }
            }

            radialForces.Clear();

            targetBufferCache2x[0] = positionSwap.colorBuffer;
            targetBufferCache2x[1] = velocitySwap.colorBuffer;
            Graphics.SetRenderTarget(targetBufferCache2x, positionSwap.depthBuffer);
            Graphics.Blit(null, physicsMaterial, simulatePassIndex);

            Graphics.SetRenderTarget(null);

            VertexProcessorUtility.CopyTexture(positionSwap, positionTexture);
            VertexProcessorUtility.CopyTexture(velocitySwap, velocityTexture);

            if (isDx9)
            {
                if (targetBufferCache3x == null)
                {
                    targetBufferCache3x = new RenderBuffer[3];
                }

                RenderTexture tangentSwap = RenderTexture.GetTemporary(processor.tangentTexture.width, processor.tangentTexture.height, processor.tangentTexture.depth, processor.tangentTexture.format);
                tangentSwap.filterMode = FilterMode.Point;

                targetBufferCache3x[0] = positionSwap.colorBuffer;
                targetBufferCache3x[1] = velocitySwap.colorBuffer;
                targetBufferCache3x[2] = tangentSwap.colorBuffer;
                Graphics.SetRenderTarget(targetBufferCache3x, positionSwap.depthBuffer);
                Graphics.Blit(null, physicsMaterial, applyPositionPassIndex);

                VertexProcessorUtility.CopyTexture(positionSwap, processor.positionTexture);
                VertexProcessorUtility.CopyTexture(velocitySwap, processor.normalTexture);
                VertexProcessorUtility.CopyTexture(tangentSwap, processor.tangentTexture);

                Graphics.SetRenderTarget(null);

                RenderTexture.ReleaseTemporary(tangentSwap);
            }

            Graphics.SetRenderTarget(null);
            RenderTexture.ReleaseTemporary(positionSwap);
            RenderTexture.ReleaseTemporary(velocitySwap);
        }
示例#3
0
        protected override void OnRebuild()
        {
            base.OnRebuild();

            DestroyResources();

            int width  = processor.positionTexture.width;
            int height = processor.positionTexture.height;

            positionTexture            = new RenderTexture(width, height, 0, VertexProcessorUtility.float4RenderTextureFormat);
            positionTexture.filterMode = FilterMode.Point;
            positionTexture.Create();

            velocityTexture            = new RenderTexture(width, height, 0, VertexProcessorUtility.float4RenderTextureFormat);
            velocityTexture.filterMode = FilterMode.Point;
            velocityTexture.Create();

            float[] weights = processor.neoFurAsset.morphWeights;

            StringBuilder guideTextureKeySB = new StringBuilder();

            guideTextureKeySB.Append(processor.baseResourceKey);
            guideTextureKeySB.Append("_");
            guideTextureKeySB.Append(processor.neoFurAsset.data.guideMethod);
            guideTextureKeySB.Append("_");
            if (processor.neoFurAsset.data.guideMethod == NeoFurAssetData.GuideMethod.Morphs)
            {
                for (int i = 0; i < weights.Length; i++)
                {
                    guideTextureKeySB.Append(weights[i].ToString(CultureInfo.InvariantCulture));
                    if (i < weights.Length - 1)
                    {
                        guideTextureKeySB.Append("_");
                    }
                }
            }
            else if (processor.neoFurAsset.data.guideMethod == NeoFurAssetData.GuideMethod.Splines)
            {
                if (processor.neoFurAsset.SplineGuideData == null)
                {
                    guideTextureKeySB.Append("null");
                }
                else
                {
                    guideTextureKeySB.Append(processor.neoFurAsset.SplineGuideData.GetInstanceID().ToString());
                }
            }

            guideTextureKeySB.Append("_PhysicsGuideTexture");
            guideTextureResource = VertexProcessorCache.GetResource <Texture2D>(guideTextureKeySB.ToString());

            if (guideTextureResource.value == null)
            {
                if (processor.neoFurAsset.data.guideMethod == NeoFurAssetData.GuideMethod.Normals)
                {
                    DefaultToNormalGuides();
                }
                else if (processor.neoFurAsset.data.guideMethod == NeoFurAssetData.GuideMethod.Morphs)
                {
                    UnpackedMesh mesh = processor.unpackedMeshResource.value;

                    if (mesh.blendShapes.Count != weights.Length)
                    {
                        Debug.LogError("mesh.blendShapes.Count != weights.Length", processor.neoFurAsset.gameObject);

                        DefaultToNormalGuides();
                    }
                    else if (weights.Length > 0)
                    {
                        Color[] guideVectorColors = new Color[width * height];

                        for (int i = 0; i < weights.Length; i++)
                        {
                            float weight = weights[i] / 100.0f;
                            if (weight == 0)
                            {
                                continue;
                            }

                            UnpackedMesh.BlendShape blendShape = mesh.blendShapes[i];

                            for (int j = 0; j < mesh.vertices.Length; j++)
                            {
                                Vector3 guideVector = blendShape.deltaVertices[j] * weight;
                                guideVectorColors[j] += new Color(guideVector.x, guideVector.y, guideVector.z, 0);
                            }
                        }

                        for (int i = 0; i < mesh.tangents.Length; i++)
                        {
                            Vector3 normal  = mesh.normals[i];
                            Vector4 tangent = mesh.tangents[i];

                            Color   guideVectorColor = guideVectorColors[i];
                            Vector3 guideVector      = new Vector3(guideVectorColor.r, guideVectorColor.g, guideVectorColor.b);

                            Vector3 binormal          = Vector3.Cross(normal, tangent);
                            Vector3 tangentSpaceGuide = VertexProcessorUtility.ToTangentSpace(guideVector, normal, binormal, tangent);
                            guideVectorColors[i] = new Color(tangentSpaceGuide.x, tangentSpaceGuide.y, tangentSpaceGuide.z, 0);
                        }
                        guideTextureResource.value            = new Texture2D(width, height, VertexProcessorUtility.float4TextureFormat, false);
                        guideTextureResource.value.filterMode = FilterMode.Point;
                        guideTextureResource.value.SetPixels(guideVectorColors);
                        guideTextureResource.value.Apply();
                    }
                    else
                    {
                        DefaultToNormalGuides();
                    }
                }
                else if (processor.neoFurAsset.data.guideMethod == NeoFurAssetData.GuideMethod.Splines)
                {
                    NeoFur.Data.PreComputedGuideData splineData = processor.neoFurAsset.SplineGuideData;

                    if (splineData == null)
                    {
                        Debug.LogWarning("Guide mode set to Splines but no spline data file is loaded", processor.neoFurAsset.gameObject);
                        DefaultToNormalGuides();
                    }
                    else if (splineData.guides.Length == 0 || splineData.guides.Length != processor.unpackedMeshResource.value.vertices.Length)
                    {
                        Debug.Log("num guides = " + splineData.guides.Length + " num verts: " + width * height, processor.neoFurAsset.gameObject);
                        Debug.LogError("Submesh for NFA does not match submesh for Spline Data Asset", processor.neoFurAsset.gameObject);
                        DefaultToNormalGuides();
                    }
                    else
                    {
                        UnpackedMesh mesh = processor.unpackedMeshResource.value;

                        Color[] guideVectorColors = new Color[width * height];
                        for (int i = 0; i < splineData.guides.Length; i++)
                        {
                            Vector3 normal  = mesh.normals[i];
                            Vector4 tangent = mesh.tangents[i];

                            int     remappedIndex = processor.optimizedVertexMapResource.value[i];
                            Vector3 guideVector   = splineData.guides[remappedIndex];

                            Vector3 binormal          = Vector3.Cross(normal, tangent);
                            Vector3 tangentSpaceGuide = VertexProcessorUtility.ToTangentSpace(guideVector, normal, binormal, tangent);
                            guideVectorColors[i] = new Color(tangentSpaceGuide.x, tangentSpaceGuide.y, tangentSpaceGuide.z, 0);
                        }

                        guideTextureResource.value            = new Texture2D(width, height, VertexProcessorUtility.float4TextureFormat, false);
                        guideTextureResource.value.filterMode = FilterMode.Point;
                        guideTextureResource.value.SetPixels(guideVectorColors);
                        guideTextureResource.value.Apply();
                    }
                }
            }
        }
示例#4
0
        private void DoTheBlits()
        {
            // get temp RTs
            RenderTexture posRT =
                RenderTexture.GetTemporary(processor.positionTexture.width,
                                           processor.positionTexture.height,
                                           processor.positionTexture.depth,
                                           processor.positionTexture.format);

            posRT.filterMode = FilterMode.Point;

            RenderTexture normRT =
                RenderTexture.GetTemporary(processor.normalTexture.width,
                                           processor.normalTexture.height,
                                           processor.normalTexture.depth,
                                           processor.normalTexture.format);

            normRT.filterMode = FilterMode.Point;

            RenderTexture tanRT =
                RenderTexture.GetTemporary(processor.tangentTexture.width,
                                           processor.tangentTexture.height,
                                           processor.tangentTexture.depth,
                                           processor.tangentTexture.format);

            tanRT.filterMode = FilterMode.Point;

            // blit using bone material
            targetBufferCache[0] = posRT.colorBuffer;
            targetBufferCache[1] = normRT.colorBuffer;
            targetBufferCache[2] = tanRT.colorBuffer;

            Graphics.SetRenderTarget(targetBufferCache, posRT.depthBuffer);

            // process morphs
            if (bakedFurMorphResources != null)
            {
                for (int i = 0; i < bakedFurMorphResources.Length; ++i)
                {
                    BakedMorph bakedFurMorph = bakedFurMorphResources[i].value;

                    //use this weight for morph targets
                    float blendWeight = processor.neoFurAsset.skinnedMeshRenderer.GetBlendShapeWeight(i) / 100;

                    if (blendWeight == 0)
                    {
                        continue;
                    }

                    // set material properties
                    boneMaterial.SetFloat("_BlendWeight", blendWeight);
                    boneMaterial.SetTexture("_BlendPosOffsetTexture", bakedFurMorph.positionOffsetTexture);
                    boneMaterial.SetTexture("_BlendNormOffsetTexture", bakedFurMorph.normalOffsetTexture);
                    boneMaterial.SetTexture("_BlendTanOffsetTexture", bakedFurMorph.tangentOffsetTexture);

                    // blit using bone material
                    targetBufferCache[0] = posRT.colorBuffer;
                    targetBufferCache[1] = normRT.colorBuffer;
                    targetBufferCache[2] = tanRT.colorBuffer;

                    Graphics.SetRenderTarget(targetBufferCache, posRT.depthBuffer);

                    // blit to target buffer cache
                    Graphics.Blit(null, boneMaterial, 0);

                    // blit/copy target buffers to processor RTs
                    VertexProcessorUtility.CopyTexture(posRT, processor.positionTexture);
                    VertexProcessorUtility.CopyTexture(normRT, processor.normalTexture);
                    VertexProcessorUtility.CopyTexture(tanRT, processor.tangentTexture);
                }
            }

            ProcessBoneWeights();

            // blit using bone material
            targetBufferCache[0] = posRT.colorBuffer;
            targetBufferCache[1] = normRT.colorBuffer;
            targetBufferCache[2] = tanRT.colorBuffer;

            Graphics.SetRenderTarget(targetBufferCache, posRT.depthBuffer);

            // blit to target buffer cache
            Graphics.Blit(null, boneMaterial, 1);

            // blit/copy target buffers to processor RTs
            VertexProcessorUtility.CopyTexture(posRT, processor.positionTexture);
            VertexProcessorUtility.CopyTexture(normRT, processor.normalTexture);
            VertexProcessorUtility.CopyTexture(tanRT, processor.tangentTexture);

            // release temp RTs
            RenderTexture.ReleaseTemporary(posRT);
            RenderTexture.ReleaseTemporary(normRT);
            RenderTexture.ReleaseTemporary(tanRT);
        }