UNPKG

three-stdlib

Version:

stand-alone library of threejs examples

1 lines 10.1 kB
{"version":3,"file":"RenderPixelatedPass.cjs","sources":["../../src/postprocessing/RenderPixelatedPass.js"],"sourcesContent":["import {\n WebGLRenderTarget,\n RGBAFormat,\n MeshNormalMaterial,\n ShaderMaterial,\n Vector2,\n Vector4,\n DepthTexture,\n NearestFilter,\n} from 'three'\nimport { Pass, FullScreenQuad } from './Pass'\n\nclass RenderPixelatedPass extends Pass {\n constructor(resolution, pixelSize, scene, camera, options = {}) {\n super()\n\n this.pixelSize = pixelSize\n this.resolution = new Vector2()\n this.renderResolution = new Vector2()\n this.setSize(resolution.x, resolution.y)\n\n this.fsQuad = new FullScreenQuad(this.material())\n this.scene = scene\n this.camera = camera\n\n this.normalEdgeStrength = options.normalEdgeStrength ?? 0.3\n this.depthEdgeStrength = options.depthEdgeStrength ?? 0.4\n\n this.rgbRenderTarget = pixelRenderTarget(this.renderResolution, RGBAFormat, true)\n this.normalRenderTarget = pixelRenderTarget(this.renderResolution, RGBAFormat, false)\n\n this.normalMaterial = new MeshNormalMaterial()\n }\n\n dispose() {\n this.rgbRenderTarget.dispose()\n this.normalRenderTarget.dispose()\n this.fsQuad.dispose()\n }\n\n setSize(width, height) {\n this.resolution.set(width, height)\n this.renderResolution.set((width / this.pixelSize) | 0, (height / this.pixelSize) | 0)\n const { x, y } = this.renderResolution\n this.rgbRenderTarget?.setSize(x, y)\n this.normalRenderTarget?.setSize(x, y)\n this.fsQuad?.material.uniforms.resolution.value.set(x, y, 1 / x, 1 / y)\n }\n\n setPixelSize(pixelSize) {\n this.pixelSize = pixelSize\n this.setSize(this.resolution.x, this.resolution.y)\n }\n\n render(renderer, writeBuffer) {\n const uniforms = this.fsQuad.material.uniforms\n uniforms.normalEdgeStrength.value = this.normalEdgeStrength\n uniforms.depthEdgeStrength.value = this.depthEdgeStrength\n\n renderer.setRenderTarget(this.rgbRenderTarget)\n renderer.render(this.scene, this.camera)\n\n const overrideMaterial_old = this.scene.overrideMaterial\n renderer.setRenderTarget(this.normalRenderTarget)\n this.scene.overrideMaterial = this.normalMaterial\n renderer.render(this.scene, this.camera)\n this.scene.overrideMaterial = overrideMaterial_old\n\n uniforms.tDiffuse.value = this.rgbRenderTarget.texture\n uniforms.tDepth.value = this.rgbRenderTarget.depthTexture\n uniforms.tNormal.value = this.normalRenderTarget.texture\n\n if (this.renderToScreen) {\n renderer.setRenderTarget(null)\n } else {\n renderer.setRenderTarget(writeBuffer)\n\n if (this.clear) renderer.clear()\n }\n\n this.fsQuad.render(renderer)\n }\n\n material() {\n return new ShaderMaterial({\n uniforms: {\n tDiffuse: { value: null },\n tDepth: { value: null },\n tNormal: { value: null },\n resolution: {\n value: new Vector4(\n this.renderResolution.x,\n this.renderResolution.y,\n 1 / this.renderResolution.x,\n 1 / this.renderResolution.y,\n ),\n },\n normalEdgeStrength: { value: 0 },\n depthEdgeStrength: { value: 0 },\n },\n vertexShader: `\n\t\t\t\tvarying vec2 vUv;\n\n\t\t\t\tvoid main() {\n\n\t\t\t\t\tvUv = uv;\n\t\t\t\t\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\n\t\t\t\t}\n\t\t\t\t`,\n fragmentShader: `\n\t\t\t\tuniform sampler2D tDiffuse;\n\t\t\t\tuniform sampler2D tDepth;\n\t\t\t\tuniform sampler2D tNormal;\n\t\t\t\tuniform vec4 resolution;\n\t\t\t\tuniform float normalEdgeStrength;\n\t\t\t\tuniform float depthEdgeStrength;\n\t\t\t\tvarying vec2 vUv;\n\n\t\t\t\tfloat getDepth(int x, int y) {\n\n\t\t\t\t\treturn texture2D( tDepth, vUv + vec2(x, y) * resolution.zw ).r;\n\n\t\t\t\t}\n\n\t\t\t\tvec3 getNormal(int x, int y) {\n\n\t\t\t\t\treturn texture2D( tNormal, vUv + vec2(x, y) * resolution.zw ).rgb * 2.0 - 1.0;\n\n\t\t\t\t}\n\n\t\t\t\tfloat depthEdgeIndicator(float depth, vec3 normal) {\n\n\t\t\t\t\tfloat diff = 0.0;\n\t\t\t\t\tdiff += clamp(getDepth(1, 0) - depth, 0.0, 1.0);\n\t\t\t\t\tdiff += clamp(getDepth(-1, 0) - depth, 0.0, 1.0);\n\t\t\t\t\tdiff += clamp(getDepth(0, 1) - depth, 0.0, 1.0);\n\t\t\t\t\tdiff += clamp(getDepth(0, -1) - depth, 0.0, 1.0);\n\t\t\t\t\treturn floor(smoothstep(0.01, 0.02, diff) * 2.) / 2.;\n\n\t\t\t\t}\n\n\t\t\t\tfloat neighborNormalEdgeIndicator(int x, int y, float depth, vec3 normal) {\n\n\t\t\t\t\tfloat depthDiff = getDepth(x, y) - depth;\n\t\t\t\t\tvec3 neighborNormal = getNormal(x, y);\n\t\t\t\t\t\n\t\t\t\t\t// Edge pixels should yield to faces who's normals are closer to the bias normal.\n\t\t\t\t\tvec3 normalEdgeBias = vec3(1., 1., 1.); // This should probably be a parameter.\n\t\t\t\t\tfloat normalDiff = dot(normal - neighborNormal, normalEdgeBias);\n\t\t\t\t\tfloat normalIndicator = clamp(smoothstep(-.01, .01, normalDiff), 0.0, 1.0);\n\t\t\t\t\t\n\t\t\t\t\t// Only the shallower pixel should detect the normal edge.\n\t\t\t\t\tfloat depthIndicator = clamp(sign(depthDiff * .25 + .0025), 0.0, 1.0);\n\n\t\t\t\t\treturn (1.0 - dot(normal, neighborNormal)) * depthIndicator * normalIndicator;\n\n\t\t\t\t}\n\n\t\t\t\tfloat normalEdgeIndicator(float depth, vec3 normal) {\n\t\t\t\t\t\n\t\t\t\t\tfloat indicator = 0.0;\n\n\t\t\t\t\tindicator += neighborNormalEdgeIndicator(0, -1, depth, normal);\n\t\t\t\t\tindicator += neighborNormalEdgeIndicator(0, 1, depth, normal);\n\t\t\t\t\tindicator += neighborNormalEdgeIndicator(-1, 0, depth, normal);\n\t\t\t\t\tindicator += neighborNormalEdgeIndicator(1, 0, depth, normal);\n\n\t\t\t\t\treturn step(0.1, indicator);\n\n\t\t\t\t}\n\n\t\t\t\tvoid main() {\n\n\t\t\t\t\tvec4 texel = texture2D( tDiffuse, vUv );\n\n\t\t\t\t\tfloat depth = 0.0;\n\t\t\t\t\tvec3 normal = vec3(0.0);\n\n\t\t\t\t\tif (depthEdgeStrength > 0.0 || normalEdgeStrength > 0.0) {\n\n\t\t\t\t\t\tdepth = getDepth(0, 0);\n\t\t\t\t\t\tnormal = getNormal(0, 0);\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfloat dei = 0.0;\n\t\t\t\t\tif (depthEdgeStrength > 0.0) \n\t\t\t\t\t\tdei = depthEdgeIndicator(depth, normal);\n\n\t\t\t\t\tfloat nei = 0.0; \n\t\t\t\t\tif (normalEdgeStrength > 0.0) \n\t\t\t\t\t\tnei = normalEdgeIndicator(depth, normal);\n\n\t\t\t\t\tfloat Strength = dei > 0.0 ? (1.0 - depthEdgeStrength * dei) : (1.0 + normalEdgeStrength * nei);\n\n\t\t\t\t\tgl_FragColor = texel * Strength;\n\n\t\t\t\t}\n\t\t\t\t`,\n })\n }\n}\n\nfunction pixelRenderTarget(resolution, pixelFormat, useDepthTexture) {\n const renderTarget = new WebGLRenderTarget(\n resolution.x,\n resolution.y,\n !useDepthTexture\n ? undefined\n : {\n depthTexture: new DepthTexture(resolution.x, resolution.y),\n depthBuffer: true,\n },\n )\n renderTarget.texture.format = pixelFormat\n renderTarget.texture.minFilter = NearestFilter\n renderTarget.texture.magFilter = NearestFilter\n renderTarget.texture.generateMipmaps = false\n renderTarget.stencilBuffer = false\n return renderTarget\n}\n\nexport { RenderPixelatedPass }\n"],"names":["Pass","Vector2","FullScreenQuad","RGBAFormat","MeshNormalMaterial","ShaderMaterial","Vector4","WebGLRenderTarget","DepthTexture","NearestFilter"],"mappings":"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"}