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