├── README.md
├── docs
├── css
│ └── page.css
├── favicons
│ ├── apple-touch-icon-120x120-precomposed.png
│ ├── apple-touch-icon-152x152-precomposed.png
│ ├── favicon-16x16.png
│ ├── favicon-180x180.png
│ ├── favicon-192x192.png
│ ├── favicon-32x32.png
│ ├── favicon-48x48.png
│ ├── favicon-60x60.png
│ └── favicon-96x96.png
├── images
│ ├── gear.svg
│ ├── noise-dark.png
│ ├── noise-light.png
│ └── resize.svg
├── index.html
├── readme
│ ├── css
│ │ └── page.css
│ ├── favicons
│ │ ├── apple-touch-icon-120x120-precomposed.png
│ │ ├── apple-touch-icon-152x152-precomposed.png
│ │ ├── favicon-16x16.png
│ │ ├── favicon-180x180.png
│ │ ├── favicon-192x192.png
│ │ ├── favicon-32x32.png
│ │ ├── favicon-48x48.png
│ │ ├── favicon-60x60.png
│ │ └── favicon-96x96.png
│ ├── images
│ │ ├── noise-dark.png
│ │ └── noise-light.png
│ ├── index.html
│ └── robots.txt
├── resources
│ ├── models
│ │ ├── cat.glb
│ │ ├── chair.glb
│ │ ├── chair_feet.glb
│ │ ├── dice.glb
│ │ ├── sphere.glb
│ │ └── torus.glb
│ └── textures
│ │ ├── chair.png
│ │ ├── dark.jpg
│ │ ├── dice.png
│ │ ├── giraffe.png
│ │ ├── noise.png
│ │ ├── torus.png
│ │ └── white.png
├── robots.txt
└── script
│ ├── main.min.js
│ ├── main.min.js.LICENSE.txt
│ └── page.min.js
└── src
└── readme
├── chair.jpg
└── sphere.jpg
/README.md:
--------------------------------------------------------------------------------
1 | # fur-threejs
2 |
3 | ## Description
4 | This project is my take on real-time fur rendering. The result is quite good and flexible since it can adapt to any 3D model. A few properties are customizable, such as length, thickness, orientation and color patterns.
5 |
6 | Technically, I implemented the traditional shells and fins technique, adapted for WebGL (which lacks Geometry Shaders unfortunately).
7 |
8 | See it live [here](https://piellardj.github.io/fur-threejs/).
9 |
10 | [](https://www.paypal.com/donate/?hosted_button_id=AF7H7GEJTL95E)
11 |
12 | ## Preview
13 |
14 | 
15 |
16 | 
17 |
--------------------------------------------------------------------------------
/docs/css/page.css:
--------------------------------------------------------------------------------
1 | body{text-align:center}#error-messages{margin:32px 8px;color:red;font-weight:bold}.demo{display:flex;flex-flow:row wrap;align-items:flex-start;justify-content:center;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}
2 | .logo{display:block;position:relative;width:64px;height:64px;margin:8px auto 16px;border-radius:50%;user-select:none;box-sizing:border-box}.logo,.logo:hover,.logo:focus,.logo:active{border-width:1px;border-style:solid;border-color:#009688;border-color:var(--var-color-control-accent, #009688)}.logo::before,.logo svg.logo-icon,.logo::after{position:absolute;top:-1px;left:-1px;width:64px;height:64px;border-radius:50%;pointer-events:none}.logo svg.logo-icon{stroke:#009688;stroke:var(--var-color-control-accent, #009688);fill:#009688;fill:var(--var-color-control-accent, #009688)}.logo::before{content:"";transform:scale(0);-webkit-transform:scale(0);-ms-transform:scale(0);transition:.1s ease;-webkit-transition:.1s ease}.logo.logo-animate-fill .logo::before{content:"";transform:scale(0);-webkit-transform:scale(0);-ms-transform:scale(0);transition:.1s ease;-webkit-transition:.1s ease}.logo:hover::before{transform:scale(1);-webkit-transform:scale(1);-ms-transform:scale(1)}.logo.logo-animate-fill{background:#eeeeee;background:var(--var-color-block-background, #eeeeee)}.logo.logo-animate-fill::before{background:#009688;background:var(--var-color-control-accent, #009688)}.logo.logo-animate-fill:hover svg.logo-icon{fill:#fff;stroke:#fff}.logo.logo-animate-empty{background:#009688;background:var(--var-color-control-accent, #009688)}.logo.logo-animate-empty::before{top:0;left:0;width:62px;height:62px;background:#eeeeee;background:var(--var-color-block-background, #eeeeee)}
3 | .intro{margin:auto;padding:16px;border-radius:8px;border:1px solid #c9c9c9;border:var(--var-color-block-border, 1px solid #c9c9c9);background:#eeeeee;background:var(--var-color-block-background, #eeeeee)}.intro h1{margin-top:0;text-align:center}@media only screen and (min-width: 560px){.intro{max-width:512px;border-width:1px}}.description{justify-content:center;line-height:125%;text-align:justify;text-indent:1em}.project-links{display:flex;flex-flow:row;justify-content:space-between;text-indent:0}
4 | a{color:#009688;color:var(--var-color-control-accent, #009688);font-weight:bold;text-decoration:none;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;border-width:0 0 2px;border-style:solid;border-color:rgba(0,0,0,0)}a:focus,a:hover{border-color:#009688;border-color:var(--var-color-control-accent, #009688)}
5 | .canvas-button{width:32px;height:32px;cursor:pointer}#canvas-container{position:relative;margin-bottom:16px;background:#000;overflow:hidden}@media only screen and (min-width: 540px){#canvas-container{margin:16px}}#canvas-container>canvas{width:100%;height:100%;z-index:10}#canvas-container>.loader{display:none}#indicators{display:flex;position:absolute;top:1px;left:1px;flex-direction:column;align-items:flex-start;color:#fff;font-family:"Lucida Console",Monaco,monospace;text-align:left;z-index:20}#indicators>div{flex:0 0 1em;margin:1px;padding:1px 4px;background:#000}#canvas-buttons-column{position:absolute;top:0;right:0;width:32px;z-index:30}#fullscreen-toggle-id{display:block;background-image:url("../images/resize.svg");background-position:0 0;background-size:200%}#fullscreen-toggle-id:hover{background-position-x:100%}#side-pane-toggle-id{display:none;background-image:url("../images/gear.svg");transition:transform .1s ease-in-out;-webkit-transition:transform .1s ease-in-out}#side-pane-toggle-id:hover{transform:rotate(-30deg);-webkit-transform:rotate(-30deg);-ms-transform:rotate(-30deg)}#side-pane-checkbox-id:checked+#canvas-container #side-pane-toggle-id:hover{transform:rotate(30deg);-webkit-transform:rotate(30deg);-ms-transform:rotate(30deg)}.hidden{display:none}#fullscreen-checkbox-id:checked+.demo{position:fixed;overflow:hidden}#fullscreen-checkbox-id:checked+.demo #canvas-container{position:fixed;top:0;left:0;width:100vw;height:100vh;margin:0;overflow:hidden;z-index:5}#fullscreen-checkbox-id:checked+.demo #canvas-container #canvas-buttons-column{transition:transform .2s ease-in-out;-webkit-transition:transform .2s ease-in-out}#fullscreen-checkbox-id:checked+.demo #canvas-container #fullscreen-toggle-id{background-position-y:100%}@media only screen and (min-width: 500px){#fullscreen-checkbox-id:checked+.demo #canvas-container #side-pane-toggle-id{display:block}}#fullscreen-checkbox-id:checked+.demo #side-pane-checkbox-id:checked+#canvas-container #canvas-buttons-column{transform:translateX(-400px)}
6 | .loader{position:absolute;top:0;right:0;bottom:0;left:0;width:120px;height:120px;margin:auto}.loader>span{color:#fff;font-size:32px;line-height:120px;text-shadow:1px 1px #000,-1px 1px #000,1px -1px #000,-1px -1px #000,1px 0 #000,-1px 0 #000,0 1px #000,0 -1px #000}.loader-animation{position:absolute;top:0;left:0;width:120px;height:120px;animation:spin 1.1s linear infinite}.loader-animation:before{position:absolute;top:-1px;left:-1px;width:122px;height:122px;border:6px solid rgba(0,0,0,0);border-top:6px solid #000;border-radius:50%;content:"";z-index:50;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}.loader-animation:after{position:absolute;top:0;left:0;width:120px;height:120px;border:4px solid rgba(0,0,0,0);border-top:4px solid #fff;border-radius:50%;content:"";z-index:51;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}
7 | .canvas-button{width:32px;height:32px;cursor:pointer}.controls-block{flex:1 0 0;max-width:36em;margin:16px 0;padding:12px 0;border-radius:8px;border:1px solid #c9c9c9;border:var(--var-color-block-border, 1px solid #c9c9c9);background:#eeeeee;background:var(--var-color-block-background, #eeeeee);z-index:0}@media only screen and (min-width: 540px){.controls-block{margin:16px}}.controls-block>hr{margin:12px 0;clear:both;border:none;border-top:1px solid #c9c9c9;border-top:var(--var-color-block-border, 1px solid #c9c9c9)}.controls-section{display:flex;flex-flow:row wrap;align-items:baseline;margin:0 16px}.controls-section>h2{width:7em;margin:0;font-size:medium;font-weight:bold;line-height:2em;text-align:left}.controls-section>.controls-list{display:flex;flex-direction:column;flex-grow:1}.controls-list>.control{display:flex;flex-flow:row wrap;align-items:center;min-width:300px;padding:3px 0}.control>label{min-width:8em;font-size:95%;line-height:95%;text-align:left}#fullscreen-checkbox-id:checked+.demo #side-pane-checkbox-id~.controls-block{position:fixed;top:0;left:100%;width:400px;max-height:calc(100% - 48px);margin:0;border-width:0 0 1px 1px;border-radius:0 0 0 8px;z-index:50;overflow-x:hidden;overflow-y:auto;transition:transform .2s ease-in-out;-webkit-transition:transform .2s ease-in-out}#fullscreen-checkbox-id:checked+.demo #side-pane-checkbox-id~.controls-block::-webkit-scrollbar{width:16px}#fullscreen-checkbox-id:checked+.demo #side-pane-checkbox-id~.controls-block::-webkit-scrollbar-track{border-radius:8px;background-color:#eeeeee;background-color:var(--var-color-block-background, #eeeeee)}#fullscreen-checkbox-id:checked+.demo #side-pane-checkbox-id~.controls-block::-webkit-scrollbar-thumb{border-width:3px 5px;border-style:solid;border-radius:8px;border-color:#eeeeee;border-color:var(--var-color-block-background, #eeeeee);background-color:#a5a5a5;background-color:var(--var-color-scrollbar, #a5a5a5)}#fullscreen-checkbox-id:checked+.demo #side-pane-checkbox-id~.controls-block::-webkit-scrollbar-thumb:focus,#fullscreen-checkbox-id:checked+.demo #side-pane-checkbox-id~.controls-block::-webkit-scrollbar-thumb:hover{background-color:#b2b2b2;background-color:var(--var-color-scrollbar-hover, #b2b2b2)}#fullscreen-checkbox-id:checked+.demo #side-pane-checkbox-id~.controls-block::-webkit-scrollbar-thumb:active{background-color:#959595;background-color:var(--var-color-scrollbar-active, #959595)}#fullscreen-checkbox-id:checked+.demo #side-pane-checkbox-id~.controls-block:hover::-webkit-scrollbar-thumb{border-width:3px}#fullscreen-checkbox-id:checked+.demo #side-pane-checkbox-id:checked~.controls-block{transform:translateX(-100%);-webkit-transform:translateX(-100%);-ms-transform:translateX(-100%)}#fullscreen-checkbox-id:checked+.demo #side-pane-checkbox-id:checked~.controls-block .tooltip{transform:translateX(-100vw) translateX(400px);-webkit-transform:translateX(-100vw) translateX(400px);-ms-transform:translateX(-100vw) translateX(400px)}#fullscreen-checkbox-id:checked+.demo #side-pane-checkbox-id:checked~.controls-block>#side-pane-close-toggle-id{display:block}#side-pane-close-toggle-id{display:none;position:absolute;top:0;right:0}#side-pane-close-toggle-id svg{stroke:#5e5e5e;stroke:var(--var-color-block-actionitem, #5e5e5e)}#side-pane-close-toggle-id svg:focus,#side-pane-close-toggle-id svg:hover{stroke:#7e7e7e;stroke:var(--var-color-block-actionitem-hover, #7e7e7e)}#side-pane-close-toggle-id svg:active{stroke:#535353;stroke:var(--var-color-block-actionitem-active, #535353)}
8 | .tabs{display:flex;position:relative;flex-flow:row wrap;flex-grow:1;width:auto;border-radius:4px;background:none;overflow:hidden}.tabs::after{position:absolute;top:0;left:0;width:100%;height:100%;border-width:2px;border-style:solid;border-color:#c9c9c9;border-color:var(--var-color-control-neutral, #c9c9c9);border-radius:4px;content:"";z-index:1;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}.tabs.compact>input+label{padding:6px 14px;font-size:75%}.tabs>input{position:absolute;top:0;left:0;width:1px;height:1px;opacity:0}.tabs>input+label{flex:1;padding:8px 14px;font-size:87.5%;font-weight:bold;text-align:center;white-space:nowrap;cursor:pointer;z-index:2}.tabs>input:disabled+label,.tabs>input[type=radio]:checked+label{cursor:default}.tabs>input+label{background:none;color:#009688;color:var(--var-color-control-accent, #009688)}.tabs>input:checked+label{background:#009688;background:var(--var-color-control-accent, #009688);color:#fff}.tabs>input:disabled+label{background:none;color:#a5a5a5}.tabs>input:disabled:checked+label{background:#a5a5a5;color:#fff}.tabs>input[type=checkbox]:not(:disabled):hover+label,.tabs>input[type=checkbox]:not(:disabled):focus+label{background:rgba(0,150,136,.05)}.tabs>input[type=checkbox]:not(:disabled):hover:checked+label,.tabs>input[type=checkbox]:not(:disabled):focus:checked+label{background:#26a69a;background:var(--var-color-control-accent-hover, #26a69a)}.tabs>input[type=checkbox]:not(:disabled):active+label{background:rgba(0,150,136,.1)}.tabs>input[type=checkbox]:not(:disabled):active:checked+label{background:#00897b;background:var(--var-color-control-accent-active, #00897b)}.tabs>input[type=radio]:not(:disabled):not(:checked):hover+label,.tabs>input[type=radio]:not(:disabled):not(:checked):focus+label{background:rgba(0,150,136,.05)}.tabs>input[type=radio]:not(:disabled):not(:checked):active+label{background:rgba(0,150,136,.1)}
9 | .checkbox{display:block;position:relative;text-align:left;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.checkbox>input[type=checkbox]{width:1px;height:1px;opacity:0}.checkbox>input[type=checkbox]+label.checkmark,.checkbox>input[type=checkbox]+label.checkmark-line{margin-left:24px;line-height:26px;cursor:pointer}.checkbox>input[type=checkbox]:disabled+label.checkmark,.checkbox>input[type=checkbox]:disabled+label.checkmark-line{cursor:default}.checkbox>input[type=checkbox]+label.checkmark::before{position:absolute;top:calc(.5*(100% - 20px));left:0;width:20px;height:20px;border-width:2px;border-style:solid;border-radius:2px;background:none;content:"";box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}.checkbox>input[type=checkbox]+label.checkmark::after{position:absolute;top:calc(.5*(100% - 20px) + .5*(20px - 14px));right:0;bottom:0;left:6.5px;width:7px;height:14px;border:solid #fff;border-width:0 3px 3px 0;background:none;content:"";box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;transform:translate(0, -1px) scale(0) rotate(45deg);-webkit-transform:translate(0, -1px) scale(0) rotate(45deg);-ms-transform:translate(0, -1px) scale(0) rotate(45deg)}.checkbox>input[type=checkbox]:checked+label.checkmark::after{transform:translate(0, -1px) scale(1) rotate(45deg);-webkit-transform:translate(0, -1px) scale(1) rotate(45deg);-ms-transform:translate(0, -1px) scale(1) rotate(45deg)}.checkbox>input[type=checkbox]+label.checkmark::before{border-color:#009688;border-color:var(--var-color-control-accent, #009688)}.checkbox>input[type=checkbox]:checked+label.checkmark::before{background:#009688;background:var(--var-color-control-accent, #009688)}.checkbox>input[type=checkbox]:hover+label.checkmark::before,.checkbox>input[type=checkbox]:focus+label.checkmark::before{border-color:#26a69a;border-color:var(--var-color-control-accent-hover, #26a69a)}.checkbox>input[type=checkbox]:hover:checked+label.checkmark::before,.checkbox>input[type=checkbox]:focus:checked+label.checkmark::before{background:#26a69a;background:var(--var-color-control-accent-hover, #26a69a)}.checkbox>input[type=checkbox]:active+label.checkmark::before{border-color:#00897b;border-color:var(--var-color-control-accent-active, #00897b)}.checkbox>input[type=checkbox]:active:checked+label.checkmark::before{background:#00897b;background:var(--var-color-control-accent-active, #00897b)}.checkbox>input[type=checkbox]:disabled+label.checkmark::before{border-color:#a5a5a5}.checkbox>input[type=checkbox]:disabled:checked+label.checkmark::before{background:#a5a5a5}
10 | .color-picker-container{position:relative}.color-picker{display:flex;flex-flow:row;align-items:center;cursor:pointer}.color-preview{width:32px;height:32px;margin-right:12px;border-width:2px;border-style:solid;border-color:#c9c9c9;border-color:var(--var-color-control-neutral, #c9c9c9);border-radius:50%;line-height:32px;box-sizing:border-box}.color-picker.compact .color-preview{width:26px;height:26px;line-height:26px}.color-picker:hover .color-preview,.color-picker:focus .color-preview{border-color:#26a69a;border-color:var(--var-color-control-accent-hover, #26a69a)}.color-picker:active .color-preview{border-color:#00897b;border-color:var(--var-color-control-accent-active, #00897b)}.color-value{text-transform:uppercase}.color-picker-popup{display:flex;position:absolute;top:0;left:0;flex-flow:column nowrap;min-width:275px;min-height:300px;text-align:left;white-space:nowrap;z-index:100}.color-picker-popup .picker .cursor{position:absolute;transform:translate(-50%, -50%);border:2px solid #fff;cursor:pointer}.color-picker-popup .value-saturation-picker{flex:1;min-height:180px}.color-picker-popup .value-saturation-picker .color-filter{position:absolute;top:0;left:0;width:100%;height:100%}.color-picker-popup .value-saturation-picker .cursor{top:0;left:0;width:16px;height:16px;border-radius:50%}.color-picker-popup .hue-picker{height:28px}.color-picker-popup .hue-picker .hue-bar{position:absolute;top:calc(50% - 5px);left:0;width:100%;height:10px;border-radius:5px;background:linear-gradient(to right, hsl(0, 100%, 50%), hsl(60, 100%, 50%), hsl(120, 100%, 50%), hsl(180, 100%, 50%), hsl(240, 100%, 50%), hsl(300, 100%, 50%), hsl(0, 100%, 50%))}.color-picker-popup .hue-picker .cursor{top:50%;left:0;width:10px;height:28px;border-radius:6px}.color-picker-popup .preview-block{display:flex;flex-flow:row nowrap}.color-picker-popup .preview-block .preview-color{flex:0 0 50px;width:50px;min-height:50px;background:green}.color-picker-popup .preview-block tr{height:28px}.color-picker-popup .preview-block input[type=text]{margin:0 0 0 4px;padding:3px 2px;border-width:1px;border-style:solid;border-radius:4px;background:none;color:inherit;font-size:inherit;border-color:#c9c9c9;border-color:var(--var-color-control-neutral, #c9c9c9)}.color-picker-popup .preview-block input[type=text]:invalid{border-color:red;outline:red solid}.color-picker-popup .outlined{border-width:1px;border-style:solid;border-color:#c9c9c9;border-color:var(--var-color-control-neutral, #c9c9c9);border-radius:4px}.popup{padding:7px;background:#fff;background:var(--var-color-theme, white);border:1px solid #c9c9c9;border:var(--var-color-block-border, 1px solid #c9c9c9);border-radius:8px;box-shadow:0 0 10px rgba(50,50,50,.6)}.popup .block{position:relative;margin:7px}
11 | .range-container{display:inline-block;position:relative;flex:1 1 0%;width:100%;min-width:15px;height:26px}.range-container input[type=range]{width:100%;min-width:128px;height:100%;margin:0;padding:0;opacity:0}.range-container input[type=range]:not(:disabled){cursor:pointer}.range-container .range-skin-container{display:flex;position:absolute;top:0;left:0;flex-flow:nowrap;width:100%;height:100%;pointer-events:none;user-select:none}.range-container .range-stub{position:relative;flex-grow:0;flex-shrink:0;width:7px}.range-container .range-progress{display:flex;flex:1;flex-flow:row nowrap}.range-container .range-progress-left{position:relative;flex-grow:0;flex-shrink:0;width:85%}.range-container .range-progress-right{position:relative;flex-grow:1}.range-container .range-bar{position:absolute;left:0;width:100%;z-index:0}.range-container .range-bar.range-bar-left{top:12px;height:3px}.range-container .range-bar.range-bar-right{top:12px;height:3px;background:#c9c9c9;background:var(--var-color-control-neutral, #c9c9c9)}.range-container .range-bar.range-stub-left{border-radius:3px 0 0 3px}.range-container .range-bar.range-stub-right{border-radius:0 3px 3px 0}.range-container .range-handle{position:absolute;top:5.5px;right:-7.5px;width:15px;height:15px;border-radius:50%;z-index:1}.range-container .range-bar-left,.range-container .range-handle{background:#009688;background:var(--var-color-control-accent, #009688)}.range-container input[type=range]:not(:disabled):hover+.range-skin-container .range-handle,.range-container input[type=range]:not(:disabled):focus+.range-skin-container .range-handle{background:#26a69a;background:var(--var-color-control-accent-hover, #26a69a)}.range-container input[type=range]:not(:disabled):active+.range-skin-container .range-handle{background:#00897b;background:var(--var-color-control-accent-active, #00897b)}.range-container input[type=range]:disabled+.range-skin-container .range-bar-left,.range-container input[type=range]:disabled+.range-skin-container .range-handle{background:#a5a5a5}.range-container .range-tooltip{position:absolute;top:-28px;right:0;min-width:24px;padding:4px;transform:translateX(50%);transition:opacity .1s ease-in-out;border-radius:4px;background:#535353;color:#eee;font-size:87.5%;text-align:center;opacity:0;z-index:2}.range-container input[type=range]:hover+.range-skin-container .range-tooltip,.range-container input[type=range]:active+.range-skin-container .range-tooltip,.range-container input[type=range]:focus+.range-skin-container .range-tooltip{opacity:1}.range-container .range-tooltip::after{position:absolute;top:100%;left:50%;width:0px;height:12px;margin-left:-6px;border-width:6px;border-style:solid;border-color:#535353 rgba(0,0,0,0) rgba(0,0,0,0);content:""}
12 | .select-container{display:inline-block;position:relative;text-align:left;user-select:none}.select-container .select-value,.select-container .select-current-value{padding:0 12px;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.select-container .select-current-value{padding-right:24px;border-width:2px;border-style:solid;border-color:#c9c9c9;border-color:var(--var-color-control-neutral, #c9c9c9);border-radius:4px;font-size:87.5%;font-weight:bold;line-height:28px}.select-container .select-current-value::after{position:absolute;top:13px;right:10px;width:0;height:0;border-width:7px;border-style:solid;border-color:rgba(0,0,0,0);content:"";border-top-color:#009688;border-top-color:var(--var-color-control-accent, #009688)}.select-container.expanded .select-current-value{border-radius:4px 4px 0 0;border-color:#26a69a;border-color:var(--var-color-control-accent-hover, #26a69a);border-bottom-color:#c9c9c9;border-bottom-color:var(--var-color-control-neutral, #c9c9c9)}.select-container.expanded .select-current-value::after{top:5px;border-color:rgba(0,0,0,0);border-bottom-color:#26a69a;border-bottom-color:var(--var-color-control-accent-hover, #26a69a)}.select-container.compact .select-current-value{font-size:75%;line-height:22px}.select-container.compact .select-current-value::after{top:10px}.select-container.compact.expanded .select-current-value::after{top:2px}.select-container:not(.expanded) .select-current-value{cursor:pointer}.select-container:not(.expanded):hover .select-current-value{border-color:#26a69a;border-color:var(--var-color-control-accent-hover, #26a69a)}.select-container:not(.expanded):hover .select-current-value::after{border-top-color:#26a69a;border-top-color:var(--var-color-control-accent-hover, #26a69a)}.select-container:not(.expanded):active .select-current-value{border-color:#00897b;border-color:var(--var-color-control-accent-active, #00897b)}.select-container:not(.expanded):active .select-current-value::after{border-top-color:#00897b;border-top-color:var(--var-color-control-accent-active, #00897b)}.select-container .select-values-list{display:none;position:absolute;top:100%;left:0;width:100%;border-width:0 2px 2px;border-style:solid;border-color:#26a69a;border-color:var(--var-color-control-accent-hover, #26a69a);border-radius:0 0 4px 4px;font-size:87.5%;line-height:32px;box-shadow:0 10px 16px rgba(0,0,0,.2);z-index:3;box-sizing:border-box;background:#fff;background:var(--var-color-theme, white)}.select-container .select-values-list::before{position:absolute;top:-4px;left:-2px;width:100%;height:6px;border-width:0 2px;border-style:solid;content:"";border-color:#26a69a;border-color:var(--var-color-control-accent-hover, #26a69a)}.select-container.expanded .select-values-list{display:block}.select-container.expanded .select-values-list .select-value{cursor:pointer}.select-container.expanded .select-values-list .select-value:hover{background:rgba(0,150,136,.1)}
13 | :root{--var-color-theme:white;--var-color-page-background:#ededed;--var-page-background-image:url("../images/noise-light.png");--var-color-block-background:#eeeeee;--var-color-block-border:1px solid #c9c9c9;--var-color-title:#535353;--var-color-text:#676767;--var-color-block-actionitem:#5e5e5e;--var-color-block-actionitem-hover:#7e7e7e;--var-color-block-actionitem-active:#535353;--var-color-scrollbar:#a5a5a5;--var-color-scrollbar-hover:#b2b2b2;--var-color-scrollbar-active:#959595;--var-color-control-neutral:#c9c9c9;--var-color-control-accent:#009688;--var-color-control-accent-hover:#26a69a;--var-color-control-accent-active:#00897b}@media(prefers-color-scheme: dark){:root{--var-color-theme:black;--var-color-page-background:#232323;--var-page-background-image:url("../images/noise-dark.png");--var-color-block-background:#202020;--var-color-block-border:1px solid #535353;--var-color-title:#eeeeee;--var-color-text:#dbdbdb;--var-color-block-actionitem:#dbdbdb;--var-color-block-actionitem-hover:#eeeeee;--var-color-block-actionitem-active:#c9c9c9;--var-color-scrollbar:#7e7e7e;--var-color-scrollbar-hover:#959595;--var-color-scrollbar-active:#676767;--var-color-control-neutral:#5e5e5e;--var-color-control-accent:#26a69a;--var-color-control-accent-hover:#4db6ac;--var-color-control-accent-active:#009688}}:root{color-scheme:light dark}html{display:flex;min-height:100%;font-family:Arial,Helvetica,sans-serif}body{display:flex;flex:1;flex-direction:column;min-height:100vh;margin:0px;background-attachment:fixed;background:#ededed;background:var(--var-color-page-background, #ededed);background-image:url("../images/noise-light.png");background-image:var(--var-page-background-image, url("../images/noise-light.png"));color:#676767;color:var(--var-color-text, #676767)}main{display:block;flex-grow:1;padding-bottom:32px}h1,h2,h3{color:#535353;color:var(--var-color-title, #535353)}
14 | .badge{width:32px;height:32px;margin:8px 12px;border:none}.badge>svg{width:32px;height:32px}.badge,.badge:hover,.badge:focus,.badge:active{border:none}.badge svg{fill:#5e5e5e;fill:var(--var-color-block-actionitem, #5e5e5e)}.badge svg:focus,.badge svg:hover{fill:#7e7e7e;fill:var(--var-color-block-actionitem-hover, #7e7e7e)}.badge svg:active{fill:#535353;fill:var(--var-color-block-actionitem-active, #535353)}.badge-shelf{display:flex;flex-flow:row;justify-content:center}footer{align-items:center;padding:8px;text-align:center;border-top:1px solid #c9c9c9;border-top:var(--var-color-block-border, 1px solid #c9c9c9);background:#eeeeee;background:var(--var-color-block-background, #eeeeee)}
15 |
--------------------------------------------------------------------------------
/docs/favicons/apple-touch-icon-120x120-precomposed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piellardj/fur-threejs/d7230990d10c333c044f617b99c2b845a6f15a9a/docs/favicons/apple-touch-icon-120x120-precomposed.png
--------------------------------------------------------------------------------
/docs/favicons/apple-touch-icon-152x152-precomposed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piellardj/fur-threejs/d7230990d10c333c044f617b99c2b845a6f15a9a/docs/favicons/apple-touch-icon-152x152-precomposed.png
--------------------------------------------------------------------------------
/docs/favicons/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piellardj/fur-threejs/d7230990d10c333c044f617b99c2b845a6f15a9a/docs/favicons/favicon-16x16.png
--------------------------------------------------------------------------------
/docs/favicons/favicon-180x180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piellardj/fur-threejs/d7230990d10c333c044f617b99c2b845a6f15a9a/docs/favicons/favicon-180x180.png
--------------------------------------------------------------------------------
/docs/favicons/favicon-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piellardj/fur-threejs/d7230990d10c333c044f617b99c2b845a6f15a9a/docs/favicons/favicon-192x192.png
--------------------------------------------------------------------------------
/docs/favicons/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piellardj/fur-threejs/d7230990d10c333c044f617b99c2b845a6f15a9a/docs/favicons/favicon-32x32.png
--------------------------------------------------------------------------------
/docs/favicons/favicon-48x48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piellardj/fur-threejs/d7230990d10c333c044f617b99c2b845a6f15a9a/docs/favicons/favicon-48x48.png
--------------------------------------------------------------------------------
/docs/favicons/favicon-60x60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piellardj/fur-threejs/d7230990d10c333c044f617b99c2b845a6f15a9a/docs/favicons/favicon-60x60.png
--------------------------------------------------------------------------------
/docs/favicons/favicon-96x96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piellardj/fur-threejs/d7230990d10c333c044f617b99c2b845a6f15a9a/docs/favicons/favicon-96x96.png
--------------------------------------------------------------------------------
/docs/images/gear.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/docs/images/noise-dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piellardj/fur-threejs/d7230990d10c333c044f617b99c2b845a6f15a9a/docs/images/noise-dark.png
--------------------------------------------------------------------------------
/docs/images/noise-light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piellardj/fur-threejs/d7230990d10c333c044f617b99c2b845a6f15a9a/docs/images/noise-light.png
--------------------------------------------------------------------------------
/docs/images/resize.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Fur
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
32 |
33 |
34 |
Fur
35 |
36 |
37 |
This project is my take on real-time fur rendering. The result is flexible and can adapt to any 3D model. A few properties are customizable, such as length, thickness, orientation and color patterns.
38 |
Technically, I implemented the traditional shells and fins technique, adapted for WebGL.
39 |
40 |
41 |
42 |
45 |
46 |
47 |
48 |
49 | You need to enable Javascript to run this experiment.
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
62 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 | Scene
81 |
82 |
83 |
92 |
93 |
Rotate:
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 | Fur
104 |
105 |
106 |
115 |
116 |
Color:
117 |
118 |
119 |
120 |
121 |
#FFFFFF
122 |
123 |
124 |
125 |
126 |
Length:
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
Density:
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
Smoothness:
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
Comb:
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
Quality:
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 | Shells & Fins
250 |
251 |
252 |
253 |
Render mode:
254 |
255 |
Full
256 |
257 |
Full
258 |
Shells only
259 |
Fins only
260 |
Nothing
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
293 |
300 |
301 |
302 |
303 |
304 |
--------------------------------------------------------------------------------
/docs/readme/css/page.css:
--------------------------------------------------------------------------------
1 | a{color:#009688;color:var(--var-color-control-accent, #009688);font-weight:bold;text-decoration:none;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;border-width:0 0 2px;border-style:solid;border-color:rgba(0,0,0,0)}a:focus,a:hover{border-color:#009688;border-color:var(--var-color-control-accent, #009688)}:root{--color-code: #e0e0e0}@media(prefers-color-scheme: dark){:root{--color-code: #343434}}body{max-width:100%}.contents{line-height:1.5em;max-width:900px;margin:auto;padding:16px 32px;border-radius:8px;border:1px solid #c9c9c9;border:var(--var-color-block-border, 1px solid #c9c9c9);background:#eeeeee;background:var(--var-color-block-background, #eeeeee)}h1{text-align:center;margin-bottom:1em}pre{overflow-x:auto;background:var(--color-code);padding:4px 16px;border-radius:8px;line-height:1.45}pre::-webkit-scrollbar{width:16px}pre::-webkit-scrollbar-track{background-color:rgba(0,0,0,0)}pre::-webkit-scrollbar-thumb{border-width:6px;border-style:solid;border-radius:8px;border-color:var(--color-code);background-color:#a5a5a5;background-color:var(--var-color-scrollbar, #a5a5a5)}pre::-webkit-scrollbar-thumb:focus,pre::-webkit-scrollbar-thumb:hover{background-color:#b2b2b2;background-color:var(--var-color-scrollbar-hover, #b2b2b2)}pre::-webkit-scrollbar-thumb:active{background-color:#959595;background-color:var(--var-color-scrollbar-active, #959595)}pre:hover::-webkit-scrollbar-thumb{border-width:5px}pre code{padding:0}code{background:var(--color-code);padding:2px 4px;border-radius:3px;font-family:ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,Liberation Mono,monospace;line-height:1.5em}video,img{max-width:100%;border-radius:8px}
2 | .logo{display:block;position:relative;width:64px;height:64px;margin:8px auto 16px;border-radius:50%;user-select:none;box-sizing:border-box}.logo,.logo:hover,.logo:focus,.logo:active{border-width:1px;border-style:solid;border-color:#009688;border-color:var(--var-color-control-accent, #009688)}.logo::before,.logo svg.logo-icon,.logo::after{position:absolute;top:-1px;left:-1px;width:64px;height:64px;border-radius:50%;pointer-events:none}.logo svg.logo-icon{stroke:#009688;stroke:var(--var-color-control-accent, #009688);fill:#009688;fill:var(--var-color-control-accent, #009688)}.logo::before{content:"";transform:scale(0);-webkit-transform:scale(0);-ms-transform:scale(0);transition:.1s ease;-webkit-transition:.1s ease}.logo.logo-animate-fill .logo::before{content:"";transform:scale(0);-webkit-transform:scale(0);-ms-transform:scale(0);transition:.1s ease;-webkit-transition:.1s ease}.logo:hover::before{transform:scale(1);-webkit-transform:scale(1);-ms-transform:scale(1)}.logo.logo-animate-fill{background:#eeeeee;background:var(--var-color-block-background, #eeeeee)}.logo.logo-animate-fill::before{background:#009688;background:var(--var-color-control-accent, #009688)}.logo.logo-animate-fill:hover svg.logo-icon{fill:#fff;stroke:#fff}.logo.logo-animate-empty{background:#009688;background:var(--var-color-control-accent, #009688)}.logo.logo-animate-empty::before{top:0;left:0;width:62px;height:62px;background:#eeeeee;background:var(--var-color-block-background, #eeeeee)}
3 | :root{--var-color-theme:white;--var-color-page-background:#ededed;--var-page-background-image:url("../images/noise-light.png");--var-color-block-background:#eeeeee;--var-color-block-border:1px solid #c9c9c9;--var-color-title:#535353;--var-color-text:#676767;--var-color-block-actionitem:#5e5e5e;--var-color-block-actionitem-hover:#7e7e7e;--var-color-block-actionitem-active:#535353;--var-color-scrollbar:#a5a5a5;--var-color-scrollbar-hover:#b2b2b2;--var-color-scrollbar-active:#959595;--var-color-control-neutral:#c9c9c9;--var-color-control-accent:#009688;--var-color-control-accent-hover:#26a69a;--var-color-control-accent-active:#00897b}@media(prefers-color-scheme: dark){:root{--var-color-theme:black;--var-color-page-background:#232323;--var-page-background-image:url("../images/noise-dark.png");--var-color-block-background:#202020;--var-color-block-border:1px solid #535353;--var-color-title:#eeeeee;--var-color-text:#dbdbdb;--var-color-block-actionitem:#dbdbdb;--var-color-block-actionitem-hover:#eeeeee;--var-color-block-actionitem-active:#c9c9c9;--var-color-scrollbar:#7e7e7e;--var-color-scrollbar-hover:#959595;--var-color-scrollbar-active:#676767;--var-color-control-neutral:#5e5e5e;--var-color-control-accent:#26a69a;--var-color-control-accent-hover:#4db6ac;--var-color-control-accent-active:#009688}}:root{color-scheme:light dark}html{display:flex;min-height:100%;font-family:Arial,Helvetica,sans-serif}body{display:flex;flex:1;flex-direction:column;min-height:100vh;margin:0px;background-attachment:fixed;background:#ededed;background:var(--var-color-page-background, #ededed);background-image:url("../images/noise-light.png");background-image:var(--var-page-background-image, url("../images/noise-light.png"));color:#676767;color:var(--var-color-text, #676767)}main{display:block;flex-grow:1;padding-bottom:32px}h1,h2,h3{color:#535353;color:var(--var-color-title, #535353)}
4 | .badge{width:32px;height:32px;margin:8px 12px;border:none}.badge>svg{width:32px;height:32px}.badge,.badge:hover,.badge:focus,.badge:active{border:none}.badge svg{fill:#5e5e5e;fill:var(--var-color-block-actionitem, #5e5e5e)}.badge svg:focus,.badge svg:hover{fill:#7e7e7e;fill:var(--var-color-block-actionitem-hover, #7e7e7e)}.badge svg:active{fill:#535353;fill:var(--var-color-block-actionitem-active, #535353)}.badge-shelf{display:flex;flex-flow:row;justify-content:center}footer{align-items:center;padding:8px;text-align:center;border-top:1px solid #c9c9c9;border-top:var(--var-color-block-border, 1px solid #c9c9c9);background:#eeeeee;background:var(--var-color-block-background, #eeeeee)}
5 |
--------------------------------------------------------------------------------
/docs/readme/favicons/apple-touch-icon-120x120-precomposed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piellardj/fur-threejs/d7230990d10c333c044f617b99c2b845a6f15a9a/docs/readme/favicons/apple-touch-icon-120x120-precomposed.png
--------------------------------------------------------------------------------
/docs/readme/favicons/apple-touch-icon-152x152-precomposed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piellardj/fur-threejs/d7230990d10c333c044f617b99c2b845a6f15a9a/docs/readme/favicons/apple-touch-icon-152x152-precomposed.png
--------------------------------------------------------------------------------
/docs/readme/favicons/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piellardj/fur-threejs/d7230990d10c333c044f617b99c2b845a6f15a9a/docs/readme/favicons/favicon-16x16.png
--------------------------------------------------------------------------------
/docs/readme/favicons/favicon-180x180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piellardj/fur-threejs/d7230990d10c333c044f617b99c2b845a6f15a9a/docs/readme/favicons/favicon-180x180.png
--------------------------------------------------------------------------------
/docs/readme/favicons/favicon-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piellardj/fur-threejs/d7230990d10c333c044f617b99c2b845a6f15a9a/docs/readme/favicons/favicon-192x192.png
--------------------------------------------------------------------------------
/docs/readme/favicons/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piellardj/fur-threejs/d7230990d10c333c044f617b99c2b845a6f15a9a/docs/readme/favicons/favicon-32x32.png
--------------------------------------------------------------------------------
/docs/readme/favicons/favicon-48x48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piellardj/fur-threejs/d7230990d10c333c044f617b99c2b845a6f15a9a/docs/readme/favicons/favicon-48x48.png
--------------------------------------------------------------------------------
/docs/readme/favicons/favicon-60x60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piellardj/fur-threejs/d7230990d10c333c044f617b99c2b845a6f15a9a/docs/readme/favicons/favicon-60x60.png
--------------------------------------------------------------------------------
/docs/readme/favicons/favicon-96x96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piellardj/fur-threejs/d7230990d10c333c044f617b99c2b845a6f15a9a/docs/readme/favicons/favicon-96x96.png
--------------------------------------------------------------------------------
/docs/readme/images/noise-dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piellardj/fur-threejs/d7230990d10c333c044f617b99c2b845a6f15a9a/docs/readme/images/noise-dark.png
--------------------------------------------------------------------------------
/docs/readme/images/noise-light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piellardj/fur-threejs/d7230990d10c333c044f617b99c2b845a6f15a9a/docs/readme/images/noise-light.png
--------------------------------------------------------------------------------
/docs/readme/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Fur - Explanations
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
32 |
33 |
34 |
fur-threejs
35 |
Description
36 |
This project is my take on real-time fur rendering. The result is quite good and flexible since it can adapt to any 3D model. A few properties are customizable, such as length, thickness, orientation and color patterns.
37 |
Technically, I implemented the traditional shells and fins technique, adapted for WebGL (which lacks Geometry Shaders unfortunately).
38 |
See it live here .
39 |
40 |
Preview
41 |
42 |
43 |
44 |
45 |
46 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/docs/readme/robots.txt:
--------------------------------------------------------------------------------
1 | User-Agent: GPTBot
2 | Disallow: /
--------------------------------------------------------------------------------
/docs/resources/models/cat.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piellardj/fur-threejs/d7230990d10c333c044f617b99c2b845a6f15a9a/docs/resources/models/cat.glb
--------------------------------------------------------------------------------
/docs/resources/models/chair.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piellardj/fur-threejs/d7230990d10c333c044f617b99c2b845a6f15a9a/docs/resources/models/chair.glb
--------------------------------------------------------------------------------
/docs/resources/models/chair_feet.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piellardj/fur-threejs/d7230990d10c333c044f617b99c2b845a6f15a9a/docs/resources/models/chair_feet.glb
--------------------------------------------------------------------------------
/docs/resources/models/dice.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piellardj/fur-threejs/d7230990d10c333c044f617b99c2b845a6f15a9a/docs/resources/models/dice.glb
--------------------------------------------------------------------------------
/docs/resources/models/sphere.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piellardj/fur-threejs/d7230990d10c333c044f617b99c2b845a6f15a9a/docs/resources/models/sphere.glb
--------------------------------------------------------------------------------
/docs/resources/models/torus.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piellardj/fur-threejs/d7230990d10c333c044f617b99c2b845a6f15a9a/docs/resources/models/torus.glb
--------------------------------------------------------------------------------
/docs/resources/textures/chair.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piellardj/fur-threejs/d7230990d10c333c044f617b99c2b845a6f15a9a/docs/resources/textures/chair.png
--------------------------------------------------------------------------------
/docs/resources/textures/dark.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piellardj/fur-threejs/d7230990d10c333c044f617b99c2b845a6f15a9a/docs/resources/textures/dark.jpg
--------------------------------------------------------------------------------
/docs/resources/textures/dice.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piellardj/fur-threejs/d7230990d10c333c044f617b99c2b845a6f15a9a/docs/resources/textures/dice.png
--------------------------------------------------------------------------------
/docs/resources/textures/giraffe.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piellardj/fur-threejs/d7230990d10c333c044f617b99c2b845a6f15a9a/docs/resources/textures/giraffe.png
--------------------------------------------------------------------------------
/docs/resources/textures/noise.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piellardj/fur-threejs/d7230990d10c333c044f617b99c2b845a6f15a9a/docs/resources/textures/noise.png
--------------------------------------------------------------------------------
/docs/resources/textures/torus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piellardj/fur-threejs/d7230990d10c333c044f617b99c2b845a6f15a9a/docs/resources/textures/torus.png
--------------------------------------------------------------------------------
/docs/resources/textures/white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/piellardj/fur-threejs/d7230990d10c333c044f617b99c2b845a6f15a9a/docs/resources/textures/white.png
--------------------------------------------------------------------------------
/docs/robots.txt:
--------------------------------------------------------------------------------
1 | User-Agent: GPTBot
2 | Disallow: /
--------------------------------------------------------------------------------
/docs/script/main.min.js.LICENSE.txt:
--------------------------------------------------------------------------------
1 | /**
2 | * @license
3 | * Copyright 2010-2024 Three.js Authors
4 | * SPDX-License-Identifier: MIT
5 | */
6 |
--------------------------------------------------------------------------------
/docs/script/page.min.js:
--------------------------------------------------------------------------------
1 | var Page;!function(e){var e=e.Demopage||(e.Demopage={}),r="error-messages",t=document.getElementById(r);if(!t)throw new Error("Cannot find element '"+r+"'.");function a(e){return t?t.querySelector("span[id=error-message-"+e+"]"):null}e.setErrorMessage=function(e,r){var n;t&&((n=a(e))?n.innerHTML=r:((n=document.createElement("span")).id="error-message-"+e,n.innerText=r,t.appendChild(n),t.appendChild(document.createElement("br"))))},e.removeErrorMessage=function(e){var r;t&&(e=a(e))&&((r=e.nextElementSibling)&&t.removeChild(r),t.removeChild(e))}}(Page=Page||{});
2 | var Page;!function(n){var e,t,i,a;function s(e){this.queryParameters={};var t=e.indexOf(s.queryDelimiter);if(t<0)this.baseUrl=e;else{this.baseUrl=e.substring(0,t);for(var r=0,n=e.substring(t+s.queryDelimiter.length).split(s.parameterDelimiter);re.length&&(i=this.queryParameters[a],t(a.substring(e.length),i))}},s.prototype.buildUrl=function(){for(var e=[],t=0,r=Object.keys(this.queryParameters);t input[type=checkbox][id]").map(function(e){return new r(e)})}),n=new e.Helpers.Storage("checkbox",function(e){return e.checked?"true":"false"},function(e,t){e=c.getByIdSafe(e);return!(!e||"true"!==t&&"false"!==t||(e.checked="true"===t,e.callObservers(),0))}),e.Helpers.Events.callAfterDOMLoaded(function(){c.load(),n.applyStoredState()}),t.addObserver=function(e,t){c.getById(e).observers.push(t)},t.setChecked=function(e,t){c.getById(e).checked=t},t.isChecked=function(e){return c.getById(e).checked},t.storeState=function(e){e=c.getById(e),n.storeState(e)},t.clearStoredState=function(e){e=c.getById(e),n.clearStoredState(e)}}(Page=Page||{});
6 | var Page;!function(d){var a,e,t=d.ColorPicker||(d.ColorPicker={});function u(e,t,n){return Math.max(t,Math.min(n,e))}function l(e,t,n){return u(Math.round(e),t,n)}function s(e,t){return(e%t+t)%t}function n(e){e=e.toString(16).toUpperCase();return 2===e.length?e:"0"+e}(e=a=a||{}).parseHexa=function(e){return/^#[0-9a-fA-F]{6}$/.test(e)?e.toUpperCase():null},e.hsvToRgb=function(e){var t=e.h/60,n=e.s*e.v,r=n*(1-Math.abs(s(t,2)-1)),t=t<=1?{r:n,g:r,b:0}:t<=2?{r:r,g:n,b:0}:t<=3?{r:0,g:n,b:r}:t<=4?{r:0,g:r,b:n}:t<=5?{r:r,g:0,b:n}:{r:n,g:0,b:r},r=e.v-n;return t.r=l(255*(t.r+r),0,255),t.g=l(255*(t.g+r),0,255),t.b=l(255*(t.b+r),0,255),t},e.rgbToHsv=function(e){var t=e.r/255,n=e.g/255,e=e.b/255,r=Math.max(t,n,e),i=r-Math.min(t,n,e),o={h:0,s:0,v:r};return 0!=i&&(r===t?o.h=(n-e)/i%6*60:r===n?o.h=60*((e-t)/i+2):r===e&&(o.h=60*((t-n)/i+4))),0!==r&&(o.s=i/r),o.h=s(o.h,360),o},e.rgbToHex=function(e){return"#"+n(e.r)+n(e.g)+n(e.b)},e.hexToRgb=function(e){return{r:parseInt(e.substring(1,3),16),g:parseInt(e.substring(3,5),16),b:parseInt(e.substring(5,7),16)}},Object.defineProperty(i.prototype,"value",{get:function(){var e=this.element.dataset.currentColor;if(e)return e;throw new Error("No current color on ColorPicker '".concat(this.id,"'."))},set:function(e){if(this.value!==e){this.element.dataset.currentColor=e,this.updateVisiblePart();for(var t=a.hexToRgb(e),n=0,r=this.observers;n input[type='range']").map(function(e){e=e.parentElement;return new t(e)})}),s=new r.Helpers.Storage("range",function(e){return""+e.value},function(e,t){e=n.getByIdSafe(e);return!!e&&(e.value=+t,e.callObservers(),!0)}),r.Helpers.Events.callAfterDOMLoaded(function(){n.load(),s.applyStoredState()}),i=!!window.MSInputMethodContext&&!!document.documentMode,e.addObserver=function(e,t){e=n.getById(e),(i?e.onChangeObservers:e.onInputObservers).push(t)},e.addLazyObserver=function(e,t){n.getById(e).onChangeObservers.push(t)},e.getValue=function(e){return n.getById(e).value},e.setValue=function(e,t){n.getById(e).value=t},e.storeState=function(e){e=n.getById(e),s.storeState(e)},e.clearStoredState=function(e){e=n.getById(e),s.clearStoredState(e)}}(Page=Page||{});
8 | var Page;!function(n){var e,t,l,i;function r(e){for(var a=this,t=(this.observers=[],this.id=e.id,this.containerElement=e,this.currentValueElement=n.Helpers.Utils.selector(e,".select-current-value"),this.valuesListElement=n.Helpers.Utils.selector(e,".select-values-list"),this.placeholder=this.valuesListElement.dataset.placeholder||"",this.currentValue=this.currentValueElement.dataset.value||null,this.valueElements=[],this.valuesListElement.querySelectorAll(".select-value[data-value]")),l=0;l