0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ShaderToyのCubeMapAへの道、あるいは動的CubeMap入門

Last updated at Posted at 2020-12-20

ShaderToyのCubeMapAへの道、あるいは動的CubeMap入門

ShadertToyのスペシャルフューチャーとして、CubeMapAがある。
CubeMapAはhttps://shadertoyunofficial.wordpress.com/2016/07/20/special-shadertoy-features/
に解説があり、6枚のマッピング用のテクスチャーを用意しておく通常のCubeMapと違い、
シェーダーで動的にCubeMap用の画像を生成する機能である。以前のポストで、opennframeworksのアドオンであるofxshadertoyでCubeMapを実現する方法を実験した、
「ShaderToy+openframeworksでキューブマップ」
https://qiita.com/quittardis/items/9e1abab3babfeb3e1206
を参考にしていただきたい、

本稿では、まだ「ShaderToyのCubeMapAへの道」、つまり途上でなので最後までたどり着けるかどうかわからないが、CubeMapAを実現すべく試行錯誤を続けたい。
 ofxshadertoyの開発者のtiagosor氏が、そうこうするうちにCubeMapAをインプリメントしてくれるかもしれないが、そうなっても、Shadertoyやopenframeworksを使わない一般的なOpenGLの動的キューブマップの勉強にもなればと考えている。

 本稿は、上に述べた「ShaderToy+openframeworksでキューブマップ」をベースに進める。

OpenGLで動的マッピンテクスチャーマッピング

要するに、キューブマップ用の6枚テクスチャーをFramebufferに紐づけられたメモリに上書きできればいいわけで、このために、OpenGLのフレームバッファを準備し、キューブマップ用に用意されたテクスチャーとフレームバッファを紐づけて、テクスチャー直接描き変えるということが目標である。

Framebuffer

ヘッダーに、

GLuint FbCubeA;
GLuint TxCubeA;

とし、初期化するところに、

// CubeA用フレームバッファの準備
	FbCubeA = 0;
	glGenFramebuffers(1, &FbCubeA);
	glBindFramebuffer(GL_FRAMEBUFFER, FbCubeA);

とする。
次以下のようににテクスチャーをアサインし、6枚のグレーのテクスチャーで
初期化する。

unsigned int textureID;
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_CUBE_MAP, textureID);

int width, height;
	width = 512;
	height = 512;
	const int size = width * height * 3;  //   4 channels, unit8 
	GLubyte* data = new GLubyte[size];
	for (int i = 0; i < size; i+= 3) {
		data[i] = 200;
		data[i+1] = 200;
		data[i+2] = 200;
	}

キューブマップ用の6枚の画像の登録

次にこの6枚をキューブマップ用のテクスチャーとして登録する。

	for (unsigned int i = 0; i < 6; i++)
	{
	
		glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
		
	}
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

	return textureID;

フレームバッファのカラーバッファとしてテクスチャを設定

 このtextureIDをvoid ofApp::update()で以下のように利用する。
描画をスクリーンでなくテクスチャーの直接描くオフスクリーンレンダリングである。

xmove はintとしてglobalで定義され、描画色をフレームごとに変化させて、
 TxCubeAは、グローバル変数で上で求めた、textureIDを代入する。

glBindFramebuffer(GL_FRAMEBUFFER, FbCubeA);
for (int face = 0; face < 6; face++)
{
    // フレームバッファのカラーバッファとしてテクスチャを設定
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, TxCubeA, 0);
    ofSetColor(255-(xmove%255), 0, 0);
  xmove++;
    ofDrawRectangle(10, 10, 512, 512);
								
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);

これで、キューブマップの画像を動的に変化させられることがわかった。
今回は描かれる画像が上下左右に切れ目なくつながった正式のキューブマップ用のテクスチャー
ではないので、これをシェーダーで描けるようになるのが次の目標である。
(Framebufferのほかにもデプスバッファを用意する場合もあるが、今回は3Dのオブジェクトを描画しないのでデプスバッファは不要)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?