Skip to content

Commit

Permalink
Add AmbiantOcclusion node
Browse files Browse the repository at this point in the history
  • Loading branch information
kchapelier committed Mar 28, 2021
1 parent 721fa07 commit 96fb7ef
Show file tree
Hide file tree
Showing 3 changed files with 166 additions and 0 deletions.
103 changes: 103 additions & 0 deletions src/js/components/jobs/ambiant-occlusion.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
"use strict";

var program = null;

/**
*
* @param context
* @returns {WorkingWebGLProgram}
*/
function getProgram (context) {
if (program === null) {
program = context.createProgram(`#version 300 es
precision highp float;
precision highp int;
precision highp sampler2D;
layout(location = 0) out vec4 fragColor;
#define PIm2 6.2831853071796
uniform vec2 resolution;
uniform float seed;
uniform float amount;
uniform float size;
uniform float threshold;
uniform float power;
uniform sampler2D source;
uniform bool sourceSet;
uniform vec2 sourceSize;
const float iterationsA = 12.0;
const float iterationsR = 6.0;
float getDepth (in vec2 uv) {
return texture(source, uv).r;
}
vec4 process (in vec2 uv) {
float depthRef = getDepth(uv);
float occlusion = 0.;
float p = size / 1024. * 5.;
for (float k = 0.; k < iterationsR; k++) {
float radius = (1. + k);
float weight = 1. - pow((iterationsR - k) / iterationsR, 2.);
for (float i = 0.; i < iterationsA; i++) {
float angle = i / iterationsA * PIm2 + k;
float otherDepth = getDepth(uv + p * radius * vec2(cos(angle), sin(angle)));
float diff = (otherDepth - 0.001) - depthRef;
if (diff > 0.) {
occlusion += pow(diff, 0.5) * weight / iterationsA;
}
}
}
occlusion = clamp((occlusion - threshold) / (1. - threshold), 0., 1.);
occlusion = pow(occlusion, power);
return vec4(vec3(1. - occlusion * amount), 1.);
}
void main () {
vec2 uv = gl_FragCoord.xy / resolution;
if (sourceSet == true) {
fragColor = process(uv);
} else {
fragColor = vec4(0., 0., 0., 1.);
}
}
`, {
amount: 'f',
size: 'f',
threshold: 'f',
power: 'f',
source: 't'
});
}

return program;
}

function ambiantOcclusionJob (context, inputs, outputs, parameters, done) {
var program = getProgram(context);
var uniforms = {
source: inputs.heightmap,
amount: parameters.amount,
size: parameters.size,
threshold: parameters.threshold,
power: parameters.power
};

program.execute(uniforms, outputs.output);

done();
}

module.exports = ambiantOcclusionJob;
50 changes: 50 additions & 0 deletions src/js/components/parameters/ambiant-occlusion-parameters.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
"use strict";

const BaseParameters = require('./base-parameters');

const { getProp, extendClass } = require('../../commons/utils');

function AmbiantOcclusionParameters (name, values, callback) {
this.constructor.super.call(this, name, callback);

this.values = {
size: getProp(values, 'size', 0.5),
amount: getProp(values, 'amount', 0.5),
threshold: getProp(values, 'threshold', 0.1),
power: getProp(values, 'power', 1.0)
};
}

extendClass(AmbiantOcclusionParameters, BaseParameters);

AmbiantOcclusionParameters.prototype.initializeElements = function () {
this.setElement('size', 'range', 'Size', {
softMin: 0.2,
softMax: 1,
hardMin: 0.2,
hardMax: 3
});

this.setElement('amount', 'range', 'Amount', {
softMin: 0,
softMax: 1,
hardMin: 0,
hardMax: 1
});

this.setElement('threshold', 'range', 'Threshold', {
softMin: 0,
softMax: 1,
hardMin: 0,
hardMax: 1
});

this.setElement('power', 'range', 'Power', {
softMin: 0.5,
softMax: 2,
hardMin: 0.5,
hardMax: 10
});
};

module.exports = AmbiantOcclusionParameters;
13 changes: 13 additions & 0 deletions src/js/components/types-provider/populated-types-provider.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
const TypeProvider = require('./types-provider');
const { extendClass } = require('./../../commons/utils');

var AmbiantOcclusionParameters = require('./../parameters/ambiant-occlusion-parameters');
var AnisotropicNoiseParameters = require('./../parameters/anisotropic-noise-parameters');
var AnisotropicBlurParameters = require('./../parameters/anisotropic-blur-parameters');
var BlendParameters = require('./../parameters/blend-parameters');
Expand Down Expand Up @@ -66,6 +67,7 @@ var VibranceParameters = require('./../parameters/vibrance-parameters');
var VoronoiseParameters = require('./../parameters/voronoise-parameters');
var WarpParameters = require('./../parameters/warp-parameters');

var ambiantOcclusionJob = require('./../jobs/ambiant-occlusion');
var anisotropicBlurJob = require('./../jobs/anisotropic-blur');
var anisotropicNoiseJob = require('./../jobs/anisotropic-noise');
var blendJob = require('./../jobs/blend');
Expand Down Expand Up @@ -141,6 +143,17 @@ function PopulatedTypeProvider () {
extendClass(PopulatedTypeProvider, TypeProvider);

PopulatedTypeProvider.prototype.populate = function () {
this.registerType({
isFilter: true,
id: 'ambiant-occlusion',
name: 'Ambiant occlusion',
keywords: [ 'ssao' ],
inputs: [ 'heightmap' ],
outputs: [ 'output' ],
parameters: AmbiantOcclusionParameters,
job: ambiantOcclusionJob
});

this.registerType({
isFilter: false,
id: 'anisotropic-noise',
Expand Down

0 comments on commit 96fb7ef

Please # to comment.