#javascript #three.js #webgl #webgl2
Вопрос:
Я пытаюсь выполнить рендеринг для одного компонента 8-битной цели рендеринга в three.js но я получаю ряд ошибок, которые я не знаю, как решить, и поиск, похоже, не дает много других совпадений. WebGLRenderTarget создается со следующими параметрами:
format: THREE.RedIntegerFormat,
type: THREE.UnsignedByteType,
internalFormat: 'R8UI',
minFilter: THREE.NearestFilter,
magFilter: THREE.NearestFilter,
При рендеринге в целевой объект рендеринга, а затем при попытке скопировать его на экран я получаю следующие ошибки WebGL:
GL_INVALID_OPERATION: No defined conversion between clear value and attachment format.
GL_INVALID_OPERATION: Fragment shader output type does not match the bound framebuffer attachment type.
GL_INVALID_OPERATION: Mismatch between texture format and sampler type (signed/unsigned/float/shadow).
Вот пример повторения проблемы, которую я вижу:
<script type="module">
import * as THREE from 'https://cdn.skypack.dev/three'
import { FullScreenQuad } from 'https://cdn.skypack.dev/three/examples/jsm/postprocessing/Pass.js'
let camera, scene, renderer;
let geometry, material, mesh;
let renderTarget, fsQuad;
class FinalMaterial extends THREE.ShaderMaterial {
constructor() {
super( {
uniforms: {
map: { value: null }
},
vertexShader: /* glsl */`
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}`,
fragmentShader: /* glsl */`
uniform sampler2D map;
varying vec2 vUv;
void main() {
vec4 texel = texture2D( map, vUv );
gl_FragColor = texel;
}`
} );
}
}
init();
function init() {
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.01, 10 );
camera.position.z = 1;
scene = new THREE.Scene();
geometry = new THREE.BoxGeometry( 0.2, 0.2, 0.2 );
material = new THREE.MeshNormalMaterial();
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setAnimationLoop( animation );
document.body.appendChild( renderer.domElement );
renderTarget = new THREE.WebGLRenderTarget(
window.innerWidth,
window.innerHeight,
{
format: THREE.RedIntegerFormat,
type: THREE.UnsignedByteType,
internalFormat: 'R8UI',
minFilter: THREE.NearestFilter,
magFilter: THREE.NearestFilter,
}
);
renderTarget.texture.internalFormat = 'R8UI';
fsQuad = new FullScreenQuad( new FinalMaterial() );
fsQuad.material.uniforms.map.value = renderTarget.texture;
}
function animation( time ) {
mesh.rotation.x = time / 2000;
mesh.rotation.y = time / 1000;
renderer.setRenderTarget( renderTarget );
renderer.render( scene, camera );
renderer.setRenderTarget( null );
fsQuad.render( renderer );
}
</script>
Комментарии:
1. Если это вам поможет, я запустил ваш фрагмент в Firefox и получил больше описательных ошибок . Похоже, что источником является UINT, а пунктом назначения является FLOAT, и наоборот.
2. @Marquizzo Спасибо! Я думаю, что понимаю немного больше о том, что происходит сейчас, но суть в том, что в основном three.js не поддерживает очистку или рендеринг для целочисленных целей рендеринга. Он не использует правильные четкие функции, и система шейдеров не настроена для записи целочисленных значений. Я сделал пару пиаров, чтобы улучшить three.js-тем не менее, поддерживаю это, так что в какой-то момент это может оказаться возможным.