【蓝图】渲染目标 - 画笔
效果示例:
![alt text](/2024/04/26/%E8%BD%AF%E4%BB%B6%E5%AD%A6%E4%B9%A0/UE/UE%E5%8A%9F%E8%83%BD%E5%AE%9E%E7%8E%B0/%E8%93%9D%E5%9B%BE/%E3%80%90%E8%93%9D%E5%9B%BE%E3%80%91%E6%B8%B2%E6%9F%93%E7%9B%AE%E6%A0%87-%E7%94%BB%E7%AC%94/%E7%94%BB%E7%AC%94%E6%95%88%E6%9E%9C%E7%A4%BA%E4%BE%8B.png)
大致思路:利用两层纹理,A 和 B,根据画笔经过位置将画布的纹理 B 修改位画笔引用的纹理 A
- A:画笔绘制的纹理
- B:画布的纹理
本文实现的效果:
![](/2024/04/26/%E8%BD%AF%E4%BB%B6%E5%AD%A6%E4%B9%A0/UE/UE%E5%8A%9F%E8%83%BD%E5%AE%9E%E7%8E%B0/%E8%93%9D%E5%9B%BE/%E3%80%90%E8%93%9D%E5%9B%BE%E3%80%91%E6%B8%B2%E6%9F%93%E7%9B%AE%E6%A0%87-%E7%94%BB%E7%AC%94/%E6%9C%80%E7%BB%88%E6%95%88%E6%9E%9C.gif)
得到画笔
基本原理
画笔实现:
![alt text](/2024/04/26/%E8%BD%AF%E4%BB%B6%E5%AD%A6%E4%B9%A0/UE/UE%E5%8A%9F%E8%83%BD%E5%AE%9E%E7%8E%B0/%E8%93%9D%E5%9B%BE/%E3%80%90%E8%93%9D%E5%9B%BE%E3%80%91%E6%B8%B2%E6%9F%93%E7%9B%AE%E6%A0%87-%E7%94%BB%E7%AC%94/%E7%94%BB%E7%AC%94%E5%AE%9E%E7%8E%B0%E6%89%80%E9%9C%80%E8%8A%82%E7%82%B9_SphereMask.png)
效果如图:
![alt text](/2024/04/26/%E8%BD%AF%E4%BB%B6%E5%AD%A6%E4%B9%A0/UE/UE%E5%8A%9F%E8%83%BD%E5%AE%9E%E7%8E%B0/%E8%93%9D%E5%9B%BE/%E3%80%90%E8%93%9D%E5%9B%BE%E3%80%91%E6%B8%B2%E6%9F%93%E7%9B%AE%E6%A0%87-%E7%94%BB%E7%AC%94/SphereMask%E6%95%88%E6%9E%9C%E7%A4%BA%E6%84%8F%E5%9B%BE.png)
将混合模式设置为Additive去掉纹理的黑色部分:
![alt text](/2024/04/26/%E8%BD%AF%E4%BB%B6%E5%AD%A6%E4%B9%A0/UE/UE%E5%8A%9F%E8%83%BD%E5%AE%9E%E7%8E%B0/%E8%93%9D%E5%9B%BE/%E3%80%90%E8%93%9D%E5%9B%BE%E3%80%91%E6%B8%B2%E6%9F%93%E7%9B%AE%E6%A0%87-%E7%94%BB%E7%AC%94/%E6%B7%B7%E5%90%88%E6%A8%A1%E5%BC%8F_Additive%E6%95%88%E6%9E%9C.png)
画笔的属性
一个画笔的属性可以分为:
- 画笔位置(图中对应传入 B 节点的二维向量 Position)
- 尺寸大小(图中对应 Radius)
- 硬度(图中对应 Hardness)
在这里提升为参数需要“右键点击->提升为参数”:
![alt text](/2024/04/26/%E8%BD%AF%E4%BB%B6%E5%AD%A6%E4%B9%A0/UE/UE%E5%8A%9F%E8%83%BD%E5%AE%9E%E7%8E%B0/%E8%93%9D%E5%9B%BE/%E3%80%90%E8%93%9D%E5%9B%BE%E3%80%91%E6%B8%B2%E6%9F%93%E7%9B%AE%E6%A0%87-%E7%94%BB%E7%AC%94/%E6%9D%90%E8%B4%A8%E8%93%9D%E5%9B%BE%E4%B8%AD%E7%9A%84%E6%8F%90%E5%8D%87%E4%B8%BA%E5%8F%82%E6%95%B0.png)
四维和二维,以及 ComponentMask
当位置信息被提升为变量之后,输出信息变为四维
![alt text](/2024/04/26/%E8%BD%AF%E4%BB%B6%E5%AD%A6%E4%B9%A0/UE/UE%E5%8A%9F%E8%83%BD%E5%AE%9E%E7%8E%B0/%E8%93%9D%E5%9B%BE/%E3%80%90%E8%93%9D%E5%9B%BE%E3%80%91%E6%B8%B2%E6%9F%93%E7%9B%AE%E6%A0%87-%E7%94%BB%E7%AC%94/%E7%94%BB%E7%AC%94Position.png)
而 SphereMask 需要的位置信息为二维,这里需要使用到 ComponentMask
![alt text](/2024/04/26/%E8%BD%AF%E4%BB%B6%E5%AD%A6%E4%B9%A0/UE/UE%E5%8A%9F%E8%83%BD%E5%AE%9E%E7%8E%B0/%E8%93%9D%E5%9B%BE/%E3%80%90%E8%93%9D%E5%9B%BE%E3%80%91%E6%B8%B2%E6%9F%93%E7%9B%AE%E6%A0%87-%E7%94%BB%E7%AC%94/ComponentMask.png)
得到画布
绘制到渲染目标 TextureRendererTarget
为了接收画笔的绘制效果,需要有一个画布进行储存,这里使用渲染目标
![alt text](/2024/04/26/%E8%BD%AF%E4%BB%B6%E5%AD%A6%E4%B9%A0/UE/UE%E5%8A%9F%E8%83%BD%E5%AE%9E%E7%8E%B0/%E8%93%9D%E5%9B%BE/%E3%80%90%E8%93%9D%E5%9B%BE%E3%80%91%E6%B8%B2%E6%9F%93%E7%9B%AE%E6%A0%87-%E7%94%BB%E7%AC%94/TextureRenderTarget2D.png)
连接画笔和画布
准备工作
在新建的蓝图 Actor 类中,用下图节点,来实现画笔绘制到画布的逻辑:
![alt text](/2024/04/26/%E8%BD%AF%E4%BB%B6%E5%AD%A6%E4%B9%A0/UE/UE%E5%8A%9F%E8%83%BD%E5%AE%9E%E7%8E%B0/%E8%93%9D%E5%9B%BE/%E3%80%90%E8%93%9D%E5%9B%BE%E3%80%91%E6%B8%B2%E6%9F%93%E7%9B%AE%E6%A0%87-%E7%94%BB%E7%AC%94/DrawMaterialToRenderTarget.png)
这个节点接收一个动态材质,并绘制在目标上,所以我们需要在开始时创建一个动态材质并保存:
![alt text](/2024/04/26/%E8%BD%AF%E4%BB%B6%E5%AD%A6%E4%B9%A0/UE/UE%E5%8A%9F%E8%83%BD%E5%AE%9E%E7%8E%B0/%E8%93%9D%E5%9B%BE/%E3%80%90%E8%93%9D%E5%9B%BE%E3%80%91%E6%B8%B2%E6%9F%93%E7%9B%AE%E6%A0%87-%E7%94%BB%E7%AC%94/%E5%88%9B%E5%BB%BA%E5%8A%A8%E6%80%81%E6%9D%90%E8%B4%A8%E5%B9%B6%E4%BF%9D%E5%AD%98.png)
这个材质的创建就需要用到在“得到画笔”那一部分创建的材质,也因此这个材质可以进行设置其大小和硬度(也可以设置其他的参数)
这里创建一个自定义事件“CE_Draw”,画笔的大小这里暂时不进行设置:
![alt text](/2024/04/26/%E8%BD%AF%E4%BB%B6%E5%AD%A6%E4%B9%A0/UE/UE%E5%8A%9F%E8%83%BD%E5%AE%9E%E7%8E%B0/%E8%93%9D%E5%9B%BE/%E3%80%90%E8%93%9D%E5%9B%BE%E3%80%91%E6%B8%B2%E6%9F%93%E7%9B%AE%E6%A0%87-%E7%94%BB%E7%AC%94/%E8%87%AA%E5%AE%9A%E4%B9%89%E4%BA%8B%E4%BB%B6%EF%BC%9ADraw.png)
为了在画布上绘制图像,自然需要知道画笔的每一个位置,这里可以使用物体的 UV 信息来作为画笔的位置,最后再绘制到渲染目标上即可
获取画笔位置
这里可以通过射线检测的方式来获取画笔映射到画布上的位置。
![alt text](/2024/04/26/%E8%BD%AF%E4%BB%B6%E5%AD%A6%E4%B9%A0/UE/UE%E5%8A%9F%E8%83%BD%E5%AE%9E%E7%8E%B0/%E8%93%9D%E5%9B%BE/%E3%80%90%E8%93%9D%E5%9B%BE%E3%80%91%E6%B8%B2%E6%9F%93%E7%9B%AE%E6%A0%87-%E7%94%BB%E7%AC%94/LineTraceForObjects.png)
这里设置简单的情景,画布水平放置,画笔垂直画布向下,因此可以设置Start
(画笔位置)和End
(从画笔位置向下延伸一定距离)
![alt text](/2024/04/26/%E8%BD%AF%E4%BB%B6%E5%AD%A6%E4%B9%A0/UE/UE%E5%8A%9F%E8%83%BD%E5%AE%9E%E7%8E%B0/%E8%93%9D%E5%9B%BE/%E3%80%90%E8%93%9D%E5%9B%BE%E3%80%91%E6%B8%B2%E6%9F%93%E7%9B%AE%E6%A0%87-%E7%94%BB%E7%AC%94/%E4%BB%8E%E7%94%BB%E7%AC%94%E4%BD%8D%E7%BD%AE%E5%90%91%E4%B8%8B%E7%9A%84%E5%B0%84%E7%BA%BF%E6%A3%80%E6%B5%8B.png)
另外我们也可以将ObjectTypes
和ActorsToIgnore
节点进行MakeArray
,来设置想要检测的目标和想要忽略的目标:
![alt text](/2024/04/26/%E8%BD%AF%E4%BB%B6%E5%AD%A6%E4%B9%A0/UE/UE%E5%8A%9F%E8%83%BD%E5%AE%9E%E7%8E%B0/%E8%93%9D%E5%9B%BE/%E3%80%90%E8%93%9D%E5%9B%BE%E3%80%91%E6%B8%B2%E6%9F%93%E7%9B%AE%E6%A0%87-%E7%94%BB%E7%AC%94/ObjectTypesMakeArray.png)
最后判断是否检测到画布,并获取碰撞位置的 UV 信息,最终传递给绘制事件进行绘制:
![alt text](/2024/04/26/%E8%BD%AF%E4%BB%B6%E5%AD%A6%E4%B9%A0/UE/UE%E5%8A%9F%E8%83%BD%E5%AE%9E%E7%8E%B0/%E8%93%9D%E5%9B%BE/%E3%80%90%E8%93%9D%E5%9B%BE%E3%80%91%E6%B8%B2%E6%9F%93%E7%9B%AE%E6%A0%87-%E7%94%BB%E7%AC%94/%E8%8E%B7%E5%8F%96%E4%BD%8D%E7%BD%AEUV%E4%BF%A1%E6%81%AF%E5%B9%B6%E7%BB%98%E5%88%B6.png)
这里需要注意:获取碰撞位置 UV,需要在“项目设置”中的“物理->优化->(勾选)支持撞击结果的 UV”,重启编辑器才能正常获得
![](/2024/04/26/%E8%BD%AF%E4%BB%B6%E5%AD%A6%E4%B9%A0/UE/UE%E5%8A%9F%E8%83%BD%E5%AE%9E%E7%8E%B0/%E8%93%9D%E5%9B%BE/%E3%80%90%E8%93%9D%E5%9B%BE%E3%80%91%E6%B8%B2%E6%9F%93%E7%9B%AE%E6%A0%87-%E7%94%BB%E7%AC%94/%E5%BC%80%E5%90%AF%E8%8E%B7%E5%8F%96UV.png)
绘制效果:
![alt text](/2024/04/26/%E8%BD%AF%E4%BB%B6%E5%AD%A6%E4%B9%A0/UE/UE%E5%8A%9F%E8%83%BD%E5%AE%9E%E7%8E%B0/%E8%93%9D%E5%9B%BE/%E3%80%90%E8%93%9D%E5%9B%BE%E3%80%91%E6%B8%B2%E6%9F%93%E7%9B%AE%E6%A0%87-%E7%94%BB%E7%AC%94/%E7%BB%98%E5%88%B6%E6%95%88%E6%9E%9C%E7%A4%BA%E6%84%8F%E5%9B%BE.png)
在物体上绘制
之前我们所谓设置的画布,其实是一个遮罩,也就是上边效果图中下方的渲染目标RT_DrawCanvas
,结合Lerp
节点,可以很轻松的在两个纹理之间进行涂抹。
![alt text](/2024/04/26/%E8%BD%AF%E4%BB%B6%E5%AD%A6%E4%B9%A0/UE/UE%E5%8A%9F%E8%83%BD%E5%AE%9E%E7%8E%B0/%E8%93%9D%E5%9B%BE/%E3%80%90%E8%93%9D%E5%9B%BE%E3%80%91%E6%B8%B2%E6%9F%93%E7%9B%AE%E6%A0%87-%E7%94%BB%E7%AC%94/%E4%B8%A4%E4%B8%AA%E6%9D%90%E8%B4%A8%E7%9A%84%E7%BB%98%E5%88%B6.png)
总结
一些简单的功能结合起来,能够实现很复杂的效果。对于刚起步的我来说,什么看起来都很神秘,学的越多,不会的就越多,不会的越多,学的就越多,所以学的越多,学的越多。
自定义画笔样式:Begin/End Draw Canvas to Render Target
下面尝试修改画笔样式,准备图片如下:
![Kokona 可爱捏](/2024/04/26/%E8%BD%AF%E4%BB%B6%E5%AD%A6%E4%B9%A0/UE/UE%E5%8A%9F%E8%83%BD%E5%AE%9E%E7%8E%B0/%E8%93%9D%E5%9B%BE/%E3%80%90%E8%93%9D%E5%9B%BE%E3%80%91%E6%B8%B2%E6%9F%93%E7%9B%AE%E6%A0%87-%E7%94%BB%E7%AC%94/%E5%8D%B0%E7%AB%A0.png)
之前画笔绘制的策略是,给画笔生成一个动态材质,将这个材质绘制到渲染目标上。
现在需要将目标纹理绘制到渲染目标上,
![节点:Begin/End Draw Canvas to Render Target](/2024/04/26/%E8%BD%AF%E4%BB%B6%E5%AD%A6%E4%B9%A0/UE/UE%E5%8A%9F%E8%83%BD%E5%AE%9E%E7%8E%B0/%E8%93%9D%E5%9B%BE/%E3%80%90%E8%93%9D%E5%9B%BE%E3%80%91%E6%B8%B2%E6%9F%93%E7%9B%AE%E6%A0%87-%E7%94%BB%E7%AC%94/%E5%BC%80%E5%A7%8B%E6%88%96%E7%BB%93%E6%9D%9F%E7%BB%98%E5%88%B6%E7%94%BB%E5%B8%83%E5%88%B0%E6%B8%B2%E6%9F%93%E7%9B%AE%E6%A0%87.png)
注意最后要连接节点结束绘制画布到渲染目标
从Canvas
节点调用DrawTexture
,选择画笔样式
![绘制纹理](/2024/04/26/%E8%BD%AF%E4%BB%B6%E5%AD%A6%E4%B9%A0/UE/UE%E5%8A%9F%E8%83%BD%E5%AE%9E%E7%8E%B0/%E8%93%9D%E5%9B%BE/%E3%80%90%E8%93%9D%E5%9B%BE%E3%80%91%E6%B8%B2%E6%9F%93%E7%9B%AE%E6%A0%87-%E7%94%BB%E7%AC%94/%E7%BB%98%E5%88%B6%E7%BA%B9%E7%90%86.png)
注意这里:如果选用的目标图片没有通道,需要在下边BlendMode
选择Additive
可叠加,从而去掉黑色部分
这里先这样,将该自定义事件替换之前设置好的Draw
通过修改ScreenPosition
来改变其在画布上的位置
这里要注意:该事件会从画笔的碰撞位置获取 UV 信息,而 UV 信息是 0~1 之间的,所以在这里要根据画布的分辨率进行调整,如下图所示
![根据画布分辨率调整](/2024/04/26/%E8%BD%AF%E4%BB%B6%E5%AD%A6%E4%B9%A0/UE/UE%E5%8A%9F%E8%83%BD%E5%AE%9E%E7%8E%B0/%E8%93%9D%E5%9B%BE/%E3%80%90%E8%93%9D%E5%9B%BE%E3%80%91%E6%B8%B2%E6%9F%93%E7%9B%AE%E6%A0%87-%E7%94%BB%E7%AC%94/%E6%A0%B9%E6%8D%AE%E7%94%BB%E5%B8%83%E5%88%86%E8%BE%A8%E7%8E%87%E8%B0%83%E6%95%B4.png)
此时运行会发现:
![画笔偏移](/2024/04/26/%E8%BD%AF%E4%BB%B6%E5%AD%A6%E4%B9%A0/UE/UE%E5%8A%9F%E8%83%BD%E5%AE%9E%E7%8E%B0/%E8%93%9D%E5%9B%BE/%E3%80%90%E8%93%9D%E5%9B%BE%E3%80%91%E6%B8%B2%E6%9F%93%E7%9B%AE%E6%A0%87-%E7%94%BB%E7%AC%94/%E7%94%BB%E7%AC%94%E5%81%8F%E7%A7%BB.png)
我们设置的图片位置发生偏移,原因是图片的中心(或者说纹理坐标原点)位于图片的左上角。
因此,这里还需要再减去画笔样式图片的一半
![画笔归中](/2024/04/26/%E8%BD%AF%E4%BB%B6%E5%AD%A6%E4%B9%A0/UE/UE%E5%8A%9F%E8%83%BD%E5%AE%9E%E7%8E%B0/%E8%93%9D%E5%9B%BE/%E3%80%90%E8%93%9D%E5%9B%BE%E3%80%91%E6%B8%B2%E6%9F%93%E7%9B%AE%E6%A0%87-%E7%94%BB%E7%AC%94/%E7%94%BB%E7%AC%94%E6%A0%B7%E5%BC%8F%E5%BD%92%E4%B8%AD.png)
此时再次运行发现效果正确:
![自定义画笔最终效果](/2024/04/26/%E8%BD%AF%E4%BB%B6%E5%AD%A6%E4%B9%A0/UE/UE%E5%8A%9F%E8%83%BD%E5%AE%9E%E7%8E%B0/%E8%93%9D%E5%9B%BE/%E3%80%90%E8%93%9D%E5%9B%BE%E3%80%91%E6%B8%B2%E6%9F%93%E7%9B%AE%E6%A0%87-%E7%94%BB%E7%AC%94/%E6%9C%80%E7%BB%88%E6%95%88%E6%9E%9C.png)
案例复刻
- 清理花园
- 地形画画(虚拟纹理)
- 平面画画(置换效果)