Beispiel #1
0
            public override void PaintRenderTextureUvSpace(PaintCommand.UV command)//PlaytimePainter painter, Brush br, Stroke st)
            {
                Brush  br = command.Brush;
                Stroke st = command.Stroke;
                var    id = command.TextureData;

                BeforeStroke(command);

                var deltaUv   = st.DeltaUv; //uv - st.uvFrom;//.Previous_uv;
                var magnitude = deltaUv.magnitude;

                var width = br.Size(false) / id.width * 4;

                var trackPortion = (deltaUv.magnitude - width * 0.5f) * 0.25f;

                if (!(trackPortion > 0) && !st.MouseUpEvent)
                {
                    return;
                }

                if (st.firstStroke)
                {
                    previousDirectionLazy = st.previousDelta = deltaUv;
                    _lazySpeedDynamic     = deltaUv.magnitude;
                    _lazyAngleSmoothed    = 0;
                    // Debug.Log("First stroke");
                }

                var angle = Mathf.Deg2Rad * Vector2.Angle(st.previousDelta, deltaUv);

                var smooth = angle < Mathf.PI * 0.5f;

                if (st.CrossedASeam() && (magnitude > previousDirectionLazy.magnitude * 8))
                {
                    // Debug.Log("Crossed a seam");
                    st.MouseUpEvent = true;
                    st.uvTo         = st.uvFrom; // painter.Previous_uv;
                    deltaUv         = Vector2.zero;
                    smooth          = false;
                }

                previousDirectionLazy = deltaUv;

                if (!st.MouseUpEvent)
                {
                    if (smooth)
                    {
                        var   clockwise = Vector3.Cross(st.previousDelta, deltaUv).z > 0 ? 1f : -1f;
                        var   sin       = Mathf.Sin(angle) * clockwise;
                        float maxSinus  = 8;
                        _lazyAngleSmoothed = Mathf.Abs(_lazyAngleSmoothed) > Mathf.Abs(sin)
                            ? sin
                            : Mathf.Lerp(_lazyAngleSmoothed, sin, 0.2f);

                        sin = _lazyAngleSmoothed;

                        if ((sin * sin > maxSinus * maxSinus) || ((sin > 0) != (maxSinus > 0)))
                        {
                            var absSin  = Mathf.Abs(sin);
                            var absNSin = Mathf.Abs(maxSinus);

                            if (absSin < absNSin)
                            {
                                maxSinus = maxSinus * absSin / absNSin;
                            }

                            st.uvTo = st.uvFrom + st.previousDelta.normalized.Rotate_Radians(maxSinus * clockwise) *
                                      trackPortion;
                            _lazySpeedDynamic = trackPortion;
                        }
                        else
                        {
                            _lazySpeedDynamic = Mathf.Min(deltaUv.magnitude * 0.5f,
                                                          Mathf.Lerp(_lazySpeedDynamic, deltaUv.magnitude * 0.5f, 0.001f));

                            _lazySpeedDynamic = Mathf.Max(trackPortion, _lazySpeedDynamic);
                            st.uvTo           = st.uvFrom + st.previousDelta.normalized.Rotate_Radians(sin) * _lazySpeedDynamic;
                        }
                    }
                    else
                    {
                        _lazySpeedDynamic  = deltaUv.magnitude;
                        _lazyAngleSmoothed = 0;
                        st.uvTo            = st.uvFrom + deltaUv.normalized * trackPortion;
                    }
                }

                var r = TexMGMT;

                var meshWidth = br.StrokeWidth(id.width, false);

                var tf = RtBrush;

                var direction = st.DeltaUv;

                var isTail = st.firstStroke;

                // bool alphaBuffer;

                if (!isTail && !smooth)
                {
                    var st2 = new Stroke(st)
                    {
                        firstStroke = false
                    };
                    r.SHADER_STROKE_SEGMENT_UPDATE(command);//br, br.Speed * 0.05f, id, st2, out alphaBuffer, painter);

                    Vector3 junkPoint = st.uvFrom + st.previousDelta * 0.01f;
                    BrushMesh = PainterCamera.BrushMeshGenerator.GetStreak(UvToPosition(st.uvFrom),
                                                                           UvToPosition(junkPoint), meshWidth, true, false);
                    tf.localScale    = Vector3.one;
                    tf.localRotation = Quaternion.identity;
                    tf.localPosition = new Vector3(0, 0, 10);


                    r.Render();
                    st.uvFrom = junkPoint;
                    isTail    = true;
                }

                command.strokeAlphaPortion = Mathf.Clamp01(br.Flow * 0.05f);

                r.SHADER_STROKE_SEGMENT_UPDATE(command);//br, br.Speed * 0.05f, id, st, out alphaBuffer, painter);

                BrushMesh = PainterCamera.BrushMeshGenerator.GetStreak(UvToPosition(st.uvFrom), UvToPosition(st.uvTo),
                                                                       meshWidth, st.MouseUpEvent, isTail);
                tf.localScale    = Vector3.one;
                tf.localRotation = Quaternion.identity;
                tf.localPosition = new Vector3(0, 0, 10);

                st.previousDelta = direction;

                r.Render();

                AfterStroke(command); //painter, br, st, alphaBuffer, id);
            }
Beispiel #2
0
            public override void PaintRenderTextureUvSpace(PaintCommand.UV command)  //PlaytimePainter painter, Brush br, Stroke st)
            {
                Brush  br = command.Brush;
                Stroke st = command.Stroke;

                BeforeStroke(command);

                var id = command.TextureData;

                if (st.firstStroke || br.decalContentious)
                {
                    if (br.rotationMethod == RotationMethod.FaceStrokeDirection)
                    {
                        var delta = st.uvTo - _previousUv;

                        var portion = Mathf.Clamp01(delta.magnitude * id.width * 4 / br.Size(false));

                        var newAngle = Vector2.SignedAngle(Vector2.up, delta) + br.decalAngleModifier;
                        br.decalAngle = Mathf.LerpAngle(br.decalAngle, newAngle, portion);

                        _previousUv = st.uvTo;
                    }

                    command.strokeAlphaPortion = 1;

                    TexMGMT.SHADER_STROKE_SEGMENT_UPDATE(command); // br, 1, id, st, out alphaBuffer, command.painter);
                    var tf = RtBrush;
                    tf.localScale    = Vector3.one * br.Size(false);
                    tf.localRotation = Quaternion.Euler(new Vector3(0, 0, br.decalAngle));
                    BrushMesh        = PainterCamera.BrushMeshGenerator.GetQuad();

                    st.uvTo = st.uvTo.To01Space();

                    var deltaUv = st.DeltaUv;

                    var uv = st.uvTo;

                    if (br.rotationMethod == RotationMethod.FaceStrokeDirection && !st.firstStroke)
                    {
                        var length = Mathf.Max(deltaUv.magnitude * 2 * id.width / br.Size(false), 1);
                        var scale  = tf.localScale;

                        if ((Mathf.Abs(Mathf.Abs(br.decalAngleModifier) - 90)) < 40)
                        {
                            scale.x *= length;
                        }
                        else
                        {
                            scale.y *= length;
                        }

                        tf.localScale = scale;
                        uv           -= deltaUv * ((length - 1) * 0.5f / length);
                    }

                    tf.localPosition = Stroke.BrushWorldPositionFrom(uv);

                    TexMGMT.Render();

                    AfterStroke(command);
                }
                else
                {
                    command.OnStrokeComplete(); //painter.AfterStroke(st);
                }
            }
Beispiel #3
0
            public virtual void PaintPixelsInRam(PaintCommand.UV command)
            {
                Brush  br = command.Brush;
                Stroke st = command.Stroke;

                var deltaUv = st.uvTo - st.uvFrom;

                if (deltaUv.magnitude > (0.2f + st.avgBrushSpeed * 3))
                {
                    deltaUv = Vector2.zero; // This is made to avoid glitch strokes on seams
                }
                else
                {
                    st.avgBrushSpeed = (st.avgBrushSpeed + deltaUv.magnitude) / 2;
                }

                var alpha = Mathf.Clamp01(br.Flow * (Application.isPlaying ? Time.deltaTime : 0.1f));

                var id = command.TextureData;

                var deltaPos = st.DeltaWorldPos;

                float steps = 1;

                if (id.disableContiniousLine)
                {
                    st.uvFrom  = st.uvTo;
                    st.posFrom = st.posTo;
                }
                else
                {
                    var uvDist    = (deltaUv.magnitude * id.width * 8 / br.Size(false));
                    var worldDist = st.DeltaWorldPos.magnitude;

                    steps = (int)Mathf.Max(1, IsAWorldSpaceBrush ? worldDist : uvDist);

                    deltaUv  /= steps;
                    deltaPos /= steps;

                    st.uvFrom  += deltaUv;
                    st.posFrom += deltaPos;
                }

                Action <PaintCommand.UV> blitMethod = null;

                command.strokeAlphaPortion = alpha;

                var painter = command.TryGetPainter();

                foreach (var p in CameraModuleBase.BrushPlugins)
                {
                    if (p.IsEnabledFor(painter, id, br))
                    {
                        p.PaintPixelsInRam(command);//st, alpha, id, br, painter);
                        blitMethod = p.PaintPixelsInRam;
                        break;
                    }
                }

                if (blitMethod == null)
                {
                    blitMethod = BlitFunctions.Paint;
                    blitMethod(command);
                }

                for (float i = 1; i < steps; i++)
                {
                    st.uvFrom  += deltaUv;
                    st.posFrom += deltaPos;
                    blitMethod(command);
                }

                command.OnStrokeComplete();//.AfterStroke(st);
            }
Beispiel #4
0
 public static void Paint(RenderTexture renderTexture, Brush br, Stroke st) =>
 _inst.PaintRenderTextureUvSpace(new PaintCommand.UV(st, renderTexture, br));
Beispiel #5
0
        public void SHADER_STROKE_SEGMENT_UPDATE(PaintCommand.UV command)
        {
            Brush       bc     = command.Brush;
            TextureMeta id     = command.TextureData;
            Stroke      stroke = command.Stroke;

            CheckPaintingBuffers();

            var isDoubleBuffer = !id.renderTexture;

            var useSingle = !isDoubleBuffer || bc.IsSingleBufferBrush();

            var blitMode = bc.GetBlitMode(false);

            command.usedAlphaBuffer = !useSingle && bc.useAlphaBuffer && bc.GetBrushType(false).SupportsAlphaBufferPainting&& blitMode.SupportsAlphaBufferPainting;

            var painter = command.TryGetPainter();

            Shader shd = null;

            if (painter)
            {
                foreach (var pl in CameraModuleBase.BrushPlugins)
                {
                    var bs = useSingle ? pl.GetBrushShaderSingleBuffer(painter) : pl.GetBrushShaderDoubleBuffer(painter);
                    if (!bs)
                    {
                        continue;
                    }
                    shd = bs;
                    break;
                }
            }

            if (!shd)
            {
                if (command.usedAlphaBuffer)
                {
                    shd = blitMode.ShaderForAlphaOutput;
                    AlphaBufferSetDirtyBeforeRender(id, blitMode.ShaderForAlphaBufferBlit);
                }
                else
                {
                    shd = useSingle ? blitMode.ShaderForSingleBuffer : blitMode.ShaderForDoubleBuffer;
                }
            }


            if (!useSingle && !RenderTextureBuffersManager.secondBufferUpdated)
            {
                RenderTextureBuffersManager.UpdateBufferTwo();
            }

            SHADER_BRUSH_UPDATE(command);

            TargetTexture = command.usedAlphaBuffer ? AlphaBuffer : id.CurrentRenderTexture();

            if (isDoubleBuffer)
            {
                PainterShaderVariables.DESTINATION_BUFFER.GlobalValue = BackBuffer;
            }

            CurrentShader = shd;
        }