@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
184 lines (172 loc) • 6.24 kB
text/typescript
// common
import COMMON_GET_UV from '../glsl/common/getUV.glsl';
import COMMON_PACK_POSITION from '../glsl/common/packPosition.glsl';
import COMMON_UNPACK_POSITION from '../glsl/common/unpackPosition.glsl';
// main
import THROUGH_VERT from '../glsl/through.vert.glsl';
import CORE_THROUGH_FRAG from '../glsl/through.frag.glsl';
import CORE_CONTRAINTS_FRAG from '../glsl/constraints.frag.glsl';
// import CORE_INTEGRATE_FRAG from '../glsl/integrate.frag.glsl';
import CORE_MOUSE_FRAG from '../glsl/mouse.frag.glsl';
import CORE_NORMALS_FRAG from '../glsl/normals.frag.glsl';
const LINE_BREAK = '\n';
const ADD_COMMON_LINE = '// *** ADD COMMON ***';
function _addCommon(core: string, commonFunctions: string[]) {
const common = commonFunctions.join(LINE_BREAK);
return core.replace(ADD_COMMON_LINE, common);
}
const THROUGH_FRAG = _addCommon(CORE_THROUGH_FRAG, [COMMON_UNPACK_POSITION]);
const CONTRAINTS_FRAG = _addCommon(CORE_CONTRAINTS_FRAG, [COMMON_GET_UV, COMMON_PACK_POSITION, COMMON_UNPACK_POSITION]);
// const INTEGRATE_FRAG = _addCommon(CORE_INTEGRATE_FRAG, [COMMON_UNPACK_POSITION]);
const MOUSE_FRAG = _addCommon(CORE_MOUSE_FRAG, [COMMON_GET_UV, COMMON_PACK_POSITION, COMMON_UNPACK_POSITION]);
const NORMALS_FRAG = _addCommon(CORE_NORMALS_FRAG, [COMMON_GET_UV, COMMON_PACK_POSITION, COMMON_UNPACK_POSITION]);
import {RawShaderMaterial, Vector2, Vector3, IUniform} from 'three';
import {ClothController} from '../ClothController';
import {IUniformN, IUniformV2, IUniformTexture, IUniformV3} from '../../../engine/nodes/utils/code/gl/Uniforms';
type RawMaterialUniforms = {[uniform: string]: IUniform};
interface CopyUniforms extends RawMaterialUniforms {
order: IUniformN;
tSize: IUniformV2;
texture: IUniformTexture;
}
interface IntegrationUniforms extends RawMaterialUniforms {
timeDelta: IUniformN;
time: IUniformN;
viscosity: IUniformN;
spring: IUniformN;
tSize: IUniformV2;
order: IUniformN;
tOriginal: IUniformTexture;
tPrevious0: IUniformTexture;
tPrevious1: IUniformTexture;
tPosition0: IUniformTexture;
tPosition1: IUniformTexture;
tViscositySpring: IUniformTexture;
}
interface MouseUniforms extends RawMaterialUniforms {
time: IUniformN;
vertex: IUniformN;
coordinates: IUniformV3;
order: IUniformN;
tSize: IUniformV2;
tOriginal: IUniformTexture;
tPosition0: IUniformTexture;
tPosition1: IUniformTexture;
}
interface ConstraintsUniforms extends RawMaterialUniforms {
time: IUniformN;
tSize: IUniformV2;
order: IUniformN;
constraintInfluence: IUniformN;
tPosition0: IUniformTexture;
tPosition1: IUniformTexture;
tAdjacentsA: IUniformTexture;
tAdjacentsB: IUniformTexture;
tDistancesA: IUniformTexture;
tDistancesB: IUniformTexture;
secondaryMotionMult: IUniformN;
}
interface NormalsUniforms extends RawMaterialUniforms {
tSize: IUniformV2;
tPosition0: IUniformTexture;
tPosition1: IUniformTexture;
tAdjacentsA: IUniformTexture;
tAdjacentsB: IUniformTexture;
}
interface CopyMaterial extends RawShaderMaterial {
uniforms: CopyUniforms;
}
interface IntegrationMaterial extends RawShaderMaterial {
uniforms: IntegrationUniforms;
}
interface MouseMaterial extends RawShaderMaterial {
uniforms: MouseUniforms;
}
interface ConstraintsMaterial extends RawShaderMaterial {
uniforms: ConstraintsUniforms;
}
interface NormalsMaterial extends RawShaderMaterial {
uniforms: NormalsUniforms;
}
function createRawMaterial() {
return new RawShaderMaterial({
uniforms: {
order: {value: null},
tSize: {value: new Vector2()},
texture: {value: null},
},
vertexShader: THROUGH_VERT,
fragmentShader: THROUGH_FRAG,
fog: false,
lights: false,
depthWrite: false,
depthTest: false,
});
}
export class ClothMaterialController {
// copyToRenderTarget
public readonly copyShader: CopyMaterial = createRawMaterial() as CopyMaterial;
// forward-integration
public readonly integrateShader: IntegrationMaterial = createRawMaterial() as IntegrationMaterial;
// mouse displacement
public readonly mouseShader: MouseMaterial = createRawMaterial() as MouseMaterial;
// vertices relaxation
public readonly constraintsShader: ConstraintsMaterial = createRawMaterial() as ConstraintsMaterial;
// calculate normals
public readonly normalsShader: NormalsMaterial = createRawMaterial() as NormalsMaterial;
constructor(public readonly mainController: ClothController) {
const integrationFragmentShader = this.mainController.integrationFragmentShader();
if (!integrationFragmentShader) {
throw 'no integrationFragmentShader';
}
this.integrateShader.fragmentShader = _addCommon(integrationFragmentShader, [COMMON_UNPACK_POSITION]);
this.integrateShader.uniforms = {
timeDelta: this.mainController.scene.timeController.timeDeltaUniform(),
time: this.mainController.scene.timeController.timeUniform(),
viscosity: {value: 0.1},
spring: {value: 1},
tSize: {value: new Vector2()},
order: {value: -1},
tOriginal: {value: null},
tPrevious0: {value: null},
tPrevious1: {value: null},
tPosition0: {value: null},
tPosition1: {value: null},
tViscositySpring: {value: null},
};
this.mainController.addMaterialUniforms(this.integrateShader);
this.mouseShader.fragmentShader = MOUSE_FRAG;
this.mouseShader.uniforms = {
time: this.mainController.scene.timeController.timeUniform(),
vertex: {value: -1},
coordinates: {value: new Vector3()},
order: {value: -1},
tSize: {value: new Vector2()},
tOriginal: {value: null},
tPosition0: {value: null},
tPosition1: {value: null},
};
this.constraintsShader.fragmentShader = CONTRAINTS_FRAG;
this.constraintsShader.uniforms = {
time: this.mainController.scene.timeController.timeUniform(),
tSize: {value: new Vector2()},
order: {value: -1},
constraintInfluence: {value: 0},
tPosition0: {value: null},
tPosition1: {value: null},
tAdjacentsA: {value: null},
tAdjacentsB: {value: null},
tDistancesA: {value: null},
tDistancesB: {value: null},
secondaryMotionMult: {value: 0},
};
this.normalsShader.fragmentShader = NORMALS_FRAG;
this.normalsShader.uniforms = {
tSize: {value: new Vector2()},
tPosition0: {value: null},
tPosition1: {value: null},
tAdjacentsA: {value: null},
tAdjacentsB: {value: null},
};
}
}