
這篇文章根大家分享一些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 和顏色就可以了 ~

我們如果把模型做成立體的 ,配合霧效就可以做出 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 free?www.freepik.com
字體來自
創意字體--商用字體_免費字體_字體下載_三極字庫官網?sjtype.com
工程下載
ShaderFallback/LowPolyShader?github.com