अपने Android ऐप्लिकेशन में AGSL का इस्तेमाल करना

इस पेज पर, AGSL की बुनियादी बातों और Android में AGSL का इस्तेमाल करने के अलग-अलग तरीके बताए गए हैं है.

आसान AGSL शेडर

आपका शेडर कोड, बनाए गए हर पिक्सल के लिए कॉल किया जाता है और पिक्सल का रंग लौटाता है पेंट किया जाना चाहिए. एक बेहद सरल शेडर वह है जो हमेशा वापस लौटता है एक ही रंग; इस उदाहरण में लाल रंग का इस्तेमाल किया गया है. शेडर, String के अंदर तय किया जाता है.

KotlinJava
private const val COLOR_SHADER_SRC =
   
"""half4 main(float2 fragCoord) {
      return half4(1,0,0,1);
   }"""

private static final String COLOR_SHADER_SRC =
   
"half4 main(float2 fragCoord) {\n" +
     
"return half4(1,0,0,1);\n" +
   
"}";

अगला चरण एक RuntimeShader बनाना है ऑब्जेक्ट आपकी शेडर स्ट्रिंग से शुरू किया गया है. इससे शेडर भी कंपाइल हो जाता है.

KotlinJava
val fixedColorShader = RuntimeShader(COLOR_SHADER_SRC)
RuntimeShader fixedColorShader = new RuntimeShader(COLOR_SHADER_SRC);

आपके RuntimeShader का इस्तेमाल किसी भी स्टैंडर्ड Android शेडर के साथ किया जा सकता है. इस तौर पर उदाहरण के लिए, इसका इस्तेमाल करके कस्टम View में ड्रॉ किया जा सकता है. Canvas.

KotlinJava
val paint = Paint()
paint
.shader = fixedColorShader
override fun onDrawForeground(canvas: Canvas?) {
   canvas
?.let {
      canvas
.drawPaint(paint) // fill the Canvas with the shader
   
}
}
Paint paint = new Paint();
paint
.setShader(fixedColorShader);
public void onDrawForeground(@Nullable Canvas canvas) {
   
if (canvas != null) {
      canvas
.drawPaint(paint); // fill the Canvas with the shader
   
}
}

इससे लाल रंग का View दिखता है. कलर पैरामीटर भेजने के लिए, uniform का इस्तेमाल किया जा सकता है बनाया जाने वाला शेडर. सबसे पहले, शेडर में uniform रंग जोड़ें:

KotlinJava
private const val COLOR_SHADER_SRC =
"""layout(color) uniform half4 iColor;
   half4 main(float2 fragCoord) {
      return iColor;
   }"""

private static final String COLOR_SHADER_SRC =
   
"layout(color) uniform half4 iColor;\n"+
     
"half4 main(float2 fragCoord) {\n" +
     
"return iColor;\n" +
   
"}";

इसके बाद, पसंदीदा रंग भेजने के लिए, अपने कस्टम View से setColorUniform को कॉल करें को AGSL शेडर में ले जाया जाएगा.

KotlinJava
fixedColorShader.setColorUniform("iColor", Color.GREEN )
fixedColorShader.setColorUniform("iColor", Color.GREEN );

अब आपको हरे रंग का View मिल रहा है; View रंग को इसकी मदद से कंट्रोल किया जाता है पैरामीटर, यूआरएल में एम्बेड किए जाने के बजाय, आपके कस्टम View में मौजूद कोड से शेडर.

इसकी जगह पर, कलर ग्रेडिएंट इफ़ेक्ट बनाया जा सकता है. पहले आपको यह बदलाव करना होगा View रिज़ॉल्यूशन को इनपुट के तौर पर स्वीकार करने के लिए शेडर:

KotlinJava
private const val COLOR_SHADER_SRC =
"""uniform float2 iResolution;
   half4 main(float2 fragCoord) {
      float2 scaled = fragCoord/iResolution.xy;
      return half4(scaled, 0, 1);
   }"""

private static final String COLOR_SHADER_SRC =
   
"uniform float2 iResolution;\n" +
     
"half4 main(float2 fragCoord) {\n" +
     
"float2 scaled = fragCoord/iResolution.xy;\n" +
     
"return half4(scaled, 0, 1);\n" +
   
"}";

ग्रेडिएंट बनाना

यह शेडर कुछ खास करता है. हर पिक्सल के लिए, यह एक float2 बनाता है वेक्टर जिसमें रिज़ॉल्यूशन से भाग देकर x और y निर्देशांक होते हैं, शून्य और एक के बीच का कोई मान बनाएगा. इसके बाद, यह स्केल किए गए वेक्टर का इस्तेमाल करके रिटर्न कलर के लिए लाल और हरे कॉम्पोनेंट बनाएं.

आपने कॉल करके View के रिज़ॉल्यूशन को एक एजीएसएल शेडर uniform में पास किया है setFloatUniform.

KotlinJava
val paint = Paint()
paint
.shader = fixedColorShader
override fun onDrawForeground(canvas: Canvas?) {
   canvas
?.let {
      fixedColorShader
.setFloatUniform("iResolution", width.toFloat(), height.toFloat())
      canvas
.drawPaint(paint)
   
}
}
Paint paint = new Paint();
paint
.setShader(fixedColorShader);
public void onDrawForeground(@Nullable Canvas canvas) {
   
if (canvas != null) {
      fixedColorShader
.setFloatUniform("iResolution", (float)getWidth(), (float()getHeight()));
      canvas
.drawPaint(paint);
   
}
}
रेड और ग्रीन ग्रेडिएंट
रेड और ग्रीन ग्रेडिएंट

शेडर को ऐनिमेट किया जा रहा है

शेडर को ऐनिमेट करने के लिए, इसी तरह की तकनीक का इस्तेमाल किया जा सकता है. ऐसा करने के लिए, आपको iTime और iDuration यूनिफ़ॉर्म पाने के लिए, शेडर में बदलाव करना होगा. शेडर इन वैल्यू का इस्तेमाल करके, रंगों के लिए त्रिकोणीय तरंगें, जिनकी वजह से वे अपनी ग्रेडिएंट वैल्यू में आगे-पीछे घूम जाती हैं.

KotlinJava
private const val DURATION = 4000f
private const val COLOR_SHADER_SRC = """
   uniform float2 iResolution;
   uniform float iTime;
   uniform float iDuration;
   half4 main(in float2 fragCoord) {
      float2 scaled = abs(1.0-mod(fragCoord/iResolution.xy+iTime/(iDuration/2.0),2.0));
      return half4(scaled, 0, 1.0);
   }
"""

private static final float DURATION = 4000f;
private static final String COLOR_SHADER_SRC =
   
"uniform float2 iResolution;\n"+
   
"uniform float iTime;\n"+
   
"uniform float iDuration;\n"+
   
"half4 main(in float2 fragCoord) {\n"+
     
"float2 scaled = abs(1.0-mod(fragCoord/iResolution.xy+iTime/(iDuration/2.0),2.0));\n"+
     
"return half4(scaled, 0, 1.0);\n"+
   
"}";

कस्टम व्यू के सोर्स कोड से, ValueAnimator iTime यूनिफ़ॉर्म.

KotlinJava
// declare the ValueAnimator
private val shaderAnimator = ValueAnimator.ofFloat(0f, DURATION)

// use it to animate the time uniform
shaderAnimator
.duration = DURATION.toLong()
shaderAnimator
.repeatCount = ValueAnimator.INFINITE
shaderAnimator
.repeatMode = ValueAnimator.RESTART
shaderAnimator
.interpolator = LinearInterpolator()

animatedShader
.setFloatUniform("iDuration", DURATION )
shaderAnimator
.addUpdateListener { animation ->
    animatedShader
.setFloatUniform("iTime", animation.animatedValue as Float )
}
shaderAnimator
.start()
// declare the ValueAnimator
private final ValueAnimator shaderAnimator = ValueAnimator.ofFloat(0f, DURATION);

// use it to animate the time uniform
shaderAnimator
.setDuration((long)DURATION);
shaderAnimator
.setRepeatCount(ValueAnimator.INFINITE);
shaderAnimator
.setRepeatMode(ValueAnimator.RESTART);
shaderAnimator
.setInterpolator(new LinearInterpolator());

animatedShader
.setFloatUniform("iDuration", DURATION );
shaderAnimator
.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
   
public final void onAnimationUpdate(ValueAnimator animation) {
      animatedShader
.setFloatUniform("iTime", (float)animation.getAnimatedValue());
   
}
});
लाल और हरे रंग का ऐनिमेटेड ग्रेडिएंट
लाल और हरे रंग का ऐनिमेटेड ग्रेडिएंट

पेंटिंग कॉम्प्लेक्स ऑब्जेक्ट

आपको बैकग्राउंड भरने के लिए शेडर ड्रॉ करने की ज़रूरत नहीं है; यह हो सकता है ऐसे किसी भी स्थान पर इस्तेमाल किया जाता है जो Paint ऑब्जेक्ट, जैसे drawText.

KotlinJava
canvas.drawText(ANIMATED_TEXT, TEXT_MARGIN_DP, TEXT_MARGIN_DP + bounds.height(),
   paint
)
canvas.drawText(ANIMATED_TEXT, TEXT_MARGIN_DP, TEXT_MARGIN_DP + bounds.height(),
   paint
);
लाल और हरे रंग का ऐनिमेटेड ग्रेडिएंट टेक्स्ट
लाल और हरे रंग का ऐनिमेटेड ग्रेडिएंट टेक्स्ट

शेडिंग और कैनवस ट्रांसफ़ॉर्मेशन

गहरे रंग वाले टेक्स्ट पर, अतिरिक्त Canvas ट्रांसफ़ॉर्मेशन ऐक्शन लागू किए जा सकते हैं. जैसे, घुमाव. ValueAnimator में, 3D रोटेशन के लिए मैट्रिक्स अपडेट किया जा सकता है बिल्ट-इन टेक्नोलॉजी का इस्तेमाल करके android.graphics.Camera क्लास.

KotlinJava
// in the ValueAnimator
camera
.rotate(0.0f, animation.animatedValue as Float / DURATION * 360f, 0.0f)
// in the ValueAnimator
camera
.rotate(0.0f, (Float)animation.getAnimatedValue() / DURATION * 360f, 0.0f);

क्योंकि आपको टेक्स्ट को कोने के बजाय, उसके बीच वाले ऐक्सिस से घुमाना है, टेक्स्ट की सीमा पाएं और फिर preTranslate और postTranslate का इस्तेमाल करके आव्यूह टेक्स्ट को स्क्रीन पर बनाए जाने की जगह बदलें.

KotlinJava
linearColorPaint.getTextBounds(ANIMATED_TEXT, 0, ANIMATED_TEXT.length, bounds)
camera
.getMatrix(rotationMatrix)
val centerX = (bounds.width().toFloat())/2
val centerY = (bounds.height().toFloat())/2
rotationMatrix
.preTranslate(-centerX, -centerY)
rotationMatrix
.postTranslate(centerX, centerY)
canvas
.save()
canvas
.concat(rotationMatrix)
canvas
.drawText(ANIMATED_TEXT, 0f, 0f + bounds.height(), paint)
canvas
.restore()
linearColorPaint.getTextBounds(ANIMATED_TEXT, 0, ANIMATED_TEXT.length(), bounds);
camera
.getMatrix(rotationMatrix);
float centerX = (float)bounds.width()/2.0f;
float centerY = (float)bounds.height()/2.0f;
rotationMatrix
.preTranslate(-centerX, -centerY);
rotationMatrix
.postTranslate(centerX, centerY);
canvas
.save();
canvas
.concat(rotationMatrix);
canvas
.drawText(ANIMATED_TEXT, 0f, 0f + bounds.height(), paint);
canvas
.restore();
लाल और हरे रंग का घूमते हुए ऐनिमेटेड ग्रेडिएंट टेक्स्ट
लाल और हरे रंग का घूमते हुए ऐनिमेटेड ग्रेडिएंट टेक्स्ट

Jetpack Compose के साथ RuntimeShader का इस्तेमाल करना

RuntimeShader का इस्तेमाल करना और भी आसान है, अगर आप Jetpack Compose. इसी ग्रेडिएंट शेडर से शुरू किया जा रहा है पहले:

private const val COLOR_SHADER_SRC =
   
"""uniform float2 iResolution;
   half4 main(float2 fragCoord) {
   float2 scaled = fragCoord/iResolution.xy;
   return half4(scaled, 0, 1);
}"""

आप इस शेडर को ShaderBrush. आपने लोगों तक पहुंचाया मुफ़्त में फिर अपनेShaderBrush Canvas का ड्रॉ का स्कोप.

// created as top level constants
val colorShader = RuntimeShader(COLOR_SHADER_SRC)
val shaderBrush = ShaderBrush(colorShader)

Canvas(
   modifier
= Modifier.fillMaxSize()
) {
   colorShader
.setFloatUniform("iResolution",
   size
.width, size.height)
   drawCircle
(brush = shaderBrush)
}
अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
AGSL Compose के तहत ग्रेडिएंट सर्कल
लाल और हरे रंग का ग्रेडिएंट सर्कल

Renderimpact के साथ RuntimeShader का इस्तेमाल करना

Google Analytics 4 पर माइग्रेट करने के लिए, लागू करने के लिए RenderEffect अभिभावक View को RuntimeShader और सभी चाइल्ड व्यू. यह कस्टम View बनाने के मुकाबले ज़्यादा खर्चीला है. लेकिन इससे आप आसानी से ऐसा इफ़ेक्ट बना सकते हैं जो आपके शॉर्ट वीडियो मूल रूप से इसका इस्तेमाल करके बनाया गया है createRuntimeShaderEffect.

KotlinJava
view.setRenderEffect(RenderEffect.createRuntimeShaderEffect(myShader, "background"))
view.setRenderEffect(RenderEffect.createRuntimeShaderEffect(myShader, "background"));

दूसरा पैरामीटर शेडर यूनिफ़ॉर्म का नाम है, जिसे eval मूल रंग पाने के लिए निर्देशांक पैरामीटर (जैसे कि fggCoord में पास किया गया) का तरीका RenderNode (व्यू और उसका चाइल्ड व्यू) देखें) जिससे आप सभी तरह के प्रभाव कर सकते है.

uniform shader background;       // Root node of View tree to be altered
return mix(returnColor, background.eval(fragCoord), 0.5);
अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
बटन के ऊपर ग्रिड मिला
बटन के ऊपर ब्लेंड किया गया एजीएसएल ग्रिड

एक बटन पर ग्रिड इफ़ेक्ट मौजूद है. हालांकि, यह फ़्लोट करने वाले ऐक्शन बटन के नीचे है (क्योंकि यह View की अलग हैरारकी में है).