package com.suno.android.common_ui.components.aura import android.graphics.RuntimeShader import android.os.Build import androidx.annotation.RequiresApi import androidx.compose.ui.geometry.Size import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.util.lerp @RequiresApi(Build.VERSION_CODES.TIRAMISU) internal class AuraShader( style: AuraStyle, ) : RuntimeShader(AURA_FRAGMENT_SHADER) { init { setColorUniform("iBackgroundColor", 0x0) setColorUniform("iColorA", style.colors.a.toArgb()) setColorUniform("iColorB", style.colors.b.toArgb()) setColorUniform("iColorC", style.colors.c.toArgb()) setFloatUniform("mixPointStart", style.points.start) setFloatUniform("mixPointBackground", style.points.background) setFloatUniform("mixPointBackgroundA", style.points.backgroundA) setFloatUniform("mixPointAB", style.points.ab) setFloatUniform("mixPointBC", style.points.bc) setFloatUniform("mixPointEnd", style.points.end) // todo move these hardcoded values to AuraStyle setFloatUniform("iFractalScale", style.scales.fractal) setFloatUniform("iGrainScale", style.scales.grain) } fun setResolution( size: Size, ) { setFloatUniform("iResolution", size.width, size.height) } // store uniform name to color so we can perform general operations private val colors by lazy { listOf( "A" to style.colors.a.toArgb(), "B" to style.colors.b.toArgb(), "C" to style.colors.c.toArgb(), ) } val floatBuffer = FloatArray(3) fun update( state: AuraState, ) = update( time = state.time, enabledScalar = state.enabledScalar.value, ) fun update( time: Float, enabledScalar: Float, ) { // accessing the `time` mutable state here causes a recomposition which will // trigger a redraw as time changes setFloatUniform("iTime", time) // generalized logic to fade colors out when disabling // by interpolating saturation and value to 0% and 30% // can change the specific gray color by changing value bound (plug gray rgb into hsv converted and use that v) colors.forEach { if (enabledScalar == 1f) return@forEach val (id, color) = it android.graphics.Color.colorToHSV(color, floatBuffer) floatBuffer[1] = lerp(0f, floatBuffer[1], enabledScalar) floatBuffer[2] = lerp(.3f, floatBuffer[2], enabledScalar) val newColor = android.graphics.Color.HSVToColor(floatBuffer) setColorUniform("iColor$id", newColor) } } }