⚡️ Limited Black Friday Deal
Get 50% off on the React Three Fiber Ultimate Course with the promo code ULTIMATE50
Buy Now
Fundamentals
Core
Master
Shaders
Shaping functions
Shader लॉजिक विशेष है, यह JavaScript या अन्य प्रोग्रामिंग भाषाओं से अलग है। जबकि सिंटैक्स समान है, जिस तरह से हम लॉजिक को लागू करते हैं वह अलग है। यह थोड़ा ब्लैक बॉक्स की तरह है, आप कुछ डेटा डालते हैं और आपको fragment shader के लिए कुछ रंग मिलते हैं, या vertex shader के लिए कुछ स्थितियाँ।
लेकिन आप आउटपुट को कैसे नियंत्रित करते हैं? आप इसे अपने अनुसार कैसे बनाते हैं? यही वह जगह है जहाँ shaping functions काम आते हैं।
हम इस पाठ के लिए fragment shader पर ध्यान केंद्रित करेंगे, लेकिन वही सिद्धांत vertex shader पर भी लागू होते हैं।
अभ्यास क्षेत्र
Shaping की कला को निपुण करने के लिए, आपको अभ्यास और प्रयोग की आवश्यकता होगी। Shader के कार्य करने के तरीके की आदत डालने में समय लगेगा, लेकिन एक बार आपने इसे समझ लिया, तो आप अद्भुत प्रभाव बना पाएंगे।
क्योंकि मैं आपको सफल होने के लिए सर्वश्रेष्ठ स्थिति में रखना चाहता हूँ, इसलिए मैंने आपके लिए यह 3D Art Gallery दृश्य तैयार किया है ताकि आप अपने shaders को एक सुखद वातावरण में रियल टाइम में देख सकें।
क्या आप अपनी रचनात्मकता को बहते हुए महसूस कर सकते हैं? ये सभी खाली frames आपकी कृतियों की प्रतीक्षा कर रहे हैं!
उपयोग किया गया 3D मॉडल है VR Gallery Maxim Mavrichev द्वारा और इसे Creative Commons Attribution के तहत लाइसेंस प्राप्त है।
मैंने <CameraControls />
का उपयोग एक प्रथम व्यक्ति कैमरा बनाने के लिए किया है ताकि गैलरी के अंदर नेविगेट कर सकें और Squoosh का उपयोग किया है टेक्सचर के आकार को कम करने के लिए।
SimpleShaderMaterial
गैलरी से सभी frames SimpleShaderMaterial
की प्रतिलिपियाँ हैं, यह एक बुनियादी कस्टम shader है जिसे मैंने आपके लिए तैयार किया है:
uColor
: एक रंगuTime
: एप्लिकेशन की शुरुआत से बीता हुआ समयvUv
: fragment के UV निर्देशांक (दोनों अक्षों पर 0 से 1 तक)
ये सभी <App.jsx />
में विस्तारित हैं ताकि हमारे दृश्य में उनका डेकरलिवत तरीके से उपयोग कर सकें।
इनका नामकरण गैलरी में उनकी स्थिति के आधार पर किया गया है, लेकिन एक बार जब आप इनसे कृतियाँ बना लेते हैं तो इन्हें किसी अधिक अर्थपूर्ण नाम से पुनः नामित करने के लिए स्वतंत्र हैं!
Functions
हमारे शेडर के प्रत्येक हिस्से के लिए, हमारे समान कोड को विभिन्न इनपुट्स के साथ निष्पादित किया जाएगा।
अगर हम एक लाइन खींचना चाहते हैं, तो हम if स्टेटमेंट्स का उपयोग करके जांच सकते हैं कि पिक्सल लाइन के भीतर है या नहीं। लेकिन अधिक जटिल आकृतियों को बनाना बहुत कठिन और अक्षम होगा।
इसके बजाय, हम अपने आउटपुट को आकार देने के लिए फंक्शनों का उपयोग करते हैं। चिंता मत करो, आपको उनका उपयोग करने के लिए गणित का विशेषज्ञ होने की आवश्यकता नहीं है। आपको बस यह समझने की जरूरत है कि आपके पास कौन-कौन फ़ंक्शन हैं, और वे क्या करते हैं।
एक फ़ंक्शन को एक मशीन के रूप में सोचें जो कुछ इनपुट लेता है और आपको कुछ आउटपुट देता है। उदाहरण के लिए, फ़ंक्शन
f(x) = x * 2
एक संख्याx
लेता है और परिणामस्वरूप आपकोx * 2
देता है।
विभिन्न फंक्शनों के प्रभाव को दृश्य रूप में देखने के लिए, हम Graphtoy का उपयोग करेंगे, यह एक सरल उपकरण है जिसमें फंक्शनों को टाइप किया जा सकता है और उनके आउटपुट को देखा जा सकता है। यह हमारे शेडर में फंक्शनों के साथ प्रयोग करते समय हमारी समझ को मान्य करने में मदद करता है।
चलो हमारे f(x) = x * 2
फ़ंक्शन को Graphtoy में विज़ुअलाइज़ करते हैं:
शेडर के साथ प्रयोग करते समय Graphtoy आपका सबसे अच्छा दोस्त बन जाएगा।
अब हमारे पास उपलब्ध विभिन्न फंक्शनों के साथ प्रयोग करने का समय है।
Step
step function एक सरल फ़ंक्शन है जो 0
रिटर्न करता है यदि इनपुट थ्रेशोल्ड से कम है, और 1
रिटर्न करता है यदि इनपुट थ्रेशोल्ड से अधिक है।
इसके दो पैरामीटर होते हैं:
edge
: थ्रेशोल्डx
: इनपुट मान
चलो इसे फ्रंट फ्रेम ArtFront02Material.jsx
फ्रैगमेंट शेडर पर आजमाते हैं:
void main() { float pct = 1.0; pct = step(0.5, vUv.x); vec3 finalColor = pct * uColor; gl_FragColor = vec4(finalColor, 1.0); }
हम एक वेरिएबल pct
घोषित करते हैं जिससे हम दिखाना चाहते हैं उसके रंग का प्रतिशत निर्धारित करते हैं। हम इसे डिफ़ॉल्ट रूप से 1.0
पर सेट करते हैं, और फिर step
फ़ंक्शन का उपयोग करते हैं इसे 0.0
पर सेट करने के लिए यदि vUv.x
0.5 से कम है।
हम देख सकते हैं कि फ्रेम के बाएँ आधे हिस्से का रंग काला है, और दाहिने आधे हिस्से का रंग uColor
यूनिफ़ॉर्म में सेट है।
चलो इसे ऊर्ध्वाधर अक्ष पर एक अलग थ्रेशोल्ड के साथ लागू करते हैं:
void main() { float pct = 1.0; pct = step(0.2, vUv.y); vec3 finalColor = pct * uColor; gl_FragColor = vec4(finalColor, 1.0); }
हम देख सकते हैं कि फ्रेम के निचले 20% का रंग काला है, और बाकी का रंग बैंगनी है।
UV कोऑर्डिनेट फ्रेम के निचले बाएं कोने पर शुरू होते हैं, इसलिए
[0, 0]
फ्रेम का निचला बायाँ कोना है, और[1, 1]
शीर्ष दायां कोना है।
अगर आप इसका प्रभाव पलटना चाहते हैं, तो आप बस step
फ़ंक्शन के पैरामीटर को स्वैप कर सकते हैं:
void main() { float pct = 1.0; pct = step(vUv.y, 0.2); vec3 finalColor = pct * uColor; gl_FragColor = vec4(finalColor, 1.0); }
अब हमारे पास विपरीत प्रभाव है।
मिक्स
mix function एक सरल फ़ंक्शन है जो दो मानों के बीच रैखिक इंटरपोलेंशन लौटाता है।
यह तीन पैरामीटर लेता है:
x
: पहला मानy
: दूसरा मानa
: वह मान जोx
औरy
के बीच इंटरपोल करें
आइए इसे आज़माते हैं:
void main() { float pct = 1.0; pct = mix(0.0, 1.0, vUv.x); vec3 finalColor = pct * uColor; gl_FragColor = vec4(finalColor, 1.0); }
हम काले से बैंगनी तक एक सुंदर ग्रेडिएंट देख सकते हैं।
कई अन्य फ़ंक्शनों की तरह, आप इसे अन्य डेटा प्रकारों पर उपयोग कर सकते हैं, जैसे वेक्टर घटक। चलिए इसका उपयोग सफेद से बैंगनी तक एक ग्रेडिएंट बनाने के लिए करते हैं ऊर्ध्वाधर अक्ष पर:
void main() { vec3 whiteColor = vec3(1.0); vec3 finalColor = mix(whiteColor, uColor, vUv.y); gl_FragColor = vec4(finalColor, 1.0); }
हम सफेद से बैंगनी तक एक सुंदर ग्रेडिएंट देख सकते हैं।
आइए इंटरपोलेंशन मान को बदलते हैं पहली बार mix
फ़ंक्शन को कॉल करके pct
मान प्राप्त करें और फिर इसे whiteColor
और uColor
के बीच इंटरपोलेंशन के लिए उपयोग करें:
void main() { vec3 whiteColor = vec3(1.0); float pct = mix(0.0, 0.3, vUv.y); vec3 finalColor = mix(whiteColor, uColor, pct); gl_FragColor = vec4(finalColor, 1.0); }
बैंगनी बहुत हल्का है क्योंकि pct
का अधिकतम मान 0.3
है।
मिश्रण फ़ंक्शन को समझने और इसके साथ प्रयोग करने के लिए Graphtoy का उपयोग करें।
mix
फ़ंक्शन के साथ 3 अलग-अलग इंटरपोलेंशंस पूरी तरह से अलग परिणाम देते हैं।
Smoothstep
स्मूदस्टेप फंक्शन एक सरल फंक्शन है जो दो मानों के बीच एक स्मूथ इंटरपोलेशन वापस करता है।
यह तीन पैरामीटर लेता है:
edge0
: निचली सीमाedge1
: ऊपरी सीमाx
:edge0
औरedge1
के बीच इंटरपोलेट करने वाला मान
यह तीन विभिन्न परिणाम देता है:
0.0
अगरx
edge0
से कम है1.0
अगरx
edge1
से अधिक है0.0
और1.0
के बीच एक स्मूथ इंटरपोलेशन अगरx
edge0
औरedge1
के बीच है
आइए इसे हमारे pct
मान को बदलने के लिए उपयोग करते हैं:
void main() { vec3 whiteColor = vec3(1.0); float pct = smoothstep(0.4, 0.6, vUv.y); vec3 finalColor = mix(whiteColor, uColor, pct); gl_FragColor = vec4(finalColor, 1.0); }
संक्रमण अब केवल 0.4
और 0.6
के बीच है। सब कुछ नीचे सफेद है, और सब कुछ ऊपर बैंगनी है।
Min & Max
min
और max
सरल फंक्शन्स हैं जो दो इनपुट्स के बीच न्यूनतम या अधिकतम मान वापस करते हैं। ये ठीक उसी प्रकार से काम करते हैं जैसे JavaScript में Math.min
और Math.max
फंक्शन्स।
आइए इनका इस्तेमाल हमारे pct
मान को सटीक बनाने के लिए करते हैं। पहले यह सुनिश्चित करें कि यह कभी भी 0.4
से कम न हो (जिसका मतलब कभी भी पूरी तरह से सफेद न हो):
void main() { vec3 whiteColor = vec3(1.0); float pct = smoothstep(0.4, 0.6, vUv.y); pct = max(pct, 0.4); vec3 finalColor = mix(whiteColor, uColor, pct); gl_FragColor = vec4(finalColor, 1.0); }
और कभी भी 0.6
से अधिक न हो (जिसका मतलब कभी भी पूरी तरह से बैंगनी न हो):
void main() { vec3 whiteColor = vec3(1.0); float pct = smoothstep(0.4, 0.6, vUv.y); pct = max(pct, 0.4); pct = min(pct, 0.6); vec3 finalColor = mix(whiteColor, uColor, pct); gl_FragColor = vec4(finalColor, 1.0); }
रंग हल्के हो गए हैं, और संक्रमण बहुत ही स्मूथ है।
आइए इसे Graphtoy पर दृश्य रूप दें:
max(x, 0.4)
का प्रतिनिधित्व
min(x, 0.6)
का प्रतिनिधित्व
और अगर हम इन्हें मिलाते हैं:
आप देख सकते हैं कि हमारे मान कभी 0.4
से कम नहीं जाते और कभी 0.6
से अधिक नहीं जाते।
हमारे
min
औरmax
फंक्शन्स के संयोजन को clamp फंक्शन द्वारा प्रतिस्थापित किया जा सकता है, जोmin(max(x, min), max)
का शॉर्टहैंड है।
संचालन एवं पैटर्न
हम कई अन्य उपयोगी फ़ंक्शनों की खोज करने से पहले यह देखें कि पैटर्न बनाने के लिए हम संचालन का उपयोग कैसे कर सकते हैं।
End of lesson preview
To get access to the entire lesson, you need to purchase the course.