markusfisch / ShaderEditor

Android app to create GLSL shaders and use them as live wallpaper
https://play.google.com/store/apps/details?id=de.markusfisch.android.shadereditor
MIT License
924 stars 137 forks source link

Request: backbuffer sample #172

Open DinhQuocTrung opened 8 months ago

DinhQuocTrung commented 8 months ago

Could you add a basic sample about backbuffer to store and load data to use later? May be store data on only one pixel? I have seen game of life sample, I thing that you could add a sample like using mouse to change color. It will be very useful for beginners. Thank you.

anmolshowcase commented 4 months ago

I Agree, it would be great if we could save one pixel data in memory and modify it when needed. backbuffer works great until you need to sample the last frame but in my case i want to sample how much time has passed since the last touch was performed and if i could store the time data in a pixel value and reference it in next frame it would work. :)

I hope we get something like that soon.

AntonPieper commented 4 months ago

I think what you really want would be the ability to also write scripts for the CPU as well.

This would require the addition of an actual filesystem and a scripting language like LuaJ or JavascriptEngine. JavascriptEngine would require API level 26 though.

Custom variables

Custom variables could be passed using a setUniform API and the data can be modified in the main loop.

Script Examples for Lua/JavaScript ### Lua Custom Variables ```lua local engine = require("ShaderEngine") -- Create a shader object local shader = engine:createShader("./main.glsl") -- Initialize sensors local accelerometer = engine:initProvider("accelerometer") local myCustomData = vec2.new(0, 0) -- Function to update uniforms local function updateUniforms(shader) -- Pass sensor data to the shader as uniforms shader:setUniform("accelerometer", accelerometer:getData()) shader:setUniform("myCustomData", myCustomData) shader:setUniform("backbuffer", engine:getBackBufferTexture()) local time = engine:getTime() shader:setUniform("time", time) myCustomData:add(1, 0) end -- Start the engine loop while engine:running() do -- Clear the screen engine:clear() -- Update sensors accelerometer:update() -- Update shader uniforms updateUniforms(shader) -- Render the full-screen shader engine:render{ shader = shader } -- Swap buffers to display the rendered frame engine:swapBuffers() end ``` ### JavaScript Custom Variables ```js import engine from "shader-engine"; // Create a shader object const shader = engine.createShader("./main.glsl"); // Initialize sensors const accelerometer = engine.initProvider("accelerometer"); const myCustomData = new Vec2(0, 0); // Function to update uniforms function updateUniforms(shader) { // Pass sensor data to the shader as uniforms shader.setUniform("accelerometer", accelerometer.data); shader.setUniform("myCustomData", myCustomData); shader.setUniform("backbuffer", engine.backBufferTexture); const time = engine.time; shader.setUniform("time", time); myCustomData.add(1, 0); } // Start the engine loop while (engine.running) { // Clear the screen engine.clear(); // Update sensors accelerometer.update(); // Update shader uniforms updateUniforms(shader); // Render the full-screen shader engine.render({shader}); // Swap buffers to display the rendered frame engine.swapBuffers(); } ```

Default Script

To not break backwards compatibility, a default script could be used and all shaders get converted into a {shader_name}/main.glsl path.

Script Examples for Lua/JavaScript ### Lua Default Script ```lua local engine = require("ShaderEngine") local shader = engine:createShader("./main.glsl") local sensors = engine:initProviders(shader:getUniformNames()) while engine:running() do engine:clear() for k, v in pairs(sensors) do v:update() shader:setUniform(k, v:getData()) end engine:render{ shader = shader } engine:swapBuffers() end ``` ### JavaScript Default Script ```js import engine from "shader-engine"; const shader = engine.createShader("./main.glsl"); const sensors = engine.initProviders(shader.uniformNames); while (engine.running) { engine.clear(); for (const [key, value] of Object.entries(sensors)) { value.update(); shader:setUniform(key, value.data); } engine.render({shader}); engine.swapBuffers(); } ```