로켓 리그를 보면서 애니메이션 데칼과 바퀴가 있음을 알았습니다.
.
위 이미지의 효과와 비슷한 것을 구현하고 싶습니다.
휠 효과를 위해 Unity Shader를 작성하는 방법은 무엇입니까?
셰이더에 대해 잘 모르지만 애니메이션 효과를 위해 표준 Unity 셰이더를 편집 할 수 있습니까?
로켓 리그를 보면서 애니메이션 데칼과 바퀴가 있음을 알았습니다.
.
위 이미지의 효과와 비슷한 것을 구현하고 싶습니다.
휠 효과를 위해 Unity Shader를 작성하는 방법은 무엇입니까?
셰이더에 대해 잘 모르지만 애니메이션 효과를 위해 표준 Unity 셰이더를 편집 할 수 있습니까?
답변:
이것을 몇 층으로 구성하여 어떻게 구성되는지 볼 수 있습니다.
Create --> Shader --> Unlit
프로젝트 메뉴에서 에셋 메뉴 또는 마우스 오른쪽 버튼 클릭 컨텍스트 메뉴에서 선택하여 Unity에서 새 셰이더를 생성하는 것으로 시작하십시오 .
상단 블록 _ScrollSpeeds
에는 텍스처가 각 방향으로 얼마나 빨리 움직이는 지 제어하는 파라미터가 추가됩니다 :
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_ScrollSpeeds ("Scroll Speeds", vector) = (-5, -20, 0, 0)
}
그러면 재료 관리자에서 이름이 "Scroll Speeds"( 스크립트에 변수 public
또는 Serialized
변수를 추가하는 것과 유사 함)와 함께 새로운 4 성분 부동 속성이 노출됩니다.MonoBehaviour
다음으로 정점 셰이더에서이 변수를 사용 o.uv
하여 기본 셰이더에 두 줄만 추가 하여 텍스처 좌표 ( ) 를 이동합니다 .
sampler2D _MainTex;
float4 _MainTex_ST;
// Declare our new parameter here so it's visible to the CG shader
float4 _ScrollSpeeds;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
// Shift the uvs over time.
o.uv += _ScrollSpeeds * _Time.x;
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
쿼드 (그것은 Kenney 의 멋진 무료 기린 질감으로 )를 때리고 다음을 얻습니다.
텍스처가 링에서 바깥쪽으로 스크롤되도록하려면 거미줄처럼 세분화 된 메쉬를 사용하면 uv v 좌표가 가운데에서 증가합니다. 그러나 그것은 그 자체로 톱날 모양의 인공물을 줄 것입니다. 대신 조각 당 UV를 계산하는 방법을 보여 드리겠습니다.
삼각법과 길이 연산 (기본 수학보다 비싸다)과 조각 당 텍스 코딩을 계산할 때 하드웨어에서 텍스처 데이터를 보간하는 것보다 예측 및 캐시하는 것이 비효율적이기 때문에 약간 더 비쌉니다. 정점 사이. 그러나 이와 같은 작은 특수 효과의 경우에는 과도하지 않습니다.
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
// Shift the UVs so (0, 0) is in the middle of the quad.
o.uv = v.uv - 0.5f;
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// Convert our texture coordinates to polar form:
float2 polar = float2(
atan2(i.uv.y, i.uv.x)/(2.0f * 3.141592653589f), // angle
length(i.uv) // radius
);
// Apply texture scale
polar *= _MainTex_ST.xy;
// Scroll the texture over time.
polar += _ScrollSpeeds.xy * _Time.x;
// Sample using the polar coordinates, instead of the original uvs.
// Here I multiply by MainTex
fixed4 col = tex2D(_MainTex, polar);
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
이것은 우리에게 이와 같은 것을 제공합니다 (여기서 재료의 타일링 매개 변수를 늘려서 진행 상황을 명확하게 나타냅니다-원 주위에 타일의 단일 반복 만 감싸는 것은 왜곡되고 이상하게 보입니다)
마지막으로 스크롤 그라디언트로 텍스쳐를 칠하기 위해 그라디언트를 두 번째 텍스쳐로 추가하고 곱하면됩니다.
먼저 맨 위에 새로운 텍스처 매개 변수를 추가합니다 :
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_TintTex("Tint Texture", 2D) = "white" {}
_ScrollSpeeds ("Scroll Speeds", vector) = (-5.0, -20.0, 0, 0)
}
CG 셰이더가 볼 수 있도록 CGPROGRAM 블록에 선언하십시오.
sampler2D _MainTex;
float4 _MainTex_ST;
// Declare our second texture sampler and its Scale/Translate values
sampler2D _TintTex;
float4 _TintTex_ST;
float4 _ScrollSpeeds;
그런 다음 프래그먼트 셰이더를 업데이트하여 두 텍스처를 모두 사용하십시오.
fixed4 frag(v2f i) : SV_Target
{
float2 polar = float2(
atan2(i.uv.y, i.uv.x) / (2.0f * 3.141592653589f), // angle
length(i.uv) // radius
);
// Copy the polar coordinates before we scale & shift them,
// so we can scale & shift the tint texture independently.
float2 tintUVs = polar * _TintTex_ST.xy;
tintUVs += _ScrollSpeeds.zw * _Time.x;
polar *= _MainTex_ST.xy;
polar += _ScrollSpeeds.xy * _Time.x;
fixed4 col = tex2D(_MainTex, polar);
// Tint the colour by our second texture.
col *= tex2D(_TintTex, tintUVs);
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
그리고 지금 우리 기린은 정말 어색해집니다.
질감과 스크롤 속도를 약간 더 예술적으로 선택하면 질문에 표시된 것과 매우 유사한 효과를 만들 수 있습니다.
위에 표시된 버전에서 두 가지 작은 아티팩트가 나타날 수 있습니다.
원 중심 근처의면은 늘어나거나 마른 체형으로 뾰족 해지며 바깥쪽으로 움직일 때 얼굴이 찌그러지고 넓어집니다.
이 왜곡은 주변에 고정 된 수의면이 있기 때문에 발생하지만 반경이 증가함에 따라 그 둘레가 넓어지고 높이는 동일하게 유지됩니다.
텍스처 샘플의 수직 성분을 대수 곡선을 따르도록 리 맵핑하여이 문제를 해결할 수 있습니다. 따라서 반경이 증가함에 따라 텍스처의 반복이 더 멀어지고 중심을 향하여 서로 더 가까워집니다. (실제로 이것은 우리에게 작고 작은 기린의 무한 회귀를 제공합니다 ...)
쿼드의 왼쪽 가운데에 1 개 또는 2 개의 흐릿한 픽셀 행이 있습니다.
이것은 GPU가 인접한 두 개의 텍스처 샘플 좌표를보고 어떤 필터링을 사용해야하는지 파악하기 때문에 발생합니다. 샘플들이 서로 가까이있을 때, 텍스처가 크게 / 닫히는 것을 나타내고 가장 상세한 밉 레벨을 보여줍니다. 샘플이 멀리 떨어져있을 때, 텍스처를 작은 줌이나 멀리서 보여 주어야한다고 생각하고, 더 작은 / 흐릿한 밉맵에서 샘플링하여 반짝이는 앨리어싱 인공물을 얻지 않도록합니다.
문제는 여기에서 -180도에서 180도까지 극좌표의 랩 어라운드 지점에 있습니다. 따라서 숫자 좌표로 인해 멀리 떨어져있는 것처럼 보이더라도 반복 텍스처 공간에서 매우 유사한 점에서 실제로 샘플링하고 있습니다. 이를 해결하기 위해 자체 샘플링 그래디언트 벡터를 제공 할 수 있습니다.
이러한 수정 사항이있는 버전은 다음과 같습니다.
fixed4 frag(v2f i) : SV_Target
{
float2 polar = float2(
atan2(i.uv.y, i.uv.x) / (2.0f * 3.141592653589f), // angle
log(dot(i.uv, i.uv)) * 0.5f // log-radius
);
// Check how much our texture sampling point changes between
// neighbouring pixels to the sides (ddx) and above/below (ddy)
float4 gradient = float4(ddx(polar), ddy(polar));
// If our angle wraps around between adjacent samples,
// discard one full rotation from its value and keep the fraction.
gradient.xz = frac(gradient.xz + 1.5f) - 0.5f;
// Copy the polar coordinates before we scale & shift them,
// so we can scale & shift the tint texture independently.
float2 tintUVs = polar * _TintTex_ST.xy;
tintUVs += _ScrollSpeeds.zw * _Time.x;
polar *= _MainTex_ST.xy;
polar += _ScrollSpeeds.xy * _Time.x;
// Sample with our custom gradients.
fixed4 col = tex2Dgrad(_MainTex, polar,
_MainTex_ST.xy * gradient.xy,
_MainTex_ST.xy * gradient.zw
);
// Since our tint texture has its own scale,
// its gradients also need to be scaled to match.
col *= tex2Dgrad(_TintTex, tintUVs,
_TintTex_ST.xy * gradient.xy,
_TintTex_ST.xy * gradient.zw
);
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
tex2Dgrad
하여 각도가 -pi에서 + pi (왼쪽의 흐릿한 픽셀의가는 선) 주위를 감싸는 필터링 아티팩트 를 수정합니다. 다음은 파란색이 더 진한 터치 결과입니다.
_Time
(버텍스) 셰이더의 텍스처 좌표에 추가 할 수 있는 내장 변수가있어 스크롤링 효과를 저렴하게 얻을 수 있습니다. 육각형 효과도 매우 간단합니다. 하나의 효과 만 강조하기 위해 질문을 편집하고 "Unity 셰이더에서 어떻게 구현하겠습니까?"라고 물으면 도움이 될 수 있습니다. 셰이더가 라이팅 / 섀도 잉에 반응해야하는지 여부를 지정해야합니다. 라이팅 / 섀도 잉은 작성 방법에 영향을 미칩니다.