Forum Replies Created
-
AuthorPosts
-
jemCustomer
That was a very clear explanation. Thank you!
JemJeremy Wernick
jemCustomerHello Yuri,
I did implement your gl.MAX_TEXTURE_IMAGE_UNITS code in my projects and it works very well. I removed my user agent testing code. I did have to re-order some of the tasks in the standard app initialization function to make it work, but it was not difficult. I had to create the player object before I set the GLTF/BIN urls, because I need information from the context to determine which GLTF url to select.Now the scene looks amazing on an iPad and all other platforms.
Thanks again,
JemJeremy Wernick
jemCustomerIt seems that my main problems with supporting iOS are lamps that cast shadows (as Yuri did point out). I would rather lose the shadows than lose the amazing looking materials. If I disable dynamic shadows, my tests work on iOS.
To test this idea, I exported the GLTF with and without shadow casting and modified the application logic to load the appropriate GLTF. Here is my code:
var iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream; if (iOS) { var URL = '__URL__ios_render_test_ios.gltf'; } else { var URL = '__URL__ios_render_test.gltf'; }
I did not need two different bin files because the meshes are the same. Here is a link to the new version of the scene on the CDN.
https://cdn.soft8soft.com/AROAJSY2GOEHMOFUVPIOE:027349a7ae/applications/ios_render_test_mk2/ios_render_test.htmlA solution like this is acceptable. I think that it would be better if I would probe the WebGL MAX_TEXTURE_IMAGE_UNITS support rather than inferring it from the agent string, but it will do for now.
Thank you,
JemJeremy Wernick
jemCustomerHello Yuri,
Thank you for the response and explanation. I have now looked at the WebGL reports for the various platforms and I can see what you are describing. iOS and Safari really do have the weakest WebGL 1.0 implementation of any platform that I must support. So, if I want my scenes to render properly on iOS, I will need to keep the scenes simple. I will need to minimize shadow casters and use simpler materials than I would on other platforms.I have two more questions:
1. Is there a way of examining a scene and observe or predict how many texture units will be required? For example is there something similar to Chrome’s developer tools that would report on WebGL resources in real time? This information may be helpful to developers building scenes. If such a tool is not available, is it best to manually review the scene in Blender using the procedure that you explained?2. Let us assume that my goal is to show the best possible quality scene on all supported platforms (rather than show an iOS quality scene to all users) and I produce two versions of my gltf/bin files. One version for iOS and another version for everything else. What is your opinion of adding some custom user agent logic to the application to load the appropriate version? I am not asking for Soft8soft to do this. This code is easy enough to write myself, but I value your opinion and you may have a better strategy.
Thanks,
JemJeremy Wernick
jemCustomerHi Yuri,
Thank you very much. This is not an urgent request, but it would be a nice feature in some scenes.
-JemJeremy Wernick
jemCustomerHi Aubrey,
It has been a little while since this thread started and I have been experimenting with this technique since then.My goal is similar to yours: I need to manage the number of objects loaded into the scene. Ideally, in my scenario, I want the scene to boot with a minimal amount of content. The scene would then load objects on demand. I have a few working prototypes, but it does require some moderately complex coding.
There are at least two fundamental challenges with dynamic object loading in Verge3D that I have run into. The first issue is how to make puzzles aware of objects that are not present in the scene. The second is how to efficiently generate the large quantity of separate *.gltf files needed from a single Blender scene.
For the first issue, how do we write puzzle logic for objects that are not present in the scene? I used proxy objects. Technically, these are empties in Blender. They are exported as objects in the gltf file and the can be operated upon by puzzle logic like ordinary mesh objects. The puzzle logic can manipulate the proxies. Proxies do not burden the system because they only add a trivial amount of data to the scene. I then wrote some custom code that would load the full object from a separate gltf file and swap the proxy for the full object at the appropriate time. This code was based on Will’s example at the beginning of the thread.
The second issue was how to create the many separate gltf files. In my case, all of my source objects were in a single Blender file. I could have broken that Blender file up by hand into many separate Blender files and then exported each as a GLTF file. In fact, this is what I did for my first test, but the process was slow and not scalable. In my second version, I wrote a Python script to do all of the scene splitting and Verge3d exporting for me based on a spreadsheet.
If I get some free time I might develop a sanitized example and share it with the community here. Right now, I am not using this in production. The solution it a bit too fragile and handcrafted for my comfort, but it was educational.
Good luck,
-JemJeremy Wernick
jemCustomerMikhail,
Thank you. This was very helpful! I did not know how environments worked in Verge3D.
I look forward to your next video.
Thank you,
JemJeremy Wernick
jemCustomerI was using v3dApp as a communication channel between the V3D scene and the page that holds the iFrame. I my scenario, both the parent web page and the child iframe are served from the same domain, so the v3dApp object is a simple communications channel.
I did edit my code and added window.v3dApp. It works well. Could this, or something like this, be added back to the core template code? I could be useful, but easy to forget if it is missing.
V3DPlayer.prototype = Object.assign(Object.create(v3d.AppPuzzles.prototype), { constructor: V3DPlayer, onLoadFinished: function(sceneLoaded, logicLoaded, editorLoaded) { if (sceneLoaded) { this.run(); initFullScreen(); window.v3dApp = app; runCode(); } }, });
Thank you. Great work!
-jemJeremy Wernick
jemCustomerI think that this function will be useful for the community.
I will experiment with a custom preloader
Thanks again,
JemJeremy Wernick
jemCustomerHi Mikhail,
I am interested in the technique that you described in the recliner example. I would like to know more about baking a normal map from a high poly model onto a low poly model. Will Soft8soft release the recliner scene as an example in the next build of Verge3D? Also, if you happen to know of any tutorials on this procedure I would appreciate if you could share a link.
Thank you,
JemJeremy Wernick
jemCustomerI saw this on the Khronos issue tracker a few days ago. I am happy to see support expanding for the GLTF format. Congratulations!
-JemJeremy Wernick
jemCustomerI just tested the technique that you described. It works perfectly! This feature is excellent and useful.
Thanks,
JemJeremy Wernick
jemCustomerWill,
I just ran into this issue. At first, I could not understand the behavior that I was seeing, but I remembered this post of yours. It was an easy fix after that.
Thanks,
JemJeremy Wernick
jemCustomerThe example contains client data, so I must share it with you privately. I will send you the file.
If it helps the discussion, I can create some non-confidential CAD models so we can discuss them openly in the forums.
Thank you,
JemJeremy Wernick
jemCustomerI was able to get the object cloning to work. I will share my solution to this problem here for anyone who needs this technique.
The goal was to create copies of objects at runtime. I needed this because my scenes are assembled from many objects and the quantities of each type object are not known ahead of time. The quantities can be large.
I wrote a small function that uses the Object3D.clone() method from the API. The function takes two arguments. The srcObjectName is the name of the object to be cloned. The name is assigned in Blender. The targetObjectName is the name of the object to which we will snap the clone. Again, the name is assigned in Blender. The function requests a non-recursive copy. I think that this means clones will share meshes and materials (I may be wrong). Lastly, the function returns the clone. This is important because we need to keep track of the clones. In my example, I place all of the clones in an array so that I may programmatically destroy them later. The clones will not be callable from the puzzles.
function cloneObject(srcObjectName, targetObjectName) { var srcObject = v3dApp.scene.getObjectByName(srcObjectName); //Create a shallow copy var cloneObject = srcObject.clone(false); var targetObject = v3dApp.scene.getObjectByName(targetObjectName); //Place the copy cloneObject.position.x = targetObject.position.x; cloneObject.position.y = targetObject.position.y; cloneObject.position.z = targetObject.position.z; cloneObject.rotation.x = targetObject.rotation.x; cloneObject.rotation.y = targetObject.rotation.y; cloneObject.rotation.z = targetObject.rotation.z; v3dApp.scene.add(cloneObject); return cloneObject; }
If you look at the Blender screenshot, you will see that the chessboard is covered with an array of empties. I use these empties as my snapping targets. I found that using the arrows type empty is useful to set the snap orientation.
Here is a link to the example on the Soft8soft CDN,
https://cdn.soft8soft.com/AROAJSY2GOEHMOFUVPIOE:027349a7ae/applications/clone_pawn/clone_pawn.htmlCheers,
JemJeremy Wernick
-
AuthorPosts