Skip to content

Instantly share code, notes, and snippets.

@briehanlombaard
Created November 28, 2017 12:09
Show Gist options
  • Select an option

  • Save briehanlombaard/0c91d63da5ac10bd846272a5b660a880 to your computer and use it in GitHub Desktop.

Select an option

Save briehanlombaard/0c91d63da5ac10bd846272a5b660a880 to your computer and use it in GitHub Desktop.
Custom shaders for aframe
<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