three.js - Threejs Adding a shader to a 3d object -
i'm trying create shader 3d object generated maya.
i can 3d object load, when try apply shader i'm getting error:
gl error :gl_invalid_operation : gldrawelements: attempt access out of range vertices in attribute 1
from have read, understand need define vertices, have no idea on how this.
here code:
<html xmlns="http://www.w3.org/1999/xhtml"><head> <title>3d render</title> <script src="js/three.min.js"></script> <script src="js/objloader.js"></script> </head> <body onload="start()" > <script> var gl; var camera, cubecamera, scene, renderer; var intervalprogress; var fov = 70, lon = 0, lat = 70, phi = 0, theta = 0; init(); animate(); function init() { camera = new three.perspectivecamera( fov, window.innerwidth / window.innerheight, 1, 1000 ); scene = new three.scene(); var mesh = new three.mesh( new three.spheregeometry( 500, 60, 40 ), new three.meshbasicmaterial({color: 0xffffff}) ); mesh.scale.x = -1; scene.add( mesh ); var light = new three.pointlight(0xffffff); light.position.set(0, 0, 500); scene.add(light); renderer = new three.webglrenderer( { antialias: true } ); renderer.setsize( window.innerwidth, window.innerheight ); document.body.appendchild( renderer.domelement ); var material = new three.meshbasicmaterial( { color:0xffffff } ); var loader = new three.objloader(); loader.load( "mesh/3d.obj", function ( object ) { object.traverse(function(child) { if (child instanceof three.mesh) { var vertshader = document.getelementbyid('vertexshader').innerhtml; var fragshader = document.getelementbyid('fragmentshader').innerhtml; var uniforms = { texture1: { type: "t", value: three.imageutils.loadtexture( "textures/texture.jpg" ) } }; material = new three.shadermaterial({ uniforms: uniforms, vertexshader: vertshader, fragmentshader: fragshader, wrapping: three.clamptoedgewrapping, shading: three.smoothshading, side: three.doubleside }); child.material = material; child.material.needsupdate = true; // child.material.color.setrgb (1, 0, 0); } }); //set scale, position , rotation of object object.scale.set( 40,40,40 ); object.rotation.x = 0; object.rotation.y = 90; object.position.y = 0; scene.add(object); }); } function animate() { requestanimationframe( animate ); render(); } function render() { var time = date.now(); lon += .15; lat = math.max( - 85, math.min( 85, lat ) ); phi = three.math.degtorad( 90 - lat ); theta = three.math.degtorad( lon ); camera.position.x = 100 * math.sin( phi ) * math.cos( theta ); camera.position.y = 100 * math.cos( phi ); camera.position.z = 100 * math.sin( phi ) * math.sin( theta ); camera.lookat( scene.position ); renderer.render( scene, camera ); } function start() { var canvas = document.getelementbyid("glcanvas"); gl = initwebgl(canvas); // initialize gl context if (gl) { gl.clearcolor(0.0, 0.0, 0.0, 1.0); // set clear color black, opaque gl.enable(gl.depth_test); // enable depth testing gl.depthfunc(gl.lequal); // near things obscure far things gl.clear(gl.color_buffer_bit|gl.depth_buffer_bit); // clear color depth buffer. } } function initwebgl(canvas) { gl = null; try { // try grab standard context. if fails, fallback experimental. gl = canvas.getcontext("webgl") || canvas.getcontext("experimental-webgl"); } catch(e) {} // if don't have gl context, give if (!gl) { alert("unable initialize webgl. browser may not support it."); gl = null; } return gl; } </script> <script id="vertexshader" type="x-shader/x-vertex"> varying vec2 vuv; void main() { vuv = uv; gl_position = projectionmatrix * modelviewmatrix * vec4(position,1.0); } </script> <script id="fragmentshader" type="x-shader/x-fragment"> uniform sampler2d texture1; varying vec2 vuv; void main() { gl_fragcolor = vec4(0.5, 0.2, 1.0, 1.0); } </script> <canvas id="glcanvas" width="1" height="1"></canvas> <canvas width="1920" height="951"></canvas> </body> </html>
i found problem, combination of mentioned above, cleaned code: here working example:
function loadobj(name, metal){ var material = null; loadtexture('textures/'+metal+'.jpg', function(texture){ loadtexture('normal/243-normal.jpg', function(texture2){ var material = createmetalshader(metal, texture, texture2); var loader = new three.objloader(); loader.load( "mesh/"+name+".obj", function ( object ) { object.traverse(function(child) { if (child instanceof three.mesh) { child.geometry = new three.geometry().frombuffergeometry( child.geometry ); child.geometry.mergevertices(); //assignuvs(child.geometry); child.material = material; child.verticesneedupdate = true; child.normalsneedupdate = true; child.uvsneedupdate = true; child.material.shading = three.smoothshading; child.geometry.computevertexnormals(); } object.scale.set( 30,30,30 ); object.rotation.x = 0; object.rotation.y = 90; object.position.y = 0; scene.add(object); currentmetalobject = object; }); }); }); }); } function loadtexture(path, callback){ var loader = new three.textureloader(); // load resource loader.load(path,function ( texture ) { callback(texture); }, function ( xhr ) { console.log( (xhr.loaded / xhr.total * 100) + '% loaded' ); }, function ( xhr ) { console.log( 'an error happened' ); } ); } function createmetalshader(metal, texturematcap, texturenormal){ var material = new three.shadermaterial({ uniforms: { tnormal: { type: 't', value: texturenormal }, tmatcap: { type: 't', value: texturematcap }, time: { type: 'f', value: 0 }, bump: { type: 'f', value: 0 }, noise: { type: 'f', value: .04 }, repeat: { type: 'v2', value: new three.vector2(1, 1) }, usenormal: { type: 'f', value: 0 }, userim: { type: 'f', value: 0 }, rimpower: { type: 'f', value: 2 }, usescreen: { type: 'f', value: 0 }, normalscale: { type: 'f', value: .5 }, normalrepeat: { type: 'f', value: 1 } }, vertexshader: document.getelementbyid('vertexshader').textcontent, fragmentshader: document.getelementbyid('fragmentshader').textcontent, wrapping: three.clamptoedgewrapping, shading: three.smoothshading, side: three.doubleside }); material.uniforms.tmatcap.value.wraps = material.uniforms.tmatcap.value.wrapt = three.clamptoedgewrapping; material.uniforms.tnormal.value.wraps = material.uniforms.tnormal.value.wrapt = three.repeatwrapping; material.name = name; return material; }
Comments
Post a Comment