diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /dom/canvas/test/webgl-conf/checkout/performance | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/canvas/test/webgl-conf/checkout/performance')
4 files changed, 3369 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/performance/parallel_shader_compile/index.html b/dom/canvas/test/webgl-conf/checkout/performance/parallel_shader_compile/index.html new file mode 100644 index 0000000000..1a2a9000d4 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/performance/parallel_shader_compile/index.html @@ -0,0 +1,401 @@ +<!-- +Copyright (c) 2019 The Khronos Group Inc. +Use of this source code is governed by an MIT-style license that can be +found in the LICENSE.txt file. +--> + +<!doctype html> +<html lang="en"> +<head> + <meta charset="utf-8"> + <title>Parallel Shader Compile test</title> + + <style> + body { + margin: 0; + } + #log { + margin: 16px; + } + @keyframes move { + 0% { left: 0%; } + 50% { left: calc(100% - 64px); } + 100% { left: 0%; } + } + #block { + position: relative; + bottom: 0%; + left: 0%; + width: 32px; + height: 32px; + background-color: #07f; + + animation-name: move; + animation-duration: 2000ms; + animation-iteration-count: infinite; + } + .container { + display: flex; + flex-wrap: wrap; + } + .button { + width: 260px + } + </style> +</head> +<body> + <pre id='log'></pre> + + <!-- The smoothness of the block's moving indicates whether the main thread is too busy. --> + <div id='block'></div> + + <script> + var testGroup; + + window.addEventListener('error', function (err) { + var logElement = document.getElementById('log'); + logElement.textContent += ' \n'; + logElement.textContent += err.error.stack.replace( + new RegExp(window.location.href, 'g'), '/') + '\n'; + }); + + function setupGLContextSerial(testRun) { + var infoElement = testRun.logElement; + + testRun.gl = document.createElement('canvas').getContext('webgl2'); + if (testRun.gl) { + infoElement.textContent += 'webgl2 context created.' + '\n\n'; + return true; + } else { + infoElement.textContent += 'webgl2 context is not supported.' + '\n\n'; + return false; + } + } + + function setupGLContextParallel(testRun) { + var infoElement = testRun.logElement; + if (setupGLContextSerial(testRun)) { + // Enable KHR_parallel_shader_compile extension + testRun.ext = testRun.gl.getExtension('KHR_parallel_shader_compile'); + if (testRun.ext) { + return true; + } else { + infoElement.textContent += 'KHR_parallel_shader_compile is unavailable, you' + + ' may need to turn on the webgl draft extensions for your browser.' + } + } + return false; + } + + function releasePrograms(testRun) { + var gl = testRun.gl; + + var programs = testRun.programs; + for (var i = 0; i < programs.length; i++) { + var program = programs[i]; + if (program.vShader) { + gl.deleteShader(program.vShader); + program.vShader = null; + } + if (program.fShader) { + gl.deleteShader(program.fShader); + program.fShader = null; + } + if (program.program) { + gl.deleteProgram(program.program); + program.program = null; + } + } + } + + function showStatistics(testRun) { + var infoElement = testRun.logElement; + infoElement.textContent += ' ' + '\n'; + infoElement.textContent += (Math.round(testRun.elapsedTotal * 100) / 100) + + 'ms - ' + 'all shaders compiled, and linked.\n'; + infoElement.textContent += ' ' + '\n'; + infoElement.textContent += 'done.' + '\n'; + + releasePrograms(testRun); + } + + function checkShader(gl, shader, infoElement) { + if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { + var info = gl.getShaderInfoLog(shader); + infoElement.textContent += 'couldn\'t compile shader:\n'; + infoElement.textContent += info.toString() + '\n'; + return false; + } + return true; + } + + function checkProgram(gl, program, infoElement) { + if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { + var info = gl.getProgramInfoLog(program); + infoElement.textContent += ' ' + '\n'; + infoElement.textContent += 'couldn\'t link program:\n'; + infoElement.textContent += info.toString() + '\n'; + return false; + } + return true; + } + + function makeAllProgramsSerial(testRun) { + var gl = testRun.gl; + var infoElement = testRun.logElement; + + var programs = testRun.programs; + for (var i = 0; i < programs.length; i++) { + var program = programs[i]; + // vertex shader compilation + var vShader = gl.createShader(gl.VERTEX_SHADER); + gl.shaderSource(vShader, program.vSource); + gl.compileShader(vShader); + checkShader(gl, vShader, infoElement); + + // fragment shader compilation + var fShader = gl.createShader(gl.FRAGMENT_SHADER); + gl.shaderSource(fShader, program.fSource); + gl.compileShader(fShader); + checkShader(gl, fShader, infoElement); + + // program + var programHandle = gl.createProgram(); + gl.attachShader(programHandle, vShader); + gl.attachShader(programHandle, fShader); + gl.linkProgram(programHandle); + checkProgram(gl, programHandle, infoElement); + } + testRun.elapsedTotal = performance.now() - testRun.start; + showStatistics(testRun); + }; + + function makeAllProgramsParallel(testRun) { + var gl = testRun.gl; + var infoElement = testRun.logElement; + + var programs = testRun.programs; + for (var i = 0; i < programs.length; i++) { + var program = programs[i]; + var vShader = gl.createShader(gl.VERTEX_SHADER); + gl.shaderSource(vShader, program.vSource); + gl.compileShader(vShader); + + var fShader = gl.createShader(gl.FRAGMENT_SHADER); + gl.shaderSource(fShader, program.fSource); + gl.compileShader(fShader); + + programHandle = gl.createProgram(); + gl.attachShader(programHandle, vShader); + gl.attachShader(programHandle, fShader); + + program.vShader = vShader; + program.fShader = fShader; + program.program = programHandle; + program.status = "Compiling"; + } + + function checkCompletion() { + var ext = testRun.ext; + + var allProgramsLinked = true; + + for (var i = 0; i < programs.length; i++) { + var program = programs[i]; + switch (program.status) { + case "Compiling": + if (gl.getShaderParameter(program.vShader, ext.COMPLETION_STATUS_KHR) && + gl.getShaderParameter(program.fShader, ext.COMPLETION_STATUS_KHR)) + { + checkShader(gl, program.vShader, infoElement); + checkShader(gl, program.fShader, infoElement); + gl.linkProgram(program.program); + program.status = "Linking"; + } + allProgramsLinked = false; + break; + + case "Linking": + if (gl.getProgramParameter(program.program, ext.COMPLETION_STATUS_KHR)) + { + checkProgram(gl, program.program, infoElement); + program.status = "Done"; + } + else { + allProgramsLinked = false; + } + break; + + case "Done": + break; + } + } + + if (allProgramsLinked) { + testRun.elapsedTotal = performance.now() - testRun.start; + showStatistics(testRun); + } + else { + requestAnimationFrame(checkCompletion); + } + } + requestAnimationFrame(checkCompletion); + } + + function parsePrograms(testRun) { + var gl = testRun.gl; + var infoElement = testRun.logElement; + + // Parse programs from the cached text, formatted as: + // __BEGINPROGRAM__ + // __VERTEXSHADER__ + // shader source line + // ... + // __FRAGMENTSHADER__ + // shader source line + // ... + // __ENDPROGRAM__ + // + // __BEGINPROGRAM__ + // ... + var arrayOfLines = testRun.test.shaderCache.match(/[^\r\n]+/g); + var programs = []; + var currentProgram = {}; + var currentShader; + var shaderSourceLine = false; + for (var ii = 0; ii < arrayOfLines.length; ii++) { + var cur = arrayOfLines[ii]; + // Use random numbers to fool the program cache mechanism. + if (cur.indexOf('PROGRAM_CACHE_BREAKER_RANDOM') != -1) { + cur = cur.replace('PROGRAM_CACHE_BREAKER_RANDOM', Math.random()) + } + + if (cur == '__VERTEXSHADER__') { + currentShader = []; + shaderSourceLine = true; + } else if (cur == '__FRAGMENTSHADER__') { + currentProgram.vSource = currentShader.join('\n'); + + currentShader = []; + shaderSourceLine = true; + } else if (cur == '__ENDPROGRAM__') { + currentProgram.fSource = currentShader.join('\n'); + programs.push(currentProgram); + + currentProgram = {}; + currentShader = []; + shaderSourceLine = false; + } else if (shaderSourceLine) { + currentShader.push(cur); + } + } + + infoElement.textContent += programs.length + ' programs found.' + '\n'; + infoElement.textContent += 'starting compilations ...' + '\n'; + + testRun.start = performance.now(); + + testRun.programs = programs; + + testRun.makeAllPrograms(testRun); + }; + + + function runTest(index, isParallel) { + var testRun = {}; + var test = testGroup[index]; + testRun.test = test; + testRun.name = test.name + (isParallel ? "_parallel" : "_serial"); + testRun.logElement = document.getElementById(testRun.name); + testRun.logElement.textContent = ''; + + testRun.setupGLContext = + (isParallel ? setupGLContextParallel : setupGLContextSerial); + + testRun.makeAllPrograms = + (isParallel ? makeAllProgramsParallel : makeAllProgramsSerial); + + if (!testRun.setupGLContext(testRun)) { + return; + } + + if (test.shaderCache === undefined) { + // load shader cache + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function() { + test.shaderCache = xhr.responseText; + + requestAnimationFrame(function() { + parsePrograms(testRun); + }); + }); + xhr.open('GET', test.location); + xhr.send(); + } else { + parsePrograms(testRun); + } + } + + function createElement(element, attribute, inner) { + if (element === undefined) { + return false; + } + if (inner === undefined) { + inner = []; + } + var el = document.createElement(element); + if (typeof(attribute) === 'object') { + for (var key in attribute) { + el.setAttribute(key, attribute[key]); + } + } + if (!Array.isArray(inner)) { + inner = [inner]; + } + for (var k = 0; k < inner.length; k++) { + if (inner[k].tagName) { + el.appendChild(inner[k]); + } else { + el.appendChild(document.createTextNode(inner[k])); + } + } + return el; + } + + var container = createElement("div", {"class": "container"}); + document.body.appendChild(container); + + testGroup = [{ + 'location': './shaders/aquarium/shader-cache.txt', + 'name': 'aquarium' + }, + ]; + + testGroup.forEach((test, index) => { + + function createTestView(test, index, isParallel) { + + testName = test.name + (isParallel ? "_parallel" : "_serial"); + + var tButton = createElement( + 'button', + {'class': 'button', 'onclick': 'runTest(' + index + ', ' + isParallel + ')'}, + testName + ); + + var tPrex = createElement("pre"); + var tPre = createElement("textarea", { "id": testName, "rows": 10, "cols": 30}); + var tDivContainer = createElement( + "div", + {"id": " " + testName + "_container"}, + [tButton, tPrex, tPre] + ); + container.appendChild(tDivContainer); + } + + createTestView(test, index, false); + createTestView(test, index, true); + }); + + </script> +</body> diff --git a/dom/canvas/test/webgl-conf/checkout/performance/parallel_shader_compile/shaders/aquarium/README b/dom/canvas/test/webgl-conf/checkout/performance/parallel_shader_compile/shaders/aquarium/README new file mode 100644 index 0000000000..3dff676045 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/performance/parallel_shader_compile/shaders/aquarium/README @@ -0,0 +1,35 @@ +1. Pulled from http://webglsamples.org/aquarium/aquarium.html, the license of which is: + +<!-- + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--> +<!DOCTYPE html> + +2. Inserted a few redundant shader code lines to bypass program cache. diff --git a/dom/canvas/test/webgl-conf/checkout/performance/parallel_shader_compile/shaders/aquarium/shader-cache.txt b/dom/canvas/test/webgl-conf/checkout/performance/parallel_shader_compile/shaders/aquarium/shader-cache.txt new file mode 100644 index 0000000000..c3ce8cf6a3 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/performance/parallel_shader_compile/shaders/aquarium/shader-cache.txt @@ -0,0 +1,2747 @@ +<!-- + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--> + + + +__BEGINPROGRAM__ +__VERTEXSHADER__ + +attribute vec4 position; +varying vec4 v_position; +void main() { + v_position = position; + gl_Position = position; + gl_Position.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + +__FRAGMENTSHADER__ + +precision mediump float; +uniform samplerCube skybox; +uniform mat4 viewDirectionProjectionInverse; +varying vec4 v_position; +void main() { + vec4 t = viewDirectionProjectionInverse * v_position; + gl_FragColor = textureCube( + skybox, + normalize(t.xyz)); + gl_FragColor.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + +__ENDPROGRAM__ +__BEGINPROGRAM__ +__VERTEXSHADER__ + +attribute vec4 position; +attribute vec2 texCoord; +varying vec2 v_texCoord; +uniform mat4 worldViewProjection; +void main() { + v_texCoord = texCoord; + gl_Position = (worldViewProjection * position); + gl_Position.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + +__FRAGMENTSHADER__ + +precision mediump float; + +varying vec2 v_texCoord; +uniform vec4 colorMult; +uniform sampler2D colorMap; +void main() { + gl_FragColor = texture2D(colorMap, v_texCoord) * colorMult; + gl_FragColor.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + +__ENDPROGRAM__ +__BEGINPROGRAM__ +__VERTEXSHADER__ +uniform mat4 worldViewProjection; +uniform mat4 world; +uniform vec3 worldVelocity; +uniform vec3 worldAcceleration; +uniform float timeRange; +uniform float time; +uniform float timeOffset; +uniform float frameDuration; +uniform float numFrames; + +// Incoming vertex attributes +attribute vec4 uvLifeTimeFrameStart; // uv, lifeTime, frameStart +attribute vec4 positionStartTime; // position.xyz, startTime +attribute vec4 velocityStartSize; // velocity.xyz, startSize +attribute vec4 accelerationEndSize; // acceleration.xyz, endSize +attribute vec4 spinStartSpinSpeed; // spinStart.x, spinSpeed.y +attribute vec4 orientation; // orientation quaternion +attribute vec4 colorMult; // multiplies color and ramp textures + +// Outgoing variables to fragment shader +varying vec2 outputTexcoord; +varying float outputPercentLife; +varying vec4 outputColorMult; + +void main() { + vec2 uv = uvLifeTimeFrameStart.xy; + float lifeTime = uvLifeTimeFrameStart.z; + float frameStart = uvLifeTimeFrameStart.w; + vec3 position = positionStartTime.xyz; + float startTime = positionStartTime.w; + vec3 velocity = (world * vec4(velocityStartSize.xyz, + 0.)).xyz + worldVelocity; + float startSize = velocityStartSize.w; + vec3 acceleration = (world * vec4(accelerationEndSize.xyz, + 0)).xyz + worldAcceleration; + float endSize = accelerationEndSize.w; + float spinStart = spinStartSpinSpeed.x; + float spinSpeed = spinStartSpinSpeed.y; + + float localTime = mod((time - timeOffset - startTime), timeRange); + float percentLife = localTime / lifeTime; + + float frame = mod(floor(localTime / frameDuration + frameStart), + numFrames); + float uOffset = frame / numFrames; + float u = uOffset + (uv.x + 0.5) * (1. / numFrames); + + outputTexcoord = vec2(u, uv.y + 0.5); + outputColorMult = colorMult; + + float size = mix(startSize, endSize, percentLife); + size = (percentLife < 0. || percentLife > 1.) ? 0. : size; + float s = sin(spinStart + spinSpeed * localTime); + float c = cos(spinStart + spinSpeed * localTime); + + vec4 rotatedPoint = vec4((uv.x * c + uv.y * s) * size, 0., + (uv.x * s - uv.y * c) * size, 1.); + vec3 center = velocity * localTime + + acceleration * localTime * localTime + + position; + + vec4 q2 = orientation + orientation; + vec4 qx = orientation.xxxw * q2.xyzx; + vec4 qy = orientation.xyyw * q2.xyzy; + vec4 qz = orientation.xxzw * q2.xxzz; + + mat4 localMatrix = mat4( + (1.0 - qy.y) - qz.z, + qx.y + qz.w, + qx.z - qy.w, + 0, + + qx.y - qz.w, + (1.0 - qx.x) - qz.z, + qy.z + qx.w, + 0, + + qx.z + qy.w, + qy.z - qx.w, + (1.0 - qx.x) - qy.y, + 0, + + center.x, center.y, center.z, 1); + rotatedPoint = localMatrix * rotatedPoint; + outputPercentLife = percentLife; + gl_Position = worldViewProjection * rotatedPoint; + gl_Position.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + +__FRAGMENTSHADER__ +#ifdef GL_ES +precision mediump float; +#endif +uniform sampler2D rampSampler; +uniform sampler2D colorSampler; + +// Incoming variables from vertex shader +varying vec2 outputTexcoord; +varying float outputPercentLife; +varying vec4 outputColorMult; + +void main() { + vec4 colorMult = texture2D(rampSampler, + vec2(outputPercentLife, 0.5)) * + outputColorMult; + gl_FragColor = texture2D(colorSampler, outputTexcoord) * colorMult; + gl_FragColor.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + +__ENDPROGRAM__ +__BEGINPROGRAM__ +__VERTEXSHADER__ +uniform mat4 viewProjection; +uniform mat4 world; +uniform mat4 viewInverse; +uniform vec3 worldVelocity; +uniform vec3 worldAcceleration; +uniform float timeRange; +uniform float time; +uniform float timeOffset; +uniform float frameDuration; +uniform float numFrames; + +// Incoming vertex attributes +attribute vec4 uvLifeTimeFrameStart; // uv, lifeTime, frameStart +attribute vec4 positionStartTime; // position.xyz, startTime +attribute vec4 velocityStartSize; // velocity.xyz, startSize +attribute vec4 accelerationEndSize; // acceleration.xyz, endSize +attribute vec4 spinStartSpinSpeed; // spinStart.x, spinSpeed.y +attribute vec4 colorMult; // multiplies color and ramp textures + +// Outgoing variables to fragment shader +varying vec2 outputTexcoord; +varying float outputPercentLife; +varying vec4 outputColorMult; + +void main() { + vec2 uv = uvLifeTimeFrameStart.xy; + float lifeTime = uvLifeTimeFrameStart.z; + float frameStart = uvLifeTimeFrameStart.w; + vec3 position = positionStartTime.xyz; + float startTime = positionStartTime.w; + vec3 velocity = (world * vec4(velocityStartSize.xyz, + 0.)).xyz + worldVelocity; + float startSize = velocityStartSize.w; + vec3 acceleration = (world * vec4(accelerationEndSize.xyz, + 0)).xyz + worldAcceleration; + float endSize = accelerationEndSize.w; + float spinStart = spinStartSpinSpeed.x; + float spinSpeed = spinStartSpinSpeed.y; + + float localTime = mod((time - timeOffset - startTime), timeRange); + float percentLife = localTime / lifeTime; + + float frame = mod(floor(localTime / frameDuration + frameStart), + numFrames); + float uOffset = frame / numFrames; + float u = uOffset + (uv.x + 0.5) * (1. / numFrames); + + outputTexcoord = vec2(u, uv.y + 0.5); + outputColorMult = colorMult; + + vec3 basisX = viewInverse[0].xyz; + vec3 basisZ = viewInverse[1].xyz; + + float size = mix(startSize, endSize, percentLife); + size = (percentLife < 0. || percentLife > 1.) ? 0. : size; + float s = sin(spinStart + spinSpeed * localTime); + float c = cos(spinStart + spinSpeed * localTime); + + vec2 rotatedPoint = vec2(uv.x * c + uv.y * s, + -uv.x * s + uv.y * c); + vec3 localPosition = vec3(basisX * rotatedPoint.x + + basisZ * rotatedPoint.y) * size + + velocity * localTime + + acceleration * localTime * localTime + + position; + + outputPercentLife = percentLife; + gl_Position = viewProjection * vec4(localPosition + world[3].xyz, 1.); + gl_Position.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + +__FRAGMENTSHADER__ +#ifdef GL_ES +precision mediump float; +#endif +uniform sampler2D rampSampler; +uniform sampler2D colorSampler; + +// Incoming variables from vertex shader +varying vec2 outputTexcoord; +varying float outputPercentLife; +varying vec4 outputColorMult; + +void main() { + vec4 colorMult = texture2D(rampSampler, + vec2(outputPercentLife, 0.5)) * + outputColorMult; + gl_FragColor = texture2D(colorSampler, outputTexcoord) * colorMult; + gl_FragColor.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + +__ENDPROGRAM__ +__BEGINPROGRAM__ +__VERTEXSHADER__ + +uniform mat4 worldViewProjection; +uniform vec3 lightWorldPos; +uniform mat4 world; +uniform mat4 viewInverse; +uniform mat4 worldInverseTranspose; +attribute vec4 position; +attribute vec3 normal; +attribute vec2 texCoord; +attribute vec3 tangent; // #normalMap +attribute vec3 binormal; // #normalMap +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_tangent; // #normalMap +varying vec3 v_binormal; // #normalMap +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; +void main() { + v_texCoord = texCoord; + v_position = (worldViewProjection * position); + v_normal = (worldInverseTranspose * vec4(normal, 0)).xyz; + v_surfaceToLight = lightWorldPos - (world * position).xyz; + v_surfaceToView = (viewInverse[3] - (world * position)).xyz; + v_binormal = (worldInverseTranspose * vec4(binormal, 0)).xyz; // #normalMap + v_tangent = (worldInverseTranspose * vec4(tangent, 0)).xyz; // #normalMap + gl_Position = v_position; + gl_Position.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + + +__FRAGMENTSHADER__ + +precision mediump float; +uniform vec4 lightColor; +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_tangent; // #normalMap +varying vec3 v_binormal; // #normalMap +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; + +uniform vec4 ambient; +uniform sampler2D diffuse; +uniform vec4 specular; +uniform sampler2D normalMap; // #normalMap +uniform float shininess; +uniform float specularFactor; +uniform float fogPower; +uniform float fogMult; +uniform float fogOffset; +uniform vec4 fogColor; + + +vec4 lit(float l ,float h, float m) { + return vec4(1.0, + max(l, 0.0), + (l > 0.0) ? pow(max(0.0, h), m) : 0.0, + 1.0); +} +void main() { + vec4 diffuseColor = texture2D(diffuse, v_texCoord); + mat3 tangentToWorld = mat3(v_tangent, // #normalMap + v_binormal, // #normalMap + v_normal); // #normalMap + vec4 normalSpec = texture2D(normalMap, v_texCoord.xy); // #normalMap + vec3 tangentNormal = normalSpec.xyz - // #normalMap + vec3(0.5, 0.5, 0.5); // #normalMap + vec3 normal = (tangentToWorld * tangentNormal); // #normalMap + normal = normalize(normal); // #normalMap + vec3 surfaceToLight = normalize(v_surfaceToLight); + vec3 surfaceToView = normalize(v_surfaceToView); + vec3 halfVector = normalize(surfaceToLight + surfaceToView); + vec4 litR = lit(dot(normal, surfaceToLight), + dot(normal, halfVector), shininess); + vec4 outColor = vec4( + (lightColor * (diffuseColor * litR.y + diffuseColor * ambient + + specular * litR.z * specularFactor * normalSpec.a)).rgb, + diffuseColor.a); + outColor = mix(outColor, vec4(fogColor.rgb, diffuseColor.a), + clamp(pow((v_position.z / v_position.w), fogPower) * fogMult - fogOffset,0.0,1.0)); + + gl_FragColor = outColor; + gl_FragColor.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + +__ENDPROGRAM__ +__BEGINPROGRAM__ +__VERTEXSHADER__ + +uniform mat4 worldViewProjection; +uniform vec3 lightWorldPos; +uniform mat4 world; +uniform mat4 viewInverse; +uniform mat4 worldInverseTranspose; +attribute vec4 position; +attribute vec3 normal; +attribute vec2 texCoord; +attribute vec3 tangent; // #normalMap +attribute vec3 binormal; // #normalMap +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_tangent; // #normalMap +varying vec3 v_binormal; // #normalMap +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; +void main() { + v_texCoord = texCoord; + v_position = (worldViewProjection * position); + v_normal = (worldInverseTranspose * vec4(normal, 0)).xyz; + v_surfaceToLight = lightWorldPos - (world * position).xyz; + v_surfaceToView = (viewInverse[3] - (world * position)).xyz; + v_binormal = (worldInverseTranspose * vec4(binormal, 0)).xyz; // #normalMap + v_tangent = (worldInverseTranspose * vec4(tangent, 0)).xyz; // #normalMap + gl_Position = v_position; + gl_Position.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + + +__FRAGMENTSHADER__ + +precision mediump float; +uniform vec4 lightColor; +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_tangent; // #normalMap +varying vec3 v_binormal; // #normalMap +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; + +uniform vec4 ambient; +uniform sampler2D diffuse; +uniform vec4 specular; +uniform sampler2D normalMap; // #normalMap +uniform float shininess; +uniform float specularFactor; +// #fogUniforms + +vec4 lit(float l ,float h, float m) { + return vec4(1.0, + max(l, 0.0), + (l > 0.0) ? pow(max(0.0, h), m) : 0.0, + 1.0); +} +void main() { + vec4 diffuseColor = texture2D(diffuse, v_texCoord); + mat3 tangentToWorld = mat3(v_tangent, // #normalMap + v_binormal, // #normalMap + v_normal); // #normalMap + vec4 normalSpec = texture2D(normalMap, v_texCoord.xy); // #normalMap + vec3 tangentNormal = normalSpec.xyz - // #normalMap + vec3(0.5, 0.5, 0.5); // #normalMap + vec3 normal = (tangentToWorld * tangentNormal); // #normalMap + normal = normalize(normal); // #normalMap + vec3 surfaceToLight = normalize(v_surfaceToLight); + vec3 surfaceToView = normalize(v_surfaceToView); + vec3 halfVector = normalize(surfaceToLight + surfaceToView); + vec4 litR = lit(dot(normal, surfaceToLight), + dot(normal, halfVector), shininess); + vec4 outColor = vec4( + (lightColor * (diffuseColor * litR.y + diffuseColor * ambient + + specular * litR.z * specularFactor * normalSpec.a)).rgb, + diffuseColor.a); + // #fogCode + gl_FragColor = outColor; + gl_FragColor.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + +__ENDPROGRAM__ +__BEGINPROGRAM__ +__VERTEXSHADER__ + +uniform mat4 worldViewProjection; +uniform vec3 lightWorldPos; +uniform mat4 world; +uniform mat4 viewInverse; +uniform mat4 worldInverseTranspose; +attribute vec4 position; +attribute vec3 normal; +attribute vec2 texCoord; +attribute vec3 tangent; // #normalMap +attribute vec3 binormal; // #normalMap +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_tangent; // #normalMap +varying vec3 v_binormal; // #normalMap +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; +void main() { + v_texCoord = texCoord; + v_position = (worldViewProjection * position); + v_normal = (worldInverseTranspose * vec4(normal, 0)).xyz; + v_surfaceToLight = lightWorldPos - (world * position).xyz; + v_surfaceToView = (viewInverse[3] - (world * position)).xyz; + v_binormal = (worldInverseTranspose * vec4(binormal, 0)).xyz; // #normalMap + v_tangent = (worldInverseTranspose * vec4(tangent, 0)).xyz; // #normalMap + gl_Position = v_position; + gl_Position.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + + +__FRAGMENTSHADER__ + +precision mediump float; +uniform vec4 lightColor; +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; + +uniform vec4 ambient; +uniform sampler2D diffuse; +uniform vec4 specular; +uniform float shininess; +uniform float specularFactor; +uniform float fogPower; +uniform float fogMult; +uniform float fogOffset; +uniform vec4 fogColor; + + +vec4 lit(float l ,float h, float m) { + return vec4(1.0, + max(l, 0.0), + (l > 0.0) ? pow(max(0.0, h), m) : 0.0, + 1.0); +} +void main() { + vec4 diffuseColor = texture2D(diffuse, v_texCoord); + vec4 normalSpec = vec4(0,0,0,0); // #noNormalMap + vec3 normal = normalize(v_normal); // #noNormalMap + vec3 surfaceToLight = normalize(v_surfaceToLight); + vec3 surfaceToView = normalize(v_surfaceToView); + vec3 halfVector = normalize(surfaceToLight + surfaceToView); + vec4 litR = lit(dot(normal, surfaceToLight), + dot(normal, halfVector), shininess); + vec4 outColor = vec4( + (lightColor * (diffuseColor * litR.y + diffuseColor * ambient + + specular * litR.z * specularFactor * normalSpec.a)).rgb, + diffuseColor.a); + outColor = mix(outColor, vec4(fogColor.rgb, diffuseColor.a), + clamp(pow((v_position.z / v_position.w), fogPower) * fogMult - fogOffset,0.0,1.0)); + + gl_FragColor = outColor; + gl_FragColor.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + +__ENDPROGRAM__ +__BEGINPROGRAM__ +__VERTEXSHADER__ + +uniform mat4 worldViewProjection; +uniform vec3 lightWorldPos; +uniform mat4 world; +uniform mat4 viewInverse; +uniform mat4 worldInverseTranspose; +attribute vec4 position; +attribute vec3 normal; +attribute vec2 texCoord; +attribute vec3 tangent; // #normalMap +attribute vec3 binormal; // #normalMap +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_tangent; // #normalMap +varying vec3 v_binormal; // #normalMap +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; +void main() { + v_texCoord = texCoord; + v_position = (worldViewProjection * position); + v_normal = (worldInverseTranspose * vec4(normal, 0)).xyz; + v_surfaceToLight = lightWorldPos - (world * position).xyz; + v_surfaceToView = (viewInverse[3] - (world * position)).xyz; + v_binormal = (worldInverseTranspose * vec4(binormal, 0)).xyz; // #normalMap + v_tangent = (worldInverseTranspose * vec4(tangent, 0)).xyz; // #normalMap + gl_Position = v_position; + gl_Position.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + + +__FRAGMENTSHADER__ + +precision mediump float; +uniform vec4 lightColor; +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; + +uniform vec4 ambient; +uniform sampler2D diffuse; +uniform vec4 specular; +uniform float shininess; +uniform float specularFactor; +// #fogUniforms + +vec4 lit(float l ,float h, float m) { + return vec4(1.0, + max(l, 0.0), + (l > 0.0) ? pow(max(0.0, h), m) : 0.0, + 1.0); +} +void main() { + vec4 diffuseColor = texture2D(diffuse, v_texCoord); + vec4 normalSpec = vec4(0,0,0,0); // #noNormalMap + vec3 normal = normalize(v_normal); // #noNormalMap + vec3 surfaceToLight = normalize(v_surfaceToLight); + vec3 surfaceToView = normalize(v_surfaceToView); + vec3 halfVector = normalize(surfaceToLight + surfaceToView); + vec4 litR = lit(dot(normal, surfaceToLight), + dot(normal, halfVector), shininess); + vec4 outColor = vec4( + (lightColor * (diffuseColor * litR.y + diffuseColor * ambient + + specular * litR.z * specularFactor * normalSpec.a)).rgb, + diffuseColor.a); + // #fogCode + gl_FragColor = outColor; + gl_FragColor.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + +__ENDPROGRAM__ +__BEGINPROGRAM__ +__VERTEXSHADER__ + +uniform vec3 lightWorldPos; +uniform mat4 viewInverse; +uniform mat4 viewProjection; +uniform vec3 worldPosition; +uniform vec3 nextPosition; +uniform float scale; +uniform float time; +uniform float fishLength; +uniform float fishWaveLength; +uniform float fishBendAmount; +attribute vec4 position; +attribute vec3 normal; +attribute vec2 texCoord; +attribute vec3 tangent; // #normalMap +attribute vec3 binormal; // #normalMap +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_tangent; // #normalMap +varying vec3 v_binormal; // #normalMap +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; +void main() { + vec3 vz = normalize(worldPosition - nextPosition); + vec3 vx = normalize(cross(vec3(0,1,0), vz)); + vec3 vy = cross(vz, vx); + mat4 orientMat = mat4( + vec4(vx, 0), + vec4(vy, 0), + vec4(vz, 0), + vec4(worldPosition, 1)); + mat4 scaleMat = mat4( + vec4(scale, 0, 0, 0), + vec4(0, scale, 0, 0), + vec4(0, 0, scale, 0), + vec4(0, 0, 0, 1)); + mat4 world = orientMat * scaleMat; + mat4 worldViewProjection = viewProjection * world; + mat4 worldInverseTranspose = world; + + v_texCoord = texCoord; + // NOTE:If you change this you need to change the laser code to match! + float mult = position.z > 0.0 ? + (position.z / fishLength) : + (-position.z / fishLength * 2.0); + float s = sin(time + mult * fishWaveLength); + float a = sign(s); + float offset = pow(mult, 2.0) * s * fishBendAmount; + v_position = ( + worldViewProjection * + (position + + vec4(offset, 0, 0, 0))); + v_normal = (worldInverseTranspose * vec4(normal, 0)).xyz; + v_surfaceToLight = lightWorldPos - (world * position).xyz; + v_surfaceToView = (viewInverse[3] - (world * position)).xyz; + v_binormal = (worldInverseTranspose * vec4(binormal, 0)).xyz; // #normalMap + v_tangent = (worldInverseTranspose * vec4(tangent, 0)).xyz; // #normalMap + gl_Position = v_position; + gl_Position.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + + +__FRAGMENTSHADER__ + +precision mediump float; +uniform vec4 lightColor; +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_tangent; // #normalMap +varying vec3 v_binormal; // #normalMap +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; + +uniform vec4 ambient; +uniform sampler2D diffuse; +uniform vec4 specular; +uniform sampler2D normalMap; +uniform sampler2D reflectionMap; // #reflection +uniform samplerCube skybox; // #reflecton +uniform float shininess; +uniform float specularFactor; +uniform float fogPower; +uniform float fogMult; +uniform float fogOffset; +uniform vec4 fogColor; + + +vec4 lit(float l ,float h, float m) { + return vec4(1.0, + max(l, 0.0), + (l > 0.0) ? pow(max(0.0, h), m) : 0.0, + 1.0); +} +void main() { + vec4 diffuseColor = texture2D(diffuse, v_texCoord); + mat3 tangentToWorld = mat3(v_tangent, // #normalMap + v_binormal, // #normalMap + v_normal); // #normalMap + vec4 normalSpec = texture2D(normalMap, v_texCoord.xy); // #normalMap + vec4 reflection = texture2D(reflectionMap, v_texCoord.xy); // #reflection + vec3 tangentNormal = normalSpec.xyz - vec3(0.5, 0.5, 0.5); // #normalMap + vec3 normal = (tangentToWorld * tangentNormal); // #normalMap + normal = normalize(normal); // #normalMap + vec3 surfaceToLight = normalize(v_surfaceToLight); + vec3 surfaceToView = normalize(v_surfaceToView); + vec4 skyColor = textureCube(skybox, -reflect(surfaceToView, normal)); // #reflection + + vec3 halfVector = normalize(surfaceToLight + surfaceToView); + vec4 litR = lit(dot(normal, surfaceToLight), + dot(normal, halfVector), shininess); + vec4 outColor = vec4(mix( + skyColor, + lightColor * (diffuseColor * litR.y + diffuseColor * ambient + + specular * litR.z * specularFactor * normalSpec.a), + 1.0 - reflection.r).rgb, + diffuseColor.a); + outColor = mix(outColor, vec4(fogColor.rgb, diffuseColor.a), + clamp(pow((v_position.z / v_position.w), fogPower) * fogMult - fogOffset,0.0,1.0)); + + gl_FragColor = outColor; + gl_FragColor.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + +__ENDPROGRAM__ +__BEGINPROGRAM__ +__VERTEXSHADER__ + +uniform vec3 lightWorldPos; +uniform mat4 viewInverse; +uniform mat4 viewProjection; +uniform vec3 worldPosition; +uniform vec3 nextPosition; +uniform float scale; +uniform float time; +uniform float fishLength; +uniform float fishWaveLength; +uniform float fishBendAmount; +attribute vec4 position; +attribute vec3 normal; +attribute vec2 texCoord; +attribute vec3 tangent; // #normalMap +attribute vec3 binormal; // #normalMap +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_tangent; // #normalMap +varying vec3 v_binormal; // #normalMap +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; +void main() { + vec3 vz = normalize(worldPosition - nextPosition); + vec3 vx = normalize(cross(vec3(0,1,0), vz)); + vec3 vy = cross(vz, vx); + mat4 orientMat = mat4( + vec4(vx, 0), + vec4(vy, 0), + vec4(vz, 0), + vec4(worldPosition, 1)); + mat4 scaleMat = mat4( + vec4(scale, 0, 0, 0), + vec4(0, scale, 0, 0), + vec4(0, 0, scale, 0), + vec4(0, 0, 0, 1)); + mat4 world = orientMat * scaleMat; + mat4 worldViewProjection = viewProjection * world; + mat4 worldInverseTranspose = world; + + v_texCoord = texCoord; + // NOTE:If you change this you need to change the laser code to match! + float mult = position.z > 0.0 ? + (position.z / fishLength) : + (-position.z / fishLength * 2.0); + float s = sin(time + mult * fishWaveLength); + float a = sign(s); + float offset = pow(mult, 2.0) * s * fishBendAmount; + v_position = ( + worldViewProjection * + (position + + vec4(offset, 0, 0, 0))); + v_normal = (worldInverseTranspose * vec4(normal, 0)).xyz; + v_surfaceToLight = lightWorldPos - (world * position).xyz; + v_surfaceToView = (viewInverse[3] - (world * position)).xyz; + v_binormal = (worldInverseTranspose * vec4(binormal, 0)).xyz; // #normalMap + v_tangent = (worldInverseTranspose * vec4(tangent, 0)).xyz; // #normalMap + gl_Position = v_position; + gl_Position.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + + +__FRAGMENTSHADER__ + +precision mediump float; +uniform vec4 lightColor; +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_tangent; // #normalMap +varying vec3 v_binormal; // #normalMap +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; + +uniform vec4 ambient; +uniform sampler2D diffuse; +uniform vec4 specular; +uniform sampler2D normalMap; +uniform sampler2D reflectionMap; // #reflection +uniform samplerCube skybox; // #reflecton +uniform float shininess; +uniform float specularFactor; +// #fogUniforms + +vec4 lit(float l ,float h, float m) { + return vec4(1.0, + max(l, 0.0), + (l > 0.0) ? pow(max(0.0, h), m) : 0.0, + 1.0); +} +void main() { + vec4 diffuseColor = texture2D(diffuse, v_texCoord); + mat3 tangentToWorld = mat3(v_tangent, // #normalMap + v_binormal, // #normalMap + v_normal); // #normalMap + vec4 normalSpec = texture2D(normalMap, v_texCoord.xy); // #normalMap + vec4 reflection = texture2D(reflectionMap, v_texCoord.xy); // #reflection + vec3 tangentNormal = normalSpec.xyz - vec3(0.5, 0.5, 0.5); // #normalMap + vec3 normal = (tangentToWorld * tangentNormal); // #normalMap + normal = normalize(normal); // #normalMap + vec3 surfaceToLight = normalize(v_surfaceToLight); + vec3 surfaceToView = normalize(v_surfaceToView); + vec4 skyColor = textureCube(skybox, -reflect(surfaceToView, normal)); // #reflection + + vec3 halfVector = normalize(surfaceToLight + surfaceToView); + vec4 litR = lit(dot(normal, surfaceToLight), + dot(normal, halfVector), shininess); + vec4 outColor = vec4(mix( + skyColor, + lightColor * (diffuseColor * litR.y + diffuseColor * ambient + + specular * litR.z * specularFactor * normalSpec.a), + 1.0 - reflection.r).rgb, + diffuseColor.a); + // #fogCode + gl_FragColor = outColor; + gl_FragColor.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + +__ENDPROGRAM__ +__BEGINPROGRAM__ +__VERTEXSHADER__ + +uniform vec3 lightWorldPos; +uniform mat4 viewInverse; +uniform mat4 viewProjection; +uniform vec3 worldPosition; +uniform vec3 nextPosition; +uniform float scale; +uniform float time; +uniform float fishLength; +uniform float fishWaveLength; +uniform float fishBendAmount; +attribute vec4 position; +attribute vec3 normal; +attribute vec2 texCoord; +attribute vec3 tangent; // #normalMap +attribute vec3 binormal; // #normalMap +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_tangent; // #normalMap +varying vec3 v_binormal; // #normalMap +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; +void main() { + vec3 vz = normalize(worldPosition - nextPosition); + vec3 vx = normalize(cross(vec3(0,1,0), vz)); + vec3 vy = cross(vz, vx); + mat4 orientMat = mat4( + vec4(vx, 0), + vec4(vy, 0), + vec4(vz, 0), + vec4(worldPosition, 1)); + mat4 scaleMat = mat4( + vec4(scale, 0, 0, 0), + vec4(0, scale, 0, 0), + vec4(0, 0, scale, 0), + vec4(0, 0, 0, 1)); + mat4 world = orientMat * scaleMat; + mat4 worldViewProjection = viewProjection * world; + mat4 worldInverseTranspose = world; + + v_texCoord = texCoord; + // NOTE:If you change this you need to change the laser code to match! + float mult = position.z > 0.0 ? + (position.z / fishLength) : + (-position.z / fishLength * 2.0); + float s = sin(time + mult * fishWaveLength); + float a = sign(s); + float offset = pow(mult, 2.0) * s * fishBendAmount; + v_position = ( + worldViewProjection * + (position + + vec4(offset, 0, 0, 0))); + v_normal = (worldInverseTranspose * vec4(normal, 0)).xyz; + v_surfaceToLight = lightWorldPos - (world * position).xyz; + v_surfaceToView = (viewInverse[3] - (world * position)).xyz; + v_binormal = (worldInverseTranspose * vec4(binormal, 0)).xyz; // #normalMap + v_tangent = (worldInverseTranspose * vec4(tangent, 0)).xyz; // #normalMap + gl_Position = v_position; + gl_Position.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + + +__FRAGMENTSHADER__ + +precision mediump float; +uniform vec4 lightColor; +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_tangent; // #normalMap +varying vec3 v_binormal; // #normalMap +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; + +uniform vec4 ambient; +uniform sampler2D diffuse; +uniform vec4 specular; +uniform sampler2D normalMap; +uniform samplerCube skybox; // #reflecton +uniform float shininess; +uniform float specularFactor; +uniform float fogPower; +uniform float fogMult; +uniform float fogOffset; +uniform vec4 fogColor; + + +vec4 lit(float l ,float h, float m) { + return vec4(1.0, + max(l, 0.0), + (l > 0.0) ? pow(max(0.0, h), m) : 0.0, + 1.0); +} +void main() { + vec4 diffuseColor = texture2D(diffuse, v_texCoord); + mat3 tangentToWorld = mat3(v_tangent, // #normalMap + v_binormal, // #normalMap + v_normal); // #normalMap + vec4 normalSpec = texture2D(normalMap, v_texCoord.xy); // #normalMap + vec4 reflection = vec4(0,0,0,0); // #noReflection + vec3 tangentNormal = normalSpec.xyz - vec3(0.5, 0.5, 0.5); // #normalMap + vec3 normal = (tangentToWorld * tangentNormal); // #normalMap + normal = normalize(normal); // #normalMap + vec3 surfaceToLight = normalize(v_surfaceToLight); + vec3 surfaceToView = normalize(v_surfaceToView); + vec4 skyColor = vec4(0.5,0.5,1,1); // #noReflection + + vec3 halfVector = normalize(surfaceToLight + surfaceToView); + vec4 litR = lit(dot(normal, surfaceToLight), + dot(normal, halfVector), shininess); + vec4 outColor = vec4(mix( + skyColor, + lightColor * (diffuseColor * litR.y + diffuseColor * ambient + + specular * litR.z * specularFactor * normalSpec.a), + 1.0 - reflection.r).rgb, + diffuseColor.a); + outColor = mix(outColor, vec4(fogColor.rgb, diffuseColor.a), + clamp(pow((v_position.z / v_position.w), fogPower) * fogMult - fogOffset,0.0,1.0)); + + gl_FragColor = outColor; + gl_FragColor.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + +__ENDPROGRAM__ +__BEGINPROGRAM__ +__VERTEXSHADER__ + +uniform vec3 lightWorldPos; +uniform mat4 viewInverse; +uniform mat4 viewProjection; +uniform vec3 worldPosition; +uniform vec3 nextPosition; +uniform float scale; +uniform float time; +uniform float fishLength; +uniform float fishWaveLength; +uniform float fishBendAmount; +attribute vec4 position; +attribute vec3 normal; +attribute vec2 texCoord; +attribute vec3 tangent; // #normalMap +attribute vec3 binormal; // #normalMap +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_tangent; // #normalMap +varying vec3 v_binormal; // #normalMap +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; +void main() { + vec3 vz = normalize(worldPosition - nextPosition); + vec3 vx = normalize(cross(vec3(0,1,0), vz)); + vec3 vy = cross(vz, vx); + mat4 orientMat = mat4( + vec4(vx, 0), + vec4(vy, 0), + vec4(vz, 0), + vec4(worldPosition, 1)); + mat4 scaleMat = mat4( + vec4(scale, 0, 0, 0), + vec4(0, scale, 0, 0), + vec4(0, 0, scale, 0), + vec4(0, 0, 0, 1)); + mat4 world = orientMat * scaleMat; + mat4 worldViewProjection = viewProjection * world; + mat4 worldInverseTranspose = world; + + v_texCoord = texCoord; + // NOTE:If you change this you need to change the laser code to match! + float mult = position.z > 0.0 ? + (position.z / fishLength) : + (-position.z / fishLength * 2.0); + float s = sin(time + mult * fishWaveLength); + float a = sign(s); + float offset = pow(mult, 2.0) * s * fishBendAmount; + v_position = ( + worldViewProjection * + (position + + vec4(offset, 0, 0, 0))); + v_normal = (worldInverseTranspose * vec4(normal, 0)).xyz; + v_surfaceToLight = lightWorldPos - (world * position).xyz; + v_surfaceToView = (viewInverse[3] - (world * position)).xyz; + v_binormal = (worldInverseTranspose * vec4(binormal, 0)).xyz; // #normalMap + v_tangent = (worldInverseTranspose * vec4(tangent, 0)).xyz; // #normalMap + gl_Position = v_position; + gl_Position.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + + +__FRAGMENTSHADER__ + +precision mediump float; +uniform vec4 lightColor; +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_tangent; // #normalMap +varying vec3 v_binormal; // #normalMap +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; + +uniform vec4 ambient; +uniform sampler2D diffuse; +uniform vec4 specular; +uniform sampler2D normalMap; +uniform samplerCube skybox; // #reflecton +uniform float shininess; +uniform float specularFactor; +// #fogUniforms + +vec4 lit(float l ,float h, float m) { + return vec4(1.0, + max(l, 0.0), + (l > 0.0) ? pow(max(0.0, h), m) : 0.0, + 1.0); +} +void main() { + vec4 diffuseColor = texture2D(diffuse, v_texCoord); + mat3 tangentToWorld = mat3(v_tangent, // #normalMap + v_binormal, // #normalMap + v_normal); // #normalMap + vec4 normalSpec = texture2D(normalMap, v_texCoord.xy); // #normalMap + vec4 reflection = vec4(0,0,0,0); // #noReflection + vec3 tangentNormal = normalSpec.xyz - vec3(0.5, 0.5, 0.5); // #normalMap + vec3 normal = (tangentToWorld * tangentNormal); // #normalMap + normal = normalize(normal); // #normalMap + vec3 surfaceToLight = normalize(v_surfaceToLight); + vec3 surfaceToView = normalize(v_surfaceToView); + vec4 skyColor = vec4(0.5,0.5,1,1); // #noReflection + + vec3 halfVector = normalize(surfaceToLight + surfaceToView); + vec4 litR = lit(dot(normal, surfaceToLight), + dot(normal, halfVector), shininess); + vec4 outColor = vec4(mix( + skyColor, + lightColor * (diffuseColor * litR.y + diffuseColor * ambient + + specular * litR.z * specularFactor * normalSpec.a), + 1.0 - reflection.r).rgb, + diffuseColor.a); + // #fogCode + gl_FragColor = outColor; + gl_FragColor.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + +__ENDPROGRAM__ +__BEGINPROGRAM__ +__VERTEXSHADER__ + +uniform vec3 lightWorldPos; +uniform mat4 viewInverse; +uniform mat4 viewProjection; +uniform vec3 worldPosition; +uniform vec3 nextPosition; +uniform float scale; +uniform float time; +uniform float fishLength; +uniform float fishWaveLength; +uniform float fishBendAmount; +attribute vec4 position; +attribute vec3 normal; +attribute vec2 texCoord; +attribute vec3 tangent; // #normalMap +attribute vec3 binormal; // #normalMap +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_tangent; // #normalMap +varying vec3 v_binormal; // #normalMap +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; +void main() { + vec3 vz = normalize(worldPosition - nextPosition); + vec3 vx = normalize(cross(vec3(0,1,0), vz)); + vec3 vy = cross(vz, vx); + mat4 orientMat = mat4( + vec4(vx, 0), + vec4(vy, 0), + vec4(vz, 0), + vec4(worldPosition, 1)); + mat4 scaleMat = mat4( + vec4(scale, 0, 0, 0), + vec4(0, scale, 0, 0), + vec4(0, 0, scale, 0), + vec4(0, 0, 0, 1)); + mat4 world = orientMat * scaleMat; + mat4 worldViewProjection = viewProjection * world; + mat4 worldInverseTranspose = world; + + v_texCoord = texCoord; + // NOTE:If you change this you need to change the laser code to match! + float mult = position.z > 0.0 ? + (position.z / fishLength) : + (-position.z / fishLength * 2.0); + float s = sin(time + mult * fishWaveLength); + float a = sign(s); + float offset = pow(mult, 2.0) * s * fishBendAmount; + v_position = ( + worldViewProjection * + (position + + vec4(offset, 0, 0, 0))); + v_normal = (worldInverseTranspose * vec4(normal, 0)).xyz; + v_surfaceToLight = lightWorldPos - (world * position).xyz; + v_surfaceToView = (viewInverse[3] - (world * position)).xyz; + v_binormal = (worldInverseTranspose * vec4(binormal, 0)).xyz; // #normalMap + v_tangent = (worldInverseTranspose * vec4(tangent, 0)).xyz; // #normalMap + gl_Position = v_position; + gl_Position.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + + +__FRAGMENTSHADER__ + +precision mediump float; +uniform vec4 lightColor; +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; + +uniform vec4 ambient; +uniform sampler2D diffuse; +uniform vec4 specular; +uniform sampler2D normalMap; +uniform samplerCube skybox; // #reflecton +uniform float shininess; +uniform float specularFactor; +uniform float fogPower; +uniform float fogMult; +uniform float fogOffset; +uniform vec4 fogColor; + + +vec4 lit(float l ,float h, float m) { + return vec4(1.0, + max(l, 0.0), + (l > 0.0) ? pow(max(0.0, h), m) : 0.0, + 1.0); +} +void main() { + vec4 diffuseColor = texture2D(diffuse, v_texCoord); + vec4 normalSpec = vec4(0,0,0,0); // #noNormalMap + vec4 reflection = vec4(0,0,0,0); // #noReflection + vec3 normal = normalize(v_normal); // #noNormalMap + vec3 surfaceToLight = normalize(v_surfaceToLight); + vec3 surfaceToView = normalize(v_surfaceToView); + vec4 skyColor = vec4(0.5,0.5,1,1); // #noReflection + + vec3 halfVector = normalize(surfaceToLight + surfaceToView); + vec4 litR = lit(dot(normal, surfaceToLight), + dot(normal, halfVector), shininess); + vec4 outColor = vec4(mix( + skyColor, + lightColor * (diffuseColor * litR.y + diffuseColor * ambient + + specular * litR.z * specularFactor * normalSpec.a), + 1.0 - reflection.r).rgb, + diffuseColor.a); + outColor = mix(outColor, vec4(fogColor.rgb, diffuseColor.a), + clamp(pow((v_position.z / v_position.w), fogPower) * fogMult - fogOffset,0.0,1.0)); + + gl_FragColor = outColor; + gl_FragColor.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + +__ENDPROGRAM__ +__BEGINPROGRAM__ +__VERTEXSHADER__ + +uniform vec3 lightWorldPos; +uniform mat4 viewInverse; +uniform mat4 viewProjection; +uniform vec3 worldPosition; +uniform vec3 nextPosition; +uniform float scale; +uniform float time; +uniform float fishLength; +uniform float fishWaveLength; +uniform float fishBendAmount; +attribute vec4 position; +attribute vec3 normal; +attribute vec2 texCoord; +attribute vec3 tangent; // #normalMap +attribute vec3 binormal; // #normalMap +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_tangent; // #normalMap +varying vec3 v_binormal; // #normalMap +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; +void main() { + vec3 vz = normalize(worldPosition - nextPosition); + vec3 vx = normalize(cross(vec3(0,1,0), vz)); + vec3 vy = cross(vz, vx); + mat4 orientMat = mat4( + vec4(vx, 0), + vec4(vy, 0), + vec4(vz, 0), + vec4(worldPosition, 1)); + mat4 scaleMat = mat4( + vec4(scale, 0, 0, 0), + vec4(0, scale, 0, 0), + vec4(0, 0, scale, 0), + vec4(0, 0, 0, 1)); + mat4 world = orientMat * scaleMat; + mat4 worldViewProjection = viewProjection * world; + mat4 worldInverseTranspose = world; + + v_texCoord = texCoord; + // NOTE:If you change this you need to change the laser code to match! + float mult = position.z > 0.0 ? + (position.z / fishLength) : + (-position.z / fishLength * 2.0); + float s = sin(time + mult * fishWaveLength); + float a = sign(s); + float offset = pow(mult, 2.0) * s * fishBendAmount; + v_position = ( + worldViewProjection * + (position + + vec4(offset, 0, 0, 0))); + v_normal = (worldInverseTranspose * vec4(normal, 0)).xyz; + v_surfaceToLight = lightWorldPos - (world * position).xyz; + v_surfaceToView = (viewInverse[3] - (world * position)).xyz; + v_binormal = (worldInverseTranspose * vec4(binormal, 0)).xyz; // #normalMap + v_tangent = (worldInverseTranspose * vec4(tangent, 0)).xyz; // #normalMap + gl_Position = v_position; + gl_Position.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + + +__FRAGMENTSHADER__ + +precision mediump float; +uniform vec4 lightColor; +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; + +uniform vec4 ambient; +uniform sampler2D diffuse; +uniform vec4 specular; +uniform sampler2D normalMap; +uniform samplerCube skybox; // #reflecton +uniform float shininess; +uniform float specularFactor; +// #fogUniforms + +vec4 lit(float l ,float h, float m) { + return vec4(1.0, + max(l, 0.0), + (l > 0.0) ? pow(max(0.0, h), m) : 0.0, + 1.0); +} +void main() { + vec4 diffuseColor = texture2D(diffuse, v_texCoord); + vec4 normalSpec = vec4(0,0,0,0); // #noNormalMap + vec4 reflection = vec4(0,0,0,0); // #noReflection + vec3 normal = normalize(v_normal); // #noNormalMap + vec3 surfaceToLight = normalize(v_surfaceToLight); + vec3 surfaceToView = normalize(v_surfaceToView); + vec4 skyColor = vec4(0.5,0.5,1,1); // #noReflection + + vec3 halfVector = normalize(surfaceToLight + surfaceToView); + vec4 litR = lit(dot(normal, surfaceToLight), + dot(normal, halfVector), shininess); + vec4 outColor = vec4(mix( + skyColor, + lightColor * (diffuseColor * litR.y + diffuseColor * ambient + + specular * litR.z * specularFactor * normalSpec.a), + 1.0 - reflection.r).rgb, + diffuseColor.a); + // #fogCode + gl_FragColor = outColor; + gl_FragColor.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + +__ENDPROGRAM__ +__BEGINPROGRAM__ +__VERTEXSHADER__ + +uniform vec3 lightWorldPos; +uniform mat4 viewInverse; +uniform mat4 viewProjection; +uniform vec3 worldPosition; +uniform vec3 nextPosition; +uniform float scale; +uniform float time; +uniform float fishLength; +uniform float fishWaveLength; +uniform float fishBendAmount; +attribute vec4 position; +attribute vec3 normal; +attribute vec2 texCoord; +attribute vec3 tangent; // #normalMap +attribute vec3 binormal; // #normalMap +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_tangent; // #normalMap +varying vec3 v_binormal; // #normalMap +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; +void main() { + vec3 vz = normalize(worldPosition - nextPosition); + vec3 vx = normalize(cross(vec3(0,1,0), vz)); + vec3 vy = cross(vz, vx); + mat4 orientMat = mat4( + vec4(vx, 0), + vec4(vy, 0), + vec4(vz, 0), + vec4(worldPosition, 1)); + mat4 scaleMat = mat4( + vec4(scale, 0, 0, 0), + vec4(0, scale, 0, 0), + vec4(0, 0, scale, 0), + vec4(0, 0, 0, 1)); + mat4 world = orientMat * scaleMat; + mat4 worldViewProjection = viewProjection * world; + mat4 worldInverseTranspose = world; + + v_texCoord = texCoord; + // NOTE:If you change this you need to change the laser code to match! + float mult = position.z > 0.0 ? + (position.z / fishLength) : + (-position.z / fishLength * 2.0); + float s = sin(time + mult * fishWaveLength); + float a = sign(s); + float offset = pow(mult, 2.0) * s * fishBendAmount; + v_position = ( + worldViewProjection * + (position + + vec4(offset, 0, 0, 0))); + v_normal = (worldInverseTranspose * vec4(normal, 0)).xyz; + v_surfaceToLight = lightWorldPos - (world * position).xyz; + v_surfaceToView = (viewInverse[3] - (world * position)).xyz; + v_binormal = (worldInverseTranspose * vec4(binormal, 0)).xyz; // #normalMap + v_tangent = (worldInverseTranspose * vec4(tangent, 0)).xyz; // #normalMap + gl_Position = v_position; + gl_Position.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + + +__FRAGMENTSHADER__ + +precision mediump float; +uniform vec4 lightColor; +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_tangent; // #normalMap +varying vec3 v_binormal; // #normalMap +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; + +uniform vec4 ambient; +uniform sampler2D diffuse; +uniform vec4 specular; +uniform sampler2D normalMap; // #normalMap +uniform float shininess; +uniform float specularFactor; +uniform float fogPower; +uniform float fogMult; +uniform float fogOffset; +uniform vec4 fogColor; + + +vec4 lit(float l ,float h, float m) { + return vec4(1.0, + max(l, 0.0), + (l > 0.0) ? pow(max(0.0, h), m) : 0.0, + 1.0); +} +void main() { + vec4 diffuseColor = texture2D(diffuse, v_texCoord); + mat3 tangentToWorld = mat3(v_tangent, // #normalMap + v_binormal, // #normalMap + v_normal); // #normalMap + vec4 normalSpec = texture2D(normalMap, v_texCoord.xy); // #normalMap + vec3 tangentNormal = normalSpec.xyz - vec3(0.5, 0.5, 0.5); // #normalMap + tangentNormal = normalize(tangentNormal + vec3(0, 0, 2)); // #normalMap + vec3 normal = (tangentToWorld * tangentNormal); // #normalMap + normal = normalize(normal); // #normalMap + vec3 surfaceToLight = normalize(v_surfaceToLight); + vec3 surfaceToView = normalize(v_surfaceToView); + vec3 halfVector = normalize(surfaceToLight + surfaceToView); + vec4 litR = lit(dot(normal, surfaceToLight), + dot(normal, halfVector), shininess); + vec4 outColor = vec4( + (lightColor * (diffuseColor * litR.y + diffuseColor * ambient + + specular * litR.z * specularFactor * normalSpec.a)).rgb, + diffuseColor.a); + outColor = mix(outColor, vec4(fogColor.rgb, diffuseColor.a), + clamp(pow((v_position.z / v_position.w), fogPower) * fogMult - fogOffset,0.0,1.0)); + + gl_FragColor = outColor; + gl_FragColor.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + +__ENDPROGRAM__ +__BEGINPROGRAM__ +__VERTEXSHADER__ + +uniform vec3 lightWorldPos; +uniform mat4 viewInverse; +uniform mat4 viewProjection; +uniform vec3 worldPosition; +uniform vec3 nextPosition; +uniform float scale; +uniform float time; +uniform float fishLength; +uniform float fishWaveLength; +uniform float fishBendAmount; +attribute vec4 position; +attribute vec3 normal; +attribute vec2 texCoord; +attribute vec3 tangent; // #normalMap +attribute vec3 binormal; // #normalMap +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_tangent; // #normalMap +varying vec3 v_binormal; // #normalMap +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; +void main() { + vec3 vz = normalize(worldPosition - nextPosition); + vec3 vx = normalize(cross(vec3(0,1,0), vz)); + vec3 vy = cross(vz, vx); + mat4 orientMat = mat4( + vec4(vx, 0), + vec4(vy, 0), + vec4(vz, 0), + vec4(worldPosition, 1)); + mat4 scaleMat = mat4( + vec4(scale, 0, 0, 0), + vec4(0, scale, 0, 0), + vec4(0, 0, scale, 0), + vec4(0, 0, 0, 1)); + mat4 world = orientMat * scaleMat; + mat4 worldViewProjection = viewProjection * world; + mat4 worldInverseTranspose = world; + + v_texCoord = texCoord; + // NOTE:If you change this you need to change the laser code to match! + float mult = position.z > 0.0 ? + (position.z / fishLength) : + (-position.z / fishLength * 2.0); + float s = sin(time + mult * fishWaveLength); + float a = sign(s); + float offset = pow(mult, 2.0) * s * fishBendAmount; + v_position = ( + worldViewProjection * + (position + + vec4(offset, 0, 0, 0))); + v_normal = (worldInverseTranspose * vec4(normal, 0)).xyz; + v_surfaceToLight = lightWorldPos - (world * position).xyz; + v_surfaceToView = (viewInverse[3] - (world * position)).xyz; + v_binormal = (worldInverseTranspose * vec4(binormal, 0)).xyz; // #normalMap + v_tangent = (worldInverseTranspose * vec4(tangent, 0)).xyz; // #normalMap + gl_Position = v_position; + gl_Position.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + + +__FRAGMENTSHADER__ + +precision mediump float; +uniform vec4 lightColor; +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_tangent; // #normalMap +varying vec3 v_binormal; // #normalMap +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; + +uniform vec4 ambient; +uniform sampler2D diffuse; +uniform vec4 specular; +uniform sampler2D normalMap; // #normalMap +uniform float shininess; +uniform float specularFactor; +// #fogUniforms + +vec4 lit(float l ,float h, float m) { + return vec4(1.0, + max(l, 0.0), + (l > 0.0) ? pow(max(0.0, h), m) : 0.0, + 1.0); +} +void main() { + vec4 diffuseColor = texture2D(diffuse, v_texCoord); + mat3 tangentToWorld = mat3(v_tangent, // #normalMap + v_binormal, // #normalMap + v_normal); // #normalMap + vec4 normalSpec = texture2D(normalMap, v_texCoord.xy); // #normalMap + vec3 tangentNormal = normalSpec.xyz - vec3(0.5, 0.5, 0.5); // #normalMap + tangentNormal = normalize(tangentNormal + vec3(0, 0, 2)); // #normalMap + vec3 normal = (tangentToWorld * tangentNormal); // #normalMap + normal = normalize(normal); // #normalMap + vec3 surfaceToLight = normalize(v_surfaceToLight); + vec3 surfaceToView = normalize(v_surfaceToView); + vec3 halfVector = normalize(surfaceToLight + surfaceToView); + vec4 litR = lit(dot(normal, surfaceToLight), + dot(normal, halfVector), shininess); + vec4 outColor = vec4( + (lightColor * (diffuseColor * litR.y + diffuseColor * ambient + + specular * litR.z * specularFactor * normalSpec.a)).rgb, + diffuseColor.a); + // #fogCode + gl_FragColor = outColor; + gl_FragColor.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + +__ENDPROGRAM__ +__BEGINPROGRAM__ +__VERTEXSHADER__ + +uniform vec3 lightWorldPos; +uniform mat4 viewInverse; +uniform mat4 viewProjection; +uniform vec3 worldPosition; +uniform vec3 nextPosition; +uniform float scale; +uniform float time; +uniform float fishLength; +uniform float fishWaveLength; +uniform float fishBendAmount; +attribute vec4 position; +attribute vec3 normal; +attribute vec2 texCoord; +attribute vec3 tangent; // #normalMap +attribute vec3 binormal; // #normalMap +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_tangent; // #normalMap +varying vec3 v_binormal; // #normalMap +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; +void main() { + vec3 vz = normalize(worldPosition - nextPosition); + vec3 vx = normalize(cross(vec3(0,1,0), vz)); + vec3 vy = cross(vz, vx); + mat4 orientMat = mat4( + vec4(vx, 0), + vec4(vy, 0), + vec4(vz, 0), + vec4(worldPosition, 1)); + mat4 scaleMat = mat4( + vec4(scale, 0, 0, 0), + vec4(0, scale, 0, 0), + vec4(0, 0, scale, 0), + vec4(0, 0, 0, 1)); + mat4 world = orientMat * scaleMat; + mat4 worldViewProjection = viewProjection * world; + mat4 worldInverseTranspose = world; + + v_texCoord = texCoord; + // NOTE:If you change this you need to change the laser code to match! + float mult = position.z > 0.0 ? + (position.z / fishLength) : + (-position.z / fishLength * 2.0); + float s = sin(time + mult * fishWaveLength); + float a = sign(s); + float offset = pow(mult, 2.0) * s * fishBendAmount; + v_position = ( + worldViewProjection * + (position + + vec4(offset, 0, 0, 0))); + v_normal = (worldInverseTranspose * vec4(normal, 0)).xyz; + v_surfaceToLight = lightWorldPos - (world * position).xyz; + v_surfaceToView = (viewInverse[3] - (world * position)).xyz; + v_binormal = (worldInverseTranspose * vec4(binormal, 0)).xyz; // #normalMap + v_tangent = (worldInverseTranspose * vec4(tangent, 0)).xyz; // #normalMap + gl_Position = v_position; + gl_Position.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + + +__FRAGMENTSHADER__ + +precision mediump float; +uniform vec4 lightColor; +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; + +uniform vec4 ambient; +uniform sampler2D diffuse; +uniform vec4 specular; +uniform float shininess; +uniform float specularFactor; +uniform float fogPower; +uniform float fogMult; +uniform float fogOffset; +uniform vec4 fogColor; + + +vec4 lit(float l ,float h, float m) { + return vec4(1.0, + max(l, 0.0), + (l > 0.0) ? pow(max(0.0, h), m) : 0.0, + 1.0); +} +void main() { + vec4 diffuseColor = texture2D(diffuse, v_texCoord); + vec4 normalSpec = vec4(0,0,0,0); // #noNormalMap + vec3 normal = normalize(v_normal); // #noNormalMap + vec3 surfaceToLight = normalize(v_surfaceToLight); + vec3 surfaceToView = normalize(v_surfaceToView); + vec3 halfVector = normalize(surfaceToLight + surfaceToView); + vec4 litR = lit(dot(normal, surfaceToLight), + dot(normal, halfVector), shininess); + vec4 outColor = vec4( + (lightColor * (diffuseColor * litR.y + diffuseColor * ambient + + specular * litR.z * specularFactor * normalSpec.a)).rgb, + diffuseColor.a); + outColor = mix(outColor, vec4(fogColor.rgb, diffuseColor.a), + clamp(pow((v_position.z / v_position.w), fogPower) * fogMult - fogOffset,0.0,1.0)); + + gl_FragColor = outColor; + gl_FragColor.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + +__ENDPROGRAM__ +__BEGINPROGRAM__ +__VERTEXSHADER__ + +uniform vec3 lightWorldPos; +uniform mat4 viewInverse; +uniform mat4 viewProjection; +uniform vec3 worldPosition; +uniform vec3 nextPosition; +uniform float scale; +uniform float time; +uniform float fishLength; +uniform float fishWaveLength; +uniform float fishBendAmount; +attribute vec4 position; +attribute vec3 normal; +attribute vec2 texCoord; +attribute vec3 tangent; // #normalMap +attribute vec3 binormal; // #normalMap +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_tangent; // #normalMap +varying vec3 v_binormal; // #normalMap +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; +void main() { + vec3 vz = normalize(worldPosition - nextPosition); + vec3 vx = normalize(cross(vec3(0,1,0), vz)); + vec3 vy = cross(vz, vx); + mat4 orientMat = mat4( + vec4(vx, 0), + vec4(vy, 0), + vec4(vz, 0), + vec4(worldPosition, 1)); + mat4 scaleMat = mat4( + vec4(scale, 0, 0, 0), + vec4(0, scale, 0, 0), + vec4(0, 0, scale, 0), + vec4(0, 0, 0, 1)); + mat4 world = orientMat * scaleMat; + mat4 worldViewProjection = viewProjection * world; + mat4 worldInverseTranspose = world; + + v_texCoord = texCoord; + // NOTE:If you change this you need to change the laser code to match! + float mult = position.z > 0.0 ? + (position.z / fishLength) : + (-position.z / fishLength * 2.0); + float s = sin(time + mult * fishWaveLength); + float a = sign(s); + float offset = pow(mult, 2.0) * s * fishBendAmount; + v_position = ( + worldViewProjection * + (position + + vec4(offset, 0, 0, 0))); + v_normal = (worldInverseTranspose * vec4(normal, 0)).xyz; + v_surfaceToLight = lightWorldPos - (world * position).xyz; + v_surfaceToView = (viewInverse[3] - (world * position)).xyz; + v_binormal = (worldInverseTranspose * vec4(binormal, 0)).xyz; // #normalMap + v_tangent = (worldInverseTranspose * vec4(tangent, 0)).xyz; // #normalMap + gl_Position = v_position; + gl_Position.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + + +__FRAGMENTSHADER__ + +precision mediump float; +uniform vec4 lightColor; +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; + +uniform vec4 ambient; +uniform sampler2D diffuse; +uniform vec4 specular; +uniform float shininess; +uniform float specularFactor; +// #fogUniforms + +vec4 lit(float l ,float h, float m) { + return vec4(1.0, + max(l, 0.0), + (l > 0.0) ? pow(max(0.0, h), m) : 0.0, + 1.0); +} +void main() { + vec4 diffuseColor = texture2D(diffuse, v_texCoord); + vec4 normalSpec = vec4(0,0,0,0); // #noNormalMap + vec3 normal = normalize(v_normal); // #noNormalMap + vec3 surfaceToLight = normalize(v_surfaceToLight); + vec3 surfaceToView = normalize(v_surfaceToView); + vec3 halfVector = normalize(surfaceToLight + surfaceToView); + vec4 litR = lit(dot(normal, surfaceToLight), + dot(normal, halfVector), shininess); + vec4 outColor = vec4( + (lightColor * (diffuseColor * litR.y + diffuseColor * ambient + + specular * litR.z * specularFactor * normalSpec.a)).rgb, + diffuseColor.a); + // #fogCode + gl_FragColor = outColor; + gl_FragColor.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + +__ENDPROGRAM__ +__BEGINPROGRAM__ +__VERTEXSHADER__ + +uniform mat4 worldViewProjection; +uniform vec3 lightWorldPos; +uniform mat4 world; +uniform mat4 viewInverse; +uniform mat4 worldInverseTranspose; +attribute vec4 position; +attribute vec3 normal; +attribute vec2 texCoord; +attribute vec3 tangent; +attribute vec3 binormal; +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_tangent; // #normalMap +varying vec3 v_binormal; // #normalMap +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; +void main() { + v_texCoord = texCoord; + v_position = (worldViewProjection * position); + v_normal = (worldInverseTranspose * vec4(normal, 0)).xyz; + v_surfaceToLight = lightWorldPos - (world * position).xyz; + v_surfaceToView = (viewInverse[3] - (world * position)).xyz; + v_binormal = (worldInverseTranspose * vec4(binormal, 0)).xyz; // #normalMap + v_tangent = (worldInverseTranspose * vec4(tangent, 0)).xyz; // #normalMap + gl_Position = v_position; + gl_Position.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + + +__FRAGMENTSHADER__ + +precision mediump float; +uniform vec4 lightColor; +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_tangent; // #normalMap +varying vec3 v_binormal; // #normalMap +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; + +uniform sampler2D diffuse; +uniform vec4 specular; +uniform sampler2D normalMap; // #normalMap +uniform sampler2D reflectionMap; +uniform samplerCube skybox; +uniform float shininess; +uniform float specularFactor; + +vec4 lit(float l ,float h, float m) { + return vec4(1.0, + max(l, 0.0), + (l > 0.0) ? pow(max(0.0, h), m) : 0.0, + 1.0); +} +void main() { + vec4 diffuseColor = texture2D(diffuse, v_texCoord); + mat3 tangentToWorld = mat3(v_tangent, // #normalMap + v_binormal, // #normalMap + v_normal); // #normalMap + vec4 normalSpec = texture2D(normalMap, v_texCoord.xy); // #normalMap + vec4 reflection = texture2D(reflectionMap, v_texCoord.xy); + vec3 tangentNormal = normalSpec.xyz - vec3(0.5, 0.5, 0.5); // #normalMap +// tangentNormal = normalize(tangentNormal + vec3(0,0,refractionFudge)); + vec3 normal = (tangentToWorld * tangentNormal); // #normalMap + normal = normalize(normal); // #normalMap + + vec3 surfaceToLight = normalize(v_surfaceToLight); + vec3 surfaceToView = normalize(v_surfaceToView); + + vec4 skyColor = textureCube(skybox, -reflect(surfaceToView, normal)); + float fudgeAmount = 1.1; + vec3 fudge = skyColor.rgb * vec3(fudgeAmount, fudgeAmount, fudgeAmount); + float bright = min(1.0, fudge.r * fudge.g * fudge.b); + vec4 reflectColor = + mix(vec4(skyColor.rgb, bright), + diffuseColor, + (1.0 - reflection.r)); + float r = abs(dot(surfaceToView, normal)); + gl_FragColor = vec4(mix( + skyColor, + reflectColor, + ((r + 0.3) * (reflection.r))).rgb, 1.0 - r); + gl_FragColor.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + +__ENDPROGRAM__ +__BEGINPROGRAM__ +__VERTEXSHADER__ + +uniform mat4 worldViewProjection; +uniform vec3 lightWorldPos; +uniform mat4 world; +uniform mat4 viewInverse; +uniform mat4 worldInverseTranspose; +attribute vec4 position; +attribute vec3 normal; +attribute vec2 texCoord; +attribute vec3 tangent; +attribute vec3 binormal; +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_tangent; // #normalMap +varying vec3 v_binormal; // #normalMap +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; +void main() { + v_texCoord = texCoord; + v_position = (worldViewProjection * position); + v_normal = (worldInverseTranspose * vec4(normal, 0)).xyz; + v_surfaceToLight = lightWorldPos - (world * position).xyz; + v_surfaceToView = (viewInverse[3] - (world * position)).xyz; + v_binormal = (worldInverseTranspose * vec4(binormal, 0)).xyz; // #normalMap + v_tangent = (worldInverseTranspose * vec4(tangent, 0)).xyz; // #normalMap + gl_Position = v_position; + gl_Position.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + + +__FRAGMENTSHADER__ + +precision mediump float; +uniform vec4 lightColor; +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; + +uniform sampler2D diffuse; +uniform vec4 specular; +uniform sampler2D reflectionMap; +uniform samplerCube skybox; +uniform float shininess; +uniform float specularFactor; + +vec4 lit(float l ,float h, float m) { + return vec4(1.0, + max(l, 0.0), + (l > 0.0) ? pow(max(0.0, h), m) : 0.0, + 1.0); +} +void main() { + vec4 diffuseColor = texture2D(diffuse, v_texCoord); + vec4 normalSpec = vec4(0,0,0,0); // #noNormalMap + vec4 reflection = texture2D(reflectionMap, v_texCoord.xy); +// tangentNormal = normalize(tangentNormal + vec3(0,0,refractionFudge)); + vec3 normal = normalize(v_normal); // #noNormalMap + + vec3 surfaceToLight = normalize(v_surfaceToLight); + vec3 surfaceToView = normalize(v_surfaceToView); + + vec4 skyColor = textureCube(skybox, -reflect(surfaceToView, normal)); + float fudgeAmount = 1.1; + vec3 fudge = skyColor.rgb * vec3(fudgeAmount, fudgeAmount, fudgeAmount); + float bright = min(1.0, fudge.r * fudge.g * fudge.b); + vec4 reflectColor = + mix(vec4(skyColor.rgb, bright), + diffuseColor, + (1.0 - reflection.r)); + float r = abs(dot(surfaceToView, normal)); + gl_FragColor = vec4(mix( + skyColor, + reflectColor, + ((r + 0.3) * (reflection.r))).rgb, 1.0 - r); + gl_FragColor.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + +__ENDPROGRAM__ +__BEGINPROGRAM__ +__VERTEXSHADER__ + +uniform mat4 worldViewProjection; +uniform vec3 lightWorldPos; +uniform mat4 world; +uniform mat4 viewInverse; +uniform mat4 worldInverseTranspose; +attribute vec4 position; +attribute vec3 normal; +attribute vec2 texCoord; +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; +void main() { + v_texCoord = texCoord; + v_position = (worldViewProjection * position); + v_normal = (worldInverseTranspose * vec4(normal, 0)).xyz; + v_surfaceToLight = lightWorldPos - (world * position).xyz; + v_surfaceToView = (viewInverse[3] - (world * position)).xyz; + gl_Position = v_position; + gl_Position.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + + +__FRAGMENTSHADER__ + +precision mediump float; +uniform vec4 lightColor; +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; + +uniform vec4 ambient; +uniform sampler2D diffuse; +uniform vec4 specular; +uniform float shininess; +uniform float specularFactor; +uniform float fogPower; +uniform float fogMult; +uniform float fogOffset; +uniform vec4 fogColor; + + +vec4 lit(float l ,float h, float m) { + return vec4(1.0, + max(l, 0.0), + (l > 0.0) ? pow(max(0.0, h), m) : 0.0, + 1.0); +} +void main() { + vec4 diffuseColor = texture2D(diffuse, v_texCoord); + vec3 normal = normalize(v_normal); + vec3 surfaceToLight = normalize(v_surfaceToLight); + vec3 surfaceToView = normalize(v_surfaceToView); + vec3 halfVector = normalize(surfaceToLight + surfaceToView); + vec4 litR = lit(dot(normal, surfaceToLight), + dot(normal, halfVector), shininess); + vec4 outColor = vec4(( + lightColor * (diffuseColor * litR.y + diffuseColor * ambient + + specular * litR.z * specularFactor)).rgb, + diffuseColor.a); + outColor = mix(outColor, vec4(fogColor.rgb, diffuseColor.a), + clamp(pow((v_position.z / v_position.w), fogPower) * fogMult - fogOffset,0.0,1.0)); + + gl_FragColor = outColor; + gl_FragColor.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + +__ENDPROGRAM__ +__BEGINPROGRAM__ +__VERTEXSHADER__ + +uniform mat4 worldViewProjection; +uniform vec3 lightWorldPos; +uniform mat4 world; +uniform mat4 viewInverse; +uniform mat4 worldInverseTranspose; +attribute vec4 position; +attribute vec3 normal; +attribute vec2 texCoord; +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; +void main() { + v_texCoord = texCoord; + v_position = (worldViewProjection * position); + v_normal = (worldInverseTranspose * vec4(normal, 0)).xyz; + v_surfaceToLight = lightWorldPos - (world * position).xyz; + v_surfaceToView = (viewInverse[3] - (world * position)).xyz; + gl_Position = v_position; + gl_Position.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + + +__FRAGMENTSHADER__ + +precision mediump float; +uniform vec4 lightColor; +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; + +uniform vec4 ambient; +uniform sampler2D diffuse; +uniform vec4 specular; +uniform float shininess; +uniform float specularFactor; +// #fogUniforms + +vec4 lit(float l ,float h, float m) { + return vec4(1.0, + max(l, 0.0), + (l > 0.0) ? pow(max(0.0, h), m) : 0.0, + 1.0); +} +void main() { + vec4 diffuseColor = texture2D(diffuse, v_texCoord); + vec3 normal = normalize(v_normal); + vec3 surfaceToLight = normalize(v_surfaceToLight); + vec3 surfaceToView = normalize(v_surfaceToView); + vec3 halfVector = normalize(surfaceToLight + surfaceToView); + vec4 litR = lit(dot(normal, surfaceToLight), + dot(normal, halfVector), shininess); + vec4 outColor = vec4(( + lightColor * (diffuseColor * litR.y + diffuseColor * ambient + + specular * litR.z * specularFactor)).rgb, + diffuseColor.a); + // #fogCode + gl_FragColor = outColor; + gl_FragColor.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + +__ENDPROGRAM__ +__BEGINPROGRAM__ +__VERTEXSHADER__ + +uniform mat4 worldViewProjection; +uniform vec3 lightWorldPos; +uniform mat4 world; +uniform mat4 viewInverse; +uniform mat4 worldInverseTranspose; +attribute vec4 position; +attribute vec3 normal; +attribute vec2 texCoord; +attribute vec3 tangent; +attribute vec3 binormal; +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_tangent; // #normalMap +varying vec3 v_binormal; // #normalMap +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; +void main() { + v_texCoord = texCoord; + v_position = (worldViewProjection * position); + v_normal = (worldInverseTranspose * vec4(normal, 0)).xyz; + v_surfaceToLight = lightWorldPos - (world * position).xyz; + v_surfaceToView = (viewInverse[3] - (world * position)).xyz; + v_binormal = (worldInverseTranspose * vec4(binormal, 0)).xyz; // #normalMap + v_tangent = (worldInverseTranspose * vec4(tangent, 0)).xyz; // #normalMap + gl_Position = v_position; + gl_Position.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + + +__FRAGMENTSHADER__ + +precision mediump float; +uniform vec4 lightColor; +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_tangent; // #normalMap +varying vec3 v_binormal; // #normalMap +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; + +uniform sampler2D diffuse; +uniform vec4 specular; +uniform sampler2D normalMap; // #normalMap +uniform sampler2D reflectionMap; +uniform samplerCube skybox; +uniform float shininess; +uniform float specularFactor; +uniform float refractionFudge; +uniform float eta; +uniform float tankColorFudge; +uniform float fogPower; +uniform float fogMult; +uniform float fogOffset; +uniform vec4 fogColor; + + +vec4 lit(float l ,float h, float m) { + return vec4(1.0, + max(l, 0.0), + (l > 0.0) ? pow(max(0.0, h), m) : 0.0, + 1.0); +} +void main() { + vec4 diffuseColor = texture2D(diffuse, v_texCoord) + + vec4(tankColorFudge, tankColorFudge, tankColorFudge, 1); + mat3 tangentToWorld = mat3(v_tangent, // #normalMap + v_binormal, // #normalMap + v_normal); // #normalMap + vec4 normalSpec = texture2D(normalMap, v_texCoord.xy); // #normalMap + vec4 refraction = texture2D(reflectionMap, v_texCoord.xy); + vec3 tangentNormal = normalSpec.xyz - vec3(0.5, 0.5, 0.5); // #normalMap + tangentNormal = normalize(tangentNormal + vec3(0,0,refractionFudge)); // #normalMap + vec3 normal = (tangentToWorld * tangentNormal); // #normalMap + normal = normalize(normal); // #normalMap + + vec3 surfaceToLight = normalize(v_surfaceToLight); + vec3 surfaceToView = normalize(v_surfaceToView); + + vec3 refractionVec = refract(surfaceToView, normal, eta); + + vec4 skyColor = textureCube(skybox, refractionVec); + +// vec4 bumpSkyColor = textureCube(skybox, refractionVec); +// vec4 nonBumpSkyColor = textureCube( +// skybox, +// refract(surfaceToView, normalize(v_normal), eta)); +// vec4 skyColor = mix(nonBumpSkyColor, bumpSkyColor, normalSpec.a); + vec4 outColor = vec4( + mix(skyColor * diffuseColor, diffuseColor, refraction.r).rgb, + diffuseColor.a); + outColor = mix(outColor, vec4(fogColor.rgb, diffuseColor.a), + clamp(pow((v_position.z / v_position.w), fogPower) * fogMult - fogOffset,0.0,1.0)); + + gl_FragColor = outColor; + gl_FragColor.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + +__ENDPROGRAM__ +__BEGINPROGRAM__ +__VERTEXSHADER__ + +uniform mat4 worldViewProjection; +uniform vec3 lightWorldPos; +uniform mat4 world; +uniform mat4 viewInverse; +uniform mat4 worldInverseTranspose; +attribute vec4 position; +attribute vec3 normal; +attribute vec2 texCoord; +attribute vec3 tangent; +attribute vec3 binormal; +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_tangent; // #normalMap +varying vec3 v_binormal; // #normalMap +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; +void main() { + v_texCoord = texCoord; + v_position = (worldViewProjection * position); + v_normal = (worldInverseTranspose * vec4(normal, 0)).xyz; + v_surfaceToLight = lightWorldPos - (world * position).xyz; + v_surfaceToView = (viewInverse[3] - (world * position)).xyz; + v_binormal = (worldInverseTranspose * vec4(binormal, 0)).xyz; // #normalMap + v_tangent = (worldInverseTranspose * vec4(tangent, 0)).xyz; // #normalMap + gl_Position = v_position; + gl_Position.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + + +__FRAGMENTSHADER__ + +precision mediump float; +uniform vec4 lightColor; +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_tangent; // #normalMap +varying vec3 v_binormal; // #normalMap +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; + +uniform sampler2D diffuse; +uniform vec4 specular; +uniform sampler2D normalMap; // #normalMap +uniform sampler2D reflectionMap; +uniform samplerCube skybox; +uniform float shininess; +uniform float specularFactor; +uniform float refractionFudge; +uniform float eta; +uniform float tankColorFudge; +// #fogUniforms + +vec4 lit(float l ,float h, float m) { + return vec4(1.0, + max(l, 0.0), + (l > 0.0) ? pow(max(0.0, h), m) : 0.0, + 1.0); +} +void main() { + vec4 diffuseColor = texture2D(diffuse, v_texCoord) + + vec4(tankColorFudge, tankColorFudge, tankColorFudge, 1); + mat3 tangentToWorld = mat3(v_tangent, // #normalMap + v_binormal, // #normalMap + v_normal); // #normalMap + vec4 normalSpec = texture2D(normalMap, v_texCoord.xy); // #normalMap + vec4 refraction = texture2D(reflectionMap, v_texCoord.xy); + vec3 tangentNormal = normalSpec.xyz - vec3(0.5, 0.5, 0.5); // #normalMap + tangentNormal = normalize(tangentNormal + vec3(0,0,refractionFudge)); // #normalMap + vec3 normal = (tangentToWorld * tangentNormal); // #normalMap + normal = normalize(normal); // #normalMap + + vec3 surfaceToLight = normalize(v_surfaceToLight); + vec3 surfaceToView = normalize(v_surfaceToView); + + vec3 refractionVec = refract(surfaceToView, normal, eta); + + vec4 skyColor = textureCube(skybox, refractionVec); + +// vec4 bumpSkyColor = textureCube(skybox, refractionVec); +// vec4 nonBumpSkyColor = textureCube( +// skybox, +// refract(surfaceToView, normalize(v_normal), eta)); +// vec4 skyColor = mix(nonBumpSkyColor, bumpSkyColor, normalSpec.a); + vec4 outColor = vec4( + mix(skyColor * diffuseColor, diffuseColor, refraction.r).rgb, + diffuseColor.a); + // #fogCode + gl_FragColor = outColor; + gl_FragColor.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + +__ENDPROGRAM__ +__BEGINPROGRAM__ +__VERTEXSHADER__ + +uniform mat4 worldViewProjection; +uniform vec3 lightWorldPos; +uniform mat4 world; +uniform mat4 viewInverse; +uniform mat4 worldInverseTranspose; +attribute vec4 position; +attribute vec3 normal; +attribute vec2 texCoord; +attribute vec3 tangent; +attribute vec3 binormal; +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_tangent; // #normalMap +varying vec3 v_binormal; // #normalMap +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; +void main() { + v_texCoord = texCoord; + v_position = (worldViewProjection * position); + v_normal = (worldInverseTranspose * vec4(normal, 0)).xyz; + v_surfaceToLight = lightWorldPos - (world * position).xyz; + v_surfaceToView = (viewInverse[3] - (world * position)).xyz; + v_binormal = (worldInverseTranspose * vec4(binormal, 0)).xyz; // #normalMap + v_tangent = (worldInverseTranspose * vec4(tangent, 0)).xyz; // #normalMap + gl_Position = v_position; + gl_Position.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + + +__FRAGMENTSHADER__ + +precision mediump float; +uniform vec4 lightColor; +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; + +uniform sampler2D diffuse; +uniform vec4 specular; +uniform sampler2D reflectionMap; +uniform samplerCube skybox; +uniform float shininess; +uniform float specularFactor; +uniform float refractionFudge; +uniform float eta; +uniform float tankColorFudge; +uniform float fogPower; +uniform float fogMult; +uniform float fogOffset; +uniform vec4 fogColor; + + +vec4 lit(float l ,float h, float m) { + return vec4(1.0, + max(l, 0.0), + (l > 0.0) ? pow(max(0.0, h), m) : 0.0, + 1.0); +} +void main() { + vec4 diffuseColor = texture2D(diffuse, v_texCoord) + + vec4(tankColorFudge, tankColorFudge, tankColorFudge, 1); + vec4 normalSpec = vec4(0,0,0,0); // #noNormalMap + vec4 refraction = texture2D(reflectionMap, v_texCoord.xy); + vec3 normal = normalize(v_normal); // #noNormalMap + + vec3 surfaceToLight = normalize(v_surfaceToLight); + vec3 surfaceToView = normalize(v_surfaceToView); + + vec3 refractionVec = refract(surfaceToView, normal, eta); + + vec4 skyColor = textureCube(skybox, refractionVec); + +// vec4 bumpSkyColor = textureCube(skybox, refractionVec); +// vec4 nonBumpSkyColor = textureCube( +// skybox, +// refract(surfaceToView, normalize(v_normal), eta)); +// vec4 skyColor = mix(nonBumpSkyColor, bumpSkyColor, normalSpec.a); + vec4 outColor = vec4( + mix(skyColor * diffuseColor, diffuseColor, refraction.r).rgb, + diffuseColor.a); + outColor = mix(outColor, vec4(fogColor.rgb, diffuseColor.a), + clamp(pow((v_position.z / v_position.w), fogPower) * fogMult - fogOffset,0.0,1.0)); + + gl_FragColor = outColor; + gl_FragColor.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + +__ENDPROGRAM__ +__BEGINPROGRAM__ +__VERTEXSHADER__ + +uniform mat4 worldViewProjection; +uniform vec3 lightWorldPos; +uniform mat4 world; +uniform mat4 viewInverse; +uniform mat4 worldInverseTranspose; +attribute vec4 position; +attribute vec3 normal; +attribute vec2 texCoord; +attribute vec3 tangent; +attribute vec3 binormal; +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_tangent; // #normalMap +varying vec3 v_binormal; // #normalMap +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; +void main() { + v_texCoord = texCoord; + v_position = (worldViewProjection * position); + v_normal = (worldInverseTranspose * vec4(normal, 0)).xyz; + v_surfaceToLight = lightWorldPos - (world * position).xyz; + v_surfaceToView = (viewInverse[3] - (world * position)).xyz; + v_binormal = (worldInverseTranspose * vec4(binormal, 0)).xyz; // #normalMap + v_tangent = (worldInverseTranspose * vec4(tangent, 0)).xyz; // #normalMap + gl_Position = v_position; + gl_Position.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + + +__FRAGMENTSHADER__ + +precision mediump float; +uniform vec4 lightColor; +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; + +uniform sampler2D diffuse; +uniform vec4 specular; +uniform sampler2D reflectionMap; +uniform samplerCube skybox; +uniform float shininess; +uniform float specularFactor; +uniform float refractionFudge; +uniform float eta; +uniform float tankColorFudge; +// #fogUniforms + +vec4 lit(float l ,float h, float m) { + return vec4(1.0, + max(l, 0.0), + (l > 0.0) ? pow(max(0.0, h), m) : 0.0, + 1.0); +} +void main() { + vec4 diffuseColor = texture2D(diffuse, v_texCoord) + + vec4(tankColorFudge, tankColorFudge, tankColorFudge, 1); + vec4 normalSpec = vec4(0,0,0,0); // #noNormalMap + vec4 refraction = texture2D(reflectionMap, v_texCoord.xy); + vec3 normal = normalize(v_normal); // #noNormalMap + + vec3 surfaceToLight = normalize(v_surfaceToLight); + vec3 surfaceToView = normalize(v_surfaceToView); + + vec3 refractionVec = refract(surfaceToView, normal, eta); + + vec4 skyColor = textureCube(skybox, refractionVec); + +// vec4 bumpSkyColor = textureCube(skybox, refractionVec); +// vec4 nonBumpSkyColor = textureCube( +// skybox, +// refract(surfaceToView, normalize(v_normal), eta)); +// vec4 skyColor = mix(nonBumpSkyColor, bumpSkyColor, normalSpec.a); + vec4 outColor = vec4( + mix(skyColor * diffuseColor, diffuseColor, refraction.r).rgb, + diffuseColor.a); + // #fogCode + gl_FragColor = outColor; + gl_FragColor.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + +__ENDPROGRAM__ +__BEGINPROGRAM__ +__VERTEXSHADER__ + +uniform mat4 world; +uniform mat4 viewProjection; +uniform vec3 lightWorldPos; +uniform mat4 viewInverse; +uniform mat4 worldInverseTranspose; +uniform float time; +attribute vec4 position; +attribute vec3 normal; +attribute vec2 texCoord; +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; +void main() { + vec3 toCamera = normalize(viewInverse[3].xyz - world[3].xyz); + vec3 yAxis = vec3(0, 1, 0); + vec3 xAxis = cross(yAxis, toCamera); + vec3 zAxis = cross(xAxis, yAxis); + + mat4 newWorld = mat4( + vec4(xAxis, 0), + vec4(yAxis, 0), + vec4(xAxis, 0), + world[3]); + + v_texCoord = texCoord; + v_position = position + vec4( + sin(time * 0.5) * pow(position.y * 0.07, 2.0) * 1.0, + -4, // TODO(gman): remove this hack + 0, + 0); + v_position = (viewProjection * newWorld) * v_position; + v_normal = (newWorld * vec4(normal, 0)).xyz; + v_surfaceToLight = lightWorldPos - (world * position).xyz; + v_surfaceToView = (viewInverse[3] - (world * position)).xyz; + gl_Position = v_position; + gl_Position.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + + +__FRAGMENTSHADER__ + +precision mediump float; +uniform vec4 lightColor; +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; + +uniform vec4 ambient; +uniform sampler2D diffuse; +uniform vec4 specular; +uniform float shininess; +uniform float specularFactor; +uniform float fogPower; +uniform float fogMult; +uniform float fogOffset; +uniform vec4 fogColor; + + +vec4 lit(float l ,float h, float m) { + return vec4(1.0, + max(l, 0.0), + (l > 0.0) ? pow(max(0.0, h), m) : 0.0, + 1.0); +} +void main() { + vec4 diffuseColor = texture2D(diffuse, v_texCoord); + if (diffuseColor.a < 0.3) { + discard; + } + vec3 normal = normalize(v_normal); + vec3 surfaceToLight = normalize(v_surfaceToLight); + vec3 surfaceToView = normalize(v_surfaceToView); + vec3 halfVector = normalize(surfaceToLight + surfaceToView); + vec4 litR = lit(dot(normal, surfaceToLight), + dot(normal, halfVector), shininess); + vec4 outColor = vec4(( + lightColor * (diffuseColor * litR.y + diffuseColor * ambient + + specular * litR.z * specularFactor)).rgb, + diffuseColor.a); + outColor = mix(outColor, vec4(fogColor.rgb, diffuseColor.a), + clamp(pow((v_position.z / v_position.w), fogPower) * fogMult - fogOffset,0.0,1.0)); + + gl_FragColor = outColor; + gl_FragColor.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + +__ENDPROGRAM__ +__BEGINPROGRAM__ +__VERTEXSHADER__ + +uniform mat4 world; +uniform mat4 viewProjection; +uniform vec3 lightWorldPos; +uniform mat4 viewInverse; +uniform mat4 worldInverseTranspose; +uniform float time; +attribute vec4 position; +attribute vec3 normal; +attribute vec2 texCoord; +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; +void main() { + vec3 toCamera = normalize(viewInverse[3].xyz - world[3].xyz); + vec3 yAxis = vec3(0, 1, 0); + vec3 xAxis = cross(yAxis, toCamera); + vec3 zAxis = cross(xAxis, yAxis); + + mat4 newWorld = mat4( + vec4(xAxis, 0), + vec4(yAxis, 0), + vec4(xAxis, 0), + world[3]); + + v_texCoord = texCoord; + v_position = position + vec4( + sin(time * 0.5) * pow(position.y * 0.07, 2.0) * 1.0, + -4, // TODO(gman): remove this hack + 0, + 0); + v_position = (viewProjection * newWorld) * v_position; + v_normal = (newWorld * vec4(normal, 0)).xyz; + v_surfaceToLight = lightWorldPos - (world * position).xyz; + v_surfaceToView = (viewInverse[3] - (world * position)).xyz; + gl_Position = v_position; + gl_Position.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + + +__FRAGMENTSHADER__ + +precision mediump float; +uniform vec4 lightColor; +varying vec4 v_position; +varying vec2 v_texCoord; +varying vec3 v_normal; +varying vec3 v_surfaceToLight; +varying vec3 v_surfaceToView; + +uniform vec4 ambient; +uniform sampler2D diffuse; +uniform vec4 specular; +uniform float shininess; +uniform float specularFactor; +// #fogUniforms + +vec4 lit(float l ,float h, float m) { + return vec4(1.0, + max(l, 0.0), + (l > 0.0) ? pow(max(0.0, h), m) : 0.0, + 1.0); +} +void main() { + vec4 diffuseColor = texture2D(diffuse, v_texCoord); + if (diffuseColor.a < 0.3) { + discard; + } + vec3 normal = normalize(v_normal); + vec3 surfaceToLight = normalize(v_surfaceToLight); + vec3 surfaceToView = normalize(v_surfaceToView); + vec3 halfVector = normalize(surfaceToLight + surfaceToView); + vec4 litR = lit(dot(normal, surfaceToLight), + dot(normal, halfVector), shininess); + vec4 outColor = vec4(( + lightColor * (diffuseColor * litR.y + diffuseColor * ambient + + specular * litR.z * specularFactor)).rgb, + diffuseColor.a); + // #fogCode + gl_FragColor = outColor; + gl_FragColor.x += PROGRAM_CACHE_BREAKER_RANDOM; +} + + +__ENDPROGRAM__ diff --git a/dom/canvas/test/webgl-conf/checkout/performance/webgl_webcodecs_video_frame/index.html b/dom/canvas/test/webgl-conf/checkout/performance/webgl_webcodecs_video_frame/index.html new file mode 100644 index 0000000000..97eb95a174 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/performance/webgl_webcodecs_video_frame/index.html @@ -0,0 +1,186 @@ +<!-- This was created from the demo of webcodecs-blogpost-demo.glitch.me, and added the webgl support for test only purpose. --> + +<!DOCTYPE html> +<html> + +<head> + <meta charset="UTF-8"> + <meta http-equiv="origin-trial" + content="AoSY6Q4OOuuZVXTqOwJlfk4n77EL0esumtLRHj+9V97JoFfLq4AKsWlza8A8HmxTx1PU7SSzpjWK6F62bwWLPQYAAAB3eyJvcmlnaW4iOiJodHRwczovL3dlYmNvZGVjcy1ibG9ncG9zdC1kZW1vLmdsaXRjaC5tZTo0NDMiLCJmZWF0dXJlIjoiV2ViQ29kZWNzIiwiZXhwaXJ5IjoxNjA1NDc0OTQ4LCJpc1N1YmRvbWFpbiI6dHJ1ZX0="> + <title>WebCodecs API demo: Encoding and Decoding</title> + <style> + canvas { + padding: 10px; + background: gold; + } + + button { + background-color: #555555; + border: none; + color: white; + padding: 15px 32px; + width: 150px; + text-align: center; + display: block; + font-size: 16px; + } + </style> + <script src="../../../../extensions/proposals/WEBGL_webcodecs_video_frame/webgl_webcodecs_video_frame.js"></script> +</head> + +<body> + <canvas id="src" width="640" height="480"></canvas> + <button onclick="playPause()">Pause</button> + <canvas id="dst" width="640" height="480"></canvas> + <script> + let codec_string = "vp8"; + let keep_going = true; + + function playPause() { + keep_going = !keep_going; + let btn = document.querySelector("button"); + if (keep_going) { + btn.innerText = "Pause"; + } else { + btn.innerText = "Play"; + } + } + + async function startDrawing() { + let cnv = document.getElementById("src"); + var ctx = cnv.getContext('2d', { alpha: false }); + + ctx.fillStyle = "white"; + let width = cnv.width; + let height = cnv.height; + let cx = width / 2; + let cy = height / 2; + let r = Math.min(width, height) / 5; + let drawOneFrame = function (time) { + let angle = Math.PI * 2 * (time / 5000); + let scale = 1 + 0.3 * Math.sin(Math.PI * 2 * (time / 7000)); + ctx.save(); + ctx.fillRect(0, 0, width, height); + + ctx.translate(cx, cy); + ctx.rotate(angle); + ctx.scale(scale, scale); + + ctx.font = '30px Verdana'; + ctx.fillStyle = 'black'; + const text = "๐๐น๐ทHello WEBGL_webcodecs_video_frame๐ฅ๐๏ธ๐"; + const size = ctx.measureText(text).width; + ctx.fillText(text, -size / 2, 0); + ctx.restore(); + window.requestAnimationFrame(drawOneFrame); + } + window.requestAnimationFrame(drawOneFrame); + } + + function captureAndEncode(processChunk) { + let cnv = document.getElementById("src"); + let fps = 30; + let pending_outputs = 0; + let frame_counter = 0; + let stream = cnv.captureStream(fps); + let processor = new MediaStreamTrackProcessor(stream.getVideoTracks()[0]); + + const init = { + output: (chunk) => { + pending_outputs--; + processChunk(chunk); + }, + error: (e) => { + console.log(e.message); + vtr.stop(); + } + }; + + const config = { + codec: codec_string, + width: cnv.width, + height: cnv.height, + bitrate: 10e6, + framerate: fps, + }; + + let encoder = new VideoEncoder(init); + encoder.configure(config); + + const frame_reader = processor.readable.getReader(); + frame_reader.read().then(function processFrame({done, value}) { + if (done) + return; + + if (pending_outputs > 30) { + // Too many frames in flight, encoder is overwhelmed + // let's drop this frame. + value.close(); + frame_reader.read().then(processFrame); + return; + } + + if(!keep_going) { + value.close(); + frame_reader.read().then(processFrame); + return; + } + + frame_counter++; + pending_outputs++; + const insert_keyframe = (frame_counter % 150) == 0; + encoder.encode(value, { keyFrame: insert_keyframe }); + + frame_reader.read().then(processFrame); + }); + } + + + function startDecodingAndRendering(cnv, handleFrame) { + + const init = { + output: handleFrame, + error: (e) => { + console.log(e.message); + } + }; + + const config = { + codec: codec_string, + codedWidth: cnv.width, + codedHeight: cnv.height + }; + + let decoder = new VideoDecoder(init); + decoder.configure(config); + return decoder; + } + + + function main() { + if (!("VideoEncoder" in window)) { + document.body.innerHTML = "<h1>WebCodecs API is not supported.</h1>"; + return; + } + + let cnv = document.getElementById("dst"); + let handleFrame = requestWebGLVideoFrameHandler(cnv); + if (handleFrame === null) { + document.body.innerHTML = + "<h1>Unable to request WebGL to render video frames.</h1>"; + return; + } + + startDrawing(); + let decoder = startDecodingAndRendering(cnv, handleFrame); + captureAndEncode((chunk) => { + decoder.decode(chunk); + }); + } + + document.body.onload = main; + </script> + +</body> + +</html>
\ No newline at end of file |