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