|
84 | 84 | border: solid black 2px;
|
85 | 85 | }
|
86 | 86 | </style>
|
87 |
| -<link type="text/css" href="../jquery-ui-1.8.2.custom/css/ui-lightness/jquery-ui-1.8.2.custom.css" rel="stylesheet" /> |
88 |
| -<script type="text/javascript" src="../jquery-ui-1.8.2.custom/js/jquery-1.4.2.min.js"></script> |
89 |
| -<script type="text/javascript" src="../jquery-ui-1.8.2.custom/js/jquery-ui-1.8.2.custom.min.js"></script> |
90 |
| -<script type="text/javascript" src="../tdl/base.js"></script> |
91 |
| -<script type="text/javascript"> |
| 87 | +</head> |
| 88 | +<body> |
| 89 | +<div id="info"> |
| 90 | + <div><a href="http://threedlibrary.googlecode.com" target="_blank">tdl.js</a> - color adjust</div> |
| 91 | + <div><a href="http://www.youtube.com/watch?v=rfQ8rKGTVlg#t=25m03s">click here to see how it works</a></div> |
| 92 | +</div> |
| 93 | +<div id="uiContainer"> |
| 94 | + <div>Adjustment</div> |
| 95 | + <div id="adjustments"> |
| 96 | + <div><input type="checkbox" value="false" id="nearest"><label for="nearest">nearest</label></div> |
| 97 | + </div> |
| 98 | +</div> |
| 99 | +<div id="viewContainer"> |
| 100 | +<canvas id="canvas" width="1024" height="1024" style="width: 100%; height: 100%;"></canvas> |
| 101 | +</div> |
| 102 | + <div style="display:none;"> |
| 103 | + <video id="vid"> |
| 104 | + <!-- |
| 105 | + <source src="http://studio.html5rocks.com/samples/video-player/chromeicon.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"' /> |
| 106 | + <source src="http://videos-cdn.mozilla.net/firefox/3.6/getpersonas.ogv" type='video/ogg; codecs="theora, vorbis"' /> |
| 107 | + <source src="sample-video.theora.ogv" type='video/ogg; codecs="theora, vorbis"' /> |
| 108 | + --> |
| 109 | + <source src="sample-video.theora.ogv" type='video/ogg; codecs="theora, vorbis"' /> |
| 110 | + <source src="sample-video.webmvp8.webm" type='video/webm; codecs="vp8, vorbis"' /> |
| 111 | + <source src="sample-video.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"' /> |
| 112 | + </video> |
| 113 | + </div> |
| 114 | +</body> |
| 115 | +<!-- ===[ basic ]============================================== --> |
| 116 | +<script id="basicVertexShader" type="text/something-not-javascript"> |
| 117 | +uniform mat4 worldViewProjection; |
| 118 | +attribute vec4 position; |
| 119 | +attribute vec2 texCoord; |
| 120 | +varying vec2 v_texCoord; |
| 121 | +void main() { |
| 122 | + gl_Position = worldViewProjection * position; |
| 123 | + v_texCoord = texCoord; |
| 124 | +} |
| 125 | +</script> |
| 126 | +<script id="basicFragmentShader" type="text/something-not-javascript"> |
| 127 | +precision mediump float; |
| 128 | +uniform sampler2D texture; |
| 129 | +varying vec2 v_texCoord; |
| 130 | +void main() { |
| 131 | + gl_FragColor = texture2D(texture, v_texCoord); |
| 132 | +} |
| 133 | +</script> |
| 134 | +<!-- ===[ colorAdjust ]============================================== --> |
| 135 | +<script id="colorAdjustVertexShader" type="text/something-not-javascript"> |
| 136 | +attribute vec4 position; |
| 137 | +attribute vec2 texCoord; |
| 138 | +varying vec2 v_texCoord; |
| 139 | +void main() { |
| 140 | + gl_Position = position; |
| 141 | + v_texCoord = texCoord; |
| 142 | +} |
| 143 | +</script> |
| 144 | +<script id="colorAdjustFragmentShader" type="text/something-not-javascript"> |
| 145 | +precision mediump float; |
| 146 | +uniform float mixAmount; |
| 147 | +uniform sampler2D inTexture; |
| 148 | +uniform sampler2D colorCube0; |
| 149 | +uniform sampler2D colorCube1; |
| 150 | +varying vec2 v_texCoord; |
| 151 | + |
| 152 | +vec4 sampleAs3DTexture(sampler2D tex, vec3 texCoord, float size) { |
| 153 | + float sliceSize = 1.0 / size; // space of 1 slice |
| 154 | + float slicePixelSize = sliceSize / size; // space of 1 pixel |
| 155 | + float sliceInnerSize = slicePixelSize * (size - 1.0); // space of size pixels |
| 156 | + float zSlice0 = min(floor(texCoord.z * size), size - 1.0); |
| 157 | + float zSlice1 = min(zSlice0 + 1.0, size - 1.0); |
| 158 | + float xOffset = slicePixelSize * 0.5 + texCoord.x * sliceInnerSize; |
| 159 | + float s0 = xOffset + (zSlice0 * sliceSize); |
| 160 | + float s1 = xOffset + (zSlice1 * sliceSize); |
| 161 | + vec4 slice0Color = texture2D(tex, vec2(s0, texCoord.y)); |
| 162 | + vec4 slice1Color = texture2D(tex, vec2(s1, texCoord.y)); |
| 163 | + float zOffset = mod(texCoord.z * size, 1.0); |
| 164 | + #if defined(USE_NEAREST) |
| 165 | + return mix(slice0Color, slice1Color, step(0.5, zOffset)); |
| 166 | + #else |
| 167 | + return mix(slice0Color, slice1Color, zOffset); |
| 168 | + #endif |
| 169 | +} |
| 170 | + |
| 171 | +void main() { |
| 172 | + vec4 originalColor = texture2D(inTexture, v_texCoord); |
| 173 | + vec4 color0 = sampleAs3DTexture(colorCube0, originalColor.rgb, 8.0); |
| 174 | + vec4 color1 = sampleAs3DTexture(colorCube1, originalColor.rgb, 8.0); |
| 175 | + gl_FragColor = vec4(mix(color0, color1, mixAmount).rgb, originalColor.a); |
| 176 | +} |
| 177 | +</script> |
| 178 | +<script src="../tdl/base.js"></script> |
| 179 | +<script> |
92 | 180 | tdl.require('tdl.buffers');
|
93 | 181 | tdl.require('tdl.fast');
|
94 | 182 | tdl.require('tdl.framebuffers');
|
|
112 | 200 | var g_setCountElements = [];
|
113 | 201 | var g_autoSet = true;
|
114 | 202 | var g_autoSetting = 0;
|
| 203 | +var g_useNearest = false; |
115 | 204 | var g_videoTexture;
|
116 | 205 | var g_colorCube0Texture;
|
117 | 206 | var g_colorCube1Texture;
|
|
120 | 209 | var g_mixAmount = 0;
|
121 | 210 | var g_eyeClock = 0;
|
122 | 211 |
|
| 212 | +var g_adjustmentNames; |
123 | 213 | var g_mixDuration = 1;
|
124 | 214 | var g_applyColorAdjust = true;
|
125 | 215 | var g_targetHeight = 0.0;
|
|
137 | 227 | { name: 'sepia', url: "adjustments/sepia.png" },
|
138 | 228 | { name: 'saturated', url: "adjustments/saturated.png", },
|
139 | 229 | { name: 'posterize', url: "adjustments/posterize.png", },
|
| 230 | + { name: 'posterize-3-rgb',url: "adjustments/posterize-3-rgb.png", }, |
| 231 | + { name: 'posterize-3-lab',url: "adjustments/posterize-3-lab.png", }, |
| 232 | + { name: 'posterize-4-lab',url: "adjustments/posterize-4-lab.png", }, |
| 233 | + { name: 'posterize-more', url: "adjustments/posterize-more.png", }, |
140 | 234 | { name: 'inverse', url: "adjustments/inverse.png", },
|
141 | 235 | { name: 'color negative', url: "adjustments/color-negative.png", },
|
142 | 236 | { name: 'high contrast', url: "adjustments/high-contrast-bw.png", },
|
|
242 | 336 | colorCube0: g_colorCubeTexture0,
|
243 | 337 | colorCube1: g_colorCubeTexture1
|
244 | 338 | };
|
245 |
| - var program = tdl.programs.loadProgramFromScriptTags( |
246 |
| - 'colorAdjustVertexShader', |
247 |
| - 'colorAdjustFragmentShader'); |
| 339 | + |
248 | 340 | var arrays = tdl.primitives.createPlane(2, 2, 1, 1);
|
249 | 341 | tdl.primitives.reorient(arrays,
|
250 | 342 | [1, 0, 0, 0,
|
251 | 343 | 0, 0,-1, 0,
|
252 | 344 | 0, 1, 0, 0,
|
253 | 345 | 0, 0, 0, 1]);
|
254 | 346 | delete arrays.normal;
|
255 |
| - return new tdl.models.Model(program, arrays, textures); |
| 347 | + |
| 348 | + const models = []; |
| 349 | + for (var i = 0; i < 2; ++i) { |
| 350 | + var program = tdl.programs.loadProgram( |
| 351 | + document.querySelector('#colorAdjustVertexShader').text, |
| 352 | + (i ? '#define USE_NEAREST 1\n' : '') + |
| 353 | + document.querySelector('#colorAdjustFragmentShader').text); |
| 354 | + models.push(new tdl.models.Model(program, arrays, textures)); |
| 355 | + } |
| 356 | + return models; |
256 | 357 | }
|
257 | 358 |
|
258 | 359 | function initialize() {
|
|
303 | 404 | tdl.log("setupAdjustments")
|
304 | 405 | var loadingCount = 1;
|
305 | 406 | var adjustmentsElement = document.getElementById("adjustments");
|
306 |
| - for (var ii = 0; ii < g_adjustmentImages.length; ++ii) { |
| 407 | + g_adjustmentNames = g_adjustmentImages.map(function(info, ii) { |
307 | 408 | ++loadingCount;
|
308 |
| - var info = g_adjustmentImages[ii]; |
309 | 409 | var div = document.createElement("div");
|
310 | 410 | info.div = div;
|
311 | 411 | div.innerHTML = info.name;
|
|
331 | 431 | });
|
332 | 432 | }
|
333 | 433 | }(img, info);
|
334 |
| - } |
| 434 | + return info.name; |
| 435 | + }); |
335 | 436 | loadingCount--;
|
336 | 437 | }
|
337 | 438 |
|
| 439 | +function parseQuery(s) { |
| 440 | + const q = {}; |
| 441 | + s.substring(s.startsWith('?') ? 1 : 0).split('&').forEach(pair => { |
| 442 | + const parts = pair.split('=').map(decodeURIComponent); |
| 443 | + q[parts[0]] = parts[1]; |
| 444 | + }); |
| 445 | + return q; |
| 446 | +} |
| 447 | + |
338 | 448 | function continueSetup() {
|
339 | 449 | var mainFBO = tdl.framebuffers.createFramebuffer(canvas.width, canvas.height, true);
|
340 | 450 | var videoPlane = setupPlane();
|
341 |
| - var colorAdjustPlane = setupColorAdjustPlane(mainFBO.texture); |
| 451 | + var colorAdjustPlanes = setupColorAdjustPlane(mainFBO.texture); |
342 | 452 | var rtPlane = setupRTPlane(mainFBO.texture);
|
343 | 453 |
|
344 | 454 | var projection = new Float32Array(16);
|
|
369 | 479 | var copyVideo = false;
|
370 | 480 | var madeVideoTexture = false;
|
371 | 481 | var video = document.getElementById("vid");
|
372 |
| - video.addEventListener("playing", function() { |
373 |
| - copyVideo = true; |
| 482 | + video.addEventListener("playing", function() { |
| 483 | + copyVideo = true; |
374 | 484 | }, true);
|
375 |
| - video.addEventListener("ended", function() { |
376 |
| - video.currentTime = startTime; video.play(); |
| 485 | + video.addEventListener("ended", function() { |
| 486 | + video.currentTime = startTime; video.play(); |
377 | 487 | }, true);
|
378 |
| - video.addEventListener("error", function() { |
379 |
| - tdl.log("could not play video"); |
| 488 | + video.addEventListener("error", function() { |
| 489 | + tdl.log("could not play video"); |
380 | 490 | }, true);
|
381 | 491 | video.volume = 0;
|
382 | 492 | video.play();
|
383 | 493 |
|
384 | 494 | var showRT = false;
|
385 |
| - $(document).keypress(function(event) { |
| 495 | + document.addEventListener('keypress', function(event) { |
386 | 496 | if (event.which == 'd'.charCodeAt(0) ||
|
387 | 497 | event.which == 'D'.charCodeAt(0)) {
|
388 | 498 | showRT = !showRT;
|
389 | 499 | tdl.log(showRT);
|
390 | 500 | }
|
391 | 501 | });
|
392 | 502 |
|
393 |
| - var videoPlanePer = { |
| 503 | + const videoPlanePer = { |
394 | 504 | worldViewProjection: worldViewProjection
|
395 | 505 | };
|
396 | 506 |
|
397 |
| - var rtPlanePer = { |
| 507 | + const rtPlanePer = { |
398 | 508 | worldViewProjection: worldViewProjection
|
399 | 509 | };
|
400 | 510 |
|
| 511 | + const nearestElem = document.querySelector("#nearest"); |
| 512 | + nearestElem.addEventListener('change', function(e) { |
| 513 | + g_useNearest = e.target.checked; |
| 514 | + }); |
| 515 | + |
| 516 | + const q = parseQuery(window.location.search); |
| 517 | + |
| 518 | + if (q.nearest && q.nearest !== 'false') { |
| 519 | + g_useNearest = true; |
| 520 | + nearestElem.checked = true; |
| 521 | + } |
| 522 | + |
| 523 | + if (q.adjustment) { |
| 524 | + const ndx = g_adjustmentNames.indexOf(q.adjustment); |
| 525 | + if (ndx >= 0) { |
| 526 | + updateSelection(ndx); |
| 527 | + } |
| 528 | + } |
| 529 | + |
401 | 530 | var frameCount = 0;
|
402 | 531 | var then = (new Date()).getTime() * 0.001;
|
403 | 532 | var clock = 0.0;
|
|
504 | 633 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
|
505 | 634 | gl.disable(gl.BLEND);
|
506 | 635 | gl.disable(gl.DEPTH_TEST);
|
| 636 | + |
| 637 | + const colorAdjustPlane = g_useNearest ? colorAdjustPlanes[1] : colorAdjustPlanes[0]; |
| 638 | + |
| 639 | + const filter = g_useNearest ? gl.NEAREST : gl.LINEAR; |
| 640 | + g_colorCubeTexture0.setParameter(gl.TEXTURE_MIN_FILTER, filter); |
| 641 | + g_colorCubeTexture0.setParameter(gl.TEXTURE_MAG_FILTER, filter); |
| 642 | + g_colorCubeTexture1.setParameter(gl.TEXTURE_MIN_FILTER, filter); |
| 643 | + g_colorCubeTexture1.setParameter(gl.TEXTURE_MAG_FILTER, filter); |
| 644 | + |
507 | 645 | colorAdjustPlane.drawPrep();
|
508 | 646 | colorAdjustPlane.draw({
|
509 | 647 | mixAmount: g_mixAmount
|
|
543 | 681 | return true;
|
544 | 682 | }
|
545 | 683 |
|
546 |
| -$(function(){ |
547 |
| - initialize(); |
548 |
| -}); |
549 |
| -</script> |
550 |
| -</head> |
551 |
| -<body> |
552 |
| -<div id="info"> |
553 |
| - <div><a href="http://threedlibrary.googlecode.com" target="_blank">tdl.js</a> - color adjust</div> |
554 |
| - <div><a href="http://www.youtube.com/watch?v=rfQ8rKGTVlg#t=25m03s">click here to see how it works</a></div> |
555 |
| -</div> |
556 |
| -<div id="uiContainer"> |
557 |
| - <div>Adjustment</div> |
558 |
| - <div id="adjustments"> |
559 |
| - </div> |
560 |
| -</div> |
561 |
| -<div id="viewContainer"> |
562 |
| -<canvas id="canvas" width="1024" height="1024" style="width: 100%; height: 100%;"></canvas> |
563 |
| -</div> |
564 |
| - <div style="display:none;"> |
565 |
| - <video id="vid"> |
566 |
| - <!-- |
567 |
| - <source src="http://studio.html5rocks.com/samples/video-player/chromeicon.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"' /> |
568 |
| - <source src="http://videos-cdn.mozilla.net/firefox/3.6/getpersonas.ogv" type='video/ogg; codecs="theora, vorbis"' /> |
569 |
| - <source src="sample-video.theora.ogv" type='video/ogg; codecs="theora, vorbis"' /> |
570 |
| - --> |
571 |
| - <source src="sample-video.theora.ogv" type='video/ogg; codecs="theora, vorbis"' /> |
572 |
| - <source src="sample-video.webmvp8.webm" type='video/webm; codecs="vp8, vorbis"' /> |
573 |
| - <source src="sample-video.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"' /> |
574 |
| - </video> |
575 |
| - </div> |
576 |
| -</body> |
577 |
| -<!-- ===[ basic ]============================================== --> |
578 |
| -<script id="basicVertexShader" type="text/something-not-javascript"> |
579 |
| -uniform mat4 worldViewProjection; |
580 |
| -attribute vec4 position; |
581 |
| -attribute vec2 texCoord; |
582 |
| -varying vec2 v_texCoord; |
583 |
| -void main() { |
584 |
| - gl_Position = worldViewProjection * position; |
585 |
| - v_texCoord = texCoord; |
586 |
| -} |
587 |
| -</script> |
588 |
| -<script id="basicFragmentShader" type="text/something-not-javascript"> |
589 |
| -#ifdef GL_ES |
590 |
| -precision mediump float; |
591 |
| -#endif |
592 |
| -uniform sampler2D texture; |
593 |
| -varying vec2 v_texCoord; |
594 |
| -void main() { |
595 |
| - gl_FragColor = texture2D(texture, v_texCoord); |
596 |
| -} |
597 |
| -</script> |
598 |
| -<!-- ===[ colorAdjust ]============================================== --> |
599 |
| -<script id="colorAdjustVertexShader" type="text/something-not-javascript"> |
600 |
| -attribute vec4 position; |
601 |
| -attribute vec2 texCoord; |
602 |
| -varying vec2 v_texCoord; |
603 |
| -void main() { |
604 |
| - gl_Position = position; |
605 |
| - v_texCoord = texCoord; |
606 |
| -} |
607 |
| -</script> |
608 |
| -<script id="colorAdjustFragmentShader" type="text/something-not-javascript"> |
609 |
| -#ifdef GL_ES |
610 |
| -precision mediump float; |
611 |
| -#endif |
612 |
| -uniform float mixAmount; |
613 |
| -uniform sampler2D inTexture; |
614 |
| -uniform sampler2D colorCube0; |
615 |
| -uniform sampler2D colorCube1; |
616 |
| -varying vec2 v_texCoord; |
617 |
| - |
618 |
| -vec4 sampleAs3DTexture(sampler2D tex, vec3 texCoord, float size) { |
619 |
| - float sliceSize = 1.0 / size; // space of 1 slice |
620 |
| - float slicePixelSize = sliceSize / size; // space of 1 pixel |
621 |
| - float sliceInnerSize = slicePixelSize * (size - 1.0); // space of size pixels |
622 |
| - float zSlice0 = min(floor(texCoord.z * size), size - 1.0); |
623 |
| - float zSlice1 = min(zSlice0 + 1.0, size - 1.0); |
624 |
| - float xOffset = slicePixelSize * 0.5 + texCoord.x * sliceInnerSize; |
625 |
| - float s0 = xOffset + (zSlice0 * sliceSize); |
626 |
| - float s1 = xOffset + (zSlice1 * sliceSize); |
627 |
| - vec4 slice0Color = texture2D(tex, vec2(s0, texCoord.y)); |
628 |
| - vec4 slice1Color = texture2D(tex, vec2(s1, texCoord.y)); |
629 |
| - float zOffset = mod(texCoord.z * size, 1.0); |
630 |
| - return mix(slice0Color, slice1Color, zOffset); |
631 |
| -} |
632 |
| - |
633 |
| -void main() { |
634 |
| - vec4 originalColor = texture2D(inTexture, v_texCoord); |
635 |
| - vec4 color0 = sampleAs3DTexture(colorCube0, originalColor.rgb, 8.0); |
636 |
| - vec4 color1 = sampleAs3DTexture(colorCube1, originalColor.rgb, 8.0); |
637 |
| - gl_FragColor = vec4(mix(color0, color1, mixAmount).rgb, originalColor.a); |
638 |
| -} |
| 684 | +window.onload = initialize; |
639 | 685 | </script>
|
640 | 686 | </html>
|
641 | 687 |
|
|
0 commit comments