void Update() { if (texture == null) { texture = GrassManipulationUtility.GetGrassTexture(transform, false); } Color[] pixels = texture.GetPixels(); for (int i = 0; i < pixels.Length; i++) { pixels[i] = Color.Lerp(pixels[i], originalColor, regenerationSpeed * Time.deltaTime); } texture.SetPixels(pixels); //Search for texture updater, which prevents multiply applys per frame (for multiple displacers) TextureUpdater updater = GetComponent <TextureUpdater>(); if (updater == null) { updater = gameObject.AddComponent <TextureUpdater>(); updater.targetTexture = texture; } updater.RequestTextureUpdate(); }
private void RoundDisplacement() { Vector2 texCoord, texForward, texRight, inverseTexForward, inverseTexRight; Vector3 rayOrigin = transform.TransformPoint(offset); Transform target = GrassManipulationUtility.GetWorldToTextureSpaceMatrix(rayOrigin, rayDirection, maxDistance, 0.1f, grassLayer, out texCoord, out texForward, out texRight); if (target == null) { return; } //Get texture of grass object var tex = GrassManipulationUtility.GetGrassTexture(target, false); //Invert the 2x2 world to texture space matrix. GrassManipulationUtility.Invert2x2Matrix(texForward, texRight, out inverseTexForward, out inverseTexRight); inverseTexForward.Normalize(); inverseTexRight.Normalize(); //Convert the world space radius to a pixel radius in texture space. This requires square textures. int pixelRadius = (int)(radius * texForward.magnitude * tex.width); //Calculate the pixel coordinates of the point where the raycast hit the texture. Vector2 mid = new Vector2(texCoord.x * tex.width, texCoord.y * tex.height); //Calculate the pixel area where the texture will be changed int targetX = (int)(mid.x - pixelRadius); int targetY = (int)(mid.y - pixelRadius); int rectX = Mathf.Clamp(targetX, 0, tex.width); int rectY = Mathf.Clamp(targetY, 0, tex.height); int width = Mathf.Min(targetX + pixelRadius * 2, tex.width) - targetX; int height = Mathf.Min(targetY + pixelRadius * 2, tex.height) - targetY; mid -= new Vector2(rectX, rectY); //Get pixels Color[] pixels = tex.GetPixels(rectX, rectY, width, height); Vector3 forward = transform.forward; //Iterate trough all pixels for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { var pixel = pixels[x + y * width]; Vector2 dir = (new Vector2(x, y) - mid) / pixelRadius; //Texture space to world space dir = dir.x * inverseTexRight + dir.y * inverseTexForward; float pressure = 1 - pressureStrength * CalcFalloff(dir.magnitude, pressureFalloff); //Check angle and pressure threshold Vector2 characterForward = new Vector2(forward.x, forward.z); if (pixel.b > pressureThreshold && Vector2.Angle(dir, characterForward) < maxAngle) { Vector2 displacementDir; if (directionalDisplacement) { var temp = transform.position - lastPosition; displacementDir = new Vector2(temp.x, temp.z); } else { displacementDir = dir; } float falloff = CalcFalloff(dir.magnitude, displacementFalloff); //Falloff and strength dir = displacementDir.normalized * falloff * displacementStrength; //To color space dir = GrassManipulationUtility.VectorToColorSpace(dir); Color newColor = new Color(dir.x, dir.y, pressure, 1); //Adds the new color to the pixel array pixels[x + y * width] = blendChanges ? Color.Lerp(pixels[x + y * width], newColor, Time.deltaTime * blendSpeed) : newColor; } } } //Save pixels and apply them to the texture tex.SetPixels(rectX, rectY, width, height, pixels); //Search for texture updater, which prevents multiply applys per frame (for multiple displacers) TextureUpdater updater = target.GetComponent <TextureUpdater>(); if (updater == null) { updater = target.gameObject.AddComponent <TextureUpdater>(); updater.targetTexture = tex; } updater.RequestTextureUpdate(); }