effect = nil ctxFBO = nil ctx = nil clockTexture = nil clockText = "" timer = 0.0 function _create() local display0 = Displays[1] ctxFBO = FrameBuffer.new(math.floor(display0.z), math.floor(display0.w)) local att = ColorAttachment.new() att.format = TextureFormatType.RGBA8 att.minFilter = TextureFilter.LinearMipmapLinear att.magFilter = TextureFilter.Linear att.wrapS = TextureWrap.ClampToEdge att.wrapT = TextureWrap.ClampToEdge ctxFBO:SetDepthStencilFormat(DepthStencilFormat.Depth24Stencil8) ctxFBO:AddColorAttachment(att) clockTexture = ctxFBO:GetColorTexture(0) ctx = GraphicsContext.new() ctx:CreateFont("font", Resolve("font.otf")) local fxSrc = [[uniform sampler2D uTexture; const float floorPosition = 0.55; float waves(in vec2 uv) { float speed = 4.0; float topright = sin(uTime*(speed+1.0) - sin(length(uv-vec2(1.0,1.0)))*53.0); float topleft = sin(uTime*(speed+1.0) - sin(length(uv-vec2(0.0,1.0)))*37.0); float bottomright = sin(uTime*(speed) - sin(length(uv-vec2(1.0,0.0)))*61.0); float bottomleft = sin(uTime*(speed+2.0) - sin(length(uv-vec2(0.0,0.0)))*47.0); float horizontalWaves = sin(uTime * (speed + 2.0) - sin(uv.y) * 47.0); float temp = horizontalWaves + bottomleft * 0.4 + bottomright * 0.2 + topleft * 0.6 + topright * 0.3; float b=smoothstep(-2.5,5.0,temp); return b*3.0; } void main() { vec2 uv = vUV; for (int i = 0; i < uNumDisplays; i++) { vec4 displayNorm = uDisplayNorm[i]; if (vUV.x >= displayNorm.x && vUV.x <= displayNorm.x + displayNorm.z && vUV.y >= displayNorm.y && vUV.y <= displayNorm.y + displayNorm.w) { vec2 duv = GetDisplayUV(uTexture, i); // Base FragColor = texture(uTexture, duv); // Reflection if (duv.y > floorPosition) { float reflectY = floorPosition - (duv.y - floorPosition); vec2 reflectUV = vec2(duv.x, reflectY); // deform the reflection based on the height function float wv = waves(vec2(reflectUV.x * 2.0, reflectUV.y * 3.6 - 0.4)); float dx = dFdx(wv); float dy = dFdy(wv); reflectUV += vec2(dx, dy) * 0.25; // Adjust deformation float lod = clamp(reflectUV.y * 3.0, 0.0, 3.0); // Adjust LOD based on distance vec4 reflectColor = textureLod(uTexture, reflectUV, lod); // Apply a simple fade based on distance from the floor float fade = 1.0 - smoothstep(floorPosition, floorPosition + 0.1, duv.y); FragColor += reflectColor * fade * 0.5; // Adjust reflection intensity } break; } } } ]] effect = Effect.new(fxSrc) clockText = os.date("%H:%M") end function _update(dt) timer = timer + dt if timer >= 0.5 then timer = 0.0 clockText = os.date("%H:%M") end end function _render() local display0 = Displays[1] ctxFBO:Bind() gl.Clear(0, 0, 0, 0) ctx:BeginFrame(display0.z, display0.w, display0.z / display0.w) ctx:FontSize(144) ctx:FontFace("font") ctx:FillColor(RGBAf(1, 1, 1, 0.75)) ctx:TextAlign(Align.CENTER | Align.MIDDLE) ctx:Text(display0.z / 2, display0.w / 2, clockText) ctx:EndFrame() ctxFBO:Unbind() clockTexture:Bind() clockTexture:GenerateMipmaps() gl.SetViewport(0, 0, math.floor(DesktopSize.x), math.floor(DesktopSize.y)) gl.Clear(0, 0, 0, 1.0) effect:Use() effect:SetTexture("uTexture", clockTexture, 0) effect:Render() end