tag:blogger.com,1999:blog-6382367493021869362023-11-15T10:21:14.002-08:00The O3D API BlogUnknownnoreply@blogger.comBlogger20125tag:blogger.com,1999:blog-638236749302186936.post-29897382629894521202010-05-03T18:40:00.000-07:002020-07-15T16:49:44.720-07:00The future of O3D<div>We <a href="http://googlecode.blogspot.com/2009/04/toward-open-web-standard-for-3d.html">launched</a> the O3D API about a year ago to start a discussion within the web community about establishing a new standard for 3D graphics on the web. Since then, we’ve also helped develop <a href="http://www.khronos.org/webgl/">WebGL</a>, a 3D graphics API based on OpenGL ES 2.0 that has gradually emerged as a standard, and is supported by other browser and hardware vendors like Mozilla, Apple and Opera.</div><div><br /></div><div> </div><div>At Google, we’re deeply committed to implementing and advancing standards, so as of today, the O3D project is changing direction, evolving from its current plug-in implementation into a JavaScript library that runs on top of WebGL. Users and developers will still be able to download the O3D plug-in and source code for at least one year, but other than a maintenance release, we plan to stop developing O3D as a plug-in and focus on improving WebGL and O3D as a JavaScript library.</div><div><br /></div><div> </div><div>We did not take this decision lightly. In initial discussions we had about WebGL, we were concerned that JavaScript would be too slow to drive a low-level API like OpenGL and we were convinced that a higher level approach like the O3D scene graph would yield better results. We were also cognizant of the lack of installed OpenGL drivers on many Windows machines, and that this could hamper WebGL’s adoption.</div><div><br /></div><div> </div><div>Since then, JavaScript has become a lot faster. We've been very impressed by the demos that developers have created with WebGL, and with the <a href="http://code.google.com/p/angleproject">ANGLE project</a>, we believe that Chromium will be able to run WebGL content on Windows computers without having to rely on installed OpenGL drivers.</div><div><br /></div><div> </div><div>The JavaScript implementation of O3D is still in its infancy, but you can find a copy of it on the <a href="http://code.google.com/p/o3d">O3D project site</a> and see it running some of the O3D samples from a WebGL enabled browser (alas, no <a href="http://www.youtube.com/watch?v=uofWfXOzX-g">Beach Demo</a> yet). Because browsers lack some requisite functionality like compressed asset loading, not all the features of O3D can be implemented purely in JavaScript. We plan to work to give the browser this functionality, and all capabilities necessary for delivering high-quality 3D content.</div><div><br /></div><div> </div><div>We’d like to thank the developers who have contributed to O3D by delivering valuable feedback, submitting changes to the plugin and developing applications. To help you convert your application to the new WebGL implementation of O3D, we will keep our <a href="http://groups.google.com/group/o3d-discuss">discussion group</a> open where our engineering team will answer your questions and provide you with technical advice. For those of you concerned about support for Internet Explorer, we’ll recommend using <a href="http://code.google.com/chrome/chromeframe/">Google Chrome Frame</a> once it supports WebGL, and hope to see IE implement WebGL natively someday. We hope you will continue working with us and the rest of the WebGL community on moving 3D on the web forward.</div><div><br /></div><div> </div><div>In the future, we will not be posting to the O3D blog. For updates on O3D and the 3D web, please subscribe to the <a href="http://blog.chromium.org/">Chromium blog</a>.</div><div><br /></div><div> </div><div>Posted by Matt Papakipos, Engineering Director, and Vangelis Kokkevis, Software Engineer</div>Unknownnoreply@blogger.com8tag:blogger.com,1999:blog-638236749302186936.post-7808903929987338932009-10-07T15:30:00.000-07:002020-07-15T16:49:45.055-07:00Plugin Update<div>A new version of the O3D plug-in (0.1.42) is now on its way! This release contains a few bug fixes along with some exciting new functionality including more flexible ways for manipulating image data via the new Bitmap object and support for Data URLs both for reading back the contents of the render buffer and for creating Raw Data buffers. For more details on what's included with this release, please take a look at our <a href="http://code.google.com/apis/o3d/docs/releasenotes.html">Release Notes</a>. As always, if you are an existing O3D user, your plug-in will be updated automatically soon, but if you just can't wait, you can go to our home page and install it manually.</div><div><br /></div><div>An interesting bit of trivia here is that this is likely the last release we'll make using our old build system. We now have all the pieces in place to switch our build over from <a href="http://www.scons.org/">scons</a> to <a href="http://code.google.com/p/gyp">GYP</a>. As you can imagine, switching build systems mid-flight in a product the size of O3D can be fairly challenging, but it looks like most of the hard work is now behind us. Switching to the new build system was a necessary step for getting O3D integrated into Chrome, but it also provides some additional benefits to developers who work with the O3D source code. GYP will generate native project files (Visual Studio on Windows and XCode on the Mac) which makes the edit/compile/debug cycle a lot faster than before. In addition, we'll soon be exposing our <a href="http://buildbot.net/">Buildbot</a>-based continuous build system to everyone so that you can monitor the build progress in real time and even pick up binaries built from the top of our trunk! Stay tuned for detailed instructions.</div><div><br /></div><div>As always, we appreciate your support and comments. Please continue using the <a href="http://groups.google.com/group/o3d-discuss">o3d-discuss</a> group for sending your feedback and questions and the <a href="http://code.google.com/p/o3d/issues">o3d issue tracker</a> for filing bugs.</div><br /><span class="post-author"><span class="Apple-style-span" style="color:#666666;">Posted by Vangelis Kokkevis, O3D Team</span></span>Unknownnoreply@blogger.com10tag:blogger.com,1999:blog-638236749302186936.post-28831414315303736162009-08-21T18:02:00.000-07:002020-07-15T16:49:44.670-07:00Guest Post by Gavriel State, Founder and CTO of TransGaming Inc.<div><span class="Apple-style-span" style="font-style: italic; ">From time to time we plan to open up our blog to guest posts from leaders in the field of 3D graphics. Today's guest post is written by Gavriel Slate, CTO at TransGaming.</span></div><div><br /></div><div><div>In June, the O3D team <a href="http://o3d.blogspot.com/2009/06/o3d-update-new-features-and-expanded.html">announced </a>O3D's new software rendering feature, which is powered by TransGaming's <a href="http://www.transgaming.com/business/swiftshader/">SwiftShader</a> software rendering system. High performance software rendering is a critical feature to enable 3D applications on the web to have the same level of global reach as the traditional 2D web. While most current PC hardware now ships with at least basic graphics hardware capable of accelerated 3D performance, there are hundreds of millions of PCs that lack such hardware, or which have older GPUs that do not support the shader capabilities needed for O3D. For example, around 50% of Pentium 4 based PCs shipped with on-board integrated graphics chipsets with no shader features. Many such PCs with poor support for shaders are in the developing world, so without software rendering the 3D web could be inaccessible to huge parts of the planet.</div><div><br /></div><div>Makers of massively multiplayer games have long understood this problem - Blizzard, the developer of the hit MMO World of Warcraft, has built their game to be compatible with graphics chips developed as far back as 2001, for example. And yet, World of Warcraft's 10 Million+ users pales in comparison to number of people using the web, which is currently estimated as 1.6 Billion. In order for 3D content to become part of the mainstream web, users of older systems can't just be left behind.</div><div><br /></div><div>Luckily, SwiftShader provides a solution to this problem. Unlike traditional software rendering, SwiftShader uses highly efficient techniques to analyze and dynamically compile shaders and other parts of the graphics pipeline into optimized CPU-specific code. This code is then cached, so future rendering of similar objects always takes place with pre-built code. SwiftShader also takes advantage of CPUs with multiple cores. Using these techniques on modern CPUs, SwiftShader can in many cases actually outperform integrated graphics hardware.</div><div><br /></div><div>In fact, in many ways, SwiftShader's software rendering model points the way for some of the developments now occurring on the hardware side. Over time, graphics technologies have been getting ever more programmable - first with ever more powerful vertex and pixel shader instruction sets, and more recently with geometry shaders and tessellation which actually generate new triangles for a scene. As GPUs become more flexible in this way, they begin to be useful for general purpose computations, traditionally the domain of the CPU. On the flip side, every year, CPU vendors are cramming in more and more cores capable of high performance vector processing. Chips such as Intel's forthcoming Larabee are designed around the idea of purely programmable software rendering on hardware with a massive number of cores.</div><div><br /></div><div>Back in the here-and-now however, O3D will automatically switch to using SwiftShader if the hardware renderer on the end-user's system doesn't have enough oomph. Although content developed for O3D should just work regardless of whether the rendering occurs in hardware or in SwiftShader, it's important for developers to test how their O3D content will run on different configurations. Ideally, this includes testing content on different 3D hardware configurations as well as testing software rendering.</div><div><br /></div><div>Note that on MacOS X and Linux, O3D uses OpenGL, so software rendering works differently. On the Mac, the underlying OpenGL implementation will automatically switch to it's own built-in software rendering if the feature you are trying to use is not available. On Linux, you can install the Mesa driver to switch your computer to use software rendering.</div></div>Unknownnoreply@blogger.com5tag:blogger.com,1999:blog-638236749302186936.post-32496720372021661422009-08-11T15:57:00.000-07:002020-07-15T16:49:44.771-07:00Shadow Mapping in O3D<p><br />Adding shadows to a scene can profoundly improve the illusion of 3D. Shadow mapping is an algorithm which provides the basis for many techniques for hardware-accelerated shadows. It works by rendering the scene in two passes. The first pass renders from the perspective of the light to create an offscreen, grayscale image called the <i>shadow map</i> (see figure below, left). The shade of gray at each pixel represents the distance from the light to the rendered point. In principle, if an object is illuminated by the light, it should get drawn in front in the shadow map. The pixel shader in the second render pass samples the shadow map to determine if a point is in shadow. For each point that is rendered, the shader computes the location where that point would appear in the shadow map, samples the shadow map there, and then compares the distance encoded in the shadow map to the point's actual distance from the light. If the point's distance from the light is quite a bit bigger than the distance encoded in the map, then the point is assumed to be in shadow (see figure below, right).</p><br /><br /><table border="1" bordercolor="#000000" cellpadding="1" cellspacing="10"><tbody><tr><td width="50%"><br /><center><br /><img src="http://o3d.googlecode.com/svn/trunk/blog/assets/shadow-map/shadow.png" /><br /></center><br /></td><td width="50%"><br /><center><br /><img src="http://o3d.googlecode.com/svn/trunk/blog/assets/shadow-map/color.png" /><br /></center><br /></td></tr><tr><td width="50%">The shadow map, which is rendered to a texture and used in lighting calculations to produce the effect of shadows in the scene. This scene is rendered from the perspective of the light. (In the example, you can view this rendering by pressing the Spacebar.)</td><td width="50%">Transform graph rendered using the shadow map.<br /></td></tr></tbody><br /></table><br /><br /><h2>The Render Graph</h2><p>In O3D, the two passes required to perform shadow mapping are brought about using a custom <a href="http://code.google.com/apis/o3d/docs/rendering.html" title="o3d docs: Rendering">render graph</a>. The render graph needs two subtrees, one to render the shadow map to a texture, and one to render the scene. In the <a href="http://code.google.com/apis/o3d/docs/samplesdirectory.html#shadowmap" title="Shadow map sample code.">shadow map sample code</a>, the render graph root has two children, each the root of a subtree. The root of the shadow pass subtree is given lower priority so that it is traversed first. Below that, there is a <code>renderSurfaceSet</code> node. That <code>renderSurfaceSet</code> node becomes the root of a standard render graph created using <code>o3djs.rendergraph.createBasicView()</code>. The subtree for the second render pass (referred to as the "color" pass in the code) is created with a second call to <code>o3djs.rendergraph.createBasicView()</code>. Each pass has its own <code>DrawContext</code> object, so the model-view and projection matrices for the shadow pass can be set to render from the perspective of the light. The figure below shows the structure of the render graph in this sample.</p><br /><br /><img width=100% src="http://o3d.googlecode.com/svn/trunk/blog/assets/shadow-map/rendergraph.gif" /><br /><br /><p>In the sample, when the user hits the space bar, the <code>toggleView()</code> function rearranges the render graph to draw the shadow map to the screen. This works by disconnecting the shadow pass subtree from the <code>renderSurfaceSet</code> and reconnecting it to the render graph root, as shown in the figure below. Without the <code>renderSurfaceSet</code> above it, the shadow pass draws to the screen instead of rendering to texture.</p><br /><br /><img src="http://o3d.googlecode.com/svn/trunk/blog/assets/shadow-map/spacerendergraph.gif" /><br /><br /><h2>Materials</h2><p>Each primitive in the scene has two draw elements, one to render with the Phong-shaded, shadowed material in the second pass, and one to render in gray to make the shadow map. The first draw element is added when the utility function in <code>o3djs.primitives</code> creates the shape.</p><br /><pre class="prettyprint">// A red phong-shaded material for the sphere.<br />var sphereMaterial = createShadowColorMaterial([0.7, 0.2, 0.1, 1]);<br /><br />// The sphere shape.<br />var sphere = o3djs.primitives.createSphere(<br />g_pack, sphereMaterial, 0.5, 50, 50);</pre><br /><p>As the shapes in the scene are added to the transform graph, they are each equipped with the <code>DrawElement</code> for the shadow pass.</p><br /><pre class="prettyprint">transformTable[tt].shape.createDrawElements(g_pack, g_shadowMaterial);<br /></pre><br /><br /><h2>Shaders</h2><p>Recall that the material used when rendering the scene for the shadow pass colors each pixel with that point's depth from the perspective of the light. To do this, the shader simply multiplies the position by the view-projection matrix for the view from the light. For efficiency, the multiplication is performed in the vertex program. This works fine, provided that the coordinates that are interpolated to produce the input to the pixel program are homogeneous.</p><br /><pre class="prettyprint">output.position = mul(input.position, worldViewProjection);<br />output.depth = output.position.zw;</pre><p>In O3D, the <i>z</i> coordinate of the position in the light's clip-space ranges from 0 to 1, so the pixel program puts in the red, green, and blue channels to produce a shade of gray.</p><br /><pre class="prettyprint">float t = input.depth.x / input.depth.y;<br />return float4(t, t, t, 1);</pre><br /><p>The shader for the color pass is a modified Phong shader. This shader computes a coefficient called <code>light</code> that captures whether the currently rendered point is illuminated or in shadow. To appeal to the shadow map, the shader needs a texture sampler parameter for the map itself. It also needs the view-projection matrix for the light's point of view so it can compute where to sample.</p><br /><pre class="prettyprint">float4x4 lightViewProjection;<br />sampler shadowMapSampler;</pre><br /><p>Again, for efficiency, the vertex program performs the matrix multiplication to convert to the light's clip space.</p><br /><pre class="prettyprint">output.projTextureCoords = mul(input.position, worldLightViewProjection);</pre><br /><p>The pixel shader converts the position of the currently rendered point from homogeneous coordinates to literal coordinates by dividing by <i>w</i>. Then to sample the texture in the right spot, clip-space <i>x</i> and <i>y</i> coordinates (which range from -1 to 1) are converted to fit the range from 0 to 1.</p><br /><pre class="prettyprint">projCoords.xy /= projCoords.w;<br />projCoords.x = 0.5 * projCoords.x + 0.5;<br />projCoords.y = -0.5 * projCoords.y + 0.5;</pre><br /><p>Finally, the depth of the current point is compared to the depth in the shadow map to determine if the point is illuminated.</p><br /><pre class="prettyprint">float light = tex2D(shadowMapSampler, projCoords.xy).r + 0.008 > depth;</pre><br /><h2>Further Optimizations</h2><p>A number of more advanced variants on the basic shadow map algorithm exist which improve the appearance of the shadows. A simple modification that would help would be to super-sample the shadow map to antialias the shadows' edges. Also, the render graph can be restructured to gain a little extra speed. For convenience, the two subtrees of the render graph in the sample code are generated using the utility function <code>o3djs.rendergraph.createBasicView()</code>, but that function generates all the nodes that are needed to put something on the screen and not all those nodes are necessary in both subtrees. In particular, the tree traversal only needs to happen once, since elements using a particular material only get added to the draw lists associated with that material. We intend to add more functions to o3djs which make it convenient to add shadows to a scene, but because the complexity of geometry and desired shadow effects are so varied, it is difficult to provide a shadow solution that works in all situations. The goal of the shadow map sample is to provide a starting point. To add shadows to an existing scene, we recommend adding to the render graph to include a shadow pass, mimicking the structure of the render graph in the sample, and then fine tuning the shaders in the scene to get the effect required.</p><br /><br /><span class="post-author">Posted by Peterson Trethewey, O3D Team</span>Unknownnoreply@blogger.com4tag:blogger.com,1999:blog-638236749302186936.post-40102689746349993282009-08-10T12:17:00.000-07:002020-07-15T16:49:44.847-07:00O3D Release 0.1.40.1Today, we're releasing version 0.1.40.1 of the O3D plugin. If you've already installed O3D, you'll receive the updated version automatically sometime later today. If you can't wait to try out the new features, just go over to our <a href="http://code.google.com/apis/o3d">main site</a> and download the plugin again. Here's a list of what's changed since our last release:<br /><br /><b>Bug Fixes</b><br /><ul><li>Added support for XP64 and Windows7. </li><li>Fixed keys not working in o3dPingPong sample when O3D area had focus. </li><li>Fixed Tar code to support long filenames. </li><li>Fixed Mac install issue that caused Firefox to think an old version was installed. </li><li>Improved performance for dynamic texture setting. </li><li>Fixed interference between the embedded V8 engine and non-O3D related scripts (like Google Analytics) on a page. o3djs now only pulls scripts marked with id="o3dscript" into V8. </li><li>Fixed a bug with nested RenderSurfaceSet objects. </li><li>Fixed beach demo scrollwheel and initialization bugs. </li></ul><br /><b>Other plugin changes<br /><ul><li><span class="Apple-style-span" style="font-weight: normal;">Added support for ParamArray in shaders.</span></li><li><span class="Apple-style-span" style="font-weight: normal;">Added support for indexed .png loading.</span></li><li><span class="Apple-style-span" style="font-weight: normal;">Improved click event handling.</span></li><li><span class="Apple-style-span" style="font-weight: normal;">Added documentation for <a href="http://src.chromium.org/viewvc/chrome/trunk/src/o3d/serializer/cross/README.txt">binary file formats</a>.</span></li><li><span class="Apple-style-span" style="font-weight: normal;">Added <a href="http://code.google.com/apis/o3d/docs/reference/classo3d_1_1_o3d.client_ref.html"><span class="Apple-style-span" style="font-family:'courier new';">client.clientInfo</span></a>.</span></li><li><span class="Apple-style-span" style="font-weight: normal;">Added <a href="http://code.google.com/apis/o3d/docs/reference/classo3d_1_1_o3d.paramrendersurface_ref.html"><span class="Apple-style-span" style="font-family:'courier new';">ParamRenderSurface</span> </a>and <a href="http://code.google.com/apis/o3d/docs/reference/classo3d_1_1_o3d.paramrenderdepthstencilsurface_ref.html"><span class="Apple-style-span" style="font-family:'courier new';">ParamRenderDepthStencilSurface</span></a>.</span></li></ul></b><br /><b><a href="http://code.google.com/apis/o3d/docs/samplesdirectory.html">Samples </a>changes<br /></b><ul><li>New Samples: <ul><li><a href="http://o3d.googlecode.com/svn/trunk/samples/shadow-map.html">Shadowmap </a></li><li><a href="http://o3d.googlecode.com/svn/trunk/samples/billboards.html">Billboards </a></li><li><a href="http://o3d.googlecode.com/svn/trunk/samples/old-school-shadows.html">Old-School Shadows </a></li><li><a href="http://code.google.com/p/o3d/downloads/list?can=2&q=GoogleIO&colspec=Filename+Summary+Uploaded+Size+DownloadCount">Google I/O 2009 samples </a></li></ul></li><li>Added a Toon Shader example to shader-test sample. </li><li>Sample particle library now supports one-shots and trails. Added examples of particle one-shots and trails to particles sample. </li><li>Picking example now shows the normal of the surface. </li><li>Box2d now uses compiled box2d library. </li><li>Fixed the beach demo to now run in hardware-accelerated mode on additional low-end GPUs by splitting up assets</li></ul><b><div><br /></div>Utilities changes</b><br /><ul><li>Added new methods </li><ul><li>o3djs.element.getNormalForTriangle </li><li>o3djs.material.createConstantMaterial </li><li>o3djs.material.createCheckerMaterial </li><li>o3djs.effect.createCheckerEffect </li><li>o3djs.math.pseudoRandom </li></ul></ul><br /><b>Tools changes<br /></b><ul><li>Fixed issue with multiple embedded shaders in the sample o3dConverter. </li><li>Added --file_paths option to sample o3dConverter to make it easier to convert existing COLLADA files. </li><li>Sample o3dConverter and sample deserializer now separate skinned streams (POSITION, NORMAL, ...) from non-skinned streams (COLOR, TEXCOORD). </li><li>Sample o3dConverter will by default mark any primitive with no normals to request a constant shader. This fixes the issue with SketchUp models getting an error of missing NORMAL stream. </li></ul>Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-638236749302186936.post-76295447173150015692009-07-31T12:00:00.000-07:002020-07-15T16:49:45.029-07:00See you at SIGGRAPH 09 in New Orleans!SIGGRAPH 2009 is starting on Monday in New Orleans, LA. Google will have a booth in the exhibition hall showcasing its latest graphics technologies including O3D. I'll be hanging out at the O3D demo station in the booth where I'll be running live demos off the web and be around to answer questions. The exhibition is open from Tuesday through Thursday of the conference. So if you're attending the conference, stop by and say hi -- Google is right in the middle between Halls F and G.<br /><br />While you're visiting the Google booth, you can also check out our other demos. We'll be showing Click2Go which uses a 3D aware cursor to allow you to more smartly navigate while in StreetView. You can play with SketchUp to make a model and then bring it into O3D. And you can feel like you're flying at the Google Earth demo which we'll be showing on a 56" 8 megapixel flat panel.<br /><br />I'll also be doing a demo at the Blender booth on Wednesday afternoon from 3-4pm showing how you can bring models from Blender and other programs into O3D. <br /><br />I'm pretty excited about the conference this year. The lineup of speakers, talks and courses looks fantastic. I'm looking forward to some of the real-time graphics talks and game papers, in particular. And of course, I'm also looking forward to getting some authentic Creole food while I'm in town!<br /><br /><span class="post-author">Posted by Rachel Weinstein Petterson, O3D Team</span>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-638236749302186936.post-72689778466235118022009-07-01T18:54:00.000-07:002020-07-15T16:49:44.977-07:00Improving O3D's hardware compatibilityWe stated before that one of the goals for O3D is to have no caps bits. That means, not having to make your code check if the user's machine has feature X: You can write your application and you can assume it will run on any machine. We also wanted to select a feature set that we thought would be a good trade off between allowing high end real time 3d graphics and running on the majority of machines currently in use without being too slow.<br /><br />Unfortunately, there are a few extremely popular GPU chipsets out there, like the Intel 950 for example, that were missing a couple of these base features we felt were important. Without those features certain common effects, like floating point textures for shadows, would not be possible. We could have just used the software renderer on machines without those features but the software renderer is not as fast as GPU hardware so we came up with what we think is a reasonable solution.<br /><br />When your application starts up O3D, it can tell O3D what features the application requires. If the user's system supports those features then O3D will use them. If the user's machine does not support those features O3D will fall back to a software renderer. If you do not explicitly request those features then O3D will not let you use them.<br /><br />We chose this solution because it provides the ability for a much wider range of applications to use GPU hardware than before. For example, only 3 of our samples required additional features to be available, which means most of the samples will run with GPU hardware acceleration even on low-end GPU hardware. <br /><br />The specific features you can request are:<br /><ol><li>Floating Point Textures.</li><li>Geometry with more than 65534 vertices.</li></ol> <br />If you are using our sample utility libraries, the second argument to o3djs.util.makeClients is now a comma separated list of features you want. For example:<br /><pre class="prettyprint">o3djs.util.makeClients(initStep2, 'FloatingPointTextures');</pre><br />will request floating point texture support for your application.<br /><br />If you dig into our samples you'll notice this is only used in 3 of our samples so far.<br /><ol><li>generate-textures.html uses floating point textures.</li><li>vertex-shader.html geometry with more than 65534 vertices.</li><li>The beach demo because it uses geometry with more than 65534 vertices.</li></ol><br />For those last 2 samples, we could have avoided requesting those features if we wanted to. For example, in the case of vertex-shader.html we could just slightly lower the resolution of the plane that it animates. For the beach demo we could split any models with more then 65534 vertices in half and draw the 2 halves separately. This shows that many applications do not need those features or can be refactored to not need them and so a very large percentage of O3D applications can run using hardware accelerated graphics. Higher end applications that need those features can request them and they'll still run everywhere, but for applications that don't they'll be able to use hardware acceleration on a much much larger set of computers.<br /><br />One question that is likely to come up is, "Could this solution be used to add really high end features like Shader 4.0?". The current answer is unfortunately "no". The reason is, if the user's machine doesn't have those features O3D uses a software renderer. Unfortunately we don't have access to a software renderer that could draw Shader 4.0 features at a reasonable speed.<br /><br />We hope you'll agree that getting hardware acceleration on as many machines as possible is as awesome as we think it is. This change helps O3D run its best on a much larger set of computers.<br /><br /><span class="post-author">Posted by Gregg Tavares, O3D Team</span>Unknownnoreply@blogger.com9tag:blogger.com,1999:blog-638236749302186936.post-51124390906997711942009-06-29T18:22:00.000-07:002020-07-15T16:49:44.873-07:00O3D Update: New features and expanded compatibilityWe're happy to announce that today we shipped a substantial update to <a href="http://code.google.com/apis/o3d" id="dhvf" title="O3D">O3D</a>, an API for creating rich 3D applications in a web browser. With today's release, we focused on addressing a theme we heard in the requests and feedback from the community: that O3D should run as well as possible on many different types of hardware. Toward that end, we're releasing two new additions: software rendering and <a href="http://code.google.com/apis/o3d/docs/performance.html#gpuhardware" id="h.1q" title="feature requirements">feature requirements</a>. If you've already installed the O3D plugin, you should receive these additions automatically.<br /><br /><div> Software rendering allows O3D to use the main processor to render 3D images if the machine running the app doesn't have supported graphics hardware. While the hardware O3D requires to run in hardware-accelerated mode is fairly modest by today's standards (a DirectX 9, Pixel Shader 2.0 capable graphics card), there are nonetheless PCs that don't meet these requirements, and we think it's important for web apps to run on all machines, regardless of hardware. </div> <div><br /></div> <div> Because software rendering is significantly slower than hardware-accelerated rendering, we're also introducing a concept called "<a id="l8bu" title="feature requests">feature requirements</a>" that will help minimize how often O3D will have to fall back to software rendering. Feature requirements allow developers to state upfront that their app will require certain hardware capabilities to render properly. If the machine running the app supports those features, O3D will run it fully hardware accelerated; if however, it is lacking any of the required capabilities, O3D will drop into a software rendered mode. Anecdotally, we found that this tiering allows 45 of our 48 samples to now run in hardware-accelerated mode with less capable graphics cards. </div> <div><br /></div> Finally, while it has nothing to do with extending hardware support, we're also adding a couple other goodies: a <a href="http://code.google.com/apis/o3d/docs/fullscreen.html" id="owmp" title="full-screen mode">full-screen mode</a> to make O3D apps more absorbing and a <a href="http://code.google.com/apis/o3d/docs/gallery.html" id="xjw6" title="Community Gallery">community gallery</a> to feature cool demos that use O3D (like <a href="http://blog.largeanimal.com/" id="py8e" title="Infinite Journey">Infinite Journey</a>, the first game developed outside Google using O3D). If you've developed an application or sample that would be useful to the O3D community, please be sure to submit it for our team to review for inclusion in the gallery using <a href="http://spreadsheets.google.com/viewform?key=rmM9ht25mcbJ0uXsFstgmCQ&hl=en" id="yi65" title="this form">this form</a>.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_F167H0-0MUg/SklpxHTJoxI/AAAAAAAAAAs/gVVRuNOXRnM/s1600-h/cg4trxrp_10gv5k75dp_b.jpg"><img style="cursor: pointer; width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_F167H0-0MUg/SklpxHTJoxI/AAAAAAAAAAs/gVVRuNOXRnM/s320/cg4trxrp_10gv5k75dp_b.jpg" alt="" id="BLOGGER_PHOTO_ID_5352925924600423186" border="0" /></a><br /><br /><span class="post-author">Posted by Henry Bridge, O3D Team<br /></span>Unknownnoreply@blogger.com4tag:blogger.com,1999:blog-638236749302186936.post-57145691993468959482009-06-24T16:24:00.000-07:002020-07-15T16:49:44.899-07:00Dealing with Asynchronous JavaScriptI'm sure many of you reading this are JavaScript experts but I'm sure some of you, like me, might have lots of graphics experience with C or C++ but not so much with JavaScript. This post is about one of the things that is different about JavaScript that I needed to learn as an experienced programmer in other languages.<br /><br />First, I highly recommend you get the book, <a title=""JavaScript: The Good Parts" by Douglas Crockford" href="http://www.google.com/search?q=javascript+the+good+parts+Douglas+Crockford">"JavaScript: The Good Parts" by Douglas Crockford</a>. It's a book that really changed my mind about JavaScript and has showed me how to use it much more effectively.<br /><br />As O3D is a JavaScript based API for the browser, there are many times when one needs to do asynchronous calls to some function. A good example is when you load a 3d scene. You call loadScene, and when the scene has finished loading some moments later, it calls a callback you specify. In C++, these types of functions usually have a parameter for you to pass in some kind of user data that will then be passed to your callback. That way you can associate something with each call. JavaScript APIs don't generally have that user data concept. The reason is, they don't need it. Here's why:<br /><br />First off, unlike C or C++, JavaScript does not define scope with braces. To see what I mean check out the following code.<br /><pre class="prettyprint">function someFunc() {<br /> {<br /> var foo = 123;<br /> }<br /> {<br /> console.log("foo = " + foo);<br /> }<br />};</pre><br />To a C++ programmer that looks like it has 3 scopes. The scope of the function, "someFunc", the scope surrounding the declaration of "foo", and the scope printing the result. (*) As such, in C++ that code would fail to compile because foo does not exist when it gets to the line to print it. In JavaScript though this is perfectly valid code because, as I mentioned, JavaScript does not use braces to define scope.<br /><br />Instead, JavaScript uses functions to define scope so foo is visible inside someFunc but it is not visible outside of someFunc.<br /><br />Functions can see the scopes above them so for example look at the code below:<br /><pre class="prettyprint">function someFunc() {<br /><br /> var foo = 123;<br /><br /> function innerFunc() {<br /> console.log("foo = " + foo);<br /> }<br /><br /> innerFunc();<br />};</pre><br />In this code, someFunc has an inner function called "innerFunc" and innerFunc can see the variable foo. Pretty straight forward.<br /><br />Here is where the magic comes in and points out a big difference between JavaScript and C++.<br /><pre class="prettyprint">function someFunc() {<br /> var foo = 123;<br /> <br /> function innerFunc() {<br /> console.log("foo = " + foo);<br /> }<br /><br /> return innerFunc;<br />}</pre><br />This version of someFunc does not print anything. Instead it returns a function that prints something. To see it print, you have to call the function it returns. If you look at the code you'll see innerFunc prints the value of "foo" but foo is declared outside of its scope. If you tried this in C++, assuming you could make it compile, your function would crash because foo would get destroyed when someFunc returned. JavaScript on the other hand doesn't work like that. This code will work just fine. You would use it like this:<br /><pre class="prettyprint">var functionReturnedBySomeFunc = someFunc();<br /><br />// call the function returned by someFunc<br />functionReturnedBySomeFunc();</pre><br />someFunc returned a function which is stored in a variable and then that function is called.<br /><br />What is this good for? Well, it's great for asynchronous callbacks like o3djs.scene.loadScene because the callback you pass in will retain knowledge of the things that were in its scope when it was defined. For example: <br /><pre class="prettyprint">// A constructor for a MyObject<br />function MyObject(client, viewInfo) {<br /> this.client = client;<br /> this.viewInfo = viewInfo;<br /> this.pack = client.createPack();<br /> this.transform = this.pack.createObject('Transform');<br />};<br /><br />MyObject.prototype.loadScene = function(url) {<br /> // declare a local variable so inner functions can see it.<br /> var that = this; <br /><br /> // An inner function that loadScene will call on completion.<br /> function loadCallback(pack, parent, exception) {<br /> if (!exception) {<br /> // you can reference the particular MyObject through<br /> // the "that" variable implicitly.<br /> that.initScene();<br /> }<br /> }<br /><br /> // load the scene.<br /> o3djs.scene.loadScene(<br /> this.client,<br /> this.pack,<br /> this.transform,<br /> url,<br /> loadCallback);<br />};<br /><br />MyObject.prototype.initScene = function() {<br /> o3djs.pack.preparePack(this.pack, this.viewInfo);<br />};</pre><br />You can use MyObject like this:<br /><pre class="prettyprint">var obj = new MyObject(client, viewInfo);<br />obj.loadScene('http://someplace.com/somemodel.o3dtgz');</pre><br />As you can hopefully see, unlike C++, we didn't need a special user data parameter to make loadScene useful. JavaScript makes it easy for us to allow the callback to have as much or as little access to other data as it needs.<br /><br />If you're new to JavaScript I hope that's a useful example. It can take a little while to get used to a new language but every language has its strengths.<br /><br />(*) console.log is something that only works on Safari, Firefox and Chrome when the debugger is running. It is non-standard JavaScript but helped to make these examples clearer.<br /><br /><span class="post-author">Posted by Gregg Tavares, O3D Team</span>Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-638236749302186936.post-90722690940524715092009-06-11T14:36:00.000-07:002020-07-15T16:49:45.182-07:00We are live<div>If you've been looking at our code repository history at all, you might be forgiven for assuming that Antoine and I are the only ones who work on O3D code, and that we're really sporadic about when we submit code (but look at how much we get done!).</div><div><br /></div><div>Since our launch, we've been syncing our internal repository intermittently with the public <a href="http://code.google.com/p/o3d">Google Code repository</a> while we made the transition to some new tools and did some rearranging. Now that transition is complete.</div><div><br /></div><div>The plan for O3D in the near future is to become more closely integrated into Chromium (while continuing to support plugins for other browsers). To make this integration easier, our code now has a new home in the Chromium.org Subversion repository. From now on, we're going to stop doing merely intermittent pushes and just do our daily work directly on the public repository, so you'll get to see all the changes as they happen, and you can follow along (and maybe now you'll see some other developers do some work! Or maybe you'll be one of those developers! ).</div><div><br /></div><div>If you want to download the O3D source, or have downloaded it in the past, you'll want to use the Chromium server by following our <a href="http://code.google.com/p/o3d/wiki/HowToBuild">updated build instructions</a>. Don't worry, you don't need to download all of Chromium to build O3D.</div><div><br /></div><div>We will continue to use our current <a href="http://code.google.com/p/o3d/issues/list">issue tracker</a> on the code.google.com site to track and log bugs and feature requests so you can see if they are being worked on, or pick one out to work on yourself.</div><div><br /></div><div>If you've been itching to fix one of those bugs, you can now submit patches to our source using the same process that Chromium developers use. Look at the Chromium <a href="http://dev.chromium.org/developers/contributing-code">guidelines for patch submission</a> if you're interested in contributing. Some things, like the buildbots, aren't set up for O3D yet, but will be available in the future. The reviewer mailing list for o3d is <a href="mailto:o3d-review@googlegroups.com">o3d-review@googlegroups.com</a>, if you are looking for a reviewer.</div><div><br /></div><div>The code on the <a href="http://code.google.com/p/o3d">Google Code site</a> will be available for some time to come, but will not be updated, and eventually we'll just redirect visitors directly to the Chromium repository. It currently contains the latest code as of Friday May 29th.</div><div><br /></div><div>The API documentation will remain <a href="http://code.google.com/apis/o3d/docs">where it is</a>.</div><div><br /></div><div>Enjoy!</div><div><br /></div><div>Posted by Greg Spencer, Senior Software Engineer</div>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-638236749302186936.post-89141671068722155012009-06-11T01:44:00.000-07:002020-07-15T16:49:45.156-07:00O3D at Google I/O 2009 Part 2After we introduced O3D to the world in April this year, we were eager to present rich 3D web applications created with O3D. Two weeks ago, at Google I/O, we presented and demoed O3D based apps by Disney/ABC, Large Animal and Crazy Pixel Productions. We could not be more proud of what they created and showed off at Google I/O.<br /><br />At Google I/O, we also had a chance to interview representatives from these companies and learn more about them and their experiences with O3D. In the interviews, they talked more about their 3D projects with O3D and where the projects are heading, shared feedback they got from I/O attendees at the Developer Sandbox pods, and also shared their thoughts about Google I/O.<br /><br />1) Crazy Pixel Productions<br /><object width="560" height="340"><param name="movie" value="http://www.youtube.com/v/Y_WQ1sLC6ok&hl=en&fs=1&"><param name="allowFullScreen" value="true"><param name="allowscriptaccess" value="always"><embed src="http://www.youtube.com/v/Y_WQ1sLC6ok&hl=en&fs=1&" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="560" height="340"></embed></object><br /><br />Crazy Pixel Productions, a full service 3D animation and game development studio, built the O3D beach demo (<a href="http://o3d.googlecode.com/svn/trunk/samples/beachdemo/beachdemo.html">demo here</a> or <a href="http://www.youtube.com/watch?v=uofWfXOzX-g">video here</a>), and is developing a 3D Tower Defense game.<br /><br />2) Disney / ABC Television Group<br /><object width="560" height="340"><param name="movie" value="http://www.youtube.com/v/vI5XcWax4QQ&hl=en&fs=1&"><param name="allowFullScreen" value="true"><param name="allowscriptaccess" value="always"><embed src="http://www.youtube.com/v/vI5XcWax4QQ&hl=en&fs=1&" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="560" height="340"></embed></object><br /><br />Disney / ABC Television Group Digital Media introduced Visual Search Interface (<a href="http://developer.abc.com/app/vsi">app here</a> or <a href="http://www.youtube.com/watch?v=k0tzZiTXEB8">video here</a>), an engaging 3D based application to both visually search and navigate through ABC's online catalog of video content.<br /><br />3) Large Animal Games<br /><object width="560" height="340"><param name="movie" value="http://www.youtube.com/v/Wxo54Airv20&hl=en&fs=1&"><param name="allowFullScreen" value="true"><param name="allowscriptaccess" value="always"><embed src="http://www.youtube.com/v/Wxo54Airv20&hl=en&fs=1&" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="560" height="340"></embed></object><br /><br />Large Animal Games, a developer/publisher of social games for casual gamers developed and presented Infinite Journey (<a href="http://blog.largeanimal.com/demo/">demo here</a> or <a href="http://www.youtube.com/watch?v=NAgug5D6Kdg">video here</a>), a 3D online platformer game that will ultimately be integrated with social networks.<br /><br />We are looking forward to seeing more exciting 3D web applications and services based on O3D in the future. To learn more about O3D's presence at Google I/O, please read our previous blog post, <a href="http://o3d.blogspot.com/2009/06/o3d-at-google-io-2009.html">O3D at Google I/O 2009</a>. Thank you.<br /><br />Posted by Mickey Kim, New Business Developer Manager<span class="post-author"><br /></span>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-638236749302186936.post-3508511742073929022009-06-02T20:17:00.000-07:002020-07-15T16:49:44.797-07:00O3D at Google I/O 2009Thank you to everyone who came to our O3D sessions at Google I/O last week! It was exhilarating to get to meet so many people that are passionate about both graphics and the web. We were really happy about both the turnout at our talks as well as the quality of the questions from the audience.<br /><br />For those of you who where unable to join us, here's a quick recap of the O3D activity at I/O:<br /><ol><li>Our very own Matt Papakipos showed off the Beach Demo during the <a href="http://www.youtube.com/watch?v=S5aJAaGZIvk#t=22m58s">first day's keynote</a>, described the technology behind O3D, and talked about how 3D fits into the future open web platform.<br /></li><li>We had a deep dive session on using O3D "<a href="http://code.google.com/events/io/sessions/AddingInteractive3DContent.html">Adding Interactive 3D Content to Your Site</a>". Vangelis Kokkevis gave a architectural overview of O3D and how it compares to other 3D APIs. Gregg Tavares took us through the steps necessary to build a simple game in 20 minutes, from getting an object on the screen to getting an animated robot walking and jumping through an environment. You can <a href="http://o3d.googlecode.com/files/O3D-GoogleIO-2009.zip">download those steps here</a>.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_F167H0-0MUg/SiXuQRbK-tI/AAAAAAAAAAU/8DTMhDWIc6A/s1600-h/DSCF3264.JPG"><img style="cursor: pointer; width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_F167H0-0MUg/SiXuQRbK-tI/AAAAAAAAAAU/8DTMhDWIc6A/s320/DSCF3264.JPG" alt="" id="BLOGGER_PHOTO_ID_5342938496267647698" border="0" /></a><br /><br /></li><li>Three of our partners showed off their wares at the developer sandbox and talked about their experiences building apps at our panel session, "<a href="http://code.google.com/events/io/sessions/O3DPartners.html">Developing on O3D: A View from the Trenches</a>". ABC/Disney showed off an awesome 3D search visualization (<a href="http://developer.abc.com/app/vsi">app here</a> or <a href="http://www.youtube.com/watch?v=k0tzZiTXEB8">video here</a>); Crazy Pixel Productions talked about their experience building the O3D Beach Demo and an upcoming <a href="http://www.youtube.com/watch?v=G_D-Lcikx7g">Tower Defense game</a>; and Large Animal Games demoed a beautiful and addictive platformer game that they're working on called "<a href="http://www.youtube.com/watch?v=NAgug5D6Kdg">Infinite Journey</a>". It's exciting to see real apps that use O3D emerge and we're really looking forward to see how they develop!<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_F167H0-0MUg/SiXuhSuO5_I/AAAAAAAAAAc/n15boV95iXY/s1600-h/DSCF3266.JPG"><img style="cursor: pointer; width: 281px; height: 320px;" src="http://3.bp.blogspot.com/_F167H0-0MUg/SiXuhSuO5_I/AAAAAAAAAAc/n15boV95iXY/s320/DSCF3266.JPG" alt="" id="BLOGGER_PHOTO_ID_5342938788673808370" border="0" /></a><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_F167H0-0MUg/SiXuxouGUII/AAAAAAAAAAk/eqgmTGy6mEk/s1600-h/DSCF3275.JPG"><img style="cursor: pointer; width: 320px; height: 240px;" src="http://4.bp.blogspot.com/_F167H0-0MUg/SiXuxouGUII/AAAAAAAAAAk/eqgmTGy6mEk/s320/DSCF3275.JPG" alt="" id="BLOGGER_PHOTO_ID_5342939069456732290" border="0" /></a><br /></li></ol><span class="post-author">We'll also be posting the slides for these sessions soon, so stay tuned!<br /><br />Posted by Henry Bridge, O3D Team<br /></span>Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-638236749302186936.post-30528526085274657352009-05-26T10:55:00.000-07:002020-07-15T16:49:44.745-07:00A gallery for your samples and applications<div>All of us at the O3D team are very excited to see developers from around the world getting involved in our project. We appreciate the great feedback we have received in the <u><a href="http://groups.google.com/group/o3d-discuss" title="O3D discussion group">O3D discussion group</a></u>, the <u><a href="http://dredwerkz.ic.cz/o3d/techoverview.html" title="translations">translations</a></u> of our documentation into other languages and some of the videos that have been created and posted on YouTube. </div><div><br /></div><div>We are also excited by some of the samples that the community has created. From medieval castles, to medical imagery and dancing teapots, developers have shown a strong interest to experiment with O3D's technology and showcase its potential. To highlight some of this work we are planning to create a small gallery that will feature screenshots and links to the samples and applications that have been created with O3D. </div><div><br /></div><div>To have your apps and samples considered for this new gallery, all you need to do is fill in this <a href="http://spreadsheets.google.com/viewform?key=rmM9ht25mcbJ0uXsFstgmCQ&hl=en" title="form">form</a>. Our engineering team will then select out of all the submissions, those that we think could be of interest to the wider O3D development community. </div><div><br /></div><div>We look forward to seeing your submissions and stay tuned for the gallery coming soon.</div><br /><span class="post-author">Posted by Christos Apartoglou, Product Marketing Manager, O3D Team</span>Unknownnoreply@blogger.com3tag:blogger.com,1999:blog-638236749302186936.post-79717807776190845262009-05-12T17:46:00.000-07:002020-07-15T16:49:45.080-07:00How to find a ModelNo, we're not talking about live models to use in your work, human or otherwise. This is about how to look up a 3D model from a file loaded in O3D.<br /><br />The first thing that should be made clear is that O3D does not directly support loading models. Instead, it provides a framework for you to build your own model loading and we've provided a sample art path to do that. The sample art path is split into 2 parts. The first part, <a title="the o3dConverter" href="http://code.google.com/p/o3d/downloads/list">the o3dConverter</a> takes a collada file and converts it into a gzipped tar file with a JSON file inside describing the scene and other files storing vertices, skinning, animation and textures. The second part is a sample loader in <a title="samples/o3djs/serialization.js" href="http://code.google.com/p/o3d/source/browse/trunk/googleclient/o3d/samples/o3djs/serialization.js">samples/o3djs/serialization.js</a> which loads the JSON file and uses the data inside to recreate the scene in O3D.<br /><br />The important points about that are:<br /><ol><li>They are samples. If you don't like them or your application has different needs then change them. </li><br /><li>They are not directly part of O3D. There is no fixed file format for O3D. If you want to make better exporters that export to a format that matches your application better, you're free to do that. If you have a solution that solves a problem better than collada and our sample format does and you want to load that format, you have the power to do it. In fact, we are really hoping you will, and if we're lucky, you'll make your solutions available to the community.</li><br /><li>There are 4 parts to that entire path: The modeler you use, the exporter you use, the converter you use, the loader you use. You can replace or change any of those 4 parts if they don't meet your needs. It's also important to notice that what you get through our sample art path is dependent on the first 2 parts, the modeler and the exporter. If you have an exporter doing something you'd like done differently you might need to find a new one or write your own. For example, maybe you'd like your exporter to combine hierarchies of models into a single model. Or, maybe you'd like your art path to export things like "shape: {type: 'sphere', radius: '50'}" instead of saving out the mesh for a sphere and you'd like your loader to create spheres at load time when it sees that. More importantly, maybe you'd like to your exporter to export materials as they are in your art tool and then have your loader create materials that match instead of our sample art path which can't do that because it's limited by collada.</li><br /></ol>With that out of the way, let's talk about the sample art path we have provided and how to find a model. If you are not familar with the O3D API it might be good to review the <a href="http://code.google.com/apis/o3d/docs/techoverview.html" title="technical overview">technical overview</a> doc, especially <a href="http://code.google.com/apis/o3d/docs/techoverview.html#whatisscenegraph" title="the part about the scene graph">the part about the scene graph</a>.<br /><br />Assuming you loaded a scene like this:<br /><pre class="prettyprint"> var path = "http://somedomain.com/assets/somescene.o3dtgz";<br /><br /> function loadCallback(pack, parent, exception) {<br /> if (exception) {<br /> alert("Could not load: " + path + "\n" + exception);<br /> } else {<br /> // Scene has been loaded.<br /> }<br /> }<br /><br /> scenePack = client.createPack();<br /> sceneRoot = pack.createObject('Transform');<br /> o3djs.scene.loadScene(client, scenePack, sceneRoot, path, loadCallback);<br /></pre><br />At this point, you can search for models in several ways. Most modeling packages show the name of the transform above a model instead of the name of the model itself. So, if you want to search by transform name there are 2 easy ways:<br /><pre class="prettyprint"> var transforms = scenePack.getObjects("myModel", "o3d.Transform");<br /></pre><br />This searches the entire pack for transforms with the name "myModel".<br /><br />another way is with:<br /><pre class="prettyprint"> var transforms = sceneRoot.getTransformsFromTreeByName("myModel");<br /></pre><br />This searches a sub tree of transforms for transforms with the name "myModel". Both functions return an array of results.<br /><br />Once you have the transforms, you may be able to use them as transforms, or if you want to find the shapes then you can try something like:<br /><pre class="prettyprint"> // assuming you found multiple transforms<br /> for (var ii = 0; ii < transforms.length; ++ii) {<br /> var shapes = transforms[ii].shapes;<br /> // now iterate through the shapes.<br /> for (var jj = 0; jj < shapes.length; ++jj) {<br /> var shape = shapes[jj];<br /> }<br /> }<br /></pre><br />Often, if you are making your own assets, you'll know the exact structure of your scene. For example, if you know there is only 1 transform named "house" and you know there is only one shape under it, you could just do the following:<br /><pre class="prettyprint"> // get the 1 transform we expect.<br /> var houseTransform = scenePack.getObjects("house", "o3d.Transform")[0];<br /> // get the single shape we expect.<br /> var houseShape = houseTransform.shapes[0];<br /></pre><br />On the other hand, if you know the name of the shape itself, you can look for shapes directly. I'm personally more familar with Maya and its default behavior is to automatically name shapes with the suffix "Shape". If you rename a transform to "house", the shape will be renamed "houseShape". In this case, if you know there is only 1 shape named "houseShape" in your scene you can do this:<br /><pre class="prettyprint"> // get the 1 shape we expect.<br /> var houseShape = scenePack.getObjects("houseShape", "o3d.Shape")[0];<br /></pre><br />The next thing to be aware of is that Shapes are made from Primitives. The point of having both Shapes and Primitives is that most modeling packages let you put more than one material on a particular model. For example you could make a house and texture the walls with one material and the roof with a different material. If that was one shape in the modeler, it would load as one shape in O3D with 2 primitives. The sample o3dCoverter takes the names of the materials and appends them to the name of the shape to make the names of the primitives. Assuming the name of the house shape was "houseShape", the primitives will be named "houseShape|roof_material" and "houseShape|wall_material".<br /><img src="http://o3d.googlecode.com/svn/trunk/blog/assets/how-to-find-a-model/houseshape-primitives.gif"/><br />Primitives can be found similarly to how we found previous objects.<br /><pre class="prettyprint"> // get the 1 primitive we expect.<br /> var housePrimitives = <br /> scenePack.getObjects("houseShape|roof_material", "o3d.Shape")[0];<br /></pre><br />Or probably more useful, assuming we have already found the shape for the house following the methods above we can use:<br /><pre class="prettyprint"> var housePrimitives = houseShape.elements;<br /> for (var ii = 0; ii < housePrimitives.length; ++ii) {<br /> var primitive = housePrimitives[ii];<br /> ...<br /> }<br /></pre><br />I hope this makes things a little clearer. It would be <i>really</i> awesome if some of you will take up the challenge and go off and make some improved exporters, better converters and better loaders that provide even more solutions. We've heard from the community that a custom Blender exporter is being worked on. We'd love to see exporters for other modeling packages that take advantage of the specific strengths and features of those packages.<br /><br />If there is anything you'd like to us to post about or other questions you have please join us in the <a href="http://groups.google.com/group/o3d-discuss" title="o3d discuss group">o3d discuss group</a>. We really appreciate your ideas and feedback.<br /><br /><span class="post-author">Posted by Gregg Tavares, O3D Team</span>Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-638236749302186936.post-69505857551180558632009-05-07T13:26:00.000-07:002020-07-15T16:49:44.952-07:00Why the change from .tgz to .o3dtgz?We recently released an update to O3D with quite a few bug fixes. One of the issues that came up just after launch made us to change the default file extension used by our samples. Originally our samples used a file extension of ".tgz". This caused an issue with overly helpful web servers.<br /><br />The issue was that some web servers are configured to notice if a file has the extension ".tgz" and if so they do special processing. They assume the file is a pre-compressed gzipped file and they negotiate with the browser on how to send it. <br /><br />For some browsers the browser says to the server, "I understand gzipped files so send it to me compressed and I'll uncompress it". The problem when that happens is the browser doesn't tell O3D the size of the file before the download starts and so there is no way for O3D to supply progress information.<br /><br />For other browsers the browser says to the server, "I don't understand gzipped files" and so the server decides to helpfully uncompress it and send the uncompressed data over the internet. The problem with that is the whole point of compressing it in the first place was to make it download faster.<br /><br />One solution is to reconfigure your server to not do that. Unfortunately that's not always easy. Maybe you do actually want your server to do that for some files, just not files needed by O3D. On top of that, many users don't have direct access to the servers they put their content on, so, reconfiguring the server is probably out of the question.<br /><br />The easier solution was to rename the files to something that doesn't end with ".tgz". This seemed to solve the problem on most of the servers we tried.<br /><br />Truthfully, O3D doesn't care what the file extension is. If you want to name your files with ".foo" or ".bar" or ".myappscene" or with no extension any of those are fine. We could have left the extension as ".tgz" and just told people, who ran into the issue mentioned above, to rename their files but it seemed better to us to just make the default something else and therefore save a large number of people the frustration.<br /><br />The point we want to make clear though is that ".o3dtgz" is not a new file format. We are not defining a file format for O3D as mentioned by several of our blog posts. See <a title="Why JSON Rulez" href="http://o3d.blogspot.com/2009/04/why-json-rulez.html" id="u4r8">Why JSON Rulez</a> for a few good reasons.<br /><br />We hope that clears up the mystery.<br /><br /><span class="post-author">Posted by Gregg Tavares, O3D Team</span>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-638236749302186936.post-87153736831013902562009-05-06T19:43:00.000-07:002020-07-15T16:49:45.106-07:00O3D plugin update<div>Hard to believe that it's been already two weeks since O3D shipped! We are all very excited to see how many of you took interest in it. Many thanks for all the great feedback you've been sending us, for the kind words of encouragement but also for raising your concerns and asking the tough questions. They are all very welcome, please keep them coming.</div><div><br /></div><div>So, what have we been doing in the meantime? Well, after a bit of well deserved rest and a decent night of sleep, we're back to coding. We're happy to announce that today we're pushing out an update to O3D. There are no API changes in this release and no functionality has been added or removed. We mostly wanted to address some of the issues that you folks discovered when you first tried O3D out and correct some of the more glaring problems, at least the ones that we could fix in this short period of time.</div><div><br /></div><div>Those of you who have already installed O3D will get the update automatically sometime later today. If you simply cannot wait, just go over to our main page and download the plugin again. Here's a list of what changed from our initial release:</div><div><br /></div><div><b>Release Notes for Rel 0.1.35.2:</b></div><div>Bug Fixes:</div><div><ul><li>Fixed touchpad scrolling for mac Safari 4. </li><li>Fixed mac bug that would crash the plugin when a tab is dragged out of the browser in Safari.</li><li>Mouse wheel events now return client-area-relative mouse coordinates.</li><li>Fixed a problem on the mac where the O3D window would hover over other HTML elements in certain instances.</li><li>Fixed a bug that prevented the O3D plugin from unloading in IE. </li><li>Assorted crash bug fixes.</li><li>[Installer] Display an actual visible error message when O3D fails to install for lack of DirectX 9.0c.</li><li>[Installer] Mac installer now explicitly checks for OSX version 10.5 (Leopard) and refuses to install on earlier versions.</li></ul></div><div><br /></div><div>Other plugin changes:</div><div><ul><li>Added missing sampler addressModeW setting.</li><li>Upgraded the embedded V8 to the latest version from Chromium. This should provide even better performance and likely fix some crash bugs too.</li></ul></div><div><br /></div><div>Samples/Utilities changes:</div><div><ul><li>[Samples] Improved performance of PrinceIO. The sample was previously hardcoded to run at 20fps. (pick refresh to make sure your browser is not caching old files)<br /></li><li>[Samples] Several improvements to the beach demo including:<ul><li>The ocean and the island now display the correct textures and have shaders that mix between 2 textures based on vertex alpha.</li><li>There is an animated camera.</li><li>There is a proxy island that loads quickly before the detailed island loads.</li><li>3D oriented particles are used at the bottom of the waterfalls.</li></ul></li><li>[Utilities] o3djs/shape.js is now split into two files, shape.js and element.js</li><li>[Utilities] o3djs/quaternions.js: Changed quaternion representation from [w, x, y, z] to [x, y, z, w] (scalar part, w, is now the fourth component).</li><li>[Utilities] Added 3D particles to particle.js and the sample, particles.html.</li><li>[Utilities] Fixed bugs in effects.js related to making shaders for normal mapped assets.</li><li>[Utilities] o3djs/debug.js: Added createSphere and createCube utilities to let you create those in arbitrary space.</li><li>[Utilities] o3djs/math.js: Added method to create a 4-by-4 perspective transformation given a set of clipping planes.</li><li>[Utilities] o3djs/math.js: Added aliases for inverse, multiply and the determinant of 4-by-4 matrices.</li></ul></div><div>Tools changes:</div><div><ul><li>Removed performance timer output from the o3dConverter.</li><li>Added o3dVerifier, a tool that test-compiles the contents of a shader (.fx) file and converts it into the shader format accepted by O3D.</li><li>Fixed o3dConverter to return all the mesh streams found in the Collada file.</li><li>Fixed od3Converter to better handle local paths to shader files in the archive.</li><li>Changed the default extension to asset files generated by the o3dConverter from .tgz to .o3dtgz to avoid issues on certain server configurations (blog post with details to follow).</li></ul></div><div><br /></div><div>You should expect that updates like this one will take place with some frequency as we continue working with the code. In case you are wondering why you don't see individual checkins in our opensource subversion repository, let me assure you that this will change very soon. We are in the process of completely switching over from our internal Perforce repository to subversion. Once we fully transition our auto-build system to using the subversion tree, we'll be doing all our development out in the open. This has been our intention all along. Stay tuned! </div><div><br /></div><br />Posted by Vangelis Kokkevis, O3D TeamUnknownnoreply@blogger.com2tag:blogger.com,1999:blog-638236749302186936.post-73331759828670242442009-05-05T17:30:00.000-07:002020-07-15T16:49:45.003-07:00How to make a Beach<div>With O3D we knew we wanted to support relatively high end graphics. One of the problems with working on an engineer-only team is that we only have access to "programmer art." I'm sure there are exceptions but "programmer art" is pretty legendary as a synonym for bad stick figures or some simple geometric primitives. That left us with a problem. How would we show people what's possible if all we had is some primitives and a teapot?<br /></div><div><div style="text-align: center;"><br /><div><img src="http://o3d.googlecode.com/svn/trunk/blog/assets/beachdemo-postmortem/beachdemo.jpg" width="512" height="320" /></div><br /><div>The Beach Demo (<a id="n-vf" title="click here for the live demo" href="http://o3d.googlecode.com/svn/trunk/samples/beachdemo/beachdemo.html" target="_blank">click here for the live demo</a>)</div><br /></div>We ended up hiring <a href="http://www.crazypixelproductions.com/">Crazy Pixel Productions</a> to create a professional quality "beach scene" for us. We told them that we wanted the graphics to look "next-gen" but also not be too big. We weren't trying to max out the system-- we just wanted to have something that shows off what can be done apart from the cubes, spheres and teapots seen in the other samples. It took Crazy Pixel approximately two person-months of full time work to make the assets. They had to make models for each bush, rock, tree and coral, draw texture maps and compute or draw normal maps. This was not a small task.<br /></div><div><br />When we received the assets from Crazy Pixel, our first step was to design a process in which we could take the source assets and produce data for the demo without any manual handling. To do this, we wrote a python script that would launch 3d Studio Max, load their file, export the file to collada, exit 3d Studio Max, read the exported file, and process all the textures from their source formats (.TGA, .PSD) to formats that were more suited to our demo (.PNG, .JPG, .DDS). The script would then write out a new collada file with the texture paths updated to point to the processed textures and finally call our sample o3dConverter utility to convert the modified collada file into something our sample libraries could load. With that process firmly in place, it was easy to take any new changes from the artists and test them out. It was also easy to quickly adjust how the textures were processed such as trying them all at half or quarter resolution or trying different compression settings.<br /><br />Loading was the easy part, just a few lines of code. The next step was making the shaders to render some of the effects. The easiest was the sky, which uses a cube map. The artists had created a sky dome in 3dsmax so we went into the application and, using the <a href="http://www.ogremax.com/http://www.ogremax.com/">Ogre Max tools</a>, were quickly able to generate the six faces of the cube. We then loaded those into Photoshop and used the <a id="aii:" href="http://developer.nvidia.com/object/photoshop_dds_plugins.html" title="NVidia Photoshop tools">NVidia Photoshop tools</a> to generate a cube map. The sky shader just takes a normalized vector from the eye to the sky and uses that to get a color from the sky cubemap.<br /><div style="text-align: center;"><br /><div><img src="http://o3d.googlecode.com/svn/trunk/blog/assets/beachdemo-postmortem/skydome.jpg" width="512" height="85" /></div><div>A cubemap made from 6 faces</div></div><br />The biggest effect is of course the water. It's done in three stages. First, the entire world is flipped upside down and is then rendered into a render target. This basically renders what you'd see if the water was a perfect mirror the exception being that anything below the water should not be rendered. That required making shaders that checked for objects below sea level and not rendering those pixels.<br /><div style="text-align: center;"><br /><div><img src="http://o3d.googlecode.com/svn/trunk/blog/assets/beachdemo-postmortem/reflection.jpg" width="256" height="256" /></div>reflection<br /></div><br />Next, the entire scene is rendered again to another render target for refraction. The shader there renders everything tinted sea color and attempts to add a little fog as the water gets deeper. Whereas the reflection shaders don't render anything below the water, the refraction shader doesn't render anything above the water.<br /><div style="text-align: center;"><br /><div><img src="http://o3d.googlecode.com/svn/trunk/blog/assets/beachdemo-postmortem/refraction.jpg" width="256" height="256" /></div>refraction<br /></div><br />When it comes time to render the water, the water shader takes the reflection render target, the refraction render target, the sky cube map, and the water color, and mixes those 4 components together depending on the angle of view and the normal of the water's surface.<br /><div style="text-align: center;"><br /><div><img style="width: 454px; height: 500px;" src="http://o3d.googlecode.com/svn/trunk/blog/assets/beachdemo-postmortem/watersurface-mix.jpg" /></div>The water surface mixed from 3 inputs.<br /></div><br />To make the final image the water surface is combined with the main view and the sky.<br /><div style="text-align: center;"><br /><div><img style="width: 454px; height: 500px;" src="http://o3d.googlecode.com/svn/trunk/blog/assets/beachdemo-postmortem/final-mix.jpg" /></div><div>The final result.</div><br /></div>One thing that's really nice about working in a browser with JavaScript is that it is very quick to edit something and hit refresh in the browser to see your changes. For a small sample that's great, but as the data gets bigger it takes longer and longer to see those changes. On my desktop machine, loading the beach demo takes under 10 seconds from my local hard drive, but when you are iterating on shaders even 10 seconds seems like too long. That's when we added the ability to edit the shaders in real-time by adding a small text area and some buttons in the demo. You can press 'e' to bring these buttons up. With just a few minutes of coding I was able to edit the shaders instantly which was a huge time saver and also made experimenting a lot more fun.<br /><br />We could have shipped that but there's a vast range of machines out there. Some have the latest greatest fastest graphic cards and others are ... let's just say less than fast. With that in mind it seemed best to try to make the demo render as fast as possible without sacrificing the effects.<br /><br />The first step was to take a look at how much stuff was being drawn. GPUs are fast but the less you give them to draw the faster they go. The original scene had over 520 model instances (70 of "palm tree", 50 of "plant", etc.) and our demo was running pretty slow on machines with a slow GPU. Of course, nothing is going to make it run fast everywhere, as there is a huge difference in machine capabilities--from systems running with an Intel GMA 3100 at the low end, to an ATI Radeon 4870 or NVidia GeForce GTX 280 at the high end. Nevertheless, we still wanted to see what we could optimize.<br /><br />The first thing we tried was collapsing the models. The simple way to think of this is that it's a lot faster to draw one model with 10,000 triangles than it is to draw 10,000 models with one triangle each. We were drawing the entire scene three times: once for reflection, once for refraction and once for the main view. That's around 1,560 models being drawn in each frame. So, we collapsed all similar models--all 70 instances of "palm tree" became one model of 70 palm trees, all 50 instances of "plant" became one model of 50 plants. Doing that for all the instances changed the scene from 520 model instances to about 70 model instances and our total number of models drawn to about 210. That helped but not as much as we were hoping as we were still asking the GPU to draw the same number of pixels.<br /><br />The next step was to realize that for the reflection render target, nothing below the water needed to be drawn. Similarly, for the refraction render target, nothing above the water needed to be rendered. And, even for the main view, nothing below the water needed to be rendered because what appears to be below the water is actually coming from the refraction we already rendered. The solution was to organize the transforms in the transform graph so that just four transforms became the parents of those combinations. This process made it easy to set or clear the visibility on just those four transforms when rendering each render target so that only what needs to be rendered in each pass is actually rendered. That brought the number of models rendered per frame to around 60 and we were asking the GPU to draw a lot less pixels. With that, the demo ran at 30hz on most of our laptops at work, which we decided was good enough.<br /><br />To see the difference in performance between a top GPU and a bottom GPU, on a fast card like those mentioned above, the beach demo is able to run at a solid 60hz on a 30inch monitor stretched full screen, as well as a solid 60hz stretched across two 24 inch monitors whereas on an Intel GMA 3100 it might run as slow as 10hz.<br /><br />There was one more big optimization added at the last minute. If you look at the demo, except for the water, almost nothing is moving. Just the flames and a few particles on the waterfall. Taking that into account, if the camera does not move then the refraction and reflection actually do not need to be re-rendered since nothing in them will change. Changing the demo to only render the reflection and refraction when the camera moves shaved off another 10-15% of rendering time. If we had something more dynamic in the scene we could not have added this optimization.<br /><br />If you decide to play with the source for the beach demo be aware the first thing you'll want to do is edit the beachdemo.js file, search for V8,<br /><pre class="prettyprint">// Comment out the line below to run the sample in the browser JavaScript<br />// engine. This may be helpful for debugging.<br />o3djs.util.setMainEngine(o3djs.util.Engine.V8);<br /></pre>and comment out that 3rd line. This will enable you to use your browser's debugger to inspect and manipulate variables. Now run the demo. You can now enter your browser's debugger and from the debugger's console start looking at and setting the various elements. Set "g_timeMult" to 0.1 to see it run at 1/10th speed or inspect "g_re" to see some render stats. You can also copy and paste this code:<br /><pre class="prettyprint"> g_torchEmitter.setParameters({<br /> numParticles: 40,<br /> lifeTime: 2,<br /> timeRange: 2,<br /> startSize: 50,<br /> endSize: 90,<br /> positionRange: [10, 10, 10],<br /> velocity: [0, 0, 60], velocityRange: [15, 15, 15],<br /> acceleration: [0, 0, -20],<br /> spinSpeedRange: 4}<br /> );<br /></pre>You may want to try changing some of the numbers to see the torches change in real time. Change the 60 in velocity to 600 and the start size to 500 to see some giant torches.<br /><br />As you can see, working on a graphic application in such an environment definitely has some advantages. Take the beach demo and hack it up! Make better water effects or maybe even turn it into a game. If you have any more questions, be sure to check our session at <a id="yqo4" title="Google I/O" href="http://code.google.com/events/io/">Google I/O</a> or our <a id="a5:t" href="http://code.google.com/apis/o3d/docs/groups.html" title="discussion groups">discussion groups</a> . </div><br /><div>Posted by Gregg Tavares, software engineer, O3D Team.<br /></div>Unknownnoreply@blogger.com3tag:blogger.com,1999:blog-638236749302186936.post-62222663408554067502009-04-24T18:10:00.000-07:002020-07-15T16:49:44.927-07:00Designing a 3D API for the browser<span ><div >When we started out with O3D we knew what we wanted to achieve: we wanted to create a browser API that provides developers direct access to the powerful 3D graphics hardware that's inside most modern PCs. We wanted it to be fast; <span >f</span>ast enough to handle the complex rendering needs of a high-end video game but without making any assumptions on what it would be used for. In essence, we wanted to provide the flexibility and speed of a low-level graphics API like OpenGL or Direct3D, while addressing the constraints of running inside the browser.</div><div ><br /></div><div >Choosing JavaScript as a language was an obvious choice since we really wanted the API to feel at home in the browser. However, JavaScript, the programming language of the web, isn't exactly synonymous with high-performance. While modern browsers have improved the speed of JS by leaps and bounds, we are still faced with a large performance gap between JS and native code. This lead us to our first realization: If we were to provide an <i>immediate mode API</i> like OpenGL or DirectX our ability to render larger scenes would be limited by the speed of JavaScript. Just consider that when using an immediate mode API, for every object to be drawn the following calls need to be made:</div><div ><br /></div><div ><ol ><li >Bind a shader.</li><li >Provide values for all the shader parameters. Even simple shaders require a handful of parameters like the view projection matrix, light positions and texture sampler settings. </li><li >Assign vertex streams such as positions, normals, tangents and texture coordinates.</li><li >Set the necessary render states such as blending modes and culling.</li><li >Issue the draw call.</li></ol><div ><br /></div>Note that all these calls need to be issued for every object, in every single frame. This means that for a large scene we would have 16ms (1/60th of a second) to not only issue the thousands of calls from JavaScript into the browser to render the objects but also handle the rest of the application's logic. This simply didn't seem to scale well, not by today's performance standards anyway.</div><div ><br /></div><div >Given our concerns about JavaScript performance, we decided to make O3D a <i>retained mode API</i>. As a retained mode API, O3D requires the app to define the objects to render and the exact sequence in which to render them. Once this is set, O3D handles issuing the draw calls, once every frame<span >.</span> Practically speaking, if nothing moves in the scene, no JavaScript code needs to be executed. If an object moves then all the app needs to do is update its transformation matrix. To achieve that, O3D internally uses two types of graphs: T<i>ransform graphs</i> and <i>render graphs. </i> A transform graph stores tree hierarchies of transforms and shapes that are used by the render calls and preserves the logical grouping of objects typically found in most asset pipelines. A render graph describes exactly what order the render operations take place in and handles things like render state setting, z-sorting of shapes for transparency, culling, setting of render targets, etc. This combination of the two graph types allows us not only to minimize the number of calls that need to be made from JavaScript into the API per frame but also migrates some of the more computationally intensive operations, like updating of the transform matrix hierarchies and doing sorting and culling, from JavaScript into native code. </div><div ><br /></div><div >Even though we use a transform graph, O3D is <i>not</i> a high-level scenegraph API. We like to think of O3D as a <i>low-level retained mode graphics API</i>. We tried to keep as little high-level functionality in the API as possible while remaining pragmatic about the performance limitations of running inside the browser. We also tried to leave behind the traditional baggage of scenegraphs that get a lot of people up in arms. We don't have cameras, lights, script nodes, predefined behaviors, etc. However, We had to make some exceptions: Most notably, we added a very basic animation system to O3D, once again because we didn't think that JavaScript would currently be capable of providing the required level of performance for evaluating hundreds of animation curves per frame.</div><div ><br /></div><div >A few other things are worth noting about O3D: </div><div ><br /></div><div ><ul ><li >We decided to make the O3D API completely shader based. We believe that the fixed function pipeline is on its way to extinction and we're not the only ones: so does OpenGL and Direct3D. Leaving the fixed function pipeline behind makes the API smaller and easier to implement. It also means that shaders need to be provided for every draw call which raises the barrier of entry a bit although this problem can be solved by providing higher level JavaScript abstractions (as we have in some of our JavaScript utility libraries).</li><li >We had decided early on that in order for O3D to be useful we need to take all the steps necessary to guarantee that the images we render look the same, regardless of the GPU or the OS it's run, so that developers can trust that what they see on their computer is exactly what all their users will see as well. In order to achieve that, we settled on a GPU spec that we feel offers a good balance between being inclusive and providing access to modern GPU features. GPUs that run O3D must be capable of at least DirectX 9.0 graphics and we only accept Shader Model 2.0 pixel and fragment shaders. We believe this covers over 60% of the GPU installed base today. For the remaining ones we are looking into providing a software rasterizer. If you feel that we haven't quite hit the right sweet spot, either that we're limiting GPU features too much or that we're not inclusive enough, please let us know <a id="kh2h" href="http://moderator.appspot.com/#16/e=41eb1" title="here" >here</a> .<br /></li><li >We believe that one of the big advantages of implementing an API that isn't exactly based off of an existing API such as Direct3D or OpenGL is that it gives the implementaters the flexibility to chose the appropriate low level graphics API to build on top of, depending on the platform. In our case, we chose to use Direct3D on Windows (DirectX enjoys a lot better GPU driver support on that platform than OpenGL) and naturally OpenGL on the Mac and Linux.<br /></li></ul></div><div ><br /></div><div >In closing, I'd like to say that what you see here is an API that was designed by a group of engineers coming from all sorts of different backgrounds: some graphics people, some games people, some web folks. We're proud of what we've created but at the same time realize it's not set in stone in any way. It's really our contribution to the discussion on finding a standard for 3D graphics in the browser, a cause that we're really committed to. As such, we always welcome your feedback, comments and even criticism! Please let us know what you think of it, and how we can improve it. You'll find links to our discussion group and moderator app in our front page (<a href="http://code.google.com/apis/o3d/" >http://code.google.com/apis/o3d</a>).</div><div ><br /></div><div ><span >Posted By Vangelis Kokkevis, Software Engineer, O3D Team.</span></div></span>Unknownnoreply@blogger.com8tag:blogger.com,1999:blog-638236749302186936.post-88749455756751189382009-04-22T16:52:00.000-07:002020-07-15T16:49:45.131-07:00Why JSON Rulez!One of the issues that came up as we developed O3D was what format to load for 3D content. There are a few standards out there, the most notable probably being Collada, and so originally we planned on loading Collada files directly in O3D. We quickly ran into limitations. <br /><br />There's nothing wrong with Collada per se, it's just that it's designed to do one thing: exchange 3D data. If your application doesn't fit its model you either have to work around it by trying to squeeze your extra data in to the nooks and crannies of the Collada spec or you have to redesign your application to fit what Collada supports.<br /><br />After a few months of working with the limitations of Collada, we thought about it more and realized that similar to how other 3D APIs like OpenGL or DirectX do not define a file format, we shouldn't either. Instead, we should provide the pieces needed to make it possible to load data into our API, and then leave file formats up to the individual application developer. This allows the developer to tailor the data they send over the net to match their application. A mapping application might only need to send line segments, street widths and names. A 3D viewer might need triangles, materials and a transform hierarchy. A game might need all that plus collision data, character data, A.I. data, etc. <br /><br />In switching to JSON we made all of that possible. Instead of some "black box" in which you give a URL and it magically loads the file with no control from the developer, we instead made the process completely transparent. Not only can you see exactly what is happening but you can also change almost every part of it to suit your situation.<br /><br />Some parts of the data seemed like they were probably too large for JSON. Textures of course fit into this category, but also other elements such as vertices, animation and skinning data can get quite large. Even though, those assets can still be 100% in JSON if you like (depending on the size of your assets), we made it possible to load those types of assets from binary data and provided an API to load the data from gzipped tar files so you can package all of this up into manageable, easy-to-download pieces.<br /><br />Having this process be open might sound like more work for each developer, but we provide a solution for this problem as well. We have a sample offline converter that takes a Collada file and converts it to a <b>sample</b> JSON format. We then have a <b>sample</b> library that reads that JSON format and recreates the Collada scene in O3D. With one command to convert your data and a couple of lines to load your scene, you'll find that it's very easy to use.<br /><br />However, the offline converter and loading library are just that, <b>samples</b>. If you want different data you are free to modify the converter or write your own. For example, if you want something different to happen at load time, the loader is written entirely in JavaScript (most of it is in <a href="http://code.google.com/p/o3d/source/browse/trunk/samples/o3djs/serialization.js">serialization.js</a>) which you can use as a starting point and modify to fit your needs. If we had chosen a fixed format, all of that flexibility would have been lost.<br /><br />Given this flexibility, we're excited to see the myriad of applications that will come out of O3D. Make something cool and share it with us via the <a id="voro" title="discussion groups" href="http://code.google.com/apis/o3d/docs/groups.html">discussion groups</a> and come meet us at <a id="s4gv" title="Google I/O" href="http://code.google.com/events/io/about.html">Google I/O</a>. <br /><br />Posted by Gregg Tavares, software engineer, O3D Team.Unknownnoreply@blogger.com4tag:blogger.com,1999:blog-638236749302186936.post-37646955655636513052009-04-20T19:58:00.000-07:002020-07-15T16:49:44.822-07:00Introducing O3D<span ><div ><div ><div ><span >Most content on the web today is in 2D, but a lot of information is more fun and useful in 3D. Projects like Google Earth and SketchUp demonstrate our passion and commitment to enabling users to create and interact with 3D content. We'd like to see the web offering the same type of 3D experiences that can be found on the desktop. That's why, <a href="http://google-code-updates.blogspot.com/2009/03/toward-open-web-standard-for-3d.html">a few weeks ago</a>, we announced our plans to contribute our technology and web development expertise to the discussions about 3D for the web within <a href="http://www.khronos.org/">Khronos</a> and the broader developer community.</span><br /></div></div></div><div ><div ><div ><div><span ><br />Today, we're making our first contribution to this effort by sharing the plug-in implementation of <a href="http://code.google.com/apis/o3d?utm_source=o3b&utm_medium=et&utm_campaign=en-US">O3D</a>: a new, shader-based, low-level graphics API for creating interactive 3D applications in a web browser. When we started working on O3D, we focused on creating a modern 3D API that's optimized for the web. We wanted to build an API that runs on multiple operating systems and browsers, performs well in JavaScript, and offers the capabilities developers need to create a diverse set of rich applications. O3D is still in an early stage, but we're making it available now to help inform the public discussion about 3D graphics in the browser. We've also created a forum to enable developers to <a href="http://moderator.appspot.com/#16/e=41eb1">submit suggestions</a> on features and functionality they desire from a 3D API for the web.<br /><br />If you are interested in learning more about O3D, you can visit our <a href="http://code.google.com/apis/o3d?utm_source=o3b&utm_medium=et&utm_campaign=en-US">site</a>, subscribe to our <a href="http://o3d.blogspot.com/">blog</a> and join our <a href="http://code.google.com/apis/o3d/docs/groups.html">discussion groups</a>. We also invite you to join us at <a href="http://code.google.com/events/io/sessions.html">Google I/O</a> (May 27th -28th), where you can see presentations about O3D and meet with the team.<br /><object height="295" width="480"><br /><param name="movie" value="http://www.youtube.com/v/uofWfXOzX-g&hl=en&fs=1&rel=0"><param name="allowFullScreen" value="true"><param name="allowscriptaccess" value="always"><embed src="http://www.youtube.com/v/uofWfXOzX-g&hl=en&fs=1&rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" height="295" width="480"></embed><br /></object><br />A video of the O3D Beach Demo<br /><br /></span></div></div></div></div></span><span ><span >Posted by Matt Papakipos, Director of Engineering and Vangelis Kokkevis, Software Engineer, O3D Team</span></span>Unknownnoreply@blogger.com20