mirror of
https://github.com/Xaymar/obs-StreamFX
synced 2024-11-15 16:25:06 +00:00
b765d6e745
Converts 'https://www.shadertoy.com/view/MslGRn' into a usable StreamFX shader.
198 lines
4.2 KiB
Text
198 lines
4.2 KiB
Text
// https://www.shadertoy.com/view/MslGRn
|
|
#define vec2 float2
|
|
#define vec3 float3
|
|
#define vec4 float4
|
|
#define ivec2 int2
|
|
#define ivec3 int3
|
|
#define ivec4 int4
|
|
#define mat3 float3x3
|
|
#define mat4 float4x4
|
|
#define fract frac
|
|
#define mix lerp
|
|
#define iTime Time.x
|
|
#define iResolution ViewSize
|
|
|
|
uniform float2 mouse<
|
|
string name = "Virtual Mouse Coordinates";
|
|
string field_type = "slider";
|
|
float2 minimum = {0, 0};
|
|
float2 maximum = {100., 100.};
|
|
float2 scale = {.01, .01};
|
|
float2 step = {.01, .01};
|
|
> = {0., 0.};
|
|
|
|
uniform float4x4 ViewProj<
|
|
bool automatic = true;
|
|
>;
|
|
|
|
uniform float4 Time<
|
|
bool automatic = true;
|
|
>;
|
|
|
|
uniform float4 ViewSize<
|
|
bool automatic = true;
|
|
>;
|
|
|
|
int2 iMouse() {
|
|
return int2(mouse.x * ViewSize.x, mouse.y * ViewSize.y);
|
|
}
|
|
|
|
#define TWO_OCTAVES
|
|
#define THREE_OCTAVES
|
|
#define SLICES 50.0
|
|
#define START_AMPLITUDE 0.01
|
|
#define START_FREQUENCY 1.25
|
|
#define START_DENSITY 0.0
|
|
#define ANIMATION_SPEED 0.075
|
|
|
|
float hash( float n )
|
|
{
|
|
return fract(sin(n)*43758.5453123);
|
|
}
|
|
|
|
float noise( in vec3 x )
|
|
{
|
|
vec3 p = floor(x);
|
|
vec3 f = fract(x);
|
|
f = f*f*(3.0-2.0*f);
|
|
float n = p.x + p.y*57.0 + 113.0*p.z;
|
|
float res = mix(mix(mix( hash(n+ 0.0), hash(n+ 1.0),f.x), mix( hash(n+ 57.0), hash(n+ 58.0),f.x),f.y), mix(mix( hash(n+113.0), hash(n+114.0),f.x), mix( hash(n+170.0), hash(n+171.0),f.x),f.y),f.z);
|
|
return res;
|
|
}
|
|
|
|
// fbm noise for 2-4 octaves including rotation per octave
|
|
float fbm( vec3 p )
|
|
{
|
|
// rotation matrix for fbm octaves
|
|
mat3 m = mat3( 0.00, 0.80, 0.60, -0.80, 0.36, -0.48, -0.60, -0.48, 0.64 );
|
|
|
|
float f = 0.0;
|
|
f += 0.5000*noise( p );
|
|
p = mul(p, m) * 2.02;
|
|
f += 0.2500*noise( p );
|
|
#ifdef TWO_OCTAVES
|
|
return f/0.75;
|
|
#else
|
|
p = mul(m, p) * 2.03;
|
|
f += 0.1250*noise( p );
|
|
#ifdef THREE_OCTAVES
|
|
return f/0.875;
|
|
#else
|
|
p = mul(m, p) * 2.01;
|
|
f += 0.0625*noise( p );
|
|
return f/0.9375;
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
vec3 gradient(float s)
|
|
{
|
|
return vec3(0.0, max(1.0-s*2.0, 0.0), max(s>0.5?1.0-(s-0.5)*5.0:1.0, 0.0));
|
|
}
|
|
|
|
#define RADIUS 0.5
|
|
bool intersectSphere(vec3 origin, vec3 direction, out float tmin, out float tmax)
|
|
{
|
|
bool hit = false;
|
|
float a = dot(direction, direction);
|
|
float b = 2.0*dot(origin, direction);
|
|
float c = dot(origin, origin) - 0.5*0.5;
|
|
float disc = b*b - 4.0*a*c; // discriminant
|
|
tmin = tmax = 0.0;
|
|
|
|
if (disc > 0.0) {
|
|
// Real root of disc, so intersection
|
|
float sdisc = sqrt(disc);
|
|
float t0 = (-b - sdisc)/(2.0*a); // closest intersection distance
|
|
float t1 = (-b + sdisc)/(2.0*a); // furthest intersection distance
|
|
|
|
tmax = t1;
|
|
if (t0 >= 0.0)
|
|
tmin = t0;
|
|
hit = true;
|
|
}
|
|
|
|
return hit;
|
|
}
|
|
|
|
vec2 rt(vec2 x,float y)
|
|
{
|
|
return vec2(cos(y)*x.x-sin(y)*x.y,sin(y)*x.x+cos(y)*x.y);
|
|
}
|
|
|
|
void mainImage( out vec4 fragColor, in vec2 fragCoord )
|
|
{
|
|
// normalized and aspect ratio corrected pixel coordinate
|
|
vec2 p = (fragCoord.xy / iResolution.xy)*2.0-1.0;
|
|
p.x *= iResolution.x/ iResolution.y;
|
|
|
|
// camera and user input
|
|
vec3 oo = vec3(0, 0, 1.0-iMouse().y/iResolution.y);
|
|
vec3 od = normalize(vec3(p.x, p.y, -2.0));
|
|
vec3 o,d;
|
|
o.xz = rt(oo.xz, 6.3*iMouse().x/iResolution.x);
|
|
o.y = oo.y;
|
|
d.xz = rt(od.xz, 6.3*iMouse().x/iResolution.x);
|
|
d.y = od.y;
|
|
|
|
// render
|
|
vec4 col = vec4(0, 0, 0, 1);
|
|
float tmin, tmax;
|
|
if (intersectSphere(o, d, tmin, tmax))
|
|
{
|
|
// step thoug the sphere with max SLICES steps
|
|
for (float i = 0.0; i < SLICES; i+=1.0)
|
|
{
|
|
// stay within the sphere bounds
|
|
float t = tmin+i/SLICES;
|
|
if (t > tmax)
|
|
break;
|
|
vec3 curpos = o + d*t;
|
|
|
|
// get sphere falloff in s
|
|
float s = (0.5-length(curpos))*2.0;
|
|
s*=s;
|
|
|
|
// get turbulence in d
|
|
float a = START_AMPLITUDE;
|
|
float b = START_FREQUENCY;
|
|
float d = START_DENSITY;
|
|
for (int j = 0; j < 3; j++)
|
|
{
|
|
d += 0.5/abs((fbm(5.0*curpos*b+ANIMATION_SPEED*iTime/b)*2.0-1.0)/a);
|
|
b *= 2.0;
|
|
a /= 2.0;
|
|
}
|
|
|
|
// get gradient color depending on s
|
|
col.rgb += gradient(s)*max(d*s,0.0);
|
|
}
|
|
}
|
|
|
|
fragColor = col;
|
|
}
|
|
|
|
struct VertFragData {
|
|
float4 pos : POSITION;
|
|
float2 uv : TEXCOORD0;
|
|
};
|
|
|
|
VertFragData VSDefault(VertFragData vtx) {
|
|
vtx.pos = mul(float4(vtx.pos.xyz, 1.0), ViewProj);
|
|
return vtx;
|
|
}
|
|
|
|
float4 PSDefault(VertFragData vtx) : TARGET {
|
|
float4 col = float4(1., 1., 1., 1.);
|
|
mainImage(col, vtx.uv * ViewSize.xy);
|
|
return col;
|
|
}
|
|
|
|
technique Draw
|
|
{
|
|
pass
|
|
{
|
|
vertex_shader = VSDefault(vtx);
|
|
pixel_shader = PSDefault(vtx);
|
|
}
|
|
}
|