web-dev-qa-db-ja.com

webglシェーダーで精度値を定義する必要があるのはなぜですか?

このチュートリアル を機能させようとしていますが、2つの問題が発生しました。そのうちの1つは次のとおりです。

コードをそのまま実行すると、フラグメントシェーダーでTHREE.WebGLShader: gl.getShaderInfoLog() ERROR: 0:2: '' : No precision specified for (float)というエラーが発生します。だから私がしたことは、私が定義するすべてのフロート/ベクトルの精度を指定することでしたvarying highp vec3 vNormal。これでエラーは解消されますが、理由がわかりません。変数宣言に精度値が追加されている例は他にありません。なぜこれが起こるのか誰かが説明できますか?それは私のブラウザ(Chrome 38)と関係がありますか?

17
Flavio

Jessyの答えは、ほとんどのフラグメントシェーダーがフラグメントシェーダーコードの先頭にデフォルトの精度を設定しているということです。

ただし、Three.jsのRawShaderMaterialを使用しています。これは、組み込みのユニフォーム、属性、および精度宣言を付加しません。したがって、自分で定義する必要があります。

一方、リンクしたチュートリアルでは、素材にThree.jsのShaderMaterialを使用しているため、Three.jsの精度宣言が自動的に付加されます。

シェーダーコードからデフォルトのユニフォーム/属性を削除し、代わりにShaderMaterialを使用すると、精度コードがなくても機能します。

頂点シェーダー

varying vec3 vNormal;

void main() {
    vNormal = normal;
    gl_Position = projectionMatrix *
                modelViewMatrix *
                vec4(position,1.0);
}

フラグメントシェーダー

varying vec3 vNormal;

void main() {
    vec3 light = vec3(0.5, 0.2, 1.0);

    // ensure it's normalized
    light = normalize(light);

    // calculate the dot product of
    // the light to the vertex normal
    float dProd = max(0.0, dot(vNormal, light));

    // feed into our frag colour
    gl_FragColor = vec4(dProd, // R
                        dProd, // G
                        dProd, // B
                        1.0);  // A
}

資料の更新

// create the sphere's material
var shaderMaterial = new THREE.ShaderMaterial({
    vertexShader:   document.getElementById('vertex-shader').innerHTML,
    fragmentShader: document.getElementById('fragment-shader').innerHTML
});

Here は、精度宣言のないコードのフィドルです。

7
Anton

WebGLフラグメントシェーダにはデフォルトの精度はありません。 (頂点シェーダーのデフォルトは高精度です。)最も簡​​単な解決策は、追加することです。

precision highp float;

すべてのフラグメントシェーダーに適用されます。これにより、すべての浮動小数点ベクトル変数の精度を定義する必要がなくなりますが、通常は

precision mediump float;

パフォーマンスのために、望ましいでしょう。 lowpにはお勧めしません。今日の優れたモバイルハードウェアは、もはやそれをサポートしておらず、lowpからmediumpへのtypedeffingと同等です。

17
Jessy