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.
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" +
"}";
Sonraki adım, bir RuntimeShader
oluşturmaktır
nesnenizin gölgelendirici dizenizle başlatılması gerekir. Bu işlem gölgelendiriciyi de derler.
val fixedColorShader = RuntimeShader(COLOR_SHADER_SRC)
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
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
}
}
Bu, kırmızı bir View
çizer. uniform
kullanarak bir renk parametresini
gölgelendiriciyi seçin. İlk olarak gölgelendiriciye uniform
rengini ekleyin:
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" +
"}";
Ardından, istediğiniz rengi geçirmek için özel View
aracınızdan setColorUniform
öğesini çağırın
AGSL gölgelendiricisine yazar.
fixedColorShader.setColorUniform("iColor", Color.GREEN )
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:
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" +
"}";
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
.
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);
}
}

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.
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"+
"}";
Özel görünüm kaynak kodunda
ValueAnimator
,
iTime
forma.
// 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());
}
});

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
.
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);

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ı.
// 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);
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.
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();

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

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
.
view.setRenderEffect(RenderEffect.createRuntimeShaderEffect(myShader, "background"))
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);

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