June 19, 2019, 05:04:27 AM

Author Topic: One of the best shaders on ShaderToy.com  (Read 2673 times)

Offline col

  • Sr. Member
  • ****
  • Posts: 422
One of the best shaders on ShaderToy.com
« on: August 23, 2018, 05:09:38 PM »
Hiya,

After giving some advice for takis76 whos trying his/her best to get into shaders I recommended going to ShaderToy.com for some inspiration. While there I saw the most famous and most gorgeous SeaScape by Alexander Alekseev. And I thought.... yeah why not port it to BMax :)

This has got to be one of the most beautiful shaders I've seen so far  :)

Code: [Select]

SuperStrict
Framework brl.system
Import brl.max2d
Import srs.shaderframework

SetGraphicsDriver GLMax2DDriver()
Local gc:TGraphics = Graphics(1200, 900)

Local sf:TShaderFramework = CreateShaderFramework(gc)
Local DefaultVertexShader:TVertexShader = sf.CreateVertexShader(vertex_source())
If Not DefaultVertexShader
Notify("Could not create vertex shader")
Return
EndIf
Local WaterPixelShader:TPixelShader = sf.CreatePixelShader(pixel_source())
If Not WaterPixelShader
Notify("Could not create pixel shader")
Return
EndIf
Local WaterShader:TShaderProgram = sf.CreateShaderProgram(DefaultVertexShader, WaterPixelShader)
If Not WaterShader
Notify("Could not create water shader")
Return
EndIf

Local resolution:TShaderUniform = WaterShader.GetShaderUniform("iResolution")
Local time:TShaderUniform = WaterShader.GetShaderUniform("iTime")
Local mouse:TShaderUniform = WaterShader.GetShaderUniform("iMouse")

Local quad:TImage = CreateImage(GraphicsWidth(), GraphicsHeight())
resolution.SetFloat2(ImageWidth(quad), ImageHeight(quad))


Global iTime:Float
While Not KeyDown(KEY_ESCAPE) And Not AppTerminate()
Cls
sf.SetShader(WaterShader)

If MouseDown(1)
mouse.SetFloat4(MouseX(), MouseY(), 1.0, 0.0)
Else If MouseDown(2)
mouse.SetFloat4(MouseX(), MouseY(), 1.0, 0.0)
EndIf

time.SetFloat(iTime)
iTime :+ (1.0 / 60.0)
DrawImage(quad, 0, 0)
sf.SetShader(Null)

SetColor 0, 0, 0
DrawText("Original shader source is by Alexander Alekseev - https://www.shadertoy.com/view/Ms2SD1", 10, 10)
Flip 1
Wend

Function vertex_source:String()
Local source:String
source :+ "#version 120~n"
source :+ "uniform vec2      iResolution;           // viewport resolution (in pixels)~n"

source :+ "varying vec4 var_color;~n"
source :+ "varying vec2 fragCoord;~n"

source :+ "void main() {~n"
source :+ "   gl_Position = ftransform();~n"
source :+ "   var_color = gl_Color;~n"
source :+ "   fragCoord = vec2(gl_MultiTexCoord0.s, 1.0 - gl_MultiTexCoord0.t) * iResolution;~n"
source :+ "}~n"
Return source
EndFunction



Function pixel_source:String()
' Original source code is available at https://www.shadertoy.com/view/Ms2SD1

Local glslSource:String

glslSource :+ "#version 120~n"
glslSource :+ "uniform vec4      iMouse;                // mouse pixel coords. xy: current (if MLB down), zw: click~n"
glslSource :+ "uniform vec2      iResolution;           // viewport resolution (in pixels)~n"
glslSource :+ "uniform float     iTime;                 // shader playback time (in seconds)~n"

glslSource :+ "varying vec4 var_color;~n"
glslSource :+ "varying vec2 fragCoord;~n"

glslSource :+ "/*~n"
glslSource :+ " * ~qSeascape~q by Alexander Alekseev aka TDM - 2014~n"
glslSource :+ " * License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.~n"
glslSource :+ " * Contact: tdmaav@gmail.com~n"
glslSource :+ " */~n"
glslSource :+ "~n"
glslSource :+ "const int NUM_STEPS = 8;~n"
glslSource :+ "const float PI = 3.141592;~n"
glslSource :+ "const float EPSILON = 1e-3;~n"
glslSource :+ "#define EPSILON_NRM (0.1 / iResolution.x)~n"
glslSource :+ "~n"
glslSource :+ "// sea~n"
glslSource :+ "const int ITER_GEOMETRY = 3;~n"
glslSource :+ "const int ITER_FRAGMENT = 5;~n"
glslSource :+ "const float SEA_HEIGHT = 0.6;~n"
glslSource :+ "const float SEA_CHOPPY = 4.0;~n"
glslSource :+ "const float SEA_SPEED = 0.8;~n"
glslSource :+ "const float SEA_FREQ = 0.16;~n"
glslSource :+ "const vec3 SEA_BASE = vec3(0.1,0.19,0.22);~n"
glslSource :+ "const vec3 SEA_WATER_COLOR = vec3(0.8,0.9,0.6);~n"
glslSource :+ "#define SEA_TIME (1.0 + iTime * SEA_SPEED)~n"
glslSource :+ "const mat2 octave_m = mat2(1.6,1.2,-1.2,1.6);~n"
glslSource :+ "~n"
glslSource :+ "// math~n"
glslSource :+ "mat3 fromEuler(vec3 ang) {~n"
glslSource :+ "    vec2 a1 = vec2(sin(ang.x),cos(ang.x));~n"
glslSource :+ "    vec2 a2 = vec2(sin(ang.y),cos(ang.y));~n"
glslSource :+ "    vec2 a3 = vec2(sin(ang.z),cos(ang.z));~n"
glslSource :+ "    mat3 m;~n"
glslSource :+ "    m[0] = vec3(a1.y*a3.y+a1.x*a2.x*a3.x,a1.y*a2.x*a3.x+a3.y*a1.x,-a2.y*a3.x);~n"
glslSource :+ "    m[1] = vec3(-a2.y*a1.x,a1.y*a2.y,a2.x);~n"
glslSource :+ "    m[2] = vec3(a3.y*a1.x*a2.x+a1.y*a3.x,a1.x*a3.x-a1.y*a3.y*a2.x,a2.y*a3.y);~n"
glslSource :+ "    return m;~n"
glslSource :+ "}~n"
glslSource :+ "float hash( vec2 p ) {~n"
glslSource :+ " float h = dot(p,vec2(127.1,311.7));~n"
glslSource :+ "    return fract(sin(h)*43758.5453123);~n"
glslSource :+ "}~n"
glslSource :+ "float noise( in vec2 p ) {~n"
glslSource :+ "    vec2 i = floor( p );~n"
glslSource :+ "    vec2 f = fract( p );~n"
glslSource :+ " vec2 u = f*f*(3.0-2.0*f);~n"
glslSource :+ "    return -1.0+2.0*mix( mix( hash( i + vec2(0.0,0.0) ),~n"
glslSource :+ "                     hash( i + vec2(1.0,0.0) ), u.x),~n"
glslSource :+ "                mix( hash( i + vec2(0.0,1.0) ),~n"
glslSource :+ "                     hash( i + vec2(1.0,1.0) ), u.x), u.y);~n"
glslSource :+ "}~n"
glslSource :+ "~n"
glslSource :+ "// lighting~n"
glslSource :+ "float diffuse(vec3 n,vec3 l,float p) {~n"
glslSource :+ "    return pow(dot(n,l) * 0.4 + 0.6,p);~n"
glslSource :+ "}~n"
glslSource :+ "float specular(vec3 n,vec3 l,vec3 e,float s) {~n"
glslSource :+ "    float nrm = (s + 8.0) / (PI * 8.0);~n"
glslSource :+ "    return pow(max(dot(reflect(e,n),l),0.0),s) * nrm;~n"
glslSource :+ "}~n"
glslSource :+ "~n"
glslSource :+ "// sky~n"
glslSource :+ "vec3 getSkyColor(vec3 e) {~n"
glslSource :+ "    e.y = max(e.y,0.0);~n"
glslSource :+ "    return vec3(pow(1.0-e.y,2.0), 1.0-e.y, 0.6+(1.0-e.y)*0.4);~n"
glslSource :+ "}~n"
glslSource :+ "~n"
glslSource :+ "// sea~n"
glslSource :+ "float sea_octave(vec2 uv, float choppy) {~n"
glslSource :+ "    uv += noise(uv);~n"
glslSource :+ "    vec2 wv = 1.0-abs(sin(uv));~n"
glslSource :+ "    vec2 swv = abs(cos(uv));~n"
glslSource :+ "    wv = mix(wv,swv,wv);~n"
glslSource :+ "    return pow(1.0-pow(wv.x * wv.y,0.65),choppy);~n"
glslSource :+ "}~n"
glslSource :+ "~n"
glslSource :+ "float map(vec3 p) {~n"
glslSource :+ "    float freq = SEA_FREQ;~n"
glslSource :+ "    float amp = SEA_HEIGHT;~n"
glslSource :+ "    float choppy = SEA_CHOPPY;~n"
glslSource :+ "    vec2 uv = p.xz; uv.x *= 0.75;~n"
glslSource :+ "~n"
glslSource :+ "    float d, h = 0.0;~n"
glslSource :+ "    for(int i = 0; i < ITER_GEOMETRY; i++) {~n"
glslSource :+ "    d = sea_octave((uv+SEA_TIME)*freq,choppy);~n"
glslSource :+ "    d += sea_octave((uv-SEA_TIME)*freq,choppy);~n"
glslSource :+ "        h += d * amp;~n"
glslSource :+ "    uv *= octave_m; freq *= 1.9; amp *= 0.22;~n"
glslSource :+ "        choppy = mix(choppy,1.0,0.2);~n"
glslSource :+ "    }~n"
glslSource :+ "    return p.y - h;~n"
glslSource :+ "}~n"
glslSource :+ "~n"
glslSource :+ "float map_detailed(vec3 p) {~n"
glslSource :+ "    float freq = SEA_FREQ;~n"
glslSource :+ "    float amp = SEA_HEIGHT;~n"
glslSource :+ "    float choppy = SEA_CHOPPY;~n"
glslSource :+ "    vec2 uv = p.xz; uv.x *= 0.75;~n"
glslSource :+ "~n"
glslSource :+ "    float d, h = 0.0;~n"
glslSource :+ "    for(int i = 0; i < ITER_FRAGMENT; i++) {~n"
glslSource :+ "    d = sea_octave((uv+SEA_TIME)*freq,choppy);~n"
glslSource :+ "    d += sea_octave((uv-SEA_TIME)*freq,choppy);~n"
glslSource :+ "        h += d * amp;~n"
glslSource :+ "    uv *= octave_m; freq *= 1.9; amp *= 0.22;~n"
glslSource :+ "        choppy = mix(choppy,1.0,0.2);~n"
glslSource :+ "    }~n"
glslSource :+ "    return p.y - h;~n"
glslSource :+ "}~n"
glslSource :+ "~n"
glslSource :+ "vec3 getSeaColor(vec3 p, vec3 n, vec3 l, vec3 eye, vec3 dist) {~n"
glslSource :+ "    float fresnel = clamp(1.0 - dot(n,-eye), 0.0, 1.0);~n"
glslSource :+ "    fresnel = pow(fresnel,3.0) * 0.65;~n"
glslSource :+ "~n"
glslSource :+ "    vec3 reflected = getSkyColor(reflect(eye,n));~n"
glslSource :+ "    vec3 refracted = SEA_BASE + diffuse(n,l,80.0) * SEA_WATER_COLOR * 0.12;~n"
glslSource :+ "~n"
glslSource :+ "    vec3 color = mix(refracted,reflected,fresnel);~n"
glslSource :+ "~n"
glslSource :+ "    float atten = max(1.0 - dot(dist,dist) * 0.001, 0.0);~n"
glslSource :+ "    color += SEA_WATER_COLOR * (p.y - SEA_HEIGHT) * 0.18 * atten;~n"
glslSource :+ "~n"
glslSource :+ "    color += vec3(specular(n,l,eye,60.0));~n"
glslSource :+ "~n"
glslSource :+ "    return color;~n"
glslSource :+ "}~n"
glslSource :+ "~n"
glslSource :+ "// tracing~n"
glslSource :+ "vec3 getNormal(vec3 p, float eps) {~n"
glslSource :+ "    vec3 n;~n"
glslSource :+ "    n.y = map_detailed(p);~n"
glslSource :+ "    n.x = map_detailed(vec3(p.x+eps,p.y,p.z)) - n.y;~n"
glslSource :+ "    n.z = map_detailed(vec3(p.x,p.y,p.z+eps)) - n.y;~n"
glslSource :+ "    n.y = eps;~n"
glslSource :+ "    return normalize(n);~n"
glslSource :+ "}~n"
glslSource :+ "~n"
glslSource :+ "float heightMapTracing(vec3 ori, vec3 dir, out vec3 p) {~n"
glslSource :+ "    float tm = 0.0;~n"
glslSource :+ "    float tx = 1000.0;~n"
glslSource :+ "    float hx = map(ori + dir * tx);~n"
glslSource :+ "    if(hx > 0.0) return tx;~n"
glslSource :+ "    float hm = map(ori + dir * tm);~n"
glslSource :+ "    float tmid = 0.0;~n"
glslSource :+ "    for(int i = 0; i < NUM_STEPS; i++) {~n"
glslSource :+ "        tmid = mix(tm,tx, hm/(hm-hx));~n"
glslSource :+ "        p = ori + dir * tmid;~n"
glslSource :+ "    float hmid = map(p);~n"
glslSource :+ " if(hmid < 0.0) {~n"
glslSource :+ "        tx = tmid;~n"
glslSource :+ "            hx = hmid;~n"
glslSource :+ "        } else {~n"
glslSource :+ "            tm = tmid;~n"
glslSource :+ "            hm = hmid;~n"
glslSource :+ "        }~n"
glslSource :+ "    }~n"
glslSource :+ "    return tmid;~n"
glslSource :+ "}~n"
glslSource :+ "~n"
glslSource :+ "// main~n"
glslSource :+ "void main() {~n"
glslSource :+ " vec2 uv = fragCoord.xy / iResolution.xy;~n"
glslSource :+ "    uv = uv * 2.0 - 1.0;~n"
glslSource :+ "    uv.x *= iResolution.x / iResolution.y;~n"
glslSource :+ "    float time = iTime * 0.3 + iMouse.x*0.01;~n"
glslSource :+ "~n"
glslSource :+ "    // ray~n"
glslSource :+ "    vec3 ang = vec3(sin(time*3.0)*0.1,sin(time)*0.2+0.3,time);~n"
glslSource :+ "    vec3 ori = vec3(0.0,3.5,time*5.0);~n"
glslSource :+ "    vec3 dir = normalize(vec3(uv.xy,-2.0)); dir.z += length(uv) * 0.15;~n"
glslSource :+ "    dir = normalize(dir) * fromEuler(ang);~n"
glslSource :+ "~n"
glslSource :+ "    // tracing~n"
glslSource :+ "    vec3 p;~n"
glslSource :+ "    heightMapTracing(ori,dir,p);~n"
glslSource :+ "    vec3 dist = p - ori;~n"
glslSource :+ "    vec3 n = getNormal(p, dot(dist,dist) * EPSILON_NRM);~n"
glslSource :+ "    vec3 light = normalize(vec3(0.0,1.0,0.8)); ~n"
glslSource :+ "~n"
glslSource :+ "    // color~n"
glslSource :+ "    vec3 color = mix(~n"
glslSource :+ "    getSkyColor(dir),~n"
glslSource :+ "    getSeaColor(p,n,light,dir,dist),~n"
glslSource :+ "    pow(smoothstep(0.0,-0.05,dir.y),0.3));~n"
glslSource :+ "~n"
glslSource :+ "    // post~n"
glslSource :+ " gl_FragColor = vec4(pow(color,vec3(0.75)), 1.0);~n"
glslSource :+ "}~n"
Return glslSource
EndFunction
If it's not annoying then it's not Microsoft.

https://github.com/davecamp

Offline LT

  • Jr. Member
  • **
  • Posts: 28
Re: One of the best shaders on ShaderToy.com
« Reply #1 on: August 23, 2018, 08:00:46 PM »
Afraid it doesn't work for me.  It gives me an error: Unhandled Exception:Invalid vertex shader ...on this line.

Code: [Select]
Local WaterShader:TShaderProgram = sf.CreateShaderProgram(DefaultVertexShader, WaterPixelShader)
Both DefaultVertexShader and WaterPixelShader are Null, for some reason.


Offline col

  • Sr. Member
  • ****
  • Posts: 422
Re: One of the best shaders on ShaderToy.com
« Reply #2 on: August 24, 2018, 07:09:26 AM »
Does it work when you visit the shadertoy website?

If so then the error may be caused if you have a hybrid GPU setup in your pc/laptop - such as an Intel/NVidia (integrated and high performance) arrangement - you should be able to set the preferred GPU in a control panel setting to the more powerful one. Max2D doesn't take multiple GPUs into account and will use the default one.
If it's not annoying then it's not Microsoft.

https://github.com/davecamp

Offline Naughty Alien

  • Hero Member
  • *****
  • Posts: 590
Re: One of the best shaders on ShaderToy.com
« Reply #3 on: August 24, 2018, 07:29:47 AM »
..show the pix mannn :)

Offline col

  • Sr. Member
  • ****
  • Posts: 422
Re: One of the best shaders on ShaderToy.com
« Reply #4 on: August 24, 2018, 09:16:07 AM »
Quote
..show the pix mannn :)

I tried to upload a .gif but it looks like a .png will have to do :)
If it's not annoying then it's not Microsoft.

https://github.com/davecamp

Offline Steve Elliott

  • Hero Member
  • *****
  • Posts: 1802
Re: One of the best shaders on ShaderToy.com
« Reply #5 on: August 24, 2018, 09:25:49 AM »
Quote
I tried to upload a .gif but it looks like a .png will have to do :)

How about an exe?  ;D
Windows 10, 64-bit, 16Gb RAM, CPU Intel i5, 3.2 GHz, Nvidia GeForce GTX 1050 (2Gb).
MacOS Mojave, 64-bit, 8Gb RAM, CPU Intel i5, 2.3 Ghz, Intel Iris Plus Graphics 640 1536 MB.
Linux Mint 19.1, 64-bit, 16Gb RAM, CPU Intel i5, 3.2 GHz, Nvidia GeForce GTX 1050 (2Gb).

Offline col

  • Sr. Member
  • ****
  • Posts: 422
Re: One of the best shaders on ShaderToy.com
« Reply #6 on: August 24, 2018, 09:43:05 AM »
Quote
How about an exe?  ;D
Done ;)
If it's not annoying then it's not Microsoft.

https://github.com/davecamp

Offline Steve Elliott

  • Hero Member
  • *****
  • Posts: 1802
Re: One of the best shaders on ShaderToy.com
« Reply #7 on: August 24, 2018, 09:50:40 AM »
Cheers col.  Yes it's very impressive - and whizzes along!
Windows 10, 64-bit, 16Gb RAM, CPU Intel i5, 3.2 GHz, Nvidia GeForce GTX 1050 (2Gb).
MacOS Mojave, 64-bit, 8Gb RAM, CPU Intel i5, 2.3 Ghz, Intel Iris Plus Graphics 640 1536 MB.
Linux Mint 19.1, 64-bit, 16Gb RAM, CPU Intel i5, 3.2 GHz, Nvidia GeForce GTX 1050 (2Gb).

Offline Naughty Alien

  • Hero Member
  • *****
  • Posts: 590
Re: One of the best shaders on ShaderToy.com
« Reply #8 on: August 24, 2018, 10:18:47 AM »
..very nice..so this is attached to some specific renderer or OGL/DX directly from BMX?

Offline Derron

  • Hero Member
  • *****
  • Posts: 2154
Re: One of the best shaders on ShaderToy.com
« Reply #9 on: August 24, 2018, 10:27:25 AM »
it is "basic" BlitzMax (openGL, DX9) and Col's module to ease the pain talking to the shader stuff. As said it is not DX11 ready for now.

Also I am afraid that it wont work with Brucey's sdl.mod yet (android/iOS/raspberry) - same to say for the render2texture module. Col is surely aware of it. But life has more interesting things here and there. So no excuse needed.

bye
Ron

Offline col

  • Sr. Member
  • ****
  • Posts: 422
Re: One of the best shaders on ShaderToy.com
« Reply #10 on: August 24, 2018, 11:16:09 AM »
As Derron says, I'm not doing anything special at all. I'm just setting up the shader stuff is about as far as credit goes for me. You could just as easily run this in MiniB3D, and any other renderer that supports shaders.

All credit rightly goes to the original shader author who clearly has some great math skills. Everything you see is being created in real-time in the pixel shader alone - amazing.
If it's not annoying then it's not Microsoft.

https://github.com/davecamp

Offline LT

  • Jr. Member
  • **
  • Posts: 28
Re: One of the best shaders on ShaderToy.com
« Reply #11 on: August 24, 2018, 03:40:05 PM »
Does it work when you visit the shadertoy website?

If so then the error may be caused if you have a hybrid GPU setup in your pc/laptop - such as an Intel/NVidia (integrated and high performance) arrangement - you should be able to set the preferred GPU in a control panel setting to the more powerful one. Max2D doesn't take multiple GPUs into account and will use the default one.

Yes, the website link worked.  I have a dedicated Nvidia graphics card.  Also, I couldn't run the .exe - Avast wouldn't let me.  :(

Offline LT

  • Jr. Member
  • **
  • Posts: 28
Re: One of the best shaders on ShaderToy.com
« Reply #12 on: August 24, 2018, 03:50:45 PM »
You could just as easily run this in MiniB3D, and any other renderer that supports shaders.
Made a cursory glance at the code and it appears to use geo shaders.  OpenGL version requirement?

Offline Steve Elliott

  • Hero Member
  • *****
  • Posts: 1802
Re: One of the best shaders on ShaderToy.com
« Reply #13 on: August 24, 2018, 03:55:00 PM »
My virus checker scanned it and passed it as safe.
Windows 10, 64-bit, 16Gb RAM, CPU Intel i5, 3.2 GHz, Nvidia GeForce GTX 1050 (2Gb).
MacOS Mojave, 64-bit, 8Gb RAM, CPU Intel i5, 2.3 Ghz, Intel Iris Plus Graphics 640 1536 MB.
Linux Mint 19.1, 64-bit, 16Gb RAM, CPU Intel i5, 3.2 GHz, Nvidia GeForce GTX 1050 (2Gb).

Offline LT

  • Jr. Member
  • **
  • Posts: 28
Re: One of the best shaders on ShaderToy.com
« Reply #14 on: August 24, 2018, 03:59:46 PM »
My virus checker scanned it and passed it as safe.
Avast won't let me run it and actually sent it automatically for interrogation.  It didn't even ask me!  :/