[PR]
×
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
プログラミング、3DCGとその他いろいろについて
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
以前、TypeScriptでレンダーターゲットのピクセルを読んだことがありました。
描画した3DCGのピクセルを読み込みます。
今回はGoogleの言語、Dartでレンダーターゲットのピクセルを読もうと思います。
ところが、Dartの3DCGライブラリThree.dartはまだ発展途上なのか、レンダーターゲットからピクセルを読めません。
しかたがないので一部WebGLを直接使います。
pixel count
import 'dart:html'; import 'dart:math'; import 'dart:web_gl'; import 'dart:typed_data'; import 'package:three/three.dart'; WebGLRenderer renderer; Scene scene = new Scene(); PerspectiveCamera camera = new PerspectiveCamera(); Mesh cube; Framebuffer renderTargetFrameBuffer; Uint8List pixels; CanvasElement canvas; void main(){ canvas = querySelector("#myCanvas"); camera.fov = PI / 3; camera.aspect = canvas.width / canvas.height; camera.near = 0.1; camera.far = 1000.0; camera.translateZ(3.0); renderer = new WebGLRenderer(canvas:canvas); renderer.setClearColor(new Color(0x000000), 1.0); var geometry = new CubeGeometry(1.0, 1.0, 1.0); var material = new MeshBasicMaterial(color:0x00ff00); cube = new Mesh(geometry, material); scene.add(cube); renderTargetFrameBuffer = createRenderTarget(); pixels = new Uint8List(canvas.width * canvas.height * 4); _animate(0.0); } Framebuffer createRenderTarget() { //Three.dartではレンダーターゲットからピクセルを読み込めないようです。 //なのでWebGLを直接使います。 RenderingContext gl = renderer.context; final int renderTargetWidth = canvas.width; final int renderTargetHeight = canvas.height; var renderTargetFrameBuffer = gl.createFramebuffer(); gl.bindFramebuffer(FRAMEBUFFER, renderTargetFrameBuffer); print("renderTargetTexture"); var renderTargetTexture = gl.createTexture(); print("bindTexture"); gl.bindTexture(TEXTURE_2D, renderTargetTexture); print("texImage2D"); gl.texImage2D( TEXTURE_2D, 0, RGBA, renderTargetWidth, renderTargetHeight, 0, RGBA, UNSIGNED_BYTE, new Uint8List(renderTargetWidth * renderTargetHeight * 4)); print("renderBuffer"); var renderBuffer = gl.createRenderbuffer(); gl.bindRenderbuffer(RENDERBUFFER, renderBuffer); gl.renderbufferStorage( RENDERBUFFER, DEPTH_COMPONENT16, renderTargetWidth, renderTargetHeight); gl.framebufferTexture2D( FRAMEBUFFER, COLOR_ATTACHMENT0, TEXTURE_2D, renderTargetTexture, 0); gl.framebufferRenderbuffer( FRAMEBUFFER, DEPTH_ATTACHMENT, RENDERBUFFER, renderBuffer); print("set null"); gl.bindTexture(TEXTURE_2D, null); gl.bindRenderbuffer(RENDERBUFFER, null); gl.bindFramebuffer(FRAMEBUFFER, null); return renderTargetFrameBuffer; } void _animate(double deltaTime){ cube.rotation.y += 0.02; renderRenderTarget(); showResults(); renderer.render(scene, camera); window.animationFrame.then(_animate); } void renderRenderTarget() { RenderingContext gl = renderer.context; gl.bindFramebuffer(FRAMEBUFFER, renderTargetFrameBuffer); renderer.render(scene, camera); gl.readPixels( 0, 0, canvas.width, canvas.height, RGBA, UNSIGNED_BYTE, pixels); gl.bindFramebuffer(FRAMEBUFFER, null); } void showResults(){ int black = 0; int green = 0; for(int y = 0; y < canvas.height;y++){ for(int x = 0; x < canvas.width; x++){ int index = (x + canvas.width * y) * 4; if(pixels[index] == 0 && pixels[index + 1] == 0 && pixels[index + 2] == 0){ black++; } else if(pixels[index] == 0 && pixels[index + 1] == 0xFF && pixels[index + 2] == 0){ green++; } } } querySelector("#pixelCountView").text = "black: $black, green: $green"; }
以上です。
早くthree.dartでも読めるようになるといいですね。