### Install Postprocessing Library Source: https://github.com/pmndrs/postprocessing/blob/main/README.md Install the postprocessing library and its peer dependency, three.js, using npm. ```sh npm install three postprocessing ``` -------------------------------- ### Basic Application Entry Point Source: https://github.com/pmndrs/postprocessing/blob/main/manual/content/getting-started.en.md A minimal TypeScript example to import and log the RenderPipeline from the postprocessing library. ```ts import { RenderPipeline } from "postprocessing"; console.log(RenderPipeline); ``` -------------------------------- ### Start Rendering Loop Source: https://github.com/pmndrs/postprocessing/blob/main/manual/content/getting-started.en.md Set up the animation frame request to continuously render the scene using the postprocessing pipeline. ```ts requestAnimationFrame(function render(timestamp: number): void { requestAnimationFrame(render); pipeline.render(timestamp); }); ``` -------------------------------- ### Project Build Configuration with esbuild Source: https://github.com/pmndrs/postprocessing/blob/main/manual/content/getting-started.en.md Example package.json script for bundling your application with esbuild, including dependencies for postprocessing and three.js. ```json { "scripts": { "build": "esbuild src/app.js --bundle --minify --outfile=dist/app.js" }, "dependencies": { "postprocessing": "x.x.x", "three": "x.x.x" }, "devDependencies": { "esbuild": "x.x.x" } } ``` -------------------------------- ### Example App JavaScript Source: https://github.com/pmndrs/postprocessing/wiki/Build-Setup A basic JavaScript file that imports and logs the EffectComposer from the postprocessing library. This serves as the entry point for bundling. ```js import { EffectComposer } from "postprocessing"; console.log(EffectComposer); ``` -------------------------------- ### Initialize RenderPipeline and Add Passes Source: https://github.com/pmndrs/postprocessing/blob/main/manual/content/getting-started.en.md Set up a render pipeline with ClearPass, GeometryPass, and EffectPass for postprocessing effects. Includes scene, camera, and renderer setup. ```ts import { BloomEffect, ClearPass, EffectPass, GeometryPass, RenderPipeline } from "postprocessing"; const container = document.querySelector(".viewport"); container.prepend(renderer.domElement); const scene = new Scene(); const camera = new PerspectiveCamera(); const pipeline = new RenderPipeline(renderer); pipeline.addPass(new ClearPass()); pipeline.addPass(new GeometryPass(scene, camera, { samples: 4 })); pipeline.addPass(new EffectPass(new BloomEffect())); ``` -------------------------------- ### Required Dependencies for Bundling Source: https://github.com/pmndrs/postprocessing/wiki/Build-Setup These are the dependencies needed to bundle the postprocessing library with esbuild. Ensure 'postprocessing' and 'three' are installed, along with 'esbuild' for development. ```json "dependencies": { "postprocessing": "x.x.x", "three": "x.x.x" }, "devDependencies": { "esbuild": "x.x.x" } ``` -------------------------------- ### Required Dependencies for Transpilation Source: https://github.com/pmndrs/postprocessing/wiki/Build-Setup Dependencies required for transpiling code using Babel. Install '@babel/core' and '@babel/preset-env' for ES5 compatibility. ```json "devDependencies": { "@babel/core": "x.x.x", "@babel/preset-env": "x.x.x" } ``` -------------------------------- ### Basic Post Processing Setup with EffectComposer Source: https://github.com/pmndrs/postprocessing/blob/main/README.md Set up an EffectComposer with a RenderPass and a BloomEffect. The composer manages passes, and the RenderPass clears buffers and renders the scene before effects are applied. ```js import { BloomEffect, EffectComposer, EffectPass, RenderPass } from "postprocessing"; const composer = new EffectComposer(renderer); composer.addPass(new RenderPass(scene, camera)); composer.addPass(new EffectPass(camera, new BloomEffect())); requestAnimationFrame(function render() { requestAnimationFrame(render); composer.render(); }); ``` -------------------------------- ### Merging Convolution Operators Example Source: https://github.com/pmndrs/postprocessing/wiki/Effect-Merging Demonstrates the incorrect and correct ways to apply multiple convolution operations. The incorrect method applies blur sequentially on the same buffer, while the correct method uses an intermediate buffer to store results. ```javascript // A 1-dimensional texture with one color channel. const inputBuffer = [60, 0, 255, 127]; // A simple convolution algorithm. function blur(inputColor, i, inputBuffer) { // Offset and clamp to edge. const j = Math.max(i - 1, 0); const k = Math.min(i + 1, inputBuffer.length - 1); // Calculate the average. return (inputColor + inputBuffer[j] + inputBuffer[k]) / 3; } // Single pass (wrong way). const outputColor = blur(inputBuffer[1], 1, inputBuffer); // => 105 console.log("incorrect:", blur(outputColor, 1, inputBuffer)); // => 140 // Two passes (right way). const outputBuffer = [0, 0, 0, 0]; outputBuffer[0] = blur(inputBuffer[0], 0, inputBuffer); // => 40 outputBuffer[1] = blur(inputBuffer[1], 1, inputBuffer); // => 105 outputBuffer[2] = blur(inputBuffer[2], 2, inputBuffer); // => 127.33 outputBuffer[3] = blur(inputBuffer[3], 3, inputBuffer); // => 169.66 console.log("correct:", blur(outputBuffer[1], 1, outputBuffer)); // => 90.77 ``` -------------------------------- ### Custom Effect with WebGL Extensions Source: https://github.com/pmndrs/postprocessing/blob/main/manual/content/custom-effects.en.md Example of a custom effect that enables specific WebGL extensions, such as DERIVATIVES, using the constructor options. ```javascript class MyEffect extends Effect { constructor() { super(name, fragmentShader, { extensions: new Set([WebGLExtension.DERIVATIVES]) }); } } ``` -------------------------------- ### Applying Effect Attributes Source: https://github.com/pmndrs/postprocessing/wiki/Custom-Effects Example of how to specify EffectAttributes for a custom effect using bitwise OR. Attributes like CONVOLUTION and DEPTH inform the EffectPass about special requirements. ```javascript class MyEffect extends Effect { constructor() { super(name, fragmentShader, { attributes: EffectAttribute.CONVOLUTION | EffectAttribute.DEPTH }); } } ``` -------------------------------- ### Custom Effect with Fragment Shader Source: https://github.com/pmndrs/postprocessing/wiki/Custom-Effects Example of a custom effect that uses a GLSL fragment shader to modify colors based on weights. This effect requires a shader file and a JavaScript class extending the Effect base class. ```glsl uniform vec3 weights; void mainImage(const in vec4 inputColor, const in vec2 uv, out vec4 outputColor) { outputColor = vec4(inputColor.rgb * weights, inputColor.a); } ``` ```javascript import { Uniform, Vector3 } from "three"; import { BlendFunction, Effect } from "postprocessing"; // Using rollup-plugin-glsl to import shader files. import fragmentShader from "./shader.frag"; export class CustomEffect extends Effect { constructor() { super("CustomEffect", fragmentShader, { blendFunction: BlendFunction.Normal, uniforms: new Map([ ["weights", new Uniform(new Vector3())] ]) }); } } ``` -------------------------------- ### Define Scripts Template Source: https://github.com/pmndrs/postprocessing/blob/main/manual/layouts/_default/single.html Defines a Hugo template block for including scripts. It conditionally gets and fingerprints a JavaScript resource based on page parameters. ```gohtml {{ define "scripts" }} {{ with .Params.script }} {{ with resources.Get (printf "js/dist/demos/%s.js" .) }} {{ $script := . | fingerprint }} {{ end }} {{ end }} {{ end }} ``` -------------------------------- ### Enable Override Material Workaround Source: https://github.com/pmndrs/postprocessing/wiki/Override-Materials Globally enables the override material workaround for all passes and effects. It is recommended to enable this before the render loop starts. This workaround fixes override materials for passes and materials that use them and is disabled by default due to potential performance impacts. ```javascript import { OverrideMaterialManager } from "postprocessing"; OverrideMaterialManager.workaroundEnabled = true; ``` -------------------------------- ### Handle Window Resize for Pipeline Source: https://github.com/pmndrs/postprocessing/blob/main/manual/content/getting-started.en.md Implement a resize handler to update the camera and pipeline dimensions when the browser window is resized. ```ts function onResize(): void { const width = container.clientWidth, height = container.clientHeight; camera.aspect = width / height; camera.updateProjectionMatrix(); pipeline.setSize(width, height); } window.addEventListener("resize", onResize); onResize(); ``` -------------------------------- ### esbuild Build Script Source: https://github.com/pmndrs/postprocessing/wiki/Build-Setup This script uses esbuild to bundle the application's JavaScript file. It creates a minified output file in the dist directory. ```json "scripts": { "build": "esbuild src/app.js --bundle --minify --outfile=dist/app.js" } ``` -------------------------------- ### Babel Configuration Source: https://github.com/pmndrs/postprocessing/wiki/Build-Setup A basic Babel configuration file to disable compact mode and comments, and to use the @babel/preset-env preset for transpilation. ```json { "compact": false, "comments": false, "presets": ["@babel/preset-env"] } ``` -------------------------------- ### Tangent Computation Notes Source: https://github.com/pmndrs/postprocessing/blob/main/demo/static/models/sponza/README.md Notes on how tangents were computed for the Sponza model using MikkTSpace and the implications for handling tangent W. ```text Tangents have been computed using MikkTSpace, as the original OBJ model did not have them. I have manually inspected the normals, and it looks correct to me. Be aware that W is -1.0 for most of the tangent signs, you will need to handle tangent W for correct results. ``` -------------------------------- ### Implement a Custom Rendering Pass Source: https://github.com/pmndrs/postprocessing/wiki/Custom-Passes This snippet demonstrates how to create a custom Pass in the postprocessing library. It utilizes a CustomMaterial and overrides the render method to apply the custom shader. ```javascript import { Pass } from "postprocessing"; import { CustomMaterial } from "./CustomMaterial.js"; export class CustomPass extends Pass { constructor() { super("CustomPass"); this.setFullscreenMaterial(new CustomMaterial()); } render(renderer, inputBuffer, outputBuffer, deltaTime, stencilTest) { const material = this.getFullscreenMaterial(); material.uniforms.inputBuffer.value = inputBuffer.texture; renderer.setRenderTarget(this.renderToScreen ? null : outputBuffer); renderer.render(this.scene, this.camera); } } ``` -------------------------------- ### Render Navigation Partial Source: https://github.com/pmndrs/postprocessing/blob/main/manual/layouts/_default/baseof.html Renders the navigation partial for the page. ```html {{ block "navigation" . }}{{ partial "navigation.html" . }}{{ end }} ``` -------------------------------- ### Render Header Partial Source: https://github.com/pmndrs/postprocessing/blob/main/manual/layouts/_default/baseof.html Renders the header partial for the page. ```html {{ block "header" . }}{{ partial "header.html" . }}{{ end }} ``` -------------------------------- ### Define a Custom Material with Shaders Source: https://github.com/pmndrs/postprocessing/wiki/Custom-Passes This snippet shows how to create a custom ShaderMaterial in Three.js, importing GLSL shaders for vertex and fragment programs. It sets up uniforms for input buffers and weights. ```javascript import { ShaderMaterial, Uniform, Vector3 } from "three"; // Using rollup-plugin-glsl to import shader files. import fragmentShader from "./shader.frag"; import vertexShader from "./shader.vert"; export class CustomMaterial extends ShaderMaterial { constructor() { super({ type: "CustomMaterial", uniforms: { inputBuffer: new Uniform(null), weights: new Uniform(new Vector3()) }, fragmentShader, vertexShader, toneMapped: false, depthWrite: false, depthTest: false }); } } ``` -------------------------------- ### Configure WebGLRenderer for Post Processing Source: https://github.com/pmndrs/postprocessing/blob/main/README.md Configure the WebGLRenderer with specific attributes for optimal post processing performance. This includes high-performance power preference and disabling antialiasing, stencil, and depth. ```js import { WebGLRenderer } from "three"; const renderer = new WebGLRenderer({ powerPreference: "high-performance", antialias: false, stencil: false, depth: false }); ``` -------------------------------- ### Render Main Content Block Source: https://github.com/pmndrs/postprocessing/blob/main/manual/layouts/_default/baseof.html Placeholder for the main content block of the page. ```html {{ block "main" . }}{{ end }} ``` -------------------------------- ### Fingerprint JavaScript Resource Source: https://github.com/pmndrs/postprocessing/blob/main/manual/layouts/_default/baseof.html Retrieves and fingerprints a JavaScript resource. ```html {{ with resources.Get "js/dist/index.js" }} {{ $script := . | fingerprint }} {{ end }} ``` -------------------------------- ### Render Footer Partial Source: https://github.com/pmndrs/postprocessing/blob/main/manual/layouts/_default/baseof.html Renders the footer partial for the page. ```html {{ block "footer" . }}{{ partial "footer.html" . }}{{ end }} ``` -------------------------------- ### Render Viewport Partial Source: https://github.com/pmndrs/postprocessing/blob/main/manual/layouts/_default/baseof.html Renders the viewport partial, likely for responsive meta tags or similar. ```html {{ partial "viewport.html" . }} ``` -------------------------------- ### Fingerprint Stylesheet Resource Source: https://github.com/pmndrs/postprocessing/blob/main/manual/layouts/_default/baseof.html Retrieves and fingerprints a CSS stylesheet resource. ```html {{ with resources.Get "css/dist/index.css" }} {{ $stylesheet := . | fingerprint }} {{ end }} ``` -------------------------------- ### Custom Effect JavaScript Implementation Source: https://github.com/pmndrs/postprocessing/blob/main/manual/content/custom-effects.en.md JavaScript class extending the base Effect class to implement a custom shader. It imports the GLSL fragment shader and sets up uniforms. ```javascript import { Uniform, Vector3 } from "three"; import { Effect } from "postprocessing"; // Use a bundler plugin like esbuild-plugin-glsl to import shaders as text. import fragmentShader from "./shader.frag"; export class CustomEffect extends Effect { constructor() { super("CustomEffect", fragmentShader, { uniforms: new Map([ ["weights", new Uniform(new Vector3())] ]) }); } } ``` -------------------------------- ### Enable High Precision Frame Buffers Source: https://github.com/pmndrs/postprocessing/blob/main/manual/content/getting-started.en.md Configure the GeometryPass to use HalfFloatType for frame buffers to prevent color degradation and banding, especially in HDR workflows. ```ts import { HalfFloatType } from "three"; const geoPass = new GeometryPass(scene, camera, { frameBufferType: HalfFloatType }); ``` -------------------------------- ### Fingerprint Vendor JavaScript Resource Source: https://github.com/pmndrs/postprocessing/blob/main/manual/layouts/_default/baseof.html Retrieves and fingerprints a vendor JavaScript resource. ```html {{ with resources.Get "js/dist/libs/vendor.js" }} {{ $script := . | fingerprint }} {{ end }} ``` -------------------------------- ### Define Main Template Source: https://github.com/pmndrs/postprocessing/blob/main/manual/layouts/_default/single.html Defines the main Hugo template block, which simply renders the page's content. ```gohtml {{ define "main" }} {{ .Content }} {{ end }} ``` -------------------------------- ### Determine Page Class Based on Kind Source: https://github.com/pmndrs/postprocessing/blob/main/manual/layouts/_default/baseof.html Dynamically sets CSS classes for the page based on its kind (home, 404, page, or list). ```html {{ $class := slice "preload" -}} {{ if eq .Kind "home" -}} {{ $class = $class | append "home" -}} {{ else if eq .Kind "404" -}} {{ $class = $class | append "error404" -}} {{ else if eq .Kind "page" -}} {{ $class = $class | append .Type -}} {{ $class = $class | append "single" -}} {{ else -}} {{ $class = $class | append .Type -}} {{ $class = $class | append "list" -}} {{ end -}} ``` -------------------------------- ### Skip to Content Link Source: https://github.com/pmndrs/postprocessing/blob/main/manual/layouts/_default/baseof.html Provides a link to skip directly to the main content of the page, using internationalization. ```html [ {{ i18n "skipToContent" . }} ](#main) ``` -------------------------------- ### Enable High Precision Frame Buffers Source: https://github.com/pmndrs/postprocessing/blob/main/README.md Enable high precision frame buffers using HalfFloatType for improved quality and to prevent banding in dark scenes, especially for HDR-like workflows. This is configured when creating the EffectComposer. ```ts import { HalfFloatType } from "three"; const composer = new EffectComposer(renderer, { frameBufferType: HalfFloatType }); ``` -------------------------------- ### Fragment Shader Function Signatures Source: https://github.com/pmndrs/postprocessing/wiki/Custom-Effects Defines the required function signatures for fragment shaders in custom effects. The mainImage function can optionally accept depth information. ```glsl void mainImage(const in vec4 inputColor, const in vec2 uv, out vec4 outputColor); void mainUv(inout vec2 uv); ``` ```glsl void mainImage(const in vec4 inputColor, const in vec2 uv, const in float depth, out vec4 outputColor); ``` -------------------------------- ### Vertex Shader Function Signatures Source: https://github.com/pmndrs/postprocessing/wiki/Custom-Effects Defines the function signatures for vertex shaders in custom effects. The mainSupport function can optionally accept UV coordinates. ```glsl void mainSupport(); ``` ```glsl void mainSupport(const in vec2 uv); ``` -------------------------------- ### Custom Pass Fragment Shader Source: https://github.com/pmndrs/postprocessing/wiki/Custom-Passes A fragment shader for a custom pass that applies custom weights to the input buffer's texels. Includes support for automatic output encoding. ```glsl uniform sampler2D inputBuffer; uniform vec3 weights; varying vec2 vUv; void main() { vec4 texel = texture2D(inputBuffer, vUv); gl_FragColor = vec4(texel.rgb * weights, texel.a); // Support automatic output encoding. #include } ``` -------------------------------- ### Texture Pack Modifications Source: https://github.com/pmndrs/postprocessing/blob/main/demo/static/models/sponza/README.md Details on modifications made to the PBR textures for the Sponza model, including resizing, merging, repacking, and re-encoding. ```text I needed to resize some of the alpha mask textures to the 1024x1024 resolution used by the new texture pack, and merge in diffuse with alpha. I also repacked the separate metallic/roughness textures into the glTF layout (G - roughness, B - metallic). The images are also re-encoded as PNG instead of TGA. All the materials also had a constant diffuse factor of about 0.58. I assume it was supposed to be there, so I kept it. I also ran the vertices and indices through a mesh optimizer. ``` -------------------------------- ### ShaderPass with Custom ShaderMaterial Source: https://github.com/pmndrs/postprocessing/wiki/Custom-Passes Use ShaderPass to apply a custom ShaderMaterial. The second argument specifies the texture sampler uniform name, defaulting to 'inputBuffer'. ```javascript import { ShaderMaterial, Uniform } from "three"; import { ShaderPass } from "postprocessing"; const myShaderMaterial = new ShaderMaterial({ defines: { LABEL: "value" }, uniforms: { tDiffuse: new Uniform(null) }, vertexShader: "...", fragmentShader: "..." }); const myShaderPass = new ShaderPass(myShaderMaterial, "tDiffuse"); ``` -------------------------------- ### Sponza Model Copyright Information Source: https://github.com/pmndrs/postprocessing/blob/main/demo/static/models/sponza/README.md Original copyright and historical information about the Sponza model, its modifications, and its purpose. ```text PBR textures for the Sponza model. For more informations: www.alexandre-pestana.com Original copyright: July 14, 2011 Morgan McGuire modified the model from Crytek's OBJ export to correct some small errors. He computed bump maps from the normal maps using normal2bump.cpp (since MTL files expect height bumps, not normals), put the "mask" textures into the alpha channel of the associated diffuse texture, cleaned up noise in the masks, created the missing gi_flag.tga texture, and removed the long untextured banner floating in the middle of the atrium that appears in the file but in none of the published images of the model. The banner is in banner.obj. http://www.crytek.com/cryengine/cryengine3/downloads Sponza Model August 19, 2010 The Atrium Sponza Palace, Dubrovnik, is an elegant and improved model created by Frank Meinl. The original Sponza model was created by Marko Dabrovic in early 2002. Over the years, the Sponza Atrium scene has become one of the most popular 3D scenes for testing global illumination and radiosity due to it's specific architectural structure which is particularly complex for global illumination light. However, nowadays it is considered as a simple model, thus it was decided to crate a new model with highly improved appearance and scene complexity. It is donated to the public for radiosity and is represented in several different formats (3ds, Obj) for use with various commercial 3D applications and renderers. Screenshot from the I3D paper http://crytek.com/sites/default/files/20100301_lpv.pdf ``` -------------------------------- ### Custom Effect GLSL Fragment Shader Source: https://github.com/pmndrs/postprocessing/blob/main/manual/content/custom-effects.en.md A basic fragment shader for a custom effect that applies weights to the input color. This shader is imported as text into the JavaScript effect. ```glsl uniform vec3 weights; vec4 mainImage(in vec4 inputColor, in vec2 uv, in GData data) { return vec4(inputColor.rgb * weights, inputColor.a); } ``` -------------------------------- ### Custom Pass Vertex Shader Source: https://github.com/pmndrs/postprocessing/wiki/Custom-Passes A basic vertex shader for a custom pass. It passes UV coordinates to the fragment shader and sets the vertex position. ```glsl varying vec2 vUv; void main() { vUv = position.xy * 0.5 + 0.5; gl_Position = vec4(position.xy, 1.0, 1.0); } ``` -------------------------------- ### Restore Scroll Positions Source: https://github.com/pmndrs/postprocessing/blob/main/manual/layouts/_default/baseof.html Immediately restores scroll positions for the navigation and main content areas from session storage. ```html {{/\* Immediately restore scroll positions. \*/}} document.querySelector(".navigation").scrollTop = Number(sessionStorage.getItem("nav-scroll")); document.querySelector("main").scrollTop = Number(sessionStorage.getItem("main-scroll")); ``` -------------------------------- ### Dark Mode CSS Class Toggle Source: https://github.com/pmndrs/postprocessing/blob/main/manual/layouts/_default/baseof.html Applies or removes the 'dark' class to the document element based on local storage to manage dark mode. ```html {{ with .Description }}{{ end }} {{ block "title" . }}{{ .Title }}{{ end }} ยท {{ .Site.Title }} {{/\* Prevent white flash on navigation in dark mode. \*/}} document.documentElement.classList\[localStorage.getItem("dark-mode")?"add":"remove"\].("dark") ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.