这篇文章根大家分享一些LowPoly动态效果的制作方法,由于使用的是uv采样方式效率很高,手机也可以随意使用,我们先来看一些效果的参考
本文将在Unity3D中还原这些效果,如果你学会后当然可以在你喜欢的引擎中实现~如果一篇太长有可能会分多篇,感兴趣的可以关注我~
参考图
完成效果
以往我们在实现多边形渐变是多是遍历定顶点修改vertexColor去实现,本效果将重UV下手
首先需要一个做一个特殊的uv,我将用maya举例(当然也可以请美术的小伙伴帮助制作Mesh)
我们首先需要这样的一个面片
我们先以这个基础的网格举例,Windows -> UV Texture Editor 打开uv 编辑器
这时uv是个样子,我们需要将uv打断,并将每个方格的uv 缩放为一个点(这就是本篇的重点了)也就是说每个网格mesh上的面uv只有一个点大小,有很多方法可以实现,我讲的方法不一定是最好的,大家可以大开脑洞~
1.选中模型按鼠标右键切换为点显示
2.框选所有的点,然后EditMesh->DetachComponent (分离组件)
3.我们再次切换为物体模式
4.我们再次点击菜单 Mesh-> Separate (分离Mesh)
其实我们上面的主要操作就是为了以线分割mesh将一个大面片分割成小面片
5.这时所有的小mesh 的中心点都在一起(也就是原来大mesh的中心点)我们全选所有被缩小的mesh 进行中心点恢复 Modify-> CenterPivot
这时所有的小mesh的中心点都在自己的位置了,下面我们对他进行缩放
6.在右边通道栏我们将其缩放到 0.001后,点击菜单 CreateUVs -> PlanarMapping,我们点击后面的小方块打开选项设置,选中y 轴投射UV
这时uv 就变成点状了 ,全选所有小mesh在右边通道栏我们将mesh缩放恢复回来
7.现在点击菜单栏 Mesh->Combine 将所有小mesh 组合到一起 ,这时点还没有合并
8.切换为点模式 全选所有点,点击菜单 EditMesh-> Merge ,这时mesh就恢复为一个整体了
UV 也已经被我们处理为点状 ,当然我们可以使用脚本处理这个过程,下面是批处理脚本,选中模型后点击 CreateUV 将会创建二套uv 并命名为lowPoly(需要注意一点,maya 中map1 对应shader中 uv0,lowPoly对应 uv1,依次类推)
import sys
import maya.cmds as cmd
def detachPoly(firstObject,faces):#分离选中Mesh(kft) cmd.polyChipOff (firstObject +'.f[0:%d]'%faces,kft=False,dup=False) cmd.polySeparate (firstObject,rs=True)def centerPivot(allSelected,scaleValue):#恢复中心点/缩放for i in allSelected:cmd.xform(i, centerPivots=True) cmds.setAttr(i + "." + "scale", scaleValue, scaleValue,scaleValue, type="double3")
def CreateUV(*args):selected = cmd.ls( selection=True )firstObject = selected[0]faces = cmd.polyEvaluate(firstObject,f=True)#获取面数detachPoly(firstObject,faces)selected = cmd.ls(selection =True)centerPivot(selected,0.001)cmd.selectMode( component=True )for i in selected:cmds.select(i+'.f[0]', add=True ) #选中所有Meshcmd.polyProjection(type='Planar' ,md ='y',uvs ='lowPoly',ibd = True,cm =True) #投影uvcenterPivot(selected,1)cmd.polyUnite(selected,n = firstObject) #合并Meshcmd.polyMergeVertex(d = 0.1) #合并点cmd.DeleteAllHistory()def stripsCreate(*args):windowID = 'PointProcessing'if cmds.window(windowID, exists=1):cmds.deleteUI(windowID)cmds.window(windowID, title='UV PointProcessing', menuBar=1, h=100, w=200)cmds.columnLayout(adjustableColumn=1)cmds.button(label='Create UV', command=partial(CreateUV), h=50,w=100)cmds.columnLayout(adjustableColumn=1)cmds.showWindow(windowID)stripsCreate()
导出之前记得删除所有的构造历史 Edit-> DeleteAllbyType->History
顺便说下maya的默认单位是厘米,Unity是米,如果你想1:1 导出
记得在设置将maya 单位设置为米
这时就可以导入到Unity中,shader部分比较简单直接上代码,需要注意的一点就是 由于我们uv是近似的一个点,如果想有平滑的过度效果 Mask图不能压缩 需要设置为RBG 24 ,因为图片分辨率不需要很大所以实际也占不了多少内存
Shader "lowPolygon" {Properties {_Color ("Color", Color) = (0,0.1721497,3301887,1)_Color2("Color2", Color) = (0.2783019,0.6024179,1,1)_texture ("texture", 2D) = "white" {}_speed ("speed", Float ) = 5_tiling("tiling", Float) = 0.01}SubShader {Tags {"RenderType"="Opaque"}Pass {Name "FORWARD"Tags {"LightMode"="ForwardBase"}CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"uniform float4 _TimeEditor;uniform float4 _Color, _Color2;uniform sampler2D _texture; uniform float4 _texture_ST;uniform float _speed, _tiling;struct VertexInput {float4 vertex : POSITION;float2 texcoord0 : TEXCOORD0;};struct VertexOutput {float4 pos : SV_POSITION;float2 uv0 : TEXCOORD0;};VertexOutput vert (VertexInput v) {VertexOutput o = (VertexOutput)0;o.uv0 = v.texcoord0;o.pos = UnityObjectToClipPos(v.vertex );return o;}float4 frag(VertexOutput i) : COLOR {float4 materialTime = _Time + _TimeEditor;float2 texUv = i.uv0+(materialTime.g *_speed)* _tiling;//mask需要四方连续float4 texture_var = tex2D(_texture,TRANSFORM_TEX(texUv, _texture));float3 emissive = lerp(_Color.rgb, _Color2.rgb,texture_var.r);return fixed4(emissive,1);}ENDCG}}
}
将材质赋予刚才导入的面片就是下面的效果
知乎视频www.zhihu.com我们先来实现参考图1 的效果 ,实际上我们只需要将上面的视频中的效果增加一些渐变色就可以达到了,新增两个Mask G通道 控制左右分色 B通道控制重中间向两边的压暗区域
struct VertexInput {float4 vertex : POSITION;float2 texcoord0 : TEXCOORD0;float2 texcoord1 : TEXCOORD1;};struct VertexOutput {float4 pos : SV_POSITION;float2 uv0 : TEXCOORD0;float2 uv1 : TEXCOORD1;};VertexOutput vert (VertexInput v) {VertexOutput o = (VertexOutput)0;o.pos = UnityObjectToClipPos(v.vertex );o.uv0 = v.texcoord0;o.uv1 = v.texcoord1;return o;}float4 frag(VertexOutput i) : COLOR {float4 materialTime = _Time + _TimeEditor;float2 texUv = i.uv0+(materialTime.g *_speed)* _tiling;float texture_R = tex2D(_texture,TRANSFORM_TEX(texUv, _texture)).r;float texture_G = tex2D(_texture, TRANSFORM_TEX(i.uv1, _texture)).g; //Mask要用正常的uv,mesh里要展uv2float texture_B = tex2D(_texture, TRANSFORM_TEX(i.uv1, _texture)).b; //Mask要用正常的uv,mesh里要展uv2float3 color_L = lerp(_ColorL_1.rgb, _ColorL_2.rgb, texture_R);float3 color_R = lerp(_ColorR_1.rgb, _ColorR_2.rgb, texture_R );float3 colorlerp = lerp(color_L, color_R, texture_G) * (texture_B + _Dark);return fixed4(colorlerp,1);}
第二个效果只需要改变下B通道 Mask 和颜色就可以了 ~
知乎视频www.zhihu.com我们如果把模型做成立体的 ,配合雾效就可以做出 3 号图的效果
我们增加一些颜色控制可以增强颜色的表现力,也可以增加一些顶点的抖动,我这里还使用原来那张贴图,你可以算一个随机值
Shader "lowPolygon_2" {Properties {_ColorL_1("ColorL_1", Color) = (0,0.1721497,3301887,1)_ColorL_2("ColorL_2", Color) = (0.2783019,0.6024179,1,1)_ColorL_3("ColorL_3", Color) = (0.2783019,0.6024179,1,1)_ColorL_Offset_1("ColorL_Offset_1", Float) = 1_ColorL_Offset_2("ColorL_Offset_2", Float) = 1_ColorR_1("ColorR_1", Color) = (0,0.1721497,3301887,1)_ColorR_2("ColorR_2", Color) = (0.2783019,0.6024179,1,1)_ColorR_3("ColorR_3", Color) = (0.2783019,0.6024179,1,1)_ColorR_Offset_1("ColorR_Offset_1", Float) = 1_ColorR_Offset_2("ColorR_Offset_2", Float) = 1_Dark("Dark", Float) = 1_texture ("texture", 2D) = "white" {}_speed ("speed", Float ) = 5_tiling("tiling", Float) = 0.01_vertexHeight("vertexHeight",Float) = 1}SubShader {Tags {"RenderType"="Opaque"}Pass {Name "FORWARD"Tags {"LightMode"="ForwardBase"}CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"#pragma multi_compile_foguniform float4 _TimeEditor;uniform float4 _ColorL_1, _ColorL_2, _ColorL_3, _ColorR_1, _ColorR_2, _ColorR_3;uniform sampler2D _texture; uniform float4 _texture_ST;uniform float _speed, _tiling, _Dark , _vertexHeight, _ColorL_Offset_1, _ColorL_Offset_2, _ColorR_Offset_1, _ColorR_Offset_2;struct VertexInput {float4 vertex : POSITION;float2 texcoord0 : TEXCOORD0;float2 texcoord1 : TEXCOORD1;};struct VertexOutput {float4 pos : SV_POSITION;//float2 uv0 : TEXCOORD0;float2 uv1 : TEXCOORD1;float2 timeUv : TEXCOORD2;UNITY_FOG_COORDS(4)};VertexOutput vert (VertexInput v) {VertexOutput o = (VertexOutput)0;float4 materialTime = _Time + _TimeEditor;float2 texUv0 = v.texcoord0 + (materialTime.g * _speed) * _tiling;float2 texUv1 = v.texcoord1 + (materialTime.g * _speed) * _tiling;o.timeUv = texUv0; //注意下哦 我这里uv0 才是点状uv,如果你用脚本创建的uv这个要修改下float4 offset_var = tex2Dlod(_texture, float4(TRANSFORM_TEX(texUv1, _texture), 0.0, 0));v.vertex.xyz += offset_var.r * _vertexHeight;o.pos = UnityObjectToClipPos(v.vertex );UNITY_TRANSFER_FOG(o, o.pos);//o.uv0 = v.texcoord0;o.uv1 = v.texcoord1;return o;}float4 frag(VertexOutput i) : COLOR {float texture_R = tex2D(_texture,TRANSFORM_TEX(i.timeUv, _texture)).r;float texture_G = tex2D(_texture, TRANSFORM_TEX(i.uv1, _texture)).g; //Mask要用正常的uv,mesh里要展uv2float texture_B = tex2D(_texture, TRANSFORM_TEX(i.uv1, _texture)).b; //Mask要用正常的uv,mesh里要展uv2float3 color_L = lerp(_ColorL_1.rgb, _ColorL_2.rgb, texture_R * _ColorL_Offset_1);float3 color_L2 = lerp(color_L, _ColorL_3, saturate(pow(texture_R * _ColorL_Offset_2, 3)));float3 color_R = lerp(_ColorR_1.rgb, _ColorR_2.rgb, texture_R * _ColorR_Offset_1);float3 color_R2 = lerp(color_R, _ColorR_3, saturate(pow(texture_R * _ColorR_Offset_2, 3)));float3 colorlerp = lerp(color_L2, color_R2, texture_G) * (texture_B + _Dark);float4 finalColor = float4(colorlerp, 1);UNITY_APPLY_FOG(i.fogCoord, finalColor);return finalColor;}ENDCG}}FallBack "Diffuse"
}
也可以增加线框渲染再 配合不同mesh 和 mask ,Color 就可组合其他的效果出来~
参考图来自
Download Abstract Blue Triangle Geometric Pattern Banner Design for freewww.freepik.com字体来自
创意字体--商用字体_免费字体_字体下载_三极字库官网sjtype.com工程下载
ShaderFallback/LowPolyShadergithub.com