Unity3D手游项目的总结和思考(5) - 植被摆动3DMAX工具

xiaoxiao2021-02-28  23

       以前的博客有提到如何实现植被摆动的效果:点击打开链接

核心问题就是,摆动的幅度是根据什么样的权重.我简单分为三种.

1.UV坐标作为权重

2.顶点到模型原点的距离作为权重

3.顶点颜色作为权重

       以CE3引擎来讲,整体摆动用第二种,细节抖动用第三种,两种结合使用,就可以实现完美的摆动效果.但是用第二种,就不能用静态合批了.因为静态合批以后,模型的原点就变了,这个权重的计算也是错误的了.如果要用静态合批还要完美的摆动,怎么办呢?

       我想到一个办法,就是把第二种的权重,保存到顶点颜色的一个通道里面,这样即使静态合批了,这个权重值也不会改变的,那么问题来了,如何保存呢.打开3DMAX的顶点颜色绘制工具,你会发现根本就刷不出这种权重值,那么只能程序来生成了,所以我就用3DMAX的脚本语言写了一个工具来自动生成这个整体摆动的权重.

工具界面:

我用蓝色通道来保存这个整体摆动权重值.

过渡曲线我尝试了几种:

权重过渡支持从上到下或者从下到上,这样的好处是可以支持灯笼这种倒挂物件的摆动.

至于顶点摆动的代码,可参考Unity官方地形的植被动画的代码,其实都是从CE3改进过来的,我的有改写过:

inline float4 AnimateVertex2(float4 pos, half3 normal, fixed4 animParams, float4 wind) { // animParams stored in vertext color // animParams.x = branch phase = unused // animParams.y = edge bending factor = green // animParams.z = branch bending factor = red // animParams.w = main bending factor = blue float fDetailAmp = 0.1f; float fBranchAmp = 0.3f; // Phases (object, vertex, branch) float fObjPhase = dot(unity_ObjectToWorld[3].xyz, 1); float fBranchPhase = fObjPhase;// + animParams.x; float fVtxPhase = dot(pos.xyz, animParams.y + fBranchPhase); // x is used for edges; y is used for branches float2 vWavesIn = _EdgeFrequencyFactor * _Time.yy + pos.xz *.3 + float2(fVtxPhase, fBranchPhase ); float4 vWaves = (frac( vWavesIn.xxyy * float4(1.975, 0.793, 0.375, 0.193) ) * 2.0 - 1.0); vWaves = SmoothTriangleWave( vWaves ); float2 vWavesSum = vWaves.xz + vWaves.yw; // Edge (xz) and branch bending (y) // sign important to match normals of both faces!!! otherwise edge fluttering will be corrupted. float3 bend = animParams.y * fDetailAmp * normal.xyz * sign(normal.xyz) * _EdgeBendingFactor; bend.y = animParams.z * fBranchAmp * _BranchBendingFactor; pos.xyz += vWavesSum.xyx * bend * wind.w; // main bending float3 mainBend = wind.xyz * wind.w * animParams.w * _MainBendingFactor; pos.xyz += mainBend * vWavesSum.y * _MainBendingFactor2; pos.xyz += mainBend; return pos; }

max脚本:

Utility LuoyinanVertexColorTool "LuoyinanVertexColorTool" ( global g_CurveType = "cubic" global g_FadeDirection = "up" Dropdownlist ddlist "Curve Type:" items:#("cubic","quadratic","linear") on ddlist selected i do g_CurveType = ddlist.items[i] Dropdownlist ddlist2 "Fade Direction:" items:#("up","down") on ddlist2 selected i do g_FadeDirection = ddlist2.items[i] button b "Start Paint" on b pressed do ( for selectNode in selection do ( Recursion selectNode ) ) ) fn Recursion node= ( if (Editable_mesh == classOf node) then ( ModifyVertexColor node ) else ( for i = 1 to node.children.count do Recursion node.children[i] ) ) fn ModifyVertexColor node= ( addModifier node (vertexPaint()) collapseStack node theMesh = node.mesh numtverts = getNumVerts theMesh print (format "g_CurveType:% g_FadeDirection:%\n" g_CurveType g_FadeDirection) print (format "name:% numfaces:% numtverts:% numcpvverts:% getNumVerts:%\n" node.name theMesh.numfaces theMesh.numtverts theMesh.numcpvverts numtverts) minHeight = 100000 maxHeight = -100000 for v = 1 to numtverts do ( vert = getVert theMesh v if (vert.z > maxHeight) then (maxHeight = vert.z) if (vert.z < minHeight) then (minHeight = vert.z) ) for f = 1 to theMesh.numfaces do ( face = getFace theMesh f v1 = getVert theMesh face.x v2 = getVert theMesh face.y v3 = getVert theMesh face.z w1 = (v1.z - minHeight) / (maxHeight - minHeight) w2 = (v2.z - minHeight) / (maxHeight - minHeight) w3 = (v3.z - minHeight) / (maxHeight - minHeight) if (g_FadeDirection == "down")then ( w1 = 1 - w1 w2 = 1 - w2 w3 = 1 - w3 ) if (g_CurveType == "cubic") then ( w1 = 2 * w1 * w1 * w1 / (1 + w1) w2 = 2 * w2 * w2 * w2 / (1 + w2) w3 = 2 * w3 * w3 * w3 / (1 + w3) ) else if (g_CurveType == "quadratic") then ( w1 = 2 * w1 * w1 / (1 + w1) w2 = 2 * w2 * w2 / (1 + w2) w3 = 2 * w3 * w3 / (1 + w3) ) vc_face = getVCFace theMesh f vc1 = getVertColor theMesh vc_face.x vc2 = getVertColor theMesh vc_face.y vc3 = getVertColor theMesh vc_face.z vc1.b = w1 * 255 vc2.b = w2 * 255 vc3.b = w3 * 255 setVertColor theMesh vc_face.x vc1 setVertColor theMesh vc_face.y vc2 setVertColor theMesh vc_face.z vc3 ) update theMesh )

至于MAX脚本的如何使用,请自行百度...

转载请注明原文地址: https://www.6miu.com/read-2800230.html

最新回复(0)