UNPKG

@kitware/vtk.js

Version:

Visualization Toolkit for the Web

239 lines (194 loc) 8.01 kB
import { newInstance as newInstance$1, obj, get, setGet } from '../../macros.js'; import vtkWebGPUShaderCache from './ShaderCache.js'; var forwarded = ['setBindGroup', 'setIndexBuffer', 'setVertexBuffer', 'draw', 'drawIndexed']; // ---------------------------------------------------------------------------- // vtkWebGPURenderEncoder methods // ---------------------------------------------------------------------------- function vtkWebGPURenderEncoder(publicAPI, model) { // Set our className model.classHierarchy.push('vtkWebGPURenderEncoder'); publicAPI.begin = function (encoder) { model.drawCallbacks = []; model.handle = encoder.beginRenderPass(model.description); if (model.label) { model.handle.pushDebugGroup(model.label); } }; publicAPI.end = function () { // loop over registered pipelines and their callbacks for (var i = 0; i < model.drawCallbacks.length; i++) { var pStruct = model.drawCallbacks[i]; var pl = pStruct.pipeline; publicAPI.setPipeline(pl); for (var cb = 0; cb < pStruct.callbacks.length; cb++) { pStruct.callbacks[cb](publicAPI); } } if (model.label) { model.handle.popDebugGroup(); } model.handle.end(); model.boundPipeline = null; }; publicAPI.setPipeline = function (pl) { if (model.boundPipeline === pl) { return; } model.handle.setPipeline(pl.getHandle()); var pd = pl.getPipelineDescription(); // check attachment state if (model.colorTextureViews.length !== pd.fragment.targets.length) { console.log("mismatched attachment counts on pipeline ".concat(pd.fragment.targets.length, " while encoder has ").concat(model.colorTextureViews.length)); console.trace(); } else { for (var i = 0; i < model.colorTextureViews.length; i++) { var _model$colorTextureVi; var fmt = (_model$colorTextureVi = model.colorTextureViews[i].getTexture()) === null || _model$colorTextureVi === void 0 ? void 0 : _model$colorTextureVi.getFormat(); if (fmt && fmt !== pd.fragment.targets[i].format) { console.log("mismatched attachments for attachment ".concat(i, " on pipeline ").concat(pd.fragment.targets[i].format, " while encoder has ").concat(fmt)); console.trace(); } } } // check depth buffer if (!model.depthTextureView !== !('depthStencil' in pd)) { console.log('mismatched depth attachments'); console.trace(); } else if (model.depthTextureView) { var _model$depthTextureVi; var dfmt = (_model$depthTextureVi = model.depthTextureView.getTexture()) === null || _model$depthTextureVi === void 0 ? void 0 : _model$depthTextureVi.getFormat(); if (dfmt && dfmt !== pd.depthStencil.format) { console.log("mismatched depth attachments on pipeline ".concat(pd.depthStencil.format, " while encoder has ").concat(dfmt)); console.trace(); } } model.boundPipeline = pl; }; publicAPI.replaceShaderCode = function (pipeline) { model.replaceShaderCodeFunction(pipeline); }; publicAPI.setColorTextureView = function (idx, view) { if (model.colorTextureViews[idx] === view) { return; } model.colorTextureViews[idx] = view; }; publicAPI.activateBindGroup = function (bg) { var device = model.boundPipeline.getDevice(); var midx = model.boundPipeline.getBindGroupLayoutCount(bg.getLabel()); model.handle.setBindGroup(midx, bg.getBindGroup(device)); // verify bind group layout matches var bgl1 = device.getBindGroupLayoutDescription(bg.getBindGroupLayout(device)); var bgl2 = device.getBindGroupLayoutDescription(model.boundPipeline.getBindGroupLayout(midx)); if (bgl1 !== bgl2) { console.log("renderEncoder ".concat(model.pipelineHash, " mismatched bind group layouts bind group has\n").concat(bgl1, "\n versus pipeline\n").concat(bgl2, "\n")); console.trace(); } }; publicAPI.attachTextureViews = function () { // for each texture create a view if we do not already have one for (var i = 0; i < model.colorTextureViews.length; i++) { if (!model.description.colorAttachments[i]) { model.description.colorAttachments[i] = { view: model.colorTextureViews[i].getHandle() }; } else { model.description.colorAttachments[i].view = model.colorTextureViews[i].getHandle(); } } if (model.depthTextureView) { model.description.depthStencilAttachment.view = model.depthTextureView.getHandle(); } }; // register pipeline callbacks from a mapper publicAPI.registerDrawCallback = function (pipeline, cb) { // if there is a matching pipeline just add the cb for (var i = 0; i < model.drawCallbacks.length; i++) { if (model.drawCallbacks[i].pipeline === pipeline) { model.drawCallbacks[i].callbacks.push(cb); return; } } model.drawCallbacks.push({ pipeline: pipeline, callbacks: [cb] }); }; // simple forwarders var _loop = function _loop(i) { publicAPI[forwarded[i]] = function () { var _model$handle; return (_model$handle = model.handle)[forwarded[i]].apply(_model$handle, arguments); }; }; for (var i = 0; i < forwarded.length; i++) { _loop(i); } } // ---------------------------------------------------------------------------- // Object factory // ---------------------------------------------------------------------------- var DEFAULT_VALUES = { description: null, handle: null, boundPipeline: null, pipelineHash: null, pipelineSettings: null, replaceShaderCodeFunction: null, depthTextureView: null, label: null }; // ---------------------------------------------------------------------------- function extend(publicAPI, model) { var initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; Object.assign(model, DEFAULT_VALUES, initialValues); // Build VTK API obj(publicAPI, model); model.description = { colorAttachments: [{ view: undefined, loadOp: 'load', storeOp: 'store' }], depthStencilAttachment: { view: undefined, depthLoadOp: 'clear', depthClearValue: 0.0, depthStoreOp: 'store' } }; // default shader code just writes out the computedColor model.replaceShaderCodeFunction = function (pipeline) { var fDesc = pipeline.getShaderDescription('fragment'); fDesc.addOutput('vec4<f32>', 'outColor'); var code = fDesc.getCode(); code = vtkWebGPUShaderCache.substitute(code, '//VTK::RenderEncoder::Impl', ['output.outColor = computedColor;']).result; fDesc.setCode(code); }; // default pipeline settings model.pipelineSettings = { primitive: { cullMode: 'none' }, depthStencil: { depthWriteEnabled: true, depthCompare: 'greater-equal', format: 'depth32float' }, fragment: { targets: [{ format: 'rgba16float', blend: { color: { srcFactor: 'src-alpha', dstFactor: 'one-minus-src-alpha' }, alpha: { srcfactor: 'one', dstFactor: 'one-minus-src-alpha' } } }] } }; model.colorTextureViews = []; get(publicAPI, model, ['boundPipeline', 'colorTextureViews']); setGet(publicAPI, model, ['depthTextureView', 'description', 'handle', 'label', 'pipelineHash', 'pipelineSettings', 'replaceShaderCodeFunction']); // For more macro methods, see "Sources/macros.js" // Object specific methods vtkWebGPURenderEncoder(publicAPI, model); } // ---------------------------------------------------------------------------- var newInstance = newInstance$1(extend, 'vtkWebGPURenderEncoder'); // ---------------------------------------------------------------------------- var vtkWebGPURenderEncoder$1 = { newInstance: newInstance, extend: extend }; export { vtkWebGPURenderEncoder$1 as default, extend, newInstance };