Favivon - Correção

This commit is contained in:
2026-05-30 19:59:39 -03:00
parent 76ddaa815d
commit d7dfd221f0
32859 changed files with 5459654 additions and 404 deletions
+425
View File
@@ -0,0 +1,425 @@
"use strict";
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const THREE = require("three");
const ID_ATTR_NAME = "_batch_id_";
const _identityMatrix = /* @__PURE__ */ new THREE.Matrix4();
const _zeroScaleMatrix = /* @__PURE__ */ (() => new THREE.Matrix4().set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1))();
const batchingParsVertex = (
/* glsl */
`
#ifdef BATCHING
attribute float ${ID_ATTR_NAME};
uniform highp sampler2D batchingTexture;
mat4 getBatchingMatrix( const in float i ) {
int size = textureSize( batchingTexture, 0 ).x;
int j = int( i ) * 4;
int x = j % size;
int y = j / size;
vec4 v1 = texelFetch( batchingTexture, ivec2( x, y ), 0 );
vec4 v2 = texelFetch( batchingTexture, ivec2( x + 1, y ), 0 );
vec4 v3 = texelFetch( batchingTexture, ivec2( x + 2, y ), 0 );
vec4 v4 = texelFetch( batchingTexture, ivec2( x + 3, y ), 0 );
return mat4( v1, v2, v3, v4 );
}
#endif
`
);
const batchingbaseVertex = (
/* glsl */
`
#ifdef BATCHING
mat4 batchingMatrix = getBatchingMatrix( ${ID_ATTR_NAME} );
#endif
`
);
const batchingnormalVertex = (
/* glsl */
`
#ifdef BATCHING
objectNormal = vec4( batchingMatrix * vec4( objectNormal, 0.0 ) ).xyz;
#ifdef USE_TANGENT
objectTangent = vec4( batchingMatrix * vec4( objectTangent, 0.0 ) ).xyz;
#endif
#endif
`
);
const batchingVertex = (
/* glsl */
`
#ifdef BATCHING
transformed = ( batchingMatrix * vec4( transformed, 1.0 ) ).xyz;
#endif
`
);
function copyAttributeData(src, target, targetOffset = 0) {
const itemSize = target.itemSize;
if (src.isInterleavedBufferAttribute || src.array.constructor !== target.array.constructor) {
const vertexCount = src.count;
for (let i = 0; i < vertexCount; i++) {
for (let c = 0; c < itemSize; c++) {
target.setComponent(i + targetOffset, c, src.getComponent(i, c));
}
}
} else {
target.array.set(src.array, targetOffset * itemSize);
}
target.needsUpdate = true;
}
class BatchedMesh extends THREE.Mesh {
constructor(maxGeometryCount, maxVertexCount, maxIndexCount = maxVertexCount * 2, material) {
super(new THREE.BufferGeometry(), material);
__publicField(this, "_vertexStarts");
__publicField(this, "_vertexCounts");
__publicField(this, "_indexStarts");
__publicField(this, "_indexCounts");
__publicField(this, "_reservedRanges");
__publicField(this, "_visible");
__publicField(this, "_active");
__publicField(this, "_maxGeometryCount");
__publicField(this, "_maxVertexCount");
__publicField(this, "_maxIndexCount");
__publicField(this, "_geometryInitialized");
__publicField(this, "_geometryCount");
__publicField(this, "_matrices");
__publicField(this, "_matricesTexture");
__publicField(this, "_customUniforms");
this._vertexStarts = [];
this._vertexCounts = [];
this._indexStarts = [];
this._indexCounts = [];
this._reservedRanges = [];
this._visible = [];
this._active = [];
this._maxGeometryCount = maxGeometryCount;
this._maxVertexCount = maxVertexCount;
this._maxIndexCount = maxIndexCount;
this._geometryInitialized = false;
this._geometryCount = 0;
this._matrices = [];
this._matricesTexture = null;
this.frustumCulled = false;
this._customUniforms = {
batchingTexture: { value: null }
};
this._initMatricesTexture();
this._initShader();
this.onBeforeRender = function() {
if (this.material.defines) {
this.material.defines.BATCHING = true;
}
};
this.onAfterRender = function() {
if (this.material.defines) {
this.material.defines.BATCHING = false;
}
};
}
_initMatricesTexture() {
let size = Math.sqrt(this._maxGeometryCount * 4);
size = THREE.MathUtils.ceilPowerOfTwo(size);
size = Math.max(size, 4);
const matricesArray = new Float32Array(size * size * 4);
const matricesTexture = new THREE.DataTexture(matricesArray, size, size, THREE.RGBAFormat, THREE.FloatType);
this._matricesTexture = matricesTexture;
this._customUniforms.batchingTexture.value = this._matricesTexture;
}
_initShader() {
const material = this.material;
const currentOnBeforeCompile = material.onBeforeCompile;
const customUniforms = this._customUniforms;
material.onBeforeCompile = function onBeforeCompile(parameters, renderer) {
parameters.vertexShader = parameters.vertexShader.replace("#include <skinning_pars_vertex>", "#include <skinning_pars_vertex>\n" + batchingParsVertex).replace("#include <uv_vertex>", "#include <uv_vertex>\n" + batchingbaseVertex).replace("#include <skinnormal_vertex>", "#include <skinnormal_vertex>\n" + batchingnormalVertex).replace("#include <skinning_vertex>", "#include <skinning_vertex>\n" + batchingVertex);
for (const uniformName in customUniforms) {
parameters.uniforms[uniformName] = customUniforms[uniformName];
}
currentOnBeforeCompile.call(this, parameters, renderer);
};
material.defines = material.defines || {};
material.defines.BATCHING = false;
}
_initializeGeometry(reference) {
const geometry = this.geometry;
const maxVertexCount = this._maxVertexCount;
const maxGeometryCount = this._maxGeometryCount;
const maxIndexCount = this._maxIndexCount;
if (this._geometryInitialized === false) {
for (const attributeName in reference.attributes) {
const srcAttribute = reference.getAttribute(attributeName);
const { array, itemSize, normalized } = srcAttribute;
const dstArray = new array.constructor(maxVertexCount * itemSize);
const dstAttribute = new srcAttribute.constructor(dstArray, itemSize, normalized);
dstAttribute.setUsage(srcAttribute.usage);
geometry.setAttribute(attributeName, dstAttribute);
}
if (reference.getIndex() !== null) {
const indexArray = maxVertexCount > 65536 ? new Uint32Array(maxIndexCount) : new Uint16Array(maxIndexCount);
geometry.setIndex(new THREE.BufferAttribute(indexArray, 1));
}
const idArray = maxGeometryCount > 65536 ? new Uint32Array(maxVertexCount) : new Uint16Array(maxVertexCount);
geometry.setAttribute(ID_ATTR_NAME, new THREE.BufferAttribute(idArray, 1));
this._geometryInitialized = true;
}
}
// Make sure the geometry is compatible with the existing combined geometry atributes
_validateGeometry(geometry) {
if (geometry.getAttribute(ID_ATTR_NAME)) {
throw new Error(`BatchedMesh: Geometry cannot use attribute "${ID_ATTR_NAME}"`);
}
const batchGeometry = this.geometry;
if (Boolean(geometry.getIndex()) !== Boolean(batchGeometry.getIndex())) {
throw new Error('BatchedMesh: All geometries must consistently have "index".');
}
for (const attributeName in batchGeometry.attributes) {
if (attributeName === ID_ATTR_NAME) {
continue;
}
if (!geometry.hasAttribute(attributeName)) {
throw new Error(
`BatchedMesh: Added geometry missing "${attributeName}". All geometries must have consistent attributes.`
);
}
const srcAttribute = geometry.getAttribute(attributeName);
const dstAttribute = batchGeometry.getAttribute(attributeName);
if (srcAttribute.itemSize !== dstAttribute.itemSize || srcAttribute.normalized !== dstAttribute.normalized) {
throw new Error("BatchedMesh: All attributes must have a consistent itemSize and normalized value.");
}
}
}
getGeometryCount() {
return this._geometryCount;
}
getVertexCount() {
const reservedRanges = this._reservedRanges;
if (reservedRanges.length === 0) {
return 0;
} else {
const finalRange = reservedRanges[reservedRanges.length - 1];
return finalRange.vertexStart + finalRange.vertexCount;
}
}
getIndexCount() {
const reservedRanges = this._reservedRanges;
const geometry = this.geometry;
if (geometry.getIndex() === null || reservedRanges.length === 0) {
return 0;
} else {
const finalRange = reservedRanges[reservedRanges.length - 1];
return finalRange.indexStart + finalRange.indexCount;
}
}
addGeometry(geometry, vertexCount = -1, indexCount = -1) {
this._initializeGeometry(geometry);
this._validateGeometry(geometry);
if (this._geometryCount >= this._maxGeometryCount) {
throw new Error("BatchedMesh: Maximum geometry count reached.");
}
const range = {
vertexStart: -1,
vertexCount: -1,
indexStart: -1,
indexCount: -1
};
let lastRange = null;
const reservedRanges = this._reservedRanges;
if (this._geometryCount !== 0) {
lastRange = reservedRanges[reservedRanges.length - 1];
}
if (vertexCount === -1) {
range.vertexCount = geometry.getAttribute("position").count;
} else {
range.vertexCount = vertexCount;
}
if (lastRange === null) {
range.vertexStart = 0;
} else {
range.vertexStart = lastRange.vertexStart + lastRange.vertexCount;
}
if (geometry.getIndex() !== null) {
if (indexCount === -1) {
range.indexCount = geometry.getIndex().count;
} else {
range.indexCount = indexCount;
}
if (lastRange === null) {
range.indexStart = 0;
} else {
range.indexStart = lastRange.indexStart + lastRange.indexCount;
}
}
if (range.indexStart !== -1 && range.indexStart + range.indexCount > this._maxIndexCount || range.vertexStart + range.vertexCount > this._maxVertexCount) {
throw new Error("BatchedMesh: Reserved space request exceeds the maximum buffer size.");
}
const indexCounts = this._indexCounts;
const indexStarts = this._indexStarts;
const vertexCounts = this._vertexCounts;
const vertexStarts = this._vertexStarts;
const visible = this._visible;
const active = this._active;
const matricesTexture = this._matricesTexture;
const matrices = this._matrices;
const matricesArray = this._matricesTexture.image.data;
visible.push(true);
active.push(true);
const geometryId = this._geometryCount;
this._geometryCount++;
matrices.push(new THREE.Matrix4());
_identityMatrix.toArray(matricesArray, geometryId * 16);
matricesTexture.needsUpdate = true;
reservedRanges.push(range);
vertexStarts.push(range.vertexStart);
vertexCounts.push(range.vertexCount);
if (geometry.getIndex() !== null) {
indexStarts.push(range.indexCount);
indexCounts.push(range.indexCount);
}
const idAttribute = this.geometry.getAttribute(ID_ATTR_NAME);
for (let i = 0; i < range.vertexCount; i++) {
idAttribute.setX(range.vertexStart + i, geometryId);
}
idAttribute.needsUpdate = true;
this.setGeometryAt(geometryId, geometry);
return geometryId;
}
/**
* @deprecated use `addGeometry` instead.
*/
applyGeometry(geometry) {
return this.addGeometry(geometry);
}
setGeometryAt(id, geometry) {
if (id >= this._geometryCount) {
throw new Error("BatchedMesh: Maximum geometry count reached.");
}
this._validateGeometry(geometry);
const range = this._reservedRanges[id];
if (geometry.getIndex() !== null && geometry.getIndex().count > range.indexCount || geometry.attributes.position.count > range.vertexCount) {
throw new Error("BatchedMesh: Reserved space not large enough for provided geometry.");
}
const batchGeometry = this.geometry;
const srcPositionAttribute = geometry.getAttribute("position");
const hasIndex = batchGeometry.getIndex() !== null;
const dstIndex = batchGeometry.getIndex();
const srcIndex = geometry.getIndex();
const vertexStart = range.vertexStart;
const vertexCount = range.vertexCount;
for (const attributeName in batchGeometry.attributes) {
if (attributeName === ID_ATTR_NAME) {
continue;
}
const srcAttribute = geometry.getAttribute(attributeName);
const dstAttribute = batchGeometry.getAttribute(attributeName);
copyAttributeData(srcAttribute, dstAttribute, vertexStart);
const itemSize = srcAttribute.itemSize;
for (let i = srcAttribute.count, l = vertexCount; i < l; i++) {
const index = vertexStart + i;
for (let c = 0; c < itemSize; c++) {
dstAttribute.setComponent(index, c, 0);
}
}
dstAttribute.needsUpdate = true;
}
this._vertexCounts[id] = srcPositionAttribute.count;
if (hasIndex) {
const indexStart = range.indexStart;
for (let i = 0; i < srcIndex.count; i++) {
dstIndex.setX(indexStart + i, vertexStart + srcIndex.getX(i));
}
for (let i = srcIndex.count, l = range.indexCount; i < l; i++) {
dstIndex.setX(indexStart + i, vertexStart);
}
dstIndex.needsUpdate = true;
this._indexCounts[id] = srcIndex.count;
}
return id;
}
deleteGeometry(geometryId) {
const active = this._active;
const matricesTexture = this._matricesTexture;
const matricesArray = matricesTexture.image.data;
if (geometryId >= active.length || active[geometryId] === false) {
return this;
}
active[geometryId] = false;
_zeroScaleMatrix.toArray(matricesArray, geometryId * 16);
matricesTexture.needsUpdate = true;
return this;
}
optimize() {
throw new Error("BatchedMesh: Optimize function not implemented.");
}
setMatrixAt(geometryId, matrix) {
const visible = this._visible;
const active = this._active;
const matricesTexture = this._matricesTexture;
const matrices = this._matrices;
const matricesArray = matricesTexture.image.data;
if (geometryId >= matrices.length || active[geometryId] === false) {
return this;
}
if (visible[geometryId] === true) {
matrix.toArray(matricesArray, geometryId * 16);
matricesTexture.needsUpdate = true;
}
matrices[geometryId].copy(matrix);
return this;
}
getMatrixAt(geometryId, matrix) {
const matrices = this._matrices;
const active = this._active;
if (geometryId >= matrices.length || active[geometryId] === false) {
return matrix;
}
return matrix.copy(matrices[geometryId]);
}
setVisibleAt(geometryId, value) {
const visible = this._visible;
const active = this._active;
const matricesTexture = this._matricesTexture;
const matrices = this._matrices;
const matricesArray = matricesTexture.image.data;
if (geometryId >= visible.length || active[geometryId] === false || visible[geometryId] === value) {
return this;
}
if (value === true) {
matrices[geometryId].toArray(matricesArray, geometryId * 16);
} else {
_zeroScaleMatrix.toArray(matricesArray, geometryId * 16);
}
matricesTexture.needsUpdate = true;
visible[geometryId] = value;
return this;
}
getVisibleAt(geometryId) {
const visible = this._visible;
const active = this._active;
if (geometryId >= visible.length || active[geometryId] === false) {
return false;
}
return visible[geometryId];
}
raycast() {
console.warn("BatchedMesh: Raycast function not implemented.");
}
copy() {
throw new Error("BatchedMesh: Copy function not implemented.");
}
toJSON() {
throw new Error("BatchedMesh: toJSON function not implemented.");
}
dispose() {
this.geometry.dispose();
this._matricesTexture.dispose();
this._matricesTexture = null;
return this;
}
}
exports.BatchedMesh = BatchedMesh;
//# sourceMappingURL=BatchedMesh.cjs.map
File diff suppressed because one or more lines are too long
+48
View File
@@ -0,0 +1,48 @@
import { Matrix4, Mesh, BufferGeometry, Material, DataTexture, IUniform } from 'three';
declare class BatchedMesh extends Mesh<BufferGeometry, Material> {
_vertexStarts: number[];
_vertexCounts: number[];
_indexStarts: number[];
_indexCounts: number[];
_reservedRanges: {
vertexStart: number;
vertexCount: number;
indexStart: number;
indexCount: number;
}[];
_visible: boolean[];
_active: boolean[];
_maxGeometryCount: number;
_maxVertexCount: number;
_maxIndexCount: number;
_geometryInitialized: boolean;
_geometryCount: number;
_matrices: Matrix4[];
_matricesTexture: DataTexture | null;
_customUniforms: Record<string, IUniform>;
constructor(maxGeometryCount: number, maxVertexCount: number, maxIndexCount?: number, material?: Material);
_initMatricesTexture(): void;
_initShader(): void;
_initializeGeometry(reference: BufferGeometry): void;
_validateGeometry(geometry: BufferGeometry): void;
getGeometryCount(): number;
getVertexCount(): number;
getIndexCount(): number;
addGeometry(geometry: BufferGeometry, vertexCount?: number, indexCount?: number): number;
/**
* @deprecated use `addGeometry` instead.
*/
applyGeometry(geometry: BufferGeometry): number;
setGeometryAt(id: number, geometry: BufferGeometry): number;
deleteGeometry(geometryId: number): this;
optimize(): never;
setMatrixAt(geometryId: number, matrix: Matrix4): this;
getMatrixAt(geometryId: number, matrix: Matrix4): Matrix4;
setVisibleAt(geometryId: number, value: boolean): this;
getVisibleAt(geometryId: number): boolean;
raycast(): void;
copy(): never;
toJSON(): never;
dispose(): this;
}
export { BatchedMesh };
+425
View File
@@ -0,0 +1,425 @@
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
import { Mesh, BufferGeometry, MathUtils, DataTexture, RGBAFormat, FloatType, BufferAttribute, Matrix4 } from "three";
const ID_ATTR_NAME = "_batch_id_";
const _identityMatrix = /* @__PURE__ */ new Matrix4();
const _zeroScaleMatrix = /* @__PURE__ */ (() => new Matrix4().set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1))();
const batchingParsVertex = (
/* glsl */
`
#ifdef BATCHING
attribute float ${ID_ATTR_NAME};
uniform highp sampler2D batchingTexture;
mat4 getBatchingMatrix( const in float i ) {
int size = textureSize( batchingTexture, 0 ).x;
int j = int( i ) * 4;
int x = j % size;
int y = j / size;
vec4 v1 = texelFetch( batchingTexture, ivec2( x, y ), 0 );
vec4 v2 = texelFetch( batchingTexture, ivec2( x + 1, y ), 0 );
vec4 v3 = texelFetch( batchingTexture, ivec2( x + 2, y ), 0 );
vec4 v4 = texelFetch( batchingTexture, ivec2( x + 3, y ), 0 );
return mat4( v1, v2, v3, v4 );
}
#endif
`
);
const batchingbaseVertex = (
/* glsl */
`
#ifdef BATCHING
mat4 batchingMatrix = getBatchingMatrix( ${ID_ATTR_NAME} );
#endif
`
);
const batchingnormalVertex = (
/* glsl */
`
#ifdef BATCHING
objectNormal = vec4( batchingMatrix * vec4( objectNormal, 0.0 ) ).xyz;
#ifdef USE_TANGENT
objectTangent = vec4( batchingMatrix * vec4( objectTangent, 0.0 ) ).xyz;
#endif
#endif
`
);
const batchingVertex = (
/* glsl */
`
#ifdef BATCHING
transformed = ( batchingMatrix * vec4( transformed, 1.0 ) ).xyz;
#endif
`
);
function copyAttributeData(src, target, targetOffset = 0) {
const itemSize = target.itemSize;
if (src.isInterleavedBufferAttribute || src.array.constructor !== target.array.constructor) {
const vertexCount = src.count;
for (let i = 0; i < vertexCount; i++) {
for (let c = 0; c < itemSize; c++) {
target.setComponent(i + targetOffset, c, src.getComponent(i, c));
}
}
} else {
target.array.set(src.array, targetOffset * itemSize);
}
target.needsUpdate = true;
}
class BatchedMesh extends Mesh {
constructor(maxGeometryCount, maxVertexCount, maxIndexCount = maxVertexCount * 2, material) {
super(new BufferGeometry(), material);
__publicField(this, "_vertexStarts");
__publicField(this, "_vertexCounts");
__publicField(this, "_indexStarts");
__publicField(this, "_indexCounts");
__publicField(this, "_reservedRanges");
__publicField(this, "_visible");
__publicField(this, "_active");
__publicField(this, "_maxGeometryCount");
__publicField(this, "_maxVertexCount");
__publicField(this, "_maxIndexCount");
__publicField(this, "_geometryInitialized");
__publicField(this, "_geometryCount");
__publicField(this, "_matrices");
__publicField(this, "_matricesTexture");
__publicField(this, "_customUniforms");
this._vertexStarts = [];
this._vertexCounts = [];
this._indexStarts = [];
this._indexCounts = [];
this._reservedRanges = [];
this._visible = [];
this._active = [];
this._maxGeometryCount = maxGeometryCount;
this._maxVertexCount = maxVertexCount;
this._maxIndexCount = maxIndexCount;
this._geometryInitialized = false;
this._geometryCount = 0;
this._matrices = [];
this._matricesTexture = null;
this.frustumCulled = false;
this._customUniforms = {
batchingTexture: { value: null }
};
this._initMatricesTexture();
this._initShader();
this.onBeforeRender = function() {
if (this.material.defines) {
this.material.defines.BATCHING = true;
}
};
this.onAfterRender = function() {
if (this.material.defines) {
this.material.defines.BATCHING = false;
}
};
}
_initMatricesTexture() {
let size = Math.sqrt(this._maxGeometryCount * 4);
size = MathUtils.ceilPowerOfTwo(size);
size = Math.max(size, 4);
const matricesArray = new Float32Array(size * size * 4);
const matricesTexture = new DataTexture(matricesArray, size, size, RGBAFormat, FloatType);
this._matricesTexture = matricesTexture;
this._customUniforms.batchingTexture.value = this._matricesTexture;
}
_initShader() {
const material = this.material;
const currentOnBeforeCompile = material.onBeforeCompile;
const customUniforms = this._customUniforms;
material.onBeforeCompile = function onBeforeCompile(parameters, renderer) {
parameters.vertexShader = parameters.vertexShader.replace("#include <skinning_pars_vertex>", "#include <skinning_pars_vertex>\n" + batchingParsVertex).replace("#include <uv_vertex>", "#include <uv_vertex>\n" + batchingbaseVertex).replace("#include <skinnormal_vertex>", "#include <skinnormal_vertex>\n" + batchingnormalVertex).replace("#include <skinning_vertex>", "#include <skinning_vertex>\n" + batchingVertex);
for (const uniformName in customUniforms) {
parameters.uniforms[uniformName] = customUniforms[uniformName];
}
currentOnBeforeCompile.call(this, parameters, renderer);
};
material.defines = material.defines || {};
material.defines.BATCHING = false;
}
_initializeGeometry(reference) {
const geometry = this.geometry;
const maxVertexCount = this._maxVertexCount;
const maxGeometryCount = this._maxGeometryCount;
const maxIndexCount = this._maxIndexCount;
if (this._geometryInitialized === false) {
for (const attributeName in reference.attributes) {
const srcAttribute = reference.getAttribute(attributeName);
const { array, itemSize, normalized } = srcAttribute;
const dstArray = new array.constructor(maxVertexCount * itemSize);
const dstAttribute = new srcAttribute.constructor(dstArray, itemSize, normalized);
dstAttribute.setUsage(srcAttribute.usage);
geometry.setAttribute(attributeName, dstAttribute);
}
if (reference.getIndex() !== null) {
const indexArray = maxVertexCount > 65536 ? new Uint32Array(maxIndexCount) : new Uint16Array(maxIndexCount);
geometry.setIndex(new BufferAttribute(indexArray, 1));
}
const idArray = maxGeometryCount > 65536 ? new Uint32Array(maxVertexCount) : new Uint16Array(maxVertexCount);
geometry.setAttribute(ID_ATTR_NAME, new BufferAttribute(idArray, 1));
this._geometryInitialized = true;
}
}
// Make sure the geometry is compatible with the existing combined geometry atributes
_validateGeometry(geometry) {
if (geometry.getAttribute(ID_ATTR_NAME)) {
throw new Error(`BatchedMesh: Geometry cannot use attribute "${ID_ATTR_NAME}"`);
}
const batchGeometry = this.geometry;
if (Boolean(geometry.getIndex()) !== Boolean(batchGeometry.getIndex())) {
throw new Error('BatchedMesh: All geometries must consistently have "index".');
}
for (const attributeName in batchGeometry.attributes) {
if (attributeName === ID_ATTR_NAME) {
continue;
}
if (!geometry.hasAttribute(attributeName)) {
throw new Error(
`BatchedMesh: Added geometry missing "${attributeName}". All geometries must have consistent attributes.`
);
}
const srcAttribute = geometry.getAttribute(attributeName);
const dstAttribute = batchGeometry.getAttribute(attributeName);
if (srcAttribute.itemSize !== dstAttribute.itemSize || srcAttribute.normalized !== dstAttribute.normalized) {
throw new Error("BatchedMesh: All attributes must have a consistent itemSize and normalized value.");
}
}
}
getGeometryCount() {
return this._geometryCount;
}
getVertexCount() {
const reservedRanges = this._reservedRanges;
if (reservedRanges.length === 0) {
return 0;
} else {
const finalRange = reservedRanges[reservedRanges.length - 1];
return finalRange.vertexStart + finalRange.vertexCount;
}
}
getIndexCount() {
const reservedRanges = this._reservedRanges;
const geometry = this.geometry;
if (geometry.getIndex() === null || reservedRanges.length === 0) {
return 0;
} else {
const finalRange = reservedRanges[reservedRanges.length - 1];
return finalRange.indexStart + finalRange.indexCount;
}
}
addGeometry(geometry, vertexCount = -1, indexCount = -1) {
this._initializeGeometry(geometry);
this._validateGeometry(geometry);
if (this._geometryCount >= this._maxGeometryCount) {
throw new Error("BatchedMesh: Maximum geometry count reached.");
}
const range = {
vertexStart: -1,
vertexCount: -1,
indexStart: -1,
indexCount: -1
};
let lastRange = null;
const reservedRanges = this._reservedRanges;
if (this._geometryCount !== 0) {
lastRange = reservedRanges[reservedRanges.length - 1];
}
if (vertexCount === -1) {
range.vertexCount = geometry.getAttribute("position").count;
} else {
range.vertexCount = vertexCount;
}
if (lastRange === null) {
range.vertexStart = 0;
} else {
range.vertexStart = lastRange.vertexStart + lastRange.vertexCount;
}
if (geometry.getIndex() !== null) {
if (indexCount === -1) {
range.indexCount = geometry.getIndex().count;
} else {
range.indexCount = indexCount;
}
if (lastRange === null) {
range.indexStart = 0;
} else {
range.indexStart = lastRange.indexStart + lastRange.indexCount;
}
}
if (range.indexStart !== -1 && range.indexStart + range.indexCount > this._maxIndexCount || range.vertexStart + range.vertexCount > this._maxVertexCount) {
throw new Error("BatchedMesh: Reserved space request exceeds the maximum buffer size.");
}
const indexCounts = this._indexCounts;
const indexStarts = this._indexStarts;
const vertexCounts = this._vertexCounts;
const vertexStarts = this._vertexStarts;
const visible = this._visible;
const active = this._active;
const matricesTexture = this._matricesTexture;
const matrices = this._matrices;
const matricesArray = this._matricesTexture.image.data;
visible.push(true);
active.push(true);
const geometryId = this._geometryCount;
this._geometryCount++;
matrices.push(new Matrix4());
_identityMatrix.toArray(matricesArray, geometryId * 16);
matricesTexture.needsUpdate = true;
reservedRanges.push(range);
vertexStarts.push(range.vertexStart);
vertexCounts.push(range.vertexCount);
if (geometry.getIndex() !== null) {
indexStarts.push(range.indexCount);
indexCounts.push(range.indexCount);
}
const idAttribute = this.geometry.getAttribute(ID_ATTR_NAME);
for (let i = 0; i < range.vertexCount; i++) {
idAttribute.setX(range.vertexStart + i, geometryId);
}
idAttribute.needsUpdate = true;
this.setGeometryAt(geometryId, geometry);
return geometryId;
}
/**
* @deprecated use `addGeometry` instead.
*/
applyGeometry(geometry) {
return this.addGeometry(geometry);
}
setGeometryAt(id, geometry) {
if (id >= this._geometryCount) {
throw new Error("BatchedMesh: Maximum geometry count reached.");
}
this._validateGeometry(geometry);
const range = this._reservedRanges[id];
if (geometry.getIndex() !== null && geometry.getIndex().count > range.indexCount || geometry.attributes.position.count > range.vertexCount) {
throw new Error("BatchedMesh: Reserved space not large enough for provided geometry.");
}
const batchGeometry = this.geometry;
const srcPositionAttribute = geometry.getAttribute("position");
const hasIndex = batchGeometry.getIndex() !== null;
const dstIndex = batchGeometry.getIndex();
const srcIndex = geometry.getIndex();
const vertexStart = range.vertexStart;
const vertexCount = range.vertexCount;
for (const attributeName in batchGeometry.attributes) {
if (attributeName === ID_ATTR_NAME) {
continue;
}
const srcAttribute = geometry.getAttribute(attributeName);
const dstAttribute = batchGeometry.getAttribute(attributeName);
copyAttributeData(srcAttribute, dstAttribute, vertexStart);
const itemSize = srcAttribute.itemSize;
for (let i = srcAttribute.count, l = vertexCount; i < l; i++) {
const index = vertexStart + i;
for (let c = 0; c < itemSize; c++) {
dstAttribute.setComponent(index, c, 0);
}
}
dstAttribute.needsUpdate = true;
}
this._vertexCounts[id] = srcPositionAttribute.count;
if (hasIndex) {
const indexStart = range.indexStart;
for (let i = 0; i < srcIndex.count; i++) {
dstIndex.setX(indexStart + i, vertexStart + srcIndex.getX(i));
}
for (let i = srcIndex.count, l = range.indexCount; i < l; i++) {
dstIndex.setX(indexStart + i, vertexStart);
}
dstIndex.needsUpdate = true;
this._indexCounts[id] = srcIndex.count;
}
return id;
}
deleteGeometry(geometryId) {
const active = this._active;
const matricesTexture = this._matricesTexture;
const matricesArray = matricesTexture.image.data;
if (geometryId >= active.length || active[geometryId] === false) {
return this;
}
active[geometryId] = false;
_zeroScaleMatrix.toArray(matricesArray, geometryId * 16);
matricesTexture.needsUpdate = true;
return this;
}
optimize() {
throw new Error("BatchedMesh: Optimize function not implemented.");
}
setMatrixAt(geometryId, matrix) {
const visible = this._visible;
const active = this._active;
const matricesTexture = this._matricesTexture;
const matrices = this._matrices;
const matricesArray = matricesTexture.image.data;
if (geometryId >= matrices.length || active[geometryId] === false) {
return this;
}
if (visible[geometryId] === true) {
matrix.toArray(matricesArray, geometryId * 16);
matricesTexture.needsUpdate = true;
}
matrices[geometryId].copy(matrix);
return this;
}
getMatrixAt(geometryId, matrix) {
const matrices = this._matrices;
const active = this._active;
if (geometryId >= matrices.length || active[geometryId] === false) {
return matrix;
}
return matrix.copy(matrices[geometryId]);
}
setVisibleAt(geometryId, value) {
const visible = this._visible;
const active = this._active;
const matricesTexture = this._matricesTexture;
const matrices = this._matrices;
const matricesArray = matricesTexture.image.data;
if (geometryId >= visible.length || active[geometryId] === false || visible[geometryId] === value) {
return this;
}
if (value === true) {
matrices[geometryId].toArray(matricesArray, geometryId * 16);
} else {
_zeroScaleMatrix.toArray(matricesArray, geometryId * 16);
}
matricesTexture.needsUpdate = true;
visible[geometryId] = value;
return this;
}
getVisibleAt(geometryId) {
const visible = this._visible;
const active = this._active;
if (geometryId >= visible.length || active[geometryId] === false) {
return false;
}
return visible[geometryId];
}
raycast() {
console.warn("BatchedMesh: Raycast function not implemented.");
}
copy() {
throw new Error("BatchedMesh: Copy function not implemented.");
}
toJSON() {
throw new Error("BatchedMesh: toJSON function not implemented.");
}
dispose() {
this.geometry.dispose();
this._matricesTexture.dispose();
this._matricesTexture = null;
return this;
}
}
export {
BatchedMesh
};
//# sourceMappingURL=BatchedMesh.js.map
File diff suppressed because one or more lines are too long
+136
View File
@@ -0,0 +1,136 @@
"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const THREE = require("three");
const constants = require("../_polyfill/constants.cjs");
const isCubeTexture = (def) => def && def.isCubeTexture;
class GroundProjectedEnv extends THREE.Mesh {
constructor(texture, options) {
var _a, _b;
const isCubeMap = isCubeTexture(texture);
const w = (_b = isCubeMap ? (_a = texture.image[0]) == null ? void 0 : _a.width : texture.image.width) != null ? _b : 1024;
const cubeSize = w / 4;
const _lodMax = Math.floor(Math.log2(cubeSize));
const _cubeSize = Math.pow(2, _lodMax);
const width = 3 * Math.max(_cubeSize, 16 * 7);
const height = 4 * _cubeSize;
const defines = [
isCubeMap ? "#define ENVMAP_TYPE_CUBE" : "",
`#define CUBEUV_TEXEL_WIDTH ${1 / width}`,
`#define CUBEUV_TEXEL_HEIGHT ${1 / height}`,
`#define CUBEUV_MAX_MIP ${_lodMax}.0`
];
const vertexShader = (
/* glsl */
`
varying vec3 vWorldPosition;
void main()
{
vec4 worldPosition = ( modelMatrix * vec4( position, 1.0 ) );
vWorldPosition = worldPosition.xyz;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
`
);
const fragmentShader = defines.join("\n") + /* glsl */
`
#define ENVMAP_TYPE_CUBE_UV
varying vec3 vWorldPosition;
uniform float radius;
uniform float height;
uniform float angle;
#ifdef ENVMAP_TYPE_CUBE
uniform samplerCube map;
#else
uniform sampler2D map;
#endif
// From: https://www.shadertoy.com/view/4tsBD7
float diskIntersectWithBackFaceCulling( vec3 ro, vec3 rd, vec3 c, vec3 n, float r )
{
float d = dot ( rd, n );
if( d > 0.0 ) { return 1e6; }
vec3 o = ro - c;
float t = - dot( n, o ) / d;
vec3 q = o + rd * t;
return ( dot( q, q ) < r * r ) ? t : 1e6;
}
// From: https://www.iquilezles.org/www/articles/intersectors/intersectors.htm
float sphereIntersect( vec3 ro, vec3 rd, vec3 ce, float ra )
{
vec3 oc = ro - ce;
float b = dot( oc, rd );
float c = dot( oc, oc ) - ra * ra;
float h = b * b - c;
if( h < 0.0 ) { return -1.0; }
h = sqrt( h );
return - b + h;
}
vec3 project()
{
vec3 p = normalize( vWorldPosition );
vec3 camPos = cameraPosition;
camPos.y -= height;
float intersection = sphereIntersect( camPos, p, vec3( 0.0 ), radius );
if( intersection > 0.0 ) {
vec3 h = vec3( 0.0, - height, 0.0 );
float intersection2 = diskIntersectWithBackFaceCulling( camPos, p, h, vec3( 0.0, 1.0, 0.0 ), radius );
p = ( camPos + min( intersection, intersection2 ) * p ) / radius;
} else {
p = vec3( 0.0, 1.0, 0.0 );
}
return p;
}
#include <common>
#include <cube_uv_reflection_fragment>
void main()
{
vec3 projectedWorldPosition = project();
#ifdef ENVMAP_TYPE_CUBE
vec3 outcolor = textureCube( map, projectedWorldPosition ).rgb;
#else
vec3 direction = normalize( projectedWorldPosition );
vec2 uv = equirectUv( direction );
vec3 outcolor = texture2D( map, uv ).rgb;
#endif
gl_FragColor = vec4( outcolor, 1.0 );
#include <tonemapping_fragment>
#include <${constants.version >= 154 ? "colorspace_fragment" : "encodings_fragment"}>
}
`;
const uniforms = {
map: { value: texture },
height: { value: (options == null ? void 0 : options.height) || 15 },
radius: { value: (options == null ? void 0 : options.radius) || 100 }
};
const geometry = new THREE.IcosahedronGeometry(1, 16);
const material = new THREE.ShaderMaterial({
uniforms,
fragmentShader,
vertexShader,
side: THREE.DoubleSide
});
super(geometry, material);
}
set radius(radius) {
this.material.uniforms.radius.value = radius;
}
get radius() {
return this.material.uniforms.radius.value;
}
set height(height) {
this.material.uniforms.height.value = height;
}
get height() {
return this.material.uniforms.height.value;
}
}
exports.GroundProjectedEnv = GroundProjectedEnv;
//# sourceMappingURL=GroundProjectedEnv.cjs.map
File diff suppressed because one or more lines are too long
+12
View File
@@ -0,0 +1,12 @@
import { Mesh, ShaderMaterial, Texture, CubeTexture, BufferGeometry } from 'three';
export interface GroundProjectedEnvParameters {
height?: number;
radius?: number;
}
export declare class GroundProjectedEnv extends Mesh<BufferGeometry, ShaderMaterial> {
constructor(texture: CubeTexture | Texture, options?: GroundProjectedEnvParameters);
set radius(radius: number);
get radius(): number;
set height(height: number);
get height(): number;
}
+136
View File
@@ -0,0 +1,136 @@
import { Mesh, IcosahedronGeometry, ShaderMaterial, DoubleSide } from "three";
import { version } from "../_polyfill/constants.js";
const isCubeTexture = (def) => def && def.isCubeTexture;
class GroundProjectedEnv extends Mesh {
constructor(texture, options) {
var _a, _b;
const isCubeMap = isCubeTexture(texture);
const w = (_b = isCubeMap ? (_a = texture.image[0]) == null ? void 0 : _a.width : texture.image.width) != null ? _b : 1024;
const cubeSize = w / 4;
const _lodMax = Math.floor(Math.log2(cubeSize));
const _cubeSize = Math.pow(2, _lodMax);
const width = 3 * Math.max(_cubeSize, 16 * 7);
const height = 4 * _cubeSize;
const defines = [
isCubeMap ? "#define ENVMAP_TYPE_CUBE" : "",
`#define CUBEUV_TEXEL_WIDTH ${1 / width}`,
`#define CUBEUV_TEXEL_HEIGHT ${1 / height}`,
`#define CUBEUV_MAX_MIP ${_lodMax}.0`
];
const vertexShader = (
/* glsl */
`
varying vec3 vWorldPosition;
void main()
{
vec4 worldPosition = ( modelMatrix * vec4( position, 1.0 ) );
vWorldPosition = worldPosition.xyz;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
`
);
const fragmentShader = defines.join("\n") + /* glsl */
`
#define ENVMAP_TYPE_CUBE_UV
varying vec3 vWorldPosition;
uniform float radius;
uniform float height;
uniform float angle;
#ifdef ENVMAP_TYPE_CUBE
uniform samplerCube map;
#else
uniform sampler2D map;
#endif
// From: https://www.shadertoy.com/view/4tsBD7
float diskIntersectWithBackFaceCulling( vec3 ro, vec3 rd, vec3 c, vec3 n, float r )
{
float d = dot ( rd, n );
if( d > 0.0 ) { return 1e6; }
vec3 o = ro - c;
float t = - dot( n, o ) / d;
vec3 q = o + rd * t;
return ( dot( q, q ) < r * r ) ? t : 1e6;
}
// From: https://www.iquilezles.org/www/articles/intersectors/intersectors.htm
float sphereIntersect( vec3 ro, vec3 rd, vec3 ce, float ra )
{
vec3 oc = ro - ce;
float b = dot( oc, rd );
float c = dot( oc, oc ) - ra * ra;
float h = b * b - c;
if( h < 0.0 ) { return -1.0; }
h = sqrt( h );
return - b + h;
}
vec3 project()
{
vec3 p = normalize( vWorldPosition );
vec3 camPos = cameraPosition;
camPos.y -= height;
float intersection = sphereIntersect( camPos, p, vec3( 0.0 ), radius );
if( intersection > 0.0 ) {
vec3 h = vec3( 0.0, - height, 0.0 );
float intersection2 = diskIntersectWithBackFaceCulling( camPos, p, h, vec3( 0.0, 1.0, 0.0 ), radius );
p = ( camPos + min( intersection, intersection2 ) * p ) / radius;
} else {
p = vec3( 0.0, 1.0, 0.0 );
}
return p;
}
#include <common>
#include <cube_uv_reflection_fragment>
void main()
{
vec3 projectedWorldPosition = project();
#ifdef ENVMAP_TYPE_CUBE
vec3 outcolor = textureCube( map, projectedWorldPosition ).rgb;
#else
vec3 direction = normalize( projectedWorldPosition );
vec2 uv = equirectUv( direction );
vec3 outcolor = texture2D( map, uv ).rgb;
#endif
gl_FragColor = vec4( outcolor, 1.0 );
#include <tonemapping_fragment>
#include <${version >= 154 ? "colorspace_fragment" : "encodings_fragment"}>
}
`;
const uniforms = {
map: { value: texture },
height: { value: (options == null ? void 0 : options.height) || 15 },
radius: { value: (options == null ? void 0 : options.radius) || 100 }
};
const geometry = new IcosahedronGeometry(1, 16);
const material = new ShaderMaterial({
uniforms,
fragmentShader,
vertexShader,
side: DoubleSide
});
super(geometry, material);
}
set radius(radius) {
this.material.uniforms.radius.value = radius;
}
get radius() {
return this.material.uniforms.radius.value;
}
set height(height) {
this.material.uniforms.height.value = height;
}
get height() {
return this.material.uniforms.height.value;
}
}
export {
GroundProjectedEnv
};
//# sourceMappingURL=GroundProjectedEnv.js.map
File diff suppressed because one or more lines are too long
+291
View File
@@ -0,0 +1,291 @@
"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const THREE = require("three");
const Lensflare = /* @__PURE__ */ (() => {
class Lensflare2 extends THREE.Mesh {
constructor() {
super(Lensflare2.Geometry, new THREE.MeshBasicMaterial({ opacity: 0, transparent: true }));
this.isLensflare = true;
this.type = "Lensflare";
this.frustumCulled = false;
this.renderOrder = Infinity;
const positionScreen = new THREE.Vector3();
const positionView = new THREE.Vector3();
const tempMap = new THREE.Texture({ width: 16, height: 16 });
tempMap.isFramebufferTexture = true;
tempMap.magFilter = THREE.NearestFilter;
tempMap.minFilter = THREE.NearestFilter;
tempMap.generateMipmaps = false;
tempMap.needsUpdate = true;
const occlusionMap = new THREE.Texture({ width: 16, height: 16 });
occlusionMap.isFramebufferTexture = true;
occlusionMap.magFilter = THREE.NearestFilter;
occlusionMap.minFilter = THREE.NearestFilter;
occlusionMap.generateMipmaps = false;
occlusionMap.needsUpdate = true;
const geometry = Lensflare2.Geometry;
const material1a = new THREE.RawShaderMaterial({
uniforms: {
scale: { value: null },
screenPosition: { value: null }
},
vertexShader: (
/* glsl */
`
precision highp float;
uniform vec3 screenPosition;
uniform vec2 scale;
attribute vec3 position;
void main() {
gl_Position = vec4( position.xy * scale + screenPosition.xy, screenPosition.z, 1.0 );
}`
),
fragmentShader: (
/* glsl */
`
precision highp float;
void main() {
gl_FragColor = vec4( 1.0, 0.0, 1.0, 1.0 );
}`
),
depthTest: true,
depthWrite: false,
transparent: false
});
const material1b = new THREE.RawShaderMaterial({
uniforms: {
map: { value: tempMap },
scale: { value: null },
screenPosition: { value: null }
},
vertexShader: (
/* glsl */
`
precision highp float;
uniform vec3 screenPosition;
uniform vec2 scale;
attribute vec3 position;
attribute vec2 uv;
varying vec2 vUV;
void main() {
vUV = uv;
gl_Position = vec4( position.xy * scale + screenPosition.xy, screenPosition.z, 1.0 );
}`
),
fragmentShader: (
/* glsl */
`
precision highp float;
uniform sampler2D map;
varying vec2 vUV;
void main() {
gl_FragColor = texture2D( map, vUV );
}`
),
depthTest: false,
depthWrite: false,
transparent: false
});
const mesh1 = new THREE.Mesh(geometry, material1a);
const elements = [];
const shader = LensflareElement.Shader;
const material2 = new THREE.RawShaderMaterial({
uniforms: {
map: { value: null },
occlusionMap: { value: occlusionMap },
color: { value: new THREE.Color(16777215) },
scale: { value: new THREE.Vector2() },
screenPosition: { value: new THREE.Vector3() }
},
vertexShader: shader.vertexShader,
fragmentShader: shader.fragmentShader,
blending: THREE.AdditiveBlending,
transparent: true,
depthWrite: false
});
const mesh2 = new THREE.Mesh(geometry, material2);
this.addElement = function(element) {
elements.push(element);
};
const scale = new THREE.Vector2();
const screenPositionPixels = new THREE.Vector2();
const validArea = new THREE.Box2();
const viewport = new THREE.Vector4();
this.onBeforeRender = function(renderer, scene, camera) {
renderer.getCurrentViewport(viewport);
const invAspect = viewport.w / viewport.z;
const halfViewportWidth = viewport.z / 2;
const halfViewportHeight = viewport.w / 2;
let size = 16 / viewport.w;
scale.set(size * invAspect, size);
validArea.min.set(viewport.x, viewport.y);
validArea.max.set(viewport.x + (viewport.z - 16), viewport.y + (viewport.w - 16));
positionView.setFromMatrixPosition(this.matrixWorld);
positionView.applyMatrix4(camera.matrixWorldInverse);
if (positionView.z > 0)
return;
positionScreen.copy(positionView).applyMatrix4(camera.projectionMatrix);
screenPositionPixels.x = viewport.x + positionScreen.x * halfViewportWidth + halfViewportWidth - 8;
screenPositionPixels.y = viewport.y + positionScreen.y * halfViewportHeight + halfViewportHeight - 8;
if (validArea.containsPoint(screenPositionPixels)) {
renderer.copyFramebufferToTexture(screenPositionPixels, tempMap);
let uniforms = material1a.uniforms;
uniforms["scale"].value = scale;
uniforms["screenPosition"].value = positionScreen;
renderer.renderBufferDirect(camera, null, geometry, material1a, mesh1, null);
renderer.copyFramebufferToTexture(screenPositionPixels, occlusionMap);
uniforms = material1b.uniforms;
uniforms["scale"].value = scale;
uniforms["screenPosition"].value = positionScreen;
renderer.renderBufferDirect(camera, null, geometry, material1b, mesh1, null);
const vecX = -positionScreen.x * 2;
const vecY = -positionScreen.y * 2;
for (let i = 0, l = elements.length; i < l; i++) {
const element = elements[i];
const uniforms2 = material2.uniforms;
uniforms2["color"].value.copy(element.color);
uniforms2["map"].value = element.texture;
uniforms2["screenPosition"].value.x = positionScreen.x + vecX * element.distance;
uniforms2["screenPosition"].value.y = positionScreen.y + vecY * element.distance;
size = element.size / viewport.w;
const invAspect2 = viewport.w / viewport.z;
uniforms2["scale"].value.set(size * invAspect2, size);
material2.uniformsNeedUpdate = true;
renderer.renderBufferDirect(camera, null, geometry, material2, mesh2, null);
}
}
};
this.dispose = function() {
material1a.dispose();
material1b.dispose();
material2.dispose();
tempMap.dispose();
occlusionMap.dispose();
for (let i = 0, l = elements.length; i < l; i++) {
elements[i].texture.dispose();
}
};
}
}
const _geometry = new THREE.BufferGeometry();
const interleavedBuffer = new THREE.InterleavedBuffer(
new Float32Array([-1, -1, 0, 0, 0, 1, -1, 0, 1, 0, 1, 1, 0, 1, 1, -1, 1, 0, 0, 1]),
5
);
_geometry.setIndex([0, 1, 2, 0, 2, 3]);
_geometry.setAttribute("position", new THREE.InterleavedBufferAttribute(interleavedBuffer, 3, 0, false));
_geometry.setAttribute("uv", new THREE.InterleavedBufferAttribute(interleavedBuffer, 2, 3, false));
Lensflare2.Geometry = _geometry;
return Lensflare2;
})();
const LensflareElement = /* @__PURE__ */ (() => {
class LensflareElement2 {
constructor(texture, size = 1, distance = 0, color = new THREE.Color(16777215)) {
this.texture = texture;
this.size = size;
this.distance = distance;
this.color = color;
}
}
LensflareElement2.Shader = {
uniforms: {
map: { value: null },
occlusionMap: { value: null },
color: { value: null },
scale: { value: null },
screenPosition: { value: null }
},
vertexShader: (
/* glsl */
`
precision highp float;
uniform vec3 screenPosition;
uniform vec2 scale;
uniform sampler2D occlusionMap;
attribute vec3 position;
attribute vec2 uv;
varying vec2 vUV;
varying float vVisibility;
void main() {
vUV = uv;
vec2 pos = position.xy;
vec4 visibility = texture2D( occlusionMap, vec2( 0.1, 0.1 ) );
visibility += texture2D( occlusionMap, vec2( 0.5, 0.1 ) );
visibility += texture2D( occlusionMap, vec2( 0.9, 0.1 ) );
visibility += texture2D( occlusionMap, vec2( 0.9, 0.5 ) );
visibility += texture2D( occlusionMap, vec2( 0.9, 0.9 ) );
visibility += texture2D( occlusionMap, vec2( 0.5, 0.9 ) );
visibility += texture2D( occlusionMap, vec2( 0.1, 0.9 ) );
visibility += texture2D( occlusionMap, vec2( 0.1, 0.5 ) );
visibility += texture2D( occlusionMap, vec2( 0.5, 0.5 ) );
vVisibility = visibility.r / 9.0;
vVisibility *= 1.0 - visibility.g / 9.0;
vVisibility *= visibility.b / 9.0;
gl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );
}
`
),
fragmentShader: (
/* glsl */
`
precision highp float;
uniform sampler2D map;
uniform vec3 color;
varying vec2 vUV;
varying float vVisibility;
void main() {
vec4 texture = texture2D( map, vUV );
texture.a *= vVisibility;
gl_FragColor = texture;
gl_FragColor.rgb *= color;
}
`
)
};
return LensflareElement2;
})();
exports.Lensflare = Lensflare;
exports.LensflareElement = LensflareElement;
//# sourceMappingURL=Lensflare.cjs.map
File diff suppressed because one or more lines are too long
+17
View File
@@ -0,0 +1,17 @@
import { Mesh, Texture, Color } from 'three'
export class LensflareElement {
constructor(texture: Texture, size?: number, distance?: number, color?: Color)
texture: Texture
size: number
distance: number
color: Color
}
export class Lensflare extends Mesh {
constructor()
readonly isLensflare: true
addElement(element: LensflareElement): void
dispose(): void
}
+291
View File
@@ -0,0 +1,291 @@
import { BufferGeometry, InterleavedBuffer, InterleavedBufferAttribute, Mesh, MeshBasicMaterial, Vector3, Texture, NearestFilter, RawShaderMaterial, Color, Vector2, AdditiveBlending, Box2, Vector4 } from "three";
const Lensflare = /* @__PURE__ */ (() => {
class Lensflare2 extends Mesh {
constructor() {
super(Lensflare2.Geometry, new MeshBasicMaterial({ opacity: 0, transparent: true }));
this.isLensflare = true;
this.type = "Lensflare";
this.frustumCulled = false;
this.renderOrder = Infinity;
const positionScreen = new Vector3();
const positionView = new Vector3();
const tempMap = new Texture({ width: 16, height: 16 });
tempMap.isFramebufferTexture = true;
tempMap.magFilter = NearestFilter;
tempMap.minFilter = NearestFilter;
tempMap.generateMipmaps = false;
tempMap.needsUpdate = true;
const occlusionMap = new Texture({ width: 16, height: 16 });
occlusionMap.isFramebufferTexture = true;
occlusionMap.magFilter = NearestFilter;
occlusionMap.minFilter = NearestFilter;
occlusionMap.generateMipmaps = false;
occlusionMap.needsUpdate = true;
const geometry = Lensflare2.Geometry;
const material1a = new RawShaderMaterial({
uniforms: {
scale: { value: null },
screenPosition: { value: null }
},
vertexShader: (
/* glsl */
`
precision highp float;
uniform vec3 screenPosition;
uniform vec2 scale;
attribute vec3 position;
void main() {
gl_Position = vec4( position.xy * scale + screenPosition.xy, screenPosition.z, 1.0 );
}`
),
fragmentShader: (
/* glsl */
`
precision highp float;
void main() {
gl_FragColor = vec4( 1.0, 0.0, 1.0, 1.0 );
}`
),
depthTest: true,
depthWrite: false,
transparent: false
});
const material1b = new RawShaderMaterial({
uniforms: {
map: { value: tempMap },
scale: { value: null },
screenPosition: { value: null }
},
vertexShader: (
/* glsl */
`
precision highp float;
uniform vec3 screenPosition;
uniform vec2 scale;
attribute vec3 position;
attribute vec2 uv;
varying vec2 vUV;
void main() {
vUV = uv;
gl_Position = vec4( position.xy * scale + screenPosition.xy, screenPosition.z, 1.0 );
}`
),
fragmentShader: (
/* glsl */
`
precision highp float;
uniform sampler2D map;
varying vec2 vUV;
void main() {
gl_FragColor = texture2D( map, vUV );
}`
),
depthTest: false,
depthWrite: false,
transparent: false
});
const mesh1 = new Mesh(geometry, material1a);
const elements = [];
const shader = LensflareElement.Shader;
const material2 = new RawShaderMaterial({
uniforms: {
map: { value: null },
occlusionMap: { value: occlusionMap },
color: { value: new Color(16777215) },
scale: { value: new Vector2() },
screenPosition: { value: new Vector3() }
},
vertexShader: shader.vertexShader,
fragmentShader: shader.fragmentShader,
blending: AdditiveBlending,
transparent: true,
depthWrite: false
});
const mesh2 = new Mesh(geometry, material2);
this.addElement = function(element) {
elements.push(element);
};
const scale = new Vector2();
const screenPositionPixels = new Vector2();
const validArea = new Box2();
const viewport = new Vector4();
this.onBeforeRender = function(renderer, scene, camera) {
renderer.getCurrentViewport(viewport);
const invAspect = viewport.w / viewport.z;
const halfViewportWidth = viewport.z / 2;
const halfViewportHeight = viewport.w / 2;
let size = 16 / viewport.w;
scale.set(size * invAspect, size);
validArea.min.set(viewport.x, viewport.y);
validArea.max.set(viewport.x + (viewport.z - 16), viewport.y + (viewport.w - 16));
positionView.setFromMatrixPosition(this.matrixWorld);
positionView.applyMatrix4(camera.matrixWorldInverse);
if (positionView.z > 0)
return;
positionScreen.copy(positionView).applyMatrix4(camera.projectionMatrix);
screenPositionPixels.x = viewport.x + positionScreen.x * halfViewportWidth + halfViewportWidth - 8;
screenPositionPixels.y = viewport.y + positionScreen.y * halfViewportHeight + halfViewportHeight - 8;
if (validArea.containsPoint(screenPositionPixels)) {
renderer.copyFramebufferToTexture(screenPositionPixels, tempMap);
let uniforms = material1a.uniforms;
uniforms["scale"].value = scale;
uniforms["screenPosition"].value = positionScreen;
renderer.renderBufferDirect(camera, null, geometry, material1a, mesh1, null);
renderer.copyFramebufferToTexture(screenPositionPixels, occlusionMap);
uniforms = material1b.uniforms;
uniforms["scale"].value = scale;
uniforms["screenPosition"].value = positionScreen;
renderer.renderBufferDirect(camera, null, geometry, material1b, mesh1, null);
const vecX = -positionScreen.x * 2;
const vecY = -positionScreen.y * 2;
for (let i = 0, l = elements.length; i < l; i++) {
const element = elements[i];
const uniforms2 = material2.uniforms;
uniforms2["color"].value.copy(element.color);
uniforms2["map"].value = element.texture;
uniforms2["screenPosition"].value.x = positionScreen.x + vecX * element.distance;
uniforms2["screenPosition"].value.y = positionScreen.y + vecY * element.distance;
size = element.size / viewport.w;
const invAspect2 = viewport.w / viewport.z;
uniforms2["scale"].value.set(size * invAspect2, size);
material2.uniformsNeedUpdate = true;
renderer.renderBufferDirect(camera, null, geometry, material2, mesh2, null);
}
}
};
this.dispose = function() {
material1a.dispose();
material1b.dispose();
material2.dispose();
tempMap.dispose();
occlusionMap.dispose();
for (let i = 0, l = elements.length; i < l; i++) {
elements[i].texture.dispose();
}
};
}
}
const _geometry = new BufferGeometry();
const interleavedBuffer = new InterleavedBuffer(
new Float32Array([-1, -1, 0, 0, 0, 1, -1, 0, 1, 0, 1, 1, 0, 1, 1, -1, 1, 0, 0, 1]),
5
);
_geometry.setIndex([0, 1, 2, 0, 2, 3]);
_geometry.setAttribute("position", new InterleavedBufferAttribute(interleavedBuffer, 3, 0, false));
_geometry.setAttribute("uv", new InterleavedBufferAttribute(interleavedBuffer, 2, 3, false));
Lensflare2.Geometry = _geometry;
return Lensflare2;
})();
const LensflareElement = /* @__PURE__ */ (() => {
class LensflareElement2 {
constructor(texture, size = 1, distance = 0, color = new Color(16777215)) {
this.texture = texture;
this.size = size;
this.distance = distance;
this.color = color;
}
}
LensflareElement2.Shader = {
uniforms: {
map: { value: null },
occlusionMap: { value: null },
color: { value: null },
scale: { value: null },
screenPosition: { value: null }
},
vertexShader: (
/* glsl */
`
precision highp float;
uniform vec3 screenPosition;
uniform vec2 scale;
uniform sampler2D occlusionMap;
attribute vec3 position;
attribute vec2 uv;
varying vec2 vUV;
varying float vVisibility;
void main() {
vUV = uv;
vec2 pos = position.xy;
vec4 visibility = texture2D( occlusionMap, vec2( 0.1, 0.1 ) );
visibility += texture2D( occlusionMap, vec2( 0.5, 0.1 ) );
visibility += texture2D( occlusionMap, vec2( 0.9, 0.1 ) );
visibility += texture2D( occlusionMap, vec2( 0.9, 0.5 ) );
visibility += texture2D( occlusionMap, vec2( 0.9, 0.9 ) );
visibility += texture2D( occlusionMap, vec2( 0.5, 0.9 ) );
visibility += texture2D( occlusionMap, vec2( 0.1, 0.9 ) );
visibility += texture2D( occlusionMap, vec2( 0.1, 0.5 ) );
visibility += texture2D( occlusionMap, vec2( 0.5, 0.5 ) );
vVisibility = visibility.r / 9.0;
vVisibility *= 1.0 - visibility.g / 9.0;
vVisibility *= visibility.b / 9.0;
gl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );
}
`
),
fragmentShader: (
/* glsl */
`
precision highp float;
uniform sampler2D map;
uniform vec3 color;
varying vec2 vUV;
varying float vVisibility;
void main() {
vec4 texture = texture2D( map, vUV );
texture.a *= vVisibility;
gl_FragColor = texture;
gl_FragColor.rgb *= color;
}
`
)
};
return LensflareElement2;
})();
export {
Lensflare,
LensflareElement
};
//# sourceMappingURL=Lensflare.js.map
File diff suppressed because one or more lines are too long
+111
View File
@@ -0,0 +1,111 @@
"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const THREE = require("three");
const LightningStrike = require("../geometries/LightningStrike.cjs");
class LightningStorm extends THREE.Object3D {
constructor(stormParams = {}) {
super();
this.isLightningStorm = true;
this.stormParams = stormParams;
stormParams.size = stormParams.size !== void 0 ? stormParams.size : 1e3;
stormParams.minHeight = stormParams.minHeight !== void 0 ? stormParams.minHeight : 80;
stormParams.maxHeight = stormParams.maxHeight !== void 0 ? stormParams.maxHeight : 100;
stormParams.maxSlope = stormParams.maxSlope !== void 0 ? stormParams.maxSlope : 1.1;
stormParams.maxLightnings = stormParams.maxLightnings !== void 0 ? stormParams.maxLightnings : 3;
stormParams.lightningMinPeriod = stormParams.lightningMinPeriod !== void 0 ? stormParams.lightningMinPeriod : 3;
stormParams.lightningMaxPeriod = stormParams.lightningMaxPeriod !== void 0 ? stormParams.lightningMaxPeriod : 7;
stormParams.lightningMinDuration = stormParams.lightningMinDuration !== void 0 ? stormParams.lightningMinDuration : 1;
stormParams.lightningMaxDuration = stormParams.lightningMaxDuration !== void 0 ? stormParams.lightningMaxDuration : 2.5;
this.lightningParameters = LightningStrike.LightningStrike.copyParameters(
stormParams.lightningParameters,
stormParams.lightningParameters
);
this.lightningParameters.isEternal = false;
this.lightningMaterial = stormParams.lightningMaterial !== void 0 ? stormParams.lightningMaterial : new THREE.MeshBasicMaterial({ color: 11599871 });
if (stormParams.onRayPosition !== void 0) {
this.onRayPosition = stormParams.onRayPosition;
} else {
this.onRayPosition = function(source, dest) {
dest.set((Math.random() - 0.5) * stormParams.size, 0, (Math.random() - 0.5) * stormParams.size);
const height = THREE.MathUtils.lerp(stormParams.minHeight, stormParams.maxHeight, Math.random());
source.set(stormParams.maxSlope * (2 * Math.random() - 1), 1, stormParams.maxSlope * (2 * Math.random() - 1)).multiplyScalar(height).add(dest);
};
}
this.onLightningDown = stormParams.onLightningDown;
this.inited = false;
this.nextLightningTime = 0;
this.lightningsMeshes = [];
this.deadLightningsMeshes = [];
for (let i = 0; i < this.stormParams.maxLightnings; i++) {
const lightning = new LightningStrike.LightningStrike(LightningStrike.LightningStrike.copyParameters({}, this.lightningParameters));
const mesh = new THREE.Mesh(lightning, this.lightningMaterial);
this.deadLightningsMeshes.push(mesh);
}
}
update(time) {
if (!this.inited) {
this.nextLightningTime = this.getNextLightningTime(time) * Math.random();
this.inited = true;
}
if (time >= this.nextLightningTime) {
const lightningMesh = this.deadLightningsMeshes.pop();
if (lightningMesh) {
const lightningParams1 = LightningStrike.LightningStrike.copyParameters(
lightningMesh.geometry.rayParameters,
this.lightningParameters
);
lightningParams1.birthTime = time;
lightningParams1.deathTime = time + THREE.MathUtils.lerp(this.stormParams.lightningMinDuration, this.stormParams.lightningMaxDuration, Math.random());
this.onRayPosition(lightningParams1.sourceOffset, lightningParams1.destOffset);
lightningParams1.noiseSeed = Math.random();
this.add(lightningMesh);
this.lightningsMeshes.push(lightningMesh);
}
this.nextLightningTime = this.getNextLightningTime(time);
}
let i = 0, il = this.lightningsMeshes.length;
while (i < il) {
const mesh = this.lightningsMeshes[i];
const lightning = mesh.geometry;
const prevState = lightning.state;
lightning.update(time);
if (prevState === LightningStrike.LightningStrike.RAY_PROPAGATING && lightning.state > prevState) {
if (this.onLightningDown) {
this.onLightningDown(lightning);
}
}
if (lightning.state === LightningStrike.LightningStrike.RAY_EXTINGUISHED) {
this.lightningsMeshes.splice(this.lightningsMeshes.indexOf(mesh), 1);
this.deadLightningsMeshes.push(mesh);
this.remove(mesh);
il--;
} else {
i++;
}
}
}
getNextLightningTime(currentTime) {
return currentTime + THREE.MathUtils.lerp(this.stormParams.lightningMinPeriod, this.stormParams.lightningMaxPeriod, Math.random()) / (this.stormParams.maxLightnings + 1);
}
copy(source, recursive) {
super.copy(source, recursive);
this.stormParams.size = source.stormParams.size;
this.stormParams.minHeight = source.stormParams.minHeight;
this.stormParams.maxHeight = source.stormParams.maxHeight;
this.stormParams.maxSlope = source.stormParams.maxSlope;
this.stormParams.maxLightnings = source.stormParams.maxLightnings;
this.stormParams.lightningMinPeriod = source.stormParams.lightningMinPeriod;
this.stormParams.lightningMaxPeriod = source.stormParams.lightningMaxPeriod;
this.stormParams.lightningMinDuration = source.stormParams.lightningMinDuration;
this.stormParams.lightningMaxDuration = source.stormParams.lightningMaxDuration;
this.lightningParameters = LightningStrike.LightningStrike.copyParameters({}, source.lightningParameters);
this.lightningMaterial = source.stormParams.lightningMaterial;
this.onLightningDown = source.onLightningDown;
return this;
}
clone() {
return new this.constructor(this.stormParams).copy(this);
}
}
exports.LightningStorm = LightningStorm;
//# sourceMappingURL=LightningStorm.cjs.map
File diff suppressed because one or more lines are too long
+32
View File
@@ -0,0 +1,32 @@
import { Material, Object3D, Vector3 } from 'three'
import { LightningStrike, RayParameters } from '../geometries/LightningStrike'
export interface StormParams {
size?: number
minHeight?: number
maxHeight?: number
maxSlope?: number
maxLightnings?: number
lightningMinPeriod?: number
lightningMaxPeriod?: number
lightningMinDuration?: number
lightningMaxDuration?: number
lightningParameters?: RayParameters
lightningMaterial?: Material
isEternal?: boolean
onRayPosition?: (source: Vector3, dest: Vector3) => void
onLightningDown?: (lightning: LightningStrike) => void
}
export class LightningStorm extends Object3D {
constructor(stormParams?: StormParams)
update(time: number): void
copy(source: LightningStorm, recursive?: boolean): this
clone(): this
}
+111
View File
@@ -0,0 +1,111 @@
import { Object3D, MeshBasicMaterial, MathUtils, Mesh } from "three";
import { LightningStrike } from "../geometries/LightningStrike.js";
class LightningStorm extends Object3D {
constructor(stormParams = {}) {
super();
this.isLightningStorm = true;
this.stormParams = stormParams;
stormParams.size = stormParams.size !== void 0 ? stormParams.size : 1e3;
stormParams.minHeight = stormParams.minHeight !== void 0 ? stormParams.minHeight : 80;
stormParams.maxHeight = stormParams.maxHeight !== void 0 ? stormParams.maxHeight : 100;
stormParams.maxSlope = stormParams.maxSlope !== void 0 ? stormParams.maxSlope : 1.1;
stormParams.maxLightnings = stormParams.maxLightnings !== void 0 ? stormParams.maxLightnings : 3;
stormParams.lightningMinPeriod = stormParams.lightningMinPeriod !== void 0 ? stormParams.lightningMinPeriod : 3;
stormParams.lightningMaxPeriod = stormParams.lightningMaxPeriod !== void 0 ? stormParams.lightningMaxPeriod : 7;
stormParams.lightningMinDuration = stormParams.lightningMinDuration !== void 0 ? stormParams.lightningMinDuration : 1;
stormParams.lightningMaxDuration = stormParams.lightningMaxDuration !== void 0 ? stormParams.lightningMaxDuration : 2.5;
this.lightningParameters = LightningStrike.copyParameters(
stormParams.lightningParameters,
stormParams.lightningParameters
);
this.lightningParameters.isEternal = false;
this.lightningMaterial = stormParams.lightningMaterial !== void 0 ? stormParams.lightningMaterial : new MeshBasicMaterial({ color: 11599871 });
if (stormParams.onRayPosition !== void 0) {
this.onRayPosition = stormParams.onRayPosition;
} else {
this.onRayPosition = function(source, dest) {
dest.set((Math.random() - 0.5) * stormParams.size, 0, (Math.random() - 0.5) * stormParams.size);
const height = MathUtils.lerp(stormParams.minHeight, stormParams.maxHeight, Math.random());
source.set(stormParams.maxSlope * (2 * Math.random() - 1), 1, stormParams.maxSlope * (2 * Math.random() - 1)).multiplyScalar(height).add(dest);
};
}
this.onLightningDown = stormParams.onLightningDown;
this.inited = false;
this.nextLightningTime = 0;
this.lightningsMeshes = [];
this.deadLightningsMeshes = [];
for (let i = 0; i < this.stormParams.maxLightnings; i++) {
const lightning = new LightningStrike(LightningStrike.copyParameters({}, this.lightningParameters));
const mesh = new Mesh(lightning, this.lightningMaterial);
this.deadLightningsMeshes.push(mesh);
}
}
update(time) {
if (!this.inited) {
this.nextLightningTime = this.getNextLightningTime(time) * Math.random();
this.inited = true;
}
if (time >= this.nextLightningTime) {
const lightningMesh = this.deadLightningsMeshes.pop();
if (lightningMesh) {
const lightningParams1 = LightningStrike.copyParameters(
lightningMesh.geometry.rayParameters,
this.lightningParameters
);
lightningParams1.birthTime = time;
lightningParams1.deathTime = time + MathUtils.lerp(this.stormParams.lightningMinDuration, this.stormParams.lightningMaxDuration, Math.random());
this.onRayPosition(lightningParams1.sourceOffset, lightningParams1.destOffset);
lightningParams1.noiseSeed = Math.random();
this.add(lightningMesh);
this.lightningsMeshes.push(lightningMesh);
}
this.nextLightningTime = this.getNextLightningTime(time);
}
let i = 0, il = this.lightningsMeshes.length;
while (i < il) {
const mesh = this.lightningsMeshes[i];
const lightning = mesh.geometry;
const prevState = lightning.state;
lightning.update(time);
if (prevState === LightningStrike.RAY_PROPAGATING && lightning.state > prevState) {
if (this.onLightningDown) {
this.onLightningDown(lightning);
}
}
if (lightning.state === LightningStrike.RAY_EXTINGUISHED) {
this.lightningsMeshes.splice(this.lightningsMeshes.indexOf(mesh), 1);
this.deadLightningsMeshes.push(mesh);
this.remove(mesh);
il--;
} else {
i++;
}
}
}
getNextLightningTime(currentTime) {
return currentTime + MathUtils.lerp(this.stormParams.lightningMinPeriod, this.stormParams.lightningMaxPeriod, Math.random()) / (this.stormParams.maxLightnings + 1);
}
copy(source, recursive) {
super.copy(source, recursive);
this.stormParams.size = source.stormParams.size;
this.stormParams.minHeight = source.stormParams.minHeight;
this.stormParams.maxHeight = source.stormParams.maxHeight;
this.stormParams.maxSlope = source.stormParams.maxSlope;
this.stormParams.maxLightnings = source.stormParams.maxLightnings;
this.stormParams.lightningMinPeriod = source.stormParams.lightningMinPeriod;
this.stormParams.lightningMaxPeriod = source.stormParams.lightningMaxPeriod;
this.stormParams.lightningMinDuration = source.stormParams.lightningMinDuration;
this.stormParams.lightningMaxDuration = source.stormParams.lightningMaxDuration;
this.lightningParameters = LightningStrike.copyParameters({}, source.lightningParameters);
this.lightningMaterial = source.stormParams.lightningMaterial;
this.onLightningDown = source.onLightningDown;
return this;
}
clone() {
return new this.constructor(this.stormParams).copy(this);
}
}
export {
LightningStorm
};
//# sourceMappingURL=LightningStorm.js.map
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+76
View File
@@ -0,0 +1,76 @@
import { BufferGeometry, Material, Mesh, Color } from 'three'
export class MarchingCubes extends Mesh {
constructor(
resolution: number,
material: Material,
enableUvs?: boolean,
enableColors?: boolean,
maxPolyCount?: number,
)
enableUvs: boolean
enableColors: boolean
resolution: number
// parameters
isolation: number
// size of field, 32 is pushing it in Javascript :)
size: number
size2: number
size3: number
halfsize: number
// deltas
delta: number
yd: number
zd: number
field: Float32Array
normal_cache: Float32Array
palette: Float32Array
maxCount: number
count: number
hasPositions: boolean
hasNormals: boolean
hasColors: boolean
hasUvs: boolean
positionArray: Float32Array
normalArray: Float32Array
uvArray: Float32Array
colorArray: Float32Array
begin(): void
end(): void
init(resolution: number): void
addBall(ballx: number, bally: number, ballz: number, strength: number, subtract: number, colors?: Color): void
addPlaneX(strength: number, subtract: number): void
addPlaneY(strength: number, subtract: number): void
addPlaneZ(strength: number, subtract: number): void
setCell(x: number, y: number, z: number, value: number): void
getCell(x: number, y: number, z: number): number
blur(intensity: number): void
reset(): void
update(): void
render(renderCallback: any): void
generateGeometry(): BufferGeometry
generateBufferGeometry(): BufferGeometry
}
export const edgeTable: Int32Array[]
export const triTable: Int32Array[]
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+212
View File
@@ -0,0 +1,212 @@
"use strict";
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const THREE = require("three");
const constants = require("../_polyfill/constants.cjs");
const Reflector = /* @__PURE__ */ (() => {
const _Reflector = class extends THREE.Mesh {
constructor(geometry, options = {}) {
super(geometry);
this.isReflector = true;
this.type = "Reflector";
this.camera = new THREE.PerspectiveCamera();
const scope = this;
const color = options.color !== void 0 ? new THREE.Color(options.color) : new THREE.Color(8355711);
const textureWidth = options.textureWidth || 512;
const textureHeight = options.textureHeight || 512;
const clipBias = options.clipBias || 0;
const shader = options.shader || _Reflector.ReflectorShader;
const multisample = options.multisample !== void 0 ? options.multisample : 4;
const reflectorPlane = new THREE.Plane();
const normal = new THREE.Vector3();
const reflectorWorldPosition = new THREE.Vector3();
const cameraWorldPosition = new THREE.Vector3();
const rotationMatrix = new THREE.Matrix4();
const lookAtPosition = new THREE.Vector3(0, 0, -1);
const clipPlane = new THREE.Vector4();
const view = new THREE.Vector3();
const target = new THREE.Vector3();
const q = new THREE.Vector4();
const textureMatrix = new THREE.Matrix4();
const virtualCamera = this.camera;
const renderTarget = new THREE.WebGLRenderTarget(textureWidth, textureHeight, {
samples: multisample,
type: THREE.HalfFloatType
});
const material = new THREE.ShaderMaterial({
uniforms: THREE.UniformsUtils.clone(shader.uniforms),
fragmentShader: shader.fragmentShader,
vertexShader: shader.vertexShader
});
material.uniforms["tDiffuse"].value = renderTarget.texture;
material.uniforms["color"].value = color;
material.uniforms["textureMatrix"].value = textureMatrix;
this.material = material;
this.onBeforeRender = function(renderer, scene, camera) {
reflectorWorldPosition.setFromMatrixPosition(scope.matrixWorld);
cameraWorldPosition.setFromMatrixPosition(camera.matrixWorld);
rotationMatrix.extractRotation(scope.matrixWorld);
normal.set(0, 0, 1);
normal.applyMatrix4(rotationMatrix);
view.subVectors(reflectorWorldPosition, cameraWorldPosition);
if (view.dot(normal) > 0)
return;
view.reflect(normal).negate();
view.add(reflectorWorldPosition);
rotationMatrix.extractRotation(camera.matrixWorld);
lookAtPosition.set(0, 0, -1);
lookAtPosition.applyMatrix4(rotationMatrix);
lookAtPosition.add(cameraWorldPosition);
target.subVectors(reflectorWorldPosition, lookAtPosition);
target.reflect(normal).negate();
target.add(reflectorWorldPosition);
virtualCamera.position.copy(view);
virtualCamera.up.set(0, 1, 0);
virtualCamera.up.applyMatrix4(rotationMatrix);
virtualCamera.up.reflect(normal);
virtualCamera.lookAt(target);
virtualCamera.far = camera.far;
virtualCamera.updateMatrixWorld();
virtualCamera.projectionMatrix.copy(camera.projectionMatrix);
textureMatrix.set(0.5, 0, 0, 0.5, 0, 0.5, 0, 0.5, 0, 0, 0.5, 0.5, 0, 0, 0, 1);
textureMatrix.multiply(virtualCamera.projectionMatrix);
textureMatrix.multiply(virtualCamera.matrixWorldInverse);
textureMatrix.multiply(scope.matrixWorld);
reflectorPlane.setFromNormalAndCoplanarPoint(normal, reflectorWorldPosition);
reflectorPlane.applyMatrix4(virtualCamera.matrixWorldInverse);
clipPlane.set(
reflectorPlane.normal.x,
reflectorPlane.normal.y,
reflectorPlane.normal.z,
reflectorPlane.constant
);
const projectionMatrix = virtualCamera.projectionMatrix;
q.x = (Math.sign(clipPlane.x) + projectionMatrix.elements[8]) / projectionMatrix.elements[0];
q.y = (Math.sign(clipPlane.y) + projectionMatrix.elements[9]) / projectionMatrix.elements[5];
q.z = -1;
q.w = (1 + projectionMatrix.elements[10]) / projectionMatrix.elements[14];
clipPlane.multiplyScalar(2 / clipPlane.dot(q));
projectionMatrix.elements[2] = clipPlane.x;
projectionMatrix.elements[6] = clipPlane.y;
projectionMatrix.elements[10] = clipPlane.z + 1 - clipBias;
projectionMatrix.elements[14] = clipPlane.w;
scope.visible = false;
const currentRenderTarget = renderer.getRenderTarget();
const currentXrEnabled = renderer.xr.enabled;
const currentShadowAutoUpdate = renderer.shadowMap.autoUpdate;
const currentToneMapping = renderer.toneMapping;
let isSRGB = false;
if ("outputColorSpace" in renderer)
isSRGB = renderer.outputColorSpace === "srgb";
else
isSRGB = renderer.outputEncoding === 3001;
renderer.xr.enabled = false;
renderer.shadowMap.autoUpdate = false;
if ("outputColorSpace" in renderer)
renderer.outputColorSpace = "srgb-linear";
else
renderer.outputEncoding = 3e3;
renderer.toneMapping = THREE.NoToneMapping;
renderer.setRenderTarget(renderTarget);
renderer.state.buffers.depth.setMask(true);
if (renderer.autoClear === false)
renderer.clear();
renderer.render(scene, virtualCamera);
renderer.xr.enabled = currentXrEnabled;
renderer.shadowMap.autoUpdate = currentShadowAutoUpdate;
renderer.toneMapping = currentToneMapping;
if ("outputColorSpace" in renderer)
renderer.outputColorSpace = isSRGB ? "srgb" : "srgb-linear";
else
renderer.outputEncoding = isSRGB ? 3001 : 3e3;
renderer.setRenderTarget(currentRenderTarget);
const viewport = camera.viewport;
if (viewport !== void 0) {
renderer.state.viewport(viewport);
}
scope.visible = true;
};
this.getRenderTarget = function() {
return renderTarget;
};
this.dispose = function() {
renderTarget.dispose();
scope.material.dispose();
};
}
};
let Reflector2 = _Reflector;
__publicField(Reflector2, "ReflectorShader", {
uniforms: {
color: {
value: null
},
tDiffuse: {
value: null
},
textureMatrix: {
value: null
}
},
vertexShader: (
/* glsl */
`
uniform mat4 textureMatrix;
varying vec4 vUv;
#include <common>
#include <logdepthbuf_pars_vertex>
void main() {
vUv = textureMatrix * vec4( position, 1.0 );
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
#include <logdepthbuf_vertex>
}`
),
fragmentShader: (
/* glsl */
`
uniform vec3 color;
uniform sampler2D tDiffuse;
varying vec4 vUv;
#include <logdepthbuf_pars_fragment>
float blendOverlay( float base, float blend ) {
return( base < 0.5 ? ( 2.0 * base * blend ) : ( 1.0 - 2.0 * ( 1.0 - base ) * ( 1.0 - blend ) ) );
}
vec3 blendOverlay( vec3 base, vec3 blend ) {
return vec3( blendOverlay( base.r, blend.r ), blendOverlay( base.g, blend.g ), blendOverlay( base.b, blend.b ) );
}
void main() {
#include <logdepthbuf_fragment>
vec4 base = texture2DProj( tDiffuse, vUv );
gl_FragColor = vec4( blendOverlay( base.rgb, color ), 1.0 );
#include <tonemapping_fragment>
#include <${constants.version >= 154 ? "colorspace_fragment" : "encodings_fragment"}>
}`
)
});
return Reflector2;
})();
exports.Reflector = Reflector;
//# sourceMappingURL=Reflector.cjs.map
File diff suppressed because one or more lines are too long
+23
View File
@@ -0,0 +1,23 @@
import { Mesh, BufferGeometry, Color, WebGLRenderTarget, PerspectiveCamera } from 'three'
import { TextureEncoding } from '../types/shared'
export interface ReflectorOptions {
color?: Color | string | number
textureWidth?: number
textureHeight?: number
clipBias?: number
shader?: object
encoding?: TextureEncoding
multisample?: number
}
export class Reflector extends Mesh {
type: 'Reflector'
camera: PerspectiveCamera
constructor(geometry?: BufferGeometry, options?: ReflectorOptions)
getRenderTarget(): WebGLRenderTarget
dispose(): void
}
+212
View File
@@ -0,0 +1,212 @@
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
import { Mesh, PerspectiveCamera, Color, Plane, Vector3, Matrix4, Vector4, WebGLRenderTarget, HalfFloatType, ShaderMaterial, UniformsUtils, NoToneMapping } from "three";
import { version } from "../_polyfill/constants.js";
const Reflector = /* @__PURE__ */ (() => {
const _Reflector = class extends Mesh {
constructor(geometry, options = {}) {
super(geometry);
this.isReflector = true;
this.type = "Reflector";
this.camera = new PerspectiveCamera();
const scope = this;
const color = options.color !== void 0 ? new Color(options.color) : new Color(8355711);
const textureWidth = options.textureWidth || 512;
const textureHeight = options.textureHeight || 512;
const clipBias = options.clipBias || 0;
const shader = options.shader || _Reflector.ReflectorShader;
const multisample = options.multisample !== void 0 ? options.multisample : 4;
const reflectorPlane = new Plane();
const normal = new Vector3();
const reflectorWorldPosition = new Vector3();
const cameraWorldPosition = new Vector3();
const rotationMatrix = new Matrix4();
const lookAtPosition = new Vector3(0, 0, -1);
const clipPlane = new Vector4();
const view = new Vector3();
const target = new Vector3();
const q = new Vector4();
const textureMatrix = new Matrix4();
const virtualCamera = this.camera;
const renderTarget = new WebGLRenderTarget(textureWidth, textureHeight, {
samples: multisample,
type: HalfFloatType
});
const material = new ShaderMaterial({
uniforms: UniformsUtils.clone(shader.uniforms),
fragmentShader: shader.fragmentShader,
vertexShader: shader.vertexShader
});
material.uniforms["tDiffuse"].value = renderTarget.texture;
material.uniforms["color"].value = color;
material.uniforms["textureMatrix"].value = textureMatrix;
this.material = material;
this.onBeforeRender = function(renderer, scene, camera) {
reflectorWorldPosition.setFromMatrixPosition(scope.matrixWorld);
cameraWorldPosition.setFromMatrixPosition(camera.matrixWorld);
rotationMatrix.extractRotation(scope.matrixWorld);
normal.set(0, 0, 1);
normal.applyMatrix4(rotationMatrix);
view.subVectors(reflectorWorldPosition, cameraWorldPosition);
if (view.dot(normal) > 0)
return;
view.reflect(normal).negate();
view.add(reflectorWorldPosition);
rotationMatrix.extractRotation(camera.matrixWorld);
lookAtPosition.set(0, 0, -1);
lookAtPosition.applyMatrix4(rotationMatrix);
lookAtPosition.add(cameraWorldPosition);
target.subVectors(reflectorWorldPosition, lookAtPosition);
target.reflect(normal).negate();
target.add(reflectorWorldPosition);
virtualCamera.position.copy(view);
virtualCamera.up.set(0, 1, 0);
virtualCamera.up.applyMatrix4(rotationMatrix);
virtualCamera.up.reflect(normal);
virtualCamera.lookAt(target);
virtualCamera.far = camera.far;
virtualCamera.updateMatrixWorld();
virtualCamera.projectionMatrix.copy(camera.projectionMatrix);
textureMatrix.set(0.5, 0, 0, 0.5, 0, 0.5, 0, 0.5, 0, 0, 0.5, 0.5, 0, 0, 0, 1);
textureMatrix.multiply(virtualCamera.projectionMatrix);
textureMatrix.multiply(virtualCamera.matrixWorldInverse);
textureMatrix.multiply(scope.matrixWorld);
reflectorPlane.setFromNormalAndCoplanarPoint(normal, reflectorWorldPosition);
reflectorPlane.applyMatrix4(virtualCamera.matrixWorldInverse);
clipPlane.set(
reflectorPlane.normal.x,
reflectorPlane.normal.y,
reflectorPlane.normal.z,
reflectorPlane.constant
);
const projectionMatrix = virtualCamera.projectionMatrix;
q.x = (Math.sign(clipPlane.x) + projectionMatrix.elements[8]) / projectionMatrix.elements[0];
q.y = (Math.sign(clipPlane.y) + projectionMatrix.elements[9]) / projectionMatrix.elements[5];
q.z = -1;
q.w = (1 + projectionMatrix.elements[10]) / projectionMatrix.elements[14];
clipPlane.multiplyScalar(2 / clipPlane.dot(q));
projectionMatrix.elements[2] = clipPlane.x;
projectionMatrix.elements[6] = clipPlane.y;
projectionMatrix.elements[10] = clipPlane.z + 1 - clipBias;
projectionMatrix.elements[14] = clipPlane.w;
scope.visible = false;
const currentRenderTarget = renderer.getRenderTarget();
const currentXrEnabled = renderer.xr.enabled;
const currentShadowAutoUpdate = renderer.shadowMap.autoUpdate;
const currentToneMapping = renderer.toneMapping;
let isSRGB = false;
if ("outputColorSpace" in renderer)
isSRGB = renderer.outputColorSpace === "srgb";
else
isSRGB = renderer.outputEncoding === 3001;
renderer.xr.enabled = false;
renderer.shadowMap.autoUpdate = false;
if ("outputColorSpace" in renderer)
renderer.outputColorSpace = "srgb-linear";
else
renderer.outputEncoding = 3e3;
renderer.toneMapping = NoToneMapping;
renderer.setRenderTarget(renderTarget);
renderer.state.buffers.depth.setMask(true);
if (renderer.autoClear === false)
renderer.clear();
renderer.render(scene, virtualCamera);
renderer.xr.enabled = currentXrEnabled;
renderer.shadowMap.autoUpdate = currentShadowAutoUpdate;
renderer.toneMapping = currentToneMapping;
if ("outputColorSpace" in renderer)
renderer.outputColorSpace = isSRGB ? "srgb" : "srgb-linear";
else
renderer.outputEncoding = isSRGB ? 3001 : 3e3;
renderer.setRenderTarget(currentRenderTarget);
const viewport = camera.viewport;
if (viewport !== void 0) {
renderer.state.viewport(viewport);
}
scope.visible = true;
};
this.getRenderTarget = function() {
return renderTarget;
};
this.dispose = function() {
renderTarget.dispose();
scope.material.dispose();
};
}
};
let Reflector2 = _Reflector;
__publicField(Reflector2, "ReflectorShader", {
uniforms: {
color: {
value: null
},
tDiffuse: {
value: null
},
textureMatrix: {
value: null
}
},
vertexShader: (
/* glsl */
`
uniform mat4 textureMatrix;
varying vec4 vUv;
#include <common>
#include <logdepthbuf_pars_vertex>
void main() {
vUv = textureMatrix * vec4( position, 1.0 );
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
#include <logdepthbuf_vertex>
}`
),
fragmentShader: (
/* glsl */
`
uniform vec3 color;
uniform sampler2D tDiffuse;
varying vec4 vUv;
#include <logdepthbuf_pars_fragment>
float blendOverlay( float base, float blend ) {
return( base < 0.5 ? ( 2.0 * base * blend ) : ( 1.0 - 2.0 * ( 1.0 - base ) * ( 1.0 - blend ) ) );
}
vec3 blendOverlay( vec3 base, vec3 blend ) {
return vec3( blendOverlay( base.r, blend.r ), blendOverlay( base.g, blend.g ), blendOverlay( base.b, blend.b ) );
}
void main() {
#include <logdepthbuf_fragment>
vec4 base = texture2DProj( tDiffuse, vUv );
gl_FragColor = vec4( blendOverlay( base.rgb, color ), 1.0 );
#include <tonemapping_fragment>
#include <${version >= 154 ? "colorspace_fragment" : "encodings_fragment"}>
}`
)
});
return Reflector2;
})();
export {
Reflector
};
//# sourceMappingURL=Reflector.js.map
File diff suppressed because one or more lines are too long
+264
View File
@@ -0,0 +1,264 @@
"use strict";
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const THREE = require("three");
const ReflectorForSSRPass = /* @__PURE__ */ (() => {
const _ReflectorForSSRPass = class extends THREE.Mesh {
constructor(geometry, options = {}) {
super(geometry);
this.isReflectorForSSRPass = true;
this.type = "ReflectorForSSRPass";
const scope = this;
const color = options.color !== void 0 ? new THREE.Color(options.color) : new THREE.Color(8355711);
const textureWidth = options.textureWidth || 512;
const textureHeight = options.textureHeight || 512;
const clipBias = options.clipBias || 0;
const shader = options.shader || _ReflectorForSSRPass.ReflectorShader;
const useDepthTexture = options.useDepthTexture === true;
const yAxis = new THREE.Vector3(0, 1, 0);
const vecTemp0 = new THREE.Vector3();
const vecTemp1 = new THREE.Vector3();
scope.needsUpdate = false;
scope.maxDistance = _ReflectorForSSRPass.ReflectorShader.uniforms.maxDistance.value;
scope.opacity = _ReflectorForSSRPass.ReflectorShader.uniforms.opacity.value;
scope.color = color;
scope.resolution = options.resolution || new THREE.Vector2(window.innerWidth, window.innerHeight);
scope._distanceAttenuation = _ReflectorForSSRPass.ReflectorShader.defines.DISTANCE_ATTENUATION;
Object.defineProperty(scope, "distanceAttenuation", {
get() {
return scope._distanceAttenuation;
},
set(val) {
if (scope._distanceAttenuation === val)
return;
scope._distanceAttenuation = val;
scope.material.defines.DISTANCE_ATTENUATION = val;
scope.material.needsUpdate = true;
}
});
scope._fresnel = _ReflectorForSSRPass.ReflectorShader.defines.FRESNEL;
Object.defineProperty(scope, "fresnel", {
get() {
return scope._fresnel;
},
set(val) {
if (scope._fresnel === val)
return;
scope._fresnel = val;
scope.material.defines.FRESNEL = val;
scope.material.needsUpdate = true;
}
});
const normal = new THREE.Vector3();
const reflectorWorldPosition = new THREE.Vector3();
const cameraWorldPosition = new THREE.Vector3();
const rotationMatrix = new THREE.Matrix4();
const lookAtPosition = new THREE.Vector3(0, 0, -1);
const view = new THREE.Vector3();
const target = new THREE.Vector3();
const textureMatrix = new THREE.Matrix4();
const virtualCamera = new THREE.PerspectiveCamera();
let depthTexture;
if (useDepthTexture) {
depthTexture = new THREE.DepthTexture();
depthTexture.type = THREE.UnsignedShortType;
depthTexture.minFilter = THREE.NearestFilter;
depthTexture.magFilter = THREE.NearestFilter;
}
const parameters = {
depthTexture: useDepthTexture ? depthTexture : null,
type: THREE.HalfFloatType
};
const renderTarget = new THREE.WebGLRenderTarget(textureWidth, textureHeight, parameters);
const material = new THREE.ShaderMaterial({
transparent: useDepthTexture,
defines: Object.assign({}, _ReflectorForSSRPass.ReflectorShader.defines, {
useDepthTexture
}),
uniforms: THREE.UniformsUtils.clone(shader.uniforms),
fragmentShader: shader.fragmentShader,
vertexShader: shader.vertexShader
});
material.uniforms["tDiffuse"].value = renderTarget.texture;
material.uniforms["color"].value = scope.color;
material.uniforms["textureMatrix"].value = textureMatrix;
if (useDepthTexture) {
material.uniforms["tDepth"].value = renderTarget.depthTexture;
}
this.material = material;
const globalPlane = new THREE.Plane(new THREE.Vector3(0, 1, 0), clipBias);
const globalPlanes = [globalPlane];
this.doRender = function(renderer, scene, camera) {
material.uniforms["maxDistance"].value = scope.maxDistance;
material.uniforms["color"].value = scope.color;
material.uniforms["opacity"].value = scope.opacity;
vecTemp0.copy(camera.position).normalize();
vecTemp1.copy(vecTemp0).reflect(yAxis);
material.uniforms["fresnelCoe"].value = (vecTemp0.dot(vecTemp1) + 1) / 2;
reflectorWorldPosition.setFromMatrixPosition(scope.matrixWorld);
cameraWorldPosition.setFromMatrixPosition(camera.matrixWorld);
rotationMatrix.extractRotation(scope.matrixWorld);
normal.set(0, 0, 1);
normal.applyMatrix4(rotationMatrix);
view.subVectors(reflectorWorldPosition, cameraWorldPosition);
if (view.dot(normal) > 0)
return;
view.reflect(normal).negate();
view.add(reflectorWorldPosition);
rotationMatrix.extractRotation(camera.matrixWorld);
lookAtPosition.set(0, 0, -1);
lookAtPosition.applyMatrix4(rotationMatrix);
lookAtPosition.add(cameraWorldPosition);
target.subVectors(reflectorWorldPosition, lookAtPosition);
target.reflect(normal).negate();
target.add(reflectorWorldPosition);
virtualCamera.position.copy(view);
virtualCamera.up.set(0, 1, 0);
virtualCamera.up.applyMatrix4(rotationMatrix);
virtualCamera.up.reflect(normal);
virtualCamera.lookAt(target);
virtualCamera.far = camera.far;
virtualCamera.updateMatrixWorld();
virtualCamera.projectionMatrix.copy(camera.projectionMatrix);
material.uniforms["virtualCameraNear"].value = camera.near;
material.uniforms["virtualCameraFar"].value = camera.far;
material.uniforms["virtualCameraMatrixWorld"].value = virtualCamera.matrixWorld;
material.uniforms["virtualCameraProjectionMatrix"].value = camera.projectionMatrix;
material.uniforms["virtualCameraProjectionMatrixInverse"].value = camera.projectionMatrixInverse;
material.uniforms["resolution"].value = scope.resolution;
textureMatrix.set(0.5, 0, 0, 0.5, 0, 0.5, 0, 0.5, 0, 0, 0.5, 0.5, 0, 0, 0, 1);
textureMatrix.multiply(virtualCamera.projectionMatrix);
textureMatrix.multiply(virtualCamera.matrixWorldInverse);
textureMatrix.multiply(scope.matrixWorld);
const currentRenderTarget = renderer.getRenderTarget();
const currentXrEnabled = renderer.xr.enabled;
const currentShadowAutoUpdate = renderer.shadowMap.autoUpdate;
const currentClippingPlanes = renderer.clippingPlanes;
renderer.xr.enabled = false;
renderer.shadowMap.autoUpdate = false;
renderer.clippingPlanes = globalPlanes;
renderer.setRenderTarget(renderTarget);
renderer.state.buffers.depth.setMask(true);
if (renderer.autoClear === false)
renderer.clear();
renderer.render(scene, virtualCamera);
renderer.xr.enabled = currentXrEnabled;
renderer.shadowMap.autoUpdate = currentShadowAutoUpdate;
renderer.clippingPlanes = currentClippingPlanes;
renderer.setRenderTarget(currentRenderTarget);
const viewport = camera.viewport;
if (viewport !== void 0) {
renderer.state.viewport(viewport);
}
};
this.getRenderTarget = function() {
return renderTarget;
};
}
};
let ReflectorForSSRPass2 = _ReflectorForSSRPass;
__publicField(ReflectorForSSRPass2, "ReflectorShader", {
defines: {
DISTANCE_ATTENUATION: true,
FRESNEL: true
},
uniforms: {
color: { value: null },
tDiffuse: { value: null },
tDepth: { value: null },
textureMatrix: { value: new THREE.Matrix4() },
maxDistance: { value: 180 },
opacity: { value: 0.5 },
fresnelCoe: { value: null },
virtualCameraNear: { value: null },
virtualCameraFar: { value: null },
virtualCameraProjectionMatrix: { value: new THREE.Matrix4() },
virtualCameraMatrixWorld: { value: new THREE.Matrix4() },
virtualCameraProjectionMatrixInverse: { value: new THREE.Matrix4() },
resolution: { value: new THREE.Vector2() }
},
vertexShader: (
/* glsl */
`
uniform mat4 textureMatrix;
varying vec4 vUv;
void main() {
vUv = textureMatrix * vec4( position, 1.0 );
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}`
),
fragmentShader: (
/* glsl */
`
uniform vec3 color;
uniform sampler2D tDiffuse;
uniform sampler2D tDepth;
uniform float maxDistance;
uniform float opacity;
uniform float fresnelCoe;
uniform float virtualCameraNear;
uniform float virtualCameraFar;
uniform mat4 virtualCameraProjectionMatrix;
uniform mat4 virtualCameraProjectionMatrixInverse;
uniform mat4 virtualCameraMatrixWorld;
uniform vec2 resolution;
varying vec4 vUv;
#include <packing>
float blendOverlay( float base, float blend ) {
return( base < 0.5 ? ( 2.0 * base * blend ) : ( 1.0 - 2.0 * ( 1.0 - base ) * ( 1.0 - blend ) ) );
}
vec3 blendOverlay( vec3 base, vec3 blend ) {
return vec3( blendOverlay( base.r, blend.r ), blendOverlay( base.g, blend.g ), blendOverlay( base.b, blend.b ) );
}
float getDepth( const in vec2 uv ) {
return texture2D( tDepth, uv ).x;
}
float getViewZ( const in float depth ) {
return perspectiveDepthToViewZ( depth, virtualCameraNear, virtualCameraFar );
}
vec3 getViewPosition( const in vec2 uv, const in float depth/*clip space*/, const in float clipW ) {
vec4 clipPosition = vec4( ( vec3( uv, depth ) - 0.5 ) * 2.0, 1.0 );//ndc
clipPosition *= clipW; //clip
return ( virtualCameraProjectionMatrixInverse * clipPosition ).xyz;//view
}
void main() {
vec4 base = texture2DProj( tDiffuse, vUv );
#ifdef useDepthTexture
vec2 uv=(gl_FragCoord.xy-.5)/resolution.xy;
uv.x=1.-uv.x;
float depth = texture2DProj( tDepth, vUv ).r;
float viewZ = getViewZ( depth );
float clipW = virtualCameraProjectionMatrix[2][3] * viewZ+virtualCameraProjectionMatrix[3][3];
vec3 viewPosition=getViewPosition( uv, depth, clipW );
vec3 worldPosition=(virtualCameraMatrixWorld*vec4(viewPosition,1)).xyz;
if(worldPosition.y>maxDistance) discard;
float op=opacity;
#ifdef DISTANCE_ATTENUATION
float ratio=1.-(worldPosition.y/maxDistance);
float attenuation=ratio*ratio;
op=opacity*attenuation;
#endif
#ifdef FRESNEL
op*=fresnelCoe;
#endif
gl_FragColor = vec4( blendOverlay( base.rgb, color ), op );
#else
gl_FragColor = vec4( blendOverlay( base.rgb, color ), 1.0 );
#endif
}
`
)
});
return ReflectorForSSRPass2;
})();
exports.ReflectorForSSRPass = ReflectorForSSRPass;
//# sourceMappingURL=ReflectorForSSRPass.cjs.map
File diff suppressed because one or more lines are too long
+48
View File
@@ -0,0 +1,48 @@
import { Mesh, ShaderMaterial, WebGLRenderTarget, BufferGeometry, WebGLRenderer, Scene, Camera, IUniform } from 'three'
export interface ReflectorShader {
defines: {
DISTANCE_ATTENUATION: boolean
FRESNEL: boolean
}
uniforms: {
[key: string]: IUniform
}
vertexShader: string
fragmentShader: string
}
export interface ReflectorForSSRPassOptions {
clipBias?: number | undefined
textureWidth?: number | undefined
textureHeight?: number | undefined
color?: number | undefined
useDepthTexture?: boolean | undefined
shader?: ReflectorShader | undefined
}
export class ReflectorForSSRPass<TGeometry extends BufferGeometry = BufferGeometry> extends Mesh<TGeometry> {
type: 'ReflectorForSSRPass'
options: ReflectorForSSRPassOptions
static ReflectorShader: ReflectorShader
needsUpdate: boolean
maxDistance: number
opacity: number
get distanceAttenuation(): boolean
set distanceAttenuation(val: boolean)
get fresnel(): boolean
set fresnel(val: boolean)
material: ShaderMaterial
renderTarget: WebGLRenderTarget
constructor(geometry: TGeometry, options: ReflectorForSSRPassOptions)
doRender: (renderer: WebGLRenderer, scene: Scene, camera: Camera) => void
getRenderTarget: () => WebGLRenderTarget
}
+264
View File
@@ -0,0 +1,264 @@
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
import { Mesh, Matrix4, Vector2, Color, Vector3, PerspectiveCamera, DepthTexture, UnsignedShortType, NearestFilter, WebGLRenderTarget, ShaderMaterial, UniformsUtils, Plane, HalfFloatType } from "three";
const ReflectorForSSRPass = /* @__PURE__ */ (() => {
const _ReflectorForSSRPass = class extends Mesh {
constructor(geometry, options = {}) {
super(geometry);
this.isReflectorForSSRPass = true;
this.type = "ReflectorForSSRPass";
const scope = this;
const color = options.color !== void 0 ? new Color(options.color) : new Color(8355711);
const textureWidth = options.textureWidth || 512;
const textureHeight = options.textureHeight || 512;
const clipBias = options.clipBias || 0;
const shader = options.shader || _ReflectorForSSRPass.ReflectorShader;
const useDepthTexture = options.useDepthTexture === true;
const yAxis = new Vector3(0, 1, 0);
const vecTemp0 = new Vector3();
const vecTemp1 = new Vector3();
scope.needsUpdate = false;
scope.maxDistance = _ReflectorForSSRPass.ReflectorShader.uniforms.maxDistance.value;
scope.opacity = _ReflectorForSSRPass.ReflectorShader.uniforms.opacity.value;
scope.color = color;
scope.resolution = options.resolution || new Vector2(window.innerWidth, window.innerHeight);
scope._distanceAttenuation = _ReflectorForSSRPass.ReflectorShader.defines.DISTANCE_ATTENUATION;
Object.defineProperty(scope, "distanceAttenuation", {
get() {
return scope._distanceAttenuation;
},
set(val) {
if (scope._distanceAttenuation === val)
return;
scope._distanceAttenuation = val;
scope.material.defines.DISTANCE_ATTENUATION = val;
scope.material.needsUpdate = true;
}
});
scope._fresnel = _ReflectorForSSRPass.ReflectorShader.defines.FRESNEL;
Object.defineProperty(scope, "fresnel", {
get() {
return scope._fresnel;
},
set(val) {
if (scope._fresnel === val)
return;
scope._fresnel = val;
scope.material.defines.FRESNEL = val;
scope.material.needsUpdate = true;
}
});
const normal = new Vector3();
const reflectorWorldPosition = new Vector3();
const cameraWorldPosition = new Vector3();
const rotationMatrix = new Matrix4();
const lookAtPosition = new Vector3(0, 0, -1);
const view = new Vector3();
const target = new Vector3();
const textureMatrix = new Matrix4();
const virtualCamera = new PerspectiveCamera();
let depthTexture;
if (useDepthTexture) {
depthTexture = new DepthTexture();
depthTexture.type = UnsignedShortType;
depthTexture.minFilter = NearestFilter;
depthTexture.magFilter = NearestFilter;
}
const parameters = {
depthTexture: useDepthTexture ? depthTexture : null,
type: HalfFloatType
};
const renderTarget = new WebGLRenderTarget(textureWidth, textureHeight, parameters);
const material = new ShaderMaterial({
transparent: useDepthTexture,
defines: Object.assign({}, _ReflectorForSSRPass.ReflectorShader.defines, {
useDepthTexture
}),
uniforms: UniformsUtils.clone(shader.uniforms),
fragmentShader: shader.fragmentShader,
vertexShader: shader.vertexShader
});
material.uniforms["tDiffuse"].value = renderTarget.texture;
material.uniforms["color"].value = scope.color;
material.uniforms["textureMatrix"].value = textureMatrix;
if (useDepthTexture) {
material.uniforms["tDepth"].value = renderTarget.depthTexture;
}
this.material = material;
const globalPlane = new Plane(new Vector3(0, 1, 0), clipBias);
const globalPlanes = [globalPlane];
this.doRender = function(renderer, scene, camera) {
material.uniforms["maxDistance"].value = scope.maxDistance;
material.uniforms["color"].value = scope.color;
material.uniforms["opacity"].value = scope.opacity;
vecTemp0.copy(camera.position).normalize();
vecTemp1.copy(vecTemp0).reflect(yAxis);
material.uniforms["fresnelCoe"].value = (vecTemp0.dot(vecTemp1) + 1) / 2;
reflectorWorldPosition.setFromMatrixPosition(scope.matrixWorld);
cameraWorldPosition.setFromMatrixPosition(camera.matrixWorld);
rotationMatrix.extractRotation(scope.matrixWorld);
normal.set(0, 0, 1);
normal.applyMatrix4(rotationMatrix);
view.subVectors(reflectorWorldPosition, cameraWorldPosition);
if (view.dot(normal) > 0)
return;
view.reflect(normal).negate();
view.add(reflectorWorldPosition);
rotationMatrix.extractRotation(camera.matrixWorld);
lookAtPosition.set(0, 0, -1);
lookAtPosition.applyMatrix4(rotationMatrix);
lookAtPosition.add(cameraWorldPosition);
target.subVectors(reflectorWorldPosition, lookAtPosition);
target.reflect(normal).negate();
target.add(reflectorWorldPosition);
virtualCamera.position.copy(view);
virtualCamera.up.set(0, 1, 0);
virtualCamera.up.applyMatrix4(rotationMatrix);
virtualCamera.up.reflect(normal);
virtualCamera.lookAt(target);
virtualCamera.far = camera.far;
virtualCamera.updateMatrixWorld();
virtualCamera.projectionMatrix.copy(camera.projectionMatrix);
material.uniforms["virtualCameraNear"].value = camera.near;
material.uniforms["virtualCameraFar"].value = camera.far;
material.uniforms["virtualCameraMatrixWorld"].value = virtualCamera.matrixWorld;
material.uniforms["virtualCameraProjectionMatrix"].value = camera.projectionMatrix;
material.uniforms["virtualCameraProjectionMatrixInverse"].value = camera.projectionMatrixInverse;
material.uniforms["resolution"].value = scope.resolution;
textureMatrix.set(0.5, 0, 0, 0.5, 0, 0.5, 0, 0.5, 0, 0, 0.5, 0.5, 0, 0, 0, 1);
textureMatrix.multiply(virtualCamera.projectionMatrix);
textureMatrix.multiply(virtualCamera.matrixWorldInverse);
textureMatrix.multiply(scope.matrixWorld);
const currentRenderTarget = renderer.getRenderTarget();
const currentXrEnabled = renderer.xr.enabled;
const currentShadowAutoUpdate = renderer.shadowMap.autoUpdate;
const currentClippingPlanes = renderer.clippingPlanes;
renderer.xr.enabled = false;
renderer.shadowMap.autoUpdate = false;
renderer.clippingPlanes = globalPlanes;
renderer.setRenderTarget(renderTarget);
renderer.state.buffers.depth.setMask(true);
if (renderer.autoClear === false)
renderer.clear();
renderer.render(scene, virtualCamera);
renderer.xr.enabled = currentXrEnabled;
renderer.shadowMap.autoUpdate = currentShadowAutoUpdate;
renderer.clippingPlanes = currentClippingPlanes;
renderer.setRenderTarget(currentRenderTarget);
const viewport = camera.viewport;
if (viewport !== void 0) {
renderer.state.viewport(viewport);
}
};
this.getRenderTarget = function() {
return renderTarget;
};
}
};
let ReflectorForSSRPass2 = _ReflectorForSSRPass;
__publicField(ReflectorForSSRPass2, "ReflectorShader", {
defines: {
DISTANCE_ATTENUATION: true,
FRESNEL: true
},
uniforms: {
color: { value: null },
tDiffuse: { value: null },
tDepth: { value: null },
textureMatrix: { value: new Matrix4() },
maxDistance: { value: 180 },
opacity: { value: 0.5 },
fresnelCoe: { value: null },
virtualCameraNear: { value: null },
virtualCameraFar: { value: null },
virtualCameraProjectionMatrix: { value: new Matrix4() },
virtualCameraMatrixWorld: { value: new Matrix4() },
virtualCameraProjectionMatrixInverse: { value: new Matrix4() },
resolution: { value: new Vector2() }
},
vertexShader: (
/* glsl */
`
uniform mat4 textureMatrix;
varying vec4 vUv;
void main() {
vUv = textureMatrix * vec4( position, 1.0 );
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}`
),
fragmentShader: (
/* glsl */
`
uniform vec3 color;
uniform sampler2D tDiffuse;
uniform sampler2D tDepth;
uniform float maxDistance;
uniform float opacity;
uniform float fresnelCoe;
uniform float virtualCameraNear;
uniform float virtualCameraFar;
uniform mat4 virtualCameraProjectionMatrix;
uniform mat4 virtualCameraProjectionMatrixInverse;
uniform mat4 virtualCameraMatrixWorld;
uniform vec2 resolution;
varying vec4 vUv;
#include <packing>
float blendOverlay( float base, float blend ) {
return( base < 0.5 ? ( 2.0 * base * blend ) : ( 1.0 - 2.0 * ( 1.0 - base ) * ( 1.0 - blend ) ) );
}
vec3 blendOverlay( vec3 base, vec3 blend ) {
return vec3( blendOverlay( base.r, blend.r ), blendOverlay( base.g, blend.g ), blendOverlay( base.b, blend.b ) );
}
float getDepth( const in vec2 uv ) {
return texture2D( tDepth, uv ).x;
}
float getViewZ( const in float depth ) {
return perspectiveDepthToViewZ( depth, virtualCameraNear, virtualCameraFar );
}
vec3 getViewPosition( const in vec2 uv, const in float depth/*clip space*/, const in float clipW ) {
vec4 clipPosition = vec4( ( vec3( uv, depth ) - 0.5 ) * 2.0, 1.0 );//ndc
clipPosition *= clipW; //clip
return ( virtualCameraProjectionMatrixInverse * clipPosition ).xyz;//view
}
void main() {
vec4 base = texture2DProj( tDiffuse, vUv );
#ifdef useDepthTexture
vec2 uv=(gl_FragCoord.xy-.5)/resolution.xy;
uv.x=1.-uv.x;
float depth = texture2DProj( tDepth, vUv ).r;
float viewZ = getViewZ( depth );
float clipW = virtualCameraProjectionMatrix[2][3] * viewZ+virtualCameraProjectionMatrix[3][3];
vec3 viewPosition=getViewPosition( uv, depth, clipW );
vec3 worldPosition=(virtualCameraMatrixWorld*vec4(viewPosition,1)).xyz;
if(worldPosition.y>maxDistance) discard;
float op=opacity;
#ifdef DISTANCE_ATTENUATION
float ratio=1.-(worldPosition.y/maxDistance);
float attenuation=ratio*ratio;
op=opacity*attenuation;
#endif
#ifdef FRESNEL
op*=fresnelCoe;
#endif
gl_FragColor = vec4( blendOverlay( base.rgb, color ), op );
#else
gl_FragColor = vec4( blendOverlay( base.rgb, color ), 1.0 );
#endif
}
`
)
});
return ReflectorForSSRPass2;
})();
export {
ReflectorForSSRPass
};
//# sourceMappingURL=ReflectorForSSRPass.js.map
File diff suppressed because one or more lines are too long
+11
View File
@@ -0,0 +1,11 @@
"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const Reflector = require("./Reflector.cjs");
class ReflectorRTT extends Reflector.Reflector {
constructor(geometry, options) {
super(geometry, options);
this.geometry.setDrawRange(0, 0);
}
}
exports.ReflectorRTT = ReflectorRTT;
//# sourceMappingURL=ReflectorRTT.cjs.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"ReflectorRTT.cjs","sources":["../../src/objects/ReflectorRTT.ts"],"sourcesContent":["import { BufferGeometry } from 'three'\nimport { Reflector, ReflectorOptions } from '../objects/Reflector'\n\nclass ReflectorRTT extends Reflector {\n constructor(geometry?: BufferGeometry, options?: ReflectorOptions) {\n super(geometry, options)\n this.geometry.setDrawRange(0, 0)\n }\n}\n\nexport { ReflectorRTT }\n"],"names":["Reflector"],"mappings":";;;AAGA,MAAM,qBAAqBA,UAAAA,UAAU;AAAA,EACnC,YAAY,UAA2B,SAA4B;AACjE,UAAM,UAAU,OAAO;AAClB,SAAA,SAAS,aAAa,GAAG,CAAC;AAAA,EACjC;AACF;;"}
+6
View File
@@ -0,0 +1,6 @@
import { BufferGeometry } from 'three';
import { Reflector, ReflectorOptions } from '../objects/Reflector';
declare class ReflectorRTT extends Reflector {
constructor(geometry?: BufferGeometry, options?: ReflectorOptions);
}
export { ReflectorRTT };
+11
View File
@@ -0,0 +1,11 @@
import { Reflector } from "./Reflector.js";
class ReflectorRTT extends Reflector {
constructor(geometry, options) {
super(geometry, options);
this.geometry.setDrawRange(0, 0);
}
}
export {
ReflectorRTT
};
//# sourceMappingURL=ReflectorRTT.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"ReflectorRTT.js","sources":["../../src/objects/ReflectorRTT.ts"],"sourcesContent":["import { BufferGeometry } from 'three'\nimport { Reflector, ReflectorOptions } from '../objects/Reflector'\n\nclass ReflectorRTT extends Reflector {\n constructor(geometry?: BufferGeometry, options?: ReflectorOptions) {\n super(geometry, options)\n this.geometry.setDrawRange(0, 0)\n }\n}\n\nexport { ReflectorRTT }\n"],"names":[],"mappings":";AAGA,MAAM,qBAAqB,UAAU;AAAA,EACnC,YAAY,UAA2B,SAA4B;AACjE,UAAM,UAAU,OAAO;AAClB,SAAA,SAAS,aAAa,GAAG,CAAC;AAAA,EACjC;AACF;"}
+220
View File
@@ -0,0 +1,220 @@
"use strict";
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const THREE = require("three");
const constants = require("../_polyfill/constants.cjs");
const Refractor = /* @__PURE__ */ (() => {
const _Refractor = class extends THREE.Mesh {
constructor(geometry, options = {}) {
super(geometry);
this.isRefractor = true;
this.type = "Refractor";
this.camera = new THREE.PerspectiveCamera();
const scope = this;
const color = options.color !== void 0 ? new THREE.Color(options.color) : new THREE.Color(8355711);
const textureWidth = options.textureWidth || 512;
const textureHeight = options.textureHeight || 512;
const clipBias = options.clipBias || 0;
const shader = options.shader || _Refractor.RefractorShader;
const multisample = options.multisample !== void 0 ? options.multisample : 4;
const virtualCamera = this.camera;
virtualCamera.matrixAutoUpdate = false;
virtualCamera.userData.refractor = true;
const refractorPlane = new THREE.Plane();
const textureMatrix = new THREE.Matrix4();
const renderTarget = new THREE.WebGLRenderTarget(textureWidth, textureHeight, {
samples: multisample,
type: THREE.HalfFloatType
});
this.material = new THREE.ShaderMaterial({
uniforms: THREE.UniformsUtils.clone(shader.uniforms),
vertexShader: shader.vertexShader,
fragmentShader: shader.fragmentShader,
transparent: true
// ensures, refractors are drawn from farthest to closest
});
this.material.uniforms["color"].value = color;
this.material.uniforms["tDiffuse"].value = renderTarget.texture;
this.material.uniforms["textureMatrix"].value = textureMatrix;
const visible = function() {
const refractorWorldPosition = new THREE.Vector3();
const cameraWorldPosition = new THREE.Vector3();
const rotationMatrix = new THREE.Matrix4();
const view = new THREE.Vector3();
const normal = new THREE.Vector3();
return function visible2(camera) {
refractorWorldPosition.setFromMatrixPosition(scope.matrixWorld);
cameraWorldPosition.setFromMatrixPosition(camera.matrixWorld);
view.subVectors(refractorWorldPosition, cameraWorldPosition);
rotationMatrix.extractRotation(scope.matrixWorld);
normal.set(0, 0, 1);
normal.applyMatrix4(rotationMatrix);
return view.dot(normal) < 0;
};
}();
const updateRefractorPlane = function() {
const normal = new THREE.Vector3();
const position = new THREE.Vector3();
const quaternion = new THREE.Quaternion();
const scale = new THREE.Vector3();
return function updateRefractorPlane2() {
scope.matrixWorld.decompose(position, quaternion, scale);
normal.set(0, 0, 1).applyQuaternion(quaternion).normalize();
normal.negate();
refractorPlane.setFromNormalAndCoplanarPoint(normal, position);
};
}();
const updateVirtualCamera = function() {
const clipPlane = new THREE.Plane();
const clipVector = new THREE.Vector4();
const q = new THREE.Vector4();
return function updateVirtualCamera2(camera) {
virtualCamera.matrixWorld.copy(camera.matrixWorld);
virtualCamera.matrixWorldInverse.copy(virtualCamera.matrixWorld).invert();
virtualCamera.projectionMatrix.copy(camera.projectionMatrix);
virtualCamera.far = camera.far;
clipPlane.copy(refractorPlane);
clipPlane.applyMatrix4(virtualCamera.matrixWorldInverse);
clipVector.set(clipPlane.normal.x, clipPlane.normal.y, clipPlane.normal.z, clipPlane.constant);
const projectionMatrix = virtualCamera.projectionMatrix;
q.x = (Math.sign(clipVector.x) + projectionMatrix.elements[8]) / projectionMatrix.elements[0];
q.y = (Math.sign(clipVector.y) + projectionMatrix.elements[9]) / projectionMatrix.elements[5];
q.z = -1;
q.w = (1 + projectionMatrix.elements[10]) / projectionMatrix.elements[14];
clipVector.multiplyScalar(2 / clipVector.dot(q));
projectionMatrix.elements[2] = clipVector.x;
projectionMatrix.elements[6] = clipVector.y;
projectionMatrix.elements[10] = clipVector.z + 1 - clipBias;
projectionMatrix.elements[14] = clipVector.w;
};
}();
function updateTextureMatrix(camera) {
textureMatrix.set(0.5, 0, 0, 0.5, 0, 0.5, 0, 0.5, 0, 0, 0.5, 0.5, 0, 0, 0, 1);
textureMatrix.multiply(camera.projectionMatrix);
textureMatrix.multiply(camera.matrixWorldInverse);
textureMatrix.multiply(scope.matrixWorld);
}
function render(renderer, scene, camera) {
scope.visible = false;
const currentRenderTarget = renderer.getRenderTarget();
const currentXrEnabled = renderer.xr.enabled;
const currentShadowAutoUpdate = renderer.shadowMap.autoUpdate;
const currentToneMapping = renderer.toneMapping;
let isSRGB = false;
if ("outputColorSpace" in renderer)
isSRGB = renderer.outputColorSpace === "srgb";
else
isSRGB = renderer.outputEncoding === 3001;
renderer.xr.enabled = false;
renderer.shadowMap.autoUpdate = false;
if ("outputColorSpace" in renderer)
renderer.outputColorSpace = "srgb-linear";
else
renderer.outputEncoding = 3e3;
renderer.toneMapping = THREE.NoToneMapping;
renderer.setRenderTarget(renderTarget);
if (renderer.autoClear === false)
renderer.clear();
renderer.render(scene, virtualCamera);
renderer.xr.enabled = currentXrEnabled;
renderer.shadowMap.autoUpdate = currentShadowAutoUpdate;
renderer.toneMapping = currentToneMapping;
renderer.setRenderTarget(currentRenderTarget);
if ("outputColorSpace" in renderer)
renderer.outputColorSpace = isSRGB ? "srgb" : "srgb-linear";
else
renderer.outputEncoding = isSRGB ? 3001 : 3e3;
const viewport = camera.viewport;
if (viewport !== void 0) {
renderer.state.viewport(viewport);
}
scope.visible = true;
}
this.onBeforeRender = function(renderer, scene, camera) {
if (camera.userData.refractor === true)
return;
if (!visible(camera) === true)
return;
updateRefractorPlane();
updateTextureMatrix(camera);
updateVirtualCamera(camera);
render(renderer, scene, camera);
};
this.getRenderTarget = function() {
return renderTarget;
};
this.dispose = function() {
renderTarget.dispose();
scope.material.dispose();
};
}
};
let Refractor2 = _Refractor;
__publicField(Refractor2, "RefractorShader", {
uniforms: {
color: {
value: null
},
tDiffuse: {
value: null
},
textureMatrix: {
value: null
}
},
vertexShader: (
/* glsl */
`
uniform mat4 textureMatrix;
varying vec4 vUv;
void main() {
vUv = textureMatrix * vec4( position, 1.0 );
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}`
),
fragmentShader: (
/* glsl */
`
uniform vec3 color;
uniform sampler2D tDiffuse;
varying vec4 vUv;
float blendOverlay( float base, float blend ) {
return( base < 0.5 ? ( 2.0 * base * blend ) : ( 1.0 - 2.0 * ( 1.0 - base ) * ( 1.0 - blend ) ) );
}
vec3 blendOverlay( vec3 base, vec3 blend ) {
return vec3( blendOverlay( base.r, blend.r ), blendOverlay( base.g, blend.g ), blendOverlay( base.b, blend.b ) );
}
void main() {
vec4 base = texture2DProj( tDiffuse, vUv );
gl_FragColor = vec4( blendOverlay( base.rgb, color ), 1.0 );
#include <tonemapping_fragment>
#include <${constants.version >= 154 ? "colorspace_fragment" : "encodings_fragment"}>
}`
)
});
return Refractor2;
})();
exports.Refractor = Refractor;
//# sourceMappingURL=Refractor.cjs.map
File diff suppressed because one or more lines are too long
+23
View File
@@ -0,0 +1,23 @@
import { Mesh, BufferGeometry, Color, WebGLRenderTarget, PerspectiveCamera } from 'three'
import { TextureEncoding } from '../types/shared'
export interface RefractorOptions {
color?: Color | string | number
textureWidth?: number
textureHeight?: number
clipBias?: number
shader?: object
encoding?: TextureEncoding
multisample?: number
}
export class Refractor extends Mesh {
type: 'Refractor'
camera: PerspectiveCamera
constructor(geometry?: BufferGeometry, options?: RefractorOptions)
getRenderTarget(): WebGLRenderTarget
dispose(): void
}
+220
View File
@@ -0,0 +1,220 @@
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
import { Mesh, PerspectiveCamera, Color, Plane, Matrix4, WebGLRenderTarget, HalfFloatType, ShaderMaterial, UniformsUtils, Vector3, Quaternion, Vector4, NoToneMapping } from "three";
import { version } from "../_polyfill/constants.js";
const Refractor = /* @__PURE__ */ (() => {
const _Refractor = class extends Mesh {
constructor(geometry, options = {}) {
super(geometry);
this.isRefractor = true;
this.type = "Refractor";
this.camera = new PerspectiveCamera();
const scope = this;
const color = options.color !== void 0 ? new Color(options.color) : new Color(8355711);
const textureWidth = options.textureWidth || 512;
const textureHeight = options.textureHeight || 512;
const clipBias = options.clipBias || 0;
const shader = options.shader || _Refractor.RefractorShader;
const multisample = options.multisample !== void 0 ? options.multisample : 4;
const virtualCamera = this.camera;
virtualCamera.matrixAutoUpdate = false;
virtualCamera.userData.refractor = true;
const refractorPlane = new Plane();
const textureMatrix = new Matrix4();
const renderTarget = new WebGLRenderTarget(textureWidth, textureHeight, {
samples: multisample,
type: HalfFloatType
});
this.material = new ShaderMaterial({
uniforms: UniformsUtils.clone(shader.uniforms),
vertexShader: shader.vertexShader,
fragmentShader: shader.fragmentShader,
transparent: true
// ensures, refractors are drawn from farthest to closest
});
this.material.uniforms["color"].value = color;
this.material.uniforms["tDiffuse"].value = renderTarget.texture;
this.material.uniforms["textureMatrix"].value = textureMatrix;
const visible = function() {
const refractorWorldPosition = new Vector3();
const cameraWorldPosition = new Vector3();
const rotationMatrix = new Matrix4();
const view = new Vector3();
const normal = new Vector3();
return function visible2(camera) {
refractorWorldPosition.setFromMatrixPosition(scope.matrixWorld);
cameraWorldPosition.setFromMatrixPosition(camera.matrixWorld);
view.subVectors(refractorWorldPosition, cameraWorldPosition);
rotationMatrix.extractRotation(scope.matrixWorld);
normal.set(0, 0, 1);
normal.applyMatrix4(rotationMatrix);
return view.dot(normal) < 0;
};
}();
const updateRefractorPlane = function() {
const normal = new Vector3();
const position = new Vector3();
const quaternion = new Quaternion();
const scale = new Vector3();
return function updateRefractorPlane2() {
scope.matrixWorld.decompose(position, quaternion, scale);
normal.set(0, 0, 1).applyQuaternion(quaternion).normalize();
normal.negate();
refractorPlane.setFromNormalAndCoplanarPoint(normal, position);
};
}();
const updateVirtualCamera = function() {
const clipPlane = new Plane();
const clipVector = new Vector4();
const q = new Vector4();
return function updateVirtualCamera2(camera) {
virtualCamera.matrixWorld.copy(camera.matrixWorld);
virtualCamera.matrixWorldInverse.copy(virtualCamera.matrixWorld).invert();
virtualCamera.projectionMatrix.copy(camera.projectionMatrix);
virtualCamera.far = camera.far;
clipPlane.copy(refractorPlane);
clipPlane.applyMatrix4(virtualCamera.matrixWorldInverse);
clipVector.set(clipPlane.normal.x, clipPlane.normal.y, clipPlane.normal.z, clipPlane.constant);
const projectionMatrix = virtualCamera.projectionMatrix;
q.x = (Math.sign(clipVector.x) + projectionMatrix.elements[8]) / projectionMatrix.elements[0];
q.y = (Math.sign(clipVector.y) + projectionMatrix.elements[9]) / projectionMatrix.elements[5];
q.z = -1;
q.w = (1 + projectionMatrix.elements[10]) / projectionMatrix.elements[14];
clipVector.multiplyScalar(2 / clipVector.dot(q));
projectionMatrix.elements[2] = clipVector.x;
projectionMatrix.elements[6] = clipVector.y;
projectionMatrix.elements[10] = clipVector.z + 1 - clipBias;
projectionMatrix.elements[14] = clipVector.w;
};
}();
function updateTextureMatrix(camera) {
textureMatrix.set(0.5, 0, 0, 0.5, 0, 0.5, 0, 0.5, 0, 0, 0.5, 0.5, 0, 0, 0, 1);
textureMatrix.multiply(camera.projectionMatrix);
textureMatrix.multiply(camera.matrixWorldInverse);
textureMatrix.multiply(scope.matrixWorld);
}
function render(renderer, scene, camera) {
scope.visible = false;
const currentRenderTarget = renderer.getRenderTarget();
const currentXrEnabled = renderer.xr.enabled;
const currentShadowAutoUpdate = renderer.shadowMap.autoUpdate;
const currentToneMapping = renderer.toneMapping;
let isSRGB = false;
if ("outputColorSpace" in renderer)
isSRGB = renderer.outputColorSpace === "srgb";
else
isSRGB = renderer.outputEncoding === 3001;
renderer.xr.enabled = false;
renderer.shadowMap.autoUpdate = false;
if ("outputColorSpace" in renderer)
renderer.outputColorSpace = "srgb-linear";
else
renderer.outputEncoding = 3e3;
renderer.toneMapping = NoToneMapping;
renderer.setRenderTarget(renderTarget);
if (renderer.autoClear === false)
renderer.clear();
renderer.render(scene, virtualCamera);
renderer.xr.enabled = currentXrEnabled;
renderer.shadowMap.autoUpdate = currentShadowAutoUpdate;
renderer.toneMapping = currentToneMapping;
renderer.setRenderTarget(currentRenderTarget);
if ("outputColorSpace" in renderer)
renderer.outputColorSpace = isSRGB ? "srgb" : "srgb-linear";
else
renderer.outputEncoding = isSRGB ? 3001 : 3e3;
const viewport = camera.viewport;
if (viewport !== void 0) {
renderer.state.viewport(viewport);
}
scope.visible = true;
}
this.onBeforeRender = function(renderer, scene, camera) {
if (camera.userData.refractor === true)
return;
if (!visible(camera) === true)
return;
updateRefractorPlane();
updateTextureMatrix(camera);
updateVirtualCamera(camera);
render(renderer, scene, camera);
};
this.getRenderTarget = function() {
return renderTarget;
};
this.dispose = function() {
renderTarget.dispose();
scope.material.dispose();
};
}
};
let Refractor2 = _Refractor;
__publicField(Refractor2, "RefractorShader", {
uniforms: {
color: {
value: null
},
tDiffuse: {
value: null
},
textureMatrix: {
value: null
}
},
vertexShader: (
/* glsl */
`
uniform mat4 textureMatrix;
varying vec4 vUv;
void main() {
vUv = textureMatrix * vec4( position, 1.0 );
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}`
),
fragmentShader: (
/* glsl */
`
uniform vec3 color;
uniform sampler2D tDiffuse;
varying vec4 vUv;
float blendOverlay( float base, float blend ) {
return( base < 0.5 ? ( 2.0 * base * blend ) : ( 1.0 - 2.0 * ( 1.0 - base ) * ( 1.0 - blend ) ) );
}
vec3 blendOverlay( vec3 base, vec3 blend ) {
return vec3( blendOverlay( base.r, blend.r ), blendOverlay( base.g, blend.g ), blendOverlay( base.b, blend.b ) );
}
void main() {
vec4 base = texture2DProj( tDiffuse, vUv );
gl_FragColor = vec4( blendOverlay( base.rgb, color ), 1.0 );
#include <tonemapping_fragment>
#include <${version >= 154 ? "colorspace_fragment" : "encodings_fragment"}>
}`
)
});
return Refractor2;
})();
export {
Refractor
};
//# sourceMappingURL=Refractor.js.map
File diff suppressed because one or more lines are too long
+46
View File
@@ -0,0 +1,46 @@
"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const THREE = require("three");
const _shadowMatrix = /* @__PURE__ */ new THREE.Matrix4();
class ShadowMesh extends THREE.Mesh {
constructor(mesh) {
const shadowMaterial = new THREE.MeshBasicMaterial({
color: 0,
transparent: true,
opacity: 0.6,
depthWrite: false,
stencilWrite: true,
stencilFunc: THREE.EqualStencilFunc,
stencilRef: 0,
stencilZPass: THREE.IncrementStencilOp
});
super(mesh.geometry, shadowMaterial);
this.isShadowMesh = true;
this.meshMatrix = mesh.matrixWorld;
this.frustumCulled = false;
this.matrixAutoUpdate = false;
}
update(plane, lightPosition4D) {
const dot = plane.normal.x * lightPosition4D.x + plane.normal.y * lightPosition4D.y + plane.normal.z * lightPosition4D.z + -plane.constant * lightPosition4D.w;
const sme = _shadowMatrix.elements;
sme[0] = dot - lightPosition4D.x * plane.normal.x;
sme[4] = -lightPosition4D.x * plane.normal.y;
sme[8] = -lightPosition4D.x * plane.normal.z;
sme[12] = -lightPosition4D.x * -plane.constant;
sme[1] = -lightPosition4D.y * plane.normal.x;
sme[5] = dot - lightPosition4D.y * plane.normal.y;
sme[9] = -lightPosition4D.y * plane.normal.z;
sme[13] = -lightPosition4D.y * -plane.constant;
sme[2] = -lightPosition4D.z * plane.normal.x;
sme[6] = -lightPosition4D.z * plane.normal.y;
sme[10] = dot - lightPosition4D.z * plane.normal.z;
sme[14] = -lightPosition4D.z * -plane.constant;
sme[3] = -lightPosition4D.w * plane.normal.x;
sme[7] = -lightPosition4D.w * plane.normal.y;
sme[11] = -lightPosition4D.w * plane.normal.z;
sme[15] = dot - lightPosition4D.w * -plane.constant;
this.matrix.multiplyMatrices(_shadowMatrix, this.meshMatrix);
}
}
exports.ShadowMesh = ShadowMesh;
//# sourceMappingURL=ShadowMesh.cjs.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"ShadowMesh.cjs","sources":["../../src/objects/ShadowMesh.js"],"sourcesContent":["import { Matrix4, Mesh, MeshBasicMaterial, EqualStencilFunc, IncrementStencilOp } from 'three'\n\n/**\n * A shadow Mesh that follows a shadow-casting Mesh in the scene, but is confined to a single plane.\n */\n\nconst _shadowMatrix = /* @__PURE__ */ new Matrix4()\n\nclass ShadowMesh extends Mesh {\n constructor(mesh) {\n const shadowMaterial = new MeshBasicMaterial({\n color: 0x000000,\n transparent: true,\n opacity: 0.6,\n depthWrite: false,\n stencilWrite: true,\n stencilFunc: EqualStencilFunc,\n stencilRef: 0,\n stencilZPass: IncrementStencilOp,\n })\n\n super(mesh.geometry, shadowMaterial)\n\n this.isShadowMesh = true\n\n this.meshMatrix = mesh.matrixWorld\n\n this.frustumCulled = false\n this.matrixAutoUpdate = false\n }\n\n update(plane, lightPosition4D) {\n // based on https://www.opengl.org/archives/resources/features/StencilTalk/tsld021.htm\n\n const dot =\n plane.normal.x * lightPosition4D.x +\n plane.normal.y * lightPosition4D.y +\n plane.normal.z * lightPosition4D.z +\n -plane.constant * lightPosition4D.w\n\n const sme = _shadowMatrix.elements\n\n sme[0] = dot - lightPosition4D.x * plane.normal.x\n sme[4] = -lightPosition4D.x * plane.normal.y\n sme[8] = -lightPosition4D.x * plane.normal.z\n sme[12] = -lightPosition4D.x * -plane.constant\n\n sme[1] = -lightPosition4D.y * plane.normal.x\n sme[5] = dot - lightPosition4D.y * plane.normal.y\n sme[9] = -lightPosition4D.y * plane.normal.z\n sme[13] = -lightPosition4D.y * -plane.constant\n\n sme[2] = -lightPosition4D.z * plane.normal.x\n sme[6] = -lightPosition4D.z * plane.normal.y\n sme[10] = dot - lightPosition4D.z * plane.normal.z\n sme[14] = -lightPosition4D.z * -plane.constant\n\n sme[3] = -lightPosition4D.w * plane.normal.x\n sme[7] = -lightPosition4D.w * plane.normal.y\n sme[11] = -lightPosition4D.w * plane.normal.z\n sme[15] = dot - lightPosition4D.w * -plane.constant\n\n this.matrix.multiplyMatrices(_shadowMatrix, this.meshMatrix)\n }\n}\n\nexport { ShadowMesh }\n"],"names":["Matrix4","Mesh","MeshBasicMaterial","EqualStencilFunc","IncrementStencilOp"],"mappings":";;;AAMA,MAAM,gBAAgC,oBAAIA,MAAAA,QAAS;AAEnD,MAAM,mBAAmBC,MAAAA,KAAK;AAAA,EAC5B,YAAY,MAAM;AAChB,UAAM,iBAAiB,IAAIC,wBAAkB;AAAA,MAC3C,OAAO;AAAA,MACP,aAAa;AAAA,MACb,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,cAAc;AAAA,MACd,aAAaC,MAAgB;AAAA,MAC7B,YAAY;AAAA,MACZ,cAAcC,MAAkB;AAAA,IACtC,CAAK;AAED,UAAM,KAAK,UAAU,cAAc;AAEnC,SAAK,eAAe;AAEpB,SAAK,aAAa,KAAK;AAEvB,SAAK,gBAAgB;AACrB,SAAK,mBAAmB;AAAA,EACzB;AAAA,EAED,OAAO,OAAO,iBAAiB;AAG7B,UAAM,MACJ,MAAM,OAAO,IAAI,gBAAgB,IACjC,MAAM,OAAO,IAAI,gBAAgB,IACjC,MAAM,OAAO,IAAI,gBAAgB,IACjC,CAAC,MAAM,WAAW,gBAAgB;AAEpC,UAAM,MAAM,cAAc;AAE1B,QAAI,CAAC,IAAI,MAAM,gBAAgB,IAAI,MAAM,OAAO;AAChD,QAAI,CAAC,IAAI,CAAC,gBAAgB,IAAI,MAAM,OAAO;AAC3C,QAAI,CAAC,IAAI,CAAC,gBAAgB,IAAI,MAAM,OAAO;AAC3C,QAAI,EAAE,IAAI,CAAC,gBAAgB,IAAI,CAAC,MAAM;AAEtC,QAAI,CAAC,IAAI,CAAC,gBAAgB,IAAI,MAAM,OAAO;AAC3C,QAAI,CAAC,IAAI,MAAM,gBAAgB,IAAI,MAAM,OAAO;AAChD,QAAI,CAAC,IAAI,CAAC,gBAAgB,IAAI,MAAM,OAAO;AAC3C,QAAI,EAAE,IAAI,CAAC,gBAAgB,IAAI,CAAC,MAAM;AAEtC,QAAI,CAAC,IAAI,CAAC,gBAAgB,IAAI,MAAM,OAAO;AAC3C,QAAI,CAAC,IAAI,CAAC,gBAAgB,IAAI,MAAM,OAAO;AAC3C,QAAI,EAAE,IAAI,MAAM,gBAAgB,IAAI,MAAM,OAAO;AACjD,QAAI,EAAE,IAAI,CAAC,gBAAgB,IAAI,CAAC,MAAM;AAEtC,QAAI,CAAC,IAAI,CAAC,gBAAgB,IAAI,MAAM,OAAO;AAC3C,QAAI,CAAC,IAAI,CAAC,gBAAgB,IAAI,MAAM,OAAO;AAC3C,QAAI,EAAE,IAAI,CAAC,gBAAgB,IAAI,MAAM,OAAO;AAC5C,QAAI,EAAE,IAAI,MAAM,gBAAgB,IAAI,CAAC,MAAM;AAE3C,SAAK,OAAO,iBAAiB,eAAe,KAAK,UAAU;AAAA,EAC5D;AACH;;"}
+10
View File
@@ -0,0 +1,10 @@
import { Mesh, Plane, Vector4, Matrix4, MeshBasicMaterial, BufferGeometry } from 'three'
export class ShadowMesh extends Mesh<BufferGeometry, MeshBasicMaterial> {
readonly isShadowMesh: true
meshMatrix: Matrix4
constructor(mesh: Mesh)
update(plane: Plane, lightPosition4D: Vector4): void
}
+46
View File
@@ -0,0 +1,46 @@
import { Mesh, MeshBasicMaterial, EqualStencilFunc, IncrementStencilOp, Matrix4 } from "three";
const _shadowMatrix = /* @__PURE__ */ new Matrix4();
class ShadowMesh extends Mesh {
constructor(mesh) {
const shadowMaterial = new MeshBasicMaterial({
color: 0,
transparent: true,
opacity: 0.6,
depthWrite: false,
stencilWrite: true,
stencilFunc: EqualStencilFunc,
stencilRef: 0,
stencilZPass: IncrementStencilOp
});
super(mesh.geometry, shadowMaterial);
this.isShadowMesh = true;
this.meshMatrix = mesh.matrixWorld;
this.frustumCulled = false;
this.matrixAutoUpdate = false;
}
update(plane, lightPosition4D) {
const dot = plane.normal.x * lightPosition4D.x + plane.normal.y * lightPosition4D.y + plane.normal.z * lightPosition4D.z + -plane.constant * lightPosition4D.w;
const sme = _shadowMatrix.elements;
sme[0] = dot - lightPosition4D.x * plane.normal.x;
sme[4] = -lightPosition4D.x * plane.normal.y;
sme[8] = -lightPosition4D.x * plane.normal.z;
sme[12] = -lightPosition4D.x * -plane.constant;
sme[1] = -lightPosition4D.y * plane.normal.x;
sme[5] = dot - lightPosition4D.y * plane.normal.y;
sme[9] = -lightPosition4D.y * plane.normal.z;
sme[13] = -lightPosition4D.y * -plane.constant;
sme[2] = -lightPosition4D.z * plane.normal.x;
sme[6] = -lightPosition4D.z * plane.normal.y;
sme[10] = dot - lightPosition4D.z * plane.normal.z;
sme[14] = -lightPosition4D.z * -plane.constant;
sme[3] = -lightPosition4D.w * plane.normal.x;
sme[7] = -lightPosition4D.w * plane.normal.y;
sme[11] = -lightPosition4D.w * plane.normal.z;
sme[15] = dot - lightPosition4D.w * -plane.constant;
this.matrix.multiplyMatrices(_shadowMatrix, this.meshMatrix);
}
}
export {
ShadowMesh
};
//# sourceMappingURL=ShadowMesh.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"ShadowMesh.js","sources":["../../src/objects/ShadowMesh.js"],"sourcesContent":["import { Matrix4, Mesh, MeshBasicMaterial, EqualStencilFunc, IncrementStencilOp } from 'three'\n\n/**\n * A shadow Mesh that follows a shadow-casting Mesh in the scene, but is confined to a single plane.\n */\n\nconst _shadowMatrix = /* @__PURE__ */ new Matrix4()\n\nclass ShadowMesh extends Mesh {\n constructor(mesh) {\n const shadowMaterial = new MeshBasicMaterial({\n color: 0x000000,\n transparent: true,\n opacity: 0.6,\n depthWrite: false,\n stencilWrite: true,\n stencilFunc: EqualStencilFunc,\n stencilRef: 0,\n stencilZPass: IncrementStencilOp,\n })\n\n super(mesh.geometry, shadowMaterial)\n\n this.isShadowMesh = true\n\n this.meshMatrix = mesh.matrixWorld\n\n this.frustumCulled = false\n this.matrixAutoUpdate = false\n }\n\n update(plane, lightPosition4D) {\n // based on https://www.opengl.org/archives/resources/features/StencilTalk/tsld021.htm\n\n const dot =\n plane.normal.x * lightPosition4D.x +\n plane.normal.y * lightPosition4D.y +\n plane.normal.z * lightPosition4D.z +\n -plane.constant * lightPosition4D.w\n\n const sme = _shadowMatrix.elements\n\n sme[0] = dot - lightPosition4D.x * plane.normal.x\n sme[4] = -lightPosition4D.x * plane.normal.y\n sme[8] = -lightPosition4D.x * plane.normal.z\n sme[12] = -lightPosition4D.x * -plane.constant\n\n sme[1] = -lightPosition4D.y * plane.normal.x\n sme[5] = dot - lightPosition4D.y * plane.normal.y\n sme[9] = -lightPosition4D.y * plane.normal.z\n sme[13] = -lightPosition4D.y * -plane.constant\n\n sme[2] = -lightPosition4D.z * plane.normal.x\n sme[6] = -lightPosition4D.z * plane.normal.y\n sme[10] = dot - lightPosition4D.z * plane.normal.z\n sme[14] = -lightPosition4D.z * -plane.constant\n\n sme[3] = -lightPosition4D.w * plane.normal.x\n sme[7] = -lightPosition4D.w * plane.normal.y\n sme[11] = -lightPosition4D.w * plane.normal.z\n sme[15] = dot - lightPosition4D.w * -plane.constant\n\n this.matrix.multiplyMatrices(_shadowMatrix, this.meshMatrix)\n }\n}\n\nexport { ShadowMesh }\n"],"names":[],"mappings":";AAMA,MAAM,gBAAgC,oBAAI,QAAS;AAEnD,MAAM,mBAAmB,KAAK;AAAA,EAC5B,YAAY,MAAM;AAChB,UAAM,iBAAiB,IAAI,kBAAkB;AAAA,MAC3C,OAAO;AAAA,MACP,aAAa;AAAA,MACb,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,cAAc;AAAA,MACd,aAAa;AAAA,MACb,YAAY;AAAA,MACZ,cAAc;AAAA,IACpB,CAAK;AAED,UAAM,KAAK,UAAU,cAAc;AAEnC,SAAK,eAAe;AAEpB,SAAK,aAAa,KAAK;AAEvB,SAAK,gBAAgB;AACrB,SAAK,mBAAmB;AAAA,EACzB;AAAA,EAED,OAAO,OAAO,iBAAiB;AAG7B,UAAM,MACJ,MAAM,OAAO,IAAI,gBAAgB,IACjC,MAAM,OAAO,IAAI,gBAAgB,IACjC,MAAM,OAAO,IAAI,gBAAgB,IACjC,CAAC,MAAM,WAAW,gBAAgB;AAEpC,UAAM,MAAM,cAAc;AAE1B,QAAI,CAAC,IAAI,MAAM,gBAAgB,IAAI,MAAM,OAAO;AAChD,QAAI,CAAC,IAAI,CAAC,gBAAgB,IAAI,MAAM,OAAO;AAC3C,QAAI,CAAC,IAAI,CAAC,gBAAgB,IAAI,MAAM,OAAO;AAC3C,QAAI,EAAE,IAAI,CAAC,gBAAgB,IAAI,CAAC,MAAM;AAEtC,QAAI,CAAC,IAAI,CAAC,gBAAgB,IAAI,MAAM,OAAO;AAC3C,QAAI,CAAC,IAAI,MAAM,gBAAgB,IAAI,MAAM,OAAO;AAChD,QAAI,CAAC,IAAI,CAAC,gBAAgB,IAAI,MAAM,OAAO;AAC3C,QAAI,EAAE,IAAI,CAAC,gBAAgB,IAAI,CAAC,MAAM;AAEtC,QAAI,CAAC,IAAI,CAAC,gBAAgB,IAAI,MAAM,OAAO;AAC3C,QAAI,CAAC,IAAI,CAAC,gBAAgB,IAAI,MAAM,OAAO;AAC3C,QAAI,EAAE,IAAI,MAAM,gBAAgB,IAAI,MAAM,OAAO;AACjD,QAAI,EAAE,IAAI,CAAC,gBAAgB,IAAI,CAAC,MAAM;AAEtC,QAAI,CAAC,IAAI,CAAC,gBAAgB,IAAI,MAAM,OAAO;AAC3C,QAAI,CAAC,IAAI,CAAC,gBAAgB,IAAI,MAAM,OAAO;AAC3C,QAAI,EAAE,IAAI,CAAC,gBAAgB,IAAI,MAAM,OAAO;AAC5C,QAAI,EAAE,IAAI,MAAM,gBAAgB,IAAI,CAAC,MAAM;AAE3C,SAAK,OAAO,iBAAiB,eAAe,KAAK,UAAU;AAAA,EAC5D;AACH;"}
+205
View File
@@ -0,0 +1,205 @@
"use strict";
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const THREE = require("three");
const constants = require("../_polyfill/constants.cjs");
const Sky = /* @__PURE__ */ (() => {
const SkyShader = {
uniforms: {
turbidity: { value: 2 },
rayleigh: { value: 1 },
mieCoefficient: { value: 5e-3 },
mieDirectionalG: { value: 0.8 },
sunPosition: { value: new THREE.Vector3() },
up: { value: new THREE.Vector3(0, 1, 0) }
},
vertexShader: (
/* glsl */
`
uniform vec3 sunPosition;
uniform float rayleigh;
uniform float turbidity;
uniform float mieCoefficient;
uniform vec3 up;
varying vec3 vWorldPosition;
varying vec3 vSunDirection;
varying float vSunfade;
varying vec3 vBetaR;
varying vec3 vBetaM;
varying float vSunE;
// constants for atmospheric scattering
const float e = 2.71828182845904523536028747135266249775724709369995957;
const float pi = 3.141592653589793238462643383279502884197169;
// wavelength of used primaries, according to preetham
const vec3 lambda = vec3( 680E-9, 550E-9, 450E-9 );
// this pre-calcuation replaces older TotalRayleigh(vec3 lambda) function:
// (8.0 * pow(pi, 3.0) * pow(pow(n, 2.0) - 1.0, 2.0) * (6.0 + 3.0 * pn)) / (3.0 * N * pow(lambda, vec3(4.0)) * (6.0 - 7.0 * pn))
const vec3 totalRayleigh = vec3( 5.804542996261093E-6, 1.3562911419845635E-5, 3.0265902468824876E-5 );
// mie stuff
// K coefficient for the primaries
const float v = 4.0;
const vec3 K = vec3( 0.686, 0.678, 0.666 );
// MieConst = pi * pow( ( 2.0 * pi ) / lambda, vec3( v - 2.0 ) ) * K
const vec3 MieConst = vec3( 1.8399918514433978E14, 2.7798023919660528E14, 4.0790479543861094E14 );
// earth shadow hack
// cutoffAngle = pi / 1.95;
const float cutoffAngle = 1.6110731556870734;
const float steepness = 1.5;
const float EE = 1000.0;
float sunIntensity( float zenithAngleCos ) {
zenithAngleCos = clamp( zenithAngleCos, -1.0, 1.0 );
return EE * max( 0.0, 1.0 - pow( e, -( ( cutoffAngle - acos( zenithAngleCos ) ) / steepness ) ) );
}
vec3 totalMie( float T ) {
float c = ( 0.2 * T ) * 10E-18;
return 0.434 * c * MieConst;
}
void main() {
vec4 worldPosition = modelMatrix * vec4( position, 1.0 );
vWorldPosition = worldPosition.xyz;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
gl_Position.z = gl_Position.w; // set z to camera.far
vSunDirection = normalize( sunPosition );
vSunE = sunIntensity( dot( vSunDirection, up ) );
vSunfade = 1.0 - clamp( 1.0 - exp( ( sunPosition.y / 450000.0 ) ), 0.0, 1.0 );
float rayleighCoefficient = rayleigh - ( 1.0 * ( 1.0 - vSunfade ) );
// extinction (absorbtion + out scattering)
// rayleigh coefficients
vBetaR = totalRayleigh * rayleighCoefficient;
// mie coefficients
vBetaM = totalMie( turbidity ) * mieCoefficient;
}
`
),
fragmentShader: (
/* glsl */
`
varying vec3 vWorldPosition;
varying vec3 vSunDirection;
varying float vSunfade;
varying vec3 vBetaR;
varying vec3 vBetaM;
varying float vSunE;
uniform float mieDirectionalG;
uniform vec3 up;
const vec3 cameraPos = vec3( 0.0, 0.0, 0.0 );
// constants for atmospheric scattering
const float pi = 3.141592653589793238462643383279502884197169;
const float n = 1.0003; // refractive index of air
const float N = 2.545E25; // number of molecules per unit volume for air at 288.15K and 1013mb (sea level -45 celsius)
// optical length at zenith for molecules
const float rayleighZenithLength = 8.4E3;
const float mieZenithLength = 1.25E3;
// 66 arc seconds -> degrees, and the cosine of that
const float sunAngularDiameterCos = 0.999956676946448443553574619906976478926848692873900859324;
// 3.0 / ( 16.0 * pi )
const float THREE_OVER_SIXTEENPI = 0.05968310365946075;
// 1.0 / ( 4.0 * pi )
const float ONE_OVER_FOURPI = 0.07957747154594767;
float rayleighPhase( float cosTheta ) {
return THREE_OVER_SIXTEENPI * ( 1.0 + pow( cosTheta, 2.0 ) );
}
float hgPhase( float cosTheta, float g ) {
float g2 = pow( g, 2.0 );
float inverse = 1.0 / pow( 1.0 - 2.0 * g * cosTheta + g2, 1.5 );
return ONE_OVER_FOURPI * ( ( 1.0 - g2 ) * inverse );
}
void main() {
vec3 direction = normalize( vWorldPosition - cameraPos );
// optical length
// cutoff angle at 90 to avoid singularity in next formula.
float zenithAngle = acos( max( 0.0, dot( up, direction ) ) );
float inverse = 1.0 / ( cos( zenithAngle ) + 0.15 * pow( 93.885 - ( ( zenithAngle * 180.0 ) / pi ), -1.253 ) );
float sR = rayleighZenithLength * inverse;
float sM = mieZenithLength * inverse;
// combined extinction factor
vec3 Fex = exp( -( vBetaR * sR + vBetaM * sM ) );
// in scattering
float cosTheta = dot( direction, vSunDirection );
float rPhase = rayleighPhase( cosTheta * 0.5 + 0.5 );
vec3 betaRTheta = vBetaR * rPhase;
float mPhase = hgPhase( cosTheta, mieDirectionalG );
vec3 betaMTheta = vBetaM * mPhase;
vec3 Lin = pow( vSunE * ( ( betaRTheta + betaMTheta ) / ( vBetaR + vBetaM ) ) * ( 1.0 - Fex ), vec3( 1.5 ) );
Lin *= mix( vec3( 1.0 ), pow( vSunE * ( ( betaRTheta + betaMTheta ) / ( vBetaR + vBetaM ) ) * Fex, vec3( 1.0 / 2.0 ) ), clamp( pow( 1.0 - dot( up, vSunDirection ), 5.0 ), 0.0, 1.0 ) );
// nightsky
float theta = acos( direction.y ); // elevation --> y-axis, [-pi/2, pi/2]
float phi = atan( direction.z, direction.x ); // azimuth --> x-axis [-pi/2, pi/2]
vec2 uv = vec2( phi, theta ) / vec2( 2.0 * pi, pi ) + vec2( 0.5, 0.0 );
vec3 L0 = vec3( 0.1 ) * Fex;
// composition + solar disc
float sundisk = smoothstep( sunAngularDiameterCos, sunAngularDiameterCos + 0.00002, cosTheta );
L0 += ( vSunE * 19000.0 * Fex ) * sundisk;
vec3 texColor = ( Lin + L0 ) * 0.04 + vec3( 0.0, 0.0003, 0.00075 );
vec3 retColor = pow( texColor, vec3( 1.0 / ( 1.2 + ( 1.2 * vSunfade ) ) ) );
gl_FragColor = vec4( retColor, 1.0 );
#include <tonemapping_fragment>
#include <${constants.version >= 154 ? "colorspace_fragment" : "encodings_fragment"}>
}
`
)
};
const material = new THREE.ShaderMaterial({
name: "SkyShader",
fragmentShader: SkyShader.fragmentShader,
vertexShader: SkyShader.vertexShader,
uniforms: THREE.UniformsUtils.clone(SkyShader.uniforms),
side: THREE.BackSide,
depthWrite: false
});
class Sky2 extends THREE.Mesh {
constructor() {
super(new THREE.BoxGeometry(1, 1, 1), material);
}
}
__publicField(Sky2, "SkyShader", SkyShader);
__publicField(Sky2, "material", material);
return Sky2;
})();
exports.Sky = Sky;
//# sourceMappingURL=Sky.cjs.map
File diff suppressed because one or more lines are too long
+18
View File
@@ -0,0 +1,18 @@
import { Mesh, BoxGeometry, ShaderMaterial, Vector3 } from 'three'
declare class Sky extends Mesh<BoxGeometry, ShaderMaterial> {
static SkyShader: {
uniforms: {
turbidity: { value: number }
rayleigh: { value: number }
mieCoefficient: { value: number }
mieDirectionalG: { value: number }
sunPosition: { value: Vector3 }
up: { value: Vector3 }
}
}
static material: ShaderMaterial
}
export { Sky }
+205
View File
@@ -0,0 +1,205 @@
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
import { Vector3, ShaderMaterial, UniformsUtils, BackSide, Mesh, BoxGeometry } from "three";
import { version } from "../_polyfill/constants.js";
const Sky = /* @__PURE__ */ (() => {
const SkyShader = {
uniforms: {
turbidity: { value: 2 },
rayleigh: { value: 1 },
mieCoefficient: { value: 5e-3 },
mieDirectionalG: { value: 0.8 },
sunPosition: { value: new Vector3() },
up: { value: new Vector3(0, 1, 0) }
},
vertexShader: (
/* glsl */
`
uniform vec3 sunPosition;
uniform float rayleigh;
uniform float turbidity;
uniform float mieCoefficient;
uniform vec3 up;
varying vec3 vWorldPosition;
varying vec3 vSunDirection;
varying float vSunfade;
varying vec3 vBetaR;
varying vec3 vBetaM;
varying float vSunE;
// constants for atmospheric scattering
const float e = 2.71828182845904523536028747135266249775724709369995957;
const float pi = 3.141592653589793238462643383279502884197169;
// wavelength of used primaries, according to preetham
const vec3 lambda = vec3( 680E-9, 550E-9, 450E-9 );
// this pre-calcuation replaces older TotalRayleigh(vec3 lambda) function:
// (8.0 * pow(pi, 3.0) * pow(pow(n, 2.0) - 1.0, 2.0) * (6.0 + 3.0 * pn)) / (3.0 * N * pow(lambda, vec3(4.0)) * (6.0 - 7.0 * pn))
const vec3 totalRayleigh = vec3( 5.804542996261093E-6, 1.3562911419845635E-5, 3.0265902468824876E-5 );
// mie stuff
// K coefficient for the primaries
const float v = 4.0;
const vec3 K = vec3( 0.686, 0.678, 0.666 );
// MieConst = pi * pow( ( 2.0 * pi ) / lambda, vec3( v - 2.0 ) ) * K
const vec3 MieConst = vec3( 1.8399918514433978E14, 2.7798023919660528E14, 4.0790479543861094E14 );
// earth shadow hack
// cutoffAngle = pi / 1.95;
const float cutoffAngle = 1.6110731556870734;
const float steepness = 1.5;
const float EE = 1000.0;
float sunIntensity( float zenithAngleCos ) {
zenithAngleCos = clamp( zenithAngleCos, -1.0, 1.0 );
return EE * max( 0.0, 1.0 - pow( e, -( ( cutoffAngle - acos( zenithAngleCos ) ) / steepness ) ) );
}
vec3 totalMie( float T ) {
float c = ( 0.2 * T ) * 10E-18;
return 0.434 * c * MieConst;
}
void main() {
vec4 worldPosition = modelMatrix * vec4( position, 1.0 );
vWorldPosition = worldPosition.xyz;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
gl_Position.z = gl_Position.w; // set z to camera.far
vSunDirection = normalize( sunPosition );
vSunE = sunIntensity( dot( vSunDirection, up ) );
vSunfade = 1.0 - clamp( 1.0 - exp( ( sunPosition.y / 450000.0 ) ), 0.0, 1.0 );
float rayleighCoefficient = rayleigh - ( 1.0 * ( 1.0 - vSunfade ) );
// extinction (absorbtion + out scattering)
// rayleigh coefficients
vBetaR = totalRayleigh * rayleighCoefficient;
// mie coefficients
vBetaM = totalMie( turbidity ) * mieCoefficient;
}
`
),
fragmentShader: (
/* glsl */
`
varying vec3 vWorldPosition;
varying vec3 vSunDirection;
varying float vSunfade;
varying vec3 vBetaR;
varying vec3 vBetaM;
varying float vSunE;
uniform float mieDirectionalG;
uniform vec3 up;
const vec3 cameraPos = vec3( 0.0, 0.0, 0.0 );
// constants for atmospheric scattering
const float pi = 3.141592653589793238462643383279502884197169;
const float n = 1.0003; // refractive index of air
const float N = 2.545E25; // number of molecules per unit volume for air at 288.15K and 1013mb (sea level -45 celsius)
// optical length at zenith for molecules
const float rayleighZenithLength = 8.4E3;
const float mieZenithLength = 1.25E3;
// 66 arc seconds -> degrees, and the cosine of that
const float sunAngularDiameterCos = 0.999956676946448443553574619906976478926848692873900859324;
// 3.0 / ( 16.0 * pi )
const float THREE_OVER_SIXTEENPI = 0.05968310365946075;
// 1.0 / ( 4.0 * pi )
const float ONE_OVER_FOURPI = 0.07957747154594767;
float rayleighPhase( float cosTheta ) {
return THREE_OVER_SIXTEENPI * ( 1.0 + pow( cosTheta, 2.0 ) );
}
float hgPhase( float cosTheta, float g ) {
float g2 = pow( g, 2.0 );
float inverse = 1.0 / pow( 1.0 - 2.0 * g * cosTheta + g2, 1.5 );
return ONE_OVER_FOURPI * ( ( 1.0 - g2 ) * inverse );
}
void main() {
vec3 direction = normalize( vWorldPosition - cameraPos );
// optical length
// cutoff angle at 90 to avoid singularity in next formula.
float zenithAngle = acos( max( 0.0, dot( up, direction ) ) );
float inverse = 1.0 / ( cos( zenithAngle ) + 0.15 * pow( 93.885 - ( ( zenithAngle * 180.0 ) / pi ), -1.253 ) );
float sR = rayleighZenithLength * inverse;
float sM = mieZenithLength * inverse;
// combined extinction factor
vec3 Fex = exp( -( vBetaR * sR + vBetaM * sM ) );
// in scattering
float cosTheta = dot( direction, vSunDirection );
float rPhase = rayleighPhase( cosTheta * 0.5 + 0.5 );
vec3 betaRTheta = vBetaR * rPhase;
float mPhase = hgPhase( cosTheta, mieDirectionalG );
vec3 betaMTheta = vBetaM * mPhase;
vec3 Lin = pow( vSunE * ( ( betaRTheta + betaMTheta ) / ( vBetaR + vBetaM ) ) * ( 1.0 - Fex ), vec3( 1.5 ) );
Lin *= mix( vec3( 1.0 ), pow( vSunE * ( ( betaRTheta + betaMTheta ) / ( vBetaR + vBetaM ) ) * Fex, vec3( 1.0 / 2.0 ) ), clamp( pow( 1.0 - dot( up, vSunDirection ), 5.0 ), 0.0, 1.0 ) );
// nightsky
float theta = acos( direction.y ); // elevation --> y-axis, [-pi/2, pi/2]
float phi = atan( direction.z, direction.x ); // azimuth --> x-axis [-pi/2, pi/2]
vec2 uv = vec2( phi, theta ) / vec2( 2.0 * pi, pi ) + vec2( 0.5, 0.0 );
vec3 L0 = vec3( 0.1 ) * Fex;
// composition + solar disc
float sundisk = smoothstep( sunAngularDiameterCos, sunAngularDiameterCos + 0.00002, cosTheta );
L0 += ( vSunE * 19000.0 * Fex ) * sundisk;
vec3 texColor = ( Lin + L0 ) * 0.04 + vec3( 0.0, 0.0003, 0.00075 );
vec3 retColor = pow( texColor, vec3( 1.0 / ( 1.2 + ( 1.2 * vSunfade ) ) ) );
gl_FragColor = vec4( retColor, 1.0 );
#include <tonemapping_fragment>
#include <${version >= 154 ? "colorspace_fragment" : "encodings_fragment"}>
}
`
)
};
const material = new ShaderMaterial({
name: "SkyShader",
fragmentShader: SkyShader.fragmentShader,
vertexShader: SkyShader.vertexShader,
uniforms: UniformsUtils.clone(SkyShader.uniforms),
side: BackSide,
depthWrite: false
});
class Sky2 extends Mesh {
constructor() {
super(new BoxGeometry(1, 1, 1), material);
}
}
__publicField(Sky2, "SkyShader", SkyShader);
__publicField(Sky2, "material", material);
return Sky2;
})();
export {
Sky
};
//# sourceMappingURL=Sky.js.map
+1
View File
File diff suppressed because one or more lines are too long
+244
View File
@@ -0,0 +1,244 @@
"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const THREE = require("three");
const constants = require("../_polyfill/constants.cjs");
class Water extends THREE.Mesh {
constructor(geometry, options = {}) {
super(geometry);
this.isWater = true;
const scope = this;
const textureWidth = options.textureWidth !== void 0 ? options.textureWidth : 512;
const textureHeight = options.textureHeight !== void 0 ? options.textureHeight : 512;
const clipBias = options.clipBias !== void 0 ? options.clipBias : 0;
const alpha = options.alpha !== void 0 ? options.alpha : 1;
const time = options.time !== void 0 ? options.time : 0;
const normalSampler = options.waterNormals !== void 0 ? options.waterNormals : null;
const sunDirection = options.sunDirection !== void 0 ? options.sunDirection : new THREE.Vector3(0.70707, 0.70707, 0);
const sunColor = new THREE.Color(options.sunColor !== void 0 ? options.sunColor : 16777215);
const waterColor = new THREE.Color(options.waterColor !== void 0 ? options.waterColor : 8355711);
const eye = options.eye !== void 0 ? options.eye : new THREE.Vector3(0, 0, 0);
const distortionScale = options.distortionScale !== void 0 ? options.distortionScale : 20;
const side = options.side !== void 0 ? options.side : THREE.FrontSide;
const fog = options.fog !== void 0 ? options.fog : false;
const mirrorPlane = new THREE.Plane();
const normal = new THREE.Vector3();
const mirrorWorldPosition = new THREE.Vector3();
const cameraWorldPosition = new THREE.Vector3();
const rotationMatrix = new THREE.Matrix4();
const lookAtPosition = new THREE.Vector3(0, 0, -1);
const clipPlane = new THREE.Vector4();
const view = new THREE.Vector3();
const target = new THREE.Vector3();
const q = new THREE.Vector4();
const textureMatrix = new THREE.Matrix4();
const mirrorCamera = new THREE.PerspectiveCamera();
const renderTarget = new THREE.WebGLRenderTarget(textureWidth, textureHeight);
const mirrorShader = {
uniforms: THREE.UniformsUtils.merge([
THREE.UniformsLib["fog"],
THREE.UniformsLib["lights"],
{
normalSampler: { value: null },
mirrorSampler: { value: null },
alpha: { value: 1 },
time: { value: 0 },
size: { value: 1 },
distortionScale: { value: 20 },
textureMatrix: { value: new THREE.Matrix4() },
sunColor: { value: new THREE.Color(8355711) },
sunDirection: { value: new THREE.Vector3(0.70707, 0.70707, 0) },
eye: { value: new THREE.Vector3() },
waterColor: { value: new THREE.Color(5592405) }
}
]),
vertexShader: (
/* glsl */
`
uniform mat4 textureMatrix;
uniform float time;
varying vec4 mirrorCoord;
varying vec4 worldPosition;
#include <common>
#include <fog_pars_vertex>
#include <shadowmap_pars_vertex>
#include <logdepthbuf_pars_vertex>
void main() {
mirrorCoord = modelMatrix * vec4( position, 1.0 );
worldPosition = mirrorCoord.xyzw;
mirrorCoord = textureMatrix * mirrorCoord;
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
gl_Position = projectionMatrix * mvPosition;
#include <beginnormal_vertex>
#include <defaultnormal_vertex>
#include <logdepthbuf_vertex>
#include <fog_vertex>
#include <shadowmap_vertex>
}`
),
fragmentShader: (
/* glsl */
`
uniform sampler2D mirrorSampler;
uniform float alpha;
uniform float time;
uniform float size;
uniform float distortionScale;
uniform sampler2D normalSampler;
uniform vec3 sunColor;
uniform vec3 sunDirection;
uniform vec3 eye;
uniform vec3 waterColor;
varying vec4 mirrorCoord;
varying vec4 worldPosition;
vec4 getNoise( vec2 uv ) {
vec2 uv0 = ( uv / 103.0 ) + vec2(time / 17.0, time / 29.0);
vec2 uv1 = uv / 107.0-vec2( time / -19.0, time / 31.0 );
vec2 uv2 = uv / vec2( 8907.0, 9803.0 ) + vec2( time / 101.0, time / 97.0 );
vec2 uv3 = uv / vec2( 1091.0, 1027.0 ) - vec2( time / 109.0, time / -113.0 );
vec4 noise = texture2D( normalSampler, uv0 ) +
texture2D( normalSampler, uv1 ) +
texture2D( normalSampler, uv2 ) +
texture2D( normalSampler, uv3 );
return noise * 0.5 - 1.0;
}
void sunLight( const vec3 surfaceNormal, const vec3 eyeDirection, float shiny, float spec, float diffuse, inout vec3 diffuseColor, inout vec3 specularColor ) {
vec3 reflection = normalize( reflect( -sunDirection, surfaceNormal ) );
float direction = max( 0.0, dot( eyeDirection, reflection ) );
specularColor += pow( direction, shiny ) * sunColor * spec;
diffuseColor += max( dot( sunDirection, surfaceNormal ), 0.0 ) * sunColor * diffuse;
}
#include <common>
#include <packing>
#include <bsdfs>
#include <fog_pars_fragment>
#include <logdepthbuf_pars_fragment>
#include <lights_pars_begin>
#include <shadowmap_pars_fragment>
#include <shadowmask_pars_fragment>
void main() {
#include <logdepthbuf_fragment>
vec4 noise = getNoise( worldPosition.xz * size );
vec3 surfaceNormal = normalize( noise.xzy * vec3( 1.5, 1.0, 1.5 ) );
vec3 diffuseLight = vec3(0.0);
vec3 specularLight = vec3(0.0);
vec3 worldToEye = eye-worldPosition.xyz;
vec3 eyeDirection = normalize( worldToEye );
sunLight( surfaceNormal, eyeDirection, 100.0, 2.0, 0.5, diffuseLight, specularLight );
float distance = length(worldToEye);
vec2 distortion = surfaceNormal.xz * ( 0.001 + 1.0 / distance ) * distortionScale;
vec3 reflectionSample = vec3( texture2D( mirrorSampler, mirrorCoord.xy / mirrorCoord.w + distortion ) );
float theta = max( dot( eyeDirection, surfaceNormal ), 0.0 );
float rf0 = 0.3;
float reflectance = rf0 + ( 1.0 - rf0 ) * pow( ( 1.0 - theta ), 5.0 );
vec3 scatter = max( 0.0, dot( surfaceNormal, eyeDirection ) ) * waterColor;
vec3 albedo = mix( ( sunColor * diffuseLight * 0.3 + scatter ) * getShadowMask(), ( vec3( 0.1 ) + reflectionSample * 0.9 + reflectionSample * specularLight ), reflectance);
vec3 outgoingLight = albedo;
gl_FragColor = vec4( outgoingLight, alpha );
#include <tonemapping_fragment>
#include <${constants.version >= 154 ? "colorspace_fragment" : "encodings_fragment"}>
#include <fog_fragment>
}`
)
};
const material = new THREE.ShaderMaterial({
fragmentShader: mirrorShader.fragmentShader,
vertexShader: mirrorShader.vertexShader,
uniforms: THREE.UniformsUtils.clone(mirrorShader.uniforms),
lights: true,
side,
fog
});
material.uniforms["mirrorSampler"].value = renderTarget.texture;
material.uniforms["textureMatrix"].value = textureMatrix;
material.uniforms["alpha"].value = alpha;
material.uniforms["time"].value = time;
material.uniforms["normalSampler"].value = normalSampler;
material.uniforms["sunColor"].value = sunColor;
material.uniforms["waterColor"].value = waterColor;
material.uniforms["sunDirection"].value = sunDirection;
material.uniforms["distortionScale"].value = distortionScale;
material.uniforms["eye"].value = eye;
scope.material = material;
scope.onBeforeRender = function(renderer, scene, camera) {
mirrorWorldPosition.setFromMatrixPosition(scope.matrixWorld);
cameraWorldPosition.setFromMatrixPosition(camera.matrixWorld);
rotationMatrix.extractRotation(scope.matrixWorld);
normal.set(0, 0, 1);
normal.applyMatrix4(rotationMatrix);
view.subVectors(mirrorWorldPosition, cameraWorldPosition);
if (view.dot(normal) > 0)
return;
view.reflect(normal).negate();
view.add(mirrorWorldPosition);
rotationMatrix.extractRotation(camera.matrixWorld);
lookAtPosition.set(0, 0, -1);
lookAtPosition.applyMatrix4(rotationMatrix);
lookAtPosition.add(cameraWorldPosition);
target.subVectors(mirrorWorldPosition, lookAtPosition);
target.reflect(normal).negate();
target.add(mirrorWorldPosition);
mirrorCamera.position.copy(view);
mirrorCamera.up.set(0, 1, 0);
mirrorCamera.up.applyMatrix4(rotationMatrix);
mirrorCamera.up.reflect(normal);
mirrorCamera.lookAt(target);
mirrorCamera.far = camera.far;
mirrorCamera.updateMatrixWorld();
mirrorCamera.projectionMatrix.copy(camera.projectionMatrix);
textureMatrix.set(0.5, 0, 0, 0.5, 0, 0.5, 0, 0.5, 0, 0, 0.5, 0.5, 0, 0, 0, 1);
textureMatrix.multiply(mirrorCamera.projectionMatrix);
textureMatrix.multiply(mirrorCamera.matrixWorldInverse);
mirrorPlane.setFromNormalAndCoplanarPoint(normal, mirrorWorldPosition);
mirrorPlane.applyMatrix4(mirrorCamera.matrixWorldInverse);
clipPlane.set(mirrorPlane.normal.x, mirrorPlane.normal.y, mirrorPlane.normal.z, mirrorPlane.constant);
const projectionMatrix = mirrorCamera.projectionMatrix;
q.x = (Math.sign(clipPlane.x) + projectionMatrix.elements[8]) / projectionMatrix.elements[0];
q.y = (Math.sign(clipPlane.y) + projectionMatrix.elements[9]) / projectionMatrix.elements[5];
q.z = -1;
q.w = (1 + projectionMatrix.elements[10]) / projectionMatrix.elements[14];
clipPlane.multiplyScalar(2 / clipPlane.dot(q));
projectionMatrix.elements[2] = clipPlane.x;
projectionMatrix.elements[6] = clipPlane.y;
projectionMatrix.elements[10] = clipPlane.z + 1 - clipBias;
projectionMatrix.elements[14] = clipPlane.w;
eye.setFromMatrixPosition(camera.matrixWorld);
const currentRenderTarget = renderer.getRenderTarget();
const currentXrEnabled = renderer.xr.enabled;
const currentShadowAutoUpdate = renderer.shadowMap.autoUpdate;
scope.visible = false;
renderer.xr.enabled = false;
renderer.shadowMap.autoUpdate = false;
renderer.setRenderTarget(renderTarget);
renderer.state.buffers.depth.setMask(true);
if (renderer.autoClear === false)
renderer.clear();
renderer.render(scene, mirrorCamera);
scope.visible = true;
renderer.xr.enabled = currentXrEnabled;
renderer.shadowMap.autoUpdate = currentShadowAutoUpdate;
renderer.setRenderTarget(currentRenderTarget);
const viewport = camera.viewport;
if (viewport !== void 0) {
renderer.state.viewport(viewport);
}
};
}
}
exports.Water = Water;
//# sourceMappingURL=Water.cjs.map
File diff suppressed because one or more lines are too long
+22
View File
@@ -0,0 +1,22 @@
import { BufferGeometry, Color, Mesh, ShaderMaterial, Side, Texture, Vector3 } from 'three'
export interface WaterOptions {
textureWidth?: number
textureHeight?: number
clipBias?: number
alpha?: number
time?: number
waterNormals?: Texture
sunDirection?: Vector3
sunColor?: Color | string | number
waterColor?: Color | string | number
eye?: Vector3
distortionScale?: number
side?: Side
fog?: boolean
}
export class Water extends Mesh {
material: ShaderMaterial
constructor(geometry: BufferGeometry, options: WaterOptions)
}
+244
View File
@@ -0,0 +1,244 @@
import { Mesh, Vector3, Color, FrontSide, Plane, Matrix4, Vector4, PerspectiveCamera, WebGLRenderTarget, UniformsUtils, UniformsLib, ShaderMaterial } from "three";
import { version } from "../_polyfill/constants.js";
class Water extends Mesh {
constructor(geometry, options = {}) {
super(geometry);
this.isWater = true;
const scope = this;
const textureWidth = options.textureWidth !== void 0 ? options.textureWidth : 512;
const textureHeight = options.textureHeight !== void 0 ? options.textureHeight : 512;
const clipBias = options.clipBias !== void 0 ? options.clipBias : 0;
const alpha = options.alpha !== void 0 ? options.alpha : 1;
const time = options.time !== void 0 ? options.time : 0;
const normalSampler = options.waterNormals !== void 0 ? options.waterNormals : null;
const sunDirection = options.sunDirection !== void 0 ? options.sunDirection : new Vector3(0.70707, 0.70707, 0);
const sunColor = new Color(options.sunColor !== void 0 ? options.sunColor : 16777215);
const waterColor = new Color(options.waterColor !== void 0 ? options.waterColor : 8355711);
const eye = options.eye !== void 0 ? options.eye : new Vector3(0, 0, 0);
const distortionScale = options.distortionScale !== void 0 ? options.distortionScale : 20;
const side = options.side !== void 0 ? options.side : FrontSide;
const fog = options.fog !== void 0 ? options.fog : false;
const mirrorPlane = new Plane();
const normal = new Vector3();
const mirrorWorldPosition = new Vector3();
const cameraWorldPosition = new Vector3();
const rotationMatrix = new Matrix4();
const lookAtPosition = new Vector3(0, 0, -1);
const clipPlane = new Vector4();
const view = new Vector3();
const target = new Vector3();
const q = new Vector4();
const textureMatrix = new Matrix4();
const mirrorCamera = new PerspectiveCamera();
const renderTarget = new WebGLRenderTarget(textureWidth, textureHeight);
const mirrorShader = {
uniforms: UniformsUtils.merge([
UniformsLib["fog"],
UniformsLib["lights"],
{
normalSampler: { value: null },
mirrorSampler: { value: null },
alpha: { value: 1 },
time: { value: 0 },
size: { value: 1 },
distortionScale: { value: 20 },
textureMatrix: { value: new Matrix4() },
sunColor: { value: new Color(8355711) },
sunDirection: { value: new Vector3(0.70707, 0.70707, 0) },
eye: { value: new Vector3() },
waterColor: { value: new Color(5592405) }
}
]),
vertexShader: (
/* glsl */
`
uniform mat4 textureMatrix;
uniform float time;
varying vec4 mirrorCoord;
varying vec4 worldPosition;
#include <common>
#include <fog_pars_vertex>
#include <shadowmap_pars_vertex>
#include <logdepthbuf_pars_vertex>
void main() {
mirrorCoord = modelMatrix * vec4( position, 1.0 );
worldPosition = mirrorCoord.xyzw;
mirrorCoord = textureMatrix * mirrorCoord;
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
gl_Position = projectionMatrix * mvPosition;
#include <beginnormal_vertex>
#include <defaultnormal_vertex>
#include <logdepthbuf_vertex>
#include <fog_vertex>
#include <shadowmap_vertex>
}`
),
fragmentShader: (
/* glsl */
`
uniform sampler2D mirrorSampler;
uniform float alpha;
uniform float time;
uniform float size;
uniform float distortionScale;
uniform sampler2D normalSampler;
uniform vec3 sunColor;
uniform vec3 sunDirection;
uniform vec3 eye;
uniform vec3 waterColor;
varying vec4 mirrorCoord;
varying vec4 worldPosition;
vec4 getNoise( vec2 uv ) {
vec2 uv0 = ( uv / 103.0 ) + vec2(time / 17.0, time / 29.0);
vec2 uv1 = uv / 107.0-vec2( time / -19.0, time / 31.0 );
vec2 uv2 = uv / vec2( 8907.0, 9803.0 ) + vec2( time / 101.0, time / 97.0 );
vec2 uv3 = uv / vec2( 1091.0, 1027.0 ) - vec2( time / 109.0, time / -113.0 );
vec4 noise = texture2D( normalSampler, uv0 ) +
texture2D( normalSampler, uv1 ) +
texture2D( normalSampler, uv2 ) +
texture2D( normalSampler, uv3 );
return noise * 0.5 - 1.0;
}
void sunLight( const vec3 surfaceNormal, const vec3 eyeDirection, float shiny, float spec, float diffuse, inout vec3 diffuseColor, inout vec3 specularColor ) {
vec3 reflection = normalize( reflect( -sunDirection, surfaceNormal ) );
float direction = max( 0.0, dot( eyeDirection, reflection ) );
specularColor += pow( direction, shiny ) * sunColor * spec;
diffuseColor += max( dot( sunDirection, surfaceNormal ), 0.0 ) * sunColor * diffuse;
}
#include <common>
#include <packing>
#include <bsdfs>
#include <fog_pars_fragment>
#include <logdepthbuf_pars_fragment>
#include <lights_pars_begin>
#include <shadowmap_pars_fragment>
#include <shadowmask_pars_fragment>
void main() {
#include <logdepthbuf_fragment>
vec4 noise = getNoise( worldPosition.xz * size );
vec3 surfaceNormal = normalize( noise.xzy * vec3( 1.5, 1.0, 1.5 ) );
vec3 diffuseLight = vec3(0.0);
vec3 specularLight = vec3(0.0);
vec3 worldToEye = eye-worldPosition.xyz;
vec3 eyeDirection = normalize( worldToEye );
sunLight( surfaceNormal, eyeDirection, 100.0, 2.0, 0.5, diffuseLight, specularLight );
float distance = length(worldToEye);
vec2 distortion = surfaceNormal.xz * ( 0.001 + 1.0 / distance ) * distortionScale;
vec3 reflectionSample = vec3( texture2D( mirrorSampler, mirrorCoord.xy / mirrorCoord.w + distortion ) );
float theta = max( dot( eyeDirection, surfaceNormal ), 0.0 );
float rf0 = 0.3;
float reflectance = rf0 + ( 1.0 - rf0 ) * pow( ( 1.0 - theta ), 5.0 );
vec3 scatter = max( 0.0, dot( surfaceNormal, eyeDirection ) ) * waterColor;
vec3 albedo = mix( ( sunColor * diffuseLight * 0.3 + scatter ) * getShadowMask(), ( vec3( 0.1 ) + reflectionSample * 0.9 + reflectionSample * specularLight ), reflectance);
vec3 outgoingLight = albedo;
gl_FragColor = vec4( outgoingLight, alpha );
#include <tonemapping_fragment>
#include <${version >= 154 ? "colorspace_fragment" : "encodings_fragment"}>
#include <fog_fragment>
}`
)
};
const material = new ShaderMaterial({
fragmentShader: mirrorShader.fragmentShader,
vertexShader: mirrorShader.vertexShader,
uniforms: UniformsUtils.clone(mirrorShader.uniforms),
lights: true,
side,
fog
});
material.uniforms["mirrorSampler"].value = renderTarget.texture;
material.uniforms["textureMatrix"].value = textureMatrix;
material.uniforms["alpha"].value = alpha;
material.uniforms["time"].value = time;
material.uniforms["normalSampler"].value = normalSampler;
material.uniforms["sunColor"].value = sunColor;
material.uniforms["waterColor"].value = waterColor;
material.uniforms["sunDirection"].value = sunDirection;
material.uniforms["distortionScale"].value = distortionScale;
material.uniforms["eye"].value = eye;
scope.material = material;
scope.onBeforeRender = function(renderer, scene, camera) {
mirrorWorldPosition.setFromMatrixPosition(scope.matrixWorld);
cameraWorldPosition.setFromMatrixPosition(camera.matrixWorld);
rotationMatrix.extractRotation(scope.matrixWorld);
normal.set(0, 0, 1);
normal.applyMatrix4(rotationMatrix);
view.subVectors(mirrorWorldPosition, cameraWorldPosition);
if (view.dot(normal) > 0)
return;
view.reflect(normal).negate();
view.add(mirrorWorldPosition);
rotationMatrix.extractRotation(camera.matrixWorld);
lookAtPosition.set(0, 0, -1);
lookAtPosition.applyMatrix4(rotationMatrix);
lookAtPosition.add(cameraWorldPosition);
target.subVectors(mirrorWorldPosition, lookAtPosition);
target.reflect(normal).negate();
target.add(mirrorWorldPosition);
mirrorCamera.position.copy(view);
mirrorCamera.up.set(0, 1, 0);
mirrorCamera.up.applyMatrix4(rotationMatrix);
mirrorCamera.up.reflect(normal);
mirrorCamera.lookAt(target);
mirrorCamera.far = camera.far;
mirrorCamera.updateMatrixWorld();
mirrorCamera.projectionMatrix.copy(camera.projectionMatrix);
textureMatrix.set(0.5, 0, 0, 0.5, 0, 0.5, 0, 0.5, 0, 0, 0.5, 0.5, 0, 0, 0, 1);
textureMatrix.multiply(mirrorCamera.projectionMatrix);
textureMatrix.multiply(mirrorCamera.matrixWorldInverse);
mirrorPlane.setFromNormalAndCoplanarPoint(normal, mirrorWorldPosition);
mirrorPlane.applyMatrix4(mirrorCamera.matrixWorldInverse);
clipPlane.set(mirrorPlane.normal.x, mirrorPlane.normal.y, mirrorPlane.normal.z, mirrorPlane.constant);
const projectionMatrix = mirrorCamera.projectionMatrix;
q.x = (Math.sign(clipPlane.x) + projectionMatrix.elements[8]) / projectionMatrix.elements[0];
q.y = (Math.sign(clipPlane.y) + projectionMatrix.elements[9]) / projectionMatrix.elements[5];
q.z = -1;
q.w = (1 + projectionMatrix.elements[10]) / projectionMatrix.elements[14];
clipPlane.multiplyScalar(2 / clipPlane.dot(q));
projectionMatrix.elements[2] = clipPlane.x;
projectionMatrix.elements[6] = clipPlane.y;
projectionMatrix.elements[10] = clipPlane.z + 1 - clipBias;
projectionMatrix.elements[14] = clipPlane.w;
eye.setFromMatrixPosition(camera.matrixWorld);
const currentRenderTarget = renderer.getRenderTarget();
const currentXrEnabled = renderer.xr.enabled;
const currentShadowAutoUpdate = renderer.shadowMap.autoUpdate;
scope.visible = false;
renderer.xr.enabled = false;
renderer.shadowMap.autoUpdate = false;
renderer.setRenderTarget(renderTarget);
renderer.state.buffers.depth.setMask(true);
if (renderer.autoClear === false)
renderer.clear();
renderer.render(scene, mirrorCamera);
scope.visible = true;
renderer.xr.enabled = currentXrEnabled;
renderer.shadowMap.autoUpdate = currentShadowAutoUpdate;
renderer.setRenderTarget(currentRenderTarget);
const viewport = camera.viewport;
if (viewport !== void 0) {
renderer.state.viewport(viewport);
}
};
}
}
export {
Water
};
//# sourceMappingURL=Water.js.map
File diff suppressed because one or more lines are too long
+261
View File
@@ -0,0 +1,261 @@
"use strict";
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const THREE = require("three");
const Reflector = require("./Reflector.cjs");
const Refractor = require("./Refractor.cjs");
const constants = require("../_polyfill/constants.cjs");
const Water2 = /* @__PURE__ */ (() => {
const _Water2 = class extends THREE.Mesh {
constructor(geometry, options = {}) {
super(geometry);
this.isWater = true;
this.type = "Water";
const scope = this;
const color = options.color !== void 0 ? new THREE.Color(options.color) : new THREE.Color(16777215);
const textureWidth = options.textureWidth || 512;
const textureHeight = options.textureHeight || 512;
const clipBias = options.clipBias || 0;
const flowDirection = options.flowDirection || new THREE.Vector2(1, 0);
const flowSpeed = options.flowSpeed || 0.03;
const reflectivity = options.reflectivity || 0.02;
const scale = options.scale || 1;
const shader = options.shader || _Water2.WaterShader;
const encoding = options.encoding !== void 0 ? options.encoding : 3e3;
const flowMap = options.flowMap || void 0;
const normalMap0 = options.normalMap0;
const normalMap1 = options.normalMap1;
const cycle = 0.15;
const halfCycle = cycle * 0.5;
const textureMatrix = new THREE.Matrix4();
const clock = new THREE.Clock();
if (Reflector.Reflector === void 0) {
console.error("THREE.Water: Required component Reflector not found.");
return;
}
if (Refractor.Refractor === void 0) {
console.error("THREE.Water: Required component Refractor not found.");
return;
}
const reflector = new Reflector.Reflector(geometry, {
textureWidth,
textureHeight,
clipBias,
encoding
});
const refractor = new Refractor.Refractor(geometry, {
textureWidth,
textureHeight,
clipBias,
encoding
});
reflector.matrixAutoUpdate = false;
refractor.matrixAutoUpdate = false;
this.material = new THREE.ShaderMaterial({
uniforms: THREE.UniformsUtils.merge([THREE.UniformsLib["fog"], shader.uniforms]),
vertexShader: shader.vertexShader,
fragmentShader: shader.fragmentShader,
transparent: true,
fog: true
});
if (flowMap !== void 0) {
this.material.defines.USE_FLOWMAP = "";
this.material.uniforms["tFlowMap"] = {
type: "t",
value: flowMap
};
} else {
this.material.uniforms["flowDirection"] = {
type: "v2",
value: flowDirection
};
}
normalMap0.wrapS = normalMap0.wrapT = THREE.RepeatWrapping;
normalMap1.wrapS = normalMap1.wrapT = THREE.RepeatWrapping;
this.material.uniforms["tReflectionMap"].value = reflector.getRenderTarget().texture;
this.material.uniforms["tRefractionMap"].value = refractor.getRenderTarget().texture;
this.material.uniforms["tNormalMap0"].value = normalMap0;
this.material.uniforms["tNormalMap1"].value = normalMap1;
this.material.uniforms["color"].value = color;
this.material.uniforms["reflectivity"].value = reflectivity;
this.material.uniforms["textureMatrix"].value = textureMatrix;
this.material.uniforms["config"].value.x = 0;
this.material.uniforms["config"].value.y = halfCycle;
this.material.uniforms["config"].value.z = halfCycle;
this.material.uniforms["config"].value.w = scale;
function updateTextureMatrix(camera) {
textureMatrix.set(0.5, 0, 0, 0.5, 0, 0.5, 0, 0.5, 0, 0, 0.5, 0.5, 0, 0, 0, 1);
textureMatrix.multiply(camera.projectionMatrix);
textureMatrix.multiply(camera.matrixWorldInverse);
textureMatrix.multiply(scope.matrixWorld);
}
function updateFlow() {
const delta = clock.getDelta();
const config = scope.material.uniforms["config"];
config.value.x += flowSpeed * delta;
config.value.y = config.value.x + halfCycle;
if (config.value.x >= cycle) {
config.value.x = 0;
config.value.y = halfCycle;
} else if (config.value.y >= cycle) {
config.value.y = config.value.y - cycle;
}
}
this.onBeforeRender = function(renderer, scene, camera) {
updateTextureMatrix(camera);
updateFlow();
scope.visible = false;
reflector.matrixWorld.copy(scope.matrixWorld);
refractor.matrixWorld.copy(scope.matrixWorld);
reflector.onBeforeRender(renderer, scene, camera);
refractor.onBeforeRender(renderer, scene, camera);
scope.visible = true;
};
}
};
let Water22 = _Water2;
__publicField(Water22, "WaterShader", {
uniforms: {
color: {
value: null
},
reflectivity: {
value: 0
},
tReflectionMap: {
value: null
},
tRefractionMap: {
value: null
},
tNormalMap0: {
value: null
},
tNormalMap1: {
value: null
},
textureMatrix: {
value: null
},
config: {
value: /* @__PURE__ */ new THREE.Vector4()
}
},
vertexShader: (
/* glsl */
`
#include <common>
#include <fog_pars_vertex>
#include <logdepthbuf_pars_vertex>
uniform mat4 textureMatrix;
varying vec4 vCoord;
varying vec2 vUv;
varying vec3 vToEye;
void main() {
vUv = uv;
vCoord = textureMatrix * vec4( position, 1.0 );
vec4 worldPosition = modelMatrix * vec4( position, 1.0 );
vToEye = cameraPosition - worldPosition.xyz;
vec4 mvPosition = viewMatrix * worldPosition; // used in fog_vertex
gl_Position = projectionMatrix * mvPosition;
#include <logdepthbuf_vertex>
#include <fog_vertex>
}`
),
fragmentShader: (
/* glsl */
`
#include <common>
#include <fog_pars_fragment>
#include <logdepthbuf_pars_fragment>
uniform sampler2D tReflectionMap;
uniform sampler2D tRefractionMap;
uniform sampler2D tNormalMap0;
uniform sampler2D tNormalMap1;
#ifdef USE_FLOWMAP
uniform sampler2D tFlowMap;
#else
uniform vec2 flowDirection;
#endif
uniform vec3 color;
uniform float reflectivity;
uniform vec4 config;
varying vec4 vCoord;
varying vec2 vUv;
varying vec3 vToEye;
void main() {
#include <logdepthbuf_fragment>
float flowMapOffset0 = config.x;
float flowMapOffset1 = config.y;
float halfCycle = config.z;
float scale = config.w;
vec3 toEye = normalize( vToEye );
// determine flow direction
vec2 flow;
#ifdef USE_FLOWMAP
flow = texture2D( tFlowMap, vUv ).rg * 2.0 - 1.0;
#else
flow = flowDirection;
#endif
flow.x *= - 1.0;
// sample normal maps (distort uvs with flowdata)
vec4 normalColor0 = texture2D( tNormalMap0, ( vUv * scale ) + flow * flowMapOffset0 );
vec4 normalColor1 = texture2D( tNormalMap1, ( vUv * scale ) + flow * flowMapOffset1 );
// linear interpolate to get the final normal color
float flowLerp = abs( halfCycle - flowMapOffset0 ) / halfCycle;
vec4 normalColor = mix( normalColor0, normalColor1, flowLerp );
// calculate normal vector
vec3 normal = normalize( vec3( normalColor.r * 2.0 - 1.0, normalColor.b, normalColor.g * 2.0 - 1.0 ) );
// calculate the fresnel term to blend reflection and refraction maps
float theta = max( dot( toEye, normal ), 0.0 );
float reflectance = reflectivity + ( 1.0 - reflectivity ) * pow( ( 1.0 - theta ), 5.0 );
// calculate final uv coords
vec3 coord = vCoord.xyz / vCoord.w;
vec2 uv = coord.xy + coord.z * normal.xz * 0.05;
vec4 reflectColor = texture2D( tReflectionMap, vec2( 1.0 - uv.x, uv.y ) );
vec4 refractColor = texture2D( tRefractionMap, uv );
// multiply water color with the mix of both textures
gl_FragColor = vec4( color, 1.0 ) * mix( refractColor, reflectColor, reflectance );
#include <tonemapping_fragment>
#include <${constants.version >= 154 ? "colorspace_fragment" : "encodings_fragment"}>
#include <fog_fragment>
}`
)
});
return Water22;
})();
exports.Water2 = Water2;
//# sourceMappingURL=Water2.cjs.map
File diff suppressed because one or more lines are too long
+23
View File
@@ -0,0 +1,23 @@
import { BufferGeometry, Color, Mesh, ShaderMaterial, Texture, Vector2 } from 'three'
import { TextureEncoding } from '../types/shared'
export interface Water2Options {
color?: Color | string | number
textureWidth?: number
textureHeight?: number
clipBias?: number
flowDirection?: Vector2
flowSpeed?: number
reflectivity?: number
scale?: number
shader?: object
flowMap?: Texture
normalMap0?: Texture
normalMap1?: Texture
encoding?: TextureEncoding
}
export class Water2 extends Mesh {
material: ShaderMaterial
constructor(geometry: BufferGeometry, options: Water2Options)
}
+261
View File
@@ -0,0 +1,261 @@
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
import { Mesh, Vector4, Color, Vector2, Matrix4, Clock, ShaderMaterial, UniformsUtils, UniformsLib, RepeatWrapping } from "three";
import { Reflector } from "./Reflector.js";
import { Refractor } from "./Refractor.js";
import { version } from "../_polyfill/constants.js";
const Water2 = /* @__PURE__ */ (() => {
const _Water2 = class extends Mesh {
constructor(geometry, options = {}) {
super(geometry);
this.isWater = true;
this.type = "Water";
const scope = this;
const color = options.color !== void 0 ? new Color(options.color) : new Color(16777215);
const textureWidth = options.textureWidth || 512;
const textureHeight = options.textureHeight || 512;
const clipBias = options.clipBias || 0;
const flowDirection = options.flowDirection || new Vector2(1, 0);
const flowSpeed = options.flowSpeed || 0.03;
const reflectivity = options.reflectivity || 0.02;
const scale = options.scale || 1;
const shader = options.shader || _Water2.WaterShader;
const encoding = options.encoding !== void 0 ? options.encoding : 3e3;
const flowMap = options.flowMap || void 0;
const normalMap0 = options.normalMap0;
const normalMap1 = options.normalMap1;
const cycle = 0.15;
const halfCycle = cycle * 0.5;
const textureMatrix = new Matrix4();
const clock = new Clock();
if (Reflector === void 0) {
console.error("THREE.Water: Required component Reflector not found.");
return;
}
if (Refractor === void 0) {
console.error("THREE.Water: Required component Refractor not found.");
return;
}
const reflector = new Reflector(geometry, {
textureWidth,
textureHeight,
clipBias,
encoding
});
const refractor = new Refractor(geometry, {
textureWidth,
textureHeight,
clipBias,
encoding
});
reflector.matrixAutoUpdate = false;
refractor.matrixAutoUpdate = false;
this.material = new ShaderMaterial({
uniforms: UniformsUtils.merge([UniformsLib["fog"], shader.uniforms]),
vertexShader: shader.vertexShader,
fragmentShader: shader.fragmentShader,
transparent: true,
fog: true
});
if (flowMap !== void 0) {
this.material.defines.USE_FLOWMAP = "";
this.material.uniforms["tFlowMap"] = {
type: "t",
value: flowMap
};
} else {
this.material.uniforms["flowDirection"] = {
type: "v2",
value: flowDirection
};
}
normalMap0.wrapS = normalMap0.wrapT = RepeatWrapping;
normalMap1.wrapS = normalMap1.wrapT = RepeatWrapping;
this.material.uniforms["tReflectionMap"].value = reflector.getRenderTarget().texture;
this.material.uniforms["tRefractionMap"].value = refractor.getRenderTarget().texture;
this.material.uniforms["tNormalMap0"].value = normalMap0;
this.material.uniforms["tNormalMap1"].value = normalMap1;
this.material.uniforms["color"].value = color;
this.material.uniforms["reflectivity"].value = reflectivity;
this.material.uniforms["textureMatrix"].value = textureMatrix;
this.material.uniforms["config"].value.x = 0;
this.material.uniforms["config"].value.y = halfCycle;
this.material.uniforms["config"].value.z = halfCycle;
this.material.uniforms["config"].value.w = scale;
function updateTextureMatrix(camera) {
textureMatrix.set(0.5, 0, 0, 0.5, 0, 0.5, 0, 0.5, 0, 0, 0.5, 0.5, 0, 0, 0, 1);
textureMatrix.multiply(camera.projectionMatrix);
textureMatrix.multiply(camera.matrixWorldInverse);
textureMatrix.multiply(scope.matrixWorld);
}
function updateFlow() {
const delta = clock.getDelta();
const config = scope.material.uniforms["config"];
config.value.x += flowSpeed * delta;
config.value.y = config.value.x + halfCycle;
if (config.value.x >= cycle) {
config.value.x = 0;
config.value.y = halfCycle;
} else if (config.value.y >= cycle) {
config.value.y = config.value.y - cycle;
}
}
this.onBeforeRender = function(renderer, scene, camera) {
updateTextureMatrix(camera);
updateFlow();
scope.visible = false;
reflector.matrixWorld.copy(scope.matrixWorld);
refractor.matrixWorld.copy(scope.matrixWorld);
reflector.onBeforeRender(renderer, scene, camera);
refractor.onBeforeRender(renderer, scene, camera);
scope.visible = true;
};
}
};
let Water22 = _Water2;
__publicField(Water22, "WaterShader", {
uniforms: {
color: {
value: null
},
reflectivity: {
value: 0
},
tReflectionMap: {
value: null
},
tRefractionMap: {
value: null
},
tNormalMap0: {
value: null
},
tNormalMap1: {
value: null
},
textureMatrix: {
value: null
},
config: {
value: /* @__PURE__ */ new Vector4()
}
},
vertexShader: (
/* glsl */
`
#include <common>
#include <fog_pars_vertex>
#include <logdepthbuf_pars_vertex>
uniform mat4 textureMatrix;
varying vec4 vCoord;
varying vec2 vUv;
varying vec3 vToEye;
void main() {
vUv = uv;
vCoord = textureMatrix * vec4( position, 1.0 );
vec4 worldPosition = modelMatrix * vec4( position, 1.0 );
vToEye = cameraPosition - worldPosition.xyz;
vec4 mvPosition = viewMatrix * worldPosition; // used in fog_vertex
gl_Position = projectionMatrix * mvPosition;
#include <logdepthbuf_vertex>
#include <fog_vertex>
}`
),
fragmentShader: (
/* glsl */
`
#include <common>
#include <fog_pars_fragment>
#include <logdepthbuf_pars_fragment>
uniform sampler2D tReflectionMap;
uniform sampler2D tRefractionMap;
uniform sampler2D tNormalMap0;
uniform sampler2D tNormalMap1;
#ifdef USE_FLOWMAP
uniform sampler2D tFlowMap;
#else
uniform vec2 flowDirection;
#endif
uniform vec3 color;
uniform float reflectivity;
uniform vec4 config;
varying vec4 vCoord;
varying vec2 vUv;
varying vec3 vToEye;
void main() {
#include <logdepthbuf_fragment>
float flowMapOffset0 = config.x;
float flowMapOffset1 = config.y;
float halfCycle = config.z;
float scale = config.w;
vec3 toEye = normalize( vToEye );
// determine flow direction
vec2 flow;
#ifdef USE_FLOWMAP
flow = texture2D( tFlowMap, vUv ).rg * 2.0 - 1.0;
#else
flow = flowDirection;
#endif
flow.x *= - 1.0;
// sample normal maps (distort uvs with flowdata)
vec4 normalColor0 = texture2D( tNormalMap0, ( vUv * scale ) + flow * flowMapOffset0 );
vec4 normalColor1 = texture2D( tNormalMap1, ( vUv * scale ) + flow * flowMapOffset1 );
// linear interpolate to get the final normal color
float flowLerp = abs( halfCycle - flowMapOffset0 ) / halfCycle;
vec4 normalColor = mix( normalColor0, normalColor1, flowLerp );
// calculate normal vector
vec3 normal = normalize( vec3( normalColor.r * 2.0 - 1.0, normalColor.b, normalColor.g * 2.0 - 1.0 ) );
// calculate the fresnel term to blend reflection and refraction maps
float theta = max( dot( toEye, normal ), 0.0 );
float reflectance = reflectivity + ( 1.0 - reflectivity ) * pow( ( 1.0 - theta ), 5.0 );
// calculate final uv coords
vec3 coord = vCoord.xyz / vCoord.w;
vec2 uv = coord.xy + coord.z * normal.xz * 0.05;
vec4 reflectColor = texture2D( tReflectionMap, vec2( 1.0 - uv.x, uv.y ) );
vec4 refractColor = texture2D( tRefractionMap, uv );
// multiply water color with the mix of both textures
gl_FragColor = vec4( color, 1.0 ) * mix( refractColor, reflectColor, reflectance );
#include <tonemapping_fragment>
#include <${version >= 154 ? "colorspace_fragment" : "encodings_fragment"}>
#include <fog_fragment>
}`
)
});
return Water22;
})();
export {
Water2
};
//# sourceMappingURL=Water2.js.map
File diff suppressed because one or more lines are too long