UNPKG

cione-comp-lib

Version:

`$ yarn add cione-comp-lib` 或者 `$ npm i cione-comp-lib -S`

158 lines (157 loc) 6.54 kB
import Texture2D from "../../../claygl/src/Texture2D.mjs"; import Texture from "../../../claygl/src/Texture.mjs"; import Shader from "../../../claygl/src/Shader.mjs"; import FrameBuffer from "../../../claygl/src/FrameBuffer.mjs"; import Material from "../../../claygl/src/Material.mjs"; import Pass from "../../../claygl/src/compositor/Pass.mjs"; import textureUtil from "../../../claygl/src/util/texture.mjs"; import normalGLSL from "../util/shader/normal.glsl.mjs"; Shader.import(normalGLSL); function attachTextureToSlot(renderer, program, symbol, texture, slot) { var gl = renderer.gl; program.setUniform(gl, "1i", symbol, slot); gl.activeTexture(gl.TEXTURE0 + slot); if (texture.isRenderable()) { texture.bind(renderer); } else { texture.unbind(renderer); } } function getBeforeRenderHook(renderer, defaultNormalMap, defaultBumpMap, defaultRoughnessMap, normalMaterial) { var previousNormalMap; var previousBumpMap; var previousRoughnessMap; var previousRenderable; var gl = renderer.gl; return function(renderable, normalMaterial2, prevNormalMaterial) { if (previousRenderable && previousRenderable.material === renderable.material) { return; } var material = renderable.material; var program = renderable.__program; var roughness = material.get("roughness"); if (roughness == null) { roughness = 1; } var normalMap = material.get("normalMap") || defaultNormalMap; var roughnessMap = material.get("roughnessMap"); var bumpMap = material.get("bumpMap"); var uvRepeat = material.get("uvRepeat"); var uvOffset = material.get("uvOffset"); var detailUvRepeat = material.get("detailUvRepeat"); var detailUvOffset = material.get("detailUvOffset"); var useBumpMap = !!bumpMap && material.isTextureEnabled("bumpMap"); var useRoughnessMap = !!roughnessMap && material.isTextureEnabled("roughnessMap"); var doubleSide = material.isDefined("fragment", "DOUBLE_SIDED"); bumpMap = bumpMap || defaultBumpMap; roughnessMap = roughnessMap || defaultRoughnessMap; if (prevNormalMaterial !== normalMaterial2) { normalMaterial2.set("normalMap", normalMap); normalMaterial2.set("bumpMap", bumpMap); normalMaterial2.set("roughnessMap", roughnessMap); normalMaterial2.set("useBumpMap", useBumpMap); normalMaterial2.set("useRoughnessMap", useRoughnessMap); normalMaterial2.set("doubleSide", doubleSide); uvRepeat != null && normalMaterial2.set("uvRepeat", uvRepeat); uvOffset != null && normalMaterial2.set("uvOffset", uvOffset); detailUvRepeat != null && normalMaterial2.set("detailUvRepeat", detailUvRepeat); detailUvOffset != null && normalMaterial2.set("detailUvOffset", detailUvOffset); normalMaterial2.set("roughness", roughness); } else { program.setUniform(gl, "1f", "roughness", roughness); if (previousNormalMap !== normalMap) { attachTextureToSlot(renderer, program, "normalMap", normalMap, 0); } if (previousBumpMap !== bumpMap && bumpMap) { attachTextureToSlot(renderer, program, "bumpMap", bumpMap, 1); } if (previousRoughnessMap !== roughnessMap && roughnessMap) { attachTextureToSlot(renderer, program, "roughnessMap", roughnessMap, 2); } if (uvRepeat != null) { program.setUniform(gl, "2f", "uvRepeat", uvRepeat); } if (uvOffset != null) { program.setUniform(gl, "2f", "uvOffset", uvOffset); } if (detailUvRepeat != null) { program.setUniform(gl, "2f", "detailUvRepeat", detailUvRepeat); } if (detailUvOffset != null) { program.setUniform(gl, "2f", "detailUvOffset", detailUvOffset); } program.setUniform(gl, "1i", "useBumpMap", +useBumpMap); program.setUniform(gl, "1i", "useRoughnessMap", +useRoughnessMap); program.setUniform(gl, "1i", "doubleSide", +doubleSide); } previousNormalMap = normalMap; previousBumpMap = bumpMap; previousRoughnessMap = roughnessMap; previousRenderable = renderable; }; } function NormalPass(opt) { this._depthTex = new Texture2D({ format: Texture.DEPTH_COMPONENT, type: Texture.UNSIGNED_INT }); this._normalTex = new Texture2D({ type: Texture.HALF_FLOAT }); this._framebuffer = new FrameBuffer(); this._framebuffer.attach(this._normalTex); this._framebuffer.attach(this._depthTex, FrameBuffer.DEPTH_ATTACHMENT); this._normalMaterial = new Material({ shader: new Shader(Shader.source("ecgl.normal.vertex"), Shader.source("ecgl.normal.fragment")) }); this._normalMaterial.enableTexture(["normalMap", "bumpMap", "roughnessMap"]); this._defaultNormalMap = textureUtil.createBlank("#000"); this._defaultBumpMap = textureUtil.createBlank("#000"); this._defaultRoughessMap = textureUtil.createBlank("#000"); this._debugPass = new Pass({ fragment: Shader.source("clay.compositor.output") }); this._debugPass.setUniform("texture", this._normalTex); this._debugPass.material.undefine("fragment", "OUTPUT_ALPHA"); } NormalPass.prototype.getDepthTexture = function() { return this._depthTex; }; NormalPass.prototype.getNormalTexture = function() { return this._normalTex; }; NormalPass.prototype.update = function(renderer, scene, camera) { var width = renderer.getWidth(); var height = renderer.getHeight(); var depthTexture = this._depthTex; var normalTexture = this._normalTex; var normalMaterial = this._normalMaterial; depthTexture.width = width; depthTexture.height = height; normalTexture.width = width; normalTexture.height = height; var opaqueList = scene.getRenderList(camera).opaque; this._framebuffer.bind(renderer); renderer.gl.clearColor(0, 0, 0, 0); renderer.gl.clear(renderer.gl.COLOR_BUFFER_BIT | renderer.gl.DEPTH_BUFFER_BIT); renderer.gl.disable(renderer.gl.BLEND); renderer.renderPass(opaqueList, camera, { getMaterial: function() { return normalMaterial; }, ifRender: function(object) { return object.renderNormal; }, beforeRender: getBeforeRenderHook(renderer, this._defaultNormalMap, this._defaultBumpMap, this._defaultRoughessMap, this._normalMaterial), sort: renderer.opaqueSortCompare }); this._framebuffer.unbind(renderer); }; NormalPass.prototype.renderDebug = function(renderer) { this._debugPass.render(renderer); }; NormalPass.prototype.dispose = function(renderer) { this._depthTex.dispose(renderer); this._normalTex.dispose(renderer); }; export { NormalPass as default };