Example #1
0
            public override void PaintRenderTextureUvSpace(PaintCommand.UV command)
            {
                Brush       br = command.Brush;
                Stroke      st = command.Stroke;
                TextureMeta id = command.TextureData;

                BeforeStroke(command);

                if (st.CrossedASeam())
                {
                    st.uvFrom = st.uvTo;
                }

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

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

                RtBrush.localScale = Vector3.one * br.StrokeWidth(id.width, false);

                BrushMesh             = PainterCamera.BrushMeshGenerator.GetQuad();
                RtBrush.localRotation = Quaternion.identity;

                RtBrush.localPosition = st.BrushWorldPosition;

                TexMGMT.Render();

                AfterStroke(command);//painter, br, st, alphaBuffer, id);
            }
Example #2
0
            public static void Paint(Vector2 uv, Brush br, RenderTexture rt)
            {
                var command = new PaintCommand.UV(new Stroke(uv)
                {
                    firstStroke = false
                }, rt.GetTextureMeta(), br)
                {
                    strokeAlphaPortion = Mathf.Clamp01(br.Flow * 0.05f)
                };

                TexMGMT.SHADER_STROKE_SEGMENT_UPDATE(command); // br, br.Speed * 0.05f, id, stroke, out alphaBuffer);

                float width = br.StrokeWidth(command.TextureData.width, false);

                RtBrush.localScale = Vector3.one;

                BrushMesh             = PainterCamera.BrushMeshGenerator.GetLongMesh(0, width);
                RtBrush.localRotation = Quaternion.Euler(new Vector3(0, 0, Vector2.Angle(Vector2.up, Vector2.zero)));

                RtBrush.localPosition = Stroke.BrushWorldPositionFrom(command.Stroke.uvTo);

                TexMGMT.Render();

                br.GetBrushType(false).AfterStroke(command);
            }
Example #3
0
            public virtual void PaintRenderTextureUvSpace(PaintCommand.UV command)
            {
                TextureMeta textureMeta = command.TextureData;
                Brush       br          = command.Brush;
                Stroke      st          = command.Stroke;

                BeforeStroke(command);

                if (st.CrossedASeam())
                {
                    st.uvFrom = st.uvTo;
                }

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

                TexMGMT.SHADER_STROKE_SEGMENT_UPDATE(command);

                var rb = RtBrush;

                rb.localScale = Vector3.one;
                var direction = st.DeltaUv;
                var length    = direction.magnitude;

                BrushMesh        = PainterCamera.BrushMeshGenerator.GetLongMesh(length * 256, br.StrokeWidth(textureMeta.width, false));
                rb.localRotation = Quaternion.Euler(new Vector3(0, 0,
                                                                (direction.x > 0 ? -1 : 1) * Vector2.Angle(Vector2.up, direction)));

                rb.localPosition = Stroke.BrushWorldPositionFrom((st.uvFrom + st.uvTo) * 0.5f);

                TexMGMT.Render();

                AfterStroke(command);
            }
Example #4
0
        public static void Paint(Vector2 uvCoords, float brushAlpha, Texture2D texture, Vector2 offset, Vector2 tiling, Brush bc)
        {
            var id = texture.GetTextureMeta();

            id.offset = offset;
            id.tiling = tiling;

            var cmd = new PaintCommand.UV(new Stroke(uvCoords), texture.GetTextureMeta(), bc);

            cmd.strokeAlphaPortion = brushAlpha;
            Paint(cmd);
        }
Example #5
0
            public override void AfterStroke(PaintCommand.UV command)
            {
                Brush  br = command.Brush;
                Stroke st = command.Stroke;

                base.AfterStroke(command);

                if (br.rotationMethod != RotationMethod.Random)
                {
                    return;
                }

                br.decalAngle = Random.Range(-90f, 450f);
                OnShaderBrushUpdate(Cfg.Brush);
            }
Example #6
0
            public override void PrePaint(PaintCommand.UV paintCommand) //Brush br, Stroke st, PlaytimePainter painter = null)
            {
                Stroke st = paintCommand.Stroke;

                var v4 = new Vector4(st.unRepeatedUv.x, st.unRepeatedUv.y, Mathf.Floor(st.unRepeatedUv.x),
                                     Mathf.Floor(st.unRepeatedUv.y));

                _pointedUvUnTiledProperty.GlobalValue = v4;

                if (!st.firstStroke)
                {
                    return;
                }

                if (method == (ColorSetMethod.MDownColor))
                {
                    var painter = paintCommand.TryGetPainter();

                    if (painter)
                    {
                        painter.SampleTexture(st.uvTo);
                    }
                    else
                    {
                        paintCommand.Brush.Color = paintCommand.TextureData.SampleAt(st.uvTo);
                    }

                    FromColor(paintCommand.Brush, st.unRepeatedUv);
                }
                else if (method == (ColorSetMethod.MDownPosition))
                {
                    FromUv(st.uvTo);
                }

                BRUSH_SAMPLING_DISPLACEMENT.GlobalValue = new Vector4(
                    (currentPixel.x + 0.5f) / Cfg.samplingMaskSize.x,

                    (currentPixel.y + 0.5f) / Cfg.samplingMaskSize.y,

                    Cfg.samplingMaskSize.x, Cfg.samplingMaskSize.y);
            }
Example #7
0
            public virtual void AfterStroke(PaintCommand.UV command)
            {
                PaintCommand.ForPainterComponent painterCommand = command as PaintCommand.ForPainterComponent;
                Brush       br = command.Brush;
                Stroke      st = command.Stroke;
                TextureMeta id = command.TextureData;

                command.OnStrokeComplete();

                if (br.useMask && st.MouseUpEvent && br.randomMaskOffset)
                {
                    br.maskOffset = new Vector2(Random.Range(0f, 1f), Random.Range(0f, 1f));
                }

                if (command.usedAlphaBuffer)
                {
                    var sh = br.GetBlitMode(false).ShaderForAlphaBufferBlit;
                    if (painterCommand == null || painterCommand.painter.NotUsingPreview)
                    {
                        TexMGMT.UpdateFromAlphaBuffer(id.CurrentRenderTexture(), sh);
                    }
                    else
                    {
                        TexMGMT.AlphaBufferSetDirtyBeforeRender(id, sh);
                    }
                }
                else if (!br.IsSingleBufferBrush() && !command.Is3DBrush)
                {
                    TexMGMT.UpdateBufferSegment();
                }

                if (painterCommand != null)
                {
                    foreach (var p in painterCommand.painter.Modules)
                    {
                        p.AfterGpuStroke(painterCommand);
                    }
                }
            }
Example #8
0
            public void BeforeStroke(PaintCommand.UV command)//Brush br, Stroke st, PlaytimePainter painter = null)
            {
                Brush  br = command.Brush;
                Stroke st = command.Stroke;

                PaintCommand.ForPainterComponent painterCommand = command as PaintCommand.ForPainterComponent;

                var cam = TexMGMT;

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

                if (painterCommand != null)
                {
                    foreach (var p in painterCommand.painter.Modules)
                    {
                        p.BeforeGpuStroke(painterCommand);//br, st, this);
                    }
                }
            }
Example #9
0
        public void Paint(PaintCommand.UV command)
        {
            var imgData = command.TextureData;

            var cpu          = command.TextureData.TargetIsTexture2D();
            var brushType    = GetBrushType(cpu);
            var blitMode     = GetBlitMode(cpu);
            var isWorldSpace = command.Is3DBrush;

            var painterCommand = command as PaintCommand.ForPainterComponent;

            PlaytimePainter painter = painterCommand?.painter;

            blitMode.PrePaint(command);

            if (cpu)
            {
                if (painter)
                {
                    foreach (var module in imgData.Modules)
                    {
                        module.OnPainting(painter);
                    }
                }

                brushType.PaintPixelsInRam(command);
            }
            else
            {
                if (painter)
                {
                    var materialData = painter.MatDta;

                    if (!imgData.renderTexture && !TexMGMT.materialsUsingRenderTexture.Contains(materialData))
                    {
                        TexMGMT.ChangeBufferTarget(imgData, materialData, painter.GetMaterialTextureProperty(), painter);
                        painter.SetTextureOnMaterial(imgData);
                    }

                    var rendered = false;

                    foreach (var pl in CameraModuleBase.BrushPlugins)
                    {
                        if (pl.IsEnabledFor(painter, imgData, this))
                        {
                            pl.PaintRenderTextureUvSpace(command);
                            rendered = true;
                            break;
                        }
                    }

                    if (!painter.terrain || brushType.SupportedForTerrainRt)
                    {
                        foreach (var module in imgData.Modules)
                        {
                            module.OnPainting(painter);
                        }

                        if (!rendered)
                        {
                            if (isWorldSpace)
                            {
                                brushType.PaintRenderTextureInWorldSpace(command as PaintCommand.WorldSpace);
                            }
                            else
                            {
                                brushType.PaintRenderTextureUvSpace(command);
                            }
                        }
                    }
                }
                else
                {
                    if (isWorldSpace)
                    {
                        brushType.PaintRenderTextureInWorldSpace(command as PaintCommand.WorldSpace);
                    }
                    else
                    {
                        brushType.PaintRenderTextureUvSpace(command);
                    }
                }
            }
        }
Example #10
0
        public static void Paint(PaintCommand.UV command)
        {
            TextureMeta image = command.TextureData;

            if (image.Pixels == null)
            {
                return;
            }

            Brush bc = command.Brush;

            var uvCoords = command.Stroke.uvFrom;

            brAlpha = command.strokeAlphaPortion;

            bc.PrepareCpuBlit(image);

            var iHalf = (int)(half);

            Vector2 offset;

            var tmp = image.UvToPixelNumber(uvCoords, out offset);

            var smooth = bc.GetBrushType(true) != BrushTypes.Pixel.Inst;

            if (smooth)
            {
                iHalf += 1;
                offset = Vector2.zero;
            }

            var hf = half - 0.5f;

            var halfFromX = Mathf.RoundToInt(-hf + offset.x);
            var halfFromY = Mathf.RoundToInt(-hf + offset.y);
            var halfToX   = Mathf.RoundToInt(hf + offset.x);
            var halfToY   = Mathf.RoundToInt(hf + offset.y);

            var fromX = tmp.x + halfFromX;

            tmp.y += halfFromY;

            var pixels = image.Pixels;

            for (y = halfFromY; y <= halfToY; y++)
            {
                tmp.x = fromX;

                for (x = halfFromX; x <= halfToX; x++)
                {
                    if (alphaMode())
                    {
                        blitMode(ref pixels[image.PixelNo(tmp)]);
                    }

                    tmp.x += 1;
                }

                tmp.y += 1;
            }
        }
Example #11
0
 public virtual void PrePaint(PaintCommand.UV paintCommand) //Brush br, Stroke st, PlaytimePainter painter = null)
 {
 }
Example #12
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);
            }
Example #13
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);
                }
            }
Example #14
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);
            }
Example #15
0
        public void SHADER_STROKE_SEGMENT_UPDATE(PaintCommand.UV command)
        {
            Brush       bc     = command.Brush;
            TextureMeta id     = command.TextureData;
            Stroke      stroke = command.Stroke;

            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;
        }
Example #16
0
        public void SHADER_BRUSH_UPDATE(PaintCommand.UV command)
        {
            Brush brush = command.Brush;

            var id = command.TextureData;

            var rendTex = id.TargetIsRenderTexture();

            var brushType = brush.GetBrushType(!rendTex);

            var is3DBrush = command.Is3DBrush;

            #region Brush

            brush.previewDirty = false;

            PainterShaderVariables.BrushColorProperty.GlobalValue = brush.Color;

            PainterShaderVariables.BrushMaskProperty.GlobalValue = brush.mask.ToVector4();

            brushType.OnShaderBrushUpdate(brush);

            if (rendTex)
            {
                PainterShaderVariables.SourceMaskProperty.GlobalValue = brush.useMask ? Data.masks.TryGet(brush.selectedSourceMask) : null;
            }

            PainterShaderVariables.MaskDynamicsProperty.GlobalValue = new Vector4(
                brush.maskTiling,
                rendTex ? brush.hardness * brush.hardness : 0,     // y - Hardness is 0 to do correct preview for Texture2D brush
                ((brush.flipMaskAlpha && brush.useMask) ? 0 : 1),  // z - flip mask if any
                (brush.maskFromGreyscale && brush.useMask) ? 1 : 0);

            PainterShaderVariables.MaskOffsetProperty.GlobalValue = brush.maskOffset.ToVector4();

            float brushSizeUvSpace = brush.Size(is3DBrush) / (id == null ? 256 : Mathf.Min(id.width, id.height));

            PainterShaderVariables.BrushFormProperty.GlobalValue = new Vector4(
                command.strokeAlphaPortion, // x - transparency
                brush.Size(is3DBrush),      // y - scale for sphere
                brushSizeUvSpace,           // z - scale for uv space
                brush.blurAmount);          // w - blur amount

            #endregion


            if (id == null)
            {
                return;
            }

            var blitMode = brush.GetBlitMode(!rendTex);

            var useAlphaBuffer = (brush.useAlphaBuffer && blitMode.SupportsAlphaBufferPainting && rendTex);

            float useTransparentLayerBackground = 0;

            PainterShaderVariables.OriginalTextureTexelSize.GlobalValue = new Vector4(
                1f / id.width,
                1f / id.height,
                id.width,
                id.height
                );

            var painter = command.TryGetPainter();

            if (id.isATransparentLayer && painter)
            {
                var md  = painter.MatDta;
                var mat = md.material;
                if (md != null && md.usePreviewShader && mat)
                {
                    var mt = mat.mainTexture;
                    PainterShaderVariables.TransparentLayerUnderProperty.GlobalValue = mt;
                    useTransparentLayerBackground = (mt && (id != mt.GetImgDataIfExists())) ? 1 : 0;
                }
            }

            PainterShaderVariables.AlphaBufferConfigProperty.GlobalValue = new Vector4(
                brush.alphaLimitForAlphaBuffer,
                brush.worldSpaceBrushPixelJitter ? 1 : 0,
                useAlphaBuffer ? 1 : 0,
                0);

            PainterShaderVariables.AlphaPaintingBuffer.GlobalValue = AlphaBuffer;

            brushType.SetKeyword(id.useTexCoord2);

            QcUnity.SetShaderKeyword(PainterShaderVariables.BRUSH_TEXCOORD_2, id.useTexCoord2);

            //if (blitMode.SupportsTransparentLayer)
            QcUnity.SetShaderKeyword(PainterShaderVariables.TARGET_TRANSPARENT_LAYER, id.isATransparentLayer);

            blitMode.SetKeyword(id).SetGlobalShaderParameters();

            if (rendTex && blitMode.UsingSourceTexture)
            {
                PainterShaderVariables.SourceTextureProperty.GlobalValue   = Data.sourceTextures.TryGet(brush.selectedSourceTexture);
                PainterShaderVariables.TextureSourceParameters.GlobalValue = new Vector4(
                    (float)brush.srcColorUsage,
                    brush.clampSourceTexture ? 1f : 0f,
                    useTransparentLayerBackground,
                    brush.ignoreSrcTextureTransparency ? 1f : 0f
                    );
            }
        }