广告牌+序列帧的Shader效果

发布于:2025-08-04 ⋅ 阅读:(15) ⋅ 点赞:(0)

首先清点自己需要什么资源,序列帧动画需要的是序列帧的图片

序列帧 - 免费 免费下载 - 爱给网

对于图片使用时黑边的问题

AlphaTest Greater 0.5 的意思是:

只有当片元(Fragment)的 Alpha 值 > 0.5 时,才通过 Alpha 测试,才会写入颜色缓冲。

AlphaTest 是 Unity 内置渲染管线(Built-in RP) 中的一个固定功能(Fixed Function Pipeline),但是在直接使用上,没有discard好用

更现代的做法:if (alpha <= 0.5) discard;
这和 AlphaTest Greater 0.5 是逻辑等价的,但更灵活且适用于 URP/HDRP/SRP 等。

广告牌,是通过修改vertex的位置,让frag接受到变化后的三角面片覆盖区域,需要的是修改vert 中的o.pos = UnityObjectToClipPos(*****);

构建 视角方向为normal,向上为固定轴,点乘出第三向量,然后通过第三向量和normal点乘得到真正的三个基向量(局部坐标变换矩阵),

                // Suppose the center in object space is fixed

                float3 center = float3(0, 0, 0);

                float3 viewer = mul(unity_WorldToObject,float4(_WorldSpaceCameraPos, 1));

这里的000,使用的时候,没有规定坐标系,而当它与model坐标系的vertexPos相计算 的时候

这个000就会被 归到model坐标系下,,这是无坐标系点的吸附(为了达成广告牌,逻辑层面上的一种解释)


这三个基向量构成的矩阵,如果乘以(0,0,0)到model坐标系下的一个xyz点 的向量,
会对xyz的数值进行Transform,而这个Transform,实际上是把在model坐标系下的向量表示值,换成了在新local坐标系下的向量表示值,

宏观上来讲,向量的方向没有发生变化,只是在新的坐标系里,xyz都变了,
这个新的坐标系称为local,
而重点是,如果此时用local里的xyz值再回到model坐标系里此时xyz都是local坐标系的表示方法,如果强行用model坐标系表示,就产生了旋转差异

序列帧逻辑

 VertexOutput o = (VertexOutput)0;

                //v.vertex.xyz += v.normal * 0.03;            // 顶点位置法向挤出,,原本是庄懂用了两张图片叠加的原因

                //o.pos = UnityObjectToClipPos(v.vertex);     // 顶点位置 OS>CS

                o.uv = TRANSFORM_TEX(v.uv, _Sequence);      // 前置UV ST操作

                float id = floor(_Time.z * _Speed);         // 计算序列id

                float idV = floor(id / _ColCount);          // 计算V轴id

                float idU = id - idV * _ColCount;           // 计算U轴id

                float stepU = 1.0 / _ColCount;              // 计算U轴步幅

                float stepV = 1.0 / _RowCount;              // 计算V轴步幅

                float2 initUV = o.uv * float2(stepU, stepV) + float2(0.0, stepV * (_RowCount - 1.0));   // 计算初始UV

                o.uv = initUV + float2(idU * stepU, -idV * stepV);   // 计算序列帧UV


广告牌的逻辑

                float3 normalDir = viewer - center;

                // If _VerticalBillboarding equals 1, we use the desired view dir as the normal dir

                // Which means the normal dir is fixed

                // Or if _VerticalBillboarding equals 0, the y of normal is 0

                // Which means the up dir is fixed

                normalDir.y = normalDir.y * _VerticalBillboarding;

                normalDir = normalize(normalDir);

                // Get the approximate up dir

                // If normal dir is already towards up, then the up dir is towards front

                float3 upDir = abs(normalDir.y) > 0.999 ? float3(0, 0, 1) : float3(0, 1, 0);

                float3 rightDir = normalize(cross(upDir, normalDir));

                upDir = normalize(cross(normalDir, rightDir));

               

                // Use the three vectors to rotate the quad

                float3 centerOffs = v.vertex.xyz - center;

                float3 localPos = center + rightDir * centerOffs.x + upDir * centerOffs.y + normalDir * centerOffs.z;

               

                o.pos = UnityObjectToClipPos(float4(localPos, 1));

                return o;

透明区域黑,和不显示

一直没有显示出来原因是cull off没有写,可能是旋转坐标系反向了,我看到的一直是背面?

            half4 frag(VertexOutput i) : SV_Target

            {

                half4 var_Sequence = tex2D(_Sequence, i.uv);      // 采样贴图 RGB颜色 A透贴

                if (var_Sequence.a < 0.2) discard;               // 透明度裁剪

                half3 finalRGB = var_Sequence.rgb * _Color.rgb; // 颜色混合

                half opacity = var_Sequence.a * _Opacity;

                //return opacity;        // 返回值

                return half4(finalRGB * opacity, opacity);        // 返回值

            }

无论mesh的形状,添加了广告牌,里面会造成这样的结果

但是加上序列帧之后,又cube有特殊了,算了,先做

unity store找一下third person controller

用于制作游戏的优质资源 | Unity Asset Store

Third Person Controller - Basic Locomotion FREE | Game Toolkits | Unity Asset Store


网站公告

今日签到

点亮在社区的每一天
去签到