2011-12-18 7 views
1

私はWebGLを学んでいます。色付きでテクスチャ付きのオブジェクトもあるプログラムを作りたいと思います。フラグメントシェーダを少し修正しようとしました。オブジェクトにテクスチャがない場合は、色付けされます。WebGLでテクスチャとカラーの使い方を教えてください。

precision mediump float; 

varying vec4 vColor; 
varying vec2 vTextureCoord; 

uniform sampler2D uSampler; 

void main(void) { 
    gl_FragColor = vColor; 
    gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t)); 
} 

これは機能しません。私はエラーが発生します:シェイダーを初期化できませんでした。

+0

JavaScriptコードも投稿してください。あなたはテクスチャとそれ以外をどのように初期化しますか? – datenwolf

+0

[lession4](http://learningwebgl.com/blog/?p=370)のオブジェクトにテクスチャキューブ(lession5から)を追加しようとしましたが、 –

答えて

8

これは意味があるかもしれませんが、テクスチャを持っているかどうかにかかわらず、別のシェーダが必要です。これを回避するには、テクスチャを必要としないときに、単一のピクセルの白いテクスチャを使用します。そうすれば、両方のケースをカバーするのに1つのシェーダが必要になります。シェーダは今、あなたのコードでは、あなたがこの

// at init time. 
var whiteColor = new Float32Array([1, 1, 1, 1]); 

// at draw time 
gl.uniform4fv(u_colorLocation, whiteColor); // use white color 
gl.bindTexture(gl.TEXTURE_2D, someTexture); // and some texture 
... draw ... 

のようなテクスチャー描くことができますそして、あなたはそれもこの

// at init time. 
var whiteTexture = gl.createTexture(); 
gl.bindTexture(gl.TEXTURE_2D, whiteTexture); 
var whitePixel = new Uint8Array([255, 255, 255, 255]); 
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, 
       gl.RGBA, gl.UNSIGNED_BYTE, whitePixel); 


// at draw time 
gl.uniform4fv(u_colorLocation, someColor); // use the color I want 
gl.bindTexture(gl.TEXTURE_2D, whiteTexture); // use the white texture 
... draw ... 

を行う非テクスチャ描画するこの

uniform vec4 u_color; 
uniform sampler2D u_texture; 

varying vec2 v_texCoord; 

void main(void) { 
    gl_FragColor = texture2D(u_texture, v_texCoord) * u_color; 
} 

のようになります。非白色の色とテクスチャを一緒に使用してテクスチャを色づけることができます。

3

正確な問題を把握するには、いくつかのコードが必要になる場合があります。例えば、あなたの頂点シェーダーはどのように見えるのですか?どのようにそれらをリンクしていますか?

その間、あなたが投稿したシェーダについて教えてくれるポインタがいくつかあります。 1つは、あなたが記述した効果を与えるものではありません。実際には、テクスチャの色が常に表示されるか、またはテクスチャが指定されていない場合は黒が表示されます。頂点の色は決して表示されません。これは、最終フラグメントカラーに2回割り当て、2番目の割り当てが常に最初の割り当てを上書きするためです。

色とテクスチャの値を加算または掛け合わせることで、2つの値をブレンドしてみてください。そのようなものを試してみてください:

gl_FragColor = vColor + texture2D(uSampler, vTextureCoord); 

質感が空の場合、あなたはまだ黒買ってあげるということがある唯一の問題(0を乗じたものがまだ0です)。これを避けるには、実際のテクスチャを使用できない場合は、常に白いテクスチャを使用してください。

説明した正確な効果(テクスチャがない場合にのみ頂点の色)が必要な場合は、条件文を使用する必要があります。それらは一般的に避けられますが、あなたの使用はひどく重いことには疑いがあります。

また、スタイルチップとして、次の行は等価である:

vec2(vTextureCoord.s, vTextureCoord.t) 
vTextureCoord.st 

第しかし、高速であってもよく、好ましいすべきです。しかし、それ以外にも、すでにとvec2であるため、vTextureCoordを直接渡すことができます(私が示したように)。

関連する問題