gpt4 book ai didi

Three.js 着色器-纹理闪烁

转载 作者:行者123 更新时间:2023-12-04 20:47:05 28 4
gpt4 key购买 nike

我是 Three.js 的新手,我认为它很棒。我试图更好地控制将纹理数据移动到着色器,以便我可以主要使用 GPU。我的程序基于 Doob 先生的魔法灰尘示例,但我没有使用粒子,而是使用存储在纹理中的加载模型。我目前遇到了闪烁的问题。下面的代码是闪烁的粗略示例,与我正在做的事情有些接近。如果有人可以帮助我了解我做错了什么或闪烁的来源......我很确定一切都是最新的,就像纹理映射和three.js修订版一样。
非常感谢

<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>Sample Three.js</title>
</head>

<div id="container">
</div>

<body>
<script type="text/javascript" src="./Scripts/three.js"></script>

<script type="text/javascript">

//
// as name suggests - utilty functions mostly from Mr.doob from THREE.FBOUtils
//
UtilityFuncs = function() {
this.textureWidth = 0;
this.textureHeight = 0;
this.scene = null;
this.camera = null;
this.renderer = null;
this.material = null;
this.jsonLoader = null;
this.jsonModel = null;
this.loadCount = 0;
}

UtilityFuncs.prototype.createScene = function( textureWidth, textureHeight, renderer ) {
var gl = renderer.getContext();

if( !gl.getExtension( "OES_texture_float" )) {
alert( "No OES_texture_float support for float textures!" );
return;
}

if( gl.getParameter(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS) == 0) {
alert( "No support for vertex shader textures!" );
return;
}

var camera = new THREE.OrthographicCamera(-textureWidth/2, textureHeight/2,
textureWidth/2, -textureHeight/2,
-1000, 1000);
camera.position.z = 100;

// Shader Stuff
var vertex_shader = [
"varying vec2 vUv;",
"void main() {",
" vUv = vec2(uv.x, 1.0 - uv.y);",
" gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
"} "
].join("\n");

var fragment_shader = [
"varying vec2 vUv;",
"uniform sampler2D tPositions;",
"void main() {",
" vec4 pos = texture2D( tPositions, vUv );",
" gl_FragColor = pos;",
"}"
].join("\n");

var material = new THREE.ShaderMaterial({
uniforms: {
tPositions: { type: "t", value: null }
},
vertexShader: vertex_shader,
fragmentShader: fragment_shader,
blending: THREE.NoBlending,
depthTest: false,
depthWrite: false,
side: THREE.DoubleSide
});

var plane = new THREE.PlaneGeometry(textureWidth, textureHeight);
var quad = new THREE.Mesh(plane, material);
quad.position.z = 0;
var scene = new THREE.Scene();
scene.add(camera);
scene.add(quad);

this.textureWidth = textureWidth;
this.textureHeight = textureHeight;
this.scene = scene;
this.camera = camera;
this.renderer = renderer;
this.material = material;
}

UtilityFuncs.prototype.createRenderTarget = function(width, height) {
var rtTexture = new THREE.WebGLRenderTarget(width, height,
{
wrapS:THREE.RepeatWrapping,
wrapT:THREE.RepeatWrapping,
minFilter: THREE.NearestFilter,
magFilter: THREE.NearestFilter,
format: THREE.RGBAFormat,
type:THREE.FloatType,
// renderbuffer defaults to RGB4
// if stencil & depth false!
// three.js, setupRenderBuffer::24848
stencilBuffer: false,
depthBuffer: true
});
rtTexture.generateMipmaps = false;
return rtTexture;
}

UtilityFuncs.prototype.createFloatTextureFromData = function(width, height, data) {
var texture = new THREE.DataTexture(
data,
width,
height,
THREE.RGBAFormat,
THREE.FloatType,
null,
THREE.RepeatWrapping,
THREE.RepeatWrapping,
THREE.NearestFilter,
THREE.NearestFilter
);

texture.generateMipmaps = false;
texture.needsUpdate = true;

return texture;
};

UtilityFuncs.prototype.readFramebuffer = function(renderer, framebuffer, width, height) {
var gl = renderer.getContext();
gl.flush();
if (framebuffer != null)
gl.bindFramebuffer( gl.FRAMEBUFFER, framebuffer );
var rdData = new Uint8Array(width*height*4);
gl.readPixels( 0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, rdData );
return rdData;
}

UtilityFuncs.prototype.readFloatFramebuffer = function(renderer, framebuffer, width, height) {
var gl = renderer.getContext();
gl.flush();
if (framebuffer != null)
gl.bindFramebuffer( gl.FRAMEBUFFER, framebuffer );
var rdData = new Float32Array(width*height*4);
gl.readPixels( 0, 0, width, height, gl.RGBA, gl.FLOAT, rdData );
return rdData;
}

UtilityFuncs.prototype.renderToTexture = function(texture, renderToTexture) {
this.material.uniforms.tPositions.value = texture;
this.renderer.render(this.scene, this.camera, renderToTexture, false);
};

UtilityFuncs.prototype.render = function(texture) {
this.material.uniforms.tPositions.value = texture;
this.renderer.render(this.scene, this.camera);
};

//
// start of main routines
//
var WIDTH = window.innerWidth,
HEIGHT = window.innerHeight;
var texWidth = 4,
texHeight = 4;
var container, renderer;
var start = Date.now();
var rtTexture, rtTexture2;
var utilities;
var rdData, rdData2, ardData, ardData2;

function launch() {

container = document.getElementById("container");
renderer = new THREE.WebGLRenderer({antialias:true});
renderer.setSize(WIDTH, HEIGHT);
container.appendChild(renderer.domElement);

utilities = new UtilityFuncs();

utilities.createScene( texWidth, texHeight, renderer );

rtTexture = utilities.createRenderTarget(texWidth, texHeight);
rtTexture2 = utilities.createRenderTarget(texWidth, texHeight);


// Create constant color test textures
var mData = new Float32Array(texWidth*texHeight*4);
for (var i = 0; i < 8; i++) {
mData[4*i] = 1.0; mData[4*i+1] = 0.0; mData[4*i+2] = 1.0; mData[4*i+3] = 1.0;
}
magentaTexture = utilities.createFloatTextureFromData(texWidth, texHeight, mData)

// Create constant color test textures
var cData = new Float32Array(texWidth*texHeight*4);
for (var i = 0; i < 8; i++) {
cData[4*i] = 0.0; cData[4*i+1] = 1.0; cData[4*i+2] = 1.0; cData[4*i+3] = 1.0;
}
cyanTexture = utilities.createFloatTextureFromData(texWidth, texHeight, cData)

utilities.renderToTexture(cyanTexture, rtTexture);
rdData = utilities.readFramebuffer(renderer, rtTexture.__webglFramebuffer,
texWidth, texHeight);

utilities.renderToTexture(magentaTexture, rtTexture2);
rdData2 = utilities.readFramebuffer(renderer, rtTexture2.__webglFramebuffer,
texWidth, texHeight);

if (rdData[0] != 0 || rdData[1] != 255 || rdData[2] != 255 || rdData[3] != 255)
console.log("rtTexture load fail\n");

if (rdData2[0] != 255 || rdData2[1] != 0 || rdData2[2] != 255 || rdData2[3] != 255)
console.log("rtTexture2 load fail\n");

animate();
}

var timer = 0;

function animate() {
requestAnimationFrame( animate );
render();
}

function render() {
//
// copy rtTexture and rtTexture2 between each other
//

utilities.renderToTexture(rtTexture, rtTexture2);
ardData2 = utilities.readFramebuffer(renderer, rtTexture2.__webglFramebuffer,
texWidth, texHeight);

utilities.renderToTexture(rtTexture2, rtTexture);
ardData = utilities.readFramebuffer(renderer, rtTexture.__webglFramebuffer,
texWidth, texHeight);

if (timer & 1)
utilities.render(rtTexture2);
else
utilities.render(rtTexture);

if (ardData[0] != 0 || ardData[1] != 255 || ardData[2] != 255 || ardData[3] != 255)
console.log("rtTexture fail\n");
if (ardData2[0] != 0 || ardData2[1] != 255 || ardData2[2] != 255 || ardData2[3] != 255)
console.log("rtTexture2 fail\n");
timer++;
}

//launch();

</script>
<button id="renderButton" onClick="launch()">Render</button>
<br/>
</body>
</html>

最佳答案

好吧,如果您更改从以下位置填充纹理的 for 循环,闪烁将停止:

for (var i = 0; i < 8; i++) ==>> for (var i = 0; i < texWidth*texHeight*4; i++)

但我在 chrome 和 firefox 上都不断收到“rtTexture2 失败”。

我发现了另一个错误。线;
if (ardData2[0] != 0 || ardData2[1] != 255 || ardData2[2] != 255 || ardData2[3] != 255)

应该:
if (ardData2[0] != 255 || ardData2[1] != 0 || ardData2[2] != 255 || ardData2[3] != 255)

但我仍然无法摆脱上述错误。

关于Three.js 着色器-纹理闪烁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15077762/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com