|
@@ -30,6 +30,8 @@ import { SmaaParams, SmaaPass } from './smaa';
|
|
|
import { isTimingMode } from '../../mol-util/debug';
|
|
|
import { BackgroundParams, BackgroundPass } from './background';
|
|
|
import { AssetManager } from '../../mol-util/assets';
|
|
|
+import { Light } from '../../mol-gl/renderer';
|
|
|
+// import { debug } from 'console';
|
|
|
|
|
|
const OutlinesSchema = {
|
|
|
...QuadSchema,
|
|
@@ -78,12 +80,31 @@ const SsaoSchema = {
|
|
|
|
|
|
uProjection: UniformSpec('m4'),
|
|
|
uInvProjection: UniformSpec('m4'),
|
|
|
+ uView: UniformSpec('m4'),
|
|
|
uBounds: UniformSpec('v4'),
|
|
|
|
|
|
uTexSize: UniformSpec('v2'),
|
|
|
|
|
|
uRadius: UniformSpec('f'),
|
|
|
uBias: UniformSpec('f'),
|
|
|
+
|
|
|
+ uCloseAO: UniformSpec('i'),
|
|
|
+ uCloseBias: UniformSpec('f'),
|
|
|
+ uCloseDistance: UniformSpec('f'),
|
|
|
+
|
|
|
+ uShadow: UniformSpec('i'),
|
|
|
+ dSSample: DefineSpec('number'),
|
|
|
+ uSDistance: UniformSpec('f'),
|
|
|
+ uSTolerance: UniformSpec('f'),
|
|
|
+ uSBias: UniformSpec('f'),
|
|
|
+
|
|
|
+ uLightDirection: UniformSpec('v3[]'),
|
|
|
+ uLightColor: UniformSpec('v3[]'),
|
|
|
+ dLightCount: DefineSpec('number'),
|
|
|
+
|
|
|
+ dOrthographic: DefineSpec('number'),
|
|
|
+ uNear: UniformSpec('f'),
|
|
|
+ uFar: UniformSpec('f'),
|
|
|
};
|
|
|
|
|
|
type SsaoRenderable = ComputeRenderable<Values<typeof SsaoSchema>>
|
|
@@ -98,12 +119,31 @@ function getSsaoRenderable(ctx: WebGLContext, depthTexture: Texture): SsaoRender
|
|
|
|
|
|
uProjection: ValueCell.create(Mat4.identity()),
|
|
|
uInvProjection: ValueCell.create(Mat4.identity()),
|
|
|
+ uView: ValueCell.create(Mat4.identity()),
|
|
|
uBounds: ValueCell.create(Vec4()),
|
|
|
|
|
|
uTexSize: ValueCell.create(Vec2.create(ctx.gl.drawingBufferWidth, ctx.gl.drawingBufferHeight)),
|
|
|
|
|
|
+ uLightDirection: ValueCell.create([]),
|
|
|
+ uLightColor: ValueCell.create([]),
|
|
|
+ dLightCount: ValueCell.create(0),
|
|
|
+
|
|
|
uRadius: ValueCell.create(8.0),
|
|
|
uBias: ValueCell.create(0.025),
|
|
|
+
|
|
|
+ uCloseAO: ValueCell.create(1),
|
|
|
+ uCloseBias: ValueCell.create(1.0),
|
|
|
+ uCloseDistance: ValueCell.create(0.01),
|
|
|
+
|
|
|
+ uShadow: ValueCell.create(1),
|
|
|
+ dSSample: ValueCell.create(1),
|
|
|
+ uSDistance: ValueCell.create(3.0),
|
|
|
+ uSTolerance: ValueCell.create(0.2),
|
|
|
+ uSBias: ValueCell.create(1.5),
|
|
|
+
|
|
|
+ dOrthographic: ValueCell.create(0),
|
|
|
+ uNear: ValueCell.create(0.0),
|
|
|
+ uFar: ValueCell.create(10000.0),
|
|
|
};
|
|
|
|
|
|
const schema = { ...SsaoSchema };
|
|
@@ -224,6 +264,10 @@ const PostprocessingSchema = {
|
|
|
dOutlineEnable: DefineSpec('boolean'),
|
|
|
dOutlineScale: DefineSpec('number'),
|
|
|
uOutlineThreshold: UniformSpec('f'),
|
|
|
+
|
|
|
+ dLightCount: DefineSpec('number'),
|
|
|
+ uLightDirection: UniformSpec('v3[]'),
|
|
|
+ uLightColor: UniformSpec('v3[]'),
|
|
|
};
|
|
|
type PostprocessingRenderable = ComputeRenderable<Values<typeof PostprocessingSchema>>
|
|
|
|
|
@@ -254,6 +298,10 @@ function getPostprocessingRenderable(ctx: WebGLContext, colorTexture: Texture, d
|
|
|
dOutlineEnable: ValueCell.create(false),
|
|
|
dOutlineScale: ValueCell.create(1),
|
|
|
uOutlineThreshold: ValueCell.create(0.33),
|
|
|
+
|
|
|
+ dLightCount: ValueCell.create(0),
|
|
|
+ uLightDirection: ValueCell.create([]),
|
|
|
+ uLightColor: ValueCell.create([]),
|
|
|
};
|
|
|
|
|
|
const schema = { ...PostprocessingSchema };
|
|
@@ -269,8 +317,24 @@ export const PostprocessingParams = {
|
|
|
samples: PD.Numeric(32, { min: 1, max: 256, step: 1 }),
|
|
|
radius: PD.Numeric(5, { min: 0, max: 10, step: 0.1 }, { description: 'Final occlusion radius is 2^x' }),
|
|
|
bias: PD.Numeric(0.8, { min: 0, max: 3, step: 0.1 }),
|
|
|
+ shadow: PD.MappedStatic('on', {
|
|
|
+ on: PD.Group({
|
|
|
+ sSamples: PD.Numeric(1, { min: 1, max: 20, step: 1 }),
|
|
|
+ sbias: PD.Numeric(0.8, { min: 0.0, max: 1.0, step: 0.01 }),
|
|
|
+ sdistance: PD.Numeric(3.0, { min: 0.0, max: 100.0, step: 1.0 }),
|
|
|
+ stolerance: PD.Numeric(1.0, { min: 0.0, max: 100.0, step: 1.0 }),
|
|
|
+ }),
|
|
|
+ off: PD.Group({})
|
|
|
+ }, { cycle: true, description: 'Darken occluded crevices with the ambient occlusion effect' }),
|
|
|
+ closeAO: PD.MappedStatic('on', {
|
|
|
+ on: PD.Group({
|
|
|
+ cbias: PD.Numeric(1.0, { min: 0.0, max: 2.0, step: 0.01 }),
|
|
|
+ cdistance: PD.Numeric(0.015, { min: 0.0, max: 0.2, step: 0.001 }),
|
|
|
+ }),
|
|
|
+ off: PD.Group({})
|
|
|
+ }, { cycle: true, description: 'Darken occluded crevices with the ambient occlusion effect' }),
|
|
|
blurKernelSize: PD.Numeric(15, { min: 1, max: 25, step: 2 }),
|
|
|
- resolutionScale: PD.Numeric(1, { min: 0.1, max: 1, step: 0.05 }, { description: 'Adjust resolution of occlusion calculation' }),
|
|
|
+ resolutionScale: PD.Numeric(1, { min: 0.1, max: 1, step: 0.05 }, { description: 'Adjust resolution of occlusion calculation' })
|
|
|
}),
|
|
|
off: PD.Group({})
|
|
|
}, { cycle: true, description: 'Darken occluded crevices with the ambient occlusion effect' }),
|
|
@@ -289,6 +353,7 @@ export const PostprocessingParams = {
|
|
|
}, { options: [['fxaa', 'FXAA'], ['smaa', 'SMAA'], ['off', 'Off']], description: 'Smooth pixel edges' }),
|
|
|
background: PD.Group(BackgroundParams, { isFlat: true }),
|
|
|
};
|
|
|
+
|
|
|
export type PostprocessingProps = PD.Values<typeof PostprocessingParams>
|
|
|
|
|
|
export class PostprocessingPass {
|
|
@@ -404,7 +469,7 @@ export class PostprocessingPass {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private updateState(camera: ICamera, transparentBackground: boolean, backgroundColor: Color, props: PostprocessingProps) {
|
|
|
+ private updateState(camera: ICamera, transparentBackground: boolean, backgroundColor: Color, props: PostprocessingProps, light: Light) {
|
|
|
let needsUpdateMain = false;
|
|
|
let needsUpdateSsao = false;
|
|
|
let needsUpdateSsaoBlur = false;
|
|
@@ -417,8 +482,19 @@ export class PostprocessingPass {
|
|
|
Mat4.invert(invProjection, camera.projection);
|
|
|
|
|
|
if (props.occlusion.name === 'on') {
|
|
|
+ const shadowocclusionEnabled = props.occlusion.params.shadow.name === 'on' ? 1 : 0;
|
|
|
+ const closeocclusionEnabled = props.occlusion.params.closeAO.name === 'on' ? 1 : 0;
|
|
|
+
|
|
|
+ ValueCell.update(this.ssaoRenderable.values.uShadow, shadowocclusionEnabled);
|
|
|
+ ValueCell.update(this.ssaoRenderable.values.uCloseAO, closeocclusionEnabled);
|
|
|
+
|
|
|
ValueCell.update(this.ssaoRenderable.values.uProjection, camera.projection);
|
|
|
ValueCell.update(this.ssaoRenderable.values.uInvProjection, invProjection);
|
|
|
+ ValueCell.update(this.ssaoRenderable.values.uView, camera.view);
|
|
|
+
|
|
|
+ ValueCell.updateIfChanged(this.ssaoRenderable.values.uNear, camera.near);
|
|
|
+ ValueCell.updateIfChanged(this.ssaoRenderable.values.uFar, camera.far);
|
|
|
+ ValueCell.updateIfChanged(this.ssaoRenderable.values.dOrthographic, orthographic);
|
|
|
|
|
|
const [w, h] = this.renderable.values.uTexSize.ref.value;
|
|
|
const b = this.ssaoRenderable.values.uBounds;
|
|
@@ -456,6 +532,36 @@ export class PostprocessingPass {
|
|
|
ValueCell.updateIfChanged(this.ssaoRenderable.values.uRadius, Math.pow(2, props.occlusion.params.radius));
|
|
|
ValueCell.updateIfChanged(this.ssaoRenderable.values.uBias, props.occlusion.params.bias);
|
|
|
|
|
|
+ if (props.occlusion.params.shadow.name === 'on') {
|
|
|
+ ValueCell.update(this.ssaoRenderable.values.dSSample, props.occlusion.params.shadow.params.sSamples);
|
|
|
+ ValueCell.update(this.ssaoRenderable.values.uSDistance, props.occlusion.params.shadow.params.sdistance);
|
|
|
+ ValueCell.update(this.ssaoRenderable.values.uSTolerance, props.occlusion.params.shadow.params.stolerance);
|
|
|
+
|
|
|
+ ValueCell.update(this.ssaoRenderable.values.uSBias, props.occlusion.params.shadow.params.sbias);
|
|
|
+ if (this.ssaoRenderable.values.dSSample.ref.value !== props.occlusion.params.shadow.params.sSamples ||
|
|
|
+ this.ssaoRenderable.values.uSDistance.ref.value !== props.occlusion.params.shadow.params.sdistance ||
|
|
|
+ this.ssaoRenderable.values.uSBias.ref.value !== props.occlusion.params.shadow.params.sbias) {
|
|
|
+ needsUpdateSsao = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (props.occlusion.params.closeAO.name === 'on') {
|
|
|
+ ValueCell.update(this.ssaoRenderable.values.uCloseBias, props.occlusion.params.closeAO.params.cbias);
|
|
|
+ ValueCell.update(this.ssaoRenderable.values.uCloseDistance, props.occlusion.params.closeAO.params.cdistance);
|
|
|
+ if (this.ssaoRenderable.values.uCloseBias.ref.value !== props.occlusion.params.closeAO.params.cbias ||
|
|
|
+ this.ssaoRenderable.values.uCloseDistance.ref.value !== props.occlusion.params.closeAO.params.cdistance) {
|
|
|
+ needsUpdateSsao = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // console.log(light.direction);
|
|
|
+ ValueCell.update(this.ssaoRenderable.values.uLightDirection, light.direction);
|
|
|
+ ValueCell.update(this.ssaoRenderable.values.uLightColor, light.color);
|
|
|
+ if (this.ssaoRenderable.values.dLightCount.ref.value !== light.count) {
|
|
|
+ ValueCell.update(this.ssaoRenderable.values.dLightCount, light.count);
|
|
|
+ needsUpdateSsao = true;
|
|
|
+ }
|
|
|
if (this.blurKernelSize !== props.occlusion.params.blurKernelSize) {
|
|
|
needsUpdateSsaoBlur = true;
|
|
|
|
|
@@ -527,6 +633,13 @@ export class PostprocessingPass {
|
|
|
if (this.renderable.values.dOcclusionEnable.ref.value !== occlusionEnabled) { needsUpdateMain = true; }
|
|
|
ValueCell.updateIfChanged(this.renderable.values.dOcclusionEnable, occlusionEnabled);
|
|
|
|
|
|
+ ValueCell.update(this.renderable.values.uLightDirection, light.direction);
|
|
|
+ ValueCell.update(this.renderable.values.uLightColor, light.color);
|
|
|
+ if (this.renderable.values.dLightCount.ref.value !== light.count) {
|
|
|
+ ValueCell.update(this.renderable.values.dLightCount, light.count);
|
|
|
+ needsUpdateMain = true;
|
|
|
+ }
|
|
|
+
|
|
|
if (needsUpdateSsao) {
|
|
|
this.ssaoRenderable.update();
|
|
|
}
|
|
@@ -564,9 +677,9 @@ export class PostprocessingPass {
|
|
|
this.transparentBackground = value;
|
|
|
}
|
|
|
|
|
|
- render(camera: ICamera, toDrawingBuffer: boolean, transparentBackground: boolean, backgroundColor: Color, props: PostprocessingProps) {
|
|
|
+ render(camera: ICamera, toDrawingBuffer: boolean, transparentBackground: boolean, backgroundColor: Color, props: PostprocessingProps, light: Light) {
|
|
|
if (isTimingMode) this.webgl.timer.mark('PostprocessingPass.render');
|
|
|
- this.updateState(camera, transparentBackground, backgroundColor, props);
|
|
|
+ this.updateState(camera, transparentBackground, backgroundColor, props, light);
|
|
|
|
|
|
if (props.outline.name === 'on') {
|
|
|
this.outlinesTarget.bind();
|