base working, added images assets, todo random generation
|
@ -23,7 +23,7 @@ module.exports = {
|
||||||
plugins: [
|
plugins: [
|
||||||
new EsLint({
|
new EsLint({
|
||||||
extensions: ['.ts', '.tsx'],
|
extensions: ['.ts', '.tsx'],
|
||||||
context: path.join(__dirname, '../src/client'),
|
context: path.join(__dirname, '../src/server'),
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
|
@ -29,9 +29,93 @@ body {
|
||||||
width: 25%;
|
width: 25%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tile-child {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: top;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#whoami {
|
||||||
|
background-color: #1d2021;
|
||||||
|
color: #ebdbb2;
|
||||||
|
}
|
||||||
|
|
||||||
|
#git {
|
||||||
|
background-color: #282828;
|
||||||
|
}
|
||||||
|
|
||||||
|
#downloadcv {
|
||||||
|
background-color: #282828;
|
||||||
|
color: #8ec07c;
|
||||||
|
border-color: #8ec07c;
|
||||||
|
}
|
||||||
|
|
||||||
|
#clickme {
|
||||||
|
background-color: #1d2021;
|
||||||
|
color: #d3869b;
|
||||||
|
border-color: #d3869b;
|
||||||
|
}
|
||||||
|
|
||||||
#root {
|
#root {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn,
|
||||||
|
.btn:focus,
|
||||||
|
.btn:active {
|
||||||
|
outline: none;
|
||||||
|
box-shadow: none;
|
||||||
|
background-color: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-mine {
|
||||||
|
border-radius: 0;
|
||||||
|
white-space: normal;
|
||||||
|
background-color: #1d2021;
|
||||||
|
color: #ebdbb2;
|
||||||
|
border-color: #ebdbb2;
|
||||||
|
transition: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-mine:hover,
|
||||||
|
.btn-mine:focus,
|
||||||
|
.btn-mine:active {
|
||||||
|
background-color: #3c3638;
|
||||||
|
color: #fbf1c7;
|
||||||
|
border-color: #fbf1c7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-clickme,
|
||||||
|
.btn-clickme:focus {
|
||||||
|
border-radius: 0;
|
||||||
|
white-space: normal;
|
||||||
|
background-color: #1d2021;
|
||||||
|
color: #ebdbb2;
|
||||||
|
border-color: #ebdbb2;
|
||||||
|
transition: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-clickme:hover,
|
||||||
|
.btn-clickme:active {
|
||||||
|
background-color: #3c3638;
|
||||||
|
color: #fbf1c7;
|
||||||
|
border-color: #fbf1c7;
|
||||||
|
animation: clickme 2s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes clickme {
|
||||||
|
0% {background-color: #b16286;}
|
||||||
|
14.28% {background-color: #458588;}
|
||||||
|
28.57% {background-color: #689d6a;}
|
||||||
|
42.85% {background-color: #98971a;}
|
||||||
|
57.14% {background-color: #d79921;}
|
||||||
|
71.42% {background-color: #d65d0e;}
|
||||||
|
85.71% {background-color: #cc241d;}
|
||||||
|
100% {background-color: #b16286;}
|
||||||
}
|
}
|
After Width: | Height: | Size: 2.4 MiB |
After Width: | Height: | Size: 2.6 MiB |
After Width: | Height: | Size: 2.4 MiB |
After Width: | Height: | Size: 2.2 MiB |
After Width: | Height: | Size: 2.3 MiB |
After Width: | Height: | Size: 2.3 MiB |
After Width: | Height: | Size: 2.6 MiB |
After Width: | Height: | Size: 2.8 MiB |
After Width: | Height: | Size: 3.3 MiB |
After Width: | Height: | Size: 1.8 MiB |
After Width: | Height: | Size: 1.2 MiB |
After Width: | Height: | Size: 1.4 MiB |
After Width: | Height: | Size: 1.0 MiB |
After Width: | Height: | Size: 242 KiB |
|
@ -0,0 +1,14 @@
|
||||||
|
import React from 'react';
|
||||||
|
// @ts-ignore
|
||||||
|
import ShadertoyReact from 'shadertoy-react';
|
||||||
|
// @ts-ignore
|
||||||
|
import fs from '../shaders/baseLattice';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {jsx} a shader
|
||||||
|
*/
|
||||||
|
export default function BaseLattice() {
|
||||||
|
return (
|
||||||
|
<ShadertoyReact fs={fs} />
|
||||||
|
);
|
||||||
|
};
|
|
@ -0,0 +1,39 @@
|
||||||
|
import React, {useState, useEffect} from 'react';
|
||||||
|
|
||||||
|
interface ClickMeProps {
|
||||||
|
windowSize: number;
|
||||||
|
setTrigger: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {jsx} a presentation of me
|
||||||
|
*/
|
||||||
|
export default function ClickMe({windowSize, setTrigger}: ClickMeProps) {
|
||||||
|
const [buttonClass, setButtonClass] = useState('');
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (window.innerWidth > 1200) {
|
||||||
|
setButtonClass('btn-lg');
|
||||||
|
} else {
|
||||||
|
setButtonClass('');
|
||||||
|
}
|
||||||
|
}, [windowSize]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className='
|
||||||
|
tile-child d-flex
|
||||||
|
flex-column
|
||||||
|
align-items-center
|
||||||
|
justify-content-center'
|
||||||
|
id='clickme'>
|
||||||
|
<button
|
||||||
|
type='button'
|
||||||
|
onClick={() => setTrigger(Math.random())}
|
||||||
|
className={'d-inline btn btn-clickme ' + buttonClass}>
|
||||||
|
Click me !
|
||||||
|
</button>
|
||||||
|
<br />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
|
@ -1,14 +1,14 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import ShadertoyReact from 'shadertoy-react';
|
import ShadertoyReact from 'shadertoy-react';
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import fs from '../shaders/collapse';
|
import fs from '../shaders/collapse';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {jsx} a shader
|
* @return {jsx} a shader
|
||||||
*/
|
*/
|
||||||
export default function Collapse() {
|
export default function Collapse() {
|
||||||
return (
|
return (
|
||||||
<ShadertoyReact fs={fs} />
|
<ShadertoyReact fs={fs} />
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
import React, {useState, useEffect} from 'react';
|
||||||
|
|
||||||
|
interface DownloadCVProps {
|
||||||
|
windowSize: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {jsx} a presentation of me
|
||||||
|
*/
|
||||||
|
export default function DownloadCV({windowSize}: DownloadCVProps) {
|
||||||
|
const [buttonClass, setButtonClass] = useState('');
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (window.innerWidth > 1200) {
|
||||||
|
setButtonClass('btn-lg');
|
||||||
|
} else {
|
||||||
|
setButtonClass('');
|
||||||
|
}
|
||||||
|
}, [windowSize]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className='
|
||||||
|
tile-child d-flex
|
||||||
|
flex-column
|
||||||
|
align-items-center
|
||||||
|
justify-content-center'
|
||||||
|
id='downloadcv'>
|
||||||
|
<a
|
||||||
|
href='https://git.gaetanbrochard.dev/gbrochar/expo-web'
|
||||||
|
className={'d-inline btn btn-mine ' + buttonClass}>
|
||||||
|
Download my CV
|
||||||
|
</a>
|
||||||
|
<br />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
|
@ -0,0 +1,45 @@
|
||||||
|
import React, {useState, useEffect} from 'react';
|
||||||
|
|
||||||
|
interface GitProps {
|
||||||
|
windowSize: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {jsx} a presentation of me
|
||||||
|
*/
|
||||||
|
export default function Git({windowSize}: GitProps) {
|
||||||
|
const [topClass, setTopClass] = useState('');
|
||||||
|
const [bottomClass, setBottomClass] = useState('');
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (window.innerWidth > 1200) {
|
||||||
|
setTopClass('btn-lg mb-3');
|
||||||
|
setBottomClass('btn-lg mt-3');
|
||||||
|
} else {
|
||||||
|
setTopClass('mb-1');
|
||||||
|
setBottomClass('mt-1');
|
||||||
|
}
|
||||||
|
}, [windowSize]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className='
|
||||||
|
tile-child d-flex
|
||||||
|
flex-column
|
||||||
|
align-items-center
|
||||||
|
justify-content-center'
|
||||||
|
id='git'>
|
||||||
|
<a
|
||||||
|
href='https://git.gaetanbrochard.dev/gbrochar/expo-web'
|
||||||
|
className={'d-inline btn btn-mine ' + topClass}>
|
||||||
|
This project's git
|
||||||
|
</a>
|
||||||
|
<br />
|
||||||
|
<a
|
||||||
|
href='https://git.gaetanbrochard.dev/gbrochar'
|
||||||
|
className={'d-inline btn btn-mine ' + bottomClass}>
|
||||||
|
My git
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
|
@ -1,25 +1,86 @@
|
||||||
import React from 'react';
|
import React, {useState, useEffect, useCallback} from 'react';
|
||||||
import Shader from './Shader';
|
import Shader from './Shader';
|
||||||
|
import WhoAmI from './WhoAmI';
|
||||||
|
import Git from './Git';
|
||||||
|
import DownloadCV from './DownloadCV';
|
||||||
|
import ClickMe from './ClickMe';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {jsx} The root component
|
* @return {jsx} The root component
|
||||||
*/
|
*/
|
||||||
export default function Root() {
|
export default function Root() {
|
||||||
|
const [windowSize, setWindowSize] = useState(0);
|
||||||
|
const [trigger, setTrigger] = useState(0);
|
||||||
|
const [content, setContent]: any = useState([]);
|
||||||
|
|
||||||
const Shaders = [
|
const Shaders = [
|
||||||
'BaseRaymarching',
|
'BaseRaymarching',
|
||||||
'Collapse',
|
'Collapse',
|
||||||
'Droplets',
|
'Droplets',
|
||||||
'Inception',
|
'Inception',
|
||||||
'Mentstom',
|
'Menstom',
|
||||||
'Torus',
|
'Torus',
|
||||||
'Triangle',
|
'Triangle',
|
||||||
|
'BaseLattice',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const handleWindowResize = useCallback((_event) => {
|
||||||
|
setWindowSize(window.innerWidth);
|
||||||
|
}, []);
|
||||||
|
useEffect(() => {
|
||||||
|
window.addEventListener('resize', handleWindowResize);
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener('resize', handleWindowResize);
|
||||||
|
};
|
||||||
|
}, [handleWindowResize]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let newContent = [];
|
||||||
|
let randomContent = [];
|
||||||
|
let shadersRandom = [];
|
||||||
|
let imagesRandom = [];
|
||||||
|
|
||||||
|
shadersRandom.push(Math.floor(Math.random() * 8));
|
||||||
|
shadersRandom.push(Math.floor(Math.random() * 8));
|
||||||
|
newContent.push(<div className='tile'><Shader name={Shaders[shadersRandom[0]]} /></div>);
|
||||||
|
newContent.push(<div className='tile'><Shader name={Shaders[shadersRandom[1]]} /></div>);
|
||||||
|
newContent.push(<div className='tile'><Shader name={Shaders[shadersRandom[2]]} /></div>);
|
||||||
|
newContent.push(<div className='tile'><Shader name={Shaders[shadersRandom[3]]} /></div>);
|
||||||
|
newContent.push(<div className='tile'><Shader name={Shaders[shadersRandom[4]]} /></div>);
|
||||||
|
newContent.push(<div className='tile'><WhoAmI /></div>);
|
||||||
|
newContent.push(<div className='tile'><Git windowSize={windowSize} /></div>);
|
||||||
|
newContent.push(<div className='tile'><Shader name={Shaders[shadersRandom[5]]} /></div>);
|
||||||
|
newContent.push(<div className='tile'><Shader name={Shaders[shadersRandom[6]]} /></div>);
|
||||||
|
newContent.push(<div className='tile'><DownloadCV windowSize={windowSize} /></div>);
|
||||||
|
newContent.push(<div className='tile'><ClickMe windowSize={windowSize} setTrigger={setTrigger} /></div>);
|
||||||
|
newContent.push(<div className='tile'><Shader name={Shaders[shadersRandom[7]]} /></div>);
|
||||||
|
newContent.push(<div className='tile'><Shader name={Shaders[shadersRandom[8]]} /></div>);
|
||||||
|
newContent.push(<div className='tile'><Shader name={Shaders[shadersRandom[9]]} /></div>);
|
||||||
|
newContent.push(<div className='tile'><Shader name={Shaders[shadersRandom[10]]} /></div>);
|
||||||
|
newContent.push(<div className='tile'><Shader name={Shaders[shadersRandom[11]]} /></div>);
|
||||||
|
setContent(newContent);
|
||||||
|
}, [trigger]);
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div id='root'>
|
<div id='root'>
|
||||||
|
{content}
|
||||||
|
{/* <div className='tile'><Shader name={Shaders[0]} /></div>
|
||||||
<div className='tile'><Shader name={Shaders[0]} /></div>
|
<div className='tile'><Shader name={Shaders[0]} /></div>
|
||||||
<div className='tile'><Shader name={Shaders[1]} /></div>
|
<div className='tile'><Shader name={Shaders[0]} /></div>
|
||||||
<div className='tile'><Shader name={Shaders[2]} /></div>
|
<div className='tile'><Shader name={Shaders[0]} /></div>
|
||||||
|
<div className='tile'><Shader name={Shaders[0]} /></div>
|
||||||
|
<div className='tile'><WhoAmI /></div>
|
||||||
|
<div className='tile'><Git windowSize={windowSize} /></div>
|
||||||
|
<div className='tile'><Shader name={Shaders[0]} /></div>
|
||||||
|
<div className='tile'><Shader name={Shaders[0]} /></div>
|
||||||
|
<div className='tile'><DownloadCV windowSize={windowSize} /></div>
|
||||||
|
<div className='tile'><ClickMe windowSize={windowSize} setTrigger={setTrigger} /></div>
|
||||||
|
<div className='tile'><Shader name={Shaders[0]} /></div>
|
||||||
|
<div className='tile'><Shader name={Shaders[0]} /></div>
|
||||||
|
<div className='tile'><Shader name={Shaders[0]} /></div>
|
||||||
|
<div className='tile'><Shader name={Shaders[0]} /></div>
|
||||||
|
<div className='tile'><Shader name={Shaders[0]} /></div> */}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,8 @@ import Menstom from './Menstom';
|
||||||
import Collapse from './Collapse';
|
import Collapse from './Collapse';
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import Torus from './Torus';
|
import Torus from './Torus';
|
||||||
|
// @ts-ignore
|
||||||
|
import BaseLattice from './BaseLattice';
|
||||||
|
|
||||||
interface ShaderProps {
|
interface ShaderProps {
|
||||||
name: string;
|
name: string;
|
||||||
|
@ -38,6 +40,8 @@ export default function Shader({name}: ShaderProps) {
|
||||||
Shader = <Collapse />;
|
Shader = <Collapse />;
|
||||||
} else if (name == 'Torus') {
|
} else if (name == 'Torus') {
|
||||||
Shader = <Torus />;
|
Shader = <Torus />;
|
||||||
|
} else if (name == 'BaseLattice') {
|
||||||
|
Shader = <BaseLattice />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import ShadertoyReact from 'shadertoy-react';
|
import ShadertoyReact from 'shadertoy-react';
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import fs from '../shaders/torus';
|
import fs from '../shaders/torus';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {jsx} a shader
|
* @return {jsx} a shader
|
||||||
*/
|
*/
|
||||||
export default function Torus() {
|
export default function Torus() {
|
||||||
return (
|
return (
|
||||||
<ShadertoyReact fs={fs} />
|
<ShadertoyReact fs={fs} />
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {jsx} a presentation of me
|
||||||
|
*/
|
||||||
|
export default function WhoAmI() {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className='
|
||||||
|
tile-child d-flex
|
||||||
|
flex-column
|
||||||
|
align-items-center
|
||||||
|
justify-content-center'
|
||||||
|
id='whoami'>
|
||||||
|
<div className='display-4 text-center'>Gaëtan Brochard</div>
|
||||||
|
<div className='lead text-center'>Developer</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
|
@ -0,0 +1,106 @@
|
||||||
|
export default `#define MAX_STEPS 1000
|
||||||
|
#define MAX_DIST 500.
|
||||||
|
#define E 0.000001
|
||||||
|
|
||||||
|
float sdCapsule(vec3 p, vec3 a, vec3 b, float r)
|
||||||
|
{
|
||||||
|
vec3 ab = b - a;
|
||||||
|
vec3 ap = p - a;
|
||||||
|
|
||||||
|
float t = dot(ab, ap) / dot(ab, ab);
|
||||||
|
t = clamp(t, 0., 1.);
|
||||||
|
|
||||||
|
vec3 c = a + t * ab;
|
||||||
|
return length(p - c) - r;
|
||||||
|
}
|
||||||
|
|
||||||
|
float sdTorus(vec3 p, vec2 r)
|
||||||
|
{
|
||||||
|
float x = length(p.xz) - r.x;
|
||||||
|
return length(vec2(x, p.y)) - r.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
float sdBox(vec3 p, vec3 s)
|
||||||
|
{
|
||||||
|
return length(max(abs(p) - s, 0.));
|
||||||
|
}
|
||||||
|
|
||||||
|
float GetDist(vec3 p)
|
||||||
|
{
|
||||||
|
vec4 s = vec4(0, 0, 0, 2);
|
||||||
|
|
||||||
|
p.x += iTime;
|
||||||
|
float s_dist = (length(mod(p, 10.) - s.xyz) - s.w);
|
||||||
|
|
||||||
|
float b_dist1 = sdBox(mod(p + 5., 10.) - vec3(5.) - vec3(0., sin(p.x * 0.2) * 2., sin(p.x * 0.2) * 2.), vec3(10., 0.5, 0.5)) * 0.3;
|
||||||
|
float b_dist2 = sdBox(mod(p + 5., 10.) - vec3(5.) - vec3(sin(p.y * 0.2) * 2., 0., sin(p.y * 0.2) * 2.), vec3(0.5, 10., 0.5)) * 0.3;
|
||||||
|
float b_dist3 = sdBox(mod(p + 5., 10.) - vec3(5.) - vec3(sin(p.z * 0.2) * 2., sin(p.z * 0.2) * 2., 0.), vec3(0.5, 0.5, 10.)) * 0.3;
|
||||||
|
|
||||||
|
float d = min(b_dist1, b_dist2);
|
||||||
|
d = min(d, b_dist3);
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
float RayMarch(vec3 ro, vec3 rd) {
|
||||||
|
float dO = 0.;
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_STEPS; i++)
|
||||||
|
{
|
||||||
|
vec3 p = ro + rd * dO;
|
||||||
|
float dS = GetDist(p);
|
||||||
|
dO += dS;
|
||||||
|
if (dO > MAX_DIST || dS < E)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dO;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 GetNormal(vec3 p)
|
||||||
|
{
|
||||||
|
float d = GetDist(p);
|
||||||
|
vec2 e = vec2(0.3, 0);
|
||||||
|
|
||||||
|
vec3 n = d - vec3(
|
||||||
|
GetDist(p - e.xyy),
|
||||||
|
GetDist(p - e.yxy),
|
||||||
|
GetDist(p - e.yyx));
|
||||||
|
return (normalize(n));
|
||||||
|
}
|
||||||
|
|
||||||
|
float GetLight(vec3 p)
|
||||||
|
{
|
||||||
|
vec3 lightPos = vec3(0, 10, iTime* 3.);
|
||||||
|
lightPos.xz += vec2(sin(iTime), cos(iTime)) * 5.;
|
||||||
|
vec3 l = normalize(lightPos - p);
|
||||||
|
vec3 n = GetNormal(p);
|
||||||
|
|
||||||
|
float dif = clamp(dot(l, n), 0., 1.);
|
||||||
|
//float d = RayMarch(p+n*E * 30., l);
|
||||||
|
//if (d < length(lightPos - p))
|
||||||
|
// dif *= 0.1;
|
||||||
|
return (dif);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 rotate(vec2 p, float theta)
|
||||||
|
{
|
||||||
|
return vec2(cos(p.x) - sin(p.y), sin(p.x) + cos(p.y));
|
||||||
|
}
|
||||||
|
|
||||||
|
void mainImage( out vec4 fragColor, in vec2 fragCoord )
|
||||||
|
{
|
||||||
|
vec2 uv = ((fragCoord - .5 * iResolution.xy) / iResolution.y);
|
||||||
|
|
||||||
|
vec3 up = normalize(vec3(cos(iTime), sin(iTime), 0));
|
||||||
|
vec3 ro = vec3(5. + cos(iTime), 5. + sin(iTime), iTime* 3.);
|
||||||
|
vec3 rd = normalize(vec3(uv.x + 1., uv.y + 1., 1 + 1));
|
||||||
|
|
||||||
|
float d = RayMarch(ro, rd);
|
||||||
|
|
||||||
|
vec3 p = ro + rd * d;
|
||||||
|
|
||||||
|
float dif = GetLight(p);
|
||||||
|
vec3 col = vec3(abs(mod((p.x + sin(iTime))/ 10., 1.) - 0.5) * dif, abs(mod((p.y + sin(iTime)) / 10., 1.) - 0.5) * dif, abs(mod((p.z + sin(iTime)) / 10., 1.) - 0.5) * dif);
|
||||||
|
//col = myvec;
|
||||||
|
fragColor = vec4(col,1.0);
|
||||||
|
}`;
|
|
@ -1,106 +1,144 @@
|
||||||
export default `#define MAX_STEPS 1000
|
export default `
|
||||||
#define MAX_DIST 500.
|
#define MAX_STEPS 1280
|
||||||
#define E 0.000001
|
#define MAX_DIST 128.
|
||||||
|
#define E 0.0001
|
||||||
|
#define PI 3.141592
|
||||||
|
|
||||||
float sdCapsule(vec3 p, vec3 a, vec3 b, float r)
|
vec3 rotX(vec3 v, float a)
|
||||||
{
|
{
|
||||||
vec3 ab = b - a;
|
return vec3(v.x, v.y * cos(a) - v.z * sin(a), v.y * sin(a) + v.z * cos(a));
|
||||||
vec3 ap = p - a;
|
|
||||||
|
|
||||||
float t = dot(ab, ap) / dot(ab, ab);
|
|
||||||
t = clamp(t, 0., 1.);
|
|
||||||
|
|
||||||
vec3 c = a + t * ab;
|
|
||||||
return length(p - c) - r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float sdTorus(vec3 p, vec2 r)
|
vec3 rotY(vec3 v, float a)
|
||||||
|
{
|
||||||
|
return vec3(v.x * cos(a) + v.z * sin(a), v.y, v.z * cos(a) - v.x * sin(a));
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 rotZ(vec3 v, float a)
|
||||||
|
{
|
||||||
|
return vec3(v.x * cos(a) - v.y * sin(a), v.x * sin(a) + v.y * cos(a), v.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 modSDF(vec3 p, vec3 c)
|
||||||
|
{
|
||||||
|
return mod(p + 0.5 * c, c) - 0.5 * c;
|
||||||
|
}
|
||||||
|
|
||||||
|
float sdfTorus(vec3 p, vec2 r)
|
||||||
{
|
{
|
||||||
float x = length(p.xz) - r.x;
|
float x = length(p.xz) - r.x;
|
||||||
return length(vec2(x, p.y)) - r.y;
|
return length(vec2(x, p.y)) - r.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
float sdBox(vec3 p, vec3 s)
|
|
||||||
|
// blackbody by aiekick : https://www.shadertoy.com/view/lttXDn
|
||||||
|
|
||||||
|
// -------------blackbody----------------- //
|
||||||
|
|
||||||
|
// return color from temperature
|
||||||
|
//http://www.physics.sfasu.edu/astro/color/blackbody.html
|
||||||
|
//http://www.vendian.org/mncharity/dir3/blackbody/
|
||||||
|
//http://www.vendian.org/mncharity/dir3/blackbody/UnstableURLs/bbr_color.html
|
||||||
|
|
||||||
|
vec3 blackbody(float Temp)
|
||||||
{
|
{
|
||||||
return length(max(abs(p) - s, 0.));
|
vec3 col = vec3(255.);
|
||||||
|
col.x = 56100000. * pow(Temp,(-3. / 2.)) + 148.;
|
||||||
|
col.y = 100.04 * log(Temp) - 623.6;
|
||||||
|
if (Temp > 6500.) col.y = 35200000. * pow(Temp,(-3. / 2.)) + 184.;
|
||||||
|
col.z = 194.18 * log(Temp) - 1448.6;
|
||||||
|
col = clamp(col, 0., 255.)/255.;
|
||||||
|
if (Temp < 1000.) col *= Temp/1000.;
|
||||||
|
return col;
|
||||||
}
|
}
|
||||||
|
|
||||||
float GetDist(vec3 p)
|
// -------------blackbody----------------- //
|
||||||
|
|
||||||
|
|
||||||
|
float scene(vec3 p)
|
||||||
{
|
{
|
||||||
vec4 s = vec4(0, 0, 0, 2);
|
float td1 = sdfTorus(
|
||||||
|
modSDF(
|
||||||
p.x += iTime;
|
rotX(
|
||||||
float s_dist = (length(mod(p, 10.) - s.xyz) - s.w);
|
p - vec3(3. + cos(p.x * 10. + iTime) / 3., sin(p.y * 10. + iTime) / 3., 6.),
|
||||||
|
PI / 2.),
|
||||||
float b_dist1 = sdBox(mod(p + 5., 10.) - vec3(5.) - vec3(0., sin(p.x * 0.2) * 2., sin(p.x * 0.2) * 2.), vec3(10., 0.5, 0.5)) * 0.3;
|
vec3(6.)), vec2(2., abs(sin(iTime)) * 0.2 + 0.1)) * 0.1;
|
||||||
float b_dist2 = sdBox(mod(p + 5., 10.) - vec3(5.) - vec3(sin(p.y * 0.2) * 2., 0., sin(p.y * 0.2) * 2.), vec3(0.5, 10., 0.5)) * 0.3;
|
float td2 = sdfTorus(
|
||||||
float b_dist3 = sdBox(mod(p + 5., 10.) - vec3(5.) - vec3(sin(p.z * 0.2) * 2., sin(p.z * 0.2) * 2., 0.), vec3(0.5, 0.5, 10.)) * 0.3;
|
modSDF(
|
||||||
|
rotZ(
|
||||||
float d = min(b_dist1, b_dist2);
|
rotX(
|
||||||
d = min(d, b_dist3);
|
p - vec3(3. + cos(p.x * 10. + iTime) / 3., -3. + sin(p.y * 10. + iTime) / 3., 6.), PI / 2.), PI / 2.), vec3(6.)), vec2(2., abs(cos(iTime)) * 0.2 + 0.1))* 0.1;
|
||||||
|
float td3 = sdfTorus(
|
||||||
|
modSDF(
|
||||||
|
rotZ(
|
||||||
|
p - vec3(cos(p.x * 10. + iTime) / 3., sin(p.y * 10. + iTime) / 3., 3.), PI / 2.), vec3(6.)), vec2(2., abs(sin(iTime)) * 0.2 + 0.1))* 0.1;
|
||||||
|
float td4 = sdfTorus(modSDF(p + vec3(cos(p.x * 10. + iTime) / 3., sin(p.y * 10. + iTime) / 3., -6.), vec3(6.)), vec2(2., abs(cos(iTime)) * 0.2 + 0.1))* 0.1;
|
||||||
|
//float td2 = 10000.;
|
||||||
|
float d = min(td1, td2);
|
||||||
|
d = min(d, td3);
|
||||||
|
d = min(d, td4);
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
float RayMarch(vec3 ro, vec3 rd) {
|
float march(vec3 ro, vec3 rd)
|
||||||
|
{
|
||||||
float dO = 0.;
|
float dO = 0.;
|
||||||
|
|
||||||
for (int i = 0; i < MAX_STEPS; i++)
|
for (int steps = 0; steps < MAX_STEPS; steps++)
|
||||||
{
|
{
|
||||||
vec3 p = ro + rd * dO;
|
vec3 p = ro + rd * dO;
|
||||||
float dS = GetDist(p);
|
float dS = scene(p);
|
||||||
dO += dS;
|
dO += dS;
|
||||||
if (dO > MAX_DIST || dS < E)
|
if (dS < E || dO > MAX_DIST)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return dO;
|
return dO;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 GetNormal(vec3 p)
|
vec3 normal(vec3 p)
|
||||||
{
|
{
|
||||||
float d = GetDist(p);
|
float d = scene(p);
|
||||||
vec2 e = vec2(0.3, 0);
|
vec2 e = vec2(0.3, 0);
|
||||||
|
|
||||||
vec3 n = d - vec3(
|
vec3 n = d - vec3(
|
||||||
GetDist(p - e.xyy),
|
scene(p - e.xyy),
|
||||||
GetDist(p - e.yxy),
|
scene(p - e.yxy),
|
||||||
GetDist(p - e.yyx));
|
scene(p - e.yyx));
|
||||||
return (normalize(n));
|
return (normalize(n));
|
||||||
}
|
}
|
||||||
|
|
||||||
float GetLight(vec3 p)
|
float light(vec3 p)
|
||||||
{
|
{
|
||||||
vec3 lightPos = vec3(0, 10, iTime* 3.);
|
vec3 lightPos = vec3(0., 0., 0.);
|
||||||
lightPos.xz += vec2(sin(iTime), cos(iTime)) * 5.;
|
|
||||||
vec3 l = normalize(lightPos - p);
|
vec3 l = normalize(lightPos - p);
|
||||||
vec3 n = GetNormal(p);
|
vec3 n = normal(p);
|
||||||
|
|
||||||
float dif = clamp(dot(l, n), 0., 1.);
|
|
||||||
//float d = RayMarch(p+n*E * 30., l);
|
|
||||||
//if (d < length(lightPos - p))
|
|
||||||
// dif *= 0.1;
|
|
||||||
return (dif);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec2 rotate(vec2 p, float theta)
|
float dif = clamp(dot(l, n), 0., 1.);
|
||||||
{
|
// float d = march(p+n*E * 30., l);
|
||||||
return vec2(cos(p.x) - sin(p.y), sin(p.x) + cos(p.y));
|
// if (d < length(lightPos - p))
|
||||||
|
// dif *= 0.1;
|
||||||
|
return (dif);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mainImage( out vec4 fragColor, in vec2 fragCoord )
|
void mainImage( out vec4 fragColor, in vec2 fragCoord )
|
||||||
{
|
{
|
||||||
vec2 uv = ((fragCoord - .5 * iResolution.xy) / iResolution.y);
|
vec2 uv = ((fragCoord - .5 * iResolution.xy) / iResolution.y);
|
||||||
|
|
||||||
vec3 up = normalize(vec3(cos(iTime), sin(iTime), 0));
|
vec3 ro = vec3(7., 7., iTime);
|
||||||
vec3 ro = vec3(5. + cos(iTime), 5. + sin(iTime), iTime* 3.);
|
vec3 rd = normalize(vec3(uv.x, uv.y, 1));
|
||||||
vec3 rd = normalize(vec3(uv.x + 1., uv.y + 1., 1 + 1));
|
rd = rotX(rd, iTime * 0.256);
|
||||||
|
rd = rotY(rd, iTime * 0.314);
|
||||||
float d = RayMarch(ro, rd);
|
rd = rotZ(rd, iTime * 0.1618);
|
||||||
|
//rd = rotX(rd, PI / 2.);
|
||||||
|
|
||||||
|
float d = march(ro, rd);
|
||||||
|
|
||||||
vec3 p = ro + rd * d;
|
vec3 p = ro + rd * d;
|
||||||
|
float dif = light(p);
|
||||||
float dif = GetLight(p);
|
vec3 col = vec3(dif);
|
||||||
vec3 col = vec3(abs(mod((p.x + sin(iTime))/ 10., 1.) - 0.5) * dif, abs(mod((p.y + sin(iTime)) / 10., 1.) - 0.5) * dif, abs(mod((p.z + sin(iTime)) / 10., 1.) - 0.5) * dif);
|
col = blackbody(d * 10.);
|
||||||
//col = myvec;
|
col += vec3(abs(mod((p.x + sin(iTime))/ 10., 1.) - 0.5) * dif, abs(mod((p.y + sin(iTime)) / 10., 1.) - 0.5) * dif, abs(mod((p.z + sin(iTime)) / 10., 1.) - 0.5) * dif);
|
||||||
fragColor = vec4(col,1.0);
|
// Output to screen
|
||||||
}`;
|
col = pow(col, vec3(0.454545));
|
||||||
|
fragColor = vec4(col, 1.0);
|
||||||
|
}`
|
|
@ -6,6 +6,7 @@
|
||||||
<meta name="Description" content="Web version of digital art exhibition">
|
<meta name="Description" content="Web version of digital art exhibition">
|
||||||
<title>Web-Expo</title>
|
<title>Web-Expo</title>
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
|
||||||
<link rel="stylesheet" href="static/css/style.css">
|
<link rel="stylesheet" href="static/css/style.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|