threepipe
Version:
A modern 3D viewer framework built on top of three.js, written in TypeScript, designed to make creating high-quality, modular, and extensible 3D experiences on the web simple and enjoyable.
90 lines • 4.41 kB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { Color } from 'three';
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js';
import { uiFolderContainer, uiToggle } from 'uiconfig.js';
import { getOrCall } from 'ts-browser-helpers';
let GBufferRenderPass = class GBufferRenderPass extends RenderPass {
constructor(passId, target, material, clearColor = new Color(1, 1, 1), clearAlpha = 1) {
super(undefined, undefined, material, clearColor, clearAlpha);
this.passId = passId;
this.target = target;
this.isGBufferRenderPass = true;
this.enabled = true;
this._transparentMats = new Set();
this._transmissiveMats = new Set();
// todo make a global parameter in the viewer to be able to render all transparent and transmissive materials to gbuffer by default
this.preprocessMaterial = (material, renderToGBuffer) => {
renderToGBuffer = renderToGBuffer ?? material.userData.renderToGBuffer;
if (material.userData.pluginsDisabled)
renderToGBuffer = false;
if (material.transparent && (renderToGBuffer || material.opacity > 0.99 && !material.map && !material.alphaMap) || // transparent and render to gbuffer
!material.transparent && !material.transmission && renderToGBuffer === false // opaque and dont render to gbuffer
) {
this._transparentMats.add(material);
material.transparent = !material.transparent;
// material.needsUpdate = true
}
if (material.transmission &&
Math.abs(material.transmission || 0) > 0 && renderToGBuffer // transmission and render to gbuffer
) {
this._transmissiveMats.add([material, material.transmission]);
material.transmission = 0;
// material.needsUpdate = true
}
};
}
/**
* Renders to {@link target}
* @param renderer
* @param _ - this is ignored
* @param _1 - this is ignored
* @param deltaTime
* @param maskActive
*/
render(renderer, _, _1, deltaTime, maskActive) {
if (!this.scene || !this.camera)
return;
const t = renderer.getRenderTarget();
const activeCubeFace = renderer.getActiveCubeFace();
const activeMipLevel = renderer.getActiveMipmapLevel();
this.scene.traverse(({ material }) => {
if (!material)
return;
if (Array.isArray(material))
material.forEach((m) => this.preprocessMaterial(m));
else
this.preprocessMaterial(material);
});
// todo; copy double sided, check with post processing
renderer.renderWithModes({
shadowMapRender: false,
backgroundRender: false,
opaqueRender: true,
transparentRender: false,
transmissionRender: false,
mainRenderPass: false,
}, () => super.render(renderer, null, getOrCall(this.target), deltaTime, maskActive)); // here this.target is the write-buffer, variable writeBuffer is ignored
this._transparentMats.forEach(m => m.transparent = !m.transparent);
this._transparentMats.clear();
this._transmissiveMats.forEach(([m, tr]) => m.transmission = tr);
this._transmissiveMats.clear();
renderer.setRenderTarget(t, activeCubeFace, activeMipLevel);
}
beforeRender(scene, camera, _) {
this.scene = scene;
this.camera = camera;
}
};
__decorate([
uiToggle('Enabled')
], GBufferRenderPass.prototype, "enabled", void 0);
GBufferRenderPass = __decorate([
uiFolderContainer((c) => c.passId + ' Render Pass')
], GBufferRenderPass);
export { GBufferRenderPass };
//# sourceMappingURL=GBufferRenderPass.js.map