123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476 |
- <!DOCTYPE html>
- <html lang="en">
- <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">
- A material rendered with custom shaders. A shader is a small program
- written in
- [link:https://www.khronos.org/files/opengles_shading_language.pdf GLSL]
- that runs on the GPU. You may want to use a custom shader if you need to:
- </p>
- <ul>
- <li>
- implement an effect not included with any of the built-in [page:Material materials]
- </li>
- <li>
- combine many objects into a single [page:BufferGeometry] in order to
- improve performance
- </li>
- </ul>
- There are the following notes to bear in mind when using a `ShaderMaterial`:
- <ul>
- <li>
- A `ShaderMaterial` will only be rendered properly by
- [page:WebGLRenderer], since the GLSL code in the
- [link:https://en.wikipedia.org/wiki/Shader#Vertex_shaders vertexShader]
- and [link:https://en.wikipedia.org/wiki/Shader#Pixel_shaders fragmentShader]
- properties must be compiled and run on the GPU using WebGL.
- </li>
- <li>
- As of THREE r72, directly assigning attributes in a ShaderMaterial is no
- longer supported. A [page:BufferGeometry] instance must be used instead,
- using [page:BufferAttribute] instances to define custom attributes.
- </li>
- <li>
- As of THREE r77, [page:WebGLRenderTarget] or
- [page:WebGLCubeRenderTarget] instances are no longer supposed to be used
- as uniforms. Their [page:Texture texture] property must be used instead.
- </li>
- <li>
- Built in attributes and uniforms are passed to the shaders along with
- your code. If you don't want the [page:WebGLProgram] to add anything to
- your shader code, you can use [page:RawShaderMaterial] instead of this
- class.
- </li>
- <li>
- You can use the directive #pragma unroll_loop_start and #pragma
- unroll_loop_end in order to unroll a `for` loop in GLSL by the shader
- preprocessor. The directive has to be placed right above the loop. The
- loop formatting has to correspond to a defined standard.
- <ul>
- <li>
- The loop has to be
- [link:https://en.wikipedia.org/wiki/Normalized_loop normalized].
- </li>
- <li>The loop variable has to be *i*.</li>
- <li>
- The value `UNROLLED_LOOP_INDEX` will be replaced with the explicitly
- value of *i* for the given iteration and can be used in preprocessor
- statements.
- </li>
- </ul>
- <code>
- #pragma unroll_loop_start
- for ( int i = 0; i < 10; i ++ ) {
- // ...
- }
- #pragma unroll_loop_end
- </code>
- </li>
- </ul>
- <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>Examples</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_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>Vertex shaders and fragment shaders</h2>
- <div>
- <p>You can specify two different types of shaders for each material:</p>
- <ul>
- <li>
- The vertex shader runs first; it receives `attributes`, calculates /
- manipulates the position of each individual vertex, and passes
- additional data (`varying`s) to the fragment shader.
- </li>
- <li>
- The fragment ( or pixel ) shader runs second; it sets the color of
- each individual "fragment" (pixel) rendered to the screen.
- </li>
- </ul>
- <p>
- There are three types of variables in shaders: uniforms, attributes, and
- varyings:
- </p>
- <ul>
- <li>
- `Uniforms` are variables that have the same value for all vertices -
- lighting, fog, and shadow maps are examples of data that would be
- stored in uniforms. Uniforms can be accessed by both the vertex shader
- and the fragment shader.
- </li>
- <li>
- `Attributes` are variables associated with each vertex---for instance,
- the vertex position, face normal, and vertex color are all examples of
- data that would be stored in attributes. Attributes can `only` be
- accessed within the vertex shader.
- </li>
- <li>
- `Varyings` are variables that are passed from the vertex shader to the
- fragment shader. For each fragment, the value of each varying will be
- smoothly interpolated from the values of adjacent vertices.
- </li>
- </ul>
- <p>
- Note that `within` the shader itself, uniforms and attributes act like
- constants; you can only modify their values by passing different values
- to the buffers from your JavaScript code.
- </p>
- </div>
- <h2>Built-in attributes and uniforms</h2>
- <div>
- <p>
- The [page:WebGLRenderer] provides many attributes and uniforms to
- shaders by default; definitions of these variables are prepended to your
- `fragmentShader` and `vertexShader` code by the [page:WebGLProgram] when
- the shader is compiled; you don't need to declare them yourself. See
- [page:WebGLProgram] for details of these variables.
- </p>
- <p>
- Some of these uniforms or attributes (e.g. those pertaining lighting,
- fog, etc.) require properties to be set on the material in order for
- [page:WebGLRenderer] to copy the appropriate values to the GPU - make
- sure to set these flags if you want to use these features in your own
- shader.
- </p>
- <p>
- If you don't want [page:WebGLProgram] to add anything to your shader
- code, you can use [page:RawShaderMaterial] instead of this class.
- </p>
- </div>
- <h2>Custom attributes and uniforms</h2>
- <div>
- <p>
- Both custom attributes and uniforms must be declared in your GLSL shader
- code (within `vertexShader` and/or `fragmentShader`). Custom uniforms
- must be defined in `both` the `uniforms` property of your
- `ShaderMaterial`, whereas any custom attributes must be defined via
- [page:BufferAttribute] instances. Note that `varying`s only need to be
- declared within the shader code (not within the material).
- </p>
- <p>
- To declare a custom attribute, please reference the
- [page:BufferGeometry] page for an overview, and the
- [page:BufferAttribute] page for a detailed look at the `BufferAttribute`
- API.
- </p>
- <p>
- When creating your attributes, each typed array that you create to hold
- your attribute's data must be a multiple of your data type's size. For
- example, if your attribute is a [page:Vector3 THREE.Vector3] type, and
- you have 3000 vertices in your [page:BufferGeometry], your typed array
- value must be created with a length of 3000 * 3, or 9000 (one value
- per-component). A table of each data type's size is shown below for
- reference:
- </p>
- <table>
- <caption>
- <a id="attribute-sizes">Attribute sizes</a>
- </caption>
- <thead>
- <tr>
- <th>GLSL type</th>
- <th>JavaScript type</th>
- <th>Size</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>
- Note that attribute buffers are `not` refreshed automatically when their
- values change. To update custom attributes, set the `needsUpdate` flag
- to true on the [page:BufferAttribute] of the geometry (see
- [page:BufferGeometry] for further details).
- </p>
- <p>
- To declare a custom [page:Uniform], use the `uniforms` property:
- <code>
- uniforms: {
- time: { value: 1.0 },
- resolution: { value: new THREE.Vector2() }
- }
- </code>
- </p>
- <p>
- You're recommended to update custom [page:Uniform] values depending on
- [page:Object3D object] and [page:Camera camera] in
- [page:Object3D.onBeforeRender] because [page:Material] can be shared
- among [page:Mesh meshes], [page:Matrix4 matrixWorld] of [page:Scene] and
- [page:Camera] are updated in [page:WebGLRenderer.render], and some
- effects render a [page:Scene scene] with their own private [page:Camera cameras].
- </p>
- </div>
- <h2>Constructor</h2>
- <h3>[name]( [param:Object parameters] )</h3>
- <p>
- [page:Object parameters] - (optional) an object with one or more
- properties defining the material's appearance. Any property of the
- material (including any property inherited from [page:Material]) can be
- passed in here.
- </p>
- <h2>Properties</h2>
- <p>See the base [page:Material] class for common properties.</p>
- <h3>[property:Boolean clipping]</h3>
- <p>
- Defines whether this material supports clipping; true to let the renderer
- pass the clippingPlanes uniform. Default is false.
- </p>
- <h3>[property:Object defaultAttributeValues]</h3>
- <p>
- When the rendered geometry doesn't include these attributes but the
- material does, these default values will be passed to the shaders. This
- avoids errors when buffer data is missing.
- <code>
- this.defaultAttributeValues = {
- 'color': [ 1, 1, 1 ],
- 'uv': [ 0, 0 ],
- 'uv1': [ 0, 0 ]
- };
- </code>
- </p>
- <h3>[property:Object defines]</h3>
- <p>
- Defines custom constants using `#define` directives within the GLSL code
- for both the vertex shader and the fragment shader; each key/value pair
- yields another 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>
- An object with the following properties:
- <code>
- this.extensions = {
- clipCullDistance: false, // set to use vertex shader clipping
- multiDraw: false // set to use vertex shader multi_draw / enable gl_DrawID
- };
- </code>
- </p>
- <h3>[property:Boolean fog]</h3>
- <p>
- Define whether the material color is affected by global fog settings; true
- to pass fog uniforms to the shader. Default is false.
- </p>
- <h3>[property:String fragmentShader]</h3>
- <p>
- Fragment shader GLSL code. This is the actual code for the shader. In the
- example above, the `vertexShader` and `fragmentShader` code is extracted
- from the DOM; it could be passed as a string directly or loaded via AJAX
- instead.
- </p>
- <h3>[property:String glslVersion]</h3>
- <p>
- Defines the GLSL version of custom shader code. Valid values are
- `THREE.GLSL1` or `THREE.GLSL3`. Default is `null`.
- </p>
- <h3>[property:String index0AttributeName]</h3>
- <p>
- If set, this calls
- [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bindAttribLocation gl.bindAttribLocation]
- to bind a generic vertex index to an attribute variable. Default is undefined.
- </p>
- <h3>[property:Boolean isShaderMaterial]</h3>
- <p>Read-only flag to check if a given object is of type [name].</p>
- <h3>[property:Boolean lights]</h3>
- <p>
- Defines whether this material uses lighting; true to pass uniform data
- related to lighting to this shader. Default is false.
- </p>
- <h3>[property:Float linewidth]</h3>
- <p>
- Controls wireframe thickness. Default is `1`.<br /><br />
- Due to limitations of the
- [link:https://www.khronos.org/registry/OpenGL/specs/gl/glspec46.core.pdf OpenGL Core Profile]
- with the [page:WebGLRenderer WebGL] renderer on most
- platforms linewidth will always be `1` regardless of the set value.
- </p>
- <h3>[property:Boolean flatShading]</h3>
- <p>
- Define whether the material is rendered with flat shading.
- Default is false.
- </p>
- <h3>[property:Object uniforms]</h3>
- <p>
- An object of the form:
- <code>
- {
- "uniform1": { value: 1.0 },
- "uniform2": { value: 2 }
- }
- </code>
- specifying the uniforms to be passed to the shader code; keys are uniform
- names, values are definitions of the form
- <code>
- {
- value: 1.0
- }
- </code>
- where `value` is the value of the uniform. Names must match the name of
- the uniform, as defined in the GLSL code. Note that uniforms are refreshed
- on every frame, so updating the value of the uniform will immediately
- update the value available to the GLSL code.
- </p>
- <h3>[property:Boolean uniformsNeedUpdate]</h3>
- <p>
- Can be used to force a uniform update while changing uniforms in
- [page:Object3D.onBeforeRender](). Default is `false`.
- </p>
- <h3>[property:Boolean vertexColors]</h3>
- <p>Defines whether vertex coloring is used. Default is `false`.</p>
- <h3>[property:String vertexShader]</h3>
- <p>
- Vertex shader GLSL code. This is the actual code for the shader. In the
- example above, the `vertexShader` and `fragmentShader` code is extracted
- from the DOM; it could be passed as a string directly or loaded via AJAX
- instead.
- </p>
- <h3>[property:Boolean wireframe]</h3>
- <p>
- Render geometry as wireframe (using GL_LINES instead of GL_TRIANGLES).
- Default is false (i.e. render as flat polygons).
- </p>
- <h3>[property:Float wireframeLinewidth]</h3>
- <p>
- Controls wireframe thickness. Default is `1`.<br /><br />
- Due to limitations of the
- [link:https://www.khronos.org/registry/OpenGL/specs/gl/glspec46.core.pdf OpenGL Core Profile]
- with the [page:WebGLRenderer WebGL] renderer on most
- platforms linewidth will always be `1` regardless of the set value.
- </p>
- <h2>Methods</h2>
- <p>See the base [page:Material] class for common methods.</p>
- <h3>[method:ShaderMaterial clone]()</h3>
- <p>
- Generates a shallow copy of this material. Note that the vertexShader and
- fragmentShader are copied `by reference`, as are the definitions of the
- `attributes`; this means that clones of the material will share the same
- compiled [page:WebGLProgram]. However, the `uniforms` are copied `by
- value`, which allows you to have different sets of uniforms for different
- copies of the material.
- </p>
- <h2>Source</h2>
- <p>
- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
- </p>
- </body>
- </html>
|