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

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

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

嘘です。プログラムだけでテクスチャ生成する手法をプロシージャルテクスチャと呼ぶそうですが、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]

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です