mirror of
https://github.com/Doodle3D/Doodle3D-Core.git
synced 2025-01-04 17:03:49 +01:00
use matcap material
This commit is contained in:
parent
9701bf0aa0
commit
4e37a4c4cf
BIN
img/matcap.png
Normal file
BIN
img/matcap.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 50 KiB |
29
shaders/matcap_frag.glsl
Normal file
29
shaders/matcap_frag.glsl
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
uniform float opacity;
|
||||||
|
uniform sampler2D tMatcap;
|
||||||
|
uniform vec3 color;
|
||||||
|
varying vec2 vNormal;
|
||||||
|
|
||||||
|
// color blending from https://www.w3.org/TR/compositing-1/#blendingcolor
|
||||||
|
float lum(vec3 c) {
|
||||||
|
return c.r * .3 + c.g * .59 + c.b * .11;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 clipColor(vec3 c) {
|
||||||
|
float l = lum(c);
|
||||||
|
float n = min(min(c.r, c.g), c.b);
|
||||||
|
float x = max(max(c.r, c.g), c.b);
|
||||||
|
if (n < 0.) c = l + (((c - l) * l) / (l - n));
|
||||||
|
if (x > 1.) c = l + (((c - l) * (1. - l)) / (x - l));
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 setLum(vec3 c, float l) {
|
||||||
|
float d = l - lum(c);
|
||||||
|
return clipColor(c + d);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 matcap = texture2D(tMatcap, vNormal);
|
||||||
|
vec3 coloredMatcap = setLum(color, lum(matcap.rgb));
|
||||||
|
gl_FragColor = vec4(coloredMatcap, opacity);
|
||||||
|
}
|
8
shaders/matcap_vert.glsl
Normal file
8
shaders/matcap_vert.glsl
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
varying vec2 vNormal;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vNormal = normalize(normalMatrix * normal).xy / 2. + .5;
|
||||||
|
|
||||||
|
#include <begin_vertex>
|
||||||
|
#include <project_vertex>
|
||||||
|
}
|
@ -20,6 +20,7 @@ import RenderChain from '../d3/RenderChain';
|
|||||||
import BaseTransformer from '../d3/transformers/BaseTransformer.js';
|
import BaseTransformer from '../d3/transformers/BaseTransformer.js';
|
||||||
import Camera from '../d3/Camera.js';
|
import Camera from '../d3/Camera.js';
|
||||||
import ReactResizeDetector from 'react-resize-detector';
|
import ReactResizeDetector from 'react-resize-detector';
|
||||||
|
import { load as loadMatcapMaterial } from '../d3/MatcapMaterial.js';
|
||||||
// import createDebug from 'debug';
|
// import createDebug from 'debug';
|
||||||
// const debug = createDebug('d3d:d3');
|
// const debug = createDebug('d3d:d3');
|
||||||
|
|
||||||
@ -74,6 +75,7 @@ class D3Panel extends React.Component {
|
|||||||
plane: this.plane
|
plane: this.plane
|
||||||
});
|
});
|
||||||
|
|
||||||
|
loadMatcapMaterial.then(this.renderRequest);
|
||||||
this.DOM = null;
|
this.DOM = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,7 +119,7 @@ class D3Panel extends React.Component {
|
|||||||
const ambientLight = new THREE.AmbientLight(0x505050);
|
const ambientLight = new THREE.AmbientLight(0x505050);
|
||||||
this.scene.add(ambientLight);
|
this.scene.add(ambientLight);
|
||||||
|
|
||||||
this.shapesManager = new ShapesManager({ toonShader: hasExtensionsFor.toonShaderPreview });
|
this.shapesManager = new ShapesManager();
|
||||||
|
|
||||||
this.UIContainer = new EventObject3D();
|
this.UIContainer = new EventObject3D();
|
||||||
this.UIContainer.matrixAutoUpdate = false;
|
this.UIContainer.matrixAutoUpdate = false;
|
||||||
|
@ -8,6 +8,7 @@ import createScene from '../d3/createScene.js';
|
|||||||
import injectSheet from 'react-jss';
|
import injectSheet from 'react-jss';
|
||||||
import ReactResizeDetector from 'react-resize-detector';
|
import ReactResizeDetector from 'react-resize-detector';
|
||||||
import requestAnimationFrame from 'raf';
|
import requestAnimationFrame from 'raf';
|
||||||
|
import { load as loadMatcapMaterial } from '../d3/MatcapMaterial.js';
|
||||||
|
|
||||||
const styles = {
|
const styles = {
|
||||||
container: {
|
container: {
|
||||||
@ -55,7 +56,9 @@ class DoodlePreview extends React.Component {
|
|||||||
this.setState(scene);
|
this.setState(scene);
|
||||||
|
|
||||||
this.editorControls = new THREE.EditorControls(scene.camera, canvas);
|
this.editorControls = new THREE.EditorControls(scene.camera, canvas);
|
||||||
this.editorControls.addEventListener('change', () => scene.render());
|
this.editorControls.addEventListener('change', scene.render);
|
||||||
|
|
||||||
|
loadMatcapMaterial.then(scene.render;
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
|
44
src/d3/MatcapMaterial.js
vendored
Normal file
44
src/d3/MatcapMaterial.js
vendored
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import * as THREE from 'three';
|
||||||
|
import matcapVert from '../../shaders/matcap_vert.glsl';
|
||||||
|
import matcapFrag from '../../shaders/matcap_frag.glsl';
|
||||||
|
import matcapURL from '../../img/matcap.png';
|
||||||
|
|
||||||
|
let matcapTexture;
|
||||||
|
export const load = new Promise((resolve, reject) => {
|
||||||
|
matcapTexture = new THREE.TextureLoader().load(matcapURL, resolve, () => {}, reject);
|
||||||
|
});
|
||||||
|
|
||||||
|
export default class MatcapMaterial extends THREE.ShaderMaterial {
|
||||||
|
constructor({ color = new THREE.Color(), opacity = 1 }) {
|
||||||
|
super({
|
||||||
|
uniforms: {
|
||||||
|
"opacity": { type: 'f', value: opacity },
|
||||||
|
"tMatcap": { type: 't', value: matcapTexture },
|
||||||
|
"color": { type: 'vec3', value: new THREE.Vector3() }
|
||||||
|
},
|
||||||
|
vertexShader: matcapVert,
|
||||||
|
fragmentShader: matcapFrag
|
||||||
|
});
|
||||||
|
|
||||||
|
this.color = color;
|
||||||
|
this.side = THREE.DoubleSide;
|
||||||
|
}
|
||||||
|
|
||||||
|
set color(color) {
|
||||||
|
this.uniforms.color.value.fromArray(color.toArray());
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
get color() {
|
||||||
|
return new THREE.Color().fromArray(this.uniforms.color.value.toArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
set opacity(opacity) {
|
||||||
|
if (!this.uniforms) return opacity;
|
||||||
|
return this.uniforms.opacity.value = opacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
clone() {
|
||||||
|
return new MatcapMaterial({ color: this.color, opacity: this.uniforms.opacity.value });
|
||||||
|
}
|
||||||
|
}
|
22
src/d3/ShapeMesh.js
vendored
22
src/d3/ShapeMesh.js
vendored
@ -3,6 +3,7 @@ import { applyMatrixOnPath } from '../utils/vectorUtils.js';
|
|||||||
import { shapeToPointsCornered } from '../shape/shapeToPoints.js';
|
import { shapeToPointsCornered } from '../shape/shapeToPoints.js';
|
||||||
import * as THREE from 'three';
|
import * as THREE from 'three';
|
||||||
import { getPointsBounds, shapeChanged } from '../shape/shapeDataUtils.js';
|
import { getPointsBounds, shapeChanged } from '../shape/shapeDataUtils.js';
|
||||||
|
import MatcapMaterial from './MatcapMaterial.js';
|
||||||
import { DESELECT_TRANSPARENCY, LEGACY_HEIGHT_STEP } from '../constants/d3Constants.js';
|
import { DESELECT_TRANSPARENCY, LEGACY_HEIGHT_STEP } from '../constants/d3Constants.js';
|
||||||
import ThreeBSP from 'three-js-csg';
|
import ThreeBSP from 'three-js-csg';
|
||||||
|
|
||||||
@ -16,32 +17,18 @@ const MAX_HEIGHT_BASE = 5;
|
|||||||
const isValidNumber = (num) => typeof num === 'number' && !isNaN(num);
|
const isValidNumber = (num) => typeof num === 'number' && !isNaN(num);
|
||||||
|
|
||||||
class ShapeMesh extends THREE.Object3D {
|
class ShapeMesh extends THREE.Object3D {
|
||||||
constructor(shapeData, active, toonShader) {
|
constructor(shapeData, active) {
|
||||||
super();
|
super();
|
||||||
this.name = shapeData.UID;
|
this.name = shapeData.UID;
|
||||||
|
|
||||||
const { sculpt, rotate, twist, height, type, transform, z, color, fill, solid } = shapeData;
|
const { sculpt, rotate, twist, height, type, transform, z, color, fill, solid } = shapeData;
|
||||||
|
|
||||||
let material;
|
const material = new MatcapMaterial({ color: new THREE.Color(color) });
|
||||||
if (toonShader) {
|
|
||||||
material = new THREE.MeshToonMaterial({
|
|
||||||
color: new THREE.Color(color),
|
|
||||||
shading: THREE.SmoothShading,
|
|
||||||
side: THREE.DoubleSide
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
material = new THREE.MeshLambertMaterial({
|
|
||||||
color: new THREE.Color(color),
|
|
||||||
side: THREE.DoubleSide
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this._mesh = new THREE.Mesh(new THREE.BufferGeometry(), material.clone());
|
this._mesh = new THREE.Mesh(new THREE.BufferGeometry(), material.clone());
|
||||||
this._mesh.name = shapeData.UID;
|
this._mesh.name = shapeData.UID;
|
||||||
this._mesh.isShapeMesh = true;
|
this._mesh.isShapeMesh = true;
|
||||||
|
|
||||||
this._toonShader = toonShader;
|
|
||||||
|
|
||||||
this._shapes = [];
|
this._shapes = [];
|
||||||
this._shapesMap = [];
|
this._shapesMap = [];
|
||||||
|
|
||||||
@ -221,7 +208,8 @@ class ShapeMesh extends THREE.Object3D {
|
|||||||
throw new Error(`Cannot update object ${this.name}: color is an invalid value.`);
|
throw new Error(`Cannot update object ${this.name}: color is an invalid value.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._holeMesh.material.color.setHex(color);
|
this._mesh.material.color = new THREE.Color(color);
|
||||||
|
this._holeMesh.material.color = new THREE.Color(color);
|
||||||
this._color = color;
|
this._color = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
6
src/d3/ShapesManager.js
vendored
6
src/d3/ShapesManager.js
vendored
@ -7,11 +7,9 @@ import ThreeBSP from 'three-js-csg';
|
|||||||
const THREE_BSP = ThreeBSP(THREE);
|
const THREE_BSP = ThreeBSP(THREE);
|
||||||
|
|
||||||
export default class ShapesManager extends THREE.Object3D {
|
export default class ShapesManager extends THREE.Object3D {
|
||||||
constructor({ toonShader }) {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this._toonShader = toonShader;
|
|
||||||
|
|
||||||
this._meshes = {};
|
this._meshes = {};
|
||||||
this._spaces = {};
|
this._spaces = {};
|
||||||
this.name = 'shapes-manager';
|
this.name = 'shapes-manager';
|
||||||
@ -137,7 +135,7 @@ export default class ShapesManager extends THREE.Object3D {
|
|||||||
_handleShapeAdded(shapeData, active) {
|
_handleShapeAdded(shapeData, active) {
|
||||||
if (!SHAPE_TYPE_PROPERTIES[shapeData.type].D3Visible) return;
|
if (!SHAPE_TYPE_PROPERTIES[shapeData.type].D3Visible) return;
|
||||||
const { space } = shapeData;
|
const { space } = shapeData;
|
||||||
const mesh = new ShapeMesh(shapeData, active, this._toonShader);
|
const mesh = new ShapeMesh(shapeData, active);
|
||||||
this._meshes[shapeData.UID] = { mesh, space };
|
this._meshes[shapeData.UID] = { mesh, space };
|
||||||
|
|
||||||
this._spaces[space].add(mesh);
|
this._spaces[space].add(mesh);
|
||||||
|
Loading…
Reference in New Issue
Block a user