Skip to content

Commit

Permalink
examples: post-processing material AO (#27475)
Browse files Browse the repository at this point in the history
* examples: post-processing material AO

* examples: postprocessing material - use gl_FragCoord.xy for map lookup

* Examples: postprocessing material ao: show diffuse pass on both sides

* Examples: postprocessing material a - simplify example

* Examples: postprocessing material ao - simplify enironment texture
  • Loading branch information
Rabbid76 authored Jan 2, 2024
1 parent 564e673 commit bad533f
Show file tree
Hide file tree
Showing 8 changed files with 436 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/examples/en/postprocessing/EffectComposer.html
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ <h2>Examples</h2>
[example:webgl_postprocessing_godrays postprocessing godrays]<br />
[example:webgl_postprocessing_gtao postprocessing gtao]<br />
[example:webgl_postprocessing_masking postprocessing masking]<br />
[example:webgl_postprocessing_material_ao postprocessing material ao]<br />
[example:webgl_postprocessing_outline postprocessing outline]<br />
[example:webgl_postprocessing_pixel postprocessing pixelate]<br />
[example:webgl_postprocessing_procedural postprocessing procedural]<br />
Expand Down
1 change: 1 addition & 0 deletions docs/examples/zh/postprocessing/EffectComposer.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ <h2>例子</h2>
[example:webgl_postprocessing_godrays postprocessing godrays]<br />
[example:webgl_postprocessing_gtao postprocessing gtao]<br />
[example:webgl_postprocessing_masking postprocessing masking]<br />
[example:webgl_postprocessing_material_ao postprocessing material ao]<br />
[example:webgl_postprocessing_outline postprocessing outline]<br />
[example:webgl_postprocessing_pixel postprocessing pixelate]<br />
[example:webgl_postprocessing_procedural postprocessing procedural]<br />
Expand Down
1 change: 1 addition & 0 deletions examples/files.json
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@
"webgl_postprocessing_gtao",
"webgl_postprocessing_rgb_halftone",
"webgl_postprocessing_masking",
"webgl_postprocessing_material_ao",
"webgl_postprocessing_ssaa",
"webgl_postprocessing_outline",
"webgl_postprocessing_pixel",
Expand Down
144 changes: 144 additions & 0 deletions examples/jsm/materials/MeshPostProcessingMaterial.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import { MeshPhysicalMaterial } from 'three';

/**
* The aim of this mesh material is to use information from a post processing pass in the diffuse color pass.
* This material is based on the MeshPhysicalMaterial.
*
* In the current state, only the information of a screen space AO pass can be used in the material.
* Actually, the output of any screen space AO (SSAO, GTAO) can be used,
* as it is only necessary to provide the AO in one color channel of a texture,
* however the AO pass must be rendered prior to the color pass,
* which makes the post-processing pass somewhat of a pre-processing pass.
* Fot this purpose a new map (`aoPassMap`) is added to the material.
* The value of the map is used the same way as the `aoMap` value.
*
* Motivation to use the outputs AO pass directly in the material:
* The incident light of a fragment is composed of ambient light, direct light and indirect light
* Ambient Occlusion only occludes ambient light and environment light, but not direct light.
* Direct light is only occluded by geometry that casts shadows.
* And of course the emitted light should not be darkened by ambient occlusion either.
* This cannot be achieved if the AO post processing pass is simply blended with the diffuse render pass.
*
* Further extension work might be to use the output of an SSR pass or an HBIL pass from a previous frame.
* This would then create the possibility of SSR and IR depending on material properties such as `roughness`, `metalness` and `reflectivity`.
**/

class MeshPostProcessingMaterial extends MeshPhysicalMaterial {

constructor( parameters ) {

const aoPassMap = parameters.aoPassMap;
const aoPassMapScale = parameters.aoPassMapScale || 1.0;
delete parameters.aoPassMap;
delete parameters.aoPassMapScale;

super( parameters );

this.onBeforeCompile = this._onBeforeCompile;
this.customProgramCacheKey = this._customProgramCacheKey;
this._aoPassMap = aoPassMap;
this.aoPassMapScale = aoPassMapScale;
this._shader = null;

}

get aoPassMap() {

return this._aoPassMap;

}

set aoPassMap( aoPassMap ) {

this._aoPassMap = aoPassMap;
this.needsUpdate = true;
this._setUniforms();

}

_customProgramCacheKey() {

return this._aoPassMap !== undefined && this._aoPassMap !== null ? 'aoPassMap' : '';

}

_onBeforeCompile( shader ) {

this._shader = shader;

if ( this._aoPassMap !== undefined && this._aoPassMap !== null ) {

shader.fragmentShader = shader.fragmentShader.replace(
'#include <aomap_pars_fragment>',
aomap_pars_fragment_replacement
);
shader.fragmentShader = shader.fragmentShader.replace(
'#include <aomap_fragment>',
aomap_fragment_replacement
);

}

this._setUniforms();

}

_setUniforms() {

if ( this._shader ) {

this._shader.uniforms.tAoPassMap = { value: this._aoPassMap };
this._shader.uniforms.aoPassMapScale = { value: this.aoPassMapScale };

}

}

}

const aomap_pars_fragment_replacement = /* glsl */`
#ifdef USE_AOMAP
uniform sampler2D aoMap;
uniform float aoMapIntensity;
#endif
uniform sampler2D tAoPassMap;
uniform float aoPassMapScale;
`;

const aomap_fragment_replacement = /* glsl */`
#ifndef AOPASSMAP_SWIZZLE
#define AOPASSMAP_SWIZZLE r
#endif
float ambientOcclusion = texelFetch( tAoPassMap, ivec2( gl_FragCoord.xy * aoPassMapScale ), 0 ).AOPASSMAP_SWIZZLE;
#ifdef USE_AOMAP
// reads channel R, compatible with a combined OcclusionRoughnessMetallic (RGB) texture
ambientOcclusion = min( ambientOcclusion, texture2D( aoMap, vAoMapUv ).r );
ambientOcclusion *= ( ambientOcclusion - 1.0 ) * aoMapIntensity + 1.0;
#endif
reflectedLight.indirectDiffuse *= ambientOcclusion;
#if defined( USE_CLEARCOAT )
clearcoatSpecularIndirect *= ambientOcclusion;
#endif
#if defined( USE_SHEEN )
sheenSpecularIndirect *= ambientOcclusion;
#endif
#if defined( USE_ENVMAP ) && defined( STANDARD )
float dotNV = saturate( dot( geometryNormal, geometryViewDir ) );
reflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.roughness );
#endif
`;

export { MeshPostProcessingMaterial };
10 changes: 10 additions & 0 deletions examples/jsm/postprocessing/GTAOPass.js
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,12 @@ class GTAOPass extends Pass {

}

get gtaoMap() {

return this.pdRenderTarget.texture;

}

setGBuffer( depthTexture, normalTexture ) {

if ( depthTexture !== undefined ) {
Expand Down Expand Up @@ -359,6 +365,9 @@ class GTAOPass extends Pass {

switch ( this.output ) {

case GTAOPass.OUTPUT.Off:
break;

case GTAOPass.OUTPUT.Diffuse:

this.copyMaterial.uniforms.tDiffuse.value = readBuffer.texture;
Expand Down Expand Up @@ -561,6 +570,7 @@ class GTAOPass extends Pass {
}

GTAOPass.OUTPUT = {
'Off': - 1,
'Default': 0,
'Diffuse': 1,
'Depth': 2,
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions examples/tags.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
"webgl_postprocessing_fxaa": [ "msaa", "multisampled" ],
"webgl_postprocessing_godrays": [ "light scattering" ],
"webgl_postprocessing_gtao": [ "ambient occlusion" ],
"webgl_postprocessing_material_ao": [ "ambient occlusion"],
"webgl_shadowmap_progressive": [ "shadow", "soft", "lightmap", "onBeforeCompile" ],
"webgl_postprocessing_ssaa": [ "msaa", "multisampled" ],
"webgl_postprocessing_ssaa_unbiased": [ "msaa", "multisampled" ],
Expand Down
Loading

0 comments on commit bad533f

Please sign in to comment.