目标:
Unity 序列帧动画shader步骤:
- 定义序列帧图的行数和列数
_RowNums ("Row Nums", float) = 0 _ColumnNums ("Column Nums", float) = 0
- 定义帧数的位置(这样做方便直接脚本控制或者animation控制)
_FrameIndex ("FrameIndex", Range(0, 1)) = 0
- uv查找算法
float r = floor(_RowNums); float c = floor(_ColumnNums); float sizeX = 1.0f / c; float sizeY = 1.0f / r; float frameIndex = floor((r * c - 1) * _FrameIndex); float2 uv = float2(IN.uv.x, IN.uv.y) / float2(c, r); float2 offset = float2(0, 0); offset.x = (frameIndex % c) * sizeX; offset.y = 1 - sizeY - floor(frameIndex / r) * sizeY;
- 完整shader
Shader "FramePlayer" { Properties { [NoScaleOffset]_BaseMap (" Texture", 2D) = "white" {} _RowNums ("Row Nums", float) = 0 _ColumnNums ("Column Nums", float) = 0 _FrameIndex ("FrameIndex", Range(0, 1)) = 0 } SubShader { Tags { "RenderType"="Opaque" "RenderPipeline"="UniversalPipeline" } HLSLINCLUDE #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" CBUFFER_START(UnityPerMaterial) float4 _BaseColor; float _RowNums; float _ColumnNums; float _FrameIndex; CBUFFER_END ENDHLSL Pass { Name "Example" Tags { "LightMode"="UniversalForward" "Queue"="Transparent"} Blend SrcAlpha OneMinusSrcAlpha HLSLPROGRAM #pragma vertex vert #pragma fragment frag struct Attributes { float4 positionOS : POSITION; float2 uv : TEXCOORD0; }; struct Varyings { float4 positionCS : SV_POSITION; float2 uv : TEXCOORD0; }; TEXTURE2D(_BaseMap); SAMPLER(sampler_BaseMap); Varyings vert(Attributes IN) { Varyings OUT; VertexPositionInputs positionInputs = GetVertexPositionInputs(IN.positionOS.xyz); OUT.positionCS = positionInputs.positionCS; OUT.uv = IN.uv; return OUT; } half4 frag(Varyings IN) : SV_Target { float r = floor(_RowNums); float c = floor(_ColumnNums); float sizeX = 1.0f / c; float sizeY = 1.0f / r; float frameIndex = floor((r * c - 1) * _FrameIndex); float2 uv = float2(IN.uv.x, IN.uv.y) / float2(c, r); float2 offset = float2(0, 0); offset.x = (frameIndex % c) * sizeX; offset.y = 1 - sizeY - floor(frameIndex / r) * sizeY; half4 baseMap = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, uv + offset); return baseMap; } ENDHLSL } } }
- 总结:一个方便脚本控制的序列帧shader