diff --git a/examples/dithering_video_1/compute.js b/examples/dithering_video_1/compute.js new file mode 100644 index 00000000..c707f209 --- /dev/null +++ b/examples/dithering_video_1/compute.js @@ -0,0 +1,81 @@ +import { brightness } from 'color'; + +const compute = /*wgsl*/` + +struct Variable{ + init: i32 +} + +${brightness} + +const workgroupSize = 1; + +@compute @workgroup_size(workgroupSize,workgroupSize,1) +fn main( + @builtin(global_invocation_id) GlobalId: vec3, + @builtin(workgroup_id) WorkGroupID: vec3, + @builtin(local_invocation_id) LocalInvocationID: vec3 +) { + //-------------------------------------------------- + let dims = textureDimensions(image); + + var layerIndex = 0; + if(variables.init == 0){ + + let pointIndex = i32(GlobalId.y + (GlobalId.x * dims.x)); + + // var point = textureLoad(image, GlobalId.yx, 0); // image + var point = textureLoad(image, GlobalId.yx); // video + layers[0][pointIndex] = point; + layers[1][pointIndex] = point; + + // variables.init = 1; + }else{ + layerIndex = 1; + } + + //-------------------------------------------------- + + let pointIndex = i32(GlobalId.x + (GlobalId.y * dims.y)); + + var point = layers[layerIndex][pointIndex]; + let b = brightness(point); + var newBrightness = 0.; + if(b > .5){ + newBrightness = 1.; + } + + let quant_error = b - newBrightness; + let distance = 1; + let distanceU = u32(distance); + let distanceF = f32(distance); + point = vec4(newBrightness); + + let pointP = &layers[layerIndex][pointIndex]; + (*pointP) = point; + + + let pointIndexC = i32(GlobalId.x + ((GlobalId.y+distanceU) * dims.y)); + var rightPoint = layers[layerIndex][pointIndexC]; + rightPoint = vec4(brightness(rightPoint) + (.5 * quant_error * params.quantError * 10)); + + let pointPC = &layers[layerIndex][pointIndexC]; + (*pointPC) = rightPoint; + + + let pointIndexR = i32((GlobalId.y+distanceU) + (GlobalId.x * dims.x)); + var bottomPoint = layers[layerIndex][pointIndexR]; + bottomPoint = vec4(brightness(bottomPoint) + (.5 * quant_error)); + + let pointPR = &layers[layerIndex][pointIndexR]; + (*pointPR) = bottomPoint; + + point = layers[layerIndex][pointIndex]; + let positionU = GlobalId.xy; + textureStore(outputTex, positionU, point); + storageBarrier(); + // workgroupBarrier(); +} +`; + +export default compute; diff --git a/examples/dithering_video_1/frag.js b/examples/dithering_video_1/frag.js new file mode 100644 index 00000000..b6042947 --- /dev/null +++ b/examples/dithering_video_1/frag.js @@ -0,0 +1,32 @@ +import { snoise } from 'noise2d'; +import { texturePosition } from 'image'; +import { fnusin } from 'animation'; + +const frag = /*wgsl*/` +struct Variable{ + init: i32 +} + +${fnusin} +${snoise} +${texturePosition} + +@fragment +fn main( + @location(0) color: vec4, + @location(1) uv: vec2, + @location(2) ratio: vec2, + @location(3) uvRatio: vec2, + @location(4) mouse: vec2, + @builtin(position) position: vec4 + ) -> @location(0) vec4 { + + //let imageUV = (uv / f + vec2(0, .549 ) ) * vec2(1,-1 * dimsRatio) * ratio.y / params.sliderA; + //var point = textureSample(computeTexture, imageSampler, imageUV); //* .998046; + var point = texturePosition(computeTexture, imageSampler, vec2(0.), uv / params.scale, false); //* .998046; + + return point; +} +`; + +export default frag; diff --git a/examples/dithering_video_1/index.js b/examples/dithering_video_1/index.js new file mode 100644 index 00000000..8bd2d577 --- /dev/null +++ b/examples/dithering_video_1/index.js @@ -0,0 +1,46 @@ +import vert from './vert.js'; +import compute from './compute.js'; +import frag from './frag.js'; +import RenderPass from 'renderpass'; +import ShaderType from 'shadertype'; +import Points from 'points'; + +const options = { + scale: 1, + quantError: .15, +} + +const base = { + renderPasses: [ + new RenderPass(vert, frag, compute, 800, 800) + ], + /** + * + * @param {Points} points + * @param {*} folder + */ + init: async (points, folder) => { + let descriptor = { + addressModeU: 'repeat', + addressModeV: 'repeat', + } + points.addSampler('imageSampler', descriptor); + await points.addTextureVideo('image', './../../img/6982698-hd_1440_1080_25fps_800x800.mp4'); + points.addBindingTexture('outputTex', 'computeTexture'); + points.addLayers(2); + points.addStorage('variables', 'Variable', false, ShaderType.COMPUTE); + + points.addUniform('scale', options.scale); + points.addUniform('quantError', options.quantError); + + folder.add(options, 'scale', 0, 1, .0001).name('Scale'); + folder.add(options, 'quantError', -1, 1, .0001).name('quantError'); + folder.open(); + }, + update: points => { + points.updateUniform('scale', options.scale); + points.updateUniform('quantError', options.quantError); + } +} + +export default base; \ No newline at end of file diff --git a/examples/dithering_video_1/vert.js b/examples/dithering_video_1/vert.js new file mode 100644 index 00000000..d1fe1d1f --- /dev/null +++ b/examples/dithering_video_1/vert.js @@ -0,0 +1,19 @@ +const vert = /*wgsl*/` + +struct Variable{ + init: i32 +} + +@vertex +fn main( + @location(0) position: vec4, + @location(1) color: vec4, + @location(2) uv: vec2, + @builtin(vertex_index) vertexIndex: u32 +) -> Fragment { + + return defaultVertexBody(position, color, uv); +} +`; + +export default vert; diff --git a/examples/index.html b/examples/index.html index a9a9c85f..39136fd8 100644 --- a/examples/index.html +++ b/examples/index.html @@ -13,6 +13,10 @@ +

showcase

+
    +

    reference

    +
      diff --git a/examples/index_files/shader_projects.js b/examples/index_files/shader_projects.js new file mode 100644 index 00000000..4ab6f161 --- /dev/null +++ b/examples/index_files/shader_projects.js @@ -0,0 +1,40 @@ +export const shaderProjects = [ + { name: 'Base', path: './base/index.js', uri: 'base', desc: 'Empty project to start.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, enabled: true, tax: 'reference, showcase' }, + { name: 'Audio 1', path: './audio1/index.js', uri: 'audio1', desc: 'Audio visualization. Click to Start audio.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, enabled: true, tax: 'reference' }, + { name: 'Audio 2', path: './audio2/index.js', uri: 'audio2', desc: 'Audio visualization. Click to Start audio.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, enabled: true, tax: 'reference' }, + { name: 'Bloom1', path: './bloom1/index.js', uri: 'bloom1', desc: '', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, enabled: true, tax: 'reference' }, + { name: 'Feedback Sampling blur', path: './circleblur/index.js', uri: 'circleblur', desc: 'Previous frame rendered used to create effect.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, enabled: true, tax: 'reference' }, + { name: 'Data 1', path: './data1/index.js', uri: 'data1', desc: 'Compute Shader example.
      Open JavaScript console to check the output returned as Float32Array.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, enabled: true, tax: 'reference' }, + { name: 'Demo 6', path: './demo_6/index.js', uri: 'demo_6', desc: 'Display of the default vertex colors of the screen triangles.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, enabled: true, tax: 'reference' }, + { name: 'Ordered Dithering', path: './dithering1/index.js', uri: 'dithering1', desc: '', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, enabled: true, tax: 'showcase' }, + { name: 'Closest Color in a Palette', path: './dithering2/index.js', uri: 'dithering2', desc: '', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, enabled: true, tax: 'showcase' }, + { name: 'Dithering 3 - 1', path: './dithering3_1/index.js', uri: 'dithering3_1', desc: 'Failed dithering that displays workgroups.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: false, enabled: true, tax: 'showcase' }, + { name: 'Dithering 3 - 2', path: './dithering3_2/index.js', uri: 'dithering3_2', desc: 'Better dithering that affects the entire image at once.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: false, enabled: true, tax: 'showcase' }, + { name: 'Dithering 4', path: './dithering4/index.js', uri: 'dithering4', desc: '', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, enabled: true, tax: 'showcase' }, + { name: 'Dithering Video 1', path: './dithering_video_1/index.js', uri: 'dithering_video_1', desc: '', author: 'absulit', authlink: 'http://absulit.com', fitWindow: false, enabled: true, tax: 'showcase' }, + { name: 'Events 1', path: './events1/index.js', uri: 'events1', desc: 'WGSL fires an event and is read on the JavaScript side. Visible in console.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, enabled: true, tax: 'reference' }, + { name: 'Image Scale 1', path: './imagescale1/index.js', uri: 'imagescale1', desc: 'Layering of images', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, enabled: true, tax: 'reference' }, + { name: 'Image Texture 1', path: './imagetexture1/index.js', uri: 'imagetexture1', desc: 'How to load a texture.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, enabled: true, tax: 'reference' }, + { name: 'Image Texture 2', path: './imagetexture2/index.js', uri: 'imagetexture2', desc: 'Distort image colors.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, enabled: true, tax: 'reference' }, + { name: 'Image Texture 3', path: './imagetexture3/index.js', uri: 'imagetexture3', desc: 'Distort image UV.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, enabled: true, tax: 'reference' }, + { name: 'Image Texture 4', path: './imagetexture4/index.js', uri: 'imagetexture4', desc: 'Image descriptor properties `addressMode*` as `clamp-to-edge`', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, enabled: true, tax: 'reference' }, + { name: 'Layers 1', path: './layers1/index.js', uri: 'layers1', desc: 'Add layers via JavaScript.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, enabled: true, tax: 'reference' }, + { name: 'Mesh 1', path: './mesh1/index.js', uri: 'mesh1', desc: 'Change the amount of triangles of the base mesh.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, enabled: true, tax: 'reference' }, + { name: 'Mouse 1', path: './mouse1/index.js', uri: 'mouse1', desc: 'Mouse demo that draws a cross.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, enabled: true, tax: 'reference' }, + { name: 'Mouse Click and Scroll 1', path: './mouseclickscroll1/index.js', uri: 'mouseclickscroll1', desc: 'Mouse events demo. Click and the screen and scroll the mouse wheel.
      Events can be read from WGSL.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, enabled: true, tax: 'reference' }, + { name: 'Noise 1', path: './noise1/index.js', uri: 'noise1', desc: 'Noise layering.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, enabled: true, tax: 'reference' }, + { name: 'Sun Distortion', path: './noisecircle1/index.js', uri: 'noisecircle1', desc: 'Effect of the Sun distorting the atmosphere.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, enabled: true, tax: 'showcase' }, + { name: 'Points Title 1', path: './pointstitle1/index.js', uri: 'pointstitle1', desc: 'POINTS library `logo`.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, enabled: true, tax: 'showcase' }, + { name: 'Random 1', path: './random1/index.js', uri: 'random1', desc: 'Update uniforms with random numbers from JavaScript.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: false, enabled: true, tax: 'reference' }, + { name: 'Random 2 (⚠ SLOW)', path: './random2/index.js', uri: 'random2', desc: 'Update a Storage with random numbers from JavaScript.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: false, enabled: true, tax: 'reference' }, + { name: 'Random 3', path: './random3/index.js', uri: 'random3', desc: 'Update texture with random numbers from a Compute Shader.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: false, enabled: true, tax: 'reference' }, + { name: 'Render Passes 1', path: './renderpasses1/index.js', uri: 'renderpasses1', desc: 'Basic two render passes example with a blur.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, enabled: true, tax: 'reference' }, + { name: 'Render Passes 2', path: './renderpasses2/index.js', uri: 'renderpasses2', desc: '10 render passes example.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: false, enabled: true, tax: 'reference' }, + { name: 'Shapes 1', path: './shapes1/index.js', uri: 'shapes1', desc: 'Drawing shapes example.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, enabled: true, tax: 'reference' }, + { name: 'Shapes 2', path: './shapes2/index.js', uri: 'shapes2', desc: '', author: 'absulit', authlink: 'http://absulit.com', fitWindow: false, enabled: false, tax: 'reference' }, + { name: 'Spritesheet 1', path: './spritesheet1/index.js', uri: 'spritesheet1', desc: 'Move your mouse. Animated sprite sheets follows your movements.
      Penguin by tamashihoshi
      Fishing Bobbles by Nelson Yiap', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, enabled: true, tax: 'reference' }, + { name: 'UVs 1', path: './uvs1/index.js', uri: 'uvs1', desc: 'Move your mouse. Displays two uvs at the same time.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, enabled: true, tax: 'reference' }, + { name: 'Video Texture 1', path: './videotexture1/index.js', uri: 'videotexture1', desc: 'Loads a video as a texture to read in WGSL and displays it.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, enabled: true, tax: 'reference' }, + // { name: 'PARAMS TEST', path: './params_test/index.js', uri:'params_test', desc:'', author: 'absulit', authlink:'http://absulit.com', fitWindow: true, enabled: true, tax: 'reference' }, + // { name: 'WebGPU Particles 1', path: './webgpu_particles_1/index.js', uri:'webgpu_particles_1', desc:'', author: 'absulit', authlink:'http://absulit.com', fitWindow: true, enabled: true, tax: 'reference' }, +] \ No newline at end of file diff --git a/examples/main.js b/examples/main.js index 9755356c..ec2abe2f 100644 --- a/examples/main.js +++ b/examples/main.js @@ -2,6 +2,7 @@ import * as dat from 'datgui'; import Points from 'points'; import RenderPass from 'renderpass'; +import { shaderProjects } from './index_files/shader_projects.js'; /** * Gets all the uri parts in an array. @@ -56,67 +57,40 @@ gui.add(isFitWindowData, 'isFitWindow').name('Fit Window').listen().onChange(val points.fitWindow = value; }); -const shaderProjects = [ - { name: 'Base', path: './base/index.js', uri: 'base', desc: 'Empty project to start.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, }, - { name: 'Audio 1', path: './audio1/index.js', uri: 'audio1', desc: 'Audio visualization. Click to Start audio.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, }, - { name: 'Audio 2', path: './audio2/index.js', uri: 'audio2', desc: 'Audio visualization. Click to Start audio.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, }, - { name: 'Bloom1', path: './bloom1/index.js', uri: 'bloom1', desc: '', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, }, - { name: 'Feedback Sampling blur.', path: './circleblur/index.js', uri: 'circleblur', desc: 'Previous frame rendered used to create effect.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, }, - { name: 'Data 1', path: './data1/index.js', uri: 'data1', desc: 'Compute Shader example.
      Open JavaScript console to check the output returned as Float32Array.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, }, - { name: 'Demo 6', path: './demo_6/index.js', uri: 'demo_6', desc: 'Display of the default vertex colors of the screen triangles.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, }, - { name: 'Ordered Dithering', path: './dithering1/index.js', uri: 'dithering1', desc: '', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, }, - { name: 'Closest Color in a Palette', path: './dithering2/index.js', uri: 'dithering2', desc: '', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, }, - { name: 'Dithering 3 - 1', path: './dithering3_1/index.js', uri: 'dithering3_1', desc: 'Failed dithering that displays workgroups.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: false, }, - { name: 'Dithering 3 - 2', path: './dithering3_2/index.js', uri: 'dithering3_2', desc: 'Better dithering that affects the entire image at once.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: false, }, - { name: 'Dithering 4', path: './dithering4/index.js', uri: 'dithering4', desc: '', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, }, - { name: 'Events 1', path: './events1/index.js', uri: 'events1', desc: 'WGSL fires an event and is read on the JavaScript side. Visible in console.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, }, - { name: 'Image Scale 1', path: './imagescale1/index.js', uri: 'imagescale1', desc: 'Layering of images', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, }, - { name: 'Image Texture 1', path: './imagetexture1/index.js', uri: 'imagetexture1', desc: 'How to load a texture.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, }, - { name: 'Image Texture 2', path: './imagetexture2/index.js', uri: 'imagetexture2', desc: 'Distort image colors.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, }, - { name: 'Image Texture 3', path: './imagetexture3/index.js', uri: 'imagetexture3', desc: 'Distort image UV.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, }, - { name: 'Image Texture 4', path: './imagetexture4/index.js', uri: 'imagetexture4', desc: 'Image descriptor properties `addressMode*` as `clamp-to-edge`', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, }, - { name: 'Layers 1', path: './layers1/index.js', uri: 'layers1', desc: 'Add layers via JavaScript.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, }, - { name: 'Mesh 1', path: './mesh1/index.js', uri: 'mesh1', desc: 'Change the amount of triangles of the base mesh.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, }, - { name: 'Mouse 1', path: './mouse1/index.js', uri: 'mouse1', desc: 'Mouse demo that draws a cross.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, }, - { name: 'Mouse Click and Scroll 1', path: './mouseclickscroll1/index.js', uri: 'mouseclickscroll1', desc: 'Mouse events demo. Click and the screen and scroll the mouse wheel.
      Events can be read from WGSL.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, }, - { name: 'Noise 1', path: './noise1/index.js', uri: 'noise1', desc: 'Noise layering.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, }, - { name: 'Sun Distortion', path: './noisecircle1/index.js', uri: 'noisecircle1', desc: 'Effect of the Sun distorting the atmosphere.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, }, - { name: 'Points Title 1', path: './pointstitle1/index.js', uri: 'pointstitle1', desc: 'POINTS library `logo`.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, }, - { name: 'Random 1', path: './random1/index.js', uri: 'random1', desc: 'Update uniforms with random numbers from JavaScript.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: false, }, - { name: 'Random 2 (⚠ SLOW)', path: './random2/index.js', uri: 'random2', desc: 'Update a Storage with random numbers from JavaScript.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: false, }, - { name: 'Random 3', path: './random3/index.js', uri: 'random3', desc: 'Update texture with random numbers from a Compute Shader.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: false, }, - { name: 'Render Passes 1', path: './renderpasses1/index.js', uri: 'renderpasses1', desc: 'Basic two render passes example with a blur.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, }, - { name: 'Render Passes 2', path: './renderpasses2/index.js', uri: 'renderpasses2', desc: '10 render passes example.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: false, }, - { name: 'Shapes 1', path: './shapes1/index.js', uri: 'shapes1', desc: 'Drawing shapes example.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, }, - { name: 'Shapes 2', path: './shapes2/index.js', uri: 'shapes2', desc: '', author: 'absulit', authlink: 'http://absulit.com', fitWindow: false, }, - { name: 'Spritesheet 1', path: './spritesheet1/index.js', uri: 'spritesheet1', desc: 'Move your mouse. Animated sprite sheets follows your movements.
      Penguin by tamashihoshi
      Fishing Bobbles by Nelson Yiap', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, }, - { name: 'UVs 1', path: './uvs1/index.js', uri: 'uvs1', desc: 'Move your mouse. Displays two uvs at the same time.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, }, - { name: 'Video Texture 1', path: './videotexture1/index.js', uri: 'videotexture1', desc: 'Loads a video as a texture to read in WGSL and displays it.', author: 'absulit', authlink: 'http://absulit.com', fitWindow: true, }, - // { name: 'PARAMS TEST', path: './params_test/index.js', uri:'params_test', desc:'', author: 'absulit', authlink:'http://absulit.com', fitWindow: true, }, - // { name: 'WebGPU Particles 1', path: './webgpu_particles_1/index.js', uri:'webgpu_particles_1', desc:'', author: 'absulit', authlink:'http://absulit.com', fitWindow: true, }, -] - const shaderNames = {}; const nav = document.getElementById('nav'); const ul = nav.children[0]; +const showcaseUl = nav.querySelector('.showcase'); +const referenceUl = nav.querySelector('.reference'); let lastSelected = null; -shaderProjects.forEach((item, index) => { - shaderNames[item.name] = index; - const li = document.createElement('li'); - const a = document.createElement('a'); - a.href = `#${item.uri}`; - a.innerHTML = item.name; - a.index = index; - a.addEventListener('click', e => { - lastSelected?.classList.remove('selected'); - e.target.classList.add('selected'); - lastSelected = e.target; - loadShaderByIndex(e.target.index) +shaderProjects + // .filter(item => item.enabled) + // .filter(item => item.tax == 'showcase') + .forEach((item, index) => { + if(!item.enabled){ + return; + } + shaderNames[item.name] = index; + const li = document.createElement('li'); + const a = document.createElement('a'); + a.href = `#${item.uri}`; + a.innerHTML = item.name; + a.index = index; + a.addEventListener('click', e => { + lastSelected?.classList.remove('selected'); + e.target.classList.add('selected'); + lastSelected = e.target; + loadShaderByIndex(e.target.index) + }); + li.appendChild(a); + if (item.tax === 'showcase') { + showcaseUl.appendChild(li); + } + if (item.tax === 'reference') { + referenceUl.appendChild(li); + } }); - li.appendChild(a); - ul.appendChild(li); -}); let selectedShader = { index: Number(localStorage.getItem('selected-shader')) || 0 } @@ -148,10 +122,10 @@ async function loadShaderByIndex(index) { async function loadShaderByURI() { const parts = uriParts(); let index = shaderProjects.findIndex(s => s.uri == parts[1]); - + if (index == -1) { index = selectedShader.index; - }else{ + } else { selectedShader.index = index; } diff --git a/examples/style.css b/examples/style.css index 9797559c..c3e480f2 100644 --- a/examples/style.css +++ b/examples/style.css @@ -11,17 +11,18 @@ body { } #info { - position : absolute; - top : 0px; - width : 80%; - padding : 10px; - box-sizing : border-box; - text-align : center; - user-select : none; - z-index : 1; - color : white; - filter: drop-shadow(1px 1px 1px #0a2627); + position : absolute; + top : 0px; + width : 80%; + padding : 10px; + box-sizing : border-box; + text-align : center; + user-select: none; + z-index : 1; + color : white; + filter : drop-shadow(1px 1px 1px #0a2627); } + #info a { color: #488553; } @@ -77,7 +78,7 @@ a:hover { } ul { - list-style-type: none; + list-style-type : none; padding-inline-start: 18px; } @@ -94,12 +95,19 @@ li a.selected { color: red; } -li.menu-main{ +li.menu-main { margin-bottom: 10px; } li.menu-main a { - color: #00ffc6; - font-size: large; + color : #00ff51; + font-size : large; font-weight: 600; +} + +h2 { + color : #00ffc6; + font-size : large; + font-weight : 600; + padding-inline-start: 18px; } \ No newline at end of file diff --git a/img/6982698-hd_1440_1080_25fps_800x800.mp4 b/img/6982698-hd_1440_1080_25fps_800x800.mp4 new file mode 100644 index 00000000..045652fa Binary files /dev/null and b/img/6982698-hd_1440_1080_25fps_800x800.mp4 differ