ShaderMaterial 着色器材质

—> Material

材质可根据用户自定义着色器来进行渲染. 着色器包括顶点着色器 vertexShader 和片段着色器 fragmentShader, 它们都是基于 GLSL ( Graphics Library Shading Language ), 直接在GPU上运算. 下面代码没看明白的请转到 WebGLBufferGeometry.

function ShaderMaterial( parameters ) { } <script id="vs_box" type="x-shader/x-vertex"> precision highp float; varying vec3 v_color; void main(){ gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); v_color = color * position; } </script> <script id="fs_box" type="x-shader/x-fragment"> precision highp float; varying vec3 v_color; void main(){ gl_FragColor = vec4(v_color, 1.0); } </script> <script id="vs_sphere" type="x-shader/x-vertex"> precision highp float; attribute vec3 a_Angle; varying vec3 v_color; void main(){ gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); v_color = color * sin(a_Angle); } </script> <script id="fs_sphere" type="x-shader/x-fragment"> precision highp float; varying vec3 v_color; void main(){ gl_FragColor = vec4(v_color, 1.0); } </script> <script id="vs_torusKnot" type="x-shader/x-vertex"> precision highp float; varying vec2 v_uv; void main(){ gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); v_uv = uv; } </script> <script id="fs_torusKnot" type="x-shader/x-fragment"> precision highp float; uniform float time; uniform sampler2D texture; varying vec2 v_uv; void main( void ) { vec2 uv = v_uv; float a = atan( uv.y, uv.x ); float r = sqrt( dot( uv, uv ) ); uv.x = cos( a ) / r; uv.y = sin( a ) / r; uv /= 10.0; uv += time * 0.05; vec3 color = texture2D( texture, uv ).rgb; gl_FragColor = vec4( color, 1.0 ); } </script> // Box: uniforms 没数据,只传 color var boxGeometry = new THREE.BoxBufferGeometry(6, 6, 6); var boxColors = []; for(var i = 0; i < boxGeometry.attributes.position.count; i++){ boxColors.push( Math.random(), Math.random(), Math.random() ); } boxGeometry.addAttribute( 'color', new THREE.Float32BufferAttribute( boxColors, 3 ) ); var boxMaterial = new THREE.ShaderMaterial({ uniforms: {}, vertexShader: document.getElementById( 'vs_box' ).textContent, fragmentShader: document.getElementById( 'fs_box' ).textContent, vertexColors: true }); var cube = new THREE.Mesh(boxGeometry, boxMaterial); scene.add(cube); // Sphere: uniforms 没数据,传角度数组 a_Angle var sphereGeometry = new THREE.SphereBufferGeometry(4, 40, 40); var sphereColors = [], angles = []; for(var j = 0; j < sphereGeometry.attributes.position.count; j++){ sphereColors.push(1.0, 1.0, 1.0); angles.push( Math.PI, Math.PI * Math.random(), 0.0 ); } sphereGeometry.addAttribute( 'color', new THREE.Float32BufferAttribute( sphereColors, 3 ) ); sphereGeometry.addAttribute( 'a_Angle', new THREE.Float32BufferAttribute( angles, 3 ) ); var shpereMaterial = new THREE.ShaderMaterial({ uniforms: {}, vertexShader: document.getElementById( 'vs_sphere' ).textContent, fragmentShader: document.getElementById( 'fs_sphere' ).textContent, vertexColors: true }); var sphere = new THREE.Mesh(sphereGeometry, shpereMaterial); scene.add(sphere); // TorusKnot uniforms 传纹理和时间 var torusKnotGeometry = new THREE.TorusKnotBufferGeometry(4, 1, 160, 20); var torusKnotMaterial = new THREE.ShaderMaterial({ uniforms: { time: { value: 1.0 }, color: { value: new THREE.Color( 0xffffff ) }, texture:{ value: new THREE.TextureLoader().load("../assets/textures/view.png") } }, vertexShader: document.getElementById( 'vs_torusKnot' ).textContent, fragmentShader: document.getElementById( 'fs_torusKnot' ).textContent, blending: THREE.AdditiveBlending, depthTest: false, transparent: true }); torusKnotMaterial.uniforms.texture.value.wrapS = torusKnotMaterial.uniforms.texture.value.wrapT = THREE.RepeatWrapping; var torusKnot = new THREE.Mesh(torusKnotGeometry, torusKnotMaterial); scene.add(torusKnot); var clock = new THREE.Clock(); function animate(){ cube.rotation.y += 0.005; sphere.rotation.y += 0.005; torusKnot.rotation.y += 0.005; var delta = clock.getDelta(); torusKnotMaterial.uniforms.time.value = clock.elapsedTime; renderer.render(scene, camera); requestAnimationFrame(animate); } animate();

Attributes

type : String

Default value : 'ShaderMaterial'
Description : 类型

defines : Object

Default value : {}
Description : 使用顶点着色器和片段着色器的GLSL代码中的 * #define * 指令定义自定义常量; 每个键/值对产生另一个指令。defines:{ XX: ~~~ }

uniforms : Object

Default value : {}
Description : 以 { name: { value: ~~ } } 来传递信息到着色器。形如uniforms:{ diffuse:{ value:texture } }

vertexShader : String

Default value : 'void main() { gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }'
Description : 顶点着色器 GLSL 代码。

fragmentShader : String

Default value : 'void main() { gl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 ); }'
Description : 片段着色器 GLSL 代码。

linewidth : Float

Default value : 1
Description : 线宽。

wireframe : Boolean

Default value : false
Description : 是否把模型渲染为线框(用 GL_LINES 替代 GL_TRIANGLES). 默认是 false, 渲染为平面多边形.

wireframeLinewidth : Float

Default value : 1
Description : 线框线宽. 由于 OpenGL 核心配置文件与大多数平台上的WebGL渲染器的限制,无论设置值如何,线宽始终为1。

fog : Boolean

Default value : false
Description : 材质颜色是否受全局雾化设置的影响; 如果将雾化uniforms数据传递到着色器,则为true。

lights : Boolean

Default value : false
Description : 此材料是否使用照明; 如果将与照明相关的uniforms数据传递给此着色器,则为true。

clipping : Boolean

Default value : false
Description : 此材质是否支持剪裁。

skinning : Boolean

Default value : false
Description : 材质是否使用蒙皮; 如果将蒙皮属性传递给着色器,则为true。

morphTargets : Boolean

Default value : false
Description : 是否使用变形目标.

morphNormals : Boolean

Default value : false
Description : 是否使用的材料变形法线,设置为 true 以将变形法线属性从 Geometry 传递到着色器。

extensions : Object

Default value : { derivatives: false, fragDepth: false, drawBuffers: false, shaderTextureLOD: false };
Description : 如上面形式来扩充属性。

defaultAttributeValues : Object

Default value : { 'color': [ 1, 1, 1 ], 'uv': [ 0, 0 ], 'uv2': [ 0, 0 ] };
Description : 当渲染的几何体不包含这些属性但材质包含时,这些默认值将传递给着色器,可以避免缓冲区数据丢失时的错误。

index0AttributeName : String

Default value : undefined
Description : 如果设置,则调用 gl.bindAttribLocation 将通用顶点索引绑定到 attribute 变量。