Created
May 13, 2015 13:59
-
-
Save jryans/0c2cddae0d671f6ee259 to your computer and use it in GitHub Desktop.
Cross Process Viewport // source http://jsbin.com/humogo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<title>Cross Process Viewport</title> | |
<script id="shader-vs" type="x-shader/x-vertex"> | |
uniform mat4 uMatrixProj; | |
uniform vec4 uLayerRects[4]; | |
uniform mat4 uLayerTransform; | |
uniform vec4 uRenderTargetOffset; | |
attribute vec4 aCoord; | |
uniform mat4 uTextureTransform; | |
uniform vec4 uTextureRects[4]; | |
varying vec2 vTexCoord; | |
void main() { | |
int vertexID = int(aCoord.w); | |
vec4 layerRect = uLayerRects[vertexID]; | |
vec4 finalPosition = vec4(aCoord.xy * layerRect.zw + layerRect.xy, 0.0, 1.0); | |
finalPosition = uLayerTransform * finalPosition; | |
finalPosition.xyz /= finalPosition.w; | |
finalPosition = finalPosition - uRenderTargetOffset; | |
finalPosition.xyz *= finalPosition.w; | |
finalPosition = uMatrixProj * finalPosition; | |
vec4 textureRect = uTextureRects[vertexID]; | |
vec2 texCoord = aCoord.xy * textureRect.zw + textureRect.xy; | |
vTexCoord = (uTextureTransform * vec4(texCoord, 0.0, 1.0)).xy; | |
gl_Position = finalPosition; | |
} | |
</script> | |
<script id="shader-fs" type="x-shader/x-fragment"> | |
#extension GL_ARB_texture_rectangle : require | |
#ifdef GL_ES | |
precision mediump float; | |
#define COLOR_PRECISION lowp | |
#else | |
#define COLOR_PRECISION | |
#endif | |
varying vec2 vTexCoord; | |
uniform vec2 uTexCoordMultiplier; | |
uniform sampler2DRect uTexture; | |
vec4 sample(vec2 coord) { | |
vec4 color; | |
color = texture2DRect(uTexture, coord); | |
return color; | |
} | |
void main() { | |
vec4 color = sample(vTexCoord * uTexCoordMultiplier); | |
COLOR_PRECISION float mask = 1.0; | |
color *= mask; | |
gl_FragColor = color; | |
} | |
</script> | |
</head> | |
<body onload="go()"> | |
<canvas></canvas> | |
<script id="jsbin-javascript"> | |
var WIDTH = 640; | |
var HEIGHT = 960; | |
var SURFACE = 0x13; | |
function go() { | |
var canvas = document.querySelector("canvas"); | |
setCanvasSize(canvas); | |
window.gl = canvas.getContext("webgl"); | |
initFeatures(); | |
initShaders(); | |
initBuffers(); | |
initUniforms(); | |
initTextures(); | |
requestAnimationFrame(draw); | |
} | |
function draw() { | |
gl.viewport(0, 0, WIDTH, HEIGHT); | |
gl.bindBuffer(gl.ARRAY_BUFFER, verticesBuffer); | |
gl.vertexAttribPointer(coordAttribute, 4, gl.FLOAT, false, 0, 0); | |
gl.drawArrays(gl.TRIANGLES, 0, 6); | |
requestAnimationFrame(draw); | |
} | |
function initTextures() { | |
var texture = gl.createTexture(); | |
gl.bindTexture(gl.TEXTURE_RECTANGLE, texture); | |
gl.texImageIOSurface2D(WIDTH, HEIGHT, SURFACE); | |
gl.texParameteri(gl.TEXTURE_RECTANGLE, gl.TEXTURE_MIN_FILTER, gl.LINEAR); | |
gl.texParameteri(gl.TEXTURE_RECTANGLE, gl.TEXTURE_MAG_FILTER, gl.LINEAR); | |
gl.texParameteri(gl.TEXTURE_RECTANGLE, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); | |
gl.texParameteri(gl.TEXTURE_RECTANGLE, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); | |
} | |
function setCanvasSize(canvas) { | |
canvas.width = WIDTH; | |
canvas.height = HEIGHT; | |
canvas.style.width = (WIDTH / devicePixelRatio) + "px"; | |
canvas.style.height = (HEIGHT / devicePixelRatio) + "px"; | |
} | |
function initFeatures() { | |
gl.blendFuncSeparate(gl.ONE, gl.ONE_MINUS_SRC_ALPHA, | |
gl.ONE, gl.ONE); | |
gl.enable(gl.BLEND); | |
} | |
function initBuffers() { | |
verticesBuffer = gl.createBuffer(); | |
gl.bindBuffer(gl.ARRAY_BUFFER, verticesBuffer); | |
var vertices = [ | |
0.0, 0.0, 0.0, 0.0, | |
1.0, 0.0, 0.0, 0.0, | |
0.0, 1.0, 0.0, 0.0, | |
1.0, 0.0, 0.0, 0.0, | |
0.0, 1.0, 0.0, 0.0, | |
1.0, 1.0, 0.0, 0.0, | |
]; | |
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); | |
} | |
function initUniforms() { | |
var loc; | |
var layerRects = [ | |
0, 0, WIDTH, HEIGHT, | |
0, 0, 0, 0, | |
0, 0, 0, 0, | |
0, 0, 0, 0, | |
]; | |
loc = gl.getUniformLocation(shaderProgram, "uLayerRects"); | |
gl.uniform4fv(loc, new Float32Array(layerRects)); | |
var textureRects = [ | |
0, 0, 1, 1, | |
0, 0, 0, 0, | |
0, 0, 0, 0, | |
0, 0, 0, 0, | |
]; | |
loc = gl.getUniformLocation(shaderProgram, "uTextureRects"); | |
gl.uniform4fv(loc, new Float32Array(textureRects)); | |
var renderOffset = [ | |
0, 0, 0, 0, | |
]; | |
loc = gl.getUniformLocation(shaderProgram, "uRenderTargetOffset"); | |
gl.uniform4fv(loc, new Float32Array(renderOffset)); | |
var textureTransformVals = [ | |
1, 0, 0, 0, | |
0, -1, 0, 0, | |
0, 0, 1, 0, | |
0, 1, 0, 1, | |
]; | |
loc = gl.getUniformLocation(shaderProgram, "uTextureTransform"); | |
gl.uniformMatrix4fv(loc, false, new Float32Array(textureTransformVals)); | |
var layerTransformVals = [ | |
1, 0, 0, 0, | |
0, 1, 0, 0, | |
0, 0, 1, 0, | |
0, 0, 0, 1, | |
]; | |
loc = gl.getUniformLocation(shaderProgram, "uLayerTransform"); | |
gl.uniformMatrix4fv(loc, false, new Float32Array(layerTransformVals)); | |
var texCoordMultiplier = [ | |
WIDTH, HEIGHT, | |
]; | |
loc = gl.getUniformLocation(shaderProgram, "uTexCoordMultiplier"); | |
gl.uniform2fv(loc, new Float32Array(texCoordMultiplier)); | |
var projectionVals = [ | |
2 / WIDTH, 0, 0, 0, | |
0, -2 / HEIGHT, 0, 0, | |
0, 0, 0, 0, | |
-1, 1, 0, 1, | |
]; | |
loc = gl.getUniformLocation(shaderProgram, "uMatrixProj"); | |
gl.uniformMatrix4fv(loc, false, new Float32Array(projectionVals)); | |
loc = gl.getUniformLocation(shaderProgram, "uTexture"); | |
gl.uniform1i(loc, 0); | |
} | |
function initShaders() { | |
var fragmentShader = getShader(gl, "shader-fs"); | |
var vertexShader = getShader(gl, "shader-vs"); | |
// Create the shader program | |
shaderProgram = gl.createProgram(); | |
gl.attachShader(shaderProgram, vertexShader); | |
gl.attachShader(shaderProgram, fragmentShader); | |
gl.linkProgram(shaderProgram); | |
// If creating the shader program failed, alert | |
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { | |
alert("Unable to initialize the shader program."); | |
} | |
gl.useProgram(shaderProgram); | |
coordAttribute = gl.getAttribLocation(shaderProgram, "aCoord"); | |
gl.enableVertexAttribArray(coordAttribute); | |
} | |
function getShader(gl, id) { | |
var shaderScript, theSource, currentChild, shader; | |
shaderScript = document.getElementById(id); | |
if (!shaderScript) { | |
return null; | |
} | |
theSource = ""; | |
currentChild = shaderScript.firstChild; | |
while(currentChild) { | |
if (currentChild.nodeType == currentChild.TEXT_NODE) { | |
theSource += currentChild.textContent; | |
} | |
currentChild = currentChild.nextSibling; | |
} | |
if (shaderScript.type == "x-shader/x-fragment") { | |
shader = gl.createShader(gl.FRAGMENT_SHADER); | |
} else if (shaderScript.type == "x-shader/x-vertex") { | |
shader = gl.createShader(gl.VERTEX_SHADER); | |
} else { | |
// Unknown shader type | |
return null; | |
} | |
gl.shaderSource(shader, theSource); | |
// Compile the shader program | |
gl.compileShader(shader); | |
// See if it compiled successfully | |
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { | |
alert("An error occurred compiling the shaders: " + gl.getShaderInfoLog(shader)); | |
return null; | |
} | |
return shader; | |
} | |
</script> | |
<script id="jsbin-source-javascript" type="text/javascript">var WIDTH = 640; | |
var HEIGHT = 960; | |
var SURFACE = 0x13; | |
function go() { | |
var canvas = document.querySelector("canvas"); | |
setCanvasSize(canvas); | |
window.gl = canvas.getContext("webgl"); | |
initFeatures(); | |
initShaders(); | |
initBuffers(); | |
initUniforms(); | |
initTextures(); | |
requestAnimationFrame(draw); | |
} | |
function draw() { | |
gl.viewport(0, 0, WIDTH, HEIGHT); | |
gl.bindBuffer(gl.ARRAY_BUFFER, verticesBuffer); | |
gl.vertexAttribPointer(coordAttribute, 4, gl.FLOAT, false, 0, 0); | |
gl.drawArrays(gl.TRIANGLES, 0, 6); | |
requestAnimationFrame(draw); | |
} | |
function initTextures() { | |
var texture = gl.createTexture(); | |
gl.bindTexture(gl.TEXTURE_RECTANGLE, texture); | |
gl.texImageIOSurface2D(WIDTH, HEIGHT, SURFACE); | |
gl.texParameteri(gl.TEXTURE_RECTANGLE, gl.TEXTURE_MIN_FILTER, gl.LINEAR); | |
gl.texParameteri(gl.TEXTURE_RECTANGLE, gl.TEXTURE_MAG_FILTER, gl.LINEAR); | |
gl.texParameteri(gl.TEXTURE_RECTANGLE, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); | |
gl.texParameteri(gl.TEXTURE_RECTANGLE, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); | |
} | |
function setCanvasSize(canvas) { | |
canvas.width = WIDTH; | |
canvas.height = HEIGHT; | |
canvas.style.width = (WIDTH / devicePixelRatio) + "px"; | |
canvas.style.height = (HEIGHT / devicePixelRatio) + "px"; | |
} | |
function initFeatures() { | |
gl.blendFuncSeparate(gl.ONE, gl.ONE_MINUS_SRC_ALPHA, | |
gl.ONE, gl.ONE); | |
gl.enable(gl.BLEND); | |
} | |
function initBuffers() { | |
verticesBuffer = gl.createBuffer(); | |
gl.bindBuffer(gl.ARRAY_BUFFER, verticesBuffer); | |
var vertices = [ | |
0.0, 0.0, 0.0, 0.0, | |
1.0, 0.0, 0.0, 0.0, | |
0.0, 1.0, 0.0, 0.0, | |
1.0, 0.0, 0.0, 0.0, | |
0.0, 1.0, 0.0, 0.0, | |
1.0, 1.0, 0.0, 0.0, | |
]; | |
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); | |
} | |
function initUniforms() { | |
var loc; | |
var layerRects = [ | |
0, 0, WIDTH, HEIGHT, | |
0, 0, 0, 0, | |
0, 0, 0, 0, | |
0, 0, 0, 0, | |
]; | |
loc = gl.getUniformLocation(shaderProgram, "uLayerRects"); | |
gl.uniform4fv(loc, new Float32Array(layerRects)); | |
var textureRects = [ | |
0, 0, 1, 1, | |
0, 0, 0, 0, | |
0, 0, 0, 0, | |
0, 0, 0, 0, | |
]; | |
loc = gl.getUniformLocation(shaderProgram, "uTextureRects"); | |
gl.uniform4fv(loc, new Float32Array(textureRects)); | |
var renderOffset = [ | |
0, 0, 0, 0, | |
]; | |
loc = gl.getUniformLocation(shaderProgram, "uRenderTargetOffset"); | |
gl.uniform4fv(loc, new Float32Array(renderOffset)); | |
var textureTransformVals = [ | |
1, 0, 0, 0, | |
0, -1, 0, 0, | |
0, 0, 1, 0, | |
0, 1, 0, 1, | |
]; | |
loc = gl.getUniformLocation(shaderProgram, "uTextureTransform"); | |
gl.uniformMatrix4fv(loc, false, new Float32Array(textureTransformVals)); | |
var layerTransformVals = [ | |
1, 0, 0, 0, | |
0, 1, 0, 0, | |
0, 0, 1, 0, | |
0, 0, 0, 1, | |
]; | |
loc = gl.getUniformLocation(shaderProgram, "uLayerTransform"); | |
gl.uniformMatrix4fv(loc, false, new Float32Array(layerTransformVals)); | |
var texCoordMultiplier = [ | |
WIDTH, HEIGHT, | |
]; | |
loc = gl.getUniformLocation(shaderProgram, "uTexCoordMultiplier"); | |
gl.uniform2fv(loc, new Float32Array(texCoordMultiplier)); | |
var projectionVals = [ | |
2 / WIDTH, 0, 0, 0, | |
0, -2 / HEIGHT, 0, 0, | |
0, 0, 0, 0, | |
-1, 1, 0, 1, | |
]; | |
loc = gl.getUniformLocation(shaderProgram, "uMatrixProj"); | |
gl.uniformMatrix4fv(loc, false, new Float32Array(projectionVals)); | |
loc = gl.getUniformLocation(shaderProgram, "uTexture"); | |
gl.uniform1i(loc, 0); | |
} | |
function initShaders() { | |
var fragmentShader = getShader(gl, "shader-fs"); | |
var vertexShader = getShader(gl, "shader-vs"); | |
// Create the shader program | |
shaderProgram = gl.createProgram(); | |
gl.attachShader(shaderProgram, vertexShader); | |
gl.attachShader(shaderProgram, fragmentShader); | |
gl.linkProgram(shaderProgram); | |
// If creating the shader program failed, alert | |
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { | |
alert("Unable to initialize the shader program."); | |
} | |
gl.useProgram(shaderProgram); | |
coordAttribute = gl.getAttribLocation(shaderProgram, "aCoord"); | |
gl.enableVertexAttribArray(coordAttribute); | |
} | |
function getShader(gl, id) { | |
var shaderScript, theSource, currentChild, shader; | |
shaderScript = document.getElementById(id); | |
if (!shaderScript) { | |
return null; | |
} | |
theSource = ""; | |
currentChild = shaderScript.firstChild; | |
while(currentChild) { | |
if (currentChild.nodeType == currentChild.TEXT_NODE) { | |
theSource += currentChild.textContent; | |
} | |
currentChild = currentChild.nextSibling; | |
} | |
if (shaderScript.type == "x-shader/x-fragment") { | |
shader = gl.createShader(gl.FRAGMENT_SHADER); | |
} else if (shaderScript.type == "x-shader/x-vertex") { | |
shader = gl.createShader(gl.VERTEX_SHADER); | |
} else { | |
// Unknown shader type | |
return null; | |
} | |
gl.shaderSource(shader, theSource); | |
// Compile the shader program | |
gl.compileShader(shader); | |
// See if it compiled successfully | |
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { | |
alert("An error occurred compiling the shaders: " + gl.getShaderInfoLog(shader)); | |
return null; | |
} | |
return shader; | |
}</script></body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var WIDTH = 640; | |
var HEIGHT = 960; | |
var SURFACE = 0x13; | |
function go() { | |
var canvas = document.querySelector("canvas"); | |
setCanvasSize(canvas); | |
window.gl = canvas.getContext("webgl"); | |
initFeatures(); | |
initShaders(); | |
initBuffers(); | |
initUniforms(); | |
initTextures(); | |
requestAnimationFrame(draw); | |
} | |
function draw() { | |
gl.viewport(0, 0, WIDTH, HEIGHT); | |
gl.bindBuffer(gl.ARRAY_BUFFER, verticesBuffer); | |
gl.vertexAttribPointer(coordAttribute, 4, gl.FLOAT, false, 0, 0); | |
gl.drawArrays(gl.TRIANGLES, 0, 6); | |
requestAnimationFrame(draw); | |
} | |
function initTextures() { | |
var texture = gl.createTexture(); | |
gl.bindTexture(gl.TEXTURE_RECTANGLE, texture); | |
gl.texImageIOSurface2D(WIDTH, HEIGHT, SURFACE); | |
gl.texParameteri(gl.TEXTURE_RECTANGLE, gl.TEXTURE_MIN_FILTER, gl.LINEAR); | |
gl.texParameteri(gl.TEXTURE_RECTANGLE, gl.TEXTURE_MAG_FILTER, gl.LINEAR); | |
gl.texParameteri(gl.TEXTURE_RECTANGLE, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); | |
gl.texParameteri(gl.TEXTURE_RECTANGLE, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); | |
} | |
function setCanvasSize(canvas) { | |
canvas.width = WIDTH; | |
canvas.height = HEIGHT; | |
canvas.style.width = (WIDTH / devicePixelRatio) + "px"; | |
canvas.style.height = (HEIGHT / devicePixelRatio) + "px"; | |
} | |
function initFeatures() { | |
gl.blendFuncSeparate(gl.ONE, gl.ONE_MINUS_SRC_ALPHA, | |
gl.ONE, gl.ONE); | |
gl.enable(gl.BLEND); | |
} | |
function initBuffers() { | |
verticesBuffer = gl.createBuffer(); | |
gl.bindBuffer(gl.ARRAY_BUFFER, verticesBuffer); | |
var vertices = [ | |
0.0, 0.0, 0.0, 0.0, | |
1.0, 0.0, 0.0, 0.0, | |
0.0, 1.0, 0.0, 0.0, | |
1.0, 0.0, 0.0, 0.0, | |
0.0, 1.0, 0.0, 0.0, | |
1.0, 1.0, 0.0, 0.0, | |
]; | |
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); | |
} | |
function initUniforms() { | |
var loc; | |
var layerRects = [ | |
0, 0, WIDTH, HEIGHT, | |
0, 0, 0, 0, | |
0, 0, 0, 0, | |
0, 0, 0, 0, | |
]; | |
loc = gl.getUniformLocation(shaderProgram, "uLayerRects"); | |
gl.uniform4fv(loc, new Float32Array(layerRects)); | |
var textureRects = [ | |
0, 0, 1, 1, | |
0, 0, 0, 0, | |
0, 0, 0, 0, | |
0, 0, 0, 0, | |
]; | |
loc = gl.getUniformLocation(shaderProgram, "uTextureRects"); | |
gl.uniform4fv(loc, new Float32Array(textureRects)); | |
var renderOffset = [ | |
0, 0, 0, 0, | |
]; | |
loc = gl.getUniformLocation(shaderProgram, "uRenderTargetOffset"); | |
gl.uniform4fv(loc, new Float32Array(renderOffset)); | |
var textureTransformVals = [ | |
1, 0, 0, 0, | |
0, -1, 0, 0, | |
0, 0, 1, 0, | |
0, 1, 0, 1, | |
]; | |
loc = gl.getUniformLocation(shaderProgram, "uTextureTransform"); | |
gl.uniformMatrix4fv(loc, false, new Float32Array(textureTransformVals)); | |
var layerTransformVals = [ | |
1, 0, 0, 0, | |
0, 1, 0, 0, | |
0, 0, 1, 0, | |
0, 0, 0, 1, | |
]; | |
loc = gl.getUniformLocation(shaderProgram, "uLayerTransform"); | |
gl.uniformMatrix4fv(loc, false, new Float32Array(layerTransformVals)); | |
var texCoordMultiplier = [ | |
WIDTH, HEIGHT, | |
]; | |
loc = gl.getUniformLocation(shaderProgram, "uTexCoordMultiplier"); | |
gl.uniform2fv(loc, new Float32Array(texCoordMultiplier)); | |
var projectionVals = [ | |
2 / WIDTH, 0, 0, 0, | |
0, -2 / HEIGHT, 0, 0, | |
0, 0, 0, 0, | |
-1, 1, 0, 1, | |
]; | |
loc = gl.getUniformLocation(shaderProgram, "uMatrixProj"); | |
gl.uniformMatrix4fv(loc, false, new Float32Array(projectionVals)); | |
loc = gl.getUniformLocation(shaderProgram, "uTexture"); | |
gl.uniform1i(loc, 0); | |
} | |
function initShaders() { | |
var fragmentShader = getShader(gl, "shader-fs"); | |
var vertexShader = getShader(gl, "shader-vs"); | |
// Create the shader program | |
shaderProgram = gl.createProgram(); | |
gl.attachShader(shaderProgram, vertexShader); | |
gl.attachShader(shaderProgram, fragmentShader); | |
gl.linkProgram(shaderProgram); | |
// If creating the shader program failed, alert | |
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { | |
alert("Unable to initialize the shader program."); | |
} | |
gl.useProgram(shaderProgram); | |
coordAttribute = gl.getAttribLocation(shaderProgram, "aCoord"); | |
gl.enableVertexAttribArray(coordAttribute); | |
} | |
function getShader(gl, id) { | |
var shaderScript, theSource, currentChild, shader; | |
shaderScript = document.getElementById(id); | |
if (!shaderScript) { | |
return null; | |
} | |
theSource = ""; | |
currentChild = shaderScript.firstChild; | |
while(currentChild) { | |
if (currentChild.nodeType == currentChild.TEXT_NODE) { | |
theSource += currentChild.textContent; | |
} | |
currentChild = currentChild.nextSibling; | |
} | |
if (shaderScript.type == "x-shader/x-fragment") { | |
shader = gl.createShader(gl.FRAGMENT_SHADER); | |
} else if (shaderScript.type == "x-shader/x-vertex") { | |
shader = gl.createShader(gl.VERTEX_SHADER); | |
} else { | |
// Unknown shader type | |
return null; | |
} | |
gl.shaderSource(shader, theSource); | |
// Compile the shader program | |
gl.compileShader(shader); | |
// See if it compiled successfully | |
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { | |
alert("An error occurred compiling the shaders: " + gl.getShaderInfoLog(shader)); | |
return null; | |
} | |
return shader; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment