edit 16 august, 2016
i managed throw error might expose what's going on. in latest code edit, adding ability hot-swap between fragment shaders. works fine shaders singleton uniforms, swapping shader structure throws following error:
uncaught typeerror: cannot read property 'x' of undefined
call stack:
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
it looks it's building structure uniforms incorrectly (it's trying reference property value
three.color
has r
, g
, , ,b
). i'm continuing dig, maybe new info trigger lightbulb someone.
original post & code
according conversation here, three.js has ability use struct
s shader uniforms. i'm trying use shader has structs, simplified bare minimum, , still can't recognize them structs.
in fiddle below, change with_structs
value true
/false
, re-run see difference.
i've tried defining uniforms this, didn't make difference.
uniforms: { "colorvalues": { "color": { type: "c", value: new three.color(0x00ff00) } }, "opacityvalues": { "opacity": { type: "f", value: 1.0 } } }
did miss properties, or approaching entirely incorrectly?
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 speed 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: run demo, must use 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 external function rather referencing draw directly, in case want update draw 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);
this lesson in how couple small , stupid mistakes can make whole thing crash , burn.
i had named singleton uniforms same thing structured uniforms. when uniform parser trying assign values, tried assign singleton value onto structure object. didn't work, naturally, , whole thing fell apart.
it seems "alternate" uniform definition way go. i'm not sure why din't work originally, have feeling due naming mismatch, above.
here's working code chunks, , i've update fiddle linked in original post.
new fragment shader (only 1 structs)
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");
new material definition
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 });
Comments
Post a Comment