Initial project import
This commit is contained in:
206
node_modules/three-stdlib/misc/GPUComputationRenderer.js
generated
vendored
Normal file
206
node_modules/three-stdlib/misc/GPUComputationRenderer.js
generated
vendored
Normal file
@@ -0,0 +1,206 @@
|
||||
import { Scene, Camera, Mesh, PlaneGeometry, ShaderMaterial, WebGLRenderTarget, RGBAFormat, DataTexture, FloatType, NoToneMapping, NearestFilter, ClampToEdgeWrapping } from "three";
|
||||
class GPUComputationRenderer {
|
||||
constructor(sizeX, sizeY, renderer) {
|
||||
this.variables = [];
|
||||
this.currentTextureIndex = 0;
|
||||
let dataType = FloatType;
|
||||
const scene = new Scene();
|
||||
const camera = new Camera();
|
||||
camera.position.z = 1;
|
||||
const passThruUniforms = {
|
||||
passThruTexture: { value: null }
|
||||
};
|
||||
const passThruShader = createShaderMaterial(getPassThroughFragmentShader(), passThruUniforms);
|
||||
const mesh = new Mesh(new PlaneGeometry(2, 2), passThruShader);
|
||||
scene.add(mesh);
|
||||
this.setDataType = function(type) {
|
||||
dataType = type;
|
||||
return this;
|
||||
};
|
||||
this.addVariable = function(variableName, computeFragmentShader, initialValueTexture) {
|
||||
const material = this.createShaderMaterial(computeFragmentShader);
|
||||
const variable = {
|
||||
name: variableName,
|
||||
initialValueTexture,
|
||||
material,
|
||||
dependencies: null,
|
||||
renderTargets: [],
|
||||
wrapS: null,
|
||||
wrapT: null,
|
||||
minFilter: NearestFilter,
|
||||
magFilter: NearestFilter
|
||||
};
|
||||
this.variables.push(variable);
|
||||
return variable;
|
||||
};
|
||||
this.setVariableDependencies = function(variable, dependencies) {
|
||||
variable.dependencies = dependencies;
|
||||
};
|
||||
this.init = function() {
|
||||
if (renderer.capabilities.isWebGL2 === false && renderer.extensions.has("OES_texture_float") === false) {
|
||||
return "No OES_texture_float support for float textures.";
|
||||
}
|
||||
if (renderer.capabilities.maxVertexTextures === 0) {
|
||||
return "No support for vertex shader textures.";
|
||||
}
|
||||
for (let i = 0; i < this.variables.length; i++) {
|
||||
const variable = this.variables[i];
|
||||
variable.renderTargets[0] = this.createRenderTarget(
|
||||
sizeX,
|
||||
sizeY,
|
||||
variable.wrapS,
|
||||
variable.wrapT,
|
||||
variable.minFilter,
|
||||
variable.magFilter
|
||||
);
|
||||
variable.renderTargets[1] = this.createRenderTarget(
|
||||
sizeX,
|
||||
sizeY,
|
||||
variable.wrapS,
|
||||
variable.wrapT,
|
||||
variable.minFilter,
|
||||
variable.magFilter
|
||||
);
|
||||
this.renderTexture(variable.initialValueTexture, variable.renderTargets[0]);
|
||||
this.renderTexture(variable.initialValueTexture, variable.renderTargets[1]);
|
||||
const material = variable.material;
|
||||
const uniforms = material.uniforms;
|
||||
if (variable.dependencies !== null) {
|
||||
for (let d = 0; d < variable.dependencies.length; d++) {
|
||||
const depVar = variable.dependencies[d];
|
||||
if (depVar.name !== variable.name) {
|
||||
let found = false;
|
||||
for (let j = 0; j < this.variables.length; j++) {
|
||||
if (depVar.name === this.variables[j].name) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
return "Variable dependency not found. Variable=" + variable.name + ", dependency=" + depVar.name;
|
||||
}
|
||||
}
|
||||
uniforms[depVar.name] = { value: null };
|
||||
material.fragmentShader = "\nuniform sampler2D " + depVar.name + ";\n" + material.fragmentShader;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.currentTextureIndex = 0;
|
||||
return null;
|
||||
};
|
||||
this.compute = function() {
|
||||
const currentTextureIndex = this.currentTextureIndex;
|
||||
const nextTextureIndex = this.currentTextureIndex === 0 ? 1 : 0;
|
||||
for (let i = 0, il = this.variables.length; i < il; i++) {
|
||||
const variable = this.variables[i];
|
||||
if (variable.dependencies !== null) {
|
||||
const uniforms = variable.material.uniforms;
|
||||
for (let d = 0, dl = variable.dependencies.length; d < dl; d++) {
|
||||
const depVar = variable.dependencies[d];
|
||||
uniforms[depVar.name].value = depVar.renderTargets[currentTextureIndex].texture;
|
||||
}
|
||||
}
|
||||
this.doRenderTarget(variable.material, variable.renderTargets[nextTextureIndex]);
|
||||
}
|
||||
this.currentTextureIndex = nextTextureIndex;
|
||||
};
|
||||
this.getCurrentRenderTarget = function(variable) {
|
||||
return variable.renderTargets[this.currentTextureIndex];
|
||||
};
|
||||
this.getAlternateRenderTarget = function(variable) {
|
||||
return variable.renderTargets[this.currentTextureIndex === 0 ? 1 : 0];
|
||||
};
|
||||
this.dispose = function() {
|
||||
mesh.geometry.dispose();
|
||||
mesh.material.dispose();
|
||||
const variables = this.variables;
|
||||
for (let i = 0; i < variables.length; i++) {
|
||||
const variable = variables[i];
|
||||
if (variable.initialValueTexture)
|
||||
variable.initialValueTexture.dispose();
|
||||
const renderTargets = variable.renderTargets;
|
||||
for (let j = 0; j < renderTargets.length; j++) {
|
||||
const renderTarget = renderTargets[j];
|
||||
renderTarget.dispose();
|
||||
}
|
||||
}
|
||||
};
|
||||
function addResolutionDefine(materialShader) {
|
||||
materialShader.defines.resolution = "vec2( " + sizeX.toFixed(1) + ", " + sizeY.toFixed(1) + " )";
|
||||
}
|
||||
this.addResolutionDefine = addResolutionDefine;
|
||||
function createShaderMaterial(computeFragmentShader, uniforms) {
|
||||
uniforms = uniforms || {};
|
||||
const material = new ShaderMaterial({
|
||||
uniforms,
|
||||
vertexShader: getPassThroughVertexShader(),
|
||||
fragmentShader: computeFragmentShader
|
||||
});
|
||||
addResolutionDefine(material);
|
||||
return material;
|
||||
}
|
||||
this.createShaderMaterial = createShaderMaterial;
|
||||
this.createRenderTarget = function(sizeXTexture, sizeYTexture, wrapS, wrapT, minFilter, magFilter) {
|
||||
sizeXTexture = sizeXTexture || sizeX;
|
||||
sizeYTexture = sizeYTexture || sizeY;
|
||||
wrapS = wrapS || ClampToEdgeWrapping;
|
||||
wrapT = wrapT || ClampToEdgeWrapping;
|
||||
minFilter = minFilter || NearestFilter;
|
||||
magFilter = magFilter || NearestFilter;
|
||||
const renderTarget = new WebGLRenderTarget(sizeXTexture, sizeYTexture, {
|
||||
wrapS,
|
||||
wrapT,
|
||||
minFilter,
|
||||
magFilter,
|
||||
format: RGBAFormat,
|
||||
type: dataType,
|
||||
depthBuffer: false
|
||||
});
|
||||
return renderTarget;
|
||||
};
|
||||
this.createTexture = function() {
|
||||
const data = new Float32Array(sizeX * sizeY * 4);
|
||||
const texture = new DataTexture(data, sizeX, sizeY, RGBAFormat, FloatType);
|
||||
texture.needsUpdate = true;
|
||||
return texture;
|
||||
};
|
||||
this.renderTexture = function(input, output) {
|
||||
passThruUniforms.passThruTexture.value = input;
|
||||
this.doRenderTarget(passThruShader, output);
|
||||
passThruUniforms.passThruTexture.value = null;
|
||||
};
|
||||
this.doRenderTarget = function(material, output) {
|
||||
const currentRenderTarget = renderer.getRenderTarget();
|
||||
const currentXrEnabled = renderer.xr.enabled;
|
||||
const currentShadowAutoUpdate = renderer.shadowMap.autoUpdate;
|
||||
const currentOutputColorSpace = renderer.outputColorSpace;
|
||||
const currentToneMapping = renderer.toneMapping;
|
||||
renderer.xr.enabled = false;
|
||||
renderer.shadowMap.autoUpdate = false;
|
||||
if ("outputColorSpace" in renderer)
|
||||
renderer.outputColorSpace = "srgb-linear";
|
||||
else
|
||||
renderer.encoding = 3e3;
|
||||
renderer.toneMapping = NoToneMapping;
|
||||
mesh.material = material;
|
||||
renderer.setRenderTarget(output);
|
||||
renderer.render(scene, camera);
|
||||
mesh.material = passThruShader;
|
||||
renderer.xr.enabled = currentXrEnabled;
|
||||
renderer.shadowMap.autoUpdate = currentShadowAutoUpdate;
|
||||
renderer.outputColorSpace = currentOutputColorSpace;
|
||||
renderer.toneMapping = currentToneMapping;
|
||||
renderer.setRenderTarget(currentRenderTarget);
|
||||
};
|
||||
function getPassThroughVertexShader() {
|
||||
return "void main() {\n\n gl_Position = vec4( position, 1.0 );\n\n}\n";
|
||||
}
|
||||
function getPassThroughFragmentShader() {
|
||||
return "uniform sampler2D passThruTexture;\n\nvoid main() {\n\n vec2 uv = gl_FragCoord.xy / resolution.xy;\n\n gl_FragColor = texture2D( passThruTexture, uv );\n\n}\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
export {
|
||||
GPUComputationRenderer
|
||||
};
|
||||
//# sourceMappingURL=GPUComputationRenderer.js.map
|
||||
Reference in New Issue
Block a user