Silhouette (Filter)
worldNormal with Laplace filter
by jmcjc5u
HTML
<div id="info">
<br> Silhouette
<br> (worldNormalPlot + Laplace filter)
</div>
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<!-- shader for worldNormal Plot -->
<script id="vsNormal" type="x-shader/x-vertex">
varying vec3 vNormal;
void main() {
gl_Position = projectionMatrix* modelViewMatrix * vec4( position, 1.0);
//vNormal = normalMatrix*normal;
vNormal = normal;
}
</script>
<script id="fsNormal" type="x-shader/x-fragment">
varying vec3 vNormal;
void main() {
vec3 color = (vNormal+1.0)/2.;
gl_FragColor = vec4 (color,1);
}
</script>
<!-- shader for Lapace filter -->
<!-- with background discard -->
<script id="vsFilter" type="x-shader/x-vertex">
varying vec2 vUv;
void main() {
gl_Position = projectionMatrix* modelViewMatrix * vec4( position, 1.0);
vUv = uv;
}
</script>
<script id="fsFilter" type="x-shader/x-fragment">
uniform sampler2D mytex;
uniform int imageSize;
varying vec2 vUv;
//http://stackoverflow.com/questions/15262729/const-float-array-in-webgl-shader
void main() {
float step_w = 1.0/float(imageSize);
float step_h = 1.0/float(imageSize);
// Laplace filter
float kernel[9];
kernel[0] = kernel[2] = kernel[6] = kernel[8] = 0.0/1.0;
kernel[1] = kernel[3] = kernel[5] = kernel[7] = 1.0/1.0;
kernel[4] = -4.0/1.0;
vec2 offset[9];
offset[0]=vec2(-step_w, -step_h);
offset[1]=vec2(0.0, -step_h); offset[2]= vec2(step_w, -step_h),
offset[3]=vec2(-step_w, 0.0), offset[4]=vec2(0.0, 0.0), offset[5]=vec2(step_w, 0.0),
offset[6]=vec2(-step_w, step_h), offset[7]=vec2(0.0, step_h), offset[8]=vec2(step_w, step_h);
vec3 sum= vec3(0.0);
for (int i=0 ; i < 9; i++) {
vec3 tmp=texture2D (mytex, vUv+offset[i]).rgb;
sum += tmp*kernel[i];
}
if ((sum.r+sum.g+sum.b)/3.0 < 0.1)
discard;
else
gl_FragColor = vec4 (0,0,0, 1.0);
}
</script>
CSS
body {
background-color: #fff;
color: #111;
margin: 0px;
overflow: hidden;
font-family: Monospace;
font-size: 20px;
position: absolute;
}
#info {
position: absolute;
top: 0px;
width: 100%;
padding: 5px;
text-align: center;
color: #ffff00
}
JavaScript
var scene, renderer, camera;
var material_shh;
var sceneRTT, cameraRTT;
var renderTarget;
init();
animate();
function init() {
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
renderer.setClearColor(0x888888);
renderer.autoClear = false;
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 10000);
camera.position.set (0, 80, 400);
let controls = new THREE.OrbitControls(camera, renderer.domElement);
var pointLight = new THREE.PointLight(0xffffff);
pointLight.position.set(0, 300, 200);
scene.add(pointLight);
var ambientLight = new THREE.AmbientLight(0x555555);
scene.add(ambientLight);
window.addEventListener('resize', onWindowResize, false);
//////////////////////////////////////////////////////////////
var normalVS = document.getElementById('vsNormal').innerHTML;
var normalFS = document.getElementById('fsNormal').innerHTML;
var material_shh_normal = new THREE.ShaderMaterial({
vertexShader: normalVS,
fragmentShader: normalFS
});
scene0 = new THREE.Scene();
var mesh = new THREE.Mesh (new THREE.TorusKnotGeometry( 10, 3, 100, 16 ),
material_shh_normal);
mesh.scale.set (5,5,5);
scene0.add (mesh);
////////////////////////////////////////////////////////
renderTarget = new THREE.WebGLRenderTarget(
1024,1024, // size of the FBO
{ minFilter: THREE.LinearFilter, magFilter: THREE.NearestFilter, format: THREE.RGBFormat }
);
var uniforms = {
imageSize: {
type: 'i',
value: 1024
},
mytex: {
type: 't',
value: renderTarget.texture
}
};
var filterVS = document.getElementById('vsFilter').innerHTML;
var filterFS = document.getElementById('fsFilter').innerHTML;
material_shh = new THREE.ShaderMaterial({
uniforms: uniforms,
vertexShader: filterVS,
fragmentShader:...