Ver código fonte

Normal buffer plugin copy material properties, Some refactor in shader and screen pass, other minor changes

master
Palash Bansal 3 anos atrás
pai
commit
84ee8a6255
Nenhuma conta vinculada ao e-mail do autor do commit

+ 50
- 1
src/plugins/pipeline/NormalBufferPlugin.ts Ver arquivo

import { import {
BufferGeometry,
Camera,
Color, Color,
FrontSide,
HalfFloatType, HalfFloatType,
IUniform, IUniform,
LinearSRGBColorSpace, LinearSRGBColorSpace,
MeshNormalMaterial, MeshNormalMaterial,
NearestFilter, NearestFilter,
NoBlending, NoBlending,
Object3D,
Scene,
TangentSpaceNormalMap,
Texture, Texture,
TextureDataType, TextureDataType,
WebGLRenderer,
WebGLRenderTarget, WebGLRenderTarget,
} from 'three' } from 'three'
import {GBufferRenderPass} from '../../postprocessing' import {GBufferRenderPass} from '../../postprocessing'
import {ThreeViewer} from '../../viewer' import {ThreeViewer} from '../../viewer'
import {IShaderPropertiesUpdater} from '../../materials' import {IShaderPropertiesUpdater} from '../../materials'
import {PipelinePassPlugin} from '../base/PipelinePassPlugin' import {PipelinePassPlugin} from '../base/PipelinePassPlugin'
import type {IMaterial, PhysicalMaterial} from '../../core'


export type NormalBufferPluginEventTypes = '' export type NormalBufferPluginEventTypes = ''
// type NormalBufferPluginTarget = WebGLMultipleRenderTargets | WebGLRenderTarget // type NormalBufferPluginTarget = WebGLMultipleRenderTargets | WebGLRenderTarget


target?: NormalBufferPluginTarget target?: NormalBufferPluginTarget
texture?: Texture texture?: Texture
readonly material: MeshNormalMaterial = new MeshNormalMaterial({
readonly material: MeshNormalMaterial = new MeshNormalMaterial2({
blending: NoBlending, blending: NoBlending,
}) })
// private _gbufferPass?: IFilter<GBufferRenderPass<WebGLMultipleRenderTargets> // private _gbufferPass?: IFilter<GBufferRenderPass<WebGLMultipleRenderTargets>


} }


class MeshNormalMaterial2 extends MeshNormalMaterial {
onBeforeRender(renderer: WebGLRenderer, scene: Scene, camera: Camera, geometry: BufferGeometry, object: Object3D) {
super.onBeforeRender(renderer, scene, camera, geometry, object)

if (!(object as any).material) return
const material = (object as any).material as IMaterial & Partial<PhysicalMaterial>

if (material.bumpMap !== undefined) this.bumpMap = material.bumpMap
if (material.bumpScale !== undefined) this.bumpScale = material.bumpScale

if (material.normalMap !== undefined) this.normalMap = material.normalMap
if (material.normalMapType !== undefined) this.normalMapType = material.normalMapType
if (material.normalScale !== undefined) this.normalScale.copy(material.normalScale)

if (material.displacementMap !== undefined) this.displacementMap = material.displacementMap
if (material.displacementScale !== undefined) this.displacementScale = material.displacementScale
if (material.displacementBias !== undefined) this.displacementBias = material.displacementBias

if (material.flatShading !== undefined) this.flatShading = material.flatShading

if (material.side !== undefined) this.side = material.side
}

onAfterRender(renderer: WebGLRenderer, scene: Scene, camera: Camera, geometry: BufferGeometry, object: Object3D) {
super.onAfterRender(renderer, scene, camera, geometry, object)

this.bumpMap = null
this.bumpScale = 1

this.normalMap = null
this.normalMapType = TangentSpaceNormalMap

this.displacementMap = null
this.displacementScale = 1
this.displacementBias = 0

this.flatShading = false

this.side = FrontSide
}
}

+ 5
- 6
src/postprocessing/ExtendedCopyPass.ts Ver arquivo

vertexShader: CopyShader.vertexShader, vertexShader: CopyShader.vertexShader,
fragmentShader: glsl` fragmentShader: glsl`
uniform float opacity; uniform float opacity;
uniform float alphaTest;
#include <alphatest_pars_fragment>
varying vec2 vUv; varying vec2 vUv;
void main() { void main() {
gl_FragColor = tDiffuseTexelToLinear(texture2D(tDiffuse, vUv)) * opacity;
#ifdef USE_ALPHATEST
if ( gl_FragColor.a < alphaTest ) discard;
#endif
vec4 diffuseColor = tDiffuseTexelToLinear(texture2D(tDiffuse, vUv)) * opacity;
#include <alphatest_fragment>
#ifdef OPAQUE #ifdef OPAQUE
gl_FragColor.a = 1.0;
diffuseColor.a = 1.0;
#endif #endif
gl_FragColor = diffuseColor;
#include <encodings_fragment> #include <encodings_fragment>
} }
`, `,

+ 3
- 3
src/postprocessing/ExtendedShaderPass.ts Ver arquivo

import {IPass} from './Pass' import {IPass} from './Pass'
import {ShaderPass} from 'three/examples/jsm/postprocessing/ShaderPass.js' import {ShaderPass} from 'three/examples/jsm/postprocessing/ShaderPass.js'
import {ExtendedShaderMaterial, IWebGLRenderer, ShaderMaterial2} from '../core' import {ExtendedShaderMaterial, IWebGLRenderer, ShaderMaterial2} from '../core'
import {Shader, WebGLMultipleRenderTargets, WebGLRenderTarget} from 'three'
import {Shader, ShaderMaterialParameters, WebGLMultipleRenderTargets, WebGLRenderTarget} from 'three'
import {uiToggle} from 'uiconfig.js' import {uiToggle} from 'uiconfig.js'
import {serialize} from 'ts-browser-helpers' import {serialize} from 'ts-browser-helpers'
import {IShaderPropertiesUpdater} from '../materials' import {IShaderPropertiesUpdater} from '../materials'


@uiToggle('Enabled') @serialize() enabled = true @uiToggle('Enabled') @serialize() enabled = true


constructor(shader: Shader|ShaderMaterial2, ...textureID: string[]) {
constructor(shader: ShaderMaterial2|ShaderMaterialParameters, ...textureID: string[]) {
super( super(
(<ShaderMaterial2>shader).isMaterial ? <ShaderMaterial2>shader : new ExtendedShaderMaterial(<Shader>shader, textureID),
(<ShaderMaterial2>shader).isMaterial ? <ShaderMaterial2>shader : new ExtendedShaderMaterial(<ShaderMaterialParameters>shader, textureID),
textureID.length < 1 ? ExtendedShaderPass.DEFAULT_TEX_ID : textureID[0]) textureID.length < 1 ? ExtendedShaderPass.DEFAULT_TEX_ID : textureID[0])
this.setDirty = this.setDirty.bind(this) this.setDirty = this.setDirty.bind(this)
} }

+ 1
- 2
src/postprocessing/GenericBlendTexturePass.ts Ver arquivo

import {CopyShader} from 'three/examples/jsm/shaders/CopyShader.js' import {CopyShader} from 'three/examples/jsm/shaders/CopyShader.js'
import {ExtendedShaderPass} from './ExtendedShaderPass' import {ExtendedShaderPass} from './ExtendedShaderPass'
import {IPass} from './Pass' import {IPass} from './Pass'
import {glsl} from 'ts-browser-helpers'


export class GenericBlendTexturePass extends ExtendedShaderPass implements IPass { export class GenericBlendTexturePass extends ExtendedShaderPass implements IPass {
constructor(uniforms: {[uniform: string]: IUniform}, blendFunc = 'c = a + b;', extraFrag = '', texture?: Texture) { constructor(uniforms: {[uniform: string]: IUniform}, blendFunc = 'c = a + b;', extraFrag = '', texture?: Texture) {
super({ super({
vertexShader: CopyShader.vertexShader, vertexShader: CopyShader.vertexShader,
fragmentShader: glsl`
fragmentShader: `
varying vec2 vUv; varying vec2 vUv;
${extraFrag} ${extraFrag}
void blend(in vec4 a, in vec4 b, inout vec4 c){ void blend(in vec4 a, in vec4 b, inout vec4 c){

+ 38
- 8
src/postprocessing/ScreenPass.ts Ver arquivo

import {ExtendedShaderPass} from './ExtendedShaderPass' import {ExtendedShaderPass} from './ExtendedShaderPass'
import {ColorSpace, Shader, SRGBColorSpace, WebGLMultipleRenderTargets, WebGLRenderTarget} from 'three'
import {
ColorSpace,
FrontSide,
NoBlending,
ShaderMaterialParameters,
SRGBColorSpace,
WebGLMultipleRenderTargets,
WebGLRenderTarget,
} from 'three'
import {IWebGLRenderer, ShaderMaterial2} from '../core' import {IWebGLRenderer, ShaderMaterial2} from '../core'
import {CopyShader} from 'three/examples/jsm/shaders/CopyShader.js' import {CopyShader} from 'three/examples/jsm/shaders/CopyShader.js'
import {IPassID, IPipelinePass} from './Pass' import {IPassID, IPipelinePass} from './Pass'
import {uiFolderContainer} from 'uiconfig.js' import {uiFolderContainer} from 'uiconfig.js'


export type TViewerScreenShaderFrag = string | [string, string] | {pars?: string, main: string} export type TViewerScreenShaderFrag = string | [string, string] | {pars?: string, main: string}
export type TViewerScreenShader = TViewerScreenShaderFrag | Shader | ShaderMaterial2
export type TViewerScreenShader = TViewerScreenShaderFrag | ShaderMaterialParameters | ShaderMaterial2


@uiFolderContainer('Screen Pass') @uiFolderContainer('Screen Pass')
export class ScreenPass extends ExtendedShaderPass implements IPipelinePass<'screen'> { export class ScreenPass extends ExtendedShaderPass implements IPipelinePass<'screen'> {


constructor(shader: TViewerScreenShader, ...textureID: string[]) { constructor(shader: TViewerScreenShader, ...textureID: string[]) {
super( super(
(<any>shader)?.fragmentShader || (<ShaderMaterial2>shader)?.isShaderMaterial ? <Shader|ShaderMaterial2>shader :
(<any>shader)?.fragmentShader || (<ShaderMaterial2>shader)?.isShaderMaterial ? <ShaderMaterialParameters|ShaderMaterial2>shader :
makeScreenShader(shader), makeScreenShader(shader),
...textureID.length ? textureID : ['tDiffuse']) ...textureID.length ? textureID : ['tDiffuse'])
} }


outputColorSpace: ColorSpace = SRGBColorSpace outputColorSpace: ColorSpace = SRGBColorSpace


private _lastReadBuffer?: WebGLMultipleRenderTargets | WebGLRenderTarget

render(renderer: IWebGLRenderer, writeBuffer?: WebGLMultipleRenderTargets | WebGLRenderTarget | null, readBuffer?: WebGLMultipleRenderTargets | WebGLRenderTarget, deltaTime?: number, maskActive?: boolean) { render(renderer: IWebGLRenderer, writeBuffer?: WebGLMultipleRenderTargets | WebGLRenderTarget | null, readBuffer?: WebGLMultipleRenderTargets | WebGLRenderTarget, deltaTime?: number, maskActive?: boolean) {
const colorSpace = renderer.outputColorSpace const colorSpace = renderer.outputColorSpace
if (!writeBuffer || this.renderToScreen) renderer.outputColorSpace = this.outputColorSpace if (!writeBuffer || this.renderToScreen) renderer.outputColorSpace = this.outputColorSpace
else console.warn('ScreenPass: outputColorSpace is ignored when renderToScreen is false') else console.warn('ScreenPass: outputColorSpace is ignored when renderToScreen is false')
super.render(renderer, writeBuffer, readBuffer, deltaTime, maskActive) super.render(renderer, writeBuffer, readBuffer, deltaTime, maskActive)
this._lastReadBuffer = readBuffer
renderer.outputColorSpace = colorSpace renderer.outputColorSpace = colorSpace
} }

reRender(renderer: IWebGLRenderer, writeBuffer?: WebGLMultipleRenderTargets | WebGLRenderTarget | null, deltaTime?: number, maskActive?: boolean) {
if (this._lastReadBuffer) this.render(renderer, writeBuffer, this._lastReadBuffer, deltaTime, maskActive)
}

dispose() {
this._lastReadBuffer = undefined
super.dispose()
}
} }


function makeScreenShader(shader: string | [string, string] | {pars?: string; main: string} | Shader | ShaderMaterial2) {
function makeScreenShader(shader: string | [string, string] | {pars?: string; main: string} | ShaderMaterialParameters | ShaderMaterial2) {
return { return {
...CopyShader, ...CopyShader,
fragmentShader: ` fragmentShader: `
varying vec2 vUv; varying vec2 vUv;


#include <alphatest_pars_fragment>
${Array.isArray(shader) ? shader[0] : (<any>shader)?.pars || ''} ${Array.isArray(shader) ? shader[0] : (<any>shader)?.pars || ''}


void main() { void main() {


gl_FragColor = tDiffuseTexelToLinear (texture2D(tDiffuse, vUv));
vec4 diffuseColor = tDiffuseTexelToLinear (texture2D(tDiffuse, vUv));
${Array.isArray(shader) ? shader[1] : typeof shader === 'string' ? shader : (shader as any)?.main || ''}
#glMarker
${Array.isArray(shader) ? shader[1] : typeof shader === 'string' ? shader : (shader as any)?.main || ''}
#include <alphatest_fragment>
#ifdef OPAQUE
diffuseColor.a = 1.0;
#endif
gl_FragColor = diffuseColor;
#include <encodings_fragment> #include <encodings_fragment>
}`, }`,
uniforms: { uniforms: {
tDiffuse: {value: null}, tDiffuse: {value: null},
}, },
}
transparent: true,
blending: NoBlending,
side: FrontSide,
} as ShaderMaterialParameters
} }


+ 1
- 1
src/rendering/RenderManager.ts Ver arquivo

{r?: number, g?: number, b?: number, a?: number, target?: IRenderTarget, depth?: boolean, stencil?: boolean, viewport?: Vector4}): void { {r?: number, g?: number, b?: number, a?: number, target?: IRenderTarget, depth?: boolean, stencil?: boolean, viewport?: Vector4}): void {
const color = this._renderer.getClearColor(new Color()) const color = this._renderer.getClearColor(new Color())
const alpha = this._renderer.getClearAlpha() const alpha = this._renderer.getClearAlpha()
this._renderer.setClearAlpha(a ?? alpha)
this._renderer.setClearColor(new Color(r ?? color.r, g ?? color.g, b ?? color.b)) this._renderer.setClearColor(new Color(r ?? color.r, g ?? color.g, b ?? color.b))
this._renderer.setClearAlpha(a ?? alpha)
const lastTarget = this._renderer.getRenderTarget() const lastTarget = this._renderer.getRenderTarget()
const activeCubeFace = this._renderer.getActiveCubeFace() const activeCubeFace = this._renderer.getActiveCubeFace()
const activeMipLevel = this._renderer.getActiveMipmapLevel() const activeMipLevel = this._renderer.getActiveMipmapLevel()

+ 1
- 1
src/viewer/ViewerRenderManager.ts Ver arquivo

this._renderer.userData.renderTransmissionPass = !doTransmissionFix // hack. used in WebGLRenderer.js this._renderer.userData.renderTransmissionPass = !doTransmissionFix // hack. used in WebGLRenderer.js


this.renderPass = new ExtendedRenderPass(this) this.renderPass = new ExtendedRenderPass(this)
this.screenPass = new ScreenPass(options.screenShader || '') // todo gamma correction by default?
this.screenPass = new ScreenPass(options.screenShader || '')
this.registerPass(this.renderPass) this.registerPass(this.renderPass)
this.registerPass(this.screenPass) this.registerPass(this.screenPass)
} }

Carregando…
Cancelar
Salvar