public override void Up(RenderTexture targetTexture, PaintParameters parameters) { if (UseWaterColor) { RenderTexture.ReleaseTemporary(_waterColorBuffer); } _lastParameters.Clear(); }
public override void Down(RenderTexture targetTexture, PaintParameters parameters, LayerManager layers) { if (UseWaterColor) { int width = Mathf.FloorToInt(targetTexture.width * WaterColorDownScale); int height = Mathf.FloorToInt(targetTexture.height * WaterColorDownScale); _waterColorBuffer = RenderTexture.GetTemporary(width, height, 0, RenderTextureFormat.ARGB32); Graphics.Blit(layers.CurrentLayer.RenderTexture, _waterColorBuffer, WaterColorProcessingMaterial, 0); BlurMaterial.SetTexture("_DiffusionTex", _diffusionTexture); BlurMaterial.SetVector("_DiffusionScale", new Vector2( width / _diffusionTexture.width, height / _diffusionTexture.height) * DiffusionScale); WaterColorProcessingMaterial.SetFloat("_Wetness", Wetness); WaterColorProcessingMaterial.SetFloat("_DryRate", DryRate); } }
public override void Move(RenderTexture targetTexture, PaintParameters parameters, Texture2D currentState) { // wear off // if (_lastParameters.Count > 0) // { // var color = currentState.GetPixel(Mathf.FloorToInt(parameters.Position.x), Mathf.FloorToInt(parameters.Position.y)); // parameters.Color = Color.Lerp(_lastParameters[0].Color, color, 0.01f); // } if (!UseWaterColor) { DrawStroke(targetTexture, parameters); return; } var tempTexture = RenderTexture.GetTemporary(_waterColorBuffer.descriptor); var blurredTexture = RenderTexture.GetTemporary(_waterColorBuffer.descriptor); var strokeTexture = RenderTexture.GetTemporary(_waterColorBuffer.descriptor); strokeTexture.Clear(Color.clear); // stroke DrawStroke(strokeTexture, parameters, WaterColorDownScale); WaterColorProcessingMaterial.SetTexture("_StrokeTex", strokeTexture); //WaterColorProcessingMaterial.SetFloat("_Wetness", Wetness); // blur Graphics.Blit(_waterColorBuffer, tempTexture, BlurMaterial, 0); Graphics.Blit(tempTexture, blurredTexture, BlurMaterial, 1); WaterColorProcessingMaterial.SetTexture("_BlurredTex", blurredTexture); // process Graphics.Blit(_waterColorBuffer, tempTexture, WaterColorProcessingMaterial, 1); Graphics.Blit(tempTexture, _waterColorBuffer); Graphics.Blit(tempTexture, targetTexture, WaterColorProcessingMaterial, 2); RenderTexture.ReleaseTemporary(strokeTexture); RenderTexture.ReleaseTemporary(tempTexture); RenderTexture.ReleaseTemporary(blurredTexture); }
public override void Down(RenderTexture targetTexture, PaintParameters parameters, LayerManager layers) { var sourceTexture = layers.TopMostLayer.RenderTexture; var width = sourceTexture.width; var height = sourceTexture.height; var texture = new Texture2D(width, height); sourceTexture.CopyToTexture(texture); var sourcePixels = texture.GetPixels32(); var maskPixels = new Color32[sourcePixels.Length]; var sourcePosition = parameters.Position; sourcePosition.Scale(new Vector2( (float)sourceTexture.width / targetTexture.width, (float)sourceTexture.height / targetTexture.height)); var intPosition = Vector2Int.FloorToInt(sourcePosition); FloodFill(sourcePixels, maskPixels, width, height, intPosition, parameters.Color); // TODO: Make optional: Dilate(maskPixels, width, height); texture.SetPixels32(maskPixels); texture.Apply(false); BrushMaterial.color = parameters.Color; var renderTexture = RenderTexture.GetTemporary(width, height, 0); Graphics.Blit(texture, renderTexture); //PaintUtils.GaussianBlur(renderTexture, 5f); Graphics.Blit(renderTexture, targetTexture, BrushMaterial); RenderTexture.ReleaseTemporary(renderTexture); Destroy(texture); }
public virtual void Move(RenderTexture targetTexture, PaintParameters parameters, Texture2D getCurrentState) { }
public virtual void Up(RenderTexture targetTexture, PaintParameters parameters) { }
public virtual void Down(RenderTexture targetTexture, PaintParameters parameters, LayerManager layers) { }
private void DrawStroke(RenderTexture targetTexture, PaintParameters current, float textureScale = 1f) { var previous = _lastParameters.Count > 0 ? _lastParameters[0] : current; var last = _lastParameters.Count > 1 ? _lastParameters[1] : previous; bool hasMoved = _lastParameters.Count > 0; var actualSpeed = Vector2.Distance(current.Position, previous.Position) / (Time.deltaTime * 1000f); // Smooth speed: current.Speed = Mathf.Lerp(previous.Speed, actualSpeed, 0.2f); var brushSize = current.BrushSize; float angle = Angle; float roundness = Roundness; if (BrushTexture != null) { BrushMaterial.EnableKeyword("USE_TEXTURE"); } else { BrushMaterial.DisableKeyword("USE_TEXTURE"); } BrushMaterial.SetFloat("_Hardness", BrushHardness); var brushTexture = BrushTexture != null ? BrushTexture : Texture2D.whiteTexture; var positionOffset = Vector2.zero; if (current.IsPen) { var tilt = current.Tilt; //var azimuth = Mathf.Atan2(tilt.y, tilt.x); var length = Mathf.Clamp01(tilt.magnitude); var altitude = Mathf.Atan2(1f - length, length); //angle = azimuth * Mathf.Rad2Deg; var brushAngle = 1f - altitude / (Mathf.PI * 0.5f); // scale brush none linearly: roundness = 1f + Mathf.Pow(brushAngle, 4f) * MaxBrushScaleFromTilt; positionOffset = new Vector2(tilt.x, -tilt.y) * brushSize * 0.4f; } var startPosition = previous.Position; var endPosition = current.Position; var startPressure = previous.Pressure; var endPressure = current.Pressure; var distance = Vector2.Distance(endPosition, startPosition); var absoluteBrushDistance = Mathf.Max(1f, brushSize * BrushSpacing); if (hasMoved && distance < absoluteBrushDistance) { return; } var tangent = (startPosition - last.Position).normalized; var normal = new Vector2(tangent.y, -tangent.x); var control = startPosition + tangent * (distance * 0.3f); RenderTexture.active = targetTexture; GL.PushMatrix(); GL.LoadPixelMatrix(0, targetTexture.width, 0, targetTexture.height); Vector2 pos = endPosition; foreach (float t in PaintUtils.DrawLine(startPosition, endPosition, absoluteBrushDistance)) { if (hasMoved && t == 0f) { continue; } pos = QuadraticInterpolation ? PaintUtils.PointOnQuadraticCurve(startPosition, control, endPosition, t) : Vector2.LerpUnclamped(startPosition, endPosition, t); var pressure = Mathf.Lerp(startPressure, endPressure, t); var speed = Mathf.Lerp(previous.Speed, current.Speed, t); var modifiedBrushSize = brushSize * Mathf.Lerp(1f, pressure, PenPressureInfluence) * (1f + Random.Range(-1f, 1f) * SizeJitter) * Mathf.Lerp(1f, 1f / (1f + speed), StrokeSpeedInfluence); angle = Angle + Mathf.Lerp(0f, Random.Range(-180f, 180f), AngleJitter); var localBrushRotation = Quaternion.Euler(0, 0, -angle); roundness = Mathf.Clamp01(Roundness + Random.Range(-1f, 1f) * RoundnessJitter); var offset = normal * (Random.Range(-1f, 1f) * modifiedBrushSize * Scatter) + positionOffset; var posOnTexture = (pos + offset) * textureScale; var sizeOnTexture = modifiedBrushSize * textureScale; var matrix = Matrix4x4.TRS(posOnTexture, localBrushRotation, new Vector3(roundness, 1f, 1f)) * Matrix4x4.TRS(-posOnTexture, Quaternion.identity, Vector3.one); GL.MultMatrix(matrix); var color = UseOwnColor ? Color : current.Color; color.a = Mathf.Clamp01(Flow + Random.Range(-1f, 1f) * FlowJitter); BrushMaterial.color = color; var rect = new Rect( posOnTexture.x - 0.5f * sizeOnTexture, posOnTexture.y - 0.5f * sizeOnTexture, sizeOnTexture, sizeOnTexture); Graphics.DrawTexture(rect, brushTexture, BrushMaterial); } if (_lastParameters.Count > 1) { _lastParameters.RemoveAt(1); } current.Position = pos; _lastParameters.Insert(0, current); GL.PopMatrix(); RenderTexture.active = null; }