From f986933485a8b8003b2395e0ac9d8335a814fbe1 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Sat, 19 Nov 2016 13:11:49 -0800 Subject: [PATCH] Add MeshToonMaterial --- examples/files.js | 1 + examples/js/effects/OutlineEffect.js | 3 +- examples/js/loaders/MMDLoader.js | 16 +- examples/webgl_loader_mmd.html | 44 ++-- examples/webgl_materials_variations_toon.html | 239 ++++++++++++++++++ src/materials/Materials.js | 1 + src/materials/MeshPhongMaterial.js | 4 - src/renderers/WebGLRenderer.js | 14 + src/renderers/shaders/ShaderChunk.js | 4 + .../clipping_planes_pars_fragment.glsl | 2 +- .../clipping_planes_pars_vertex.glsl | 2 +- .../ShaderChunk/clipping_planes_vertex.glsl | 2 +- .../shaders/ShaderChunk/envmap_fragment.glsl | 2 +- .../ShaderChunk/envmap_pars_fragment.glsl | 4 +- .../ShaderChunk/envmap_pars_vertex.glsl | 2 +- .../shaders/ShaderChunk/envmap_vertex.glsl | 2 +- .../gradientmap_pars_fragment.glsl | 15 +- .../lights_phong_pars_fragment.glsl | 2 +- .../shaders/ShaderChunk/worldpos_vertex.glsl | 2 +- src/renderers/shaders/ShaderLib.js | 26 +- .../shaders/ShaderLib/meshphong_frag.glsl | 1 - src/renderers/webgl/WebGLPrograms.js | 1 + 22 files changed, 345 insertions(+), 44 deletions(-) create mode 100644 examples/webgl_materials_variations_toon.html diff --git a/examples/files.js b/examples/files.js index cd520861a7..991d6bd14d 100644 --- a/examples/files.js +++ b/examples/files.js @@ -155,6 +155,7 @@ var files = { "webgl_materials_variations_phong", "webgl_materials_variations_standard", "webgl_materials_variations_physical", + "webgl_materials_variations_toon", "webgl_materials_video", "webgl_materials_wireframe", "webgl_math_spherical_distribution", diff --git a/examples/js/effects/OutlineEffect.js b/examples/js/effects/OutlineEffect.js index 88f2821d03..2ebbaccd35 100644 --- a/examples/js/effects/OutlineEffect.js +++ b/examples/js/effects/OutlineEffect.js @@ -64,6 +64,7 @@ THREE.OutlineEffect = function ( renderer, parameters ) { MeshBasicMaterial: 'basic', MeshLambertMaterial: 'lambert', MeshPhongMaterial: 'phong', + MeshToonMaterial: 'toon', MeshStandardMaterial: 'physical', MeshPhysicalMaterial: 'physical' }; @@ -93,7 +94,7 @@ THREE.OutlineEffect = function ( renderer, parameters ) { var vertexShaderChunk2 = [ - "#if ! defined( LAMBERT ) && ! defined( PHONG ) && ! defined( PHYSICAL )", + "#if ! defined( LAMBERT ) && ! defined( PHONG ) && ! defined( TOON ) && ! defined( PHYSICAL )", " #ifndef USE_ENVMAP", " vec3 objectNormal = normalize( normal );", diff --git a/examples/js/loaders/MMDLoader.js b/examples/js/loaders/MMDLoader.js index 402992f6f5..75abdf9682 100644 --- a/examples/js/loaders/MMDLoader.js +++ b/examples/js/loaders/MMDLoader.js @@ -857,7 +857,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress var initMaterials = function () { - var textures = []; + var textures = {}; var textureLoader = new THREE.TextureLoader( scope.manager ); var tgaLoader = new THREE.TGALoader( scope.manager ); var canvas = document.createElement( 'canvas' ); @@ -894,6 +894,8 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress } + if ( textures[ fullPath ] !== undefined ) return fullPath; + var loader = THREE.Loader.Handlers.get( fullPath ); if ( loader === null ) { @@ -948,11 +950,9 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress texture.readyCallbacks = []; - var uuid = THREE.Math.generateUUID(); - - textures[ uuid ] = texture; + textures[ fullPath ] = texture; - return uuid; + return fullPath; } @@ -983,13 +983,13 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress /* * Color * - * MMD MeshPhongMaterial + * MMD MeshToonMaterial * diffuse - color * specular - specular * ambient - emissive * a * (a = 1.0 without map texture or 0.2 with map texture) * - * MeshPhongMaterial doesn't have ambient. Set it to emissive instead. + * MeshToonMaterial doesn't have ambient. Set it to emissive instead. * It'll be too bright if material has map texture so using coef 0.2. */ params.color = new THREE.Color( m.diffuse[ 0 ], m.diffuse[ 1 ], m.diffuse[ 2 ] ); @@ -1097,7 +1097,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress var p = materialParams[ i ]; var p2 = model.materials[ i ]; - var m = new THREE.MeshPhongMaterial(); + var m = new THREE.MeshToonMaterial(); geometry.addGroup( p.faceOffset * 3, p.faceNum * 3, i ); diff --git a/examples/webgl_loader_mmd.html b/examples/webgl_loader_mmd.html index 49225ba99c..aa2383f005 100644 --- a/examples/webgl_loader_mmd.html +++ b/examples/webgl_loader_mmd.html @@ -158,6 +158,27 @@ window.addEventListener( 'resize', onWindowResize, false ); + var phongMaterials; + var originalMaterials; + + function makePhongMaterials ( materials ) { + + var array = []; + + for ( var i = 0, il = materials.length; i < il; i ++ ) { + + var m = new THREE.MeshPhongMaterial(); + m.copy( materials[ i ] ); + m.needsUpdate = true; + + array.push( m ); + + } + + phongMaterials = new THREE.MultiMaterial( array ); + + } + function initGui () { var api = { @@ -178,27 +199,16 @@ gui.add( api, 'gradient mapping' ).onChange( function () { - if ( mesh.userData.gradientMaps === undefined ) mesh.userData.gradientMaps = []; - - var materials = mesh.material.materials; - var gradientMaps = mesh.userData.gradientMaps; - - for ( var i = 0, il = materials.length; i < il; i ++ ) { - - var material = materials[ i ]; - - if ( api[ 'gradient mapping' ] ) { - - material.gradientMap = gradientMaps[ i ]; + if ( originalMaterials === undefined ) originalMaterials = mesh.material; + if ( phongMaterials === undefined ) makePhongMaterials( mesh.material.materials ); - } else { + if ( api[ 'gradient mapping' ] ) { - gradientMaps[ i ] = material.gradientMap; - material.gradientMap = null; + mesh.material = originalMaterials; - } + } else { - material.needsUpdate = true; + mesh.material = phongMaterials; } diff --git a/examples/webgl_materials_variations_toon.html b/examples/webgl_materials_variations_toon.html new file mode 100644 index 0000000000..f77780e958 --- /dev/null +++ b/examples/webgl_materials_variations_toon.html @@ -0,0 +1,239 @@ + + + + three.js webgl - materials + + + + + + +
+
three.js - Toon Material Variantions w/ OutlineEffect by Ben Houston.
+ + + + + + + + + + + + + diff --git a/src/materials/Materials.js b/src/materials/Materials.js index 3ccf676bbd..cc84dfe0ec 100644 --- a/src/materials/Materials.js +++ b/src/materials/Materials.js @@ -7,6 +7,7 @@ export { MultiMaterial } from './MultiMaterial.js'; export { MeshPhysicalMaterial } from './MeshPhysicalMaterial.js'; export { MeshStandardMaterial } from './MeshStandardMaterial.js'; export { MeshPhongMaterial } from './MeshPhongMaterial.js'; +export { MeshToonMaterial } from './MeshToonMaterial.js'; export { MeshNormalMaterial } from './MeshNormalMaterial.js'; export { MeshLambertMaterial } from './MeshLambertMaterial.js'; export { MeshDepthMaterial } from './MeshDepthMaterial.js'; diff --git a/src/materials/MeshPhongMaterial.js b/src/materials/MeshPhongMaterial.js index 542a6731c8..81fe515b25 100644 --- a/src/materials/MeshPhongMaterial.js +++ b/src/materials/MeshPhongMaterial.js @@ -44,8 +44,6 @@ import { Color } from '../math/Color'; * reflectivity: , * refractionRatio: , * - * gradientMap: new THREE.Texture( ), - * * wireframe: , * wireframeLinewidth: , * @@ -96,8 +94,6 @@ function MeshPhongMaterial( parameters ) { this.reflectivity = 1; this.refractionRatio = 0.98; - this.gradientMap = null; - this.wireframe = false; this.wireframeLinewidth = 1; this.wireframeLinecap = 'round'; diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index d59283aae2..beceeedfad 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -623,6 +623,7 @@ function WebGLRenderer( parameters ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.normal ); if ( ! material.isMeshPhongMaterial && + ! material.isMeshToonMaterial && ! material.isMeshStandardMaterial && material.shading === FlatShading ) { @@ -1775,6 +1776,7 @@ function WebGLRenderer( parameters ) { if ( material.isShaderMaterial || material.isMeshPhongMaterial || + material.isMeshToonMaterial || material.isMeshStandardMaterial || material.envMap ) { @@ -1790,6 +1792,7 @@ function WebGLRenderer( parameters ) { } if ( material.isMeshPhongMaterial || + material.isMeshToonMaterial || material.isMeshLambertMaterial || material.isMeshBasicMaterial || material.isMeshStandardMaterial || @@ -1862,6 +1865,7 @@ function WebGLRenderer( parameters ) { if ( material.isMeshBasicMaterial || material.isMeshLambertMaterial || material.isMeshPhongMaterial || + material.isMeshToonMaterial || material.isMeshStandardMaterial || material.isMeshDepthMaterial ) { @@ -1892,6 +1896,10 @@ function WebGLRenderer( parameters ) { refreshUniformsPhong( m_uniforms, material ); + } else if ( material.isMeshToonMaterial ) { + + refreshUniformsToon( m_uniforms, material ); + } else if ( material.isMeshPhysicalMaterial ) { refreshUniformsPhysical( m_uniforms, material ); @@ -2136,6 +2144,12 @@ function WebGLRenderer( parameters ) { } + } + + function refreshUniformsToon( uniforms, material ) { + + refreshUniformsPhong( uniforms, material ); + if ( material.gradientMap ) { uniforms.gradientMap.value = material.gradientMap; diff --git a/src/renderers/shaders/ShaderChunk.js b/src/renderers/shaders/ShaderChunk.js index f3f27c78c9..b36319d1bb 100644 --- a/src/renderers/shaders/ShaderChunk.js +++ b/src/renderers/shaders/ShaderChunk.js @@ -99,6 +99,8 @@ import meshphong_frag from './ShaderLib/meshphong_frag.glsl'; import meshphong_vert from './ShaderLib/meshphong_vert.glsl'; import meshphysical_frag from './ShaderLib/meshphysical_frag.glsl'; import meshphysical_vert from './ShaderLib/meshphysical_vert.glsl'; +import meshtoon_frag from './ShaderLib/meshtoon_frag.glsl'; +import meshtoon_vert from './ShaderLib/meshtoon_vert.glsl'; import normal_frag from './ShaderLib/normal_frag.glsl'; import normal_vert from './ShaderLib/normal_vert.glsl'; import points_frag from './ShaderLib/points_frag.glsl'; @@ -208,6 +210,8 @@ export var ShaderChunk = { meshphong_vert: meshphong_vert, meshphysical_frag: meshphysical_frag, meshphysical_vert: meshphysical_vert, + meshtoon_frag: meshtoon_frag, + meshtoon_vert: meshtoon_vert, normal_frag: normal_frag, normal_vert: normal_vert, points_frag: points_frag, diff --git a/src/renderers/shaders/ShaderChunk/clipping_planes_pars_fragment.glsl b/src/renderers/shaders/ShaderChunk/clipping_planes_pars_fragment.glsl index 3eb44cdade..91679b5828 100644 --- a/src/renderers/shaders/ShaderChunk/clipping_planes_pars_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/clipping_planes_pars_fragment.glsl @@ -1,6 +1,6 @@ #if NUM_CLIPPING_PLANES > 0 - #if ! defined( PHYSICAL ) && ! defined( PHONG ) + #if ! defined( PHYSICAL ) && ! defined( PHONG ) && ! defined( TOON ) varying vec3 vViewPosition; #endif diff --git a/src/renderers/shaders/ShaderChunk/clipping_planes_pars_vertex.glsl b/src/renderers/shaders/ShaderChunk/clipping_planes_pars_vertex.glsl index d83f96d56c..219c502181 100644 --- a/src/renderers/shaders/ShaderChunk/clipping_planes_pars_vertex.glsl +++ b/src/renderers/shaders/ShaderChunk/clipping_planes_pars_vertex.glsl @@ -1,3 +1,3 @@ -#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG ) +#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG ) && ! defined( TOON ) varying vec3 vViewPosition; #endif diff --git a/src/renderers/shaders/ShaderChunk/clipping_planes_vertex.glsl b/src/renderers/shaders/ShaderChunk/clipping_planes_vertex.glsl index d3fa83858e..bbdfb399b5 100644 --- a/src/renderers/shaders/ShaderChunk/clipping_planes_vertex.glsl +++ b/src/renderers/shaders/ShaderChunk/clipping_planes_vertex.glsl @@ -1,4 +1,4 @@ -#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG ) +#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG ) && ! defined( TOON ) vViewPosition = - mvPosition.xyz; #endif diff --git a/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl b/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl index 097196b19b..99de62aa55 100644 --- a/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl @@ -1,6 +1,6 @@ #ifdef USE_ENVMAP - #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) + #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( TOON ) vec3 cameraToVertex = normalize( vWorldPosition - cameraPosition ); diff --git a/src/renderers/shaders/ShaderChunk/envmap_pars_fragment.glsl b/src/renderers/shaders/ShaderChunk/envmap_pars_fragment.glsl index 575800944a..b9950d32cc 100644 --- a/src/renderers/shaders/ShaderChunk/envmap_pars_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/envmap_pars_fragment.glsl @@ -5,7 +5,7 @@ #ifdef USE_ENVMAP - #if ! defined( PHYSICAL ) && ( defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) ) + #if ! defined( PHYSICAL ) && ( defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( TOON ) ) varying vec3 vWorldPosition; #endif @@ -16,7 +16,7 @@ #endif uniform float flipEnvMap; - #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( PHYSICAL ) + #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( TOON ) || defined( PHYSICAL ) uniform float refractionRatio; #else varying vec3 vReflect; diff --git a/src/renderers/shaders/ShaderChunk/envmap_pars_vertex.glsl b/src/renderers/shaders/ShaderChunk/envmap_pars_vertex.glsl index 7feab7532e..9b77fed79c 100644 --- a/src/renderers/shaders/ShaderChunk/envmap_pars_vertex.glsl +++ b/src/renderers/shaders/ShaderChunk/envmap_pars_vertex.glsl @@ -1,6 +1,6 @@ #ifdef USE_ENVMAP - #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) + #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( TOON ) varying vec3 vWorldPosition; #else diff --git a/src/renderers/shaders/ShaderChunk/envmap_vertex.glsl b/src/renderers/shaders/ShaderChunk/envmap_vertex.glsl index ce32d52289..d0fa2cd76d 100644 --- a/src/renderers/shaders/ShaderChunk/envmap_vertex.glsl +++ b/src/renderers/shaders/ShaderChunk/envmap_vertex.glsl @@ -1,6 +1,6 @@ #ifdef USE_ENVMAP - #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) + #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( TOON ) vWorldPosition = worldPosition.xyz; diff --git a/src/renderers/shaders/ShaderChunk/gradientmap_pars_fragment.glsl b/src/renderers/shaders/ShaderChunk/gradientmap_pars_fragment.glsl index aabfe13bce..c8332bae36 100644 --- a/src/renderers/shaders/ShaderChunk/gradientmap_pars_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/gradientmap_pars_fragment.glsl @@ -1,4 +1,4 @@ -#ifdef USE_GRADIENTMAP +#ifdef TOON uniform sampler2D gradientMap; @@ -7,7 +7,18 @@ // 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 + + return texture2D( gradientMap, coord ).rgb; + + #else + + return ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 ); + + #endif + } + #endif diff --git a/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl b/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl index 43b158b385..b0675ede53 100644 --- a/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl @@ -44,7 +44,7 @@ struct BlinnPhongMaterial { void RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) { - #ifdef USE_GRADIENTMAP + #ifdef TOON vec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color; diff --git a/src/renderers/shaders/ShaderChunk/worldpos_vertex.glsl b/src/renderers/shaders/ShaderChunk/worldpos_vertex.glsl index d1db3f9a04..dc29a4e803 100644 --- a/src/renderers/shaders/ShaderChunk/worldpos_vertex.glsl +++ b/src/renderers/shaders/ShaderChunk/worldpos_vertex.glsl @@ -1,4 +1,4 @@ -#if defined( USE_ENVMAP ) || defined( PHONG ) || defined( PHYSICAL ) || defined( LAMBERT ) || defined ( USE_SHADOWMAP ) +#if defined( USE_ENVMAP ) || defined( PHONG ) || defined( TOON ) || defined( PHYSICAL ) || defined( LAMBERT ) || defined ( USE_SHADOWMAP ) #ifdef USE_SKINNING diff --git a/src/renderers/shaders/ShaderLib.js b/src/renderers/shaders/ShaderLib.js index 99d7baf547..2ac9256a03 100644 --- a/src/renderers/shaders/ShaderLib.js +++ b/src/renderers/shaders/ShaderLib.js @@ -54,7 +54,6 @@ var ShaderLib = { UniformsLib.bumpmap, UniformsLib.normalmap, UniformsLib.displacementmap, - UniformsLib.gradientmap, UniformsLib.fog, UniformsLib.lights, { @@ -69,6 +68,31 @@ var ShaderLib = { }, + toon: { + + uniforms: Object.assign( {}, + UniformsLib.common, + 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 + + }, + standard: { uniforms: Object.assign( {}, diff --git a/src/renderers/shaders/ShaderLib/meshphong_frag.glsl b/src/renderers/shaders/ShaderLib/meshphong_frag.glsl index 4b909fc5de..5041e7a5f1 100644 --- a/src/renderers/shaders/ShaderLib/meshphong_frag.glsl +++ b/src/renderers/shaders/ShaderLib/meshphong_frag.glsl @@ -17,7 +17,6 @@ uniform float opacity; #include #include #include -#include #include #include #include diff --git a/src/renderers/webgl/WebGLPrograms.js b/src/renderers/webgl/WebGLPrograms.js index c64d5cfe67..a6ea358315 100644 --- a/src/renderers/webgl/WebGLPrograms.js +++ b/src/renderers/webgl/WebGLPrograms.js @@ -15,6 +15,7 @@ function WebGLPrograms( renderer, capabilities ) { MeshBasicMaterial: 'basic', MeshLambertMaterial: 'lambert', MeshPhongMaterial: 'phong', + MeshToonMaterial: 'toon', MeshStandardMaterial: 'physical', MeshPhysicalMaterial: 'physical', LineBasicMaterial: 'basic', -- GitLab