現在地メニュー >> GLSL >> GLSL編05 >> GLSL編05::まとめ

問題

フラグメントライティングを行え

答え

glsl.vert

//varying変数
varying vec3 normal;//法線
varying vec3 vtoL;//視点座標系での頂点→光源のベクトル

//頂点シェーダ
void main(void)
{
	//投影変換 (モデルビュー * プロジェクション) * 頂点座標
	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

	////各種基本的なベクトルを計算
	normal = gl_NormalMatrix * gl_Normal;//法線を視点座標系にする
	vec4 V = gl_ModelViewMatrix * gl_Vertex;//視点座標系の頂点位置
	vtoL = gl_LightSource[0].position.xyz - V.xyz;//頂点→光源へのベクトル

}

glsl.frag

//varying変数
varying vec3 normal;//法線
varying vec3 vtoL;//視点座標系での頂点→光源のベクトル


//フラグメント
void main(void)
{
	////  ambientの計算  ////
	vec4 ambient = gl_LightSource[0].ambient * gl_FrontMaterial.ambient;

	////  diffuse計算  ////
	vec3 N = normalize(normal);//正規化
	vec3 L = normalize(vtoL);//正規化
	float NdotL = dot(N,L);
	vec4 diffuse = vec4( max(0.0,NdotL) ) * gl_LightSource[0].diffuse * gl_FrontMaterial.diffuse;

	////  specular計算(Bilnのモデルを使用)  ////
	vec3 H = normalize(gl_LightSource[0].halfVector.xyz);
	float NdotH = dot(N,H);
	vec4 specular = pow(max(0.0,NdotH),gl_FrontMaterial.shininess);
	if(NdotL <=0)//条件によってはspecular無し
	{
		specular = 0;
	}
	specular = specular* gl_LightSource[0].specular * gl_FrontMaterial.specular;

	gl_FragColor = ambient + diffuse + specular;
}

main.cpp

#include <iostream>
#include <string>
#include <fstream>
#include <gl/glew.h>
#include <gl/glut.h>

#pragma comment (lib,"glew32.lib")

GLuint vShaderId;
GLuint fShaderId;
GLuint programId;


//GLSLのセットアップ
void setUpGLSL()
{
	//---- 頂点シェーダオブジェクトの作成 ----//
	vShaderId = glCreateShader(GL_VERTEX_SHADER);
	
	//.vertファイルの中身を全て読み込む
	std::ifstream inputFile1("glsl.vert");
	std::istreambuf_iterator<char> vdataBegin(inputFile1);
	std::istreambuf_iterator<char> vdataEnd;
	std::string fileData1(vdataBegin,vdataEnd);
	const char *vfile = fileData1.c_str();

	//ソースコードをシェーダオブジェクトに変換
	glShaderSource(vShaderId, 1, &vfile,NULL);
	glCompileShader(vShaderId);//コンパイル
	
	
	//---- フラグメントシェーダオブジェクトの作成 ----//
	fShaderId = glCreateShader(GL_FRAGMENT_SHADER);

	//.fragファイルの中身を全て読み込む
	std::ifstream inputFile2("glsl.frag");
	std::istreambuf_iterator<char> fdataBegin(inputFile2);
	std::istreambuf_iterator<char> fdataEnd;
	std::string fileData2(fdataBegin,fdataEnd);
	const char *ffile = fileData2.c_str();
	//ソースコードをシェーダオブジェクトに変換
	glShaderSource(fShaderId, 1, &ffile,NULL);
	glCompileShader(fShaderId);//コンパイル

	//プログラムオブジェクトの作成
	programId = glCreateProgram();
	glAttachShader(programId,vShaderId);
	glAttachShader(programId,fShaderId);

	GLint linked;
	glLinkProgram(programId);
	glGetProgramiv(programId, GL_LINK_STATUS, &linked);
	if(linked == GL_FALSE)
	{
		std::cerr << "Link Err.\n";
	}

	glUseProgram(programId);


}

void SetMaterialGold()
{
	static GLfloat gold_amb[] = { 0.24725f, 0.1995f, 0.0745f, 1.f };
	static GLfloat gold_diff[] = { 0.75164f, 0.60648f , 0.22648f, 1.f };
	static GLfloat gold_spe[] = { 0.628281f, 0.555802f,0.366065f,1.f };
	static GLfloat gold_shin[] = { 51.2f };

	glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, gold_amb);
	glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, gold_diff);
	glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, gold_spe);
	glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, gold_shin);
}

void display()
{
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();

	static float Light0Pos[]={1,1,1,0}; //光源の位置
	glLightfv(GL_LIGHT0, GL_POSITION, Light0Pos);//位置だけ設定(あとはデフォルト)

	gluLookAt(0,0,5,0,0,0,0,1,0);
	SetMaterialGold();
	glutSolidSphere(0.5,60,60);
	
	glutSwapBuffers();
}

void reshape(int w, int h)
{
	glViewport(0,0,w,h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(30,double(w)/h,0.1,200);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

void keyboard(unsigned char key, int x, int y)
{
	switch(key)
	{
	case 'q':
		glDeleteShader(vShaderId);
		glDeleteShader(fShaderId);
		glDeleteProgram(programId);
		exit(0);
		break;
	}
}

void init()
{
	glClearColor(0.3,0.3,0.3,1);
	glEnable(GL_DEPTH_TEST);
}

int main(int argc, char **argv)
{
	glutInit(&argc,argv);
	glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
	glutInitWindowSize(640,480);
	glutCreateWindow("Basic Lighting");

	glutDisplayFunc(display);
	glutReshapeFunc(reshape);
	glutKeyboardFunc(keyboard);
	init();

	glewInit();
	if (!glewIsSupported("GL_VERSION_2_0"))
	{
		std::cerr << "Can't Use GLSL\n";
		return -1;
	}

	setUpGLSL();
	glutMainLoop();

	return 0;
}

メモ

頂点ライティングとフラグメントライティングでは、
鏡面反射部分に結構差がでる...はず。

目次

― その他 ―

Wiki内検索

計測中...(07.10.8〜)

Save The World






▲よろしければ広告のクリックもお願いします


▲ランキングに参加しました

管理人/副管理人のみ編集できます