目标:
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
|