@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
154 lines (134 loc) • 4.49 kB
JavaScript
import {
ClampToEdgeWrapping,
Color,
FrontSide,
GLSL3,
LinearFilter,
NormalBlending,
ShaderMaterial,
UniformsLib,
UniformsUtils,
Vector2,
Vector4 as ThreeVector4
} from 'three';
import TerrainShader from "../shaders/TerrainShader.js";
import { whitePixelTexture } from "../texture/whitePixelTexture.js";
/**
*
* @param {Vector2} [gridResolution]
* @param {Texture} [splatMap]
* @param {THREE.DataTexture2DArray} [diffuseMaps]
* @param {Texture} [lightMap]
* @return {ShaderMaterial}
* @constructor
*/
export function SplatMaterial(
{
gridResolution,
splatMap,
diffuseMaps,
lightMap
}
) {
const uniforms = UniformsUtils.merge([
UniformsLib.common,
UniformsLib.specularmap,
UniformsLib.envmap,
UniformsLib.aomap,
UniformsLib.lightmap,
UniformsLib.emissivemap,
UniformsLib.fog,
UniformsLib.lights,
{
"splatWeightMap": {
type: "t",
value: null
},
"splatLayerCount": {
type: "f",
value: 4
},
"splatResolution": {
type: 'v2',
value: new Vector2(1, 1)
},
"gridResolution": {
type: "v2",
value: new Vector2(1, 1)
},
uGridTransform: {
type: 'v4',
value: new ThreeVector4()
},
"gridBorderWidth": {
type: "f",
value: 0.1
},
"materialScalesMap": { type: "t", value: null },
"diffuseMaps": { type: "t", value: null },
"diffuseGridOverlayMap": { type: "t", value: null },
"diffuseGridOverlaySprite": { type: "t", value: whitePixelTexture() }
},
{
"emissive": { type: "c", value: new Color(0x000000) },
"specular": { type: "c", value: new Color(0xFFFFFF) },
"shininess": { type: "f", value: 0 },
"envMapIntensity": { value: 1 } // temporary
},
{
"f_CloudsTime": { type: "f", value: 0 },
"f_CloudsAmount": { type: "f", value: 0.9 },
"f_CloudsIntensity": { type: "f", value: 0.3 },
"v_CloudsSpeed_0": { type: "v2", value: new Vector2(0.03, -0.03) },
"v_CloudsSpeed_1": { type: "v2", value: new Vector2(0.011, -0.011) },
"v_CloudsSpeed_2": { type: "v2", value: new Vector2(0.023, -0.023) },
"v_CloudsSize_0": { type: "v2", value: new Vector2(40, 40) },
"v_CloudsSize_1": { type: "v2", value: new Vector2(20, 20) },
"v_CloudsSize_2": { type: "v2", value: new Vector2(10, 10) },
"t_Clouds_0": { type: "t", value: null },
"t_Clouds_1": { type: "t", value: null },
"t_Clouds_2": { type: "t", value: null }
}
]);
if (gridResolution !== undefined) {
uniforms.gridResolution.value.set(gridResolution.x, gridResolution.y);
}
const sm = new ShaderMaterial({
uniforms: uniforms,
vertexShader: TerrainShader.vertexShader,
fragmentShader: TerrainShader.fragmentShader,
side: FrontSide,
blending: NormalBlending,
depthTest: true,
depthWrite: true,
transparent: false,
lights: true,
defines: {
SHADOWMAP_CLOUDS: false,
DIFFUSE_GRAIN: false
},
glslVersion: GLSL3
});
sm.depthWrite = true;
sm.transparent = false;
uniforms.diffuse.value = new Color(0xFFFFFF);
if (splatMap !== void 0) {
//TODO: check power of two
splatMap.wrapS = splatMap.wrapT = ClampToEdgeWrapping;
splatMap.minFilter = LinearFilter;
splatMap.magFilter = LinearFilter;
uniforms.splatMap.value = splatMap;
}
if (diffuseMaps !== void 0) {
uniforms.diffuseMaps.value = diffuseMaps;
}
if (lightMap !== void 0) {
sm.aoMap = true;
uniforms.aoMap.value = lightMap;
uniforms.aoMapIntensity.value = 0.7;
}
sm.extensions.derivatives = true; //needed for rendering grid
sm.needsUpdate = true;
sm.isSplatMaterial = true;
return sm;
}