2016-08-08 32 views
0

編集2016年8月16日シェーダー&構造体

は、私は最終的にそれが何が起こっているのか公開するかもしれないエラーをスローするように得ることができました。最新のコード編集では、フラグメントシェーダー間のホットスワップ機能を追加しました。これは、シングルトンの制服とシェーダのために正常に動作しますが、構造とシェーダにスワップすると、次のエラーがスローされます。

Uncaught TypeError: Cannot read property 'x' of undefined

コールスタック:

それは間違った構造の制服を構築しているように見えます
setValue3fv @ three.js:31915 
THREE.WebGLUniforms.StructuredUniform.setValue @ three.js:32148 
THREE.WebGLUniforms.WebGLUniforms.upload @ three.js:32285 
setProgram @ three.js:26733 renderBufferDirect @ three.js:25492 
renderObjects @ three.js:26303 
render @ three.js:26044 
draw @ VM160:191doStructs @ VM86:148 

(それはだがr,g、およびbのみを持つTHREE.Colorのプロパティvalueを参照しようとしています。私は掘り起こし続けていますが、おそらくこの新しい情報が誰かの電球を引き起こすでしょう。

オリジナルポスト&コード

会話hereによると、Three.jsはシェーダの制服としてstruct Sを使用する能力を持っています。私は今構造体を持つシェーダを使用しようとしていますが、最小限に単純化されていますが、構造体として認識することはできません。

下記のフィドルでは、WITH_STRUCTSの値をtrue/falseに変更して、その違いを確認するために再実行してください。

私もこのような制服を定義しようとしましたが、違いはありませんでした。

uniforms: { 
    "colorValues": { 
     "color": { type: "c", value: new THREE.Color(0x00ff00) } 
    }, 
    "opacityValues": { 
     "opacity": { type: "f", value: 1.0 } 
    } 
} 

いくつかのプロパティが不足しているのですか、それとも完全に間違っていますか?

jsFiddle: http://jsfiddle.net/TheJim01/546syLur/

HTML:

<script src="http://threejs.org/build/three.js"></script> 
<script src="http://threejs.org/examples/js/controls/TrackballControls.js"></script> 
<script src="http://threejs.org/examples/js/libs/stats.min.js"></script> 
<div id="host"></div> 

<script> 
// INITIALIZE 
var WIDTH = window.innerWidth, 
    HEIGHT = window.innerHeight, 
    FOV = 35, 
    NEAR = 1, 
    FAR = 1000; 

var renderer = new THREE.WebGLRenderer({ antialias: true }); 
renderer.setSize(WIDTH, HEIGHT); 
document.getElementById('host').appendChild(renderer.domElement); 

var camera = new THREE.PerspectiveCamera(FOV, WIDTH/HEIGHT, NEAR, FAR); 
camera.position.z = 250; 

var trackballControl = new THREE.TrackballControls(camera, renderer.domElement); 
trackballControl.rotateSpeed = 5.0; // need to speed it up a little 

var scene = new THREE.Scene(); 

var light = new THREE.PointLight(0xffffff, 1, Infinity); 
light.position.copy(camera.position); 

scene.add(light); 

function draw(){ 
    light.position.copy(camera.position); 
    renderer.render(scene, camera); 
} 
trackballControl.addEventListener('change', draw); 

function navStartHandler(e) { 
    renderer.domElement.addEventListener('mousemove', navMoveHandler); 
    renderer.domElement.addEventListener('mouseup', navEndHandler); 
} 
function navMoveHandler(e) { 
    trackballControl.update(); 
} 
function navEndHandler(e) { 
    renderer.domElement.removeEventListener('mousemove', navMoveHandler); 
    renderer.domElement.removeEventListener('mouseup', navEndHandler); 
} 

renderer.domElement.addEventListener('mousedown', navStartHandler); 
renderer.domElement.addEventListener('mousewheel', navMoveHandler); 
</script> 

<fieldset id="controls"> 
    <legend>Controls</legend> 
    <input id="drawButton" type="button" value="DRAW" /> 
    <input id="useStructsCheck" type="checkbox" /><label for="useStructsCheck">Use Structs</label> 
</fieldset> 

CSS:

html, body{ 
    padding: 0; 
    margin: 0; 
    width: 100%; 
    overflow: hidden; 
} 

#controls { 
    position: absolute; 
    top: 20px; 
    left: 20px; 
    z-index: 99; 
    color: white; 
    border-radius: 10px; 
} 

#host { 
    width: 100%; 
    height: 100%; 
} 

のJavaScript:

// NOTE: To run this demo, you MUST use the HTTP protocol, not HTTPS! 

var WITH_STRUCTS = false; 

var vShaderCode = [ 
    "precision highp float;", 
    "precision highp int;", 

    "uniform mat4 modelViewMatrix;", 
    "uniform mat4 projectionMatrix;", 

    "attribute vec3 position;", 

    "void main() {", 
     "vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);", 
     "gl_Position = projectionMatrix * mvPosition;", 
    "}" 
].join("\n"); 

var fShaderCode_structs = [ 
    "precision highp float;", 
    "precision highp int;", 

    "struct ColorStruct{", 
     "vec3 value;", 
    "};", 
    "struct OpacityStruct{", 
     "float value;", 
    "};", 
    "uniform ColorStruct color;", 
    "uniform OpacityStruct opacity;", 

    "void main() {", 
     "gl_FragColor = vec4(color.value, opacity.value);", 
    "}" 
].join("\n"); 

var fShaderCode_nostructs = [ 
    "precision highp float;", 
    "precision highp int;", 

    "uniform vec3 color;", 
    "uniform float opacity;", 

    "void main() {", 
     "gl_FragColor = vec4(color, opacity);", 
    "}" 
].join("\n"); 

var geo = new THREE.BoxBufferGeometry(30, 30, 30); 

var mat = new THREE.RawShaderMaterial({ 
     uniforms: { 
     "color": { type: "c", value: new THREE.Color(0xff0000) }, 
      "opacity": { type: "1f", value: 1.0 }, 
      "color.value": { type: "c", value: new THREE.Color(0x00ff00) }, 
      "opacity.value": { type: "1f", value: 1.0 } 
     }, 
     vertexShader: vShaderCode, 
     fragmentShader: (WITH_STRUCTS) ? fShaderCode_structs : fShaderCode_nostructs 
    }); 

var msh = new THREE.Mesh(geo, mat); 
scene.add(msh); 

draw(); 

// Draw button 
// Making this an external function rather than referencing draw directly, in case we want to update draw with parameters. 
function doDraw() { 
    draw(); 
} 
document.getElementById("drawButton").addEventListener("click", doDraw); 

// Use Structs checkbox 
function doStructs() { 
    WITH_STRUCTS = !WITH_STRUCTS; 
    if (WITH_STRUCTS) { 
    mat.fragmentShader = fShaderCode_structs; 
    } 
    else { 
    mat.fragmentShader = fShaderCode_nostructs; 
    } 
    mat.needsUpdate = true; 
    draw(); 
} 
document.getElementById("useStructsCheck").addEventListener("click", doStructs); 
+0

私は、フラグメントシェーダが少し曖昧にするために自分のコードを更新しました(別の2プリプロセッサロジックを使用するのではなく、シェーダコードのチャンク)。私もレンダラーに物事を辿り、 'gl.getUniformLocation(program、" color.value ");'( 'opacity.value')の呼び出しを見ることができます。正しく設定されている。 – TheJim01

答えて

0

これは夫婦小さく、愚かな過ちは全部のクラッシュを作成し、燃やすことができる方法でレッスンです。

シングルトンの制服には、私の制服と同じものを付けました。ユニフォームパーサーが値を割り当てようとしていたときに、構造体オブジェクトにシングルトン値を割り当てようとしました。それは自然には機能しませんでしたし、すべてが分断されました。

「代替の」統一された定義が行かれたようです。なぜ私は元々仕事をしていないのか分かりませんが、上記のような名前の不一致が原因だと感じています。

ここに作業コードのチャンクがあります。オリジナルの投稿にリンクされたフィドルを更新しました。

新しいフラグメントシェーダ(構造体WITHのみ1)

var fShaderCode_structs = [ 
    "precision highp float;", 
    "precision highp int;", 

    "struct ColorStruct{", 
     "vec3 cvalue;", 
    "};", 
    "struct OpacityStruct{", 
     "float ovalue;", 
    "};", 
    "uniform ColorStruct colorS;", 
    "uniform OpacityStruct opacityS;", 

    "void main() {", 
     "gl_FragColor = vec4(colorS.cvalue, opacityS.ovalue);", 
    "}" 
].join("\n"); 

新素材の定義

var mat = new THREE.RawShaderMaterial({ 
    uniforms: { 
     "color": { type: "c", value: new THREE.Color(0xff0000) }, 
      "opacity": { type: "1f", value: 1.0 }, 
      "colorS": { 
       value: { type: "c", cvalue: new THREE.Color(0x00ff00) }, 
      }, 
      "opacityS": { 
       value: { type: "1f", ovalue: 1.0 } 
      } 
     }, 
     vertexShader: vShaderCode, 
     fragmentShader: (WITH_STRUCTS) ? fShaderCode_structs : fShaderCode_nostructs 
    });