@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
147 lines (118 loc) • 4.79 kB
JavaScript
import { GLSL3, ShaderMaterial, UniformsUtils, Vector2 } from "three";
import { fp_build_fragment_shader } from "./fp_build_fragment_shader.js";
import { fp_build_vertex_shader } from "./fp_build_vertex_shader.js";
export class ForwardPlusThreeMaterial extends ShaderMaterial {
constructor({ uniforms, fragmentShader, vertexShader }) {
const _uniforms = UniformsUtils.merge([
uniforms,
{
fp_t_light_tiles: {
type: 't',
value: null
},
fp_t_light_lookup: {
type: 't',
value: null
},
fp_t_light_data: {
type: 't',
value: null
},
fp_t_decal_atlas: {
type: 't',
value: null
},
fp_f_camera_near: {
type: 'f',
value: 0
},
fp_f_camera_far: {
type: 'f',
value: 0
},
fp_resolution: {
type: 'v2',
value: new Vector2()
}
}]);
super({
uniforms: _uniforms,
lights: true,
vertexShader: fp_build_vertex_shader(vertexShader),
fragmentShader: fp_build_fragment_shader(fragmentShader),
glslVersion: GLSL3
});
this.__fragment_shader = fragmentShader;
this.__vertex_shader = vertexShader;
// this.onBeforeCompile = console.warn;
}
/**
*
* @param {MeshStandardMaterial} material
*/
copy_basic(material) {
this.alphaTest = material.alphaTest;
this.blendDst = material.blendDst;
this.blendDstAlpha = material.blendDstAlpha;
this.blendEquation = material.blendEquation;
this.blendEquationAlpha = material.blendEquationAlpha;
this.blending = material.blending;
this.blendSrc = material.blendSrc;
this.blendSrcAlpha = material.blendSrcAlpha;
this.clippingPlanes = material.clippingPlanes;
this.clipShadows = material.clipShadows;
this.colorWrite = material.colorWrite;
this.depthFunc = material.depthFunc;
this.depthTest = material.depthTest;
this.depthWrite = material.depthWrite;
this.fog = material.fog;
this.stencilWrite = material.stencilWrite;
this.stencilFunc = material.stencilFunc;
this.stencilRef = material.stencilRef;
this.stencilWriteMask = material.stencilWriteMask;
this.stencilFuncMask = material.stencilFuncMask;
this.stencilFail = material.stencilFail;
this.stencilZFail = material.stencilZFail;
this.stencilZPass = material.stencilZPass;
this.name = `FP#${material.name}`;
this.opacity = material.opacity;
this.polygonOffset = material.polygonOffset;
this.polygonOffsetFactor = material.polygonOffsetFactor;
this.polygonOffsetUnits = material.polygonOffsetUnits;
this.precision = material.precision;
this.premultipliedAlpha = material.premultipliedAlpha;
this.dithering = material.dithering;
this.flatShading = material.flatShading;
this.side = material.side;
this.shadowSide = material.shadowSide;
this.toneMapped = material.toneMapped;
this.transparent = material.transparent;
this.vertexColors = material.vertexColors;
this.visible = material.visible;
// TODO consider cloning user data
this.userData = material.userData;
// copy defines
for (const definesKey in material.defines) {
this.defines[definesKey] = material.defines[definesKey];
}
if (material.color !== undefined) {
this.uniforms.diffuse.value.copy(material.color);
}
//
this.lights = true;
this.skinning = material.skinning;
// request material update
this.needsUpdate = true;
}
/**
*
* @param {LightManager} light_manager
*/
attach_lights(light_manager) {
const uniforms = this.uniforms;
uniforms['fp_t_light_tiles'].value = light_manager.getTextureClusters();
uniforms['fp_t_light_lookup'].value = light_manager.getTextureLookup();
uniforms['fp_t_light_data'].value = light_manager.getTextureData();
uniforms['fp_t_decal_atlas'].value = light_manager.getTextureDecalAtlas();
}
}