mirror of
https://github.com/patriciogonzalezvivo/thebookofshaders
synced 2024-11-03 23:15:23 +00:00
232 lines
7.2 KiB
HTML
232 lines
7.2 KiB
HTML
<!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 -->
|
|
<script type="text/javascript" src="https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/build/GlslCanvas.min.js"></script>
|
|
|
|
<style>
|
|
body {
|
|
background: #FFFFFF;
|
|
}
|
|
|
|
pre {
|
|
font-size: 130%;
|
|
}
|
|
|
|
canvas {
|
|
display: block;
|
|
margin-left: auto;
|
|
margin-right: auto;
|
|
border-radius: 6px;
|
|
max-width: 1200px;
|
|
width: 80%;
|
|
height: 50%;
|
|
|
|
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">
|
|
|
|
var billboard;
|
|
var editor;
|
|
// 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\
|
|
}";
|
|
|
|
// 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);
|
|
};
|
|
})();
|
|
|
|
window.addEventListener("hashchange", function () {
|
|
loadFunction()
|
|
}, false);
|
|
|
|
window.onresize = function(event) {
|
|
if (typeof window.innerWidth != 'undefined') {
|
|
billboard. = window.innerWidth
|
|
};
|
|
|
|
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);
|
|
billboard = new GlslCanvas(demoCanvas);
|
|
}
|
|
|
|
var demoEditor = document.getElementById("editor");
|
|
if (demoEditor) {
|
|
editor = CodeMirror(demoEditor,{
|
|
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(cm) {
|
|
demoCanvas.setAttribute("data-fragment", preFunction + cm.getValue() + postFunction);
|
|
billboard.load(preFunction + cm.getValue() + postFunction);
|
|
});
|
|
}
|
|
}
|
|
|
|
window.onload = function () {
|
|
loadFunction();
|
|
};
|
|
</script>
|
|
</body>
|
|
</html> |