@openhps/core
Version:
Open Hybrid Positioning System - Core component
115 lines (104 loc) • 4.21 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _LightingNode = _interopRequireDefault(require("./LightingNode.js"));
var _CacheNode = require("../core/CacheNode.js");
var _PropertyNode = require("../core/PropertyNode.js");
var _Camera = require("../accessors/Camera.js");
var _Normal = require("../accessors/Normal.js");
var _Position = require("../accessors/Position.js");
var _TSLBase = require("../tsl/TSLBase.js");
var _AccessorsUtils = require("../accessors/AccessorsUtils.js");
var _PMREMNode = require("../pmrem/PMREMNode.js");
var _MaterialProperties = require("../accessors/MaterialProperties.js");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const _envNodeCache = new WeakMap();
/**
* Represents a physical model for Image-based lighting (IBL). The environment
* is defined via environment maps in the equirectangular, cube map or cubeUV (PMREM) format.
* `EnvironmentNode` is intended for PBR materials like {@link MeshStandardNodeMaterial}.
*
* @augments LightingNode
*/
class EnvironmentNode extends _LightingNode.default {
static get type() {
return 'EnvironmentNode';
}
/**
* Constructs a new environment node.
*
* @param {Node} [envNode=null] - A node representing the environment.
*/
constructor(envNode = null) {
super();
/**
* A node representing the environment.
*
* @type {?Node}
* @default null
*/
this.envNode = envNode;
}
setup(builder) {
const {
material
} = builder;
let envNode = this.envNode;
if (envNode.isTextureNode || envNode.isMaterialReferenceNode) {
const value = envNode.isTextureNode ? envNode.value : material[envNode.property];
let cacheEnvNode = _envNodeCache.get(value);
if (cacheEnvNode === undefined) {
cacheEnvNode = (0, _PMREMNode.pmremTexture)(value);
_envNodeCache.set(value, cacheEnvNode);
}
envNode = cacheEnvNode;
}
//
const useAnisotropy = material.useAnisotropy === true || material.anisotropy > 0;
const radianceNormalView = useAnisotropy ? _AccessorsUtils.transformedBentNormalView : _Normal.transformedNormalView;
const radiance = envNode.context(createRadianceContext(_PropertyNode.roughness, radianceNormalView)).mul(_MaterialProperties.materialEnvIntensity);
const irradiance = envNode.context(createIrradianceContext(_Normal.transformedNormalWorld)).mul(Math.PI).mul(_MaterialProperties.materialEnvIntensity);
const isolateRadiance = (0, _CacheNode.cache)(radiance);
const isolateIrradiance = (0, _CacheNode.cache)(irradiance);
//
builder.context.radiance.addAssign(isolateRadiance);
builder.context.iblIrradiance.addAssign(isolateIrradiance);
//
const clearcoatRadiance = builder.context.lightingModel.clearcoatRadiance;
if (clearcoatRadiance) {
const clearcoatRadianceContext = envNode.context(createRadianceContext(_PropertyNode.clearcoatRoughness, _Normal.transformedClearcoatNormalView)).mul(_MaterialProperties.materialEnvIntensity);
const isolateClearcoatRadiance = (0, _CacheNode.cache)(clearcoatRadianceContext);
clearcoatRadiance.addAssign(isolateClearcoatRadiance);
}
}
}
var _default = exports.default = EnvironmentNode;
const createRadianceContext = (roughnessNode, normalViewNode) => {
let reflectVec = null;
return {
getUV: () => {
if (reflectVec === null) {
reflectVec = _Position.positionViewDirection.negate().reflect(normalViewNode);
// Mixing the reflection with the normal is more accurate and keeps rough objects from gathering light from behind their tangent plane.
reflectVec = roughnessNode.mul(roughnessNode).mix(reflectVec, normalViewNode).normalize();
reflectVec = reflectVec.transformDirection(_Camera.cameraViewMatrix);
}
return reflectVec;
},
getTextureLevel: () => {
return roughnessNode;
}
};
};
const createIrradianceContext = normalWorldNode => {
return {
getUV: () => {
return normalWorldNode;
},
getTextureLevel: () => {
return (0, _TSLBase.float)(1.0);
}
};
};