AGSLで画像にエフェクトを加える

2.2K Views

November 28, 24

スライド概要

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

関連スライド

各ページのテキスト
1.

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

2.

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

3.

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

4.

エフェクトの例を紹介

5.

エフェクトを加える画像

6.

雨粒のようなエフェクト 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

7.

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

8.

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

9.

実装方法の要点を紹介

10.

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

11.
[beta]
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の関数はある。
}
など

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

13.
[beta]
Jetpack ComposeでAGSLを使う
val shader = RuntimeShader(AGSL_CODE)
Image(
painter = painterResource(id
= R.drawable.landscape),
@Language("AGSL")
modifier = Modifier. const val AGSL_CODE = """
uniform float 2 resolution;
onSizeChanged { size ->
uniform shader contens;
shader.setFloatUniform(
vec4 main(in vec2 fragCoord)
{
shader.setFloatUniform("resolution",
size.width.toFloat(),size.height.toFloat())
)

・・・
}.graphicsLayer {
renderEffect""".trimIndent()
= RenderEffect
.createRuntimeShaderEffect(shader, "contents")
.asComposeRenderEffect()
}
)

14.
[beta]
Jetpack ComposeでAGSLを使う
val shader = RuntimeShader(AGSL_CODE)
Image(
painter = painterResource(id = R.drawable.landscape),
modifier = Modifier.
onSizeChanged { size ->
shader.setFloatUniform(
shader.setFloatUniform("resolution", size.width.toFloat(),size.height.toFloat())
)
}.graphicsLayer {

@Language("AGSL")
renderEffect = RenderEffect
const val AGSL_CODE = """
uniform
float 2 resolution;
.createRuntimeShaderEffect(shader,
"contents")
uniform shader contens;
.asComposeRenderEffect()

}
)

・・・

15.
[beta]
Jetpack ComposeでAGSLを使う
val shader = RuntimeShader(AGSL_CODE)
Image(
painter = painterResource(id = R.drawable.landscape),
modifier = Modifier.
onSizeChanged { size ->

@Language("AGSL")
shader.setFloatUniform(
const val AGSL_CODE = """
uniform
float 2 resolution;
shader.setFloatUniform("resolution",
size.width.toFloat(),size.height.toFloat())
uniform shader contens;
)

}.graphicsLayer {

・・・

renderEffect = RenderEffect
.createRuntimeShaderEffect(shader, "contents")
.asComposeRenderEffect()
}
)

16.
[beta]
Jetpack ComposeでAGSLを使う
val shader = RuntimeShader(AGSL_CODE)
Image(
painter = painterResource(id = R.drawable.landscape),
modifier = Modifier.
onSizeChanged { size ->
shader.setFloatUniform(
)

時間やセンサー情報などのパラメーターをAGSLで使
shader.setFloatUniform("resolution",
size.width.toFloat(),size.height.toFloat())
いたい場合、setFloatUnifom等をgraphicLayer内に
記述する。

}.graphicsLayer {
shader.setFloatUniform("time", time)
renderEffect = RenderEffect
.createRuntimeShaderEffect(shader, "contents")
.asComposeRenderEffect()
}
)

17.

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

18.

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