forked from BabylonJS/Babylon.js
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added support of Screen Space Reflection Post-Process
- Loading branch information
1 parent
dffc86f
commit 4e7ec14
Showing
8 changed files
with
561 additions
and
81 deletions.
There are no files selected for viewing
138 changes: 89 additions & 49 deletions
138
src/PostProcesses/RenderPipeline/Pipelines/standardRenderingPipeline.ts
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
import { Nullable } from "../types"; | ||
import { Camera } from "../Cameras/camera"; | ||
import { Effect } from "../Materials/effect"; | ||
import { PostProcess, PostProcessOptions } from "./postProcess"; | ||
import { Constants } from "../Engines/constants"; | ||
import { Scene } from '../scene'; | ||
import { GeometryBufferRenderer } from '../Rendering/geometryBufferRenderer'; | ||
import { serialize } from '../Misc/decorators'; | ||
|
||
import "../Shaders/screenSpaceReflection.fragment"; | ||
|
||
|
||
declare type Engine = import("../Engines/engine").Engine; | ||
/** | ||
* The SharpenPostProcess applies a sharpen kernel to every pixel | ||
* See http://en.wikipedia.org/wiki/Kernel_(image_processing) | ||
*/ | ||
export class ScreenSpaceReflectionPostProcess extends PostProcess { | ||
/** | ||
* Gets or sets a reflection threshold mainly used to adjust the reflection's height. | ||
*/ | ||
@serialize() | ||
public threshold: number = 0; | ||
/** | ||
* Gets or sets the current reflection strength. 1.0 is an ideal value but can be increased/decreased for particular results. | ||
*/ | ||
@serialize() | ||
public strength: number = 1; | ||
/** | ||
* Gets or sets the falloff exponent used while computing fresnel. More the exponent is high, more the reflections will be discrete. | ||
*/ | ||
@serialize() | ||
public reflectionSpecularFalloffExponent: number = 3; | ||
|
||
private _geometryBufferRenderer: Nullable<GeometryBufferRenderer>; | ||
private _enableSmoothReflections: boolean = true; | ||
private _reflectionSamples: number = 64; | ||
|
||
/** | ||
* Creates a new instance ConvolutionPostProcess | ||
* @param name The name of the effect. | ||
* @param scene The scene containing the objects to calculate reflections. | ||
* @param options The required width/height ratio to downsize to before computing the render pass. | ||
* @param camera The camera to apply the render pass to. | ||
* @param samplingMode The sampling mode to be used when computing the pass. (default: 0) | ||
* @param engine The engine which the post process will be applied. (default: current engine) | ||
* @param reusable If the post process can be reused on the same frame. (default: false) | ||
* @param textureType Type of textures used when performing the post process. (default: 0) | ||
* @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false) | ||
*/ | ||
constructor(name: string, scene: Scene, options: number | PostProcessOptions, camera: Nullable<Camera>, samplingMode?: number, engine?: Engine, reusable?: boolean, textureType: number = Constants.TEXTURETYPE_UNSIGNED_INT, blockCompilation = false) { | ||
super(name, "screenSpaceReflection", [ | ||
"projection", "view", "threshold", "reflectionSpecularFalloffExponent", "strength" | ||
], [ | ||
"textureSampler", "normalSampler", "positionSampler", "roughnessSampler" | ||
], options, camera, samplingMode, engine, reusable, | ||
"#define SSR_SUPPORTED\n#define REFLECTION_SAMPLES 64\n", | ||
textureType, undefined, null, blockCompilation); | ||
|
||
// Get geometry buffer renderer and update effect | ||
const geometryBufferRenderer = scene.enableGeometryBufferRenderer(); | ||
if (geometryBufferRenderer) { | ||
if (geometryBufferRenderer.isSupported) { | ||
geometryBufferRenderer.enablePosition = true; | ||
geometryBufferRenderer.enableRoughness = true; | ||
this._geometryBufferRenderer = geometryBufferRenderer; | ||
} | ||
} | ||
|
||
this._updateEffectDefines(); | ||
|
||
// On apply, send uniforms | ||
this.onApply = (effect: Effect) => { | ||
if (!geometryBufferRenderer) { | ||
return; | ||
} | ||
|
||
// Samplers | ||
const positionIndex = geometryBufferRenderer.getTextureIndex(GeometryBufferRenderer.POSITION_TEXTURE_TYPE); | ||
const roughnessIndex = geometryBufferRenderer.getTextureIndex(GeometryBufferRenderer.ROUGHNESS_TEXTURE_TYPE); | ||
|
||
effect.setTexture("normalSampler", geometryBufferRenderer.getGBuffer().textures[1]); | ||
effect.setTexture("positionSampler", geometryBufferRenderer.getGBuffer().textures[positionIndex]); | ||
effect.setTexture("roughnessSampler", geometryBufferRenderer.getGBuffer().textures[roughnessIndex]); | ||
|
||
// Uniforms | ||
const camera = scene.activeCamera; | ||
if (!camera) { | ||
return; | ||
} | ||
|
||
const viewMatrix = camera.getViewMatrix(); | ||
const projectionMatrix = camera.getProjectionMatrix(); | ||
|
||
effect.setMatrix("projection", projectionMatrix); | ||
effect.setMatrix("view", viewMatrix); | ||
effect.setFloat("threshold", this.threshold); | ||
effect.setFloat("reflectionSpecularFalloffExponent", this.reflectionSpecularFalloffExponent); | ||
effect.setFloat("strength", this.strength); | ||
}; | ||
} | ||
|
||
/** | ||
* Gets wether or not smoothing reflections is enabled. | ||
* Enabling smoothing will require more GPU power and can generate a drop in FPS. | ||
*/ | ||
@serialize() | ||
public get enableSmoothReflections(): boolean { | ||
return this._enableSmoothReflections; | ||
} | ||
|
||
/** | ||
* Sets wether or not smoothing reflections is enabled. | ||
* Enabling smoothing will require more GPU power and can generate a drop in FPS. | ||
*/ | ||
public set enableSmoothReflections(enabled: boolean) { | ||
if (enabled === this._enableSmoothReflections) { | ||
return; | ||
} | ||
|
||
this._enableSmoothReflections = enabled; | ||
this._updateEffectDefines(); | ||
} | ||
|
||
/** | ||
* Gets the number of samples taken while computing reflections. More samples count is high, | ||
* more the post-process wil require GPU power and can generate a drop in FPS. | ||
*/ | ||
@serialize() | ||
public get reflectionSamples(): number { | ||
return this._reflectionSamples; | ||
} | ||
|
||
/** | ||
* Sets the number of samples taken while computing reflections. More samples count is high, | ||
* more the post-process wil require GPU power and can generate a drop in FPS. | ||
*/ | ||
public set reflectionSamples(samples: number) { | ||
if (samples === this._reflectionSamples) { | ||
return; | ||
} | ||
|
||
this._reflectionSamples = samples; | ||
this._updateEffectDefines(); | ||
} | ||
|
||
private _updateEffectDefines(): void { | ||
const defines: string[] = []; | ||
if (this._geometryBufferRenderer) { | ||
defines.push("#define SSR_SUPPORTED"); | ||
} | ||
if (this._enableSmoothReflections) { | ||
defines.push("#define ENABLE_SMOOTH_REFLECTIONS"); | ||
} | ||
|
||
defines.push("#define REFLECTION_SAMPLES " + (this._reflectionSamples >> 0)); | ||
|
||
this.updateEffect(defines.join("\n")); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.