これを行う方法の例を次に示します。
螺鈿効果OFF :
螺鈿効果ON :
頂点シェーダー:
uniform vec3 fvEyePosition;
varying vec3 ViewDirection;
varying vec3 Normal;
void main( void )
{
gl_Position = ftransform();
vec4 fvObjectPosition = gl_ModelViewMatrix * gl_Vertex;
ViewDirection = fvEyePosition - fvObjectPosition.xyz;
Normal = gl_NormalMatrix * gl_Normal;
}
フラグメント シェーダー:
uniform samplerCube cubeMap;
varying vec3 ViewDirection;
varying vec3 Normal;
const float mother_pearl_brightness = 1.5;
#define MOTHER_PEARL
void main( void )
{
vec3 fvNormal = normalize(Normal);
vec3 fvViewDirection = normalize(ViewDirection);
vec3 fvReflection = normalize(reflect(fvViewDirection, fvNormal));
#ifdef MOTHER_PEARL
float view_dot_normal = max(dot(fvNormal, fvViewDirection), 0.0);
float view_dot_normal_inverse = 1.0 - view_dot_normal;
gl_FragColor = textureCube(cubeMap, fvReflection) * view_dot_normal;
gl_FragColor.r += mother_pearl_brightness * textureCube(cubeMap, fvReflection + vec3(0.1, 0.0, 0.0) * view_dot_normal_inverse) * (1.0 - view_dot_normal);
gl_FragColor.g += mother_pearl_brightness * textureCube(cubeMap, fvReflection + vec3(0.0, 0.1, 0.0) * view_dot_normal_inverse) * (1.0 - view_dot_normal);
gl_FragColor.b += mother_pearl_brightness * textureCube(cubeMap, fvReflection + vec3(0.0, 0.0, 0.1) * view_dot_normal_inverse) * (1.0 - view_dot_normal);
#else
gl_FragColor = textureCube(cubeMap, fvReflection);
#endif
}
もちろん、R、G、B コンポーネントの計算方法はあまり正確ではありませんが、このコードを投稿するのは、解決策ではなく方法を示すためです。
編集:
虹色シェーダーの約束された「適切な」バージョンは次のとおりです。
頂点シェーダー:
varying vec3 v_view_direction;
varying vec3 v_normal;
varying vec2 v_texture_coordinate;
void main(void)
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
v_texture_coordinate = gl_MultiTexCoord0.xy;
v_view_direction = -gl_ModelViewMatrix[3].xyz;
v_normal = gl_NormalMatrix * gl_Normal;
}
フラグメント シェーダー:
uniform samplerCube texture_reflection;
uniform sampler2D texture_iridescence;
uniform sampler2D texture_noise;
varying vec3 v_view_direction;
varying vec3 v_normal;
varying vec2 v_texture_coordinate;
const float noise_strength = 0.5;
void main(void)
{
vec3 n_normal = normalize(v_normal);
vec3 n_wiew_direction = normalize(v_view_direction);
vec3 n_reflection = normalize(reflect(n_wiew_direction, n_normal));
vec3 noise_vector = (texture2D(texture_noise, v_texture_coordinate).xyz - vec3(0.5)) * noise_strength;
float inverse_dot_view = 1.0 - max(dot(normalize(n_normal + noise_vector), n_wiew_direction), 0.0);
vec3 lookup_table_color = texture2D(texture_iridescence, vec2(inverse_dot_view, 0.0)).rgb;
gl_FragColor.rgb = textureCube(texture_reflection, n_reflection).rgb * lookup_table_color * 2.5;
gl_FragColor.a = 1.0;
}
結果
虹色効果なし:
虹色効果 (ルックアップ テクスチャ 1):
虹色効果 (ルックアップ テクスチャ 2):
虹色ルックアップ テクスチャ 2:
ノイズ テクスチャ:
備考:
虹色ルックアップ テクスチャは 1D テクスチャにすることもできます。これにより、メモリ効率が大幅に向上します。
また、ノイズ ベクトルの計算方法は、実際にはナンセンスです。適切な解決策は、バンプ マッピングを使用することです。でもねえ、それはうまくいきます!:D