瀏覽代碼

Merge pull request #18003 from Mugen87/dev39

MeshToonMaterial: Stop deriving from MeshPhongMaterial.
Michael Herzog 5 年之前
父節點
當前提交
e2d4abb9cf

+ 167 - 20
docs/api/en/materials/MeshToonMaterial.html

@@ -8,11 +8,11 @@
 		<link type="text/css" rel="stylesheet" href="page.css" />
 		<link type="text/css" rel="stylesheet" href="page.css" />
 	</head>
 	</head>
 	<body>
 	<body>
-		[page:Material] &rarr; [page:MeshPhongMaterial] &rarr;
+		[page:Material] &rarr;
 
 
 		<h1>[name]</h1>
 		<h1>[name]</h1>
 
 
-		<div class="desc">An extension of the [page:MeshPhongMaterial] with toon shading.</div>
+		<div class="desc">A material implementing toon shading.</div>
 
 
 		<iframe id="scene" src="scenes/material-browser.html#MeshToonMaterial"></iframe>
 		<iframe id="scene" src="scenes/material-browser.html#MeshToonMaterial"></iframe>
 
 
@@ -33,46 +33,193 @@
 		</script>
 		</script>
 
 
 		<h2>Examples</h2>
 		<h2>Examples</h2>
-		[example:webgl_materials_variations_toon materials / variations / toon]<br />
+		<p>
+			[example:webgl_materials_variations_toon materials / variations / toon]
+		</p>
 
 
 		<h2>Constructor</h2>
 		<h2>Constructor</h2>
 
 
 		<h3>[name]( [param:Object parameters] )</h3>
 		<h3>[name]( [param:Object parameters] )</h3>
 		<p>
 		<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] and [page:MeshStandardMaterial]) can be passed in here.<br /><br />
+			[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.<br /><br />
 
 
-		The exception is the property [page:Hexadecimal color], which can be passed in as a hexadecimal
-		string and is *0xffffff* (white) by default. [page:Color.set]( color ) is called internally.
+			The exception is the property [page:Hexadecimal color], which can be passed in as a hexadecimal
+			string and is *0xffffff* (white) by default. [page:Color.set]( color ) is called internally.
 		</p>
 		</p>
 
 
-
 		<h2>Properties</h2>
 		<h2>Properties</h2>
-		<p>See the base [page:Material] and [page:MeshPhongMaterial] classes for common properties.</p>
+		<p>See the base [page:Material] class for common properties.</p>
 
 
-		<h3>[property:Texture gradientMap]</h3>
-		<p>Gradient map for the toon shading. Default is *null*.</p>
+		<h3>[property:Texture alphaMap]</h3>
+		<p>The alpha map is a grayscale texture that controls the opacity across the surface
+			(black: fully transparent; white: fully opaque). Default is null.<br /><br />
+
+			Only the color of the texture is used, ignoring the alpha channel if one exists.
+			For RGB and RGBA textures, the [page:WebGLRenderer WebGL] renderer will use the
+			green channel when sampling this texture due to the extra bit of precision provided
+			for green in DXT-compressed and uncompressed RGB 565 formats. Luminance-only and
+			luminance/alpha textures will also still work as expected.
+		</p>
+
+		<h3>[property:Texture aoMap]</h3>
+		<p>The red channel of this texture is used as the ambient occlusion map. Default is null.
+		The aoMap requires a second set of UVs, and consequently will ignore the [page:Texture repeat]
+		and [page:Texture offset] Texture properties.</p>
+
+		<h3>[property:Float aoMapIntensity]</h3>
+		<p>Intensity of the ambient occlusion effect. Default is 1. Zero is no occlusion effect.</p>
+
+		<h3>[property:Texture bumpMap]</h3>
+		<p>
+			The texture to create a bump map. The black and white values map to the perceived depth in relation to the lights.
+			Bump doesn't actually affect the geometry of the object, only the lighting. If a normal map is defined this will
+			be ignored.
+		</p>
+
+		<h3>[property:Float bumpScale]</h3>
+		<p>How much the bump map affects the material. Typical ranges are 0-1. Default is 1.</p>
+
+
+		<h3>[property:Color color]</h3>
+		<p>[page:Color] of the material, by default set to white (0xffffff).</p>
+
+		<h3>[property:Texture displacementMap]</h3>
+		<p>
+			The displacement map affects the position of the mesh's vertices. Unlike other maps
+			which only affect the light and shade of the material the displaced vertices can cast shadows,
+			block other objects, and otherwise act as real geometry. The displacement texture is
+			an image where the value of each pixel (white being the highest) is mapped against,
+			and repositions, the vertices of the mesh.
+		</p>
+
+		<h3>[property:Float displacementScale]</h3>
+		<p>
+			How much the displacement map affects the mesh (where black is no displacement,
+			and white is maximum displacement). Without a displacement map set, this value is not applied.
+			 Default is 1.
+		</p>
+
+		<h3>[property:Float displacementBias]</h3>
+		<p>
+			The offset of the displacement map's values on the mesh's vertices.
+			Without a displacement map set, this value is not applied. Default is 0.
+		</p>
+
+		<h3>[property:Color emissive]</h3>
+		<p>
+		Emissive (light) color of the material, essentially a solid color unaffected by other lighting.
+		Default is black.
+		</p>
+
+		<h3>[property:Texture emissiveMap]</h3>
+		<p>
+		Set emisssive (glow) map. Default is null. The emissive map color is modulated by
+		the emissive color and the emissive intensity. If you have an emissive map, be sure to
+		set the emissive color to something other than black.
+		</p>
+
+		<h3>[property:Float emissiveIntensity]</h3>
+		<p>Intensity of the emissive light. Modulates the emissive color. Default is 1.</p>
 
 
 		<h3>[property:Boolean isMeshToonMaterial]</h3>
 		<h3>[property:Boolean isMeshToonMaterial]</h3>
 		<p>
 		<p>
-			Used to check whether this or derived classes are mesh toon materials. Default is *true*.<br /><br />
+			Used to check whether this or derived classes are [name]. Default is *true*.<br /><br />
 
 
 			You should not change this, as it used internally for optimisation.
 			You should not change this, as it used internally for optimisation.
 		</p>
 		</p>
 
 
-		<h3>[property:Object defines]</h3>
-		<p>An object of the form:
-			<code>
-				{ 'TOON': '' };
-			</code>
+		<h3>[property:Texture gradientMap]</h3>
+		<p>Gradient map for toon shading. Default is *null*.</p>
+
+		<h3>[property:Texture lightMap]</h3>
+		<p>The light map. Default is null. The lightMap requires a second set of UVs,
+		and consequently will ignore the [page:Texture repeat] and [page:Texture offset]
+		Texture properties.</p>
+
+		<h3>[property:Float lightMapIntensity]</h3>
+		<p>Intensity of the baked light. Default is 1.</p>
+
+		<h3>[property:Texture map]</h3>
+		<p>The color map. Default is null. The texture map color is modulated by the diffuse [page:.color].</p>
+
+		<h3>[property:boolean morphNormals]</h3>
+		<p>
+			Defines whether the material uses morphNormals. Set as true to pass morphNormal
+			attributes from the [page:Geometry]	to the shader. Default is *false*.
+		</p>
+
+		<h3>[property:Boolean morphTargets]</h3>
+		<p>Define whether the material uses morphTargets. Default is false.</p>
 
 
-			This is used by the [page:WebGLRenderer] for selecting shaders.
+		<h3>[property:Texture normalMap]</h3>
+		<p>
+			The texture to create a normal map. The RGB values affect the surface normal for each pixel fragment and change
+			the way the color is lit. Normal maps do not change the actual shape of the surface, only the lighting.
 		</p>
 		</p>
 
 
+		<h3>[property:Integer normalMapType]</h3>
+		<p>
+			The type of normal map.<br /><br />
 
 
-		<h2>Methods</h2>
-		<p>See the base [page:Material] and [page:MeshPhongMaterial] classes for common methods.</p>
+			Options are [page:constant THREE.TangentSpaceNormalMap] (default), and [page:constant THREE.ObjectSpaceNormalMap].
+		</p>
+
+		<h3>[property:Vector2 normalScale]</h3>
+		<p>
+			How much the normal map affects the material. Typical ranges are 0-1.
+			Default is a [page:Vector2] set to (1,1).
+		</p>
+
+		<h3>[property:Float shininess]</h3>
+		<p>How shiny the [page:.specular] highlight is; a higher value gives a sharper highlight. Default is *30*.</p>
+
+
+		<h3>[property:Boolean skinning]</h3>
+		<p>Define whether the material uses skinning. Default is false.</p>
+
+		<h3>[property:Color specular]</h3>
+		<p>
+			Specular color of the material. Default is a [page:Color] set to *0x111111* (very dark grey).<br /><br />
+
+			This defines how shiny the material is and the color of its shine.
+		</p>
+
+		<h3>[property:Texture specularMap]</h3>
+		<p>
+			The specular map value affects both how much the specular surface highlight
+			contributes and how much of the environment map affects the surface. Default is null.
+		</p>
+
+		<h3>[property:Boolean wireframe]</h3>
+		<p>Render geometry as wireframe. Default is *false* (i.e. render as flat polygons).</p>
+
+		<h3>[property:String wireframeLinecap]</h3>
+		<p>
+			Define appearance of line ends. Possible values are "butt", "round" and "square". Default is 'round'.<br /><br />
+
+			This corresponds to the [link:https://developer.mozilla.org/en/docs/Web/API/CanvasRenderingContext2D/lineCap 2D Canvas lineCap]
+			property and it is ignored by the [page:WebGLRenderer WebGL] renderer.
+		</p>
 
 
+		<h3>[property:String wireframeLinejoin]</h3>
+		<p>
+			Define appearance of line joints. Possible values are "round", "bevel" and "miter". Default is 'round'.<br /><br />
+
+			This corresponds to the [link:https://developer.mozilla.org/en/docs/Web/API/CanvasRenderingContext2D/lineJoin 2D Canvas lineJoin]
+			property and it is ignored by the [page:WebGLRenderer WebGL] renderer.
+		</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>
 
 
 		<h2>Source</h2>
 		<h2>Source</h2>
 
 

+ 175 - 24
docs/api/zh/materials/MeshToonMaterial.html

@@ -8,11 +8,11 @@
 		<link type="text/css" rel="stylesheet" href="page.css" />
 		<link type="text/css" rel="stylesheet" href="page.css" />
 	</head>
 	</head>
 	<body>
 	<body>
-		[page:Material] &rarr; [page:MeshPhongMaterial] &rarr;
+		[page:Material] &rarr;
 
 
-		<h1>卡通网格材质([name])</h1>
+		<h1>[name]</h1>
 
 
-		<div class="desc">[page:MeshPhongMaterial]卡通着色的扩展。</div>
+		<div class="desc">A material implementing toon shading.</div>
 
 
 		<iframe id="scene" src="scenes/material-browser.html#MeshToonMaterial"></iframe>
 		<iframe id="scene" src="scenes/material-browser.html#MeshToonMaterial"></iframe>
 
 
@@ -32,45 +32,196 @@
 
 
 		</script>
 		</script>
 
 
-		<h2>例子(Examples)</h2>
-		[example:webgl_materials_variations_toon materials / variations / toon]<br />
+		<h2>Examples</h2>
+		<p>
+			[example:webgl_materials_variations_toon materials / variations / toon]
+		</p>
 
 
-		<h2>构造函数(Constructor)</h2>
+		<h2>Constructor</h2>
 
 
 		<h3>[name]( [param:Object parameters] )</h3>
 		<h3>[name]( [param:Object parameters] )</h3>
-		<p> [page:Object parameters] - (可选)用于定义材质外观的对象,具有一个或多个属性。
-			材质的任何属性都可以从此处传入(包括从[page:Material]和[page:MeshStandardMaterial]继承的任何属性)。<br /><br />
-			属性[page:Hexadecimal color]例外,其可以作为十六进制字符串传递,默认情况下为 *0xffffff*(白色),内部调用[page:Color.set](color)。
+		<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.<br /><br />
+
+			The exception is the property [page:Hexadecimal color], which can be passed in as a hexadecimal
+			string and is *0xffffff* (white) by default. [page:Color.set]( color ) is called internally.
 		</p>
 		</p>
 
 
+		<h2>Properties</h2>
+		<p>See the base [page:Material] class for common properties.</p>
 
 
-		<h2>属性(Properties)</h2>
-		<p>共有属性请参见其基类[page:Material]和[page:MeshPhongMaterial]。</p>
+		<h3>[property:Texture alphaMap]</h3>
+		<p>The alpha map is a grayscale texture that controls the opacity across the surface
+			(black: fully transparent; white: fully opaque). Default is null.<br /><br />
 
 
-		<h3>[property:Texture gradientMap]</h3>
-		<p> 卡通着色的渐变贴图,默认值为*null*。</p>
+			Only the color of the texture is used, ignoring the alpha channel if one exists.
+			For RGB and RGBA textures, the [page:WebGLRenderer WebGL] renderer will use the
+			green channel when sampling this texture due to the extra bit of precision provided
+			for green in DXT-compressed and uncompressed RGB 565 formats. Luminance-only and
+			luminance/alpha textures will also still work as expected.
+		</p>
+
+		<h3>[property:Texture aoMap]</h3>
+		<p>The red channel of this texture is used as the ambient occlusion map. Default is null.
+		The aoMap requires a second set of UVs, and consequently will ignore the [page:Texture repeat]
+		and [page:Texture offset] Texture properties.</p>
+
+		<h3>[property:Float aoMapIntensity]</h3>
+		<p>Intensity of the ambient occlusion effect. Default is 1. Zero is no occlusion effect.</p>
+
+		<h3>[property:Texture bumpMap]</h3>
+		<p>
+			The texture to create a bump map. The black and white values map to the perceived depth in relation to the lights.
+			Bump doesn't actually affect the geometry of the object, only the lighting. If a normal map is defined this will
+			be ignored.
+		</p>
+
+		<h3>[property:Float bumpScale]</h3>
+		<p>How much the bump map affects the material. Typical ranges are 0-1. Default is 1.</p>
+
+
+		<h3>[property:Color color]</h3>
+		<p>[page:Color] of the material, by default set to white (0xffffff).</p>
+
+		<h3>[property:Texture displacementMap]</h3>
+		<p>
+			The displacement map affects the position of the mesh's vertices. Unlike other maps
+			which only affect the light and shade of the material the displaced vertices can cast shadows,
+			block other objects, and otherwise act as real geometry. The displacement texture is
+			an image where the value of each pixel (white being the highest) is mapped against,
+			and repositions, the vertices of the mesh.
+		</p>
+
+		<h3>[property:Float displacementScale]</h3>
+		<p>
+			How much the displacement map affects the mesh (where black is no displacement,
+			and white is maximum displacement). Without a displacement map set, this value is not applied.
+			 Default is 1.
+		</p>
+
+		<h3>[property:Float displacementBias]</h3>
+		<p>
+			The offset of the displacement map's values on the mesh's vertices.
+			Without a displacement map set, this value is not applied. Default is 0.
+		</p>
+
+		<h3>[property:Color emissive]</h3>
+		<p>
+		Emissive (light) color of the material, essentially a solid color unaffected by other lighting.
+		Default is black.
+		</p>
+
+		<h3>[property:Texture emissiveMap]</h3>
+		<p>
+		Set emisssive (glow) map. Default is null. The emissive map color is modulated by
+		the emissive color and the emissive intensity. If you have an emissive map, be sure to
+		set the emissive color to something other than black.
+		</p>
+
+		<h3>[property:Float emissiveIntensity]</h3>
+		<p>Intensity of the emissive light. Modulates the emissive color. Default is 1.</p>
 
 
 		<h3>[property:Boolean isMeshToonMaterial]</h3>
 		<h3>[property:Boolean isMeshToonMaterial]</h3>
-		<p> 用于检查此类或派生类是否为卡通网格材质。默认值为 *true*。<br /><br />
+		<p>
+			Used to check whether this or derived classes are [name]. Default is *true*.<br /><br />
 
 
-			因为其通常用在内部优化,所以不应该更改该属性值。
+			You should not change this, as it used internally for optimisation.
 		</p>
 		</p>
 
 
-		<h3>[property:Object defines]</h3>
-		<p>如下形式的对象:
-			<code>
-				{ 'TOON': '' };
-			</code>
+		<h3>[property:Texture gradientMap]</h3>
+		<p>Gradient map for toon shading. Default is *null*.</p>
+
+		<h3>[property:Texture lightMap]</h3>
+		<p>The light map. Default is null. The lightMap requires a second set of UVs,
+		and consequently will ignore the [page:Texture repeat] and [page:Texture offset]
+		Texture properties.</p>
+
+		<h3>[property:Float lightMapIntensity]</h3>
+		<p>Intensity of the baked light. Default is 1.</p>
 
 
-			[page:WebGLRenderer]使用它来选择shaders。
+		<h3>[property:Texture map]</h3>
+		<p>The color map. Default is null. The texture map color is modulated by the diffuse [page:.color].</p>
+
+		<h3>[property:boolean morphNormals]</h3>
+		<p>
+			Defines whether the material uses morphNormals. Set as true to pass morphNormal
+			attributes from the [page:Geometry]	to the shader. Default is *false*.
 		</p>
 		</p>
 
 
+		<h3>[property:Boolean morphTargets]</h3>
+		<p>Define whether the material uses morphTargets. Default is false.</p>
+
+		<h3>[property:Texture normalMap]</h3>
+		<p>
+			The texture to create a normal map. The RGB values affect the surface normal for each pixel fragment and change
+			the way the color is lit. Normal maps do not change the actual shape of the surface, only the lighting.
+		</p>
+
+		<h3>[property:Integer normalMapType]</h3>
+		<p>
+			The type of normal map.<br /><br />
+
+			Options are [page:constant THREE.TangentSpaceNormalMap] (default), and [page:constant THREE.ObjectSpaceNormalMap].
+		</p>
+
+		<h3>[property:Vector2 normalScale]</h3>
+		<p>
+			How much the normal map affects the material. Typical ranges are 0-1.
+			Default is a [page:Vector2] set to (1,1).
+		</p>
+
+		<h3>[property:Float shininess]</h3>
+		<p>How shiny the [page:.specular] highlight is; a higher value gives a sharper highlight. Default is *30*.</p>
+
+
+		<h3>[property:Boolean skinning]</h3>
+		<p>Define whether the material uses skinning. Default is false.</p>
+
+		<h3>[property:Color specular]</h3>
+		<p>
+			Specular color of the material. Default is a [page:Color] set to *0x111111* (very dark grey).<br /><br />
 
 
-		<h2>方法(Methods)</h2>
-		<p>共有方法请参见其基类[page:Material]和[page:MeshPhongMaterial]。</p>
+			This defines how shiny the material is and the color of its shine.
+		</p>
+
+		<h3>[property:Texture specularMap]</h3>
+		<p>
+			The specular map value affects both how much the specular surface highlight
+			contributes and how much of the environment map affects the surface. Default is null.
+		</p>
+
+		<h3>[property:Boolean wireframe]</h3>
+		<p>Render geometry as wireframe. Default is *false* (i.e. render as flat polygons).</p>
+
+		<h3>[property:String wireframeLinecap]</h3>
+		<p>
+			Define appearance of line ends. Possible values are "butt", "round" and "square". Default is 'round'.<br /><br />
+
+			This corresponds to the [link:https://developer.mozilla.org/en/docs/Web/API/CanvasRenderingContext2D/lineCap 2D Canvas lineCap]
+			property and it is ignored by the [page:WebGLRenderer WebGL] renderer.
+		</p>
+
+		<h3>[property:String wireframeLinejoin]</h3>
+		<p>
+			Define appearance of line joints. Possible values are "round", "bevel" and "miter". Default is 'round'.<br /><br />
+
+			This corresponds to the [link:https://developer.mozilla.org/en/docs/Web/API/CanvasRenderingContext2D/lineJoin 2D Canvas lineJoin]
+			property and it is ignored by the [page:WebGLRenderer WebGL] renderer.
+		</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>
 
 
-		<h2>源码(Source)</h2>
+		<h2>Source</h2>
 
 
 		<p>
 		<p>
 			[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
 			[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

+ 2 - 4
examples/webgl_materials_variations_toon.html

@@ -85,9 +85,7 @@
 								bumpScale: bumpScale,
 								bumpScale: bumpScale,
 								color: diffuseColor,
 								color: diffuseColor,
 								specular: specularColor,
 								specular: specularColor,
-								reflectivity: beta,
 								shininess: specularShininess,
 								shininess: specularShininess,
-								envMap: alphaIndex % 2 === 0 ? null : reflectionCube
 							} );
 							} );
 
 
 							var mesh = new THREE.Mesh( geometry, material );
 							var mesh = new THREE.Mesh( geometry, material );
@@ -126,8 +124,8 @@
 				addLabel( "-shininess", new THREE.Vector3( - 350, 0, 0 ) );
 				addLabel( "-shininess", new THREE.Vector3( - 350, 0, 0 ) );
 				addLabel( "+shininess", new THREE.Vector3( 350, 0, 0 ) );
 				addLabel( "+shininess", new THREE.Vector3( 350, 0, 0 ) );
 
 
-				addLabel( "-specular, -reflectivity", new THREE.Vector3( 0, - 300, 0 ) );
-				addLabel( "+specular, +reflectivity", new THREE.Vector3( 0, 300, 0 ) );
+				addLabel( "-specular", new THREE.Vector3( 0, - 300, 0 ) );
+				addLabel( "+specular", new THREE.Vector3( 0, 300, 0 ) );
 
 
 				addLabel( "-diffuse", new THREE.Vector3( 0, 0, - 300 ) );
 				addLabel( "-diffuse", new THREE.Vector3( 0, 0, - 300 ) );
 				addLabel( "+diffuse", new THREE.Vector3( 0, 0, 300 ) );
 				addLabel( "+diffuse", new THREE.Vector3( 0, 0, 300 ) );

+ 65 - 4
src/materials/MeshToonMaterial.d.ts

@@ -1,15 +1,76 @@
+import { Color } from './../math/Color';
 import { Texture } from './../textures/Texture';
 import { Texture } from './../textures/Texture';
-import { MeshPhongMaterialParameters, MeshPhongMaterial } from './MeshPhongMaterial';
+import { Vector2 } from './../math/Vector2';
+import { MaterialParameters, Material } from './Material';
+import { NormalMapTypes } from '../constants';
 
 
-export interface MeshToonMaterialParameters extends MeshPhongMaterialParameters {
+export interface MeshToonMaterialParameters extends MaterialParameters {
+	/** geometry color in hexadecimal. Default is 0xffffff. */
+	color?: Color | string | number;
+	specular?: Color | string | number;
+	shininess?: number;
+	opacity?: number;
 	gradientMap?: Texture | null;
 	gradientMap?: Texture | null;
+	map?: Texture | null;
+	lightMap?: Texture | null;
+	lightMapIntensity?: number;
+	aoMap?: Texture | null;
+	aoMapIntensity?: number;
+	emissive?: Color | string | number;
+	emissiveIntensity?: number;
+	emissiveMap?: Texture | null;
+	bumpMap?: Texture | null;
+	bumpScale?: number;
+	normalMap?: Texture | null;
+	normalMapType?: NormalMapTypes;
+	normalScale?: Vector2;
+	displacementMap?: Texture | null;
+	displacementScale?: number;
+	displacementBias?: number;
+	specularMap?: Texture | null;
+	alphaMap?: Texture | null;
+	wireframe?: boolean;
+	wireframeLinewidth?: number;
+	wireframeLinecap?: string;
+	wireframeLinejoin?: string;
+	skinning?: boolean;
+	morphTargets?: boolean;
+	morphNormals?: boolean;
 }
 }
 
 
-export class MeshToonMaterial extends MeshPhongMaterial {
+export class MeshToonMaterial extends Material {
 
 
 	constructor( parameters?: MeshToonMaterialParameters );
 	constructor( parameters?: MeshToonMaterialParameters );
 
 
-	gradientMap: Texture | null;
+	color: Color;
+	specular: Color;
+	shininess: number;
+	gradientMap: Texture | null;
+	map: Texture | null;
+	lightMap: Texture | null;
+	lightMapIntensity: number;
+	aoMap: Texture | null;
+	aoMapIntensity: number;
+	emissive: Color;
+	emissiveIntensity: number;
+	emissiveMap: Texture | null;
+	bumpMap: Texture | null;
+	bumpScale: number;
+	normalMap: Texture | null;
+	normalMapType: NormalMapTypes;
+	normalScale: Vector2;
+	displacementMap: Texture | null;
+	displacementScale: number;
+	displacementBias: number;
+	specularMap: Texture | null;
+	alphaMap: Texture | null;
+	wireframe: boolean;
+	wireframeLinewidth: number;
+	wireframeLinecap: string;
+	wireframeLinejoin: string;
+	skinning: boolean;
+	morphTargets: boolean;
+	morphNormals: boolean;
 
 
 	setValues( parameters: MeshToonMaterialParameters ): void;
 	setValues( parameters: MeshToonMaterialParameters ): void;
 
 

+ 123 - 5
src/materials/MeshToonMaterial.js

@@ -1,38 +1,156 @@
-import { MeshPhongMaterial } from './MeshPhongMaterial.js';
+import { TangentSpaceNormalMap } from '../constants.js';
+import { Material } from './Material.js';
+import { Vector2 } from '../math/Vector2.js';
+import { Color } from '../math/Color.js';
 
 
 /**
 /**
  * @author takahirox / http://github.com/takahirox
  * @author takahirox / http://github.com/takahirox
  *
  *
  * parameters = {
  * parameters = {
- *  gradientMap: new THREE.Texture( <Image> )
+ *  color: <hex>,
+ *  specular: <hex>,
+ *  shininess: <float>,
+ *
+ *  map: new THREE.Texture( <Image> ),
+ *  gradientMap: new THREE.Texture( <Image> ),
+ *
+ *  lightMap: new THREE.Texture( <Image> ),
+ *  lightMapIntensity: <float>
+ *
+ *  aoMap: new THREE.Texture( <Image> ),
+ *  aoMapIntensity: <float>
+ *
+ *  emissive: <hex>,
+ *  emissiveIntensity: <float>
+ *  emissiveMap: new THREE.Texture( <Image> ),
+ *
+ *  bumpMap: new THREE.Texture( <Image> ),
+ *  bumpScale: <float>,
+ *
+ *  normalMap: new THREE.Texture( <Image> ),
+ *  normalMapType: THREE.TangentSpaceNormalMap,
+ *  normalScale: <Vector2>,
+ *
+ *  displacementMap: new THREE.Texture( <Image> ),
+ *  displacementScale: <float>,
+ *  displacementBias: <float>,
+ *
+ *  specularMap: new THREE.Texture( <Image> ),
+ *
+ *  alphaMap: new THREE.Texture( <Image> ),
+ *
+ *  wireframe: <boolean>,
+ *  wireframeLinewidth: <float>,
+ *
+ *  skinning: <bool>,
+ *  morphTargets: <bool>,
+ *  morphNormals: <bool>
  * }
  * }
  */
  */
 
 
 function MeshToonMaterial( parameters ) {
 function MeshToonMaterial( parameters ) {
 
 
-	MeshPhongMaterial.call( this );
+	Material.call( this );
 
 
 	this.defines = { 'TOON': '' };
 	this.defines = { 'TOON': '' };
 
 
 	this.type = 'MeshToonMaterial';
 	this.type = 'MeshToonMaterial';
 
 
+	this.color = new Color( 0xffffff );
+	this.specular = new Color( 0x111111 );
+	this.shininess = 30;
+
+	this.map = null;
 	this.gradientMap = null;
 	this.gradientMap = null;
 
 
+	this.lightMap = null;
+	this.lightMapIntensity = 1.0;
+
+	this.aoMap = null;
+	this.aoMapIntensity = 1.0;
+
+	this.emissive = new Color( 0x000000 );
+	this.emissiveIntensity = 1.0;
+	this.emissiveMap = null;
+
+	this.bumpMap = null;
+	this.bumpScale = 1;
+
+	this.normalMap = null;
+	this.normalMapType = TangentSpaceNormalMap;
+	this.normalScale = new Vector2( 1, 1 );
+
+	this.displacementMap = null;
+	this.displacementScale = 1;
+	this.displacementBias = 0;
+
+	this.specularMap = null;
+
+	this.alphaMap = null;
+
+	this.wireframe = false;
+	this.wireframeLinewidth = 1;
+	this.wireframeLinecap = 'round';
+	this.wireframeLinejoin = 'round';
+
+	this.skinning = false;
+	this.morphTargets = false;
+	this.morphNormals = false;
+
 	this.setValues( parameters );
 	this.setValues( parameters );
 
 
 }
 }
 
 
-MeshToonMaterial.prototype = Object.create( MeshPhongMaterial.prototype );
+MeshToonMaterial.prototype = Object.create( Material.prototype );
 MeshToonMaterial.prototype.constructor = MeshToonMaterial;
 MeshToonMaterial.prototype.constructor = MeshToonMaterial;
 
 
 MeshToonMaterial.prototype.isMeshToonMaterial = true;
 MeshToonMaterial.prototype.isMeshToonMaterial = true;
 
 
 MeshToonMaterial.prototype.copy = function ( source ) {
 MeshToonMaterial.prototype.copy = function ( source ) {
 
 
-	MeshPhongMaterial.prototype.copy.call( this, source );
+	Material.prototype.copy.call( this, source );
+
+	this.color.copy( source.color );
+	this.specular.copy( source.specular );
+	this.shininess = source.shininess;
 
 
+	this.map = source.map;
 	this.gradientMap = source.gradientMap;
 	this.gradientMap = source.gradientMap;
 
 
+	this.lightMap = source.lightMap;
+	this.lightMapIntensity = source.lightMapIntensity;
+
+	this.aoMap = source.aoMap;
+	this.aoMapIntensity = source.aoMapIntensity;
+
+	this.emissive.copy( source.emissive );
+	this.emissiveMap = source.emissiveMap;
+	this.emissiveIntensity = source.emissiveIntensity;
+
+	this.bumpMap = source.bumpMap;
+	this.bumpScale = source.bumpScale;
+
+	this.normalMap = source.normalMap;
+	this.normalMapType = source.normalMapType;
+	this.normalScale.copy( source.normalScale );
+
+	this.displacementMap = source.displacementMap;
+	this.displacementScale = source.displacementScale;
+	this.displacementBias = source.displacementBias;
+
+	this.specularMap = source.specularMap;
+
+	this.alphaMap = source.alphaMap;
+
+	this.wireframe = source.wireframe;
+	this.wireframeLinewidth = source.wireframeLinewidth;
+	this.wireframeLinecap = source.wireframeLinecap;
+	this.wireframeLinejoin = source.wireframeLinejoin;
+
+	this.skinning = source.skinning;
+	this.morphTargets = source.morphTargets;
+	this.morphNormals = source.morphNormals;
+
 	return this;
 	return this;
 
 
 };
 };

+ 41 - 11
src/renderers/WebGLRenderer.js

@@ -1775,6 +1775,7 @@ function WebGLRenderer( parameters ) {
 
 
 			if ( material.isShaderMaterial ||
 			if ( material.isShaderMaterial ||
 				material.isMeshPhongMaterial ||
 				material.isMeshPhongMaterial ||
+				material.isMeshToonMaterial ||
 				material.isMeshStandardMaterial ||
 				material.isMeshStandardMaterial ||
 				material.envMap ) {
 				material.envMap ) {
 
 
@@ -1790,6 +1791,7 @@ function WebGLRenderer( parameters ) {
 			}
 			}
 
 
 			if ( material.isMeshPhongMaterial ||
 			if ( material.isMeshPhongMaterial ||
+				material.isMeshToonMaterial ||
 				material.isMeshLambertMaterial ||
 				material.isMeshLambertMaterial ||
 				material.isMeshBasicMaterial ||
 				material.isMeshBasicMaterial ||
 				material.isMeshStandardMaterial ||
 				material.isMeshStandardMaterial ||
@@ -1800,6 +1802,7 @@ function WebGLRenderer( parameters ) {
 			}
 			}
 
 
 			if ( material.isMeshPhongMaterial ||
 			if ( material.isMeshPhongMaterial ||
+				material.isMeshToonMaterial ||
 				material.isMeshLambertMaterial ||
 				material.isMeshLambertMaterial ||
 				material.isMeshBasicMaterial ||
 				material.isMeshBasicMaterial ||
 				material.isMeshStandardMaterial ||
 				material.isMeshStandardMaterial ||
@@ -1919,19 +1922,15 @@ function WebGLRenderer( parameters ) {
 				refreshUniformsCommon( m_uniforms, material );
 				refreshUniformsCommon( m_uniforms, material );
 				refreshUniformsLambert( m_uniforms, material );
 				refreshUniformsLambert( m_uniforms, material );
 
 
-			} else if ( material.isMeshPhongMaterial ) {
+			} else if ( material.isMeshToonMaterial ) {
 
 
 				refreshUniformsCommon( m_uniforms, material );
 				refreshUniformsCommon( m_uniforms, material );
+				refreshUniformsToon( m_uniforms, material );
 
 
-				if ( material.isMeshToonMaterial ) {
-
-					refreshUniformsToon( m_uniforms, material );
-
-				} else {
-
-					refreshUniformsPhong( m_uniforms, material );
+			} else if ( material.isMeshPhongMaterial ) {
 
 
-				}
+				refreshUniformsCommon( m_uniforms, material );
+				refreshUniformsPhong( m_uniforms, material );
 
 
 			} else if ( material.isMeshStandardMaterial ) {
 			} else if ( material.isMeshStandardMaterial ) {
 
 
@@ -2355,7 +2354,8 @@ function WebGLRenderer( parameters ) {
 
 
 	function refreshUniformsToon( uniforms, material ) {
 	function refreshUniformsToon( uniforms, material ) {
 
 
-		refreshUniformsPhong( uniforms, material );
+		uniforms.specular.value.copy( material.specular );
+		uniforms.shininess.value = Math.max( material.shininess, 1e-4 ); // to prevent pow( 0.0, 0.0 )
 
 
 		if ( material.gradientMap ) {
 		if ( material.gradientMap ) {
 
 
@@ -2363,6 +2363,36 @@ function WebGLRenderer( parameters ) {
 
 
 		}
 		}
 
 
+		if ( material.emissiveMap ) {
+
+			uniforms.emissiveMap.value = material.emissiveMap;
+
+		}
+
+		if ( material.bumpMap ) {
+
+			uniforms.bumpMap.value = material.bumpMap;
+			uniforms.bumpScale.value = material.bumpScale;
+			if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1;
+
+		}
+
+		if ( material.normalMap ) {
+
+			uniforms.normalMap.value = material.normalMap;
+			uniforms.normalScale.value.copy( material.normalScale );
+			if ( material.side === BackSide ) uniforms.normalScale.value.negate();
+
+		}
+
+		if ( material.displacementMap ) {
+
+			uniforms.displacementMap.value = material.displacementMap;
+			uniforms.displacementScale.value = material.displacementScale;
+			uniforms.displacementBias.value = material.displacementBias;
+
+		}
+
 	}
 	}
 
 
 	function refreshUniformsStandard( uniforms, material ) {
 	function refreshUniformsStandard( uniforms, material ) {
@@ -2555,7 +2585,7 @@ function WebGLRenderer( parameters ) {
 
 
 	function materialNeedsLights( material ) {
 	function materialNeedsLights( material ) {
 
 
-		return material.isMeshLambertMaterial || material.isMeshPhongMaterial ||
+		return material.isMeshLambertMaterial || material.isMeshToonMaterial || material.isMeshPhongMaterial ||
 			material.isMeshStandardMaterial || material.isShadowMaterial ||
 			material.isMeshStandardMaterial || material.isShadowMaterial ||
 			( material.isShaderMaterial && material.lights === true );
 			( material.isShaderMaterial && material.lights === true );
 
 

+ 8 - 0
src/renderers/shaders/ShaderChunk.js

@@ -39,6 +39,8 @@ import lightmap_pars_fragment from './ShaderChunk/lightmap_pars_fragment.glsl.js
 import lights_lambert_vertex from './ShaderChunk/lights_lambert_vertex.glsl.js';
 import lights_lambert_vertex from './ShaderChunk/lights_lambert_vertex.glsl.js';
 import lights_pars_begin from './ShaderChunk/lights_pars_begin.glsl.js';
 import lights_pars_begin from './ShaderChunk/lights_pars_begin.glsl.js';
 import envmap_physical_pars_fragment from './ShaderChunk/envmap_physical_pars_fragment.glsl.js';
 import envmap_physical_pars_fragment from './ShaderChunk/envmap_physical_pars_fragment.glsl.js';
+import lights_toon_fragment from './ShaderChunk/lights_toon_fragment.glsl.js';
+import lights_toon_pars_fragment from './ShaderChunk/lights_toon_pars_fragment.glsl.js';
 import lights_phong_fragment from './ShaderChunk/lights_phong_fragment.glsl.js';
 import lights_phong_fragment from './ShaderChunk/lights_phong_fragment.glsl.js';
 import lights_phong_pars_fragment from './ShaderChunk/lights_phong_pars_fragment.glsl.js';
 import lights_phong_pars_fragment from './ShaderChunk/lights_phong_pars_fragment.glsl.js';
 import lights_physical_fragment from './ShaderChunk/lights_physical_fragment.glsl.js';
 import lights_physical_fragment from './ShaderChunk/lights_physical_fragment.glsl.js';
@@ -110,6 +112,8 @@ import meshlambert_frag from './ShaderLib/meshlambert_frag.glsl.js';
 import meshlambert_vert from './ShaderLib/meshlambert_vert.glsl.js';
 import meshlambert_vert from './ShaderLib/meshlambert_vert.glsl.js';
 import meshmatcap_frag from './ShaderLib/meshmatcap_frag.glsl.js';
 import meshmatcap_frag from './ShaderLib/meshmatcap_frag.glsl.js';
 import meshmatcap_vert from './ShaderLib/meshmatcap_vert.glsl.js';
 import meshmatcap_vert from './ShaderLib/meshmatcap_vert.glsl.js';
+import meshtoon_frag from './ShaderLib/meshtoon_frag.glsl.js';
+import meshtoon_vert from './ShaderLib/meshtoon_vert.glsl.js';
 import meshphong_frag from './ShaderLib/meshphong_frag.glsl.js';
 import meshphong_frag from './ShaderLib/meshphong_frag.glsl.js';
 import meshphong_vert from './ShaderLib/meshphong_vert.glsl.js';
 import meshphong_vert from './ShaderLib/meshphong_vert.glsl.js';
 import meshphysical_frag from './ShaderLib/meshphysical_frag.glsl.js';
 import meshphysical_frag from './ShaderLib/meshphysical_frag.glsl.js';
@@ -165,6 +169,8 @@ export var ShaderChunk = {
 	lightmap_pars_fragment: lightmap_pars_fragment,
 	lightmap_pars_fragment: lightmap_pars_fragment,
 	lights_lambert_vertex: lights_lambert_vertex,
 	lights_lambert_vertex: lights_lambert_vertex,
 	lights_pars_begin: lights_pars_begin,
 	lights_pars_begin: lights_pars_begin,
+	lights_toon_fragment: lights_toon_fragment,
+	lights_toon_pars_fragment: lights_toon_pars_fragment,
 	lights_phong_fragment: lights_phong_fragment,
 	lights_phong_fragment: lights_phong_fragment,
 	lights_phong_pars_fragment: lights_phong_pars_fragment,
 	lights_phong_pars_fragment: lights_phong_pars_fragment,
 	lights_physical_fragment: lights_physical_fragment,
 	lights_physical_fragment: lights_physical_fragment,
@@ -236,6 +242,8 @@ export var ShaderChunk = {
 	meshlambert_vert: meshlambert_vert,
 	meshlambert_vert: meshlambert_vert,
 	meshmatcap_frag: meshmatcap_frag,
 	meshmatcap_frag: meshmatcap_frag,
 	meshmatcap_vert: meshmatcap_vert,
 	meshmatcap_vert: meshmatcap_vert,
+	meshtoon_frag: meshtoon_frag,
+	meshtoon_vert: meshtoon_vert,
 	meshphong_frag: meshphong_frag,
 	meshphong_frag: meshphong_frag,
 	meshphong_vert: meshphong_vert,
 	meshphong_vert: meshphong_vert,
 	meshphysical_frag: meshphysical_frag,
 	meshphysical_frag: meshphysical_frag,

+ 13 - 12
src/renderers/shaders/ShaderChunk/gradientmap_pars_fragment.glsl.js

@@ -1,26 +1,27 @@
 export default /* glsl */`
 export default /* glsl */`
-#ifdef TOON
+
+#ifdef USE_GRADIENTMAP
 
 
 	uniform sampler2D gradientMap;
 	uniform sampler2D gradientMap;
 
 
-	vec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {
+#endif
 
 
-		// dotNL will be from -1.0 to 1.0
-		float dotNL = dot( normal, lightDirection );
-		vec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );
+vec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {
 
 
-		#ifdef USE_GRADIENTMAP
+	// dotNL will be from -1.0 to 1.0
+	float dotNL = dot( normal, lightDirection );
+	vec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );
 
 
-			return texture2D( gradientMap, coord ).rgb;
+	#ifdef USE_GRADIENTMAP
 
 
-		#else
+		return texture2D( gradientMap, coord ).rgb;
 
 
-			return ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );
+	#else
 
 
-		#endif
+		return ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );
 
 
+	#endif
 
 
-	}
+}
 
 
-#endif
 `;
 `;

+ 2 - 10
src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl.js

@@ -19,16 +19,8 @@ struct BlinnPhongMaterial {
 
 
 void RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {
 void RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {
 
 
-	#ifdef TOON
-
-		vec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;
-
-	#else
-
-		float dotNL = saturate( dot( geometry.normal, directLight.direction ) );
-		vec3 irradiance = dotNL * directLight.color;
-
-	#endif
+	float dotNL = saturate( dot( geometry.normal, directLight.direction ) );
+	vec3 irradiance = dotNL * directLight.color;
 
 
 	#ifndef PHYSICALLY_CORRECT_LIGHTS
 	#ifndef PHYSICALLY_CORRECT_LIGHTS
 
 

+ 7 - 0
src/renderers/shaders/ShaderChunk/lights_toon_fragment.glsl.js

@@ -0,0 +1,7 @@
+export default /* glsl */`
+ToonMaterial material;
+material.diffuseColor = diffuseColor.rgb;
+material.specularColor = specular;
+material.specularShininess = shininess;
+material.specularStrength = specularStrength;
+`;

+ 46 - 0
src/renderers/shaders/ShaderChunk/lights_toon_pars_fragment.glsl.js

@@ -0,0 +1,46 @@
+export default /* glsl */`
+varying vec3 vViewPosition;
+
+#ifndef FLAT_SHADED
+
+	varying vec3 vNormal;
+
+#endif
+
+
+struct ToonMaterial {
+
+	vec3	diffuseColor;
+	vec3	specularColor;
+	float	specularShininess;
+	float	specularStrength;
+
+};
+
+void RE_Direct_Toon( const in IncidentLight directLight, const in GeometricContext geometry, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {
+
+	vec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;
+
+	#ifndef PHYSICALLY_CORRECT_LIGHTS
+
+		irradiance *= PI; // punctual light
+
+	#endif
+
+	reflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );
+
+	reflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;
+
+}
+
+void RE_IndirectDiffuse_Toon( const in vec3 irradiance, const in GeometricContext geometry, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {
+
+	reflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );
+
+}
+
+#define RE_Direct				RE_Direct_Toon
+#define RE_IndirectDiffuse		RE_IndirectDiffuse_Toon
+
+#define Material_LightProbeLOD( material )	(0)
+`;

+ 26 - 1
src/renderers/shaders/ShaderLib.js

@@ -63,7 +63,6 @@ var ShaderLib = {
 			UniformsLib.bumpmap,
 			UniformsLib.bumpmap,
 			UniformsLib.normalmap,
 			UniformsLib.normalmap,
 			UniformsLib.displacementmap,
 			UniformsLib.displacementmap,
-			UniformsLib.gradientmap,
 			UniformsLib.fog,
 			UniformsLib.fog,
 			UniformsLib.lights,
 			UniformsLib.lights,
 			{
 			{
@@ -106,6 +105,32 @@ var ShaderLib = {
 
 
 	},
 	},
 
 
+	toon: {
+
+		uniforms: mergeUniforms( [
+			UniformsLib.common,
+			UniformsLib.specularmap,
+			UniformsLib.aomap,
+			UniformsLib.lightmap,
+			UniformsLib.emissivemap,
+			UniformsLib.bumpmap,
+			UniformsLib.normalmap,
+			UniformsLib.displacementmap,
+			UniformsLib.gradientmap,
+			UniformsLib.fog,
+			UniformsLib.lights,
+			{
+				emissive: { value: new Color( 0x000000 ) },
+				specular: { value: new Color( 0x111111 ) },
+				shininess: { value: 30 }
+			}
+		] ),
+
+		vertexShader: ShaderChunk.meshtoon_vert,
+		fragmentShader: ShaderChunk.meshtoon_frag
+
+	},
+
 	matcap: {
 	matcap: {
 
 
 		uniforms: mergeUniforms( [
 		uniforms: mergeUniforms( [

+ 0 - 1
src/renderers/shaders/ShaderLib/meshphong_frag.glsl.js

@@ -20,7 +20,6 @@ uniform float opacity;
 #include <emissivemap_pars_fragment>
 #include <emissivemap_pars_fragment>
 #include <envmap_common_pars_fragment>
 #include <envmap_common_pars_fragment>
 #include <envmap_pars_fragment>
 #include <envmap_pars_fragment>
-#include <gradientmap_pars_fragment>
 #include <fog_pars_fragment>
 #include <fog_pars_fragment>
 #include <bsdfs>
 #include <bsdfs>
 #include <lights_pars_begin>
 #include <lights_pars_begin>

+ 71 - 0
src/renderers/shaders/ShaderLib/meshtoon_frag.glsl.js

@@ -0,0 +1,71 @@
+export default /* glsl */`
+#define TOON
+
+uniform vec3 diffuse;
+uniform vec3 emissive;
+uniform vec3 specular;
+uniform float shininess;
+uniform float opacity;
+
+#include <common>
+#include <packing>
+#include <dithering_pars_fragment>
+#include <color_pars_fragment>
+#include <uv_pars_fragment>
+#include <uv2_pars_fragment>
+#include <map_pars_fragment>
+#include <alphamap_pars_fragment>
+#include <aomap_pars_fragment>
+#include <lightmap_pars_fragment>
+#include <emissivemap_pars_fragment>
+#include <gradientmap_pars_fragment>
+#include <fog_pars_fragment>
+#include <bsdfs>
+#include <lights_pars_begin>
+#include <lights_toon_pars_fragment>
+#include <shadowmap_pars_fragment>
+#include <bumpmap_pars_fragment>
+#include <normalmap_pars_fragment>
+#include <specularmap_pars_fragment>
+#include <logdepthbuf_pars_fragment>
+#include <clipping_planes_pars_fragment>
+
+void main() {
+
+	#include <clipping_planes_fragment>
+
+	vec4 diffuseColor = vec4( diffuse, opacity );
+	ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );
+	vec3 totalEmissiveRadiance = emissive;
+
+	#include <logdepthbuf_fragment>
+	#include <map_fragment>
+	#include <color_fragment>
+	#include <alphamap_fragment>
+	#include <alphatest_fragment>
+	#include <specularmap_fragment>
+	#include <normal_fragment_begin>
+	#include <normal_fragment_maps>
+	#include <emissivemap_fragment>
+
+	// accumulation
+	#include <lights_toon_fragment>
+	#include <lights_fragment_begin>
+	#include <lights_fragment_maps>
+	#include <lights_fragment_end>
+
+	// modulation
+	#include <aomap_fragment>
+
+	vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;
+
+	gl_FragColor = vec4( outgoingLight, diffuseColor.a );
+
+	#include <tonemapping_fragment>
+	#include <encodings_fragment>
+	#include <fog_fragment>
+	#include <premultiplied_alpha_fragment>
+	#include <dithering_fragment>
+
+}
+`;

+ 57 - 0
src/renderers/shaders/ShaderLib/meshtoon_vert.glsl.js

@@ -0,0 +1,57 @@
+export default /* glsl */`
+#define TOON
+
+varying vec3 vViewPosition;
+
+#ifndef FLAT_SHADED
+
+	varying vec3 vNormal;
+
+#endif
+
+#include <common>
+#include <uv_pars_vertex>
+#include <uv2_pars_vertex>
+#include <displacementmap_pars_vertex>
+#include <color_pars_vertex>
+#include <fog_pars_vertex>
+#include <morphtarget_pars_vertex>
+#include <skinning_pars_vertex>
+#include <shadowmap_pars_vertex>
+#include <logdepthbuf_pars_vertex>
+#include <clipping_planes_pars_vertex>
+
+void main() {
+
+	#include <uv_vertex>
+	#include <uv2_vertex>
+	#include <color_vertex>
+
+	#include <beginnormal_vertex>
+	#include <morphnormal_vertex>
+	#include <skinbase_vertex>
+	#include <skinnormal_vertex>
+	#include <defaultnormal_vertex>
+
+#ifndef FLAT_SHADED // Normal computed with derivatives when FLAT_SHADED
+
+	vNormal = normalize( transformedNormal );
+
+#endif
+
+	#include <begin_vertex>
+	#include <morphtarget_vertex>
+	#include <skinning_vertex>
+	#include <displacementmap_vertex>
+	#include <project_vertex>
+	#include <logdepthbuf_vertex>
+	#include <clipping_planes_vertex>
+
+	vViewPosition = - mvPosition.xyz;
+
+	#include <worldpos_vertex>
+	#include <shadowmap_vertex>
+	#include <fog_vertex>
+
+}
+`;

+ 1 - 1
src/renderers/webgl/WebGLPrograms.js

@@ -23,7 +23,7 @@ function WebGLPrograms( renderer, extensions, capabilities ) {
 		MeshBasicMaterial: 'basic',
 		MeshBasicMaterial: 'basic',
 		MeshLambertMaterial: 'lambert',
 		MeshLambertMaterial: 'lambert',
 		MeshPhongMaterial: 'phong',
 		MeshPhongMaterial: 'phong',
-		MeshToonMaterial: 'phong',
+		MeshToonMaterial: 'toon',
 		MeshStandardMaterial: 'physical',
 		MeshStandardMaterial: 'physical',
 		MeshPhysicalMaterial: 'physical',
 		MeshPhysicalMaterial: 'physical',
 		MeshMatcapMaterial: 'matcap',
 		MeshMatcapMaterial: 'matcap',