jit.gl.shader / GLSL でプロシージャルテクスチャ(ビーチボール)生成

スクリーンショット 2014-08-04 23.30.07

夏だしビーチボールで夏感を演出

嘘です。プログラムだけでテクスチャ生成する手法をプロシージャルテクスチャと呼ぶそうですが、OpenGL Superbibleにビーチボールのサンプルがあったので実装してみました。法線ベクトルやVertexの位置を利用して色を決めてますね。まだアルゴリズムを飲み込めてないので、ポケモンのハイパーボールを練習で作ってみようか。

JXS / GLSLコード

<jittershader name="mrr-3colored-lights">
	<description>
	</description>

	<language name="glsl" version="1.2">
		<program name="vp" type="vertex">
<![CDATA[

#version 120 

varying vec3 N,L,V;

void main(void)
{
	vec3 lightPos = gl_LightSource[0].position.xyz;

	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;	
	
	//map object-space position onto unit sphere
	V =gl_Vertex.xyz;
	
	//eye-space normal
	N = gl_NormalMatrix * gl_Normal;
	
	//eye-space light vector
	vec4 Veye = gl_ModelViewMatrix * gl_Vertex;
	L =lightPos - Veye.xyz;	
}

]]>
		</program>
		<program name="fp" type="fragment">
<![CDATA[

#version 120

varying vec3 V;
varying vec3 N;
varying vec3 L;

const vec3 myRed 	= vec3(1,0,0);
const vec3 myYellow = vec3(1,1,0);
const vec3 myGreen 	= vec3(0,1,0);
const vec3 myBlue 	= vec3(0,0,1);
const vec3 myWhite 	= vec3(1,1,1);
const vec3 myBlack 	= vec3(0,0,0);

const vec3 northHalfSpace = vec3(0,0,1);
const vec3 northeastHalfSpace = vec3(0.707,0,0.707);
const vec3 northwestHalfSpace = vec3(-0.707,0,0.707);
const float capSize = 0.03;
const float smoothEdgeTol = 0.0005;
const float ambientLighting = 0.1;
const float specularExp = 10.0;
const float specularIntensity = 0.5;

void main()
{
	vec3 NN = normalize(N);
	vec3 NL = normalize(L); //for ambient;
	vec3 NH = normalize(NL +vec3(0,0,1)); //for specular
	vec3 NV = normalize(V);
	
	float mirror = (NV.x >= 0) ? 1. : -1.;
	NV.xz *= mirror; //
	
	vec4 distance;
	distance.x = dot(NV, northHalfSpace);
	distance.y = dot(NV, northeastHalfSpace);
	distance.z = dot(NV, northwestHalfSpace);
	
	distance.w = abs(NV.y) - 1.0 + capSize;	
	distance = smoothstep(vec4(0.), vec4(smoothEdgeTol), distance);
	
	
	vec3 surfColor = mix(myBlack,myRed,distance.x);
	surfColor += mix(myBlack,myGreen,distance.y * (1.0 - distance.z));
	surfColor += mix(surfColor, myBlue, 1.0 - distance.y);
	
	//top bottom
	surfColor = mix(surfColor, myWhite, distance.w);
	
	//ambient
	surfColor *= (ambientLighting + vec3(max(0,dot(NN,NL))));
	//specluar
	surfColor += (specularIntensity *vec3(pow(max(0,dot(NN,NH)),specularExp)));
	
	gl_FragColor = vec4(surfColor,1);
}
]]>
		</program>
	</language>
</jittershader>

Leave a Comment