__本篇博客基于序列帧动画V0.1
链接: Unity HLSL Shader 序列帧动画V0.1
__文题修正:当序列帧图片只有一行时会出现图片没显示的bug,修复方法是对offset的xy值进行锁定(saturate)。
__修正后的代码
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 = saturate((frameIndex % c) * sizeX);
offset.y = saturate(1 - sizeY - floor(frameIndex / r) * sizeY);
half4 baseMap = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, uv + offset);
return baseMap;
}
ENDHLSL
}
}
}