android shadertoy效果 转换成 Android动态壁纸的写法

kotlin 复制代码
package com.example.wallpaper3d.shader

import android.content.Context
import android.opengl.GLES20
import android.opengl.GLSurfaceView
import android.service.wallpaper.WallpaperService
import android.util.Log
import android.view.SurfaceHolder
import java.nio.ByteBuffer
import java.nio.ByteOrder
import java.nio.FloatBuffer
import javax.microedition.khronos.egl.EGLConfig
import javax.microedition.khronos.opengles.GL10

class ShaderWallpaperService : WallpaperService() {
    override fun onCreateEngine(): Engine {
        return ShaderEngine()
    }
    
    inner class ShaderEngine : Engine() {
        private lateinit var glSurfaceView: GLSurfaceView
        private lateinit var renderer: ShaderRenderer

        override fun onCreate(surfaceHolder: SurfaceHolder) {
            super.onCreate(surfaceHolder)
            glSurfaceView = MyGLSurfaceView(this@ShaderWallpaperService)
            renderer = ShaderRenderer(this@ShaderWallpaperService)
            glSurfaceView.setRenderer(renderer)
            glSurfaceView.renderMode = GLSurfaceView.RENDERMODE_CONTINUOUSLY
        }

        override fun onVisibilityChanged(visible: Boolean) {
            super.onVisibilityChanged(visible)
            if (visible) {
                glSurfaceView.onResume()
            } else {
                glSurfaceView.onPause()
            }
        }

        inner class MyGLSurfaceView(context: Context) : GLSurfaceView(context) {
            init {
                setEGLContextClientVersion(2)
                holder.setFormat(android.graphics.PixelFormat.TRANSLUCENT)
                setZOrderOnTop(false)
            }

            override fun getHolder(): SurfaceHolder {
                return surfaceHolder // 使用壁纸引擎的 SurfaceHolder
            }
        }
    }
}

class ShaderRenderer(val context: Context) : GLSurfaceView.Renderer {
    // 顶点坐标(全屏四边形)
    private val vertexCoords = floatArrayOf(
        -1.0f, -1.0f, 0.0f,  // 左下
        1.0f, -1.0f, 0.0f,   // 右下
        -1.0f, 1.0f, 0.0f,   // 左上
        1.0f, 1.0f, 0.0f     // 右上
    )
    private val vertexBuffer: FloatBuffer

    // Shader 程序 ID
    private var programId: Int = 0
    // 时间和分辨率的 uniform 位置
    private var timeLoc: Int = 0
    private var resolutionLoc: Int = 0
    private var startTime: Long = 0

    init {
        // 初始化顶点缓冲
        vertexBuffer = ByteBuffer.allocateDirect(vertexCoords.size * 4)
            .order(ByteOrder.nativeOrder())
            .asFloatBuffer()
            .put(vertexCoords)
        vertexBuffer.position(0)
    }

    override fun onSurfaceCreated(gl: GL10?, config: EGLConfig?) {
        // 编译并链接 shaders
        val vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode)

        val  fragmentShaderCode = ShaderLoader.loadFromAssets(context,"shaders/shader_3.glsl")
        val fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode)
        programId = GLES20.glCreateProgram().apply {
            GLES20.glAttachShader(this, vertexShader)
            GLES20.glAttachShader(this, fragmentShader)
            GLES20.glLinkProgram(this)
        }
        GLES20.glUseProgram(programId)

        // 获取 uniform 变量位置
        timeLoc = GLES20.glGetUniformLocation(programId, "iTime")
        resolutionLoc = GLES20.glGetUniformLocation(programId, "iResolution")

        // 记录开始时间
        startTime = System.currentTimeMillis()
    }

    override fun onSurfaceChanged(gl: GL10?, width: Int, height: Int) {
        GLES20.glViewport(0, 0, width, height)
        // 传递分辨率给 shader
        GLES20.glUniform2f(resolutionLoc, width.toFloat(), height.toFloat())
    }

    override fun onDrawFrame(gl: GL10?) {
        GLES20.glClearColor(0f, 0f, 0f, 1f)
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)

        // 计算运行时间(秒)
        val currentTime = (System.currentTimeMillis() - startTime) / 1000f
        GLES20.glUniform1f(timeLoc, currentTime)

        // 绑定顶点数据
        val positionLoc = GLES20.glGetAttribLocation(programId, "aPosition")
        GLES20.glEnableVertexAttribArray(positionLoc)
        GLES20.glVertexAttribPointer(
            positionLoc, 3, GLES20.GL_FLOAT, false,
            3 * 4, vertexBuffer
        )

        // 绘制全屏四边形
        GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4)
        GLES20.glDisableVertexAttribArray(positionLoc)
    }

    // 加载并编译 shader
    private fun loadShader(type: Int, shaderCode: String): Int {
        Log.i("ccccccc", "shader_code===$shaderCode")
        return GLES20.glCreateShader(type).apply {
            GLES20.glShaderSource(this, shaderCode)
            GLES20.glCompileShader(this)
        }
    }

    // 顶点着色器(全屏四边形)
    private val vertexShaderCode = """
        attribute vec3 aPosition;
        void main() {
            gl_Position = vec4(aPosition, 1.0);
        }
    """.trimIndent()
    
}

shader_3.glsl内容

ini 复制代码
#version 100
precision mediump float;

uniform float iTime;
uniform vec2 iResolution;

// 旋转90度开关(注释掉可关闭旋转)
#define ROTATE_90

void main() {
    vec2 fragCoord = gl_FragCoord.xy;

    // 处理90度旋转:交换x/y坐标并修正方向
    #ifdef ROTATE_90
    // 交换x和y,实现旋转;反转x轴修正方向
    fragCoord = vec2(fragCoord.y, iResolution.x - fragCoord.x);
    // 旋转后重新计算分辨率比例(宽高互换)
    vec2 r = vec2(iResolution.y, iResolution.x);
    #else
    vec2 r = iResolution.xy;
    #endif

    vec3 c;
    float l, z = iTime;

    // 减少迭代次数(原3次→2次,提升性能)
    for(int i = 0; i < 2; i++) {
        vec2 uv, p = fragCoord.xy / r;
        uv = p;

        // 坐标中心化并适配宽高比
        p -= 0.5;
        p.x *= r.x / r.y;

        // 时间动画控制(略微降低速度,避免过度闪烁)
        z += 0.05;
        l = length(p);

        // 核心扭曲计算(保留原效果)
        uv += p / l * (sin(z) + 1.0) * abs(sin(l * 9.0 - z * 2.0));

        // 颜色计算(增强对比度)
        c[i] = 0.02 / length(mod(uv, 1.0) - 0.5);
    }

    // 补充第三通道颜色(保持三通道平衡)
    c[2] = 0.02 / length(mod((fragCoord.xy / r) + sin(z)*0.1, 1.0) - 0.5);

    // 输出颜色(调整透明度避免过亮)
    gl_FragColor = vec4(c / l, 1.0);
}

拷贝对应的效果代码 扔给ai 然后替换glsl文件内容。这里仅限于 变量只有 iTime iResolution 的效果。如果有其他变量 需要ai帮你把其他变量的设置 补充上

相关推荐
STCNXPARM7 小时前
Linux camera之V4L2子系统详解
android·linux·camera·v4l2架构
2501_944525547 小时前
Flutter for OpenHarmony 个人理财管理App实战 - 账户详情页面
android·java·开发语言·前端·javascript·flutter
不急不躁12310 小时前
Android16 GTS GtsPermissionTestcases 测试,跳过权限检查
android
符哥200812 小时前
关于用Android Compose开发成不成熟的分析
android·android jetpack
蜗牛、Z12 小时前
Android 蓝牙/Wi-Fi通信协议之:蓝牙扫描ScanCallback详解
android
黄昏晓x12 小时前
Linux----进程控制
android·linux·运维
我是阿亮啊13 小时前
android中事件分发机制
android·事件分发·事件分发机制
心前阳光14 小时前
Unity 模拟父子关系
android·unity·游戏引擎
2501_9151063214 小时前
当 Perfdog 开始收费之后,我重新整理了一替代方案
android·ios·小程序·https·uni-app·iphone·webview
多多*14 小时前
2月3日面试题整理 字节跳动后端开发相关
android·java·开发语言·网络·jvm·adb·c#