मैं इसे कुछ परतों में बनाऊंगा ताकि आप देख सकें कि यह एक साथ कैसे आता है।
Create --> Shader --> Unlit
प्रोजेक्ट विंडो में या तो एसेट्स मेनू या राइट-क्लिक संदर्भ मेनू का चयन करके एकता में एक नया शेडर बनाने से शुरू करें ।
शीर्ष ब्लॉक में हम _ScrollSpeeds
यह नियंत्रित करने के लिए एक पैरामीटर जोड़ेंगे कि बनावट प्रत्येक दिशा में कितनी तेजी से चलती है:
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_ScrollSpeeds ("Scroll Speeds", vector) = (-5, -20, 0, 0)
}
यह सामग्री इंस्पेक्टर में एक नया 4-घटक फ्लोट संपत्ति उजागर करता है, दोस्ताना नाम "स्क्रॉल गति" ( एक स्क्रिप्ट में एक चर public
या जोड़ने के समान ) के साथSerialized
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;
}
थप्पड़ कि एक ट्रैक्टर पर ( केनी द्वारा एक सुंदर मुक्त जिराफ़ बनावट के साथ ) और आपको मिलता है:
एक रिंग में बनावट को बाहर की ओर स्क्रॉल करने के लिए, हम बस मकड़ी की तरह उप-विभाजित एक जाल का उपयोग कर सकते हैं, केंद्र के बाहर से uv v समन्वय बढ़ेगा। लेकिन यह अपने आप पर कुछ sawblade के आकार की कलाकृतियों देगा। इसके बजाय, मैं दिखाता हूँ कि हम अपने UVs की गणना कैसे कर सकते हैं।
यह ट्रिगर और लंबाई के संचालन (जो मूल गणित की तुलना में अधिक महंगा है) की वजह से थोड़ा अधिक महंगा है, और क्योंकि यह केवल प्रक्षेपवक्र की तुलना में प्रति टुकड़े टेक्सकोर्ड्स की गणना करते समय हार्डवेयर में डेटा की भविष्यवाणी और कैश करने के लिए उतना कुशल नहीं है। कोने के बीच। लेकिन इस तरह थोड़ा विशेष प्रभाव के लिए, यह अत्यधिक नहीं है।
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)
}
और इसे हमारे CGPROGRAM ब्लॉक में घोषित करें ताकि CG shader इसे देख सके:
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;
}
और अब हमारा जिराफ वास्तव में त्रासद हो गया है:
बनावट और स्क्रॉलिंग दरों के थोड़ा अधिक कलात्मक चयन के साथ, यह प्रश्न में दिखाए गए एक के समान प्रभाव पैदा कर सकता है।
आप ऊपर दिखाए गए संस्करण के साथ दो छोटी कलाकृतियों को देख सकते हैं:
सर्कल के केंद्र के पास के चेहरे एक फैला / पतला / नुकीला मिलता है, फिर जैसे ही वे बाहर की ओर बढ़ते हैं वे चौड़ी / चौड़ी हो जाती हैं।
यह विकृति इसलिए होती है क्योंकि हमारे पास परिधि के चारों ओर निश्चित संख्या में चेहरे होते हैं, लेकिन वे जिस परिधि में फैले होते हैं, वह दायरा व्यापक हो जाता है, जबकि उनकी ऊंचाई समान रहती है।
हम इसे एक लघुगणकीय वक्र का पालन करने के लिए बनावट के नमूने के ऊर्ध्वाधर घटक को फिर से निर्धारित करके ठीक कर सकते हैं, इसलिए बनावट का दोहराव आगे बढ़ने के साथ-साथ त्रिज्या बढ़ता है, और केंद्र की ओर करीब होता है। (वास्तव में, यह हमें छोटे और छोटे जिराफों का एक अनंत प्रतिफल देता है ...)
क्वाड के मध्य-बाएँ के साथ एक या दो धुंधले पिक्सेल की एक पंक्ति है।
ऐसा इसलिए होता है क्योंकि 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;
}
_Time
वैरिएबल है जिसे आप स्क्रॉलिंग प्रभाव गंदगी को सस्ते में प्राप्त करने के लिए (वर्टेक्स) शेडर में अपनी बनावट निर्देशांक में जोड़ सकते हैं। षट्भुज प्रभाव बहुत सीधा भी होगा। यदि आप अपने प्रश्न को केवल एक प्रभाव को उजागर करने के लिए संपादित करते हैं और पूछते हैं कि "मैं इसे यूनिटी शैडर में कैसे लागू करूंगा," तो हम शायद आपकी मदद कर सकते हैं। यह निर्दिष्ट करना सुनिश्चित करें कि क्या छायाकार को प्रकाश / छायांकन का जवाब देने की आवश्यकता है, क्योंकि उस पर इसका प्रभाव है कि यह कैसे लिखा जाएगा।