Created
November 28, 2017 12:09
-
-
Save briehanlombaard/0c91d63da5ac10bd846272a5b660a880 to your computer and use it in GitHub Desktop.
Custom shaders for aframe
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <script src="https://aframe.io/releases/0.7.0/aframe.min.js"></script> | |
| <script type="text/javascript"> | |
| AFRAME.registerShader('hello-world', { | |
| schema: { | |
| color: {type: 'vec3', default: '0.5 0.5 0.5', is: 'uniform'} | |
| }, | |
| vertexShader: [ | |
| 'void main() {', | |
| ' gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;', | |
| '}' | |
| ].join('\n'), | |
| fragmentShader: [ | |
| 'uniform vec3 color;', | |
| 'void main() {', | |
| ' gl_FragColor = vec4(color, 1.0);', | |
| '}' | |
| ].join('\n') | |
| }); | |
| AFRAME.registerShader('noise', { | |
| schema: { | |
| time: { type: 'time', is: 'uniform' }, | |
| color: { type: 'color', is: 'uniform', default: 'red' }, | |
| weight: { type: 'number', default: 1.0, is: 'uniform' } | |
| }, | |
| vertexShader: [ | |
| 'vec3 mod289(vec3 x)', | |
| '{', | |
| 'return x - floor(x * (1.0 / 289.0)) * 289.0;', | |
| '}', | |
| 'vec4 mod289(vec4 x)', | |
| '{', | |
| 'return x - floor(x * (1.0 / 289.0)) * 289.0;', | |
| '}', | |
| 'vec4 permute(vec4 x)', | |
| '{', | |
| 'return mod289(((x*34.0)+1.0)*x);', | |
| '}', | |
| 'vec4 taylorInvSqrt(vec4 r)', | |
| '{', | |
| 'return 1.79284291400159 - 0.85373472095314 * r;', | |
| '}', | |
| 'vec3 fade(vec3 t) {', | |
| 'return t*t*t*(t*(t*6.0-15.0)+10.0);', | |
| '}', | |
| '// Classic Perlin noise, periodic variant', | |
| 'float pnoise(vec3 P, vec3 rep)', | |
| '{', | |
| 'vec3 Pi0 = mod(floor(P), rep); // Integer part, modulo period', | |
| 'vec3 Pi1 = mod(Pi0 + vec3(1.0), rep); // Integer part + 1, mod period', | |
| 'Pi0 = mod289(Pi0);', | |
| 'Pi1 = mod289(Pi1);', | |
| 'vec3 Pf0 = fract(P); // Fractional part for interpolation', | |
| 'vec3 Pf1 = Pf0 - vec3(1.0); // Fractional part - 1.0', | |
| 'vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x);', | |
| 'vec4 iy = vec4(Pi0.yy, Pi1.yy);', | |
| 'vec4 iz0 = Pi0.zzzz;', | |
| 'vec4 iz1 = Pi1.zzzz;', | |
| 'vec4 ixy = permute(permute(ix) + iy);', | |
| 'vec4 ixy0 = permute(ixy + iz0);', | |
| 'vec4 ixy1 = permute(ixy + iz1);', | |
| 'vec4 gx0 = ixy0 * (1.0 / 7.0);', | |
| 'vec4 gy0 = fract(floor(gx0) * (1.0 / 7.0)) - 0.5;', | |
| 'gx0 = fract(gx0);', | |
| 'vec4 gz0 = vec4(0.5) - abs(gx0) - abs(gy0);', | |
| 'vec4 sz0 = step(gz0, vec4(0.0));', | |
| 'gx0 -= sz0 * (step(0.0, gx0) - 0.5);', | |
| 'gy0 -= sz0 * (step(0.0, gy0) - 0.5);', | |
| 'vec4 gx1 = ixy1 * (1.0 / 7.0);', | |
| 'vec4 gy1 = fract(floor(gx1) * (1.0 / 7.0)) - 0.5;', | |
| 'gx1 = fract(gx1);', | |
| 'vec4 gz1 = vec4(0.5) - abs(gx1) - abs(gy1);', | |
| 'vec4 sz1 = step(gz1, vec4(0.0));', | |
| 'gx1 -= sz1 * (step(0.0, gx1) - 0.5);', | |
| 'gy1 -= sz1 * (step(0.0, gy1) - 0.5);', | |
| 'vec3 g000 = vec3(gx0.x,gy0.x,gz0.x);', | |
| 'vec3 g100 = vec3(gx0.y,gy0.y,gz0.y);', | |
| 'vec3 g010 = vec3(gx0.z,gy0.z,gz0.z);', | |
| 'vec3 g110 = vec3(gx0.w,gy0.w,gz0.w);', | |
| 'vec3 g001 = vec3(gx1.x,gy1.x,gz1.x);', | |
| 'vec3 g101 = vec3(gx1.y,gy1.y,gz1.y);', | |
| 'vec3 g011 = vec3(gx1.z,gy1.z,gz1.z);', | |
| 'vec3 g111 = vec3(gx1.w,gy1.w,gz1.w);', | |
| 'vec4 norm0 = taylorInvSqrt(vec4(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110)));', | |
| 'g000 *= norm0.x;', | |
| 'g010 *= norm0.y;', | |
| 'g100 *= norm0.z;', | |
| 'g110 *= norm0.w;', | |
| 'vec4 norm1 = taylorInvSqrt(vec4(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111)));', | |
| 'g001 *= norm1.x;', | |
| 'g011 *= norm1.y;', | |
| 'g101 *= norm1.z;', | |
| 'g111 *= norm1.w;', | |
| 'float n000 = dot(g000, Pf0);', | |
| 'float n100 = dot(g100, vec3(Pf1.x, Pf0.yz));', | |
| 'float n010 = dot(g010, vec3(Pf0.x, Pf1.y, Pf0.z));', | |
| 'float n110 = dot(g110, vec3(Pf1.xy, Pf0.z));', | |
| 'float n001 = dot(g001, vec3(Pf0.xy, Pf1.z));', | |
| 'float n101 = dot(g101, vec3(Pf1.x, Pf0.y, Pf1.z));', | |
| 'float n011 = dot(g011, vec3(Pf0.x, Pf1.yz));', | |
| 'float n111 = dot(g111, Pf1);', | |
| 'vec3 fade_xyz = fade(Pf0);', | |
| 'vec4 n_z = mix(vec4(n000, n100, n010, n110), vec4(n001, n101, n011, n111), fade_xyz.z);', | |
| 'vec2 n_yz = mix(n_z.xy, n_z.zw, fade_xyz.y);', | |
| 'float n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); ', | |
| 'return 2.2 * n_xyz;', | |
| '}', | |
| 'float f( vec3 p ) {', | |
| 'return pnoise( vec3( p ), vec3( 10.0, 10.0, 10.0 ) );', | |
| '}', | |
| 'varying vec3 vNormal;', | |
| 'varying vec3 vReflect;', | |
| 'varying float ao;', | |
| 'uniform float time;', | |
| 'uniform float weight;', | |
| 'float fround( float value ) {', | |
| 'return floor( value + 0.5 );', | |
| '}', | |
| 'vec3 v3round( vec3 value ) {', | |
| 'return vec3( fround( value.x ), fround( value.y ), fround( value.z ) );', | |
| '}', | |
| 'void main() {', | |
| 'vec3 evNormal = normal;', | |
| 'vec3 aniNormal = 2.0 * evNormal + time / 1000.0;', | |
| 'float f0 = weight * f( aniNormal );', | |
| 'float fx = weight * f( aniNormal + vec3( .0001, 0.0, 0.0 ) );', | |
| 'float fy = weight * f( aniNormal + vec3( 0.0, .0001, 0.0 ) );', | |
| 'float fz = weight * f( aniNormal + vec3( 0.0, 0.0, .0001 ) );', | |
| 'vec3 modifiedNormal = normalize( evNormal - vec3( (fx - f0) / .0001, (fy - f0) / .0001, (fz - f0) / .0001 ) );', | |
| 'if( weight > 0.0 ) {', | |
| 'ao = f0 / weight;', | |
| '} else {', | |
| 'ao = 0.0;', | |
| '}', | |
| 'vNormal = modifiedNormal;', | |
| 'vec3 newPosition = position + f0 * evNormal;', | |
| 'vec3 nWorld = normalize( mat3( modelMatrix[0].xyz, modelMatrix[1].xyz, modelMatrix[2].xyz ) * modifiedNormal );', | |
| 'vReflect = normalize( reflect( normalize( newPosition.xyz - cameraPosition ), nWorld ) );', | |
| 'gl_Position = projectionMatrix * modelViewMatrix * vec4( newPosition, 1.0 );', | |
| '}' | |
| ].join('\n'), | |
| fragmentShader: [ | |
| 'varying vec3 vNormal;', | |
| 'varying vec3 vReflect;', | |
| 'varying float ao;', | |
| 'uniform vec3 color;', | |
| 'float PI = 3.14159265358979323846264;', | |
| 'void main() {', | |
| 'float yaw = .5 - atan( vReflect.z, - vReflect.x ) / ( 2.0 * PI );', | |
| 'float pitch = .5 - asin( vReflect.y ) / PI;', | |
| 'vec2 pos = vec2( yaw, pitch );', | |
| 'float diffuse_value1 = .0015 * max(dot(vNormal, vec3( -490.0, 29.8, -85.8 ) ), 0.0); ', | |
| 'float diffuse_value2 = .0005 * max(dot(vNormal, vec3( -460.0, 40.27, 187.4 ) ), 0.0); ', | |
| 'float diffuse_value3 = .0010 * max(dot(vNormal, vec3( 175.5, 30.04, 466.4 ) ), 0.0); ', | |
| 'float diffuse_value4 = .0005 * max(dot(vNormal, vec3( 466.0, 45.3, 172.9 ) ), 0.0); ', | |
| 'gl_FragColor = vec4( color - .15 * ao + .5 * vec3( diffuse_value1 + diffuse_value2 + diffuse_value3 + diffuse_value4 ), 1.0 );', | |
| '}' | |
| ].join('\n') | |
| }); | |
| AFRAME.registerShader('sky', { | |
| schema: { | |
| luminance: { type: 'number', default: 1, max: 0, min: 2, is: 'uniform' }, | |
| turbidity: { type: 'number', default: 2, max: 0, min: 20, is: 'uniform' }, | |
| reileigh: { type: 'number', default: 1, max: 0, min: 4, is: 'uniform' }, | |
| mieCoefficient: { type: 'number', default: 0.005, min: 0, max: 0.1, is: 'uniform' }, | |
| mieDirectionalG: { type: 'number', default: 0.8, min: 0, max: 1, is: 'uniform' }, | |
| sunPosition: { type: 'vec3', default: '0 0 -1', is: 'uniform' } | |
| }, | |
| vertexShader: [ | |
| 'varying vec3 vWorldPosition;', | |
| 'void main() {', | |
| 'vec4 worldPosition = modelMatrix * vec4( position, 1.0 );', | |
| 'vWorldPosition = worldPosition.xyz;', | |
| 'gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', | |
| '}' | |
| ].join('\n'), | |
| fragmentShader: [ | |
| 'uniform sampler2D skySampler;', | |
| 'uniform vec3 sunPosition;', | |
| 'varying vec3 vWorldPosition;', | |
| 'vec3 cameraPos = vec3(0., 0., 0.);', | |
| 'uniform float luminance;', | |
| 'uniform float turbidity;', | |
| 'uniform float reileigh;', | |
| 'uniform float mieCoefficient;', | |
| 'uniform float mieDirectionalG;', | |
| '// constants for atmospheric scattering', | |
| 'const float e = 2.71828182845904523536028747135266249775724709369995957;', | |
| 'const float pi = 3.141592653589793238462643383279502884197169;', | |
| 'const float n = 1.0003; // refractive index of air', | |
| 'const float N = 2.545E25; // number of molecules per unit volume for air at', | |
| '// 288.15K and 1013mb (sea level -45 celsius)', | |
| 'const float pn = 0.035; // depolatization factor for standard air', | |
| '// wavelength of used primaries, according to preetham', | |
| 'const vec3 lambda = vec3(680E-9, 550E-9, 450E-9);', | |
| '// mie stuff', | |
| '// K coefficient for the primaries', | |
| 'const vec3 K = vec3(0.686, 0.678, 0.666);', | |
| 'const float v = 4.0;', | |
| '// optical length at zenith for molecules', | |
| 'const float rayleighZenithLength = 8.4E3;', | |
| 'const float mieZenithLength = 1.25E3;', | |
| 'const vec3 up = vec3(0.0, 1.0, 0.0);', | |
| 'const float EE = 1000.0;', | |
| 'const float sunAngularDiameterCos = 0.999956676946448443553574619906976478926848692873900859324;', | |
| '// 66 arc seconds -> degrees, and the cosine of that', | |
| '// earth shadow hack', | |
| 'const float cutoffAngle = pi/1.95;', | |
| 'const float steepness = 1.5;', | |
| 'vec3 totalRayleigh(vec3 lambda)', | |
| '{', | |
| 'return (8.0 * pow(pi, 3.0) * pow(pow(n, 2.0) - 1.0, 2.0) * (6.0 + 3.0 * pn)) / (3.0 * N * pow(lambda, vec3(4.0)) * (6.0 - 7.0 * pn));', | |
| '}', | |
| // see http://blenderartists.org/forum/showthread.php?321110-Shaders-and-Skybox-madness | |
| '// A simplied version of the total Reayleigh scattering to works on browsers that use ANGLE', | |
| 'vec3 simplifiedRayleigh()', | |
| '{', | |
| 'return 0.0005 / vec3(94, 40, 18);', | |
| '}', | |
| 'float rayleighPhase(float cosTheta)', | |
| '{ ', | |
| 'return (3.0 / (16.0*pi)) * (1.0 + pow(cosTheta, 2.0));', | |
| '}', | |
| 'vec3 totalMie(vec3 lambda, vec3 K, float T)', | |
| '{', | |
| 'float c = (0.2 * T ) * 10E-18;', | |
| 'return 0.434 * c * pi * pow((2.0 * pi) / lambda, vec3(v - 2.0)) * K;', | |
| '}', | |
| 'float hgPhase(float cosTheta, float g)', | |
| '{', | |
| 'return (1.0 / (4.0*pi)) * ((1.0 - pow(g, 2.0)) / pow(1.0 - 2.0*g*cosTheta + pow(g, 2.0), 1.5));', | |
| '}', | |
| 'float sunIntensity(float zenithAngleCos)', | |
| '{', | |
| 'return EE * max(0.0, 1.0 - exp(-((cutoffAngle - acos(zenithAngleCos))/steepness)));', | |
| '}', | |
| '// Filmic ToneMapping http://filmicgames.com/archives/75', | |
| 'float A = 0.15;', | |
| 'float B = 0.50;', | |
| 'float C = 0.10;', | |
| 'float D = 0.20;', | |
| 'float E = 0.02;', | |
| 'float F = 0.30;', | |
| 'float W = 1000.0;', | |
| 'vec3 Uncharted2Tonemap(vec3 x)', | |
| '{', | |
| 'return ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F;', | |
| '}', | |
| 'void main() ', | |
| '{', | |
| 'float sunfade = 1.0-clamp(1.0-exp((sunPosition.y/450000.0)),0.0,1.0);', | |
| 'float reileighCoefficient = reileigh - (1.0* (1.0-sunfade));', | |
| 'vec3 sunDirection = normalize(sunPosition);', | |
| 'float sunE = sunIntensity(dot(sunDirection, up));', | |
| '// extinction (absorbtion + out scattering) ', | |
| '// rayleigh coefficients', | |
| 'vec3 betaR = simplifiedRayleigh() * reileighCoefficient;', | |
| '// mie coefficients', | |
| 'vec3 betaM = totalMie(lambda, K, turbidity) * mieCoefficient;', | |
| '// optical length', | |
| '// cutoff angle at 90 to avoid singularity in next formula.', | |
| 'float zenithAngle = acos(max(0.0, dot(up, normalize(vWorldPosition - cameraPos))));', | |
| 'float sR = rayleighZenithLength / (cos(zenithAngle) + 0.15 * pow(93.885 - ((zenithAngle * 180.0) / pi), -1.253));', | |
| 'float sM = mieZenithLength / (cos(zenithAngle) + 0.15 * pow(93.885 - ((zenithAngle * 180.0) / pi), -1.253));', | |
| '// combined extinction factor ', | |
| 'vec3 Fex = exp(-(betaR * sR + betaM * sM));', | |
| '// in scattering', | |
| 'float cosTheta = dot(normalize(vWorldPosition - cameraPos), sunDirection);', | |
| 'float rPhase = rayleighPhase(cosTheta*0.5+0.5);', | |
| 'vec3 betaRTheta = betaR * rPhase;', | |
| 'float mPhase = hgPhase(cosTheta, mieDirectionalG);', | |
| 'vec3 betaMTheta = betaM * mPhase;', | |
| 'vec3 Lin = pow(sunE * ((betaRTheta + betaMTheta) / (betaR + betaM)) * (1.0 - Fex),vec3(1.5));', | |
| 'Lin *= mix(vec3(1.0),pow(sunE * ((betaRTheta + betaMTheta) / (betaR + betaM)) * Fex,vec3(1.0/2.0)),clamp(pow(1.0-dot(up, sunDirection),5.0),0.0,1.0));', | |
| '//nightsky', | |
| 'vec3 direction = normalize(vWorldPosition - cameraPos);', | |
| 'float theta = acos(direction.y); // elevation --> y-axis, [-pi/2, pi/2]', | |
| 'float phi = atan(direction.z, direction.x); // azimuth --> x-axis [-pi/2, pi/2]', | |
| 'vec2 uv = vec2(phi, theta) / vec2(2.0*pi, pi) + vec2(0.5, 0.0);', | |
| '// vec3 L0 = texture2D(skySampler, uv).rgb+0.1 * Fex;', | |
| 'vec3 L0 = vec3(0.1) * Fex;', | |
| '// composition + solar disc', | |
| 'float sundisk = smoothstep(sunAngularDiameterCos,sunAngularDiameterCos+0.00002,cosTheta);', | |
| 'L0 += (sunE * 19000.0 * Fex)*sundisk;', | |
| 'vec3 whiteScale = 1.0/Uncharted2Tonemap(vec3(W));', | |
| 'vec3 texColor = (Lin+L0); ', | |
| 'texColor *= 0.04 ;', | |
| 'texColor += vec3(0.0,0.001,0.0025)*0.3;', | |
| 'float g_fMaxLuminance = 1.0;', | |
| 'float fLumScaled = 0.1 / luminance; ', | |
| 'float fLumCompressed = (fLumScaled * (1.0 + (fLumScaled / (g_fMaxLuminance * g_fMaxLuminance)))) / (1.0 + fLumScaled); ', | |
| 'float ExposureBias = fLumCompressed;', | |
| 'vec3 curr = Uncharted2Tonemap((log2(2.0/pow(luminance,4.0)))*texColor);', | |
| 'vec3 color = curr*whiteScale;', | |
| 'vec3 retColor = pow(color,vec3(1.0/(1.2+(1.2*sunfade))));', | |
| 'gl_FragColor.rgb = retColor;', | |
| 'gl_FragColor.a = 1.0;', | |
| '}' | |
| ].join('\n') | |
| }); | |
| </script> | |
| <a-scene> | |
| <a-sky material="shader: sky;"></a-sky> | |
| <a-entity geometry="primitive: box;" | |
| material="shader: noise;"></a-entity> | |
| </a-scene> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment