import '@kitware/vtk.js/favicon';
import '@kitware/vtk.js/Rendering/WebGPU/Profiles/Geometry';
import * as macro from '@kitware/vtk.js/macros'; import vtkActor from '@kitware/vtk.js/Rendering/Core/Actor'; import vtkConeSource from '@kitware/vtk.js/Filters/Sources/ConeSource'; import vtkFullScreenRenderWindow from '@kitware/vtk.js/Rendering/Misc/FullScreenRenderWindow'; import vtkMapper from '@kitware/vtk.js/Rendering/Core/Mapper'; import vtkWebGPUPolyDataMapper from '@kitware/vtk.js/Rendering/WebGPU/PolyDataMapper';
import controlPanel from './controller.html';
const newCustomMapper = macro.newInstance( (publicAPI, model, initialValues = {}) => { Object.assign(model, { wonkyness: 0.05 }, initialValues);
vtkMapper.extend(publicAPI, model, initialValues); macro.setGet(publicAPI, model, ['wonkyness']);
model.classHierarchy.push('vtkCustomMapper'); }, 'vtkCustomMapper' );
const newWebGPUCustomMapper = macro.newInstance( (publicAPI, model, initialValues = {}) => { Object.assign(model, {}, initialValues);
vtkWebGPUPolyDataMapper.extend(publicAPI, model, initialValues);
publicAPI.setFragmentShaderTemplate( model.fragmentShaderTemplate.replace( '//VTK::Normal::Impl', '//VTK::Normal::Impl\n\n//VTK::Wonkyness::Impl' ) );
model.UBO.addEntry('Wonkyness', 'f32');
model.classHierarchy.push('vtkWebGPUCustomMapper');
const superClass = { ...publicAPI };
publicAPI.updateUBO = () => { model.UBO.setValue('Wonkyness', model.renderable.getWonkyness()); superClass.updateUBO(); };
publicAPI.replaceShaderWonkyness = (hash, pipeline, vertexInput) => { const vDesc = pipeline.getShaderDescription('vertex'); if (vDesc.hasOutput('normalVC')) { const fDesc = pipeline.getShaderDescription('fragment'); let code = fDesc.getCode(); code = code.replace( '//VTK::Wonkyness::Impl', ` diffuseColor = (1.0 - mapperUBO.Wonkyness) * diffuseColor + vec4<f32>(mapperUBO.Wonkyness*input.normalVC, 1.0); ` ); fDesc.setCode(code); } }; publicAPI.setShaderReplacement( 'replaceShaderWonkyness', publicAPI.replaceShaderWonkyness ); }, 'vtkWebGPUCustomMapper' );
const fullScreenRenderer = vtkFullScreenRenderWindow.newInstance({ background: [0.2, 0.2, 0.3], }); const renderer = fullScreenRenderer.getRenderer(); const renderWindow = fullScreenRenderer.getRenderWindow();
const apiRW = fullScreenRenderer.getApiSpecificRenderWindow(); const vnfactory = apiRW.getViewNodeFactory(); if (vnfactory.getClassName().includes('WebGPU')) { vnfactory.registerOverride('vtkCustomMapper', newWebGPUCustomMapper); }
const coneSource = vtkConeSource.newInstance({ height: 1.0, resolution: 20 });
const mapper = newCustomMapper(); mapper.setInputConnection(coneSource.getOutputPort());
const actor = vtkActor.newInstance(); actor.setMapper(mapper);
renderer.addActor(actor); renderer.resetCamera(); renderWindow.render();
fullScreenRenderer.addController(controlPanel); const wonkynessChange = document.querySelector('.wonkyness'); const representationSelector = document.querySelector('.representations');
representationSelector.addEventListener('change', (e) => { const newRepValue = Number(e.target.value); actor.getProperty().setRepresentation(newRepValue); renderWindow.render(); });
wonkynessChange.addEventListener('input', (e) => { const resolution = Number(e.target.value); mapper.setWonkyness(resolution / 100.0); renderWindow.render(); });
global.source = coneSource; global.mapper = mapper; global.actor = actor; global.renderer = renderer; global.renderWindow = renderWindow;
|