Skip to content
Draft
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
123 changes: 122 additions & 1 deletion examples/jsm/postprocessing/SSShadowPass.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { CopyShader } from '../shaders/CopyShader.js';

class SSShadowPass extends Pass {

constructor( { renderer, scene, camera, width, height, encoding, morphTargets = false } ) {
constructor( { renderer, scene, camera, width, height, selects, encoding, morphTargets = false } ) {

super();

Expand All @@ -49,6 +49,29 @@ class SSShadowPass extends Pass {

this.tempColor = new Color();

this._selects = selects;

this.selective = Array.isArray( this._selects );
Object.defineProperty( this, 'selects', {
get() {

return this._selects;

},
set( val ) {

if (this._selects === val ) return;
this._selects = val;
if ( Array.isArray( val ) ) {
this.selective = true;
this.ssshadowMaterial.defines.SELECTIVE = true;
this.ssshadowMaterial.needsUpdate = true;

}

}
} );

this._infiniteThick = SSShadowShader.defines.INFINITE_THICK;
Object.defineProperty( this, 'infiniteThick', {
get() {
Expand Down Expand Up @@ -98,6 +121,13 @@ class SSShadowPass extends Pass {
format: RGBAFormat
} );

this.recievesShadowsRenderTarget = new WebGLRenderTarget( this.width, this.height, {
minFilter: NearestFilter,
magFilter: NearestFilter,
format: RGBAFormat,
type: HalfFloatType,
} );

// ssshadow render target

this.ssshadowRenderTarget = new WebGLRenderTarget( this.width, this.height, {
Expand Down Expand Up @@ -126,7 +156,9 @@ class SSShadowPass extends Pass {

this.ssshadowMaterial.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.texture;
this.ssshadowMaterial.uniforms[ 'tNormal' ].value = this.normalRenderTarget.texture;
this.ssshadowMaterial.defines.SELECTIVE = this.selective;
this.ssshadowMaterial.needsUpdate = true;
this.ssshadowMaterial.uniforms[ 'tRecievesShadows' ].value = this.recievesShadowsRenderTarget.texture;
this.ssshadowMaterial.uniforms[ 'tRefractive' ].value = this.refractiveRenderTarget.texture;
this.ssshadowMaterial.uniforms[ 'tDepth' ].value = this.beautyRenderTarget.depthTexture;
this.ssshadowMaterial.uniforms[ 'cameraNear' ].value = this.camera.near;
Expand All @@ -141,6 +173,14 @@ class SSShadowPass extends Pass {
this.normalMaterial = new MeshNormalMaterial( { morphTargets } );
this.normalMaterial.blending = NoBlending;

this.recievesShadowsOnMaterial = new MeshBasicMaterial( {
color: 'white',
} );

this.recievesShadowsOffMaterial = new MeshBasicMaterial( {
color: 'black',
} );

// refractiveOn material

this.refractiveOnMaterial = new MeshBasicMaterial( {
Expand Down Expand Up @@ -196,12 +236,15 @@ class SSShadowPass extends Pass {

this.beautyRenderTarget.dispose();
this.normalRenderTarget.dispose();
this.recievesShadowsRenderTarget.dispose();
this.refractiveRenderTarget.dispose();
this.ssshadowRenderTarget.dispose();

// dispose materials

this.normalMaterial.dispose();
this.recievesShadowsOnMaterial.dispose();
this.recievesShadowsOffMaterial.dispose();
this.refractiveOnMaterial.dispose();
this.refractiveOffMaterial.dispose();
this.copyMaterial.dispose();
Expand All @@ -226,6 +269,13 @@ class SSShadowPass extends Pass {

this.renderOverride( renderer, this.normalMaterial, this.normalRenderTarget, 0, 0 );

// render selected objects

if ( this.selective ) {

this.renderRecievesShadows( renderer, this.recievesShadowsOnMaterial, this.recievesShadowsRenderTarget, 0, 0);
}

// render SSShadow

this.ssshadowMaterial.uniforms[ 'lightPosition' ].value = this.lightPosition;
Expand Down Expand Up @@ -282,6 +332,14 @@ class SSShadowPass extends Pass {

break;

case SSShadowPass.OUTPUT.RecievesShadows:

this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.recievesShadowsRenderTarget.texture;
this.copyMaterial.blending = NoBlending;
this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );

break;

default:
console.warn( 'THREE.SSShadowPass: Unknown output type.' );

Expand Down Expand Up @@ -350,6 +408,67 @@ class SSShadowPass extends Pass {

}

renderRecievesShadows( renderer, overrideMaterial, renderTarget, clearColor, clearAlpha ) {

this.originalClearColor.copy( renderer.getClearColor( this.tempColor ) );
const originalClearAlpha = renderer.getClearAlpha( this.tempColor );
const originalAutoClear = renderer.autoClear;

renderer.setRenderTarget( renderTarget );
renderer.autoClear = false;

clearColor = overrideMaterial.clearColor || clearColor;
clearAlpha = overrideMaterial.clearAlpha || clearAlpha;

if ( ( clearColor != undefined ) && ( clearColor != null ) ) {

renderer.setClearColor( clearColor );
renderer.setClearAlpha( clearAlpha || 0.0 );
renderer.clear();

}

this.scene.traverseVisible( child => {

if ( !child?.material?.visible ) {

return;

}
child._SSShadowPassBackupMaterial = child.material;
if ( this._selects.includes( child ) ) {

child.material = this.recievesShadowsOnMaterial;

} else {

child.material = this.recievesShadowsOffMaterial;

}

} );

renderer.render( this.scene, this.camera );

this.scene.traverseVisible( child => {

if ( !child?.material?.visible ) {

return;

}

child.material = child._SSShadowPassBackupMaterial;

} );

// restore original state
renderer.autoClear = originalAutoClear;
renderer.setClearColor( this.originalClearColor );
renderer.setClearAlpha( originalClearAlpha );

}

setSize( width, height ) {

this.width = width;
Expand All @@ -359,6 +478,7 @@ class SSShadowPass extends Pass {
this.ssshadowMaterial.needsUpdate = true;
this.beautyRenderTarget.setSize( width, height );
this.normalRenderTarget.setSize( width, height );
this.recievesShadowsRenderTarget.setSize( width, height );
this.ssshadowRenderTarget.setSize( width, height );
this.refractiveRenderTarget.setSize( width, height );

Expand All @@ -376,6 +496,7 @@ SSShadowPass.OUTPUT = {
'Beauty': 3,
'Depth': 4,
'Normal': 5,
'RecievesShadows': 6,
'Refractive': 7,
};

Expand Down
6 changes: 6 additions & 0 deletions examples/jsm/shaders/SSShadowShader.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const SSShadowShader = {
'tDiffuse': { value: null },
'tNormal': { value: null },
'tRefractive': { value: null },
'tRecievesShadows': { value: null },
'tDepth': { value: null },
'cameraNear': { value: null },
'cameraFar': { value: null },
Expand Down Expand Up @@ -58,6 +59,7 @@ const SSShadowShader = {
uniform sampler2D tNormal;
uniform sampler2D tRefractive;
uniform sampler2D tDiffuse;
uniform sampler2D tRecievesShadows;
uniform float cameraRange;
uniform vec2 resolution;
uniform float cameraNear;
Expand Down Expand Up @@ -115,6 +117,10 @@ const SSShadowShader = {
return xy;
}
void main(){
#ifdef SELECTIVE
float recievesShadows=texture2D(tRecievesShadows,vUv).r;
if(recievesShadows!=1.) return;
#endif

// gl_FragColor=vec4(0,0,.5,1);return;

Expand Down
8 changes: 8 additions & 0 deletions examples/webgl_postprocessing_ssshadow.html
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
let controls;
let camera, scene, renderer;
const objects = [];
const selects = [];
const raycaster = new THREE.Raycaster();
const mouseDown = new THREE.Vector2();
const mouse = new THREE.Vector2();
Expand Down Expand Up @@ -85,6 +86,7 @@
plane.position.y = - 0.0001;
// plane.receiveShadow = true;
scene.add( plane );
selects.push(plane);
plane.name = 'plane';

// Lights
Expand Down Expand Up @@ -116,6 +118,7 @@
mesh.name = 'bunny';
scene.add( mesh );
objects.push( mesh );
selects.push( mesh );

// Release decoder resources.
dracoLoader.dispose();
Expand All @@ -132,6 +135,7 @@
mesh.name = 'box';
scene.add( mesh );
objects.push( mesh );
selects.push( mesh );

geometry = new THREE.IcosahedronBufferGeometry( .025, 4 );
// material = new THREE.MeshStandardMaterial( { color: 'cyan' } );
Expand All @@ -141,6 +145,7 @@
mesh.name = 'sphere';
scene.add( mesh );
objects.push( mesh );
selects.push( mesh );

geometry = new THREE.ConeBufferGeometry( .025, .05, 64 );
// material = new THREE.MeshStandardMaterial( { color: 'yellow' } );
Expand All @@ -150,6 +155,7 @@
mesh.name = 'cone';
scene.add( mesh );
objects.push( mesh );
selects.push( mesh );

// renderer
renderer = new THREE.WebGLRenderer( { antialias: false } );
Expand All @@ -176,6 +182,7 @@
width: innerWidth,
height: innerHeight,
encoding: THREE.sRGBEncoding,
selects: selects,
} );

composer.addPass( ssshadowPass );
Expand Down Expand Up @@ -231,6 +238,7 @@
'Beauty': SSShadowPass.OUTPUT.Beauty,
'Depth': SSShadowPass.OUTPUT.Depth,
'Normal': SSShadowPass.OUTPUT.Normal,
'Recieves Shadows': SSShadowPass.OUTPUT.RecievesShadows,
} ).onChange( function ( value ) {

ssshadowPass.output = parseInt( value );
Expand Down