question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Add example of Pass that writes in a renderTarget before

See original GitHub issue

Is your feature request related to a problem?

I can’t figure out how to write to a custom renderTarget while rendering in a Pass. I have the following code:

import * as THREE from 'three'
import { Resizer, Pass } from 'postprocessing'

export class MyCustomPass extends Pass {
  constructor() {
    super('MyCustomPass')

    this.setFullscreenMaterial(
      new THREE.ShaderMaterial({
        blending: THREE.NoBlending,
        depthWrite: false,
        depthTest: false,
        toneMapped: false,

        uniforms: {
          inputBuffer: { value: null },
          renderTargetTexture: { value: null },
        },

        vertexShader: /* glsl */ `
          varying vec2 vUv;

          void main() {
            vUv = position.xy * 0.5 + 0.5;
            gl_Position = vec4(position.xy, 1.0, 1.0);
          }
        `,
        fragmentShader: /* glsl */ `
          uniform sampler2D inputBuffer;
          uniform sampler2D renderTargetTexture;
          varying vec2 vUv;

          void main() {
            // vec4 texel = texture2D(inputBuffer, vUv); // this works as expected
            vec4 texel = texture2D(renderTargetTexture, vUv); // this doesn't work
            gl_FragColor = texel; 

            // Support automatic output encoding.
            #include <encodings_fragment>
          }
        `,
      })
    )
    this.needsSwap = false

    // create a custom renderTarget here
    this.renderTarget = new THREE.WebGLRenderTarget(1, 1, {
      minFilter: THREE.LinearFilter,
      magFilter: THREE.LinearFilter,
      format: THREE.RGBAFormat,
      stencilBuffer: false,
      depthBuffer: false,
    })
    this.renderTarget.texture.name = 'MyCustomPass.Target'
    this.renderTarget.texture.generateMipmaps = false

    this.resolution = new Resizer(this, Resizer.AUTO_SIZE, Resizer.AUTO_SIZE)
  }

  render(renderer, inputBuffer, outputBuffer, deltaTime, stencilTest) {
    const material = this.getFullscreenMaterial()

    // first render everything in the rendertarget
    renderer.setRenderTarget(this.renderTarget)
    renderer.render(this.scene, this.camera)

    // then render from the rendertarget to the main
    material.uniforms.renderTargetTexture.value = this.renderTarget.texture 
    material.uniforms.inputBuffer.value = inputBuffer.texture
    renderer.setRenderTarget(this.renderToScreen ? null : outputBuffer)
    renderer.render(this.scene, this.camera)
  }

  setSize(width, height) {
    this.resolution.base.set(width, height)

    this.renderTarget.setSize(this.resolution.width, this.resolution.height)
  }

  initialize(renderer, alpha, frameBufferType) {
    if (frameBufferType !== undefined && frameBufferType !== THREE.UnsignedByteType) {
      const material = this.getFullscreenMaterial()
      material.defines.FRAMEBUFFER_PRECISION_HIGH = '1'
    }
  }
}

I need this code for an effect, however when I render this, this happens:

image

Do you have any idea why? Would be nice if the custom Pass/Effect guides could go more in-depth.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:8 (8 by maintainers)

github_iconTop GitHub Comments

1reaction
marcofugarocommented, May 21, 2021

Thanks a lot! So weird that is the only use-case where SMAA has no effect, black on transparent edges.

Anyway, I ended up removing the alpha altogether (chroma keying the border after antialias was a no-go). Thanks for your help!

Here is the final setup, I apply the white background as a postprocessing effect because I need to do LUT before, otherwise it would mess up the whites:

const effectPass = new EffectPass(camera, lutEffect, pixelOutlineEffect, backgroundEffect)
const effectPass2 = new EffectPass(camera, smaaEffect)
composer.addPass(effectPass)
composer.addPass(effectPass2)

You can close this issue now if you want!

1reaction
vanruesccommented, May 21, 2021

Thanks for the reproduction! This was indeed a bit tricky to debug.

If I use the effect (comment out the pass and uncomment the effect line) the image somehow is lighter in tones:

Sorry, that was my fault: I didn’t set the blend function of the effect to NORMAL (default is SCREEN).

I can’t get the outline to antialias

That’s because the outline color is the same color as the background (rgba(0,0,0,0)). SMAA only looks at color, not alpha. I think this can be considered a bug, although the original implementation also doesn’t consider alpha edges, probably for performance reasons.

If you set the edge color to a different color or disable alpha, antialiasing will work properly:

No SMAA, No Outline SMAA SMAA Edges No SMAA SMAA, Black Outline SMAA, Red Outline
smaa-00 smaa-01 smaa-edges smaa-02 smaa-03 smaa-04

Fixed sandbox: https://codesandbox.io/s/postprocessing-outline-forked-8wz9x?file=/src/index.js

Read more comments on GitHub >

github_iconTop Results From Across the Web

Render Target Texture With Multiple Passes
In this example we add two meshes, pool and ground, to the RTT and distort the UVs of the texture applied to the...
Read more >
Customizing Render Pass Setup - Apple Developer
This sample executes a pair of render passes to render a view's contents. For the first pass, the sample creates a custom render...
Read more >
Three.js Post Processing
EffectComposer(renderer);. Then as the first pass we add a RenderPass that will render our scene with our camera into the first render target....
Read more >
Custom Pass | High Definition RP | 7.7.1 - Unity - Manual
Here is an example of what can be achieved using custom passes: TIPS_Effect_Size ... You can't read and write to the same render...
Read more >
Tutorial 14 : Render To Texture
Creating the Render Target; Rendering to the texture; Using the rendered texture ... we will actually write in the Render Target 0, which...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found