@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
150 lines (144 loc) • 5.94 kB
text/typescript
import {PerspectiveCamera} from 'three';
import {PhysicalCamera, ShapedAreaLight, PhysicalSpotLight, IESLoader} from './three-gpu-pathtracer';
import {PathTracingRendererRopNode} from '../../../engine/nodes/rop/PathTracingRenderer';
import {PolyEngine} from '../../../engine/Poly';
import {ViewerCallbackOptions} from '../../../engine/poly/registers/cameras/PolyCamerasRegister';
import {PathTracingViewer} from '../../../engine/viewers/PathTracingViewer';
import {ThreejsViewer} from '../../../engine/viewers/Threejs';
import {CoreCameraRendererController} from '../../camera/CoreCameraRendererController';
import {CoreCameraPerspectiveFrameMode} from '../../camera/frameMode/CoreCameraPerspectiveFrameMode';
import {monkeyPatchSpotLight} from '../../monkeyPatch/SpotLight';
import {
CoreSceneObjectsFactory,
GeneratorName,
PerspectiveCameraOptions,
PerspectiveCameraUpdateOptions,
PerspectiveCameraUpdate,
AreaLightOptions,
SpotLightUpdateOptions,
SpotLightUpdate,
} from '../../CoreSceneObjectsFactory';
import {IES_PROFILE_LM_63_1995} from '../../lights/spotlight/ies/lm_63_1995';
import {ObjectType, registerObjectType} from '../../geometry/Constant';
// type PhysicalSpotLightUpdateOptions = SpotLightUpdateOptions<PhysicalSpotLight>
const PHYSICAL_CAMERA_UPDATE: PerspectiveCameraUpdate<PhysicalCamera> = (
options: PerspectiveCameraUpdateOptions<PhysicalCamera>
) => {
const {camera, params} = options;
const {apertureBlades, fStop, focusDistance, apertureRotation, anamorphicRatio} = params;
camera.apertureBlades = apertureBlades;
camera.fStop = fStop;
camera.focusDistance = focusDistance;
camera.apertureRotation = apertureRotation;
camera.anamorphicRatio = anamorphicRatio;
};
const PHYSICAL_SPOT_LIGHT_UPDATE: SpotLightUpdate<PhysicalSpotLight> = (
options: SpotLightUpdateOptions<PhysicalSpotLight>
) => {
const {spotLight} = options;
spotLight.iesTexture = new IESLoader().parse(IES_PROFILE_LM_63_1995);
};
export function onPBRModuleRegister(poly: PolyEngine) {
CoreSceneObjectsFactory.registerGenerator(GeneratorName.PERSPECTIVE_CAMERA, (options: PerspectiveCameraOptions) => {
const {fov, aspect, near, far} = options;
// we also register PerspectiveCamera here,
// as otherwise, cameras created by other objects, like the CubeCamera,
// only appear as Object3D in the scene tree
registerObjectType({
type: ObjectType.PERSPECTIVE_CAMERA,
checkFunc: (o) => {
if ((o as PerspectiveCamera).isPerspectiveCamera) {
return ObjectType.PERSPECTIVE_CAMERA;
}
},
ctor: PerspectiveCamera,
humanName: 'PerspectiveCamera',
});
registerObjectType({
type: ObjectType.PHYSICAL_CAMERA,
checkFunc: (o) => {
if ((o as PhysicalCamera).bokehSize != null) {
return ObjectType.PHYSICAL_CAMERA;
}
},
ctor: PhysicalCamera,
humanName: 'PhysicalCamera',
});
return new PhysicalCamera(fov, aspect, near, far);
});
CoreSceneObjectsFactory.registerGenerator(GeneratorName.PERSPECTIVE_CAMERA_UPDATE, PHYSICAL_CAMERA_UPDATE as any);
CoreSceneObjectsFactory.registerGenerator(GeneratorName.AREA_LIGHT, (options: AreaLightOptions) => {
const {color, intensity, width, height} = options;
registerObjectType({
type: ObjectType.AREA_LIGHT,
checkFunc: (o) => {
if ((o as ShapedAreaLight).isCircular) {
return ObjectType.SHAPED_AREA_LIGHT;
}
},
ctor: ShapedAreaLight,
humanName: 'ShapedAreaLight',
});
return new ShapedAreaLight(color, intensity, width, height);
});
CoreSceneObjectsFactory.registerGenerator(GeneratorName.SPOT_LIGHT, () => {
registerObjectType({
type: ObjectType.PHYSICAL_SPOT_LIGHT,
checkFunc: (o) => {
if ((o as PhysicalSpotLight).iesTexture) {
return ObjectType.PHYSICAL_SPOT_LIGHT;
}
},
ctor: PhysicalSpotLight,
humanName: ObjectType.PHYSICAL_SPOT_LIGHT,
});
const physicalSpotLight = new PhysicalSpotLight();
monkeyPatchSpotLight(physicalSpotLight);
return physicalSpotLight;
});
CoreSceneObjectsFactory.registerGenerator(GeneratorName.SPOT_LIGHT_UPDATE, PHYSICAL_SPOT_LIGHT_UPDATE as any);
poly.registerCamera<PhysicalCamera | PerspectiveCamera>(
PhysicalCamera,
(options: ViewerCallbackOptions<PhysicalCamera | PerspectiveCamera>) => {
const {camera, scene, canvas} = options;
// calling .rendererNode() is preferred to
// .rendererConfig() as this would create the renderer
// which in some conditions leads to 2 renderers being created
// (one now, and one in the viewwer).
// And this can create issues as an env map may pick up the first renderer
// and therefore not be available in the second renderer.
const rendererNode = canvas
? CoreCameraRendererController.rendererNode({
camera,
scene,
})
: undefined;
if (rendererNode instanceof PathTracingRendererRopNode) {
const viewer = new PathTracingViewer<PhysicalCamera>({
...options,
updateCameraAspect: (aspect, resolution) => {
CoreCameraPerspectiveFrameMode.updateCameraAspect(options.camera, aspect, {resolution});
},
});
return viewer;
} else {
const viewer = new ThreejsViewer<PerspectiveCamera>({
...options,
updateCameraAspect: (aspect, resolution) => {
CoreCameraPerspectiveFrameMode.updateCameraAspect(options.camera, aspect, {resolution});
},
});
return viewer;
}
}
);
// CoreSceneObjectsFactory.generators.perspectiveCamera = (fov, aspect, near, far) =>
// new PhysicalCamera(fov, aspect, near, far);
// CoreSceneObjectsFactory.generators.areaLight = (color, intensity, width, height) =>
// new ShapedAreaLight(color, intensity, width, height);
// CoreSceneObjectsFactory.generators.spotLight = () => new PhysicalSpotLight();
// CoreSceneObjectsFactory.generators.spotLightUpdate = (options:SpotLightUpdateOptions<SpotLight>) => {
// const {spotLight}=options
// spotLight.iesTexture = new IESLoader().parse(IES_PROFILE_LM_63_1995);
// };
}