Skip to content

Commit

Permalink
Tweaked SSAA options. Added example.
Browse files Browse the repository at this point in the history
  • Loading branch information
tsherif committed May 28, 2015
1 parent bf77e41 commit 707c3ff
Show file tree
Hide file tree
Showing 6 changed files with 172 additions and 12 deletions.
39 changes: 30 additions & 9 deletions api/latest/scenejs.js
Original file line number Diff line number Diff line change
Expand Up @@ -1749,11 +1749,13 @@ var SceneJS_Canvas = function (id, canvasId, contextAttr, options) {
? WebGLDebugUtils.makeLostContextSimulatingCanvas(canvas)
: canvas;

this.ssaaMultiplier = this.options.ssaaMultiplier || 1;

// If the canvas uses css styles to specify the sizes make sure the basic
// width and height attributes match or the WebGL context will use 300 x 150

this.canvas.width = this.canvas.clientWidth;
this.canvas.height = this.canvas.clientHeight;
this.canvas.width = this.canvas.clientWidth * this.ssaaMultiplier;
this.canvas.height = this.canvas.clientHeight * this.ssaaMultiplier;

/**
* Attributes given when initialising the WebGL context
Expand Down Expand Up @@ -1812,6 +1814,15 @@ SceneJS_Canvas.prototype.loseWebGLContext = function () {
}
};

/**
* Set canvas size multiplier for supersample anti-aliasing
*/
SceneJS_Canvas.prototype.setSSAAMultiplier = function (ssaaMultiplier) {
this.ssaaMultiplier = ssaaMultiplier;
this.canvas.width = this.canvas.clientWidth * ssaaMultiplier;
this.canvas.height = this.canvas.clientHeight * ssaaMultiplier;
};


/**
* @class A container for a scene graph and its display
Expand All @@ -1820,7 +1831,6 @@ SceneJS_Canvas.prototype.loseWebGLContext = function () {
* @private
*/
var SceneJS_Engine = function (json, options) {

json.type = "scene"; // The type property supplied by user on the root JSON node is ignored - would always be 'scene'

/**
Expand Down Expand Up @@ -2252,8 +2262,10 @@ SceneJS_Engine.prototype.start = function () {
// Animation frame callback
window[fnName] = function () {

width = canvas.width = canvas.clientWidth;
height = canvas.height = canvas.clientHeight;
var ssaaMultiplier = self.canvas.ssaaMultiplier || 1;

width = canvas.width = canvas.clientWidth * ssaaMultiplier;
height = canvas.height = canvas.clientHeight * ssaaMultiplier;

if (width != lastWidth || height != lastHeight) {
scene.publish("canvasSize", {
Expand Down Expand Up @@ -11876,6 +11888,13 @@ SceneJS.Scene.prototype.getZBufferDepth = function () {
return gl.getParameter(gl.DEPTH_BITS);
};

/**
* Set canvas size multiplier for supersample anti-aliasing
*/
SceneJS.Scene.prototype.setSSAAMultiplier = function (ssaaMultiplier) {
return this._engine.canvas.setSSAAMultiplier(ssaaMultiplier);
};

/**
* Sets a regular expression to select which of the scene subgraphs that are rooted by {@link SceneJS.Tag} nodes are included in scene renders
* @param {String} [tagMask] Regular expression string to match on the tag attributes of {@link SceneJS.Tag} nodes. Nothing is selected when this is omitted.
Expand Down Expand Up @@ -15278,9 +15297,10 @@ SceneJS_Display.prototype._logPickList = function () {
SceneJS_Display.prototype.pick = function (params) {

var canvas = this._canvas.canvas;
var ssaaMultiplier = this._canvas.ssaaMultiplier;
var hit = null;
var canvasX = params.canvasX;
var canvasY = params.canvasY;
var canvasX = params.canvasX * ssaaMultiplier;
var canvasY = params.canvasY * ssaaMultiplier;
var pickBuf = this.pickBuf;

// Lazy-create pick buffer
Expand Down Expand Up @@ -16782,8 +16802,9 @@ SceneJS.RenderContext.prototype.getCanvasPos = function(offset) {
this.getProjPos(offset);

var canvas = this._frameCtx.canvas.canvas;
var canvasWidth = canvas.width;
var canvasHeight = canvas.height;
var ssaaMultiplier = this._frameCtx.canvas.ssaaMultiplier;
var canvasWidth = canvas.width / ssaaMultiplier;
var canvasHeight = canvas.height / ssaaMultiplier;

/* Projection division and map to canvas
*/
Expand Down
123 changes: 123 additions & 0 deletions examples/canvas_SSAA.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>SceneJS Example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">

<style>
body {
margin: 0;
-moz-user-select: -moz-none;
-khtml-user-select: none;
-webkit-user-select: none;
}
</style>

<script src="../api/latest/scenejs.js"></script>
<link href="css/styles.css" rel="stylesheet"/>

<body>

<div id="infoDark">
<a href="http://scenejs.org" target="_other">SceneJS</a> - Super sample anti-aliasing<br>
On platforms that don't implement anti-aliasing on the WebGL context, one can use supersampling<br>
to anti-alias by rendering to a larger canvas and then scaling the canvas down using CSS.
<br>
Use the up and down arrow keys to increase or decrease supersampling multiplier for the canvas size.
<br>
Current multiplier: <span id="ssaa">2</span>
</div>

<script>

// Demonstrates how to make geometries reflective or non-reflective
//
// In the scene below, we make a geometry reflective with 1) a 'reflect'
// node with a cube map, and 2) a flags node with a 'reflective' flag,
// which allows the cube map to affect the surface's color.
//
// When the flag is false, the cube map is ignored and geometry
// then appears non-reflective.
//
// As we periodically toggle the flag, watch the geometry switch between
// reflective and non-reflective.
//
// If there is a reflect node is the sub-graph, the geometry will be
// reflective by default when 1) the flags node is omitted, or
// 2) the 'reflective' flag is not specified and defaults to true

// Point SceneJS to the bundled plugins
SceneJS.setConfigs({
pluginPath: "../api/latest/plugins"
});

var ssaaMultiplier = 2;

// Create scene
var scene = SceneJS.createScene({
contextAttr: {
antialias: false
},
nodes: [

// Orbiting camera node, implemented by plugin at
// http://scenejs.org/api/latest/plugins/node/cameras/orbit.js
{
type: "cameras/orbit",
yaw:30,
pitch:-30,
zoom:8,
zoomSensitivity:1.0,
nodes: [

{
type: "material",
color:{ r:0.3, g:0.3, b:1.0 },

// Mirror-like reflection when specular == 1.0, no reflection at all
// when specular == 0.0. We have the value at 0.8 to allow some of the
// yellowness to show through, to simulate a gold-like material.
specular: 0.8,

nodes: [

// Teapot primitive implemented by plugin at
// http://scenejs.org/api/latest/plugins/node/geometry/teapot.js
{
type: "geometry/teapot"
}
]

}
]
}
]
}, { ssaaMultiplier: ssaaMultiplier });

var ssaaElement = document.getElementById("ssaa");

window.addEventListener("keydown", function(e) {
var keyCode = e.keyCode;

if (keyCode === 38) {
ssaaMultiplier *= 2;
}

if (keyCode === 40) {
ssaaMultiplier /= 2;
}

ssaaMultiplier = Math.max(ssaaMultiplier, 1);

scene.setSSAAMultiplier(ssaaMultiplier);

if (ssaaMultiplier > 1) {
ssaaElement.innerText = ssaaMultiplier;
} else {
ssaaElement.innerText = "1 (no anti-aliasing)";
}
});
</script>
</body>
</html>
3 changes: 2 additions & 1 deletion examples/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,8 @@ <h1><a href="../index.html">SceneJS</a> / Examples</h1>
"canvas_capture_transparent",
"canvas_external",
"canvas_external_transparent",
"canvas_transparent"
"canvas_transparent",
"canvas_SSAA"
],

"Cameras": [
Expand Down
11 changes: 10 additions & 1 deletion src/core/canvas.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ var SceneJS_Canvas = function (id, canvasId, contextAttr, options) {
? WebGLDebugUtils.makeLostContextSimulatingCanvas(canvas)
: canvas;

this.ssaaMultiplier = options.ssaaMultiplier || 1;
this.ssaaMultiplier = this.options.ssaaMultiplier || 1;

// If the canvas uses css styles to specify the sizes make sure the basic
// width and height attributes match or the WebGL context will use 300 x 150
Expand Down Expand Up @@ -108,4 +108,13 @@ SceneJS_Canvas.prototype.loseWebGLContext = function () {
}
};

/**
* Set canvas size multiplier for supersample anti-aliasing
*/
SceneJS_Canvas.prototype.setSSAAMultiplier = function (ssaaMultiplier) {
this.ssaaMultiplier = ssaaMultiplier;
this.canvas.width = this.canvas.clientWidth * ssaaMultiplier;
this.canvas.height = this.canvas.clientHeight * ssaaMultiplier;
};


1 change: 0 additions & 1 deletion src/core/engine.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
* @private
*/
var SceneJS_Engine = function (json, options) {

json.type = "scene"; // The type property supplied by user on the root JSON node is ignored - would always be 'scene'

/**
Expand Down
7 changes: 7 additions & 0 deletions src/core/scene/scene.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ SceneJS.Scene.prototype.getZBufferDepth = function () {
return gl.getParameter(gl.DEPTH_BITS);
};

/**
* Set canvas size multiplier for supersample anti-aliasing
*/
SceneJS.Scene.prototype.setSSAAMultiplier = function (ssaaMultiplier) {
return this._engine.canvas.setSSAAMultiplier(ssaaMultiplier);
};

/**
* Sets a regular expression to select which of the scene subgraphs that are rooted by {@link SceneJS.Tag} nodes are included in scene renders
* @param {String} [tagMask] Regular expression string to match on the tag attributes of {@link SceneJS.Tag} nodes. Nothing is selected when this is omitted.
Expand Down

0 comments on commit 707c3ff

Please sign in to comment.