Created
May 6, 2018 17:27
-
-
Save Erreur32/d7ca5fb1c21975288d9e87c531375885 to your computer and use it in GitHub Desktop.
rvGRaV
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
start of fragment shader playground in THREEjs | |
work with https://www.shadertoy.com/ and http://glslsandbox.com/ | |
fragments shader ... isint finished at moment. | |
ES6 | |
*/ | |
Object.defineProperty( window,'log',{ set: p => console.log(p) , get: ()=>'log = ...'} ) | |
var camera, scene, renderer | |
var uniforms, material, mesh | |
const VERTEXSHADER_2D = 'void main(){ gl_Position = vec4( position, 1.0 ); }' | |
window.onload = function() | |
{ | |
console.clear() | |
new ThreeShader( ) | |
} | |
class ThreeShader | |
{ | |
constructor( holder ) | |
{ | |
holder = holder || document.body | |
scene = new THREE.Scene() | |
renderer = new THREE.WebGLRenderer() | |
camera = new THREE.Camera() | |
holder.appendChild( renderer.domElement ) | |
this.start = +new Date() | |
this.shaderSetup() | |
} | |
shaderSetup() | |
{ | |
const VEC2 = 'v2' | |
const FLOAT = 'f' | |
// | |
uniforms = { | |
iGlobalTime: { type: FLOAT , value: 1.0 }, | |
time: { type: FLOAT , value: 1.0 }, | |
iResolution: { type: VEC2 , value: new THREE.Vector2() }, | |
resolution: { type: VEC2 , value: new THREE.Vector2() }, | |
iMouse: { type: VEC2 , value: new THREE.Vector2() }, | |
mouse: { type: VEC2 , value: new THREE.Vector2() } | |
} | |
// this.geometry = new THREE.PlaneBufferGeometry( 1,1 ) | |
material = new THREE.ShaderMaterial({ | |
uniforms: uniforms, | |
// attributes: { vertexOpacity: { value: [] } }, | |
vertexShader: VERTEXSHADER_2D , | |
fragmentShader: this.galaxy | |
}) | |
mesh = new THREE.Mesh( new THREE.PlaneBufferGeometry ( 2 , 2 ) , material ) | |
scene.add( mesh ) | |
window.addEventListener( 'resize' , this.onResize.bind(this) , false ) | |
this.onResize() | |
this.onRender() | |
} | |
onRender() | |
{ | |
const SPEED = .1 | |
requestAnimationFrame( this.onRender.bind( this ) ) | |
uniforms.time.value = uniforms.iGlobalTime.value = ( new Date() - this.start ) * 0.001 * SPEED | |
renderer.render( scene , camera ) | |
} | |
onResize() | |
{ | |
let width = window.innerWidth | |
let height = window.innerHeight | |
uniforms.resolution.value.x = uniforms.iResolution.value.x = width | |
uniforms.resolution.value.y = uniforms.iResolution.value.y = height | |
renderer.setSize( width , height ) | |
} | |
shaderToyFragment( fragment ){ | |
return ` | |
uniform float iGlobalTime; | |
uniform vec2 iResolution; | |
uniform vec2 iMouse; | |
${fragment} | |
void main(void) { | |
//uv is between 0 and 1 | |
vec2 uv = gl_FragCoord.xy / iResolution.xy; | |
vec2 delta = 1.0 / iResolution.xy; | |
mainImage(gl_FragColor,gl_FragCoord.xy); | |
} | |
` | |
} | |
get minFragment() | |
{ | |
return ` | |
uniform float iGlobalTime; | |
uniform vec2 iResolution; | |
void main() { | |
float x = mod(iGlobalTime + gl_FragCoord.x, 20.) < 10. ? 1. : 0.; | |
float y = mod(iGlobalTime + gl_FragCoord.y, 20.) < 10. ? 1. : 0.; | |
gl_FragColor = vec4(vec3(min(x, y)), 1.); | |
} | |
`} | |
get vertexShader() | |
{ | |
let vertex = ` | |
uniform float iGlobalTime; | |
uniform vec2 iResolution; | |
void main() { | |
gl_Position = vec4( position, 1.0 ); | |
} | |
` | |
return vertex | |
} | |
get simpleFshader() | |
{ | |
let fragment = ` | |
uniform float iGlobalTime; | |
uniform vec2 iResolution; | |
float field(in vec3 p) { | |
float strength = 7. + .03 * log(1.e-6 + fract(sin(iGlobalTime) * 4373.11)); | |
float accum = 0.; | |
float prev = 0.; | |
float tw = 0.; | |
for (int i = 0; i < 32; ++i) { | |
float mag = dot(p, p); | |
p = abs(p) / mag + vec3(-.5, -.4, -1.5); | |
float w = exp(-float(i) / 7.); | |
accum += w * exp(-strength * pow(abs(mag - prev), 2.3)); | |
tw += w; | |
prev = mag; | |
} | |
return max(0., 5. * accum / tw - .7); | |
} | |
void mainImage( out vec4 fragColor, in vec2 fragCoord ) { | |
vec2 uv = 2. * fragCoord.xy / iResolution.xy - 1.; | |
vec2 uvs = uv * iResolution.xy / max(iResolution.x, iResolution.y); | |
vec3 p = vec3(uvs / 4., 0) + vec3(1., -1.3, 0.); | |
p += .2 * vec3(sin(iGlobalTime / 16.), sin(iGlobalTime / 12.), sin(iGlobalTime / 128.)); | |
float t = field(p); | |
float v = (1. - exp((abs(uv.x) - 1.) * 6.)) * (1. - exp((abs(uv.y) - 1.) * 6.)); | |
fragColor = mix(.4, 1., v) * vec4(1.8 * t * t * t, 1.4 * t * t, t, 1.0); | |
} | |
void main(void) { | |
//uv is between 0 and 1 | |
vec2 uv = gl_FragCoord.xy / iResolution.xy; | |
vec2 delta = 1.0 / iResolution.xy; | |
// gl_FragColor = vec4(sin(iGlobalTime), uv.x, uv.y ,1.0); | |
mainImage(gl_FragColor,gl_FragCoord.xy); | |
} | |
` | |
return fragment | |
} | |
get galaxyCloud() | |
{ | |
let fragment = ` | |
//CBS | |
//Parallax scrolling fractal galaxy. | |
//Inspired by JoshP's Simplicity shader: https://www.shadertoy.com/view/lslGWr | |
// http://www.fractalforums.com/new-theories-and-research/very-simple-formula-for-fractal-patterns/ | |
float field(in vec3 p,float s) { | |
float strength = 7. + .03 * log(1.e-6 + fract(sin(iGlobalTime) * 4373.11)); | |
float accum = s/4.; | |
float prev = 0.; | |
float tw = 0.; | |
for (int i = 0; i < 26; ++i) { | |
float mag = dot(p, p); | |
p = abs(p) / mag + vec3(-.5, -.4, -1.5); | |
float w = exp(-float(i) / 7.); | |
accum += w * exp(-strength * pow(abs(mag - prev), 2.2)); | |
tw += w; | |
prev = mag; | |
} | |
return max(0., 5. * accum / tw - .7); | |
} | |
// Less iterations for second layer | |
float field2(in vec3 p, float s) { | |
float strength = 5. + .03 * log(1.e-6 + fract(sin(iGlobalTime) * 4373.11)); | |
//float strength = 7. + .03 * log(1.e-6 + fract(sin(iGlobalTime) * 4373.11)); | |
float accum = s/4.; | |
float prev = 0.; | |
float tw = 0.; | |
for (int i = 0; i < 18; ++i) { | |
float mag = dot(p, p); | |
p = abs(p) / mag + vec3(-.5, -.4, -1.5); | |
float w = exp(-float(i) / 7.); | |
accum += w * exp(-strength * pow(abs(mag - prev), 2.2)); | |
tw += w; | |
prev = mag; | |
} | |
return max(0., 5. * accum / tw - .7); | |
} | |
vec3 nrand3( vec2 co ) | |
{ | |
vec3 a = fract( cos( co.x*8.3e-3 + co.y )*vec3(1.3e5, 4.7e5, 2.9e5) ); | |
vec3 b = fract( sin( co.x*0.3e-3 + co.y )*vec3(8.1e5, 1.0e5, 0.1e5) ); | |
vec3 c = mix(a, b, 0.5); | |
return c; | |
} | |
void mainImage( out vec4 fragColor, in vec2 fragCoord ) { | |
vec2 uv = 2. * fragCoord.xy / iResolution.xy - 1.; | |
vec2 uvs = uv * iResolution.xy / max(iResolution.x, iResolution.y); | |
vec3 p = vec3(uvs / 4., 0) + vec3(1., -1.3, 0.); | |
p += .2 * vec3(sin(iGlobalTime / 16.), sin(iGlobalTime / 12.), sin(iGlobalTime / 128.)); | |
float freqs[4];//=float[4](0.2,0.5,0.1,0.7); | |
freqs[0]=0.2; | |
freqs[1]=0.5; | |
freqs[2]=0.1; | |
freqs[3]=0.7; | |
//Sound | |
/* | |
freqs[0] = texture2D( iChannel0, vec2( 0.01, 0.25 ) ).x; | |
freqs[1] = texture2D( iChannel0, vec2( 0.07, 0.25 ) ).x; | |
freqs[2] = texture2D( iChannel0, vec2( 0.15, 0.25 ) ).x; | |
freqs[3] = texture2D( iChannel0, vec2( 0.30, 0.25 ) ).x; | |
*/ | |
float t = field(p,freqs[2]); | |
float v = (1. - exp((abs(uv.x) - 1.) * 6.)) * (1. - exp((abs(uv.y) - 1.) * 6.)); | |
//Second Layer | |
vec3 p2 = vec3(uvs / (4.+sin(iGlobalTime*0.11)*0.2+0.2+sin(iGlobalTime*0.15)*0.3+0.4), 1.5) + vec3(2., -1.3, -1.); | |
p2 += 0.25 * vec3(sin(iGlobalTime / 16.), sin(iGlobalTime / 12.), sin(iGlobalTime / 128.)); | |
float t2 = field2(p2,freqs[3]); | |
vec4 c2 = mix(.4, 1., v) * vec4(1.3 * t2 * t2 * t2 ,1.8 * t2 * t2 , t2* freqs[0], t2); | |
//Let's add some stars | |
//Thanks to http://glsl.heroku.com/e#6904.0 | |
vec2 seed = p.xy * 2.0; | |
seed = floor(seed * iResolution.x); | |
vec3 rnd = nrand3( seed ); | |
vec4 starcolor = vec4(pow(rnd.y,40.0)); | |
//Second Layer | |
vec2 seed2 = p2.xy * 2.0; | |
seed2 = floor(seed2 * iResolution.x); | |
vec3 rnd2 = nrand3( seed2 ); | |
starcolor += vec4(pow(rnd2.y,40.0)); | |
fragColor = mix(freqs[3]-.3, 1., v) * vec4(1.5*freqs[2] * t * t* t , 1.2*freqs[1] * t * t, freqs[3]*t, 1.0)+c2+starcolor; | |
} | |
` | |
return this.shaderToyFragment( fragment ) | |
} | |
get another() | |
{ | |
var fragment = ` | |
void mainImage( out vec4 fragColor, in vec2 fragCoord ) | |
{ | |
vec2 uv = fragCoord.xy / iResolution.xy; | |
fragColor = vec4(uv,0.5+0.5*sin(iGlobalTime),1.0); | |
} | |
`; return this.shaderToyFragment( fragment ) | |
} | |
get ibilinear() | |
{ | |
var fragment = ` | |
// https://www.shadertoy.com/view/MscXDS | |
// Created by inigo quilez - iq/2014 | |
// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. | |
// Inverse bilienar interpolation: given four points defining a quadrilateral, compute the | |
// uv coordinates of any point in the plane that would give result to that point as a | |
// bilinear interpolation of the four points. | |
// | |
// The problem resolves through a quadratic equation. More information in this article: | |
// | |
// http://www.iquilezles.org/www/articles/ibilinear/ibilinear.htm | |
vec2 sincos( const in float x ) | |
{ | |
return vec2(sin(x), cos(x)); | |
} | |
vec3 rotatez( const in vec3 vPos, const in vec2 vSinCos ) | |
{ | |
return vec3( vSinCos.y * vPos.x + vSinCos.x * vPos.y, -vSinCos.x * vPos.x + vSinCos.y * vPos.y, vPos.z); | |
} | |
vec3 rotatez( const in vec3 vPos, const in float fAngle ) | |
{ | |
return rotatez( vPos, sincos(fAngle) ); | |
} | |
vec2 rotatez( const in vec2 vPos, const in float fAngle ) | |
{ | |
return rotatez( vec3(vPos, 0.0), sincos(fAngle) ).xy; | |
} | |
mat4 rotatez( const in mat4 vPos, const in float fAngle ) | |
{ | |
return mat4(rotatez( vec3(vPos[0].xy, 0.0), sincos(fAngle) ).xy, 0.0, 0.0, | |
rotatez( vec3(vPos[1].xy, 0.0), sincos(fAngle) ).xy, 0.0, 0.0, | |
rotatez( vec3(vPos[2].xy, 0.0), sincos(fAngle) ).xy, 0.0, 0.0, | |
rotatez( vec3(vPos[3].xy, 0.0), sincos(fAngle) ).xy, 0.0, 0.0); | |
} | |
float cross( in vec2 a, in vec2 b ) { return a.x*b.y - a.y*b.x; } | |
#define PI 3.14159265359 | |
#define E 2.7182818284 | |
#define GR 1.61803398875 | |
#define EPS (.01*(1.0+saw(time))) | |
#define time (float(__LINE__)+iGlobalTime/PI) | |
float saw(float x) | |
{ | |
return acos(cos(x))/3.14; | |
} | |
vec2 saw(vec2 x) | |
{ | |
return acos(cos(x))/3.14; | |
} | |
vec3 saw(vec3 x) | |
{ | |
return acos(cos(x))/3.14; | |
} | |
vec4 saw(vec4 x) | |
{ | |
return acos(cos(x))/3.14; | |
} | |
vec3 phase(float map) | |
{ | |
return vec3(saw(map), | |
saw(4.0*PI/3.0+map), | |
saw(2.0*PI/3.0+map)); | |
} | |
//a is up | |
//b is center | |
//d is right | |
vec3 invBilinear( in vec3 p, in vec3 a, in vec3 b, in vec3 c) | |
{ | |
vec3 duv = p-b; | |
vec3 xdir = c-b; | |
vec3 ydir = a-b; | |
float theta = PI/2.0;//time; | |
xdir = rotatez(xdir, theta); | |
ydir = rotatez(ydir, theta); | |
float w = length(cross(xdir, ydir)); | |
return vec3(dot(duv, xdir), dot(duv, ydir), w); | |
} | |
float sdSegment( in vec2 p, in vec2 a, in vec2 b ) | |
{ | |
vec2 pa = p - a; | |
vec2 ba = b - a; | |
float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 ); | |
return length( pa - ba*h ); | |
} | |
vec3 hash3( float n ) { return fract(sin(vec3(n,n+1.0,n+2.0))*43758.5453123); } | |
void mainImage( out vec4 fragColor, in vec2 fragCoord ) | |
{ | |
vec3 p = vec3((-iResolution.xy + 2.0*fragCoord.xy)/iResolution.y, 0.0); | |
// background | |
vec3 col = vec3( 0.35 + 0.1*p.y ); | |
vec2 r = (.5*cos(1.06*iGlobalTime))*vec2(cos(iGlobalTime), sin(iGlobalTime)); | |
float s = .5; | |
// move points | |
vec3 a = vec3(r+s*cos( 1.11*iGlobalTime + vec2(0.1,4.0) ), 0.0); | |
vec3 b = vec3(r+s*cos( 1.12*iGlobalTime + vec2(1.0,3.0) ), 0.0); | |
vec3 c = vec3(r+s*cos( 1.13*iGlobalTime + vec2(2.0,2.0) ), 0.0); | |
// area of the quad | |
vec3 uv = invBilinear( p, a, b, c ); | |
// quad borders | |
float h = GR/iResolution.y; | |
float axis = 1.0-smoothstep(h,2.0*h,sdSegment(p.xy,a.xy,b.xy)); | |
axis += 1.0-smoothstep(h,2.0*h,sdSegment(p.xy,c.xy,b.xy)); | |
axis += 1.0-smoothstep(h,2.0*h,sdSegment(p.xy,a.xy,c.xy)); | |
fragColor = vec4( col, 1.0 ); | |
fragColor.rgb = vec3(saw(abs(uv.x/uv.z)*PI), saw(abs(uv.y/uv.z)*PI), axis); | |
fragColor.a = 1.0; | |
} | |
`; return this.shaderToyFragment( fragment ) | |
} | |
get galaxy() | |
{ | |
var fragment = ` | |
// http://glslsandbox.com/e#18021.0 | |
#ifdef GL_ES | |
precision mediump float; | |
#endif | |
uniform float time; | |
uniform vec2 mouse; | |
uniform vec2 resolution; | |
#define iterations 17 | |
#define formuparam 0.53 | |
#define volsteps 20 | |
#define stepsize 0.1 | |
#define zoom 0.800 | |
#define tile 0.850 | |
#define speed 0.010 | |
#define brightness 0.0015 | |
#define darkmatter 0.300 | |
#define distfading 0.730 | |
#define saturation 0.850 | |
void main(void) | |
{ | |
//get coords and direction | |
vec2 uv=gl_FragCoord.xy/resolution.xy-.5; | |
uv.y*=resolution.y/resolution.x; | |
vec3 dir=vec3(uv*zoom,1.); | |
float time=time*speed+.25; | |
//mouse rotation | |
float a1=.5+mouse.x/resolution.x*2.; | |
float a2=.8+mouse.y/resolution.y*2.; | |
mat2 rot1=mat2(cos(a1),sin(a1),-sin(a1),cos(a1)); | |
mat2 rot2=mat2(cos(a2),sin(a2),-sin(a2),cos(a2)); | |
dir.xz*=rot1; | |
dir.xy*=rot2; | |
vec3 from=vec3(1.,.5,0.5); | |
from+=vec3(time*2.,time,-2.); | |
from.xz*=rot1; | |
from.xy*=rot2; | |
//volumetric rendering | |
float s=0.1,fade=1.; | |
vec3 v=vec3(0.); | |
for (int r=0; r<volsteps; r++) { | |
vec3 p=from+s*dir*.5; | |
p = abs(vec3(tile)-mod(p,vec3(tile*2.))); // tiling fold | |
float pa,a=pa=0.; | |
for (int i=0; i<iterations; i++) { | |
p=abs(p)/dot(p,p)-formuparam; // the magic formula | |
a+=abs(length(p)-pa); // absolute sum of average change | |
pa=length(p); | |
} | |
float dm=max(0.,darkmatter-a*a*.001); //dark matter | |
a*=a*a; // add contrast | |
if (r>6) fade*=1.-dm; // dark matter, don't render near | |
//v+=vec3(dm,dm*.5,0.); | |
v+=fade; | |
v+=vec3(s,s*s,s*s*s*s)*a*brightness*fade; // coloring based on distance | |
fade*=distfading; // distance fading | |
s+=stepsize; | |
} | |
v=mix(vec3(length(v)),v,saturation); //color adjust | |
gl_FragColor = vec4(v*.01,1.); | |
} | |
` ; return fragment | |
} | |
get closeToNeuron() | |
{ | |
var fragment = ` | |
#ifdef GL_ES | |
precision mediump float; | |
#endif | |
#extension GL_OES_standard_derivatives : enable | |
uniform float time; | |
uniform vec2 mouse; | |
uniform vec2 resolution; | |
#define PI 3.14159 | |
float hash(float n) { | |
return fract(sin(n)*43758.5435); | |
} | |
float noise(vec3 x) { | |
vec3 p = floor(x); | |
vec3 f = fract(x); | |
f = f*f*(3.0 - 2.0*f); | |
float n = p.x + p.y*57.0 + p.z*113.0; | |
return mix( | |
mix( | |
mix(hash(n + 000.0), hash(n + 001.0), f.x), | |
mix(hash(n + 057.0), hash(n + 058.0), f.x), | |
f.y), | |
mix( | |
mix(hash(n + 113.0), hash(n + 114.0), f.x), | |
mix(hash(n + 170.0), hash(n + 171.0), f.x), | |
f.y), | |
f.z); | |
} | |
float map(vec3 p) { | |
p.z += time*0.5; | |
float n = abs(dot(cos(p*PI), sin(p.yzx*PI))); | |
return .45 - n*.33 + 0.02*smoothstep(0.7, 1.0, noise(10.0*p)) + 0.01*noise(40.0*p); | |
} | |
float march(vec3 ro, vec3 rd) { | |
float t = 0.0; | |
for(int i = 0; i < 100; i++) { | |
float h = map(ro + rd*t); | |
if(abs(h) < 0.001 || t >= 10.0) break; | |
t += h*0.5; | |
} | |
return t; | |
} | |
vec3 normal(vec3 p) { | |
vec2 h = vec2(0.001, 0.0); | |
vec3 n = vec3( | |
map(p + h.xyy) - map(p - h.xyy), | |
map(p + h.yxy) - map(p - h.yxy), | |
map(p + h.yyx) - map(p - h.yyx) | |
); | |
return normalize(n); | |
} | |
float shadow(vec3 p, vec3 l) { | |
float res = 1.0; | |
float t = 0.002; | |
for(int i = 0; i < 100; i++) { | |
float h = map(p + l*t); | |
if(abs(h) < 0.0 || t >= 7.0) break; | |
t += h; | |
res = min(res, 16.0*h/t); | |
} | |
return clamp(res, 0.0, 1.0); | |
} | |
mat3 camera(vec3 eye, vec3 lat) { | |
vec3 ww = normalize(lat - eye); | |
vec3 uu = normalize(cross(vec3(0, 1, 0), ww)); | |
vec3 vv = normalize(cross(ww, uu)); | |
return mat3(uu, vv, ww); | |
} | |
void main( void ) { | |
vec2 uv = -1.0 + 2.0*(gl_FragCoord.xy/resolution); | |
uv.x *= resolution.x/resolution.y; | |
vec2 mo = -1.5 + 3.0*mouse; | |
vec3 col = vec3(0); | |
vec3 ro = vec3(0, 0, -3); | |
vec3 rd = camera(ro, vec3(4.0*mo.x, 2.0*mo.y, 0.0))*normalize(vec3(uv, 1.97)); | |
float i = march(ro, rd); | |
if(i < 10.0) { | |
vec3 pos = ro + rd*i; | |
vec3 nor = normal(pos); | |
vec3 ref = reflect(rd, nor); | |
vec3 lig = normalize(vec3(0.8, 0.7, -0.6)); | |
vec3 bli = -lig; | |
float amb = 0.5 + 0.5*nor.y; | |
float dif = clamp(dot(lig, nor), 0.0, 1.0); | |
float bac = clamp(dot(bli, nor), 0.0, 1.0); | |
float spe = pow(clamp(dot(ref, lig), 0.0, 1.0), 8.0); | |
float fre = pow(clamp(1.0 + dot(rd, nor), 0.0, 1.0), 2.0); | |
float sha = shadow(pos, lig); | |
col = 0.2*amb*vec3(1); | |
col += 1.2*dif*vec3(1)*sha; | |
col += 0.15*bac*vec3(1); | |
vec3 mat = vec3(0.4, 0.7, 0.3); | |
pos.z += time*0.5; | |
float f = smoothstep(0.7, 1.0, noise(10.0*pos)); | |
mat = mix(mat, vec3(1.0, 0.2, 0.2), smoothstep(0.0, 1.0, 100.0*f)); | |
col *= mat; | |
col += 0.2*spe*vec3(1)*dif*sha; | |
col += 0.2*fre*vec3(1); | |
} | |
col = mix(col, vec3(0.9, 1.0, 0.9), 1.0 - exp(-i*0.5)); | |
gl_FragColor = vec4(col, 1); | |
} | |
`;return fragment | |
} | |
get tejut() | |
{ | |
var frag = ` | |
#ifdef GL_ES | |
precision mediump float; | |
#endif | |
uniform float time; | |
uniform vec2 resolution; | |
#define FORMUPARAM 0.599 | |
#define ITERATIONS 105 | |
#define INNER_ITERS 10 | |
#define ZOOM 1.2 | |
void main() | |
{ | |
vec2 uv = (gl_FragCoord.xy/resolution.xy)-.5; | |
uv *= ZOOM; | |
//uv += vec2(.15 * sin(time * .2), .1 * cos(time * .1)); | |
float t = time * .1 + ((.25+.05*sin(time*.1))/(length(uv.xy)+.07))* 2.2; | |
float si = sin(t); | |
float co = cos(t); | |
mat2 ma = mat2(co, si, -si, co); | |
float c = 0.0; | |
float v1 = 0.0; | |
float v2 = 0.0; | |
for (int i = 0; i < ITERATIONS; i++) | |
{ | |
float s = float(i) * .035; | |
vec3 p = s * vec3(uv, 1.0 + sin(time * .015)); | |
p.xy *= ma; | |
p += vec3(.22,.3, s-1.5-sin(t*.13)*.1); | |
for (int i = 0; i < INNER_ITERS; i++) | |
{ | |
p = abs(p) / dot(p,p) - FORMUPARAM; | |
} | |
v1 += dot(p,p)*.0015 * (2.8+sin(length(uv.xy*18.0)+.5-t*.7)); | |
v2 += dot(p,p)*.0025 * (1.5+sin(length(uv.xy*13.5)+1.21-t*.3)); | |
c = length(p.xy*.3) * .85; | |
} | |
float len = length(uv); | |
v1 *= smoothstep(.7, .0, len); | |
v2 *= smoothstep(.6, .0, len); | |
float re = clamp(c, 0.0, 1.0); | |
float gr = clamp((v1+c)*.25, 0.0, 1.0); | |
float bl = clamp(v2, 0.0, 1.0); | |
vec3 col = vec3(re, gr, bl) + smoothstep(0.15, .0, len) * .9; | |
gl_FragColor=vec4(col, 1.0); | |
} | |
`; return frag | |
} | |
// earth with clouds | |
// https://www.shadertoy.com/view/ldyXRw | |
get earth() | |
{ | |
var frag = ` | |
#define SHADERTOY | |
#ifdef __cplusplus | |
#define _in(T) const T & | |
#define _inout(T) T & | |
#define _out(T) T & | |
#define _begin(type) type { | |
#define _end } | |
#define _mutable(T) T | |
#define _constant(T) const T | |
#define mul(a, b) (a) * (b) | |
#endif | |
#if defined(GL_ES) || defined(GL_SHADING_LANGUAGE_VERSION) | |
#define _in(T) const in T | |
#define _inout(T) inout T | |
#define _out(T) out T | |
#define _begin(type) type ( | |
#define _end ) | |
#define _mutable(T) T | |
#define _constant(T) const T | |
#define mul(a, b) (a) * (b) | |
precision mediump float; | |
#endif | |
#ifdef HLSL | |
#define _in(T) const in T | |
#define _inout(T) inout T | |
#define _out(T) out T | |
#define _begin(type) { | |
#define _end } | |
#define _mutable(T) static T | |
#define _constant(T) static const T | |
#define vec2 float2 | |
#define vec3 float3 | |
#define vec4 float4 | |
#define mat2 float2x2 | |
#define mat3 float3x3 | |
#define mat4 float4x4 | |
#define mix lerp | |
#define fract frac | |
#define mod fmod | |
#pragma pack_matrix(row_major) | |
#endif | |
#ifdef HLSLTOY | |
cbuffer uniforms : register(b0) { | |
float2 u_res; | |
float u_time; | |
float2 u_mouse; | |
}; | |
void mainImage(_out(float4) fragColor, _in(float2) fragCoord); | |
float4 main(float4 uv : SV_Position) : SV_Target{ float4 col; mainImage(col, uv.xy); return col; } | |
#endif | |
#if defined(__cplusplus) || defined(SHADERTOY) | |
#define u_res iResolution | |
#define u_time iGlobalTime | |
#define u_mouse iMouse | |
#endif | |
#ifdef GLSLSANDBOX | |
uniform float time; | |
uniform vec2 mouse; | |
uniform vec2 resolution; | |
#define u_res resolution | |
#define u_time time | |
#define u_mouse mouse | |
void mainImage(_out(vec4) fragColor, _in(vec2) fragCoord); | |
void main() { mainImage(gl_FragColor, gl_FragCoord.xy); } | |
#endif | |
#ifdef UE4 | |
_constant(vec2) u_res = vec2(0, 0); | |
_constant(vec2) u_mouse = vec2(0, 0); | |
_mutable(float) u_time = 0; | |
#endif | |
#define PI 3.14159265359 | |
struct ray_t { | |
vec3 origin; | |
vec3 direction; | |
}; | |
#define BIAS 1e-4 // small offset to avoid self-intersections | |
struct sphere_t { | |
vec3 origin; | |
float radius; | |
int material; | |
}; | |
struct plane_t { | |
vec3 direction; | |
float distance; | |
int material; | |
}; | |
struct hit_t { | |
float t; | |
int material_id; | |
vec3 normal; | |
vec3 origin; | |
}; | |
#define max_dist 1e8 | |
_constant(hit_t) no_hit = _begin(hit_t) | |
float(max_dist + 1e1), // 'infinite' distance | |
-1, // material id | |
vec3(0., 0., 0.), // normal | |
vec3(0., 0., 0.) // origin | |
_end; | |
// ---------------------------------------------------------------------------- | |
// Various 3D utilities functions | |
// ---------------------------------------------------------------------------- | |
ray_t get_primary_ray( | |
_in(vec3) cam_local_point, | |
_inout(vec3) cam_origin, | |
_inout(vec3) cam_look_at | |
){ | |
vec3 fwd = normalize(cam_look_at - cam_origin); | |
vec3 up = vec3(0, 1, 0); | |
vec3 right = cross(up, fwd); | |
up = cross(fwd, right); | |
ray_t r = _begin(ray_t) | |
cam_origin, | |
normalize(fwd + up * cam_local_point.y + right * cam_local_point.x) | |
_end; | |
return r; | |
} | |
_constant(mat3) mat3_ident = mat3(1, 0, 0, 0, 1, 0, 0, 0, 1); | |
#ifndef HLSL | |
mat3 transpose( | |
_in(mat3) m | |
){ | |
return mat3( | |
m[0][0], m[1][0], m[2][0], | |
m[0][1], m[1][1], m[2][1], | |
m[0][2], m[1][2], m[2][2]); | |
} | |
#endif | |
mat2 rotate_2d( | |
_in(float) angle_degrees | |
){ | |
float angle = radians(angle_degrees); | |
float _sin = sin(angle); | |
float _cos = cos(angle); | |
return mat2(_cos, -_sin, _sin, _cos); | |
} | |
mat3 rotate_around_z( | |
_in(float) angle_degrees | |
){ | |
float angle = radians(angle_degrees); | |
float _sin = sin(angle); | |
float _cos = cos(angle); | |
return mat3(_cos, -_sin, 0, _sin, _cos, 0, 0, 0, 1); | |
} | |
mat3 rotate_around_y( | |
_in(float) angle_degrees | |
){ | |
float angle = radians(angle_degrees); | |
float _sin = sin(angle); | |
float _cos = cos(angle); | |
return mat3(_cos, 0, _sin, 0, 1, 0, -_sin, 0, _cos); | |
} | |
mat3 rotate_around_x( | |
_in(float) angle_degrees | |
){ | |
float angle = radians(angle_degrees); | |
float _sin = sin(angle); | |
float _cos = cos(angle); | |
return mat3(1, 0, 0, 0, _cos, -_sin, 0, _sin, _cos); | |
} | |
// http://http.developer.nvidia.com/GPUGems3/gpugems3_ch24.html | |
vec3 linear_to_srgb( | |
_in(vec3) color | |
){ | |
const float p = 1. / 2.2; | |
return vec3(pow(color.r, p), pow(color.g, p), pow(color.b, p)); | |
} | |
vec3 srgb_to_linear( | |
_in(vec3) color | |
){ | |
const float p = 2.2; | |
return vec3(pow(color.r, p), pow(color.g, p), pow(color.b, p)); | |
} | |
#ifdef __cplusplus | |
vec3 faceforward( | |
_in(vec3) N, | |
_in(vec3) I, | |
_in(vec3) Nref | |
){ | |
return dot(Nref, I) < 0 ? N : -N; | |
} | |
#endif | |
float checkboard_pattern( | |
_in(vec2) pos, | |
_in(float) scale | |
){ | |
vec2 pattern = floor(pos * scale); | |
return mod(pattern.x + pattern.y, 2.0); | |
} | |
float band ( | |
_in(float) start, | |
_in(float) peak, | |
_in(float) end, | |
_in(float) t | |
){ | |
return | |
smoothstep (start, peak, t) * | |
(1. - smoothstep (peak, end, t)); | |
} | |
// from https://www.shadertoy.com/view/4sSSW3 | |
// original http://orbit.dtu.dk/fedora/objects/orbit:113874/datastreams/file_75b66578-222e-4c7d-abdf-f7e255100209/content | |
void fast_orthonormal_basis( | |
_in(vec3) n, | |
_out(vec3) f, | |
_out(vec3) r | |
){ | |
float a = 1. / (1. + n.z); | |
float b = -n.x*n.y*a; | |
f = vec3(1. - n.x*n.x*a, b, -n.x); | |
r = vec3(b, 1. - n.y*n.y*a, -n.y); | |
} | |
// ---------------------------------------------------------------------------- | |
// Analytical surface-ray intersection routines | |
// ---------------------------------------------------------------------------- | |
// geometrical solution | |
// info: http://www.scratchapixel.com/old/lessons/3d-basic-lessons/lesson-7-intersecting-simple-shapes/ray-sphere-intersection/ | |
void intersect_sphere( | |
_in(ray_t) ray, | |
_in(sphere_t) sphere, | |
_inout(hit_t) hit | |
){ | |
vec3 rc = sphere.origin - ray.origin; | |
float radius2 = sphere.radius * sphere.radius; | |
float tca = dot(rc, ray.direction); | |
if (tca < 0.) return; | |
float d2 = dot(rc, rc) - tca * tca; | |
if (d2 > radius2) return; | |
float thc = sqrt(radius2 - d2); | |
float t0 = tca - thc; | |
float t1 = tca + thc; | |
if (t0 < 0.) t0 = t1; | |
if (t0 > hit.t) return; | |
vec3 impact = ray.origin + ray.direction * t0; | |
hit.t = t0; | |
hit.material_id = sphere.material; | |
hit.origin = impact; | |
hit.normal = (impact - sphere.origin) / sphere.radius; | |
} | |
// ---------------------------------------------------------------------------- | |
// Volumetric utilities | |
// ---------------------------------------------------------------------------- | |
struct volume_sampler_t { | |
vec3 origin; // start of ray | |
vec3 pos; // current pos of acccumulation ray | |
float height; | |
float coeff_absorb; | |
float T; // transmitance | |
vec3 C; // color | |
float alpha; | |
}; | |
volume_sampler_t begin_volume( | |
_in(vec3) origin, | |
_in(float) coeff_absorb | |
){ | |
volume_sampler_t v = _begin(volume_sampler_t) | |
origin, origin, 0., | |
coeff_absorb, 1., | |
vec3(0., 0., 0.), 0. | |
_end; | |
return v; | |
} | |
float illuminate_volume( | |
_inout(volume_sampler_t) vol, | |
_in(vec3) V, | |
_in(vec3) L | |
); | |
void integrate_volume( | |
_inout(volume_sampler_t) vol, | |
_in(vec3) V, | |
_in(vec3) L, | |
_in(float) density, | |
_in(float) dt | |
){ | |
// change in transmittance (follows Beer-Lambert law) | |
float T_i = exp(-vol.coeff_absorb * density * dt); | |
// Update accumulated transmittance | |
vol.T *= T_i; | |
// integrate output radiance (here essentially color) | |
vol.C += vol.T * illuminate_volume(vol, V, L) * density * dt; | |
// accumulate opacity | |
vol.alpha += (1. - T_i) * (1. - vol.alpha); | |
} | |
// ---------------------------------------------------------------------------- | |
// Noise function by iq from https://www.shadertoy.com/view/4sfGzS | |
// ---------------------------------------------------------------------------- | |
float hash( | |
_in(float) n | |
){ | |
return fract(sin(n)*753.5453123); | |
} | |
float noise_iq( | |
_in(vec3) x | |
){ | |
vec3 p = floor(x); | |
vec3 f = fract(x); | |
f = f*f*(3.0 - 2.0*f); | |
#if 1 | |
float n = p.x + p.y*157.0 + 113.0*p.z; | |
return mix(mix(mix( hash(n+ 0.0), hash(n+ 1.0),f.x), | |
mix( hash(n+157.0), hash(n+158.0),f.x),f.y), | |
mix(mix( hash(n+113.0), hash(n+114.0),f.x), | |
mix( hash(n+270.0), hash(n+271.0),f.x),f.y),f.z); | |
#else | |
vec2 uv = (p.xy + vec2(37.0, 17.0)*p.z) + f.xy; | |
vec2 rg = texture2D(iChannel0, (uv + 0.5) / 256.0, -100.0).yx; | |
return mix(rg.x, rg.y, f.z); | |
#endif | |
} | |
#define noise(x) noise_iq(x) | |
// ---------------------------------------------------------------------------- | |
// Fractional Brownian Motion | |
// depends on custom basis function | |
// ---------------------------------------------------------------------------- | |
#define DECL_FBM_FUNC(_name, _octaves, _basis) float _name(_in(vec3) pos, _in(float) lacunarity, _in(float) init_gain, _in(float) gain) { vec3 p = pos; float H = init_gain; float t = 0.; for (int i = 0; i < _octaves; i++) { t += _basis * H; p *= lacunarity; H *= gain; } return t; } | |
DECL_FBM_FUNC(fbm, 4, noise(p)) | |
// ---------------------------------------------------------------------------- | |
// Planet | |
// ---------------------------------------------------------------------------- | |
_constant(sphere_t) planet = _begin(sphere_t) | |
vec3(0, 0, 0), 1., 0 | |
_end; | |
#define max_height .4 | |
#define max_ray_dist (max_height * 4.) | |
vec3 background( | |
_in(ray_t) eye | |
){ | |
#if 0 | |
return vec3(.15, .3, .4); | |
#else | |
_constant(vec3) sun_color = vec3(1., .9, .55); | |
float sun_amount = dot(eye.direction, vec3(0, 0, 1)); | |
vec3 sky = mix( | |
vec3(.0, .05, .2), | |
vec3(.15, .3, .4), | |
1.0 - eye.direction.y); | |
sky += sun_color * min(pow(sun_amount, 30.0) * 5.0, 1.0); | |
sky += sun_color * min(pow(sun_amount, 10.0) * .6, 1.0); | |
return sky; | |
#endif | |
} | |
void setup_scene() | |
{ | |
} | |
void setup_camera( | |
_inout(vec3) eye, | |
_inout(vec3) look_at | |
){ | |
#if 0 | |
eye = vec3(.0, 0, -1.93); | |
look_at = vec3(-.1, .9, 2); | |
#else | |
eye = vec3(0, 0, -2.5); | |
look_at = vec3(0, 0, 2); | |
#endif | |
} | |
// ---------------------------------------------------------------------------- | |
// Clouds | |
// ---------------------------------------------------------------------------- | |
#define CLOUDS | |
#define anoise (abs(noise(p) * 2. - 1.)) | |
DECL_FBM_FUNC(fbm_clouds, 4, anoise) | |
#define vol_coeff_absorb 30.034 | |
_mutable(volume_sampler_t) cloud; | |
float illuminate_volume( | |
_inout(volume_sampler_t) cloud, | |
_in(vec3) V, | |
_in(vec3) L | |
){ | |
return exp(cloud.height) / .055; | |
} | |
void clouds_map( | |
_inout(volume_sampler_t) cloud, | |
_in(float) t_step | |
){ | |
float dens = fbm_clouds( | |
cloud.pos * 3.2343 + vec3(.35, 13.35, 2.67), | |
2.0276, .5, .5); | |
#define cld_coverage .29475675 // higher=less clouds | |
#define cld_fuzzy .0335 // higher=fuzzy, lower=blockier | |
dens *= smoothstep(cld_coverage, cld_coverage + cld_fuzzy, dens); | |
dens *= band(.2, .35, .65, cloud.height); | |
integrate_volume(cloud, | |
cloud.pos, cloud.pos, // unused dummies | |
dens, t_step); | |
} | |
void clouds_march( | |
_in(ray_t) eye, | |
_inout(volume_sampler_t) cloud, | |
_in(float) max_travel, | |
_in(mat3) rot | |
){ | |
const int steps = 75; | |
const float t_step = max_ray_dist / float(steps); | |
float t = 0.; | |
for (int i = 0; i < steps; i++) { | |
if (t > max_travel || cloud.alpha >= 1.) return; | |
vec3 o = cloud.origin + t * eye.direction; | |
cloud.pos = mul(rot, o - planet.origin); | |
cloud.height = (length(cloud.pos) - planet.radius) / max_height; | |
t += t_step; | |
clouds_map(cloud, t_step); | |
} | |
} | |
void clouds_shadow_march( | |
_in(vec3) dir, | |
_inout(volume_sampler_t) cloud, | |
_in(mat3) rot | |
){ | |
const int steps = 5; | |
const float t_step = max_height / float(steps); | |
float t = 0.; | |
for (int i = 0; i < steps; i++) { | |
vec3 o = cloud.origin + t * dir; | |
cloud.pos = mul(rot, o - planet.origin); | |
cloud.height = (length(cloud.pos) - planet.radius) / max_height; | |
t += t_step; | |
clouds_map(cloud, t_step); | |
} | |
} | |
// ---------------------------------------------------------------------------- | |
// Terrain | |
// ---------------------------------------------------------------------------- | |
#define TERR_STEPS 120 | |
#define TERR_EPS .005 | |
#define rnoise (1. - abs(noise(p) * 2. - 1.)) | |
DECL_FBM_FUNC(fbm_terr, 3, noise(p)) | |
DECL_FBM_FUNC(fbm_terr_r, 3, rnoise) | |
DECL_FBM_FUNC(fbm_terr_normals, 7, noise(p)) | |
DECL_FBM_FUNC(fbm_terr_r_normals, 7, rnoise) | |
vec2 sdf_terrain_map(_in(vec3) pos) | |
{ | |
float h0 = fbm_terr(pos * 2.0987, 2.0244, .454, .454); | |
float n0 = smoothstep(.35, 1., h0); | |
float h1 = fbm_terr_r(pos * 1.50987 + vec3(1.9489, 2.435, .5483), 2.0244, .454, .454); | |
float n1 = smoothstep(.6, 1., h1); | |
float n = n0 + n1; | |
return vec2(length(pos) - planet.radius - n * max_height, n / max_height); | |
} | |
vec2 sdf_terrain_map_detail(_in(vec3) pos) | |
{ | |
float h0 = fbm_terr_normals(pos * 2.0987, 2.0244, .454, .454); | |
float n0 = smoothstep(.35, 1., h0); | |
float h1 = fbm_terr_r_normals(pos * 1.50987 + vec3(1.9489, 2.435, .5483), 2.0244, .454, .454); | |
float n1 = smoothstep(.6, 1., h1); | |
float n = n0 + n1; | |
return vec2(length(pos) - planet.radius - n * max_height, n / max_height); | |
} | |
vec3 sdf_terrain_normal(_in(vec3) p) | |
{ | |
#define F(t) sdf_terrain_map_detail(t).x | |
vec3 dt = vec3(0.001, 0, 0); | |
return normalize(vec3( | |
F(p + dt.xzz) - F(p - dt.xzz), | |
F(p + dt.zxz) - F(p - dt.zxz), | |
F(p + dt.zzx) - F(p - dt.zzx) | |
)); | |
#undef F | |
} | |
// ---------------------------------------------------------------------------- | |
// Lighting | |
// ---------------------------------------------------------------------------- | |
vec3 setup_lights( | |
_in(vec3) L, | |
_in(vec3) normal | |
){ | |
vec3 diffuse = vec3(0, 0, 0); | |
// key light | |
vec3 c_L = vec3(7, 5, 3); | |
diffuse += max(0., dot(L, normal)) * c_L; | |
// fill light 1 - faked hemisphere | |
float hemi = clamp(.25 + .5 * normal.y, .0, 1.); | |
diffuse += hemi * vec3(.4, .6, .8) * .2; | |
// fill light 2 - ambient (reversed key) | |
float amb = clamp(.12 + .8 * max(0., dot(-L, normal)), 0., 1.); | |
diffuse += amb * vec3(.4, .5, .6); | |
return diffuse; | |
} | |
vec3 illuminate( | |
_in(vec3) pos, | |
_in(vec3) eye, | |
_in(mat3) local_xform, | |
_in(vec2) df | |
){ | |
// current terrain height at position | |
float h = df.y; | |
//return vec3 (h); | |
vec3 w_normal = normalize(pos); | |
#define LIGHT | |
#ifdef LIGHT | |
vec3 normal = sdf_terrain_normal(pos); | |
float N = dot(normal, w_normal); | |
#else | |
float N = w_normal.y; | |
#endif | |
// materials | |
#define c_water vec3(.015, .110, .455) | |
#define c_grass vec3(.086, .132, .018) | |
#define c_beach vec3(.153, .172, .121) | |
#define c_rock vec3(.080, .050, .030) | |
#define c_snow vec3(.600, .600, .600) | |
// limits | |
#define l_water .05 | |
#define l_shore .17 | |
#define l_grass .211 | |
#define l_rock .351 | |
float s = smoothstep(.4, 1., h); | |
vec3 rock = mix( | |
c_rock, c_snow, | |
smoothstep(1. - .3*s, 1. - .2*s, N)); | |
vec3 grass = mix( | |
c_grass, rock, | |
smoothstep(l_grass, l_rock, h)); | |
vec3 shoreline = mix( | |
c_beach, grass, | |
smoothstep(l_shore, l_grass, h)); | |
vec3 water = mix( | |
c_water / 2., c_water, | |
smoothstep(0., l_water, h)); | |
#ifdef LIGHT | |
vec3 L = mul(local_xform, normalize(vec3(1, 1, 0))); | |
shoreline *= setup_lights(L, normal); | |
vec3 ocean = setup_lights(L, w_normal) * water; | |
#else | |
vec3 ocean = water; | |
#endif | |
return mix( | |
ocean, shoreline, | |
smoothstep(l_water, l_shore, h)); | |
} | |
// ---------------------------------------------------------------------------- | |
// Rendering | |
// ---------------------------------------------------------------------------- | |
vec3 render( | |
_in(ray_t) eye, | |
_in(vec3) point_cam | |
){ | |
mat3 rot_y = rotate_around_y(27.); | |
mat3 rot = mul(rotate_around_x(u_time * -12.), rot_y); | |
mat3 rot_cloud = mul(rotate_around_x(u_time * 8.), rot_y); | |
sphere_t atmosphere = planet; | |
atmosphere.radius += max_height; | |
hit_t hit = no_hit; | |
intersect_sphere(eye, atmosphere, hit); | |
if (hit.material_id < 0) { | |
return background(eye); | |
} | |
float t = 0.; | |
vec2 df = vec2(1, max_height); | |
vec3 pos; | |
float max_cld_ray_dist = max_ray_dist; | |
for (int i = 0; i < TERR_STEPS; i++) { | |
if (t > max_ray_dist) break; | |
vec3 o = hit.origin + t * eye.direction; | |
pos = mul(rot, o - planet.origin); | |
df = sdf_terrain_map(pos); | |
if (df.x < TERR_EPS) { | |
max_cld_ray_dist = t; | |
break; | |
} | |
t += df.x * .4567; | |
} | |
#ifdef CLOUDS | |
cloud = begin_volume(hit.origin, vol_coeff_absorb); | |
clouds_march(eye, cloud, max_cld_ray_dist, rot_cloud); | |
#endif | |
if (df.x < TERR_EPS) { | |
vec3 c_terr = illuminate(pos, eye.direction, rot, df); | |
vec3 c_cld = cloud.C; | |
float alpha = cloud.alpha; | |
float shadow = 1.; | |
#ifdef CLOUDS // clouds ground shadows | |
pos = mul(transpose(rot), pos); | |
cloud = begin_volume(pos, vol_coeff_absorb); | |
vec3 local_up = normalize(pos); | |
clouds_shadow_march(local_up, cloud, rot_cloud); | |
shadow = mix(.7, 1., step(cloud.alpha, 0.33)); | |
#endif | |
return mix(c_terr * shadow, c_cld, alpha); | |
} else { | |
return mix(background(eye), cloud.C, cloud.alpha); | |
} | |
} | |
#define FOV tan(radians(30.)) | |
// ---------------------------------------------------------------------------- | |
// Main Rendering function | |
// depends on external defines: FOV | |
// ---------------------------------------------------------------------------- | |
void mainImage( | |
_out(vec4) fragColor, | |
#ifdef SHADERTOY | |
vec2 fragCoord | |
#else | |
_in(vec2) fragCoord | |
#endif | |
){ | |
// assuming screen width is larger than height | |
vec2 aspect_ratio = vec2(u_res.x / u_res.y, 1); | |
vec3 color = vec3(0, 0, 0); | |
vec3 eye, look_at; | |
setup_camera(eye, look_at); | |
setup_scene(); | |
vec2 point_ndc = fragCoord.xy / u_res.xy; | |
#ifdef HLSL | |
point_ndc.y = 1. - point_ndc.y; | |
#endif | |
vec3 point_cam = vec3( | |
(2.0 * point_ndc - 1.0) * aspect_ratio * FOV, | |
-1.0); | |
ray_t ray = get_primary_ray(point_cam, eye, look_at); | |
color += render(ray, point_cam); | |
fragColor = vec4(linear_to_srgb(color), 1); | |
} | |
`; return this.shaderToyFragment( frag ) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r75/three.min.js"></script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
body | |
width: 100% | |
height: 100% | |
background: #333 | |
font-family: arial | |
color: #999 | |
margin: 0 | |
padding: 0 | |
overflow: hidden |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment