问题:
我编写了一个自定义着色器,用于从精灵表制作动画精灵(没有详细说明为什么我要这样做,而不是在这个项目中使用 Unity 的动画播放器”)。
效果很好,但投射的阴影是完整的精灵表,而不是 surf 方法中显示的当前单元格。例如,如果有一个包含 4 帧的精灵表。您将看到纸张的每个帧都有 4 个单独的阴影,而不是当前帧投射的阴影。
我可以更改材质属性中的“平铺”和“偏移”值来校正阴影。 但这需要 CPU 端的逻辑来更新它们,并且需要与着色器同步。
问题: 有没有办法将其纯粹保留在着色器中并具有正确的阴影?
这是附加的着色器:
Shader "Custom/Pixel_Sprite_Diffuse"
{
Properties
{
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
_Cutoff("Cutoff", Range(0, 1)) = 0.5
[ToggleOff] _SpecularHighlights ("Specular Highlights", Float) = 1.000000
[ToggleOff] _GlossyReflections ("Glossy Reflections", Float) = 1.000000
cell_x_count("Cell Count X", float) = 1
cell_y_count("Cell Count Y", float) = 1
frame_count("Frame Count", float) = 1
speed("Speed", float) = 1
}
SubShader
{
Tags{ "RenderType" = "TransparentCutout" "Queue" = "Transparent"}
ZWrite Off
//Tags{ "RenderType" = "Transparent" "Queue" = "TransparentCutout"}
//ZWrite Off Blend SrcAlpha OneMinusSrcAlpha
LOD 300
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Standard alphatest:_Cutoff
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
sampler2D _MainTex;
struct Input
{
float2 uv_MainTex;
};
half _Glossiness;
half _Metallic;
float _SpecularHighlights;
float _GlossyReflections;
fixed4 _Color;
float frame_count;
float cell_x_count;
float cell_y_count;
float speed;
// Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
// See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
// #pragma instancing_options assumeuniformscaling
UNITY_INSTANCING_BUFFER_START(Props)
// put more per-instance properties here
UNITY_INSTANCING_BUFFER_END(Props)
void surf (Input IN, inout SurfaceOutputStandard o)
{
int currentIndex = (int)
(((float)_Time * speed * 20) % frame_count);
float2 cellSize
= float2(
1.0 / cell_x_count,
1.0 / cell_y_count
);
const float2 offset = float2
(
((float)currentIndex % cell_x_count) / cell_x_count,
1 - (1 * floor(2.0 * (float)currentIndex * cellSize.x * cellSize.y))
);
const float2 cellCoord =
float2(
IN.uv_MainTex.x * cellSize.x,
-(1 - IN.uv_MainTex.y) * cellSize.y
);
const float2 samplePoint = offset + cellCoord;
float4 color = tex2D(_MainTex, samplePoint);
if( color.a < .01)
{
discard;
}
o.Albedo = color.rgb;
o.Alpha = color.a;
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
}
ENDCG
}
FallBack "Standard"
}
我之前制作了一个脚本解决方案来更新材质上的“平铺”和“偏移”,以创建动画幻觉,这在很大程度上有效,但设置起来不如简单的着色器简单。
现在,您的着色器正在使用后备中的
ShadowCaster
通道,定义为 FallBack "Standard"
。您需要定义自己的 ShadowCaster 通道:从标准复制通道并复制您的自定义纹理坐标转换。
您可以将该转换提取到 .cginc 文件中的方法,并通过
#include "YourLibrary.cginc"
将其包含在传递中。该方法将选取所有相同的着色器属性值,因为它们是为所有通道设置的。