Skip to content
Snippets Groups Projects
Commit c7dad009 authored by ludovic autin's avatar ludovic autin
Browse files

fake screen space shadow, second pass ssao

parent 24317717
Branches
No related tags found
No related merge requests found
...@@ -48,7 +48,9 @@ function occlusionStyle(plugin: PluginContext) { ...@@ -48,7 +48,9 @@ function occlusionStyle(plugin: PluginContext) {
blurKernelSize: 15, blurKernelSize: 15,
radius: 5, radius: 5,
samples: 32, samples: 32,
resolutionScale: 1 resolutionScale: 1,
shadow: { name: 'off', params: {} },
closeAO: { name: 'off', params: {} }
} }, } },
outline: { name: 'on', params: { outline: { name: 'on', params: {
scale: 1.0, scale: 1.0,
......
...@@ -24,7 +24,15 @@ const Canvas3DPresets = { ...@@ -24,7 +24,15 @@ const Canvas3DPresets = {
illustrative: { illustrative: {
canvas3d: <Preset>{ canvas3d: <Preset>{
postprocessing: { postprocessing: {
occlusion: { name: 'on', params: { samples: 32, radius: 6, bias: 1.4, blurKernelSize: 15, resolutionScale: 1 } }, occlusion: { name: 'on', params: {
bias: 0.8,
blurKernelSize: 15,
radius: 5,
samples: 32,
resolutionScale: 1,
shadow: { name: 'off', params: {} },
closeAO: { name: 'off', params: {} }
} },
outline: { name: 'on', params: { scale: 1, threshold: 0.33, color: Color(0x000000) } } outline: { name: 'on', params: { scale: 1, threshold: 0.33, color: Color(0x000000) } }
}, },
renderer: { renderer: {
...@@ -36,7 +44,15 @@ const Canvas3DPresets = { ...@@ -36,7 +44,15 @@ const Canvas3DPresets = {
occlusion: { occlusion: {
canvas3d: <Preset>{ canvas3d: <Preset>{
postprocessing: { postprocessing: {
occlusion: { name: 'on', params: { samples: 32, radius: 6, bias: 1.4, blurKernelSize: 15, resolutionScale: 1 } }, occlusion: { name: 'on', params: {
bias: 0.8,
blurKernelSize: 15,
radius: 5,
samples: 32,
resolutionScale: 1,
shadow: { name: 'off', params: {} },
closeAO: { name: 'off', params: {} }
} },
outline: { name: 'off', params: {} } outline: { name: 'off', params: {} }
}, },
renderer: { renderer: {
......
...@@ -604,6 +604,8 @@ export const LoadCellPackModel = StateAction.build({ ...@@ -604,6 +604,8 @@ export const LoadCellPackModel = StateAction.build({
bias: 1, bias: 1,
blurKernelSize: 15, blurKernelSize: 15,
resolutionScale: 1, resolutionScale: 1,
shadow: { name: 'off', params: {} },
closeAO: { name: 'off', params: {} }
} }
}, },
outline: { outline: {
......
...@@ -150,7 +150,7 @@ export class DrawPass { ...@@ -150,7 +150,7 @@ export class DrawPass {
} }
} }
this.postprocessing.render(camera, false, transparentBackground, renderer.props.backgroundColor, postprocessingProps); this.postprocessing.render(camera, false, transparentBackground, renderer.props.backgroundColor, postprocessingProps, renderer.light);
} }
this.depthTextureOpaque.detachFramebuffer(this.colorTarget.framebuffer, 'depth'); this.depthTextureOpaque.detachFramebuffer(this.colorTarget.framebuffer, 'depth');
...@@ -204,7 +204,7 @@ export class DrawPass { ...@@ -204,7 +204,7 @@ export class DrawPass {
} }
} }
this.postprocessing.render(camera, false, transparentBackground, renderer.props.backgroundColor, postprocessingProps); this.postprocessing.render(camera, false, transparentBackground, renderer.props.backgroundColor, postprocessingProps, renderer.light);
} }
// render transparent primitives and volumes // render transparent primitives and volumes
...@@ -268,7 +268,7 @@ export class DrawPass { ...@@ -268,7 +268,7 @@ export class DrawPass {
} }
} }
this.postprocessing.render(camera, false, transparentBackground, renderer.props.backgroundColor, postprocessingProps); this.postprocessing.render(camera, false, transparentBackground, renderer.props.backgroundColor, postprocessingProps, renderer.light);
if (!this.packedDepth) { if (!this.packedDepth) {
this.depthTextureOpaque.attachFramebuffer(this.postprocessing.target.framebuffer, 'depth'); this.depthTextureOpaque.attachFramebuffer(this.postprocessing.target.framebuffer, 'depth');
......
...@@ -30,6 +30,8 @@ import { SmaaParams, SmaaPass } from './smaa'; ...@@ -30,6 +30,8 @@ import { SmaaParams, SmaaPass } from './smaa';
import { isTimingMode } from '../../mol-util/debug'; import { isTimingMode } from '../../mol-util/debug';
import { BackgroundParams, BackgroundPass } from './background'; import { BackgroundParams, BackgroundPass } from './background';
import { AssetManager } from '../../mol-util/assets'; import { AssetManager } from '../../mol-util/assets';
import { Light } from '../../mol-gl/renderer';
// import { debug } from 'console';
const OutlinesSchema = { const OutlinesSchema = {
...QuadSchema, ...QuadSchema,
...@@ -78,12 +80,31 @@ const SsaoSchema = { ...@@ -78,12 +80,31 @@ const SsaoSchema = {
uProjection: UniformSpec('m4'), uProjection: UniformSpec('m4'),
uInvProjection: UniformSpec('m4'), uInvProjection: UniformSpec('m4'),
uView: UniformSpec('m4'),
uBounds: UniformSpec('v4'), uBounds: UniformSpec('v4'),
uTexSize: UniformSpec('v2'), uTexSize: UniformSpec('v2'),
uRadius: UniformSpec('f'), uRadius: UniformSpec('f'),
uBias: 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>> type SsaoRenderable = ComputeRenderable<Values<typeof SsaoSchema>>
...@@ -98,12 +119,31 @@ function getSsaoRenderable(ctx: WebGLContext, depthTexture: Texture): SsaoRender ...@@ -98,12 +119,31 @@ function getSsaoRenderable(ctx: WebGLContext, depthTexture: Texture): SsaoRender
uProjection: ValueCell.create(Mat4.identity()), uProjection: ValueCell.create(Mat4.identity()),
uInvProjection: ValueCell.create(Mat4.identity()), uInvProjection: ValueCell.create(Mat4.identity()),
uView: ValueCell.create(Mat4.identity()),
uBounds: ValueCell.create(Vec4()), uBounds: ValueCell.create(Vec4()),
uTexSize: ValueCell.create(Vec2.create(ctx.gl.drawingBufferWidth, ctx.gl.drawingBufferHeight)), 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), uRadius: ValueCell.create(8.0),
uBias: ValueCell.create(0.025), 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 }; const schema = { ...SsaoSchema };
...@@ -224,6 +264,10 @@ const PostprocessingSchema = { ...@@ -224,6 +264,10 @@ const PostprocessingSchema = {
dOutlineEnable: DefineSpec('boolean'), dOutlineEnable: DefineSpec('boolean'),
dOutlineScale: DefineSpec('number'), dOutlineScale: DefineSpec('number'),
uOutlineThreshold: UniformSpec('f'), uOutlineThreshold: UniformSpec('f'),
dLightCount: DefineSpec('number'),
uLightDirection: UniformSpec('v3[]'),
uLightColor: UniformSpec('v3[]'),
}; };
type PostprocessingRenderable = ComputeRenderable<Values<typeof PostprocessingSchema>> type PostprocessingRenderable = ComputeRenderable<Values<typeof PostprocessingSchema>>
...@@ -254,6 +298,10 @@ function getPostprocessingRenderable(ctx: WebGLContext, colorTexture: Texture, d ...@@ -254,6 +298,10 @@ function getPostprocessingRenderable(ctx: WebGLContext, colorTexture: Texture, d
dOutlineEnable: ValueCell.create(false), dOutlineEnable: ValueCell.create(false),
dOutlineScale: ValueCell.create(1), dOutlineScale: ValueCell.create(1),
uOutlineThreshold: ValueCell.create(0.33), uOutlineThreshold: ValueCell.create(0.33),
dLightCount: ValueCell.create(0),
uLightDirection: ValueCell.create([]),
uLightColor: ValueCell.create([]),
}; };
const schema = { ...PostprocessingSchema }; const schema = { ...PostprocessingSchema };
...@@ -269,8 +317,24 @@ export const PostprocessingParams = { ...@@ -269,8 +317,24 @@ export const PostprocessingParams = {
samples: PD.Numeric(32, { min: 1, max: 256, step: 1 }), 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' }), 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 }), 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 }), 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({}) off: PD.Group({})
}, { cycle: true, description: 'Darken occluded crevices with the ambient occlusion effect' }), }, { cycle: true, description: 'Darken occluded crevices with the ambient occlusion effect' }),
...@@ -289,6 +353,7 @@ export const PostprocessingParams = { ...@@ -289,6 +353,7 @@ export const PostprocessingParams = {
}, { options: [['fxaa', 'FXAA'], ['smaa', 'SMAA'], ['off', 'Off']], description: 'Smooth pixel edges' }), }, { options: [['fxaa', 'FXAA'], ['smaa', 'SMAA'], ['off', 'Off']], description: 'Smooth pixel edges' }),
background: PD.Group(BackgroundParams, { isFlat: true }), background: PD.Group(BackgroundParams, { isFlat: true }),
}; };
export type PostprocessingProps = PD.Values<typeof PostprocessingParams> export type PostprocessingProps = PD.Values<typeof PostprocessingParams>
export class PostprocessingPass { export class PostprocessingPass {
...@@ -404,7 +469,7 @@ 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 needsUpdateMain = false;
let needsUpdateSsao = false; let needsUpdateSsao = false;
let needsUpdateSsaoBlur = false; let needsUpdateSsaoBlur = false;
...@@ -417,8 +482,19 @@ export class PostprocessingPass { ...@@ -417,8 +482,19 @@ export class PostprocessingPass {
Mat4.invert(invProjection, camera.projection); Mat4.invert(invProjection, camera.projection);
if (props.occlusion.name === 'on') { 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.uProjection, camera.projection);
ValueCell.update(this.ssaoRenderable.values.uInvProjection, invProjection); 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 [w, h] = this.renderable.values.uTexSize.ref.value;
const b = this.ssaoRenderable.values.uBounds; const b = this.ssaoRenderable.values.uBounds;
...@@ -456,6 +532,36 @@ export class PostprocessingPass { ...@@ -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.uRadius, Math.pow(2, props.occlusion.params.radius));
ValueCell.updateIfChanged(this.ssaoRenderable.values.uBias, props.occlusion.params.bias); 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) { if (this.blurKernelSize !== props.occlusion.params.blurKernelSize) {
needsUpdateSsaoBlur = true; needsUpdateSsaoBlur = true;
...@@ -527,6 +633,13 @@ export class PostprocessingPass { ...@@ -527,6 +633,13 @@ export class PostprocessingPass {
if (this.renderable.values.dOcclusionEnable.ref.value !== occlusionEnabled) { needsUpdateMain = true; } if (this.renderable.values.dOcclusionEnable.ref.value !== occlusionEnabled) { needsUpdateMain = true; }
ValueCell.updateIfChanged(this.renderable.values.dOcclusionEnable, occlusionEnabled); 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) { if (needsUpdateSsao) {
this.ssaoRenderable.update(); this.ssaoRenderable.update();
} }
...@@ -564,9 +677,9 @@ export class PostprocessingPass { ...@@ -564,9 +677,9 @@ export class PostprocessingPass {
this.transparentBackground = value; 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'); 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') { if (props.outline.name === 'on') {
this.outlinesTarget.bind(); this.outlinesTarget.bind();
......
...@@ -54,6 +54,7 @@ export const enum MarkingType { ...@@ -54,6 +54,7 @@ export const enum MarkingType {
interface Renderer { interface Renderer {
readonly stats: RendererStats readonly stats: RendererStats
readonly props: Readonly<RendererProps> readonly props: Readonly<RendererProps>
readonly light: Readonly<Light>
clear: (toBackgroundColor: boolean, ignoreTransparentBackground?: boolean) => void clear: (toBackgroundColor: boolean, ignoreTransparentBackground?: boolean) => void
clearDepth: (packed?: boolean) => void clearDepth: (packed?: boolean) => void
...@@ -118,7 +119,7 @@ export const RendererParams = { ...@@ -118,7 +119,7 @@ export const RendererParams = {
}; };
export type RendererProps = PD.Values<typeof RendererParams> export type RendererProps = PD.Values<typeof RendererParams>
type Light = { export type Light = {
count: number count: number
direction: number[] direction: number[]
color: number[] color: number[]
...@@ -126,7 +127,7 @@ type Light = { ...@@ -126,7 +127,7 @@ type Light = {
const tmpDir = Vec3(); const tmpDir = Vec3();
const tmpColor = Vec3(); const tmpColor = Vec3();
function getLight(props: RendererProps['light'], light?: Light): Light { export function getLight(props: RendererProps['light'], light?: Light): Light {
const { direction, color } = light || { const { direction, color } = light || {
direction: (new Array(5 * 3)).fill(0), direction: (new Array(5 * 3)).fill(0),
color: (new Array(5 * 3)).fill(0), color: (new Array(5 * 3)).fill(0),
...@@ -827,6 +828,9 @@ namespace Renderer { ...@@ -827,6 +828,9 @@ namespace Renderer {
instancedDrawCount: stats.instancedDrawCount, instancedDrawCount: stats.instancedDrawCount,
}; };
}, },
get light(): Light {
return light;
},
dispose: () => { dispose: () => {
// TODO // TODO
} }
......
...@@ -29,6 +29,18 @@ uniform vec2 uOcclusionOffset; ...@@ -29,6 +29,18 @@ uniform vec2 uOcclusionOffset;
uniform float uMaxPossibleViewZDiff; uniform float uMaxPossibleViewZDiff;
#if dLightCount != 0
uniform vec3 uLightDirection[dLightCount];
uniform vec3 uLightColor[dLightCount];
#endif
// #pragma unroll_loop_start
// for (int i = 0; i < dLightCount; ++i) {
// uLightDirection[i];
// uLightColor[i];
// }
// #pragma unroll_loop_end
const vec3 occlusionColor = vec3(0.0); const vec3 occlusionColor = vec3(0.0);
#include common #include common
......
...@@ -16,14 +16,37 @@ uniform sampler2D tDepth; ...@@ -16,14 +16,37 @@ uniform sampler2D tDepth;
uniform vec2 uTexSize; uniform vec2 uTexSize;
uniform vec4 uBounds; uniform vec4 uBounds;
uniform float uNear;
uniform float uFar;
#if dLightCount != 0
uniform vec3 uLightDirection[dLightCount];
uniform vec3 uLightColor[dLightCount];
#endif
uniform vec3 uSamples[dNSamples]; uniform vec3 uSamples[dNSamples];
uniform mat4 uProjection; uniform mat4 uProjection;
uniform mat4 uView;
uniform mat4 uInvProjection; uniform mat4 uInvProjection;
uniform float uRadius; uniform float uRadius;
uniform float uBias; uniform float uBias;
uniform float uSDistance;
uniform float uSTolerance;
uniform float uSBias;
uniform int uShadow;
uniform int uCloseAO;
uniform float uCloseBias;
uniform float uCloseDistance;
#define PI 3.14159265
#define SAMPLES_HIGH 1
#define SAMPLES_ULTRA 0
#define SAMPLE_NOISE 1
float smootherstep(float edge0, float edge1, float x) { float smootherstep(float edge0, float edge1, float x) {
x = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0); x = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
return x * x * x * (x * (x * 6.0 - 15.0) + 10.0); return x * x * x * (x * (x * 6.0 - 15.0) + 10.0);
...@@ -72,6 +95,241 @@ vec3 normalFromDepth(const in float depth, const in float depth1, const in float ...@@ -72,6 +95,241 @@ vec3 normalFromDepth(const in float depth, const in float depth1, const in float
return normalize(normal); return normalize(normal);
} }
float compareDepths( in float depth1, in float depth2 ){
float near = uNear;
float far = uFar;
float aorange = 160.0; //uniform
float depthTolerance = 0.0;//uniform
float aoMultiplier = 100.0;//uniform
float aoCap = 1.0;//uniform
float diff = sqrt(clamp(1.0-(depth1-depth2) / (aorange/(far-near)),0.0,1.0));
float ao = min(aoCap,max(0.0,depth1-depth2-depthTolerance) * aoMultiplier) * diff;
return ao;
}
float computeAO(in vec2 scrCoord){
float depth = getDepth(scrCoord);
vec2 invTexSize = 1.0 / uTexSize;
int do_noise = 0;
float scale = 1.0; //uniform
float aspect = uTexSize.x/uTexSize.y;
int rings = min(6,int(uRadius)); //uniform
int samples = min(6,int(dNSamples)); //uniform
//vec3 randomVec = normalize(vec3(getNoiseVec2(scrCoord), 0.0));
vec2 noise = getNoiseVec2(scrCoord);//getRandom(srcCoord);//
float w;
float h;
if (do_noise == 1) {
w = invTexSize.x/clamp(depth,0.05,1.0)+(noise.x*(1.0-noise.x))*scale;
h = invTexSize.y/clamp(depth,0.05,1.0)+(noise.y*(1.0-noise.y))*scale;
}
else {
w = invTexSize.x/clamp(depth,0.05,1.0)+0.001*scale;//+(noise.x*(1.0-noise.x));
h = invTexSize.y/clamp(depth,0.05,1.0)+0.001*scale;//+(noise.y*(1.0-noise.y));
}
float pw;
float ph;
float ao;
float s;
int ringsamples;
for (int i = 1; i <= rings; i += 1){
ringsamples = i * samples;
for (int j = 0 ; j < ringsamples ; j += 1) {
float step = PI*2.0 / float(ringsamples);
pw = (cos(float(j)*step)*float(i));
ph = (sin(float(j)*step)*float(i))*aspect;
float v = getDepth( vec2(scrCoord.s+pw*w,scrCoord.t+ph*h));
ao += compareDepths(depth, v);
s += 1.0;
}
}
ao /= s;
// ao = 1.0-ao;
return ao;
}
float computeOcclusion(in float aradius, in mat3 TBN, in vec3 selfViewPos ){
float occlusion = 0.0;
for(int i = 0; i < dNSamples; i++){
vec3 sampleViewPos = TBN * uSamples[i];
sampleViewPos = selfViewPos + sampleViewPos * aradius;
vec4 offset = vec4(sampleViewPos, 1.0);
offset = uProjection * offset;
offset.xyz = (offset.xyz / offset.w) * 0.5 + 0.5;
float sampleViewZ = screenSpaceToViewSpace(vec3(offset.xy, getDepth(offset.xy)), uInvProjection).z;
occlusion += step(sampleViewPos.z + 0.025, sampleViewZ) * smootherstep(0.0, 1.0, aradius / abs(selfViewPos.z - sampleViewZ));
}
return occlusion;
}
float calcAO(in vec2 tcoord, in vec2 uv, in vec3 p, in vec3 cnorm)
{
float _Bias = 0.129;
float _Intensity = uCloseBias;
float _Distance = 0.001;
vec2 t = tcoord + uv;
float depth = getDepth(t);
vec3 diff = screenSpaceToViewSpace(vec3(t, depth), uInvProjection) - p;
vec3 v = normalize(diff);
float d = length(diff) * _Distance;
// cnorm = normalize(_WorldSpaceCameraPos - p);
return max(0.0, dot(cnorm, v) - _Bias) * (1.0 / (1.0 + d)) * _Intensity;
}
float invlerp(float from, float to, float value)
{
return (value - from) / (to - from);
}
float getViewZ(const in float depth) {
#if dOrthographic == 1
return orthographicDepthToViewZ(depth, uNear, uFar);
#else
return perspectiveDepthToViewZ(depth, uNear, uFar);
#endif
}
// Gold Noise function
float PHI = 1.61803398874989484820459 * 00000.1; // Golden Ratio
float PIT = 3.14159265358979323846264 * 00000.1; // PI
float SRT = 1.41421356237309504880169 * 10000.0; // Square Root of Two
float random_0t1(in vec2 coordinate, in float seed)
{
return fract(sin(dot(coordinate*seed, vec2(PHI, PIT)))*SRT);
}
float ssao(in vec2 uv, in vec3 normal)
{
float _SampleRadius = 5.0;
float _DistanceCutoff = 100.0;
float _CutoffFalloff = 25.0;
vec2 CROSS[4] = vec2[4]( vec2(1.0, 0.0), vec2(-1.0, 0.0), vec2(0.0, 1.0), vec2(0.0, -1.0) );
float depth = getDepth(uv);
float eyeDepth = getViewZ(depth);
vec3 position = screenSpaceToViewSpace(vec3(uv, depth), uInvProjection);
float radius = uCloseDistance; // original was max(_SampleRadius / eyeDepth, 0.005);
// clip(_DistanceCutoff - eyeDepth); // Skip out of range pixels
if (_DistanceCutoff - eyeDepth < 0.0) discard;
#if defined(SAMPLE_NOISE)
float a = random_0t1(uv,depth);
float b = random_0t1(uv,eyeDepth);
vec2 random = normalize(vec2(a,b));
// original used a texture for noise
// vec2 random = normalize(tex2D(_NoiseTex, _ScreenParams.xy * uv / _NoiseSize).rg * 2.0 - 1.0);
#endif
float ao = 0.0;
// Sampling
for (int j = 0; j < 4; j++)
{
vec2 coord1;
#if defined(SAMPLE_NOISE)
coord1 = reflect(CROSS[j], random) * radius;
#else
coord1 = CROSS[j] * radius;
#endif
// #if !SAMPLES_VERY_LOW
vec2 coord2 = coord1 * 0.707;
coord2 = vec2(coord2.x - coord2.y, coord2.x + coord2.y);
// #endif
#if defined(SAMPLES_ULTRA) // 20
ao += calcAO(uv, coord1 * 0.20, position, normal);
ao += calcAO(uv, coord2 * 0.40, position, normal);
ao += calcAO(uv, coord1 * 0.60, position, normal);
ao += calcAO(uv, coord2 * 0.80, position, normal);
ao += calcAO(uv, coord1, position, normal);
#elif defined(SAMPLES_HIGH) // 16
ao += calcAO(uv, coord1 * 0.25, position, normal);
ao += calcAO(uv, coord2 * 0.50, position, normal);
ao += calcAO(uv, coord1 * 0.75, position, normal);
ao += calcAO(uv, coord2, position, normal);
#elif defined(SAMPLES_MEDIUM) // 12
ao += calcAO(uv, coord1 * 0.30, position, normal);
ao += calcAO(uv, coord2 * 0.60, position, normal);
ao += calcAO(uv, coord1 * 0.90, position, normal);
#elif defined(SAMPLES_LOW ) // 8
ao += calcAO(uv, coord1 * 0.30, position, normal);
ao += calcAO(uv, coord2 * 0.80, position, normal);
#else // 4
ao += calcAO(uv, coord1 * 0.50, position, normal);
#endif
}
#if SAMPLES_ULTRA
ao /= 20.0;
#elif SAMPLES_HIGH
ao /= 16.0;
#elif SAMPLES_MEDIUM
ao /= 12.0;
#elif SAMPLES_LOW
ao /= 8.0;
#else
ao /= 4.0;
#endif
// Distance cutoff
ao = mix(1.0 - ao, 1.0, saturate(invlerp(_DistanceCutoff - _CutoffFalloff, _DistanceCutoff, eyeDepth)));
return ao;
}
float ScreenSpaceShadows(in vec2 uv, in vec3 position, in vec3 light_direction)
{
// Settings
int g_sss_steps = dSSample; // Quality/performancedNSamples
float g_sss_ray_max_distance = uSDistance; // Max shadow length
float g_sss_tolerance = uSTolerance; // Error in favor of reducing gaps
float g_sss_step_length = g_sss_ray_max_distance / float(g_sss_steps);
float uvdepth = getDepth(uv);
float eyeDepth = getViewZ(uvdepth);
// Compute ray position and direction (in view-space)
vec3 ray_pos = position;
vec3 ray_dir = -light_direction; //light direction in View space
vec2 uv_pos = uv;
// Compute ray step
vec3 ray_step = ray_dir * g_sss_step_length;
vec2 uv_step = ray_dir.xy * g_sss_step_length;
// Ray march towards the light
float occlusion = 0.0;
vec4 ray_uv = vec4(0.0,0.0,0.0,0.0);
for (int i = 0; i < g_sss_steps; i++)
{
// Step the ray
uv_pos += uv_step;
ray_pos += ray_step;
// Compute the difference between the ray's and the camera's depth
ray_uv = (uProjection * vec4(ray_pos,1.0));
ray_uv.xyz = (ray_uv.xyz / ray_uv.w) * 0.5 + 0.5;
float depth = getDepth(ray_uv.xy);
float depth_z = getViewZ(depth);
float depth_delta = ray_pos.z - depth_z;
if (depth_delta < g_sss_tolerance){
// original test : if (abs(g_sss_tolerance - depth_delta) < g_sss_tolerance){
occlusion = 1.0;
vec2 fade = max(12.0 * abs(ray_uv.xy - 0.5) - 5.0, vec2(0.0,0.0));
occlusion *= saturate(1.0 - dot(fade, fade));
break;
}
}
// Fade out as we approach the edges of the screen
// occlusion *= screen_fade(ray_uv);return 1.0 - occlusion;
occlusion = 1.0 - (uSBias * occlusion);
return occlusion;
}
// StarCraft II Ambient Occlusion by [Filion and McNaughton 2008] // StarCraft II Ambient Occlusion by [Filion and McNaughton 2008]
void main(void) { void main(void) {
vec2 invTexSize = 1.0 / uTexSize; vec2 invTexSize = 1.0 / uTexSize;
...@@ -100,23 +358,40 @@ void main(void) { ...@@ -100,23 +358,40 @@ void main(void) {
vec3 bitangent = cross(selfViewNormal, tangent); vec3 bitangent = cross(selfViewNormal, tangent);
mat3 TBN = mat3(tangent, bitangent, selfViewNormal); mat3 TBN = mat3(tangent, bitangent, selfViewNormal);
float occlusion = 0.0; float occlusion = computeOcclusion(uRadius, TBN, selfViewPos);
for(int i = 0; i < dNSamples; i++){
vec3 sampleViewPos = TBN * uSamples[i];
sampleViewPos = selfViewPos + sampleViewPos * uRadius;
vec4 offset = vec4(sampleViewPos, 1.0);
offset = uProjection * offset;
offset.xyz = (offset.xyz / offset.w) * 0.5 + 0.5;
float sampleViewZ = screenSpaceToViewSpace(vec3(offset.xy, getDepth(offset.xy)), uInvProjection).z;
occlusion += step(sampleViewPos.z + 0.025, sampleViewZ) * smootherstep(0.0, 1.0, uRadius / abs(selfViewPos.z - sampleViewZ));
}
occlusion = 1.0 - (uBias * occlusion / float(dNSamples)); occlusion = 1.0 - (uBias * occlusion / float(dNSamples));
vec2 packedOcclusion = packUnitIntervalToRG(occlusion); /*
// alternative ao algo
float ao = computeAO(selfCoords);
ao = clamp(ao,0.0,1.0);
if ( ao > 1.0 ) {ao = 1.0 ;}
if ( ao < 0.0 ) {ao = 0.0 ;}
if (selfDepth > 1.0 ) {ao = 1.0 ;}
if (selfDepth < 0.0 ) {ao = 0.0 ;}
ao = 1.0 - (uBias * ao);
*/
float ao = 1.0;
if (uCloseAO == 1){
ao = saturate(ssao(selfCoords, selfViewNormal));
}
float o = 9999.9;
if (uShadow == 1) {
#if dLightCount != 0
float sh[dLightCount];
#pragma unroll_loop_start
for (int i = 0; i < dLightCount; ++i) {
sh[i] = ScreenSpaceShadows(selfCoords, selfViewPos, uLightDirection[i]);
o = min(o,min(min(sh[i],ao),occlusion));
}
#pragma unroll_loop_end
#endif
}
else{
o = min(ao,occlusion);
}
vec2 packedOcclusion = packUnitIntervalToRG(o);
gl_FragColor = vec4(packedOcclusion, selfPackedDepth); gl_FragColor = vec4(packedOcclusion, selfPackedDepth);
} }
`; `;
\ No newline at end of file
...@@ -60,8 +60,8 @@ export class QuickStyles extends PurePluginUIComponent { ...@@ -60,8 +60,8 @@ export class QuickStyles extends PurePluginUIComponent {
}, },
occlusion: { occlusion: {
name: 'on', name: 'on',
params: { bias: 0.8, blurKernelSize: 15, radius: 5, samples: 32, resolutionScale: 1 } params: { bias: 0.8, blurKernelSize: 15, radius: 5, samples: 32, resolutionScale: 1, shadow: { name: 'off', params: {} }, closeAO: { name: 'off', params: {} } }
}, }
} }
}); });
} }
...@@ -79,13 +79,15 @@ export class QuickStyles extends PurePluginUIComponent { ...@@ -79,13 +79,15 @@ export class QuickStyles extends PurePluginUIComponent {
params: pp.outline.name === 'on' params: pp.outline.name === 'on'
? pp.outline.params ? pp.outline.params
: { scale: 1, color: Color(0x000000), threshold: 0.33 } : { scale: 1, color: Color(0x000000), threshold: 0.33 }
}, }
/*
occlusion: { occlusion: {
name: 'on', name: 'on',
params: pp.occlusion.name === 'on' params: pp.occlusion.name === 'on'
? pp.occlusion.params ? pp.occlusion.params
: { bias: 0.8, blurKernelSize: 15, radius: 5, samples: 32, resolutionScale: 1 } : { bias: 0.8, blurKernelSize: 15, radius: 5, samples: 32, resolutionScale: 1, shadow: { name: 'off', params: {} }, closeAO: { name: 'off', params: {}} }
}, },
*/
} }
}); });
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment