Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

examples: post-processing material AO #27475

Merged
merged 6 commits into from
Jan 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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