Files
live-wallpaper/samples/dry_rocky_gorge.lua
Diego Lopes 52dc6fc757 Add GStreamer support for video textures and update related files
- Introduced GStreamerTexture class for handling video frames.
- Updated texture loading methods to include FromGStreamer.
- Modified effect handling to support GStreamer textures.
- Updated launch configuration and added new sample scripts.
2026-03-20 21:54:43 -04:00

291 lines
7.9 KiB
Lua

-- Dry Rocky Gorge by Shane
-- License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
-- Converted from ShaderToy to live-wallpaper system
effect = nil
rockTexture = nil
function _create()
rockTexture = Texture.FromFile("rock_texture.jpg")
rockTexture:Bind()
rockTexture:SetFilter(TextureFilter.LinearMipmapLinear, TextureFilter.Linear)
rockTexture:SetWrap(TextureWrap.Repeat, TextureWrap.Repeat)
rockTexture:GenerateMipmaps()
local fxSrc = [[
in vec2 vPosition;
uniform sampler2D iChannel0;
#define FAR 80.
mat2 r2(in float a){ float c = cos(a), s = sin(a); return mat2(c, s, -s, c); }
float hash31( vec3 p ){ return fract(sin(dot(p, vec3(157, 113, 7)))*45758.5453); }
float hash21( vec2 p ){ return fract(sin(dot(p, vec2(41, 289)))*45758.5453); }
vec3 hash33(vec3 p){
float n = sin(dot(p, vec3(7, 157, 113)));
return fract(vec3(2097152, 262144, 32768)*n);
}
float n3D(vec3 p){
const vec3 s = vec3(7, 157, 113);
vec3 ip = floor(p); p -= ip;
vec4 h = vec4(0., s.yz, s.y + s.z) + dot(ip, s);
p = p*p*(3. - 2.*p);
h = mix(fract(sin(h)*43758.5453), fract(sin(h + s.x)*43758.5453), p.x);
h.xy = mix(h.xz, h.yw, p.y);
return mix(h.x, h.y, p.z);
}
float n2D(vec2 p) {
vec2 i = floor(p); p -= i; p *= p*(3. - p*2.);
return dot(mat2(fract(sin(vec4(0, 41, 289, 330) + dot(i, vec2(41, 289)))*43758.5453))*
vec2(1. - p.y, p.y), vec2(1. - p.x, p.x));
}
vec3 tex3D( sampler2D t, in vec3 p, in vec3 n ){
n = max(abs(n), 0.001);
n /= dot(n, vec3(1));
vec3 tx = texture(t, p.yz).xyz;
vec3 ty = texture(t, p.zx).xyz;
vec3 tz = texture(t, p.xy).xyz;
return (tx*tx*n.x + ty*ty*n.y + tz*tz*n.z);
}
vec2 path(in float z){
return vec2(sin(z*.075)*8., cos(z*.1)*.75);
}
float smax(float a, float b, float s){
float h = clamp(.5 + .5*(a - b)/s, 0., 1.);
return mix(b, a, h) + h*(1. - h)*s;
}
float terrain(vec2 p){
p /= 8.;
p += .5;
float a = 1., sum = 0., res = 0.;
for (int i=0; i<5; i++){
res += n2D(p)*a;
p = mat2(1, -.75, .75, 1)*p*2.72;
sum += a;
a *= -.5/1.7;
}
return res/sum;
}
float map(vec3 p){
float trSf = terrain(p.xz);
p.xy -= path(p.z);
vec2 ca = abs(p.xy*vec2(1, .7) + vec2(0, -2.75));
float n = smax(6. - mix(length(ca), max(ca.x, ca.y), .25), p.y - 1.75, 2.) + (.5 - trSf)*4.;
return n;
}
vec3 texBump( sampler2D tx, in vec3 p, in vec3 n, float bf){
const vec2 e = vec2(.001, 0);
mat3 m = mat3( tex3D(tx, p - e.xyy, n), tex3D(tx, p - e.yxy, n), tex3D(tx, p - e.yyx, n));
vec3 g = vec3(.299, .587, .114)*m;
g = (g - dot(tex3D(tx, p , n), vec3(.299, .587, .114)) )/e.x;
g -= n*dot(n, g);
return normalize( n + g*bf );
}
float trace(vec3 ro, vec3 rd){
float t = 0., d;
for (int i=0; i<160; i++){
d = map(ro + rd*t);
if(abs(d)<.001*(t*.025 + 1.) || t>FAR) break;
t += d*.7;
}
return min(t, FAR);
}
float softShadow(vec3 ro, vec3 n, vec3 lp, float k, float t){
const int maxIterationsShad = 48;
ro += n*.0015;
vec3 rd = lp - ro;
float shade = 1.;
float dist = .0;
float end = max(length(rd), 0.0001);
rd /= end;
for (int i=0; i<maxIterationsShad; i++){
float h = map(ro + rd*dist);
shade = min(shade, smoothstep(0.0, 1.0, k*h/dist));
dist += clamp(h, .02, .25);
if (h<0. || dist > end) break;
}
return min(max(shade, 0.) + .15, 1.);
}
vec3 getNormal( in vec3 p ){
vec2 e = vec2(.001, -.001);
return normalize(e.xyy*map(p + e.xyy) + e.yyx*map(p + e.yyx) + e.yxy*map(p + e.yxy) + e.xxx*map(p + e.xxx));
}
float calcAO(in vec3 p, in vec3 nor){
float sca = 1.5, occ = 0.;
for(float i=0.; i<5.; i++){
float hr = .01 + i*.5/4.;
float dd = map(nor*hr + p);
occ += (hr - dd)*sca;
sca *= .7;
}
return clamp(1. - occ, 0., 1.);
}
float fmap(vec3 p){
p *= vec3(1, 4, 1)/400.;
return n3D(p)*0.57 + n3D(p*4.)*0.28 + n3D(p*8.)*0.15;
}
vec4 cloudLayers(vec3 ro, vec3 rd, vec3 lp, float far){
rd = (rd + (hash33(rd.zyx)*0.004-0.002));
rd *= (1. + fract(sin(dot(vec3(7, 157, 113), rd.zyx))*43758.5453)*0.04-0.02);
float localDensity=0., td=0., w=0.;
float d=1., t=0.;
const float h = .5;
vec3 col = vec3(0), sp;
vec4 d4 = vec4(1, 0, 0, 0);
vec3 sn = normalize(hash33(rd.yxz)*.03-rd);
for (int i=0; i<4; i++) {
if(td>1. || t>far)break;
sp = ro + rd*t;
d = fmap(sp);
localDensity = (h - d) * step(d, h);
w = (1. - td) * localDensity;
td += w*.5 + 1./65.;
vec3 lightDir = lp-sp;
float lDist = max(length(lightDir), 0.001);
lightDir /= lDist;
float atten = 100./(1. + lDist*0.005 + lDist*lDist*0.00005);
float diff = max(dot( sn, lightDir ), 0.);
float spec = pow(max( dot( reflect(-lightDir, sn), -rd ), 0. ), 4.);
col += w*(diff + vec3(1, .75, .5)*spec + .5)*atten;
t += max(d4.x*.5, 0.25)*100.;
}
return vec4(col, t);
}
vec3 getSky(in vec3 ro, in vec3 rd, vec3 lp, float t){
float sun = max(dot(rd, normalize(lp - ro)), 0.0);
float horiz = pow(1.0-max(rd.y, 0.0), 3.)*.25;
vec3 col = mix(vec3(.25, .5, 1)*.8, vec3(.8, .75, .7), sun*.5);
col = mix(col, vec3(1, .5, .25), horiz);
col += 0.25*vec3(1, .7, .4)*pow(sun, 5.0);
col += 0.25*vec3(1, .8, .6)*pow(sun, 64.0);
col += 0.15*vec3(1, .9, .7)*max(pow(sun, 512.0), .25);
col = clamp(col + hash31(rd)*0.04 - 0.02, 0., 1.);
float tt = (1000. - ro.y)/(rd.y + .2);
if(t>=FAR && tt>0.){
vec4 cl = cloudLayers(ro + rd*tt, rd, lp, FAR*3.);
vec3 clouds = cl.xyz;
col = mix( col, vec3(1), clouds);
}
return col;
}
vec3 getObjectColor(vec3 p, vec3 n){
vec3 tx = tex3D(iChannel0, p/8., n );
vec3 gr = mix(vec3(1), vec3(.8, 1.3, .2), smoothstep(.5, 1., n.y));
return mix(tx, tx*gr, smoothstep(.7, 1., (n.y)));
}
vec3 doColor(in vec3 ro, in vec3 rd, in vec3 lp, float t){
vec3 sceneCol = vec3(0);
if(t<FAR){
vec3 sp = ro + rd*t;
vec3 sn = getNormal(sp);
vec3 tx = sp;
sn = texBump(iChannel0, tx/2., sn, .15);
float sh = softShadow(sp, sn, lp, 16., t);
float ao = calcAO(sp, sn);
sh = (sh + ao*.25)*ao;
vec3 ld = lp - sp;
float lDist = max(length(ld), 0.001);
ld /= lDist;
float atten = 3./(1. + lDist*0.005 + lDist*lDist*0.00005);
float diff = max(dot(sn, ld), 0.);
float spec = pow(max( dot( reflect(-ld, sn), -rd ), 0.0 ), 64.0);
vec3 objCol = getObjectColor(sp, sn);
sceneCol = objCol*(diff + ao*.5 + vec3(1, .7, .5)*spec);
sceneCol *= atten*sh;
}
return sceneCol;
}
void main(){
vec2 fragCoord = (vPosition * 0.5 + 0.5) * uDesktopSize;
vec2 uv = (fragCoord - uDesktopSize.xy*.5)/uDesktopSize.y;
vec3 ro = vec3(0, 0, uTime*5.);
vec3 lk = ro + vec3(0, -.04, .25);
vec3 lp = ro + vec3(8, FAR*.26, FAR*.52)*3.;
ro.xy += path(ro.z);
lk.xy += path(lk.z);
lp.xy += path(lp.z);
float FOV = 3.14159/3.;
vec3 forward = normalize(lk-ro);
vec3 right = normalize(vec3(forward.z, 0., -forward.x ));
vec3 up = cross(forward, right);
vec3 rd = normalize(uv.x*right + uv.y*up + forward/FOV);
vec2 sw = path(lk.z);
rd.xy *= r2(-sw.x/24.);
rd.yz *= r2(-sw.y/16.);
float t = trace(ro, rd);
vec3 sky = getSky(ro, rd, lp, t);
vec3 sceneColor = doColor(ro, rd, lp, t);
float fog = smoothstep(0., .95, t/FAR);
vec3 fogCol = sky;
sceneColor = mix(sceneColor, fogCol, fog);
uv = fragCoord/uDesktopSize.xy;
sceneColor *= pow(16.*uv.x*uv.y*(1. - uv.x)*(1. - uv.y) , .125)*.75 + .25;
FragColor = vec4(sqrt(clamp(sceneColor, 0.0, 1.0)), 1.0);
}
]]
effect = Effect.new(fxSrc)
end
function _update(dt)
end
function _render()
gl.Clear(0, 0, 0, 1.0)
effect:Use()
effect:SetTexture("iChannel0", rockTexture, 0)
effect:Render()
end