Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Post Process Pixelate #3177

Closed
wants to merge 10 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
313 changes: 313 additions & 0 deletions examples/graphics/post-effects-private.html
@@ -0,0 +1,313 @@
<!DOCTYPE html>
<html>
<head>
<title>PlayCanvas Post Effects</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<link rel="icon" type="image/png" href="../playcanvas-favicon.png" />
<script src="../../build/playcanvas.js"></script>
<script src="../assets/scripts/asset-loader.js"></script>
<script src="../../build/playcanvas-extras.js"></script>
<style>
body {
margin: 0;
overflow-y: hidden;
}
</style>
</head>

<body>
<!-- The canvas element -->
<canvas id="application-canvas"></canvas>

<script>
var canvas = document.getElementById("application-canvas");
var app = new pc.Application(canvas, {
keyboard: new pc.Keyboard(window),
mouse: new pc.Mouse(document.body),
touch: new pc.TouchDevice(document.body)
});
app.start();

// Set the canvas to fill the window and automatically change resolution to be the same as the canvas size
app.setCanvasFillMode(pc.FILLMODE_FILL_WINDOW);
app.setCanvasResolution(pc.RESOLUTION_AUTO);

window.addEventListener("resize", function () {
app.resizeCanvas(canvas.width, canvas.height);
});

var miniStats = new pcx.MiniStats(app);

// A list of assets that need to be loaded
var assetManifest = {
statue: {
type: "container",
url: "../assets/models/statue.glb"
},
orbitCamera: {
type: "script",
url: "../../scripts/camera/orbit-camera.js"
},
bloom: {
type: "script",
url: "../../scripts/posteffects/posteffect-bloom.js"
},
bokeh: {
type: "script",
url: "../../scripts/posteffects/posteffect-bokeh.js"
},
sepia: {
type: "script",
url: "../../scripts/posteffects/posteffect-sepia.js"
},
vignette: {
type: "script",
url: "../../scripts/posteffects/posteffect-vignette.js"
},
pixelate: {
type: "script",
url: "../../scripts/posteffects/posteffect-pixelate.js"
}
};

// Load all assets and then run the example
loadManifestAssets(app, assetManifest, function () {
run();
});

function createMaterial(colors) {
var material = new pc.StandardMaterial();
for (var param in colors) {
material[param] = colors[param];
}
material.update();
return material;
}

function run() {
app.scene.ambientLight = new pc.Color(0.4, 0.4, 0.4);

// Generate some materials to assign to scene objects
var gray = createMaterial({
ambient: new pc.Color(0.1, 0.1, 0.1),
diffuse: new pc.Color(0.5, 0.5, 0.5)
});
var white = createMaterial({
emissive: new pc.Color(1, 1, 1)
});
var blue = createMaterial({
diffuse: new pc.Color(0, 0, 0),
emissive: new pc.Color(0, 0, 1)
});

entity = assetManifest["statue"].asset.resource.instantiateRenderEntity({
castShadows: true
});
app.root.addChild(entity);

// Create an Entity with a camera component
var camera = new pc.Entity();
camera.addComponent("camera", {
clearColor: new pc.Color(0.4, 0.45, 0.5),
farClip: 75
});
camera.addComponent("script");
camera.script.create("orbitCamera", {
attributes: {
distanceMin: 15,
distanceMax: 40,
inertiaFactor: 0.2 // Override default of 0 (no inertia)
}
});
camera.script.create("orbitCameraInputMouse");
camera.script.create("orbitCameraInputTouch");

camera.script.create("bloom", {
attributes: {
bloomIntensity: 1,
bloomThreshold: 0.1,
blurAmount: 4
}
});
camera.script.create("sepia", {
attributes: {
amount: 0.7
}
});
camera.script.create("vignette", {
attributes: {
darkness: 2,
offset: 1
}
});
camera.script.create("bokeh", {
attributes: {
aperture: 1,
maxBlur: 0.02
}
});
camera.script.create("pixelate", {
attributes: {
amount: 5.0
}
});

// Create an Entity for the ground
var ground = new pc.Entity();
ground.addComponent("model", {
type: "box"
});
ground.setLocalScale(50, 1, 50);
ground.setLocalPosition(0, -0.5, 0);
ground.model.material = gray;

// Create an spot light
var light = new pc.Entity();
light.addComponent("light", {
type: "spot",
color: new pc.Color(1, 1, 1),
outerConeAngle: 60,
innerConeAngle: 40,
range: 100,
intensity: 1,
castShadows: true,
shadowBias: 0.005,
normalOffsetBias: 0.01,
shadowResolution: 2048
});

var cone = new pc.Entity();
cone.addComponent("model", {
type: "cone"
});
cone.model.material = white;
light.addChild(cone);

// Create a point light
var pointlight = new pc.Entity();
pointlight.addComponent("light", {
type: "point",
color: new pc.Color(0, 0, 1),
range: 100,
intensity: 1
});
pointlight.addComponent("model", {
type: "sphere"
});
pointlight.model.material = blue;

// Add Entities into the scene hierarchy
app.root.addChild(camera);
app.root.addChild(light);
app.root.addChild(pointlight);
app.root.addChild(ground);

// Set Orbit Camera focus position
camera.script.orbitCamera.pivotPoint = new pc.Vec3(0,7, 0);
camera.script.orbitCamera.distance = 25;

// Allow user to toggle individual post effects
app.keyboard.on("keydown", function (e) {
switch (e.key) {
case pc.KEY_1:
camera.script.bloom.enabled = !camera.script.bloom.enabled;
break;
case pc.KEY_2:
camera.script.sepia.enabled = !camera.script.sepia.enabled;
break;
case pc.KEY_3:
camera.script.vignette.enabled = !camera.script.vignette.enabled;
break;
case pc.KEY_4:
camera.script.bokeh.enabled = !camera.script.bokeh.enabled;
break;
case pc.KEY_5:
camera.script.pixelate.enabled = !camera.script.pixelate.enabled;
break;
case pc.KEY_6:
camera.camera.disablePostEffectsLayer = camera.camera.disablePostEffectsLayer === pc.LAYERID_UI ? undefined : pc.LAYERID_UI;
break;
}
}, this);

// Simple update loop to rotate the light
var radius = 20;
var height = 5;
var angle = 0;

var pointRadius = 5;
var pointHeight = 10;

// Create a 2D screen
var screen = new pc.Entity();
screen.addComponent("screen", {
referenceResolution: new pc.Vec2(1280, 720),
scaleBlend: 0.5,
scaleMode: pc.SCALEMODE_BLEND,
screenSpace: true
});
app.root.addChild(screen);

// Load a font
var fontAsset = new pc.Asset('arial.json', "font", {
url: "../assets/fonts/arial.json"
});
fontAsset.on('load', onFontLoaded);
app.assets.add(fontAsset);
app.assets.load(fontAsset);

// When the font is loaded, create text to show which effects are enabled
var text;
function onFontLoaded() {
// Create a basic text element
text = new pc.Entity();
text.addComponent("element", {
anchor: new pc.Vec4(0.1, 0.1, 0.5, 0.5),
fontAsset: fontAsset,
fontSize: 28,
pivot: new pc.Vec2(0.5, 0.1),
type: pc.ELEMENTTYPE_TEXT,
alignment: pc.Vec2.ZERO
});
screen.addChild(text);
}

app.on("update", function (dt) {
angle += 20 * dt;
if (angle > 360) {
angle -= 360;
}
if (entity) {
light.lookAt(entity.getPosition());
light.rotateLocal(90, 0, 0);
light.setLocalPosition(radius * Math.sin(angle * pc.math.DEG_TO_RAD), height, radius * Math.cos(angle * pc.math.DEG_TO_RAD));

pointlight.setLocalPosition(pointRadius * Math.sin(-2 * angle * pc.math.DEG_TO_RAD), pointHeight, pointRadius * Math.cos(-2 * angle * pc.math.DEG_TO_RAD));

if (camera.script.bokeh) {
camera.script.bokeh.focus = light.getLocalPosition().z - camera.getLocalPosition().z;
}
}

// update text showing which post effects are enabled
if (text) {
text.element.text =
"[Key 1] Bloom: " + camera.script.bloom.enabled +
"\n[Key 2] Sepia: " + camera.script.sepia.enabled +
"\n[Key 3] Vignette: " + camera.script.vignette.enabled +
"\n[Key 4] Bokeh: " + camera.script.bokeh.enabled +
"\n[Key 5] Pixelate: " + camera.script.pixelate.enabled +
"\n[Key 6] Post-process UI: " + (camera.camera.disablePostEffectsLayer !== pc.LAYERID_UI);

}

// display the depth texture
if (camera.script.bokeh.enabled) {
app.renderDepthTexture(0.6, 0.7, 0.6, 0.3);
}
});
}
</script>
</body>
</html>