diff --git a/src/client/main.ts b/src/client/main.ts index af44a39..a4f00f1 100644 --- a/src/client/main.ts +++ b/src/client/main.ts @@ -1,5 +1,5 @@ import vsSource from './shaders/shader.vert'; -import fsSource4 from './shaders/texture.frag'; +import texture from './shaders/texture.frag'; import {fetchObj, updateObj} from './objutils'; import {initShaderProgram} from './shaders'; @@ -31,7 +31,7 @@ async function main() { vertexShader: null, }; const canvas: any = document.querySelector('#glCanvas')!; - context.gl = canvas.getContext('webgl'); + context.gl = canvas.getContext('webgl2'); if (context.gl == null) { canvas.parentNode.removeChild(canvas); @@ -43,7 +43,7 @@ async function main() { const data = await fetchObj('/static/objs/racer.obj'); initParams(context); updateObj(context, data, true); - initShaderProgram(context, vsSource, fsSource4); + initShaderProgram(context, vsSource, texture); setProgramInfo(context); context.texture = loadTexture(context.gl, '/static/textures/racer.png'); let then = 0; diff --git a/src/client/shaders/fractal.frag b/src/client/shaders/fractal.frag new file mode 100644 index 0000000..c27e5be --- /dev/null +++ b/src/client/shaders/fractal.frag @@ -0,0 +1,95 @@ +precision highp float; + +varying highp vec2 vTextureCoord; +varying highp vec4 vNormal; +varying highp vec3 vPosition; +uniform sampler2D uSampler; + +vec2 cinv(in vec2 z) +{ + return (vec2(z.x, -z.y) / dot(z, z)); +} + +vec2 cmul(in vec2 z1, in vec2 z2) +{ + return(vec2(z1.x * z2.x - z1.y * z2.y, z1.x * z2.y + z1.y * z2.x)); +} + +vec2 cdiv(in vec2 z1, in vec2 z2) +{ + return (cmul(z1, cinv(z2))); +} + +vec3 extremize(vec3 v, float n) { + if (v.x > n / 2.) + v.x = n; + else + v.x = 0.; + if (v.y > n / 2.) + v.y = n; + else + v.y = 0.; + if (v.z > n / 2.) + v.z = n; + else + v.z = 0.; + return v; +} + +void main() { + vec2 a0 = vec2(sin(16.) * 1.0 + 5., 0.); + vec2 a1 = vec2(sin(17.) * 2.0, 0.); + vec2 a2 = vec2(sin(18.) * 3.0, 0.); + vec2 a3 = vec2(sin(19.) * 4.0, 0.); + vec2 a4 = vec2(sin(1.1) * 5.0, 0.); + vec2 a5 = vec2(sin(1.2) * 6.0, 0.); + vec2 a6 = vec2(sin(1.3) * 7.0, 0.); + vec2 a7 = vec2(sin(1.4) * 8.0, 0.); + vec2 a8 = vec2(sin(15.) * 9.0, 0.); + vec2 a9 = vec2(sin(16.) * 10.0, 0.); + vec2 a10 = vec2(sin(17.) * 11.0, 1.); + + vec2 a = vec2(1.0, 1. + sin(0.16) * 0.002); + vec2 c = vec2(0.01, 0.1); + // Normalized pixel coordinates (from 0 to 1) + vec2 z = cmul((vTextureCoord/vec2(1., 1.) - 0.5), vec2(4., 0.)); + vec2 init_z = z; + z.x = abs(z.x); + z.y = abs(z.y); + vec2 old_z = z; + float i_backup; + for (float i = 0.0; i < 16.0; i += 1.) + { + z = z - cmul(a, cdiv(a0 + cmul(z, a1 + cmul(z, a2 + cmul(z, a3 + cmul(z, a4 + cmul(z, a5 + + cmul(z, a6 + cmul(z, a7 + cmul(z, a8 + cmul(z, a9 + cmul(a10, z)))))))))), + a1 + cmul(z, cmul(a2, vec2(2., 0.)) + cmul(z, cmul(a3, vec2(3., 0.)) + + cmul(z, cmul(a4, vec2(4., 0.)) + cmul(z, cmul(a5, vec2(5., 0.)) + + cmul(z, cmul(a6, vec2(6., 0.)) + cmul(z, cmul(a7, vec2(7., 0.)) + + cmul(z, cmul(a8, vec2(8., 0.)) + cmul(z, cmul(a9, vec2(9., 0.)) + + cmul(cmul(a10, vec2(10., 0.)), z))))))))))) + c; + + if (old_z.x * old_z.x + old_z.y * old_z.y < z.x * z.x + z.y * z.y + 0.001 + && old_z.x * old_z.x + old_z.y * old_z.y > z.x * z.x + z.y * z.y - 0.001) + { + i_backup = i / 16.0; + break; + } + old_z = z; + } + vec3 n = normalize(vec3(-50., 100., 50.) - vPosition); + float diffuse = max(dot(normalize(vNormal.xyz), n), 0.); + float specular = pow( + max(dot( + reflect(n, normalize(vNormal.xyz)), + normalize(vec3(0., 0., -50.) - vPosition)), + 0.), 10.); + gl_FragColor = vec4(vec3(z.x, z.y, i_backup) * diffuse * 0.8 + vec3(z.x, z.y, i_backup) * 0.2 + vec3(specular), 1.0); +} + +// void main() { +// vec3 n = normalize(vec3(-200., 200., -200.) - vPosition); +// float diffuse = max(dot(normalize(vNormal.xyz), n), 0.); +// vec3 tmp = extremize(mod(vPosition.xyz + vec3(1000.), vec3(100.)), 100.); +// float texture = (tmp.x + tmp.y + tmp.z) / 300.; +// gl_FragColor = vec4(vec3(texture * diffuse), 1.0); +// } \ No newline at end of file diff --git a/src/client/uijquery.ts b/src/client/uijquery.ts index 6529d6d..c308845 100644 --- a/src/client/uijquery.ts +++ b/src/client/uijquery.ts @@ -4,11 +4,12 @@ import {fetchObj, updateObj} from './objutils'; import {changeFragmentShader} from './shaders'; import vsSource from './shaders/shader.vert'; -import fsSource from './shaders/blackandwhite.frag'; -import fsSource2 from './shaders/colored.frag'; -import fsSource3 from './shaders/grey.frag'; -import fsSource4 from './shaders/texture.frag'; -import fsSource5 from './shaders/sobel.frag'; +import blackandwhite from './shaders/blackandwhite.frag'; +import colored from './shaders/colored.frag'; +import grey from './shaders/grey.frag'; +import texture from './shaders/texture.frag'; +import sobel from './shaders/sobel.frag'; +import fractal from './shaders/fractal.frag'; /** * UI block for updating parameters @@ -110,18 +111,21 @@ export function uiUpdateObject(context: any) { */ export function uiUpdateShader(context: any) { $('#s_blackandwhite').on('click', function() { - changeFragmentShader(context, fsSource, vsSource); + changeFragmentShader(context, blackandwhite, vsSource); }); $('#s_color').on('click', function() { - changeFragmentShader(context, fsSource2, vsSource); + changeFragmentShader(context, colored, vsSource); }); $('#s_grey').on('click', function() { - changeFragmentShader(context, fsSource3, vsSource); + changeFragmentShader(context, grey, vsSource); }); $('#s_texture').on('click', function() { - changeFragmentShader(context, fsSource4, vsSource); + changeFragmentShader(context, texture, vsSource); }); $('#s_sobel').on('click', function() { - changeFragmentShader(context, fsSource5, vsSource); + changeFragmentShader(context, sobel, vsSource); + }); + $('#s_fractal').on('click', function() { + changeFragmentShader(context, fractal, vsSource); }); } diff --git a/views/index.ejs b/views/index.ejs index 02a9ee8..bcfe8d7 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -25,6 +25,7 @@ +
Change distance: