Android uygulamanızda AGSL'yi kullanma

Bu sayfada AGSL ile ilgili temel bilgiler ve AGSL'yi Android cihazınızda kullanmanın farklı yolları açıklanmaktadır. uygulamasını indirin.

Basit bir AGSL gölgelendirici

Gölgelendirici kodunuz, çizilen her piksel için çağrılır ve pikselin rengini döndürür. birlikte boyanmalıdır. Son derece basit bir gölgelendirici, her zaman tek bir renk; Bu örnekte kırmızı kullanılmıştır. Gölgelendirici, String içinde tanımlanır.

Kotlin

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

Java

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

Sonraki adım, bir RuntimeShader oluşturmaktır nesnenizin gölgelendirici dizenizle başlatılması gerekir. Bu işlem gölgelendiriciyi de derler.

Kotlin

val fixedColorShader = RuntimeShader(COLOR_SHADER_SRC)

Java

RuntimeShader fixedColorShader = new RuntimeShader(COLOR_SHADER_SRC);

RuntimeShader cihazınız standart bir Android gölgelendiricinin kullanabildiği her yerde kullanılabilir. Kullanıcı kullanarak özel bir View çizmek için kullanabilirsiniz, Canvas

Kotlin

val paint = Paint()
paint.shader = fixedColorShader
override fun onDrawForeground(canvas: Canvas?) {
   canvas?.let {
      canvas.drawPaint(paint) // fill the Canvas with the shader
   }
}

Java

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
   }
}

Bu, kırmızı bir View çizer. uniform kullanarak bir renk parametresini gölgelendiriciyi seçin. İlk olarak gölgelendiriciye uniform rengini ekleyin:

Kotlin

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

Java

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

Ardından, istediğiniz rengi geçirmek için özel View aracınızdan setColorUniform öğesini çağırın AGSL gölgelendiricisine yazar.

Kotlin

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

Java

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

Şimdi yeşil bir View alıyorsunuz; View rengi, parametresiniView gölgelendir.

Bunun yerine bir renk gradyanı efekti oluşturabilirsiniz. Öncelikle View çözünürlüğünü giriş olarak kabul etmek için gölgelendiriciyi tıklayın:

Kotlin

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

Java

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" +
   "}";

Gradyan çizme

Bu gölgelendirici biraz gösterişli bir şey yapar. Her piksel için bir float2 oluşturur çözünürlüğüne bölünmüş, x ve y koordinatlarını içeren vektör değeri, sıfır ile bir arasında bir değer oluşturur. Daha sonra bu ölçeklendirilmiş vektörü döndürme renginin kırmızı ve yeşil bileşenlerini oluşturmaktır.

View çözünürlüğünü bir AGSL gölgelendiriciye uniform setFloatUniform.

Kotlin

val paint = Paint()
paint.shader = fixedColorShader
override fun onDrawForeground(canvas: Canvas?) {
   canvas?.let {
      fixedColorShader.setFloatUniform("iResolution", width.toFloat(), height.toFloat())
      canvas.drawPaint(paint)
   }
}

Java

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);
   }
}
Kırmızı ve Yeşil gradyanı
Kırmızı ve yeşil gradyanı

Gölgelendiriciyi canlandırma

Benzer bir teknik kullanarak gölgelendiriciyi iTime ve iDuration formalarını alacak şekilde değiştirebilirsiniz. Gölgelendirici, bu değerleri kullanarak üçgen dalga dalga şeklinin yanı sıra, bunların renk geçişi değerleri arasında ileri geri geçiş yapmasına neden olur.

Kotlin

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);
   }
"""

Java

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"+
   "}";

Özel görünüm kaynak kodunda ValueAnimator, iTime forma.

Kotlin

// 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()

Java

// 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());
   }
});
Kırmızı ve Yeşil animasyonlu gradyanı
Kırmızı ve Yeşil animasyonlu gradyan

Karmaşık nesneleri boyama

Arka planı doldurmak için gölgelendiriciyi çizmeniz gerekmez; bu olabilir kabul eden herhangi bir yerde kullanılması Paint nesnesi, örneğin drawText.

Kotlin

canvas.drawText(ANIMATED_TEXT, TEXT_MARGIN_DP, TEXT_MARGIN_DP + bounds.height(),
   paint)

Java

canvas.drawText(ANIMATED_TEXT, TEXT_MARGIN_DP, TEXT_MARGIN_DP + bounds.height(),
   paint);
Kırmızı ve Yeşil animasyonlu gradyan metin
Kırmızı ve Yeşil animasyonlu gradyan metin

Gölge ve Tuval dönüşümleri

Gölgeli metninize ek Canvas dönüşümleri uygulayabilirsiniz. Örneğin: sağlayabilir. ValueAnimator içinde, 3D döndürmeler için bir matrisi güncelleyebilirsiniz yerleşik özellikleri kullanarak android.graphics.Camera sınıfı.

Kotlin

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

Java

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

Metni köşeden değil merkez eksenden döndürmek istediğiniz için metin sınırlarını alın ve ardından, metni değiştirmek için preTranslate ve postTranslate öğelerini kullanın 0,0 değeri döndürmenin merkezi olacak şekilde, metni çevirmek için matris metnin ekranda çizildiği konumu değiştirin.

Kotlin

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()

Java

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();
Kırmızı ve yeşil dönen animasyonlu gradyan metin
Kırmızı ve yeşil dönen animasyonlu gradyan metin

RuntimeShader'ı Jetpack Compose ile kullanma

RuntimeShader kullanmak, kullanıcı arayüzünü geliştirmek için çok daha kolaydır Jetpack Compose. Şuradan aynı gradyan gölgelendiriciyle başlayarak: şu tarihten önce:

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

Bu gölgelendiriciyi ShaderBrush. Siz sonra ShaderBrush öğesini, Canvas öğesinin çizim kapsamı.

// 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 gradyan daire
Kırmızı ve yeşil gradyan daire

RuntimeShader'ı RenderEffect ile kullanma

Tekliflerinizi otomatikleştirmek ve optimize etmek için Şu öğeyi uygulamak için RenderEffect: RuntimeShader tarihinde bir ana yayıncı View ile paylaşıldı ve tüm çocuk görüntülemelerini kapsar. Bu işlem, özel bir View çizmekten daha pahalıdır. ama kullanarak, arka plandaki küçük şeyleri içeren bir efekt oluşturmanızı sağlar. orijinalinde createRuntimeShaderEffect.

Kotlin

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

Java

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

İkinci parametre, bireval koordinat parametresini (fragCoord'da iletilen gibi) orijinal rengi elde etmek için RenderNode (Görünüm ve alt öğesi) kullanarak her tür efekti uygulayabilirsiniz.

uniform shader background;       // Root node of View tree to be altered
return mix(returnColor, background.eval(fragCoord), 0.5);
.
Karışık ızgara düğmesi
AGSL ızgarası karışık düğme üzerinde

Izgara efekti, bir düğmenin üzerinde ancak kayan işlem düğmesinin altında karışık olarak gösteriliyor (farklı bir View hiyerarşisinde olduğu için).