当前位置: 首页> 健康> 养生 > 怎么查询备案号_宁波室内设计公司排名_百度一下你就知道123_优化大师好用吗

怎么查询备案号_宁波室内设计公司排名_百度一下你就知道123_优化大师好用吗

时间:2025/7/14 3:28:17来源:https://blog.csdn.net/qq992817263/article/details/144514171 浏览次数:1次
怎么查询备案号_宁波室内设计公司排名_百度一下你就知道123_优化大师好用吗

项目源码:后期发布

索引

  • 图层
    • 渲染绘画区域
    • 图层Shader
  • 编辑器
    • 编辑模式
    • 新建图层
    • 设置当前图层
    • 上、下移动图层
    • 删除图层
    • 图层快照

图层

PS中,图层的概念贯穿始终(了解PS图层),他可以称作PS最基础也是最强大的特性之一。

那么,在TextureShop中,我们的第一个任务也即是设计并完成图层的功能。

渲染绘画区域

接上篇,为了实现渲染绘画区域的逻辑,我们添加一个控制变量:

    /// <summary>/// 图层/// </summary>public sealed class TextureLayer{//图层是否为脏的,将触发重新生成渲染源private bool _isTextureDirty = false;}

然后,在帧轮询方法OnUpdate中,检测并重新生成渲染源:

    /// <summary>/// 图层/// </summary>public sealed class TextureLayer{/// <summary>/// 图层更新/// </summary>public void OnUpdate(){//当图层改变时(被标记为脏的)if (_isTextureDirty){_isTextureDirty = false;for (int x = 0; x < _texture.width; x++){for (int y = 0; y < _texture.height; y++){//通过偏移值(锚点),从绘画板中提取颜色,填充到_texture(渲染源)中Color bColor = _plate.GetColor(x + Offset.x, y + Offset.y);_texture.SetPixel(x, y, bColor);}}_texture.Apply();}}}

_isTextureDirty变量的控制至关重要,它使得即便在同一帧多次改变了图层数据,也仅仅只会进行一次生成渲染源,而不是图层每改变一次便触发一次生成渲染源,那将带来极大的性能开销。

图层Shader

再者是图层持有的Shader TextureLayer.shader,在TextureLayer类的构造方法中,他已将渲染源设置给了Shader:

 _material.SetTexture("_PaintTex", _texture);

那么在TextureLayer.shader中将是我们自行编写的渲染逻辑,只不过此时我们没有额外的处理,直接原封不动的输出了渲染源中的颜色:

Shader "Hidden/TextureShop/TextureLayer"
{Properties{[PerRendererData] _MainTex("Sprite Texture", 2D) = "white" {}[HideInInspector] _PaintTex("图层纹理", 2D) = "white" {}}SubShader{Tags{"Queue" = "Transparent""IgnoreProjector" = "True""RenderType" = "Transparent""PreviewType" = "Plane""CanUseSpriteAtlas" = "True"}Cull OffLighting OffZWrite OffZTest[unity_GUIZTestMode]Blend SrcAlpha OneMinusSrcAlphaPass{Name "Default"CGPROGRAM#pragma vertex vert#pragma fragment frag#pragma target 2.0#include "UnityCG.cginc"#include "UnityUI.cginc"struct VertData{float4 vertex   : POSITION;fixed4 color : COLOR;float2 texcoord : TEXCOORD0;UNITY_VERTEX_INPUT_INSTANCE_ID};struct FragData{float4 vertex   : SV_POSITION;fixed4 color : COLOR;float2 texcoord  : TEXCOORD0;float4 worldPosition : TEXCOORD1;UNITY_VERTEX_OUTPUT_STEREO};sampler2D _PaintTex;FragData vert(VertData IN){FragData OUT;UNITY_SETUP_INSTANCE_ID(IN);UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);OUT.worldPosition = IN.vertex;OUT.vertex = UnityObjectToClipPos(OUT.worldPosition);OUT.texcoord = IN.texcoord;OUT.color = IN.color;return OUT;}fixed4 frag(FragData IN) : SV_Target{//原封不动输出颜色half4 color = tex2D(_PaintTex, IN.texcoord);return color;}ENDCG}}
}

编辑器

我们需要定义一个最顶层的控制器类,也将作为我们整个程序的入口,TextureShop的编辑器:

    /// <summary>/// TextureShop编辑器/// </summary>[DisallowMultipleComponent]public sealed class TextureShopEditor : MonoBehaviour{}

回顾图层的尺寸等参数,所有的图层应当拥有一样的尺寸大小,所以将他们加入到编辑器中,以公开到外部设置:

    /// <summary>/// TextureShop编辑器/// </summary>[DisallowMultipleComponent]public sealed class TextureShopEditor : MonoBehaviour{/// <summary>/// 绘画区域宽度/// </summary>public int PaintAreaWidth = 512;/// <summary>/// 绘画区域高度/// </summary>public int PaintAreaHeight = 512;/// <summary>/// 绘画板宽度/// </summary>public int PlateWidth = 2048;/// <summary>/// 绘画板高度/// </summary>public int PlateHeight = 2048;}

编辑模式

编辑模式目前暂定为如下几种:

编辑模式描述
不可进行任何编辑操作
移动选中选区时,移动选区内容,否则移动绘画板内容
选取以矩形方式选择选区
套索以套索方式选择选区
魔术棒以魔术棒方式选择选区
修剪进行高自由度修剪选区
仿制图章按住Alt锚定一片区域,然后在其他地方可复制该区域
画笔使用鼠标进行绘画
橡皮擦使用鼠标进行擦除
    /// <summary>/// TextureShop编辑器/// </summary>[DisallowMultipleComponent]public sealed class TextureShopEditor : MonoBehaviour{/// <summary>/// 编辑模式/// </summary>[SerializeField] private EditMode _mode = EditMode.None;}/// <summary>/// 编辑模式/// </summary>public enum EditMode{/// <summary>/// 无/// </summary>None,/// <summary>/// 移动/// </summary>Move,/// <summary>/// 选取/// </summary>Choose,/// <summary>/// 套索/// </summary>Noose,/// <summary>/// 魔术棒/// </summary>MagicWand,/// <summary>/// 修剪/// </summary>Trim,/// <summary>/// 仿制图章/// </summary>CloneStamp,/// <summary>/// 画笔/// </summary>Paint,/// <summary>/// 擦除/// </summary>Erase}

新建图层

新建图层时,传入尺寸、图像数据等参数(如果传入了图像,将该图像颜色数据载入新建的图层中,否则新建一个空图层):

    /// <summary>/// TextureShop编辑器/// </summary>[DisallowMultipleComponent]public sealed class TextureShopEditor : MonoBehaviour{//图层渲染器放置的根节点private RectTransform _textureLayerRoot;/// <summary>/// 所有的图层/// </summary>public List<TextureLayer> TextureLayers { get; private set; } = new List<TextureLayer>();/// <summary>/// 新建一个图层/// </summary>/// <param name="layerName">图层名称</param>/// <param name="texture">图层图像</param>/// <param name="offset">偏移值</param>/// <returns>图层</returns>public TextureLayer NewTextureLayer(string layerName, Texture2D texture, Vector2Int offset = default){layerName = string.IsNullOrEmpty(layerName) ? "新建图层" : layerName;TextureLayer textureLayer = new TextureLayer(layerName, PaintAreaWidth, PaintAreaHeight, PlateWidth, PlateHeight, _textureLayerRoot, texture, offset);TextureLayers.Add(textureLayer);return textureLayer;}}

设置当前图层

只有当前图层不为空,才能进一步编辑当前图层:

    /// <summary>/// TextureShop编辑器/// </summary>[DisallowMultipleComponent]public sealed class TextureShopEditor : MonoBehaviour{/// <summary>/// 当前选中的图层/// </summary>public TextureLayer CurrentLayer { get; private set; }/// <summary>/// 设置当前激活的图层/// </summary>/// <param name="layer">图层</param>public void SetCurrentLayer(TextureLayer layer){if (CurrentLayer == layer)return;CurrentLayer = layer;}}

上、下移动图层

图层越靠下(在图层列表中越靠后),其显示层级越高,也即是能在视觉上挡住之前的图层:

    /// <summary>/// TextureShop编辑器/// </summary>[DisallowMultipleComponent]public sealed class TextureShopEditor : MonoBehaviour{/// <summary>/// 向上移动当前图层(显示层级降低)/// </summary>public void MoveLayerUpwards(){if (CurrentLayer != null){int index = TextureLayers.IndexOf(CurrentLayer);if (index > 0){index -= 1;TextureLayers.Remove(CurrentLayer);TextureLayers.Insert(index, CurrentLayer);//移动图层渲染器实体,改变其在父级中的位置CurrentLayer.Entity.transform.SetSiblingIndex(index);}}}/// <summary>/// 向下移动当前图层(显示层级升高)/// </summary>public void MoveLayerDownwards(){if (CurrentLayer != null){int index = TextureLayers.IndexOf(CurrentLayer);if (index < TextureLayers.Count - 1){index += 1;TextureLayers.Remove(CurrentLayer);TextureLayers.Insert(index, CurrentLayer);CurrentLayer.Entity.transform.SetSiblingIndex(index);}}}}

删除图层

    /// <summary>/// TextureShop编辑器/// </summary>[DisallowMultipleComponent]public sealed class TextureShopEditor : MonoBehaviour{/// <summary>/// 删除一个图层/// </summary>/// <param name="layer">图层</param>public void DeleteTextureLayer(TextureLayer layer){if (layer == null)return;if (CurrentLayer == layer){SetCurrentLayer(null);}layer.Dispose();TextureLayers.Remove(layer);}}

图层快照

在进行某些操作时,如果用户未点击确认,而是点击了取消,则之前的操作将被还原,如下:

在这里插入图片描述

为了实现这个功能,我们引入图层快照(当然,更高级的应当引入命令模式,但这不在本系列的学习范畴内):

    /// <summary>/// 图层快照/// </summary>public sealed class TextureLayerSnapshot{internal Plate _plate;internal Plate _region;internal Vector2Int _offset;/// <summary>/// 图层快照/// </summary>public TextureLayerSnapshot(int paintAreaWidth, int paintAreaHeight, int plateWidth, int plateHeight){_plate = new Plate(plateWidth, plateHeight, true);_region = new Plate(paintAreaWidth, paintAreaHeight, false);_offset = new Vector2Int((_plate.Width - _region.Width) / 2, (_plate.Height - _region.Height) / 2);}/// <summary>/// 释放图层快照资源/// </summary>public void Dispose(){if (_plate != null){_plate.Dispose();_plate = null;}if (_region != null){_region.Dispose();_region = null;}}}

任何图层,都可以为其创建快照,并在之后的某一时刻还原到快照,快照能够记录一个图层在某一时刻的完整状态:

    /// <summary>/// TextureShop编辑器/// </summary>[DisallowMultipleComponent]public sealed class TextureShopEditor : MonoBehaviour{/// <summary>/// 当前的图层快照/// </summary>public TextureLayerSnapshot CurrentSnapshot { get; private set; }/// <summary>/// 为当前图层创建快照/// </summary>public void CreateLayerSnapshot(){if (CurrentLayer != null){CurrentLayer.OutputToSnapshot(CurrentSnapshot);}}/// <summary>/// 将当前图层还原到快照/// </summary>public void RestoreLayerSnapshot(){if (CurrentLayer != null){CurrentLayer.InputOfSnapshot(CurrentSnapshot);}}}

至于图层如何创建快照,如何还原到快照,将由他自己定夺:

    /// <summary>/// 图层/// </summary>public sealed class TextureLayer{/// <summary>/// 输出到快照/// </summary>/// <param name="snapshot">快照</param>internal void OutputToSnapshot(TextureLayerSnapshot snapshot){_plate.CopyTo(snapshot._plate);_region.CopyTo(snapshot._region);snapshot._offset = Offset;}/// <summary>/// 通过快照输入/// </summary>/// <param name="snapshot">快照</param>internal void InputOfSnapshot(TextureLayerSnapshot snapshot){snapshot._plate.CopyTo(_plate);snapshot._region.CopyTo(_region);Offset = snapshot._offset;//图层为脏的,触发重新生成渲染源_isTextureDirty = true;}}

到此,图层的功能就实现得差不多了。

关键字:怎么查询备案号_宁波室内设计公司排名_百度一下你就知道123_优化大师好用吗

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: