thebookofshaders/function.html

239 lines
7.3 KiB
HTML
Raw Normal View History

2015-03-15 15:21:47 +00:00
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>GLSL Shader Code Editor</title>
<!-- CodeMirror -->
<link type='text/css' rel='stylesheet' href="src/codemirror/css/codemirror.css">
<link type='text/css' rel="stylesheet" href="src/codemirror/addon/fold/foldgutter.css">
<link type='text/css' rel="stylesheet" href="src/codemirror/addon/dialog/dialog.css">
<link type='text/css' rel="stylesheet" href="src/codemirror/addon/hint/show-hint.css">
<link type='text/css' rel="stylesheet" href="src/codemirror/theme/neo.css">
<script type="text/javascript" src="src/codemirror.js"></script>
<script type="text/javascript" src="src/codemirror/addon/search/searchcursor.js"></script>
<script type="text/javascript" src="src/codemirror/addon/search/search.js"></script>
<script type="text/javascript" src="src/codemirror/addon/dialog/dialog.js"></script>
<script type="text/javascript" src="src/codemirror/addon/edit/matchbrackets.js"></script>
<script type="text/javascript" src="src/codemirror/addon/edit/closebrackets.js"></script>
<script type="text/javascript" src="src/codemirror/addon/comment/comment.js"></script>
<script type="text/javascript" src="src/codemirror/addon/wrap/hardwrap.js"></script>
<script type="text/javascript" src="src/codemirror/addon/fold/foldcode.js"></script>
<script type="text/javascript" src="src/codemirror/addon/fold/brace-fold.js"></script>
<script type="text/javascript" src="src/codemirror/keymap/sublime.js"></script>
<script type="text/javascript" src="src/codemirror/addon/hint/show-hint.js"></script>
<script type="text/javascript" src="src/codemirror/mode/clike.js"></script>
<!-- GLSL Canvas -->
2015-07-14 14:34:43 +00:00
<script type="text/javascript" src="https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/build/GlslCanvas.min.js"></script>
2015-03-15 15:21:47 +00:00
<style>
body {
background: #FFFFFF;
}
pre {
font-size: 130%;
}
canvas {
display: block;
margin-left: auto;
margin-right: auto;
border-radius: 6px;
max-width: 800px;
overflow: hidden;
-webkit-mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC);
}
.CodeMirror {
background: #ECECEC;
font-size: 14px;
line-height: 1.5em;
display: block;
margin-left: auto;
margin-right: auto;
border-radius: 6px;
max-width: 700px;
}
</style>
</head>
<body>
<canvas id="canvas" class="center" width="800" height="320"></canvas>
<div id="editor"></div>
<script type="text/javascript">
2015-07-27 12:50:39 +00:00
var billboard;
var editor;
2015-03-15 15:21:47 +00:00
// Graph plotter function take from
// From http://blog.hvidtfeldts.net/index.php/2011/07/plotting-high-frequency-functions-using-a-gpu/
var preFunction = "\n\
#ifdef GL_ES\n\
precision mediump float;\n\
#endif\n\
\n\
#define PI 3.14159265359\n\
\n\
uniform vec2 u_resolution;\n\
uniform vec2 u_mouse;\n\
uniform float u_time;\n\
\n\
float lineJitter = 0.5;\n\
float lineWidth = 7.0;\n\
float gridWidth = 1.7;\n\
float scale = 0.0013;\n\
float zoom = 2.5;\n\
vec2 offset = vec2(0.5);\n\
\n";
var postFunction = "\n\
float rand(vec2 co){\n\
return fract(sin(dot(co.xy,vec2(12.9898,78.233)))*43758.5453);\n\
}\n\
\n\
vec3 plot2D(in vec2 _st, in float _width ) {\n\
const float samples = 3.0;\n\
\n\
vec2 steping = _width*vec2(scale)/samples;\n\
\n\
float count = 0.0;\n\
float mySamples = 0.0;\n\
for (float i = 0.0; i < samples; i++) {\n\
for (float j = 0.0;j < samples; j++) {\n\
if (i*i+j*j>samples*samples) \n\
continue;\n\
mySamples++;\n\
float ii = i + lineJitter*rand(vec2(_st.x+ i*steping.x,_st.y+ j*steping.y));\n\
float jj = j + lineJitter*rand(vec2(_st.y + i*steping.x,_st.x+ j*steping.y));\n\
float f = function(_st.x+ ii*steping.x)-(_st.y+ jj*steping.y);\n\
count += (f>0.) ? 1.0 : -1.0;\n\
}\n\
}\n\
vec3 color = vec3(1.0);\n\
if (abs(count)!=mySamples)\n\
color = vec3(abs(float(count))/float(mySamples));\n\
return color;\n\
}\n\
\n\
vec3 grid2D( in vec2 _st, in float _width ) {\n\
float axisDetail = _width*scale;\n\
if (abs(_st.x)<axisDetail || abs(_st.y)<axisDetail) \n\
return 1.0-vec3(0.65,0.65,1.0);\n\
if (abs(mod(_st.x,1.0))<axisDetail || abs(mod(_st.y,1.0))<axisDetail) \n\
return 1.0-vec3(0.80,0.80,1.0);\n\
if (abs(mod(_st.x,0.25))<axisDetail || abs(mod(_st.y,0.25))<axisDetail) \n\
return 1.0-vec3(0.95,0.95,1.0);\n\
return vec3(0.0);\n\
}\n\
\n\
void main(){\n\
vec2 st = (gl_FragCoord.xy/u_resolution.xy)-offset;\n\
st.x *= u_resolution.x/u_resolution.y;\n\
\n\
scale *= zoom;\n\
st *= zoom;\n\
\n\
vec3 color = plot2D(st,lineWidth);\n\
color -= grid2D(st,gridWidth);\n\
\n\
gl_FragColor = vec4(color,1.0);\n\
}";
2015-07-27 12:50:39 +00:00
// Events
window.requestAnimFrame = (function() {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(/* function FrameRequestCallback */ callback, /* DOMElement Element */ element) {
return window.setTimeout(callback, 1000/60);
};
})();
// Keep track of the mouse
var mouse = {x: 0, y: 0};
document.addEventListener('mousemove', function(e){
mouse.x = e.clientX || e.pageX;
mouse.y = e.clientY || e.pageY
}, false);
2015-03-15 15:21:47 +00:00
window.addEventListener("hashchange", function () {
loadFunction()
}, false);
function removeElementsByClass(className){
var elements = document.getElementsByClassName(className);
while(elements.length > 0){
elements[0].parentNode.removeChild(elements[0]);
}
}
function loadFunction(){
var func = "\n\
float function(in float x) {\n\
float y = 0.0;\n\
";
var hash = ""
if (window.location.hash !== ""){
hash = location.hash;
if(hash.search("#") === 0){
hash = hash.substr(1);
}
}
if(hash === ""){
hash = "y = x;"
}
func += hash +"\n\
return y;\n\
}\n"
removeElementsByClass("CodeMirror");
var demoCanvas = document.getElementById("canvas");
if(demoCanvas){
demoCanvas.setAttribute("data-fragment", preFunction + func + postFunction);
2015-07-27 12:50:39 +00:00
billboard = new GlslCanvas(demoCanvas);
2015-03-15 15:21:47 +00:00
}
var demoEditor = document.getElementById("editor");
2015-07-27 12:50:39 +00:00
if (demoEditor) {
editor = CodeMirror(demoEditor,{
2015-03-15 15:21:47 +00:00
value: func,
lineNumbers: false,
matchBrackets: true,
mode: "x-shader/x-fragment",
keyMap: "sublime",
autoCloseBrackets: true,
extraKeys: {"Ctrl-Space": "autocomplete"},
showCursorWhenSelecting: true,
indentUnit: 4
});
editor.on("change", function() {
demoCanvas.setAttribute("data-fragment", preFunction + editor.getValue() + postFunction);
2015-07-27 12:50:39 +00:00
billboard.load(editor.getValue());
2015-03-15 15:21:47 +00:00
});
}
}
2015-07-27 12:50:39 +00:00
function render() {
billboard.setMouse(mouse)
billboard.render()
window.requestAnimFrame(render);
}
2015-03-15 15:21:47 +00:00
window.onload = function () {
loadFunction();
2015-07-27 12:50:39 +00:00
render();
2015-03-15 15:21:47 +00:00
};
</script>
</body>
</html>