@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
80 lines (72 loc) • 2.35 kB
text/typescript
/**
* Creates a Sky Material
*
* @remarks
*
* For best result, assign this material to a very large box.
*
*/
import {ShaderMaterial} from 'three';
import {PrimitiveMatNode} from './_Base';
import {Vector3} from 'three';
import {Sky} from 'three/examples/jsm/objects/Sky';
import {MatType} from '../../poly/registers/nodes/types/Mat';
interface ShaderMaterialWithSkyUniforms extends ShaderMaterial {
uniforms: {
turbidity: {value: number};
rayleigh: {value: number};
mieCoefficient: {value: number};
mieDirectionalG: {value: number};
sunPosition: {value: Vector3};
up: {value: Vector3};
};
}
import {ParamConfig, NodeParamsConfig} from '../utils/params/ParamsConfig';
class SkyMatParamsConfig extends NodeParamsConfig {
/** @param turbidity */
turbidity = ParamConfig.FLOAT(2, {
range: [0, 20],
});
/** @param rayleigh */
rayleigh = ParamConfig.FLOAT(1, {
range: [0, 4],
});
/** @param mieCoefficient */
mieCoefficient = ParamConfig.FLOAT(0.005);
/** @param mieDirectional */
mieDirectional = ParamConfig.FLOAT(0.8);
/** @param inclination */
inclination = ParamConfig.FLOAT(0.5);
/** @param azimuth */
azimuth = ParamConfig.FLOAT(0.25);
/** @param up */
up = ParamConfig.VECTOR3([0, 1, 0]);
}
const ParamsConfig = new SkyMatParamsConfig();
export class SkyMatNode extends PrimitiveMatNode<ShaderMaterialWithSkyUniforms, SkyMatParamsConfig> {
override paramsConfig = ParamsConfig;
static override type() {
return MatType.SKY;
}
override createMaterial() {
const object = new Sky();
const mat = object.material as ShaderMaterialWithSkyUniforms;
mat.depthWrite = true;
return mat;
}
override async cook() {
this._material = this._material || this.createMaterial();
const uniforms = this._material.uniforms;
uniforms.turbidity.value = this.pv.turbidity;
uniforms.rayleigh.value = this.pv.rayleigh;
uniforms.mieCoefficient.value = this.pv.mieCoefficient;
uniforms.mieDirectionalG.value = this.pv.mieDirectional;
uniforms.up.value.copy(this.pv.up);
const theta = Math.PI * (this.pv.inclination - 0.5);
const phi = 2 * Math.PI * (this.pv.azimuth - 0.5);
uniforms.sunPosition.value.x = Math.cos(phi);
uniforms.sunPosition.value.y = Math.sin(phi) * Math.sin(theta);
uniforms.sunPosition.value.z = Math.sin(phi) * Math.cos(theta);
this.setMaterial(this._material);
}
}