123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441 |
- <!DOCTYPE html>
- <html lang="fr">
- <head>
- <meta charset="utf-8" />
- <base href="../../../" />
- <script src="page.js"></script>
- <link type="text/css" rel="stylesheet" href="page.css" />
- </head>
- <body>
- [page:Material] →
- <h1>[name]</h1>
- <p class="desc">
- Un matériau rendu avec des shaders personnalisés. Un shader est un petit programme écrit en
- [link:https://www.khronos.org/files/opengles_shading_language.pdf GLSL] qui s'exécute sur le GPU.
- Vous pouvez utiliser un shader personnalisé si vous avez besoin de :
- <ul>
- <li>implémenter un effet qui n'est inclus dans aucun des [page:Material materials] intégrés</li>
- <li>combiner de nombreux objets en une seule [page:BufferGeometry] afin d'améliorer les performances</li>
- </ul>
- Il y a les notes suivantes à garder à l'esprit lors de l'utilisation d'un `ShaderMaterial` :
- <ul>
- <li>
- Un `ShaderMaterial` ne sera rendu correctement que par [page: WebGLRenderer],
- depuis le code GLSL dans le [link:https://en.wikipedia.org/wiki/Shader#Vertex_shaders vertexShader]
- et les propriétés [link:https://en.wikipedia.org/wiki/Shader#Pixel_shaders fragmentShader] doivent
- être compilées et exécutées sur le GPU à l'aide de WebGL.
- </li>
- <li>
- Depuis THREE r72, l'attribution directe d'attributs dans un ShaderMaterial n'est plus prise en charge.
- Une instance [page:BufferGeometry] doit être utilisée à la place, en utilisant des instances [page:BufferAttribute] pour définir des attributs personnalisés.
- </li>
- <li>
- Depuis THREE r77, les instances [page:WebGLRenderTarget] ou [page:WebGLCubeRenderTarget]
- ne sont plus censés être utilisés comme uniformes. Leur propriété [page:Texture texture]
- doit être utilisé à la place.
- </li>
- <li>
- Les attributs et les uniformes intégrés sont transmis aux shaders avec votre code.
- Si vous ne voulez pas que [page:WebGLProgram] ajoute quoi que ce soit à votre code de shader, vous pouvez utiliser
- [page:RawShaderMaterial] au lieu de cette classe.
- </li>
- <li>
- Vous pouvez utiliser la directive #pragma unroll_loop_start et #pragma unroll_loop_end afin de dérouler une boucle `for` en GLSL par le préprocesseur de shader.
- La directive doit être placée juste au-dessus de la boucle. Le formatage de la boucle doit correspondre à une norme définie.
- <ul>
- <li>
- La boucle doit être normalisée ([link:https://en.wikipedia.org/wiki/Normalized_loop normalized]).
- </li>
- <li>
- La variable d'itération de la boucle doit être *i*.
- </li>
- <li>
- La valeur `UNROLLED_LOOP_INDEX` sera remplacée par la valeur explicite de *i* pour l'itération donnée et peut être utilisée dans les instructions du préprocesseur.
- </li>
- </ul>
- <code>
- #pragma unroll_loop_start
- for ( int i = 0; i < 10; i ++ ) {
- // ...
- }
- #pragma unroll_loop_end
- </code>
- </li>
- </ul>
- </p>
- <h2>Code Example</h2>
- <code>
- const material = new THREE.ShaderMaterial( {
- uniforms: {
- time: { value: 1.0 },
- resolution: { value: new THREE.Vector2() }
- },
- vertexShader: document.getElementById( 'vertexShader' ).textContent,
- fragmentShader: document.getElementById( 'fragmentShader' ).textContent
- } );
- </code>
- <h2>Exemples</h2>
- <p>
- [example:webgl_buffergeometry_custom_attributes_particles webgl / buffergeometry / custom / attributes / particles]<br />
- [example:webgl_buffergeometry_selective_draw webgl / buffergeometry / selective / draw]<br />
- [example:webgl_custom_attributes webgl / custom / attributes]<br />
- [example:webgl_custom_attributes_lines webgl / custom / attributes / lines]<br />
- [example:webgl_custom_attributes_points webgl / custom / attributes / points]<br />
- [example:webgl_custom_attributes_points2 webgl / custom / attributes / points2]<br />
- [example:webgl_custom_attributes_points3 webgl / custom / attributes / points3]<br />
- [example:webgl_depth_texture webgl / depth / texture]<br />
- [example:webgl_gpgpu_birds webgl / gpgpu / birds]<br />
- [example:webgl_gpgpu_protoplanet webgl / gpgpu / protoplanet]<br />
- [example:webgl_gpgpu_water webgl / gpgpu / water]<br />
- [example:webgl_interactive_points webgl / interactive / points]<br />
- [example:webgl_video_kinect webgl / video / kinect]<br />
- [example:webgl_lights_hemisphere webgl / lights / hemisphere]<br />
- [example:webgl_marchingcubes webgl / marchingcubes]<br />
- [example:webgl_materials_envmaps webgl / materials / envmaps]<br />
- [example:webgl_materials_lightmap webgl / materials / lightmap]<br />
- [example:webgl_materials_wireframe webgl / materials / wireframe]<br />
- [example:webgl_modifier_tessellation webgl / modifier / tessellation]<br />
- [example:webgl_postprocessing_dof2 webgl / postprocessing / dof2]<br />
- [example:webgl_postprocessing_godrays webgl / postprocessing / godrays]
- </p>
- <h2>Shaders de vertex et shaders de fragments</h2>
- <div>
- <p>Vous pouvez spécifier deux types de shaders différents pour chaque matériau :</p>
- <ul>
- <li>
- Le vertex shader s'exécute en premier ; il reçoit des `attributs`, calcule / manipule
- la position de chaque sommet individuel, et transmet des données supplémentaires ("variantes") au fragment shader.
- </li>
- <li>
- Le shader fragment ( ou pixel ) s'exécute en second ; il définit la couleur de chaque "fragment" individuel
- (pixel) rendu à l'écran.
- </li>
- </ul>
- <p>Il existe trois types de variables dans les shaders : les `uniforms`, les `attributes` et les `varyings` :</p>
- <ul>
- <li>
- Les `Uniforms` sont des variables qui ont la même valeur pour tous les sommets - éclairage, brouillard,
- et les cartes d'ombre sont des exemples de données qui seraient stockées dans des uniformes.
- Les uniformes sont accessibles à la fois par le vertex shader et le fragment shader.
- </li>
- <li>
- `Attributes` sont des variables associées à chaque sommet --- par exemple, la position du sommet,
- face normale et vertex color sont tous des exemples de données qui seraient stockées dans des attributs.
- Les attributs ne sont accessibles "que" dans le vertex shader.
- </li>
- <li>
- `Varyings` sont des variables qui sont passées du vertex shader au fragment shader.
- Pour chaque fragment, la valeur de chaque variable sera interpolée en douceur à partir des valeurs des sommets adjacents.
- </li>
- </ul>
- <p>
- Notez que "dans" le shader lui-même, les uniformes et les attributs agissent comme des constantes ;
- vous ne pouvez modifier leurs valeurs qu'en transmettant des valeurs différentes aux tampons à partir de votre code JavaScript.
- </p>
- </div>
- <h2>Attributs et uniformes intégrés</h2>
- <div>
- <p>
- La [page:WebGLRenderer] fournit de nombreux attributs et uniformes aux shaders par défaut ;
- les définitions de ces variables sont ajoutées à vos `fragmentShader` et `vertexShader`
- codés par le [page:WebGLProgram] lorsque le shader est compilé ; vous n'avez pas besoin de les déclarer vous-même.
- Voir [page:WebGLProgram] pour plus de détails sur ces variables.
- </p>
- <p>
- Certains de ces uniformes ou attributs (par exemple, ceux concernant l'éclairage, le brouillard, etc.)
- exigent que les propriétés soient définies sur le matériau pour que [page: WebGLRenderer] copie
- les valeurs appropriées au GPU - assurez-vous de définir ces flags si vous souhaitez les utiliser
- fonctionnalités dans votre propre shader.
- </p>
- <p>
- Si vous ne voulez pas que [page:WebGLProgram] ajoute quoi que ce soit à votre code de shader, vous pouvez utiliser
- [page:RawShaderMaterial] au lieu de cette classe.
- </p>
- </div>
- <h2>Attributs et uniformes personnalisés</h2>
- <div>
- <p>
- Les attributs personnalisés et les uniformes doivent être déclarés dans votre code de shader GLSL
- (dans `vertexShader` et/ou `fragmentShader`). Les uniformes personnalisés doivent être définis dans "les deux"
- propriétés `uniforms` de votre `ShaderMaterial`, alors que tous les attributs personnalisés doivent être
- définis via les instances [page:BufferAttribute]. Notez que "varying" doit uniquement être déclaré dans le code du shader (et non dans le matériau).
- </p>
- <p>
- Pour déclarer un attribut personnalisé, veuillez vous référer à la page [page:BufferGeometry] pour un aperçu,
- et la page [page:BufferAttribute] pour un aperçu détaillé de l'API `BufferAttribute`.
- </p>
- <p>
- Lors de la création de vos attributs, chaque tableau typé que vous créez pour contenir vos
- données doit être un multiple de la taille de votre type de données. Par exemple, si votre attribut
- est de type [page:Vector3 THREE.Vector3], et vous avez 3000 sommets dans votre
- [page:BufferGeometry], votre valeur de tableau typée doit être créée avec une longueur de 3000 * 3,
- ou 9000 (une valeur par composant). Un tableau de la taille de chaque type de données est présenté ci-dessous à titre de référence :
- </p>
- <table>
- <caption><a id="attribute-sizes">Taille des attributs</a></caption>
- <thead>
- <tr>
- <th>type GLSL</th>
- <th>type JavaScript</th>
- <th>taille</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>float</td>
- <td>[page:Number]</td>
- <td>1</td>
- </tr>
- <tr>
- <td>vec2</td>
- <td>[page:Vector2 THREE.Vector2]</td>
- <td>2</td>
- </tr>
- <tr>
- <td>vec3</td>
- <td>[page:Vector3 THREE.Vector3]</td>
- <td>3</td>
- </tr>
- <tr>
- <td>vec3</td>
- <td>[page:Color THREE.Color]</td>
- <td>3</td>
- </tr>
- <tr>
- <td>vec4</td>
- <td>[page:Vector4 THREE.Vector4]</td>
- <td>4</td>
- </tr>
- </tbody>
- </table>
- <p>
- Notez que les tampons d'attributs ne sont `pas` actualisés automatiquement lorsque leurs valeurs changent. Pour mettre à jour les attributs personnalisés,
- définissez le paramètre `needsUpdate` sur true sur le [page:BufferAttribute] de la géométrie (voir [page:BufferGeometry]
- pour plus de détails).
- </p>
- <p>
- Pour déclarer un [page:Uniform] personnalisé, utilisez la propriété `uniforms` :
- <code>
- uniforms: {
- time: { value: 1.0 },
- resolution: { value: new THREE.Vector2() }
- }
- </code>
- </p>
- <p>
- Il est recommandé de mettre à jour les valeurs [page:Uniform] personnalisées en fonction de [page:Object3D object] et [page:Camera camera]
- dans [page:Object3D.onBeforeRender] car [page:Material] peut être partagé entre [page:Mesh meshes], [page:Matrix4 matrixWorld]
- de [page:Scene] et [page:Camera] sont mis à jour dans [page:WebGLRenderer.render], et certains effets rendent une [page:Scene scene]
- avec leur propre [page : cameras] privées.
- </p>
- </div>
- <h2>Constructeur</h2>
- <h3>[name]( [param:Object parameters] )</h3>
- <p>
- [page:Object parameters] - (optionnel) un objet avec une ou plusieurs propriétés définissant l'apparence du matériau.
- Toute propriété du matériau (y compris toute proprioété héritée de [page:Material]) peut être passée dans l'objet.
- </p>
- <h2>Propriétés</h2>
- <p>Voir la classe [page:Material] pour les propriétés communes.</p>
- <h3>[property:Boolean clipping]</h3>
- <p>
- Définit si ce matériau prend en charge l'écrêtage ; true pour laisser le moteur de rendu transmettre l'uniforme clippingPlanes. La valeur par défaut est false.
- </p>
- <h3>[property:Object defaultAttributeValues]</h3>
- <p>
- Lorsque la géométrie rendue n'inclut pas ces attributs mais que le matériau le fait,
- ces valeurs par défaut seront transmises aux shaders. Cela évite les erreurs lorsque des données de tampon sont manquantes.
- <code>
- this.defaultAttributeValues = {
- 'color': [ 1, 1, 1 ],
- 'uv': [ 0, 0 ],
- 'uv1': [ 0, 0 ]
- };
- </code>
- </p>
- <h3>[property:Object defines]</h3>
- <p>
- Définit des constantes personnalisées à l'aide des directives `#define` dans le code GLSL pour les deux
- shader de vertex et le shader de fragment ; chaque paire clé/valeur produit une autre directive :
- <code>
- defines: {
- FOO: 15,
- BAR: true
- }
- </code>
- yields the lines
- <code>
- #define FOO 15
- #define BAR true
- </code>
- in the GLSL code.
- </p>
- <h3>[property:Object extensions]</h3>
- <p>
- Un objet avec les propriétés suivantes :
- <code>
- this.extensions = {
- derivatives: false, // set to use derivatives
- fragDepth: false, // set to use fragment depth values
- drawBuffers: false, // set to use draw buffers
- shaderTextureLOD: false // set to use shader texture LOD
- };
- </code>
- </p>
- <h3>[property:Boolean fog]</h3>
- <p>
- Définissez si la couleur du matériau est affectée par les paramètres de brouillard globaux ; vrai pour passer
- les uniformes de brouillard au shader. La valeur par défaut est false.
- </p>
- <h3>[property:String fragmentShader]</h3>
- <p>
- Code GLSL du shader de fragment. C'est le code réel du shader. Dans l'exemple ci-dessus,
- le code `vertexShader` et `fragmentShader` est extrait du DOM ; il peut être passé
- sous forme de chaîne de caractères ou chargé via AJAX à la place.
- </p>
- <h3>[property:String glslVersion]</h3>
- <p>
- Définit la version GLSL du code de shader personnalisé. Pertinent uniquement pour WebGL 2 afin de définir s'il faut spécifier
- GLSL 3.0 ou pas. Les valeurs valides sont `THREE.GLSL1` ou `THREE.GLSL3`. La valeur par défaut est `null`.
- </p>
- <h3>[property:String index0AttributeName]</h3>
- <p>
- Si définit, cela appelle [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bindAttribLocation gl.bindAttribLocation]
- pour lier un index de sommet générique à une variable d'attribut.
- La valeur par défaut est undefined.
- </p>
- <h3>[property:Boolean isShaderMaterial]</h3>
- <p>
- Attribut en lecture seule pour vérifier si l'object donné est de type [name].
- </p>
- <h3>[property:Boolean lights]</h3>
- <p>
- Définit si ce matériau utilise l'éclairage ; true pour transmettre des données uniformes liées à l'éclairage à ce shader. La valeur par défaut est false.
- </p>
- <h3>[property:Float linewidth]</h3>
- <p>Contrôle l'épaisseur du filaire. La valeur par défaut est 1.<br /><br />
- A cause des limitations de [link:https://www.khronos.org/registry/OpenGL/specs/gl/glspec46.core.pdf OpenGL Core Profile]
- avec le moteur de rendu [page:WebGLRenderer WebGL] sur la plupârt des plateformes, l'épaisseur de ligne (linewidth) sera toujours
- à 1, indépendamment de la valeur définie.
- </p>
- <h3>[property:Boolean flatShading]</h3>
- <p>
- Définit si le matériau est rendu avec un ombrage plat. La valeur par défaut est false.
- </p>
- <h3>[property:Object uniforms]</h3>
- <p>
- Un object de la forme:
- <code>
- { "uniform1": { value: 1.0 }, "uniform2": { value: 2 } }
- </code>
- spécifiant les uniformes à transmettre au code shader ; les clés sont des noms uniformes, les valeurs sont des définitions de la forme
- <code>
- { value: 1.0 }
- </code>
- Quand `value` est la valeur de l'uniforme. Les noms doivent correspondre au nom de l'uniforme,
- tel que défini dans le code GLSL. A noter que les uniformes sont rafraichis à chaque frame,
- donc la mise à jour de la valeur de l'uniforme mettra immédiatement à jour la valeur disponible pour le code GLSL.
- </p>
- <h3>[property:Boolean uniformsNeedUpdate]</h3>
- <p>
- Peut être utilisé pour forcer une mise à jour uniforme lors du changement d'uniformes dans [page:Object3D.onBeforeRender](). La valeur par défaut est `false`.
- </p>
- <h3>[property:Boolean vertexColors]</h3>
- <p>
- Définit si la coloration des sommets est utilisée. La valeur par défaut est `false`.
- </p>
- <h3>[property:String vertexShader]</h3>
- <p>
- Code GLSL du vertex shader. C'est le code réel du shader. Dans l'exemple ci-dessus,
- le code `vertexShader` et `fragmentShader` est extrait du DOM ; il peut être passé
- sous forme de chaîne de caractères ou chargé via AJAX à la place.
- </p>
- <h3>[property:Boolean wireframe]</h3>
- <p>
- Rendre la géométrie en fil de fer (en utilisant GL_LINES au lieu de GL_TRIANGLES). La valeur par défaut est false (c'est-à-dire rendre sous forme de polygones plats).
- </p>
- <h3>[property:Float wireframeLinewidth]</h3>
- <p>Contrôle l'épaisseur du filaire. La valeur par défaut est 1.<br /><br />
- A cause des limitations de [link:https://www.khronos.org/registry/OpenGL/specs/gl/glspec46.core.pdf OpenGL Core Profile]
- avec le moteur de rendu [page:WebGLRenderer WebGL] sur la plupârt des plateformes, l'épaisseur de ligne (linewidth) sera toujours
- à 1, indépendamment de la valeur définie.
- </p>
- <h2>Méthodes</h2>
- <p>Voir la classe [page:Material] pour les méthodes communes.</p>
- <h3>[method:ShaderMaterial clone]()</h3>
- <p>
- Génère une copie superficielle de ce matériau. Notez que le vertexShader et le fragmentShader
- sont copiés "par référence", de même que les définitions des "attributs" ; cela signifie
- que les clones du matériel partageront la même [page:WebGLProgram] compilée. Cependant, le
- `uniformes` sont copiés `par valeur`, ce qui vous permet d'avoir différents ensembles d'uniformes
- pour différentes copies du matériel.
- </p>
- <h2>Source</h2>
- <p>
- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
- </p>
- </body>
- </html>
|