---
title: AGSLで画像にエフェクトを加える
tags: 
author: [yoneyama shumpei](https://convert.docswell.com/user/6096936988)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/9J2DYNW1JR.jpg?width=480
description: AGSLで画像にエフェクトを加える by yoneyama shumpei
published: November 28, 24
canonical: https://convert.docswell.com/s/6096936988/KEX8PR-2024-11-28-001327
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/9J2DYNW1JR.jpg)

AGSLで画像にエフェクトを加える
米山 俊平（@Komeyama）


# Page. 2

![Page Image](https://bcdn.docswell.com/page/DEY2GPL4EM.jpg)

今回の内容
• AGSLを使ったエフェクトの例をいくつか紹介
• Jetpack Composeで実装する場合の要点を紹介


# Page. 3

![Page Image](https://bcdn.docswell.com/page/VJN8G54678.jpg)

AGSL（Android Graphics Shading Language）
• 高度なグラフィックが要求されるAndroidアプリでシェーダー
を使いたいときに使用できる。
• GLSL（OpenGL Shading Language）の構文と似ている。
• Android13以降で使用可能である。
など


# Page. 4

![Page Image](https://bcdn.docswell.com/page/YE9KWYQRE3.jpg)

エフェクトの例を紹介


# Page. 5

![Page Image](https://bcdn.docswell.com/page/GE8RN6GGJD.jpg)

エフェクトを加える画像


# Page. 6

![Page Image](https://bcdn.docswell.com/page/LELKP9GXJR.jpg)

雨粒のようなエフェクト
Shaderは以下のGLSLのコードを参考にした。
• 『Heartfelt』Created by BigWIngs
• https://www.shadertoy.com/view/ltffzl
• 『Sitting By The Window』Created by Kris_Katur
• https://www.shadertoy.com/view/slfSzS


# Page. 7

![Page Image](https://bcdn.docswell.com/page/4JM24ZQ3JW.jpg)

タップ操作によって変化する波紋風エフェクト
Shaderは以下のGLSLのコードを参考にした。
『RippleEffectFragmentShader』Created by abhi_bansal
• https://www.shadertoy.com/view/ldBXDD


# Page. 8

![Page Image](https://bcdn.docswell.com/page/PJRMW68RE9.jpg)

デバイスの傾きによって変化するレアカード風エフェクト
Shaderは以下のGLSLのコードを参考にした。
『Voronoi Boronoi』Created by jcraw
• https://www.shadertoy.com/view/Mc2BD1


# Page. 9

![Page Image](https://bcdn.docswell.com/page/PEXVPM8Y7X.jpg)

実装方法の要点を紹介


# Page. 10

![Page Image](https://bcdn.docswell.com/page/3EKQDGK4ED.jpg)

GLSLとの主な違いを簡単なコードで紹介
GLSL
AGSL
uniform vec2 u_resolution;
uniform vec2 u_resolution;
uniform shader u_contents;
uniform sampler2D u_text;
vec4 main(in vec2 fragCoord) {
void main() {
}
vec2 fragCoord.xy / u_resolution.xy;
vec2 uv = fragCoord.xy / u_resolution.xy
vec3 col = vec3(0,0);
vec3 col = vec3(0,0);
vec3 imgCol = u_contents.evel(uv * u_resolution.xy).rgb;
vec4 texColor = texture(u_tex, uv);
col.r = imgCol.b;
col.r = texColor.b;
col.g = imgCol.r;
col.g = texColor.r;
col.b = imgCol.g;
col.b = texColor.g;
return vec4(col, 1.0);
gl_FragColor = vec4(col, 1.0);
}


# Page. 11

![Page Image](https://bcdn.docswell.com/page/L73PRNZDE5.jpg)

GLSLとの主な違いを簡単なコードで紹介
GLSL
AGSL
uniform vec2 u_resolution;
uniform vec2 u_resolution;
uniform shader u_contents;
uniform sampler2D u_text;
vec4 main(in vec2 fragCoord) {
void main() {
vec2 fragCoord.xy / u_resolution.xy;
vec2 uv = fragCoord.xy / u_resolution.xy
vec3 col = vec3(0,0);
vec3 col = vec3(0,0);
その他
vec3 imgCol = u_contents.evel(uv
* u_resolution.xy).rgb;
col.r = imgCol.b;
col.g = imgCol.r;
col.b = imgCol.g;
return vec4(col, 1.0);
}
vec4 texColor = texture(u_tex, uv);
• 座標について
col.r = texColor.b;
• AGSLは左上を基準、GLSLは左下が基準となる。
col.g = texColor.r;
• Developersに変換方法の参考例が記載されている。
col.b = texColor.g;
▪ https://developer.android.com/develop/ui/views/graphics/agsl/agslvs-glsl#coordinate_space gl_FragColor = vec4(col, 1.0);
• AGSLには存在しないGLSLの関数はある。
}
など


# Page. 12

![Page Image](https://bcdn.docswell.com/page/87DLYWR2EG.jpg)

Jetpack ComposeでAGSLを使う
val shader = RuntimeShader(AGSL_CODE)
Image(
painter = painterResource(id = R.drawable.landscape),
modifier = Modifier.
onSizeChanged { size -&gt;
shader.setFloatUniform(
shader.setFloatUniform(&quot;resolution&quot;, size.width.toFloat(),size.height.toFloat())
)
}.graphicsLayer {
renderEffect = RenderEffect
.createRuntimeShaderEffect(shader, &quot;contents&quot;)
.asComposeRenderEffect()
}
)


# Page. 13

![Page Image](https://bcdn.docswell.com/page/VJP269WLJ8.jpg)

Jetpack ComposeでAGSLを使う
val shader = RuntimeShader(AGSL_CODE)
Image(
painter = painterResource(id
= R.drawable.landscape),
@Language(&quot;AGSL&quot;)
modifier = Modifier. const val AGSL_CODE = &quot;&quot;&quot;
uniform float 2 resolution;
onSizeChanged { size -&gt;
uniform shader contens;
shader.setFloatUniform(
vec4 main(in vec2 fragCoord)
{
shader.setFloatUniform(&quot;resolution&quot;,
size.width.toFloat(),size.height.toFloat())
)
・・・
}.graphicsLayer {
renderEffect&quot;&quot;&quot;.trimIndent()
= RenderEffect
.createRuntimeShaderEffect(shader, &quot;contents&quot;)
.asComposeRenderEffect()
}
)


# Page. 14

![Page Image](https://bcdn.docswell.com/page/2EVD3M86EQ.jpg)

Jetpack ComposeでAGSLを使う
val shader = RuntimeShader(AGSL_CODE)
Image(
painter = painterResource(id = R.drawable.landscape),
modifier = Modifier.
onSizeChanged { size -&gt;
shader.setFloatUniform(
shader.setFloatUniform(&quot;resolution&quot;, size.width.toFloat(),size.height.toFloat())
)
}.graphicsLayer {
@Language(&quot;AGSL&quot;)
renderEffect = RenderEffect
const val AGSL_CODE = &quot;&quot;&quot;
uniform
float 2 resolution;
.createRuntimeShaderEffect(shader,
&quot;contents&quot;)
uniform shader contens;
.asComposeRenderEffect()
}
)
・・・


# Page. 15

![Page Image](https://bcdn.docswell.com/page/57GY3G527L.jpg)

Jetpack ComposeでAGSLを使う
val shader = RuntimeShader(AGSL_CODE)
Image(
painter = painterResource(id = R.drawable.landscape),
modifier = Modifier.
onSizeChanged { size -&gt;
@Language(&quot;AGSL&quot;)
shader.setFloatUniform(
const val AGSL_CODE = &quot;&quot;&quot;
uniform
float 2 resolution;
shader.setFloatUniform(&quot;resolution&quot;,
size.width.toFloat(),size.height.toFloat())
uniform shader contens;
)
}.graphicsLayer {
・・・
renderEffect = RenderEffect
.createRuntimeShaderEffect(shader, &quot;contents&quot;)
.asComposeRenderEffect()
}
)


# Page. 16

![Page Image](https://bcdn.docswell.com/page/4EQM5XZ9JP.jpg)

Jetpack ComposeでAGSLを使う
val shader = RuntimeShader(AGSL_CODE)
Image(
painter = painterResource(id = R.drawable.landscape),
modifier = Modifier.
onSizeChanged { size -&gt;
shader.setFloatUniform(
)
時間やセンサー情報などのパラメーターをAGSLで使
shader.setFloatUniform(&quot;resolution&quot;,
size.width.toFloat(),size.height.toFloat())
いたい場合、setFloatUnifom等をgraphicLayer内に
記述する。
}.graphicsLayer {
shader.setFloatUniform(&quot;time&quot;, time)
renderEffect = RenderEffect
.createRuntimeShaderEffect(shader, &quot;contents&quot;)
.asComposeRenderEffect()
}
)


# Page. 17

![Page Image](https://bcdn.docswell.com/page/KJ4V96DRE1.jpg)

まとめ
• AGSLを使うことで面白いエフェクトをアプリに加えることができ
る。
• センサー情報等を使うことでモバイルデバイスならではの表現をア
プリに加えられる。
• シェーダー自体の作成は難しいが、Shadertoyなどにある先人達の
作ったGLSLのコードを参考にすれば、比較的楽にAndroidアプリに
組み込むことができる。


# Page. 18

![Page Image](https://bcdn.docswell.com/page/LE13KVZVJG.jpg)

ご清聴ありがとうございました


