我有一个关于渲染层的问题。我现在有了一个大型应用程序。这就是为什么我试图在这里解释我的主要问题,只用代码中我遇到困难的部分来解释。这里的特别之处在于,我使用不同的摄像机来进行深度纹理的后处理,与纹理相机的位置和其他值完全相同。由于精度原因,我只在近距离内使用浮动值。一切都很好。
我的问题是,我的后处理影响了现场的一切,当然,它看起来很糟糕。我的后处理应该只影响场景中的某些对象。我的问题是所有的物体都是场景的一部分。几乎每个对象都可以生成或消失(在其他模块中触发以保持代码干净)。一切都很好。我只是不知道如何将后处理效果限制(封装)到我选择的对象。作为一个非常简单的例子,您将如何在这里添加一个框或所有其他对象,这样它们就不会受到后置处理的影响。
import {THREE, OrbitControls, RenderPass, ShaderPass, EffectComposer, CopyShader, FXAAShader} from './three-defs.js';
import {entity} from "./entity.js";
const vertexShad = `
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`;
const fragmentShad = `
varying vec2 vUv;
uniform sampler2D tDiffuse;
void main() {
vec3 color = texture2D(tDiffuse, vUv).rgb;
gl_FragColor = vec4(color, 1.);
}
`;
export const threejs_component = (() => {
class ThreeJSController extends entity.Component {
constructor() {
super();
}
InitEntity() {
this.threejs_ = new THREE.WebGLRenderer({antialias: true, logarithmicDepthBuffer: true});
this.threejs_.outputEncoding = THREE.sRGBEncoding;
this.threejs_.setPixelRatio(window.devicePixelRatio);
this.threejs_.shadowMap.enabled = true;
this.threejs_.shadowMap.type = THREE.PCFSoftShadowMap;
this.threejs_.domElement.id = 'threejs';
this.container = document.getElementById('container');
this.threejs_.setSize(this.container.clientWidth, this.container.clientHeight);
this.container.appendChild( this.threejs_.domElement );
const aspect = this.container.clientWidth / this.container.clientHeight;
const fov = 60;
const near = 1e-6;
const far = 1E27;
this.camera_ = new THREE.PerspectiveCamera(fov, aspect, near, far);
this.scene_ = new THREE.Scene();
this.scene_.background = new THREE.Color( 0x111111 );
this.depthCameraNear_ = 100000;
this.depthCamera_ = new THREE.PerspectiveCamera(fov, aspect, this.depthCameraNear_, far);
this.postCamera_ = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
this.postScene_ = new THREE.Scene();
/*
this.composer_ = new EffectComposer(this.threejs_);
const renderPass = new RenderPass(this.scene_, this.camera_);
const fxaaPass = new ShaderPass(FXAAShader);
this.composer_.addPass(renderPass);
this.composer_.addPass(fxaaPass);
*/
this.resolution_ = new THREE.Vector2();
this.threejs_.getDrawingBufferSize(this.resolution_);
this.target1_ = new THREE.WebGLRenderTarget(this.resolution_.x, this.resolution_.y);
this.target1_.texture.format = THREE.RGBFormat;
this.target1_.texture.minFilter = THREE.NearestFilter;
this.target1_.texture.magFilter = THREE.NearestFilter;
this.target1_.texture.generateMipmaps = false;
this.target1_.stencilBuffer = false;
this.target2_ = new THREE.WebGLRenderTarget(this.resolution_.x, this.resolution_.y);
this.target2_.stencilBuffer = false;
this.target2_.depthBuffer = true;
this.target2_.depthTexture = new THREE.DepthTexture();
this.target2_.depthTexture.format = THREE.DepthFormat;
this.target2_.depthTexture.type = THREE.FloatType;
this.depthPass_ = new THREE.ShaderMaterial({
vertexShader: vertexShad,
fragmentShader: fragmentShad,
uniforms: {
tDiffuse: { value: null },
tDepth: { value: null },
},
});
var postPlane = new THREE.PlaneBufferGeometry( 2, 2 );
this.postScreen_ = new THREE.Mesh( postPlane, this.depthPass_ );
this.postScene_.add( this.postScreen_ );
}
Render() {
this.threejs_.setRenderTarget(this.target1_);
this.threejs_.clear();
this.threejs_.render(this.scene_, this.camera_);
this.threejs_.setRenderTarget( null );
this.threejs_.setRenderTarget(this.target2_);
this.threejs_.clear();
this.threejs_.render(this.scene_, this.depthCamera_);
this.threejs_.setRenderTarget( null );
this.depthPass_.uniforms.tDiffuse.value = this.target1_.texture;
this.depthPass_.uniforms.tDepth.value = this.target2_.depthTexture;
this.depthPass_.uniformsNeedUpdate = true;
this.threejs_.render(this.postScene_, this.postCamera_);
}
Update(timeElapsed) {
const player = this.FindEntity('player');
if (!player) {
return;
}
const pos = player._position;
}
}//end class
return {
ThreeJSController: ThreeJSController,
};
})();也许我的后处理平面是个坏主意,而有层次感的作曲家才是解决办法?还是两者都要?
发布于 2022-08-22 05:17:04
编程有时会令人沮丧。半天后我找到了解决办法。我使用composer是因为它使代码更短、更简洁。
export const threejs_component = (() => {
class ThreeJSController extends entity.Component {
constructor() {
super();
}
InitEntity() {
this.threejs_ = new THREE.WebGLRenderer({antialias: true, logarithmicDepthBuffer: true});
this.threejs_.outputEncoding = THREE.sRGBEncoding;
this.threejs_.setPixelRatio(window.devicePixelRatio);
this.threejs_.shadowMap.enabled = true;
this.threejs_.shadowMap.type = THREE.PCFSoftShadowMap;
this.threejs_.domElement.id = 'threejs';
this.container = document.getElementById('container');
this.threejs_.setSize(this.container.clientWidth, this.container.clientHeight);
this.container.appendChild( this.threejs_.domElement );
const aspect = this.container.clientWidth / this.container.clientHeight;
const fov = 60;
const near = 1e-6;
const far = 1E27;
this.camera_ = new THREE.PerspectiveCamera(fov, aspect, near, far);
this.scene_ = new THREE.Scene();
//this.scene_.background = new THREE.Color( 0x111111 );
this.threejs_.setClearColor( 0x000000 );
this.depthCameraNear_ = 100000;
this.depthCamera_ = new THREE.PerspectiveCamera(fov, aspect, this.depthCameraNear_, far);
this.composer_ = new EffectComposer(this.threejs_);
const renderPass = new RenderPass(this.scene_, this.camera_);
const fxaaPass = new ShaderPass(FXAAShader);
this.composer_.addPass(renderPass);
this.composer_.addPass(fxaaPass);
this.resolution_ = new THREE.Vector2();
this.threejs_.getDrawingBufferSize(this.resolution_);
this.target_ = new THREE.WebGLRenderTarget(this.resolution_.x, this.resolution_.y);
this.target_.stencilBuffer = false;
this.target_.depthBuffer = true;
this.target_.depthTexture = new THREE.DepthTexture();
this.target_.depthTexture.format = THREE.DepthFormat;
this.target_.depthTexture.type = THREE.FloatType;
}
Render() {
this.threejs_.autoClear = true;
this.threejs_.setRenderTarget(this.target_);
this.threejs_.render(this.scene_, this.depthCamera_);
this.threejs_.setRenderTarget( null );
this.threejs_.clear();
this.camera_.layers.set(0);
this.threejs_.render(this.scene_, this.camera_);
this.composer_.render();
this.threejs_.autoClear = false;
this.threejs_.clearDepth();
this.camera_.layers.set(1);
this.threejs_.render(this.scene_, this.camera_);
}
Update(timeElapsed) {
const player = this.FindEntity('player');
if (!player) {
return;
}
const pos = player._position;
}
}//end class
return {
ThreeJSController: ThreeJSController,
};
})();子模块访问编写器来设置后处理着色器,如下所示
composer_.addPass(new ShaderPass(customShader));对于组,我使用它将模型和组设置为首选层。
model.traverse( function( child ) { child.layers.set(1); });我几乎从来不喝啤酒,但现在我可以用一杯来庆祝这一天了。
https://stackoverflow.com/questions/73432598
复制相似问题