G'kar Posted December 24, 2015 Share Posted December 24, 2015 I have just contribute to BabylonJs with playground recently.This trig a few question on how to handle storage of resources around the playground.I mean texture images, or shader code.Here is the results of my thinking, with questions as well.Context : I am mainly hacking around very basic sample code to test babylonJs,possibly with idea to share on forum with other users.Scope can be: A) local on my PC, B ) on the playgroundA) Local PC. This is easy case. Here everything is under control.I run my local web server, to run the BJS scene in my browser.I have a dummy html file that refer the javascript I am testing.Idea is to have html that put the javascript in same state as provided by playground.In parallel, along with that I put my texture image as local file, no problem.This context is important for me as I can use my usual texteditor, ...B ) Playground.Very nice environment, easy to setup quickly basic BJS scene.The drawback: you only control the javascript code of your scene.Html framework is pre-defined inside playground and you don't control.I found that I have to provided link to external texture needed by my BJS playground test.--------------------------------------------------------------------1) texture1A) on my local PC, the javascript is referring texture as local file, in can edit, change at will1B) on playground When stable I migrate texture to file as remote URL (want same javascript to move to playground) something like : ....material.diffuseTexture = new BABYLON.Texture('http://url.../image.png',scene); So where can we store our texture files ? I give a try to : - google blog: setup a blogspot uploading file and manage to get a url to the image Working but not really easy (need to manual edit the blog page) Url are quite ugly : example : 'http://2.bp.blogspot.com/-sTvFL0vGFXE/VncKTkHuR7I/AAAAAAAAD1A/vDokBOMvxqk/s1600/Fuller-ico-uv.jpg' - Checking with my access provider webpage. Ftp access to the file on the server, nice ! Issue is the access from playground have cross-origin-ressource-sharing problem. And not sure how to bypass such limitation not under my control, but set my my access provider. - Use my own webserver: Ok, this one is perfect. But overkill ! I need to setup all that (linuxbox, domain name, apache, ...) Probably not the solution for lambda user. - anyone have other solutions ?--------------------------------------------------------------------2) shaderjust starting to play with shader material. Doing thing as :material = new BABYLON.ShaderMaterial("shader", scene, "ShaderRessource", { attributes: ["position", "uv"],uniforms: [...]});Now what to put for ShaderRessource. This should locate the shader code to be used in the material.This can be DOM element in the HTML, using {vertexElement: "vertexShaderCode", fragmentElement: "fragmentShaderCode"}This could be file located either in babylonJS Shader/src, or file on the webserver serving the javascript/html.Needed files are : ShaderRessource.fragment.fx and ShaderRessource.vertex.fx2A) Again for local PC, it is easy to have html DOM, or local file, no problemo.2B) Here trouble begins: On playground I have no direct control of HTML file, so not easy to fill the html (as shown in http://gamedevelopment.tutsplus.com/tutorials/building-shaders-with-babylonjs-and-webgl-theory-and-examples--cms-24146) I suspect solution exist to have javascript to refer the html and create and dynamicaly fill the <script type="application/fragmentShader" id="fragmentShaderCode"> with your code. Ok I didn't dig a lot in this direction as it sound quite complex. So I check to external file reference option, but failed so far to put something in place. It is limited to ShaderRessource located on same web server as the one serving the html/javascript. So having a url such as "http://my.own.remote.web.server/myshader" On a local test the browser generate invalid url like (concatenate local and remote): h t t p://192.168.56.101:8000/test/src/Shaders/h t t p://my.own.remote.web.server/myshader.fragment.fx I backtrack the "issue?" to babylon.effects.ts code: var fragmentShaderUrl; if (fragment[0] === "." || fragment[0] === "/") { fragmentShaderUrl = fragment; } else { fragmentShaderUrl = Engine.ShadersRepository + fragment; } // Fragment shader Tools.LoadFile(fragmentShaderUrl + ".fragment.fx", callback); The first char of resource locator is checked for "." or "/", obviously this restrict the shader code to be fetched from external website (start with http is needed ?). Is it intentional limitation/feature ? Is there any trick to allow a playground test to refer shader files located on an arbitrary url on the web ? Is it worth trying (or wish-able) to tune the BJS code to work differently ? Any idea is welcome, this would help me to soon share my own shader/playground with you Alternative I have is to fully setup a full website with html, javascript, texture and shader as standalone whole. (but the playground sounds better if possible) Quote Link to comment Share on other sites More sharing options...
Wingnut Posted December 24, 2015 Share Posted December 24, 2015 Hi G'kar! These problems are likely caused by CORS (Cross-origin resource sharing). The behaviors you describe seem normal to me. Many folk use the ShadersStore to store shader code in the playground. It looks like this... http://playground.babylonjs.com/#16UICJ#1 CYOS is our "Create Your Own Shader" editor... I'm sure you have seen it. The demo above... uses the Spherical Environment Mapping shader... and I chose the "Zip" choice in CYOS... to bring it to my home computer. Then I listed it's source, and the shader code was there... in ShadersStore format. I just pasted it into the playground... easy. In other words, if you write/paste your shader code into CYOS, get it working good there, then grab a zip, CYOS will put the shader code in ShadersStore format FOR YOU... handy. For playground images, I often use textures and pictures gotten from wikipedia commons CORS-cleared images. Let me show you how I find a CORS-clear image... 1. Visit here: https://images.google.com/ 2. Search for... oh... maybe 'cow' (for example) 3. We got cows. Now choose "Search Tools". 4. Now choose "Usage Rights" ==> Labeled for reuse Almost all 'wikipedia commons' pictures are CORS-clear. So are Facebook pictures. Others are still CORS-restricted. As you likely know, there is no warning or alert when a playground image has been blocked by CORS. It just won't load/render... silent failure. I chose https://upload.wikimedia.org/wikipedia/commons/7/72/Winking_Jersey_Cow.JPG Now let's test our cow in a modified materials playground demo (see line 64)... http://playground.babylonjs.com/#1N4VL8 We got good cow! Yay! It's a CORS-clear picture. How do you set YOUR home web server to allow CORS-clear reusable images and shader retrieval? I have no idea, but the information is available on the net. You are among MANY who wish CORS would have never happened, because it causes many problems for the JS-based XmlHttpRequest object (sometimes called XHR), which is used heavily in BabylonJS and many other systems. I will let you read about WHY it was adopted a few years ago. I hate it, personally. There's not much that can be done about it. You/We just need to learn the rules, and adapt, unfortunately. I hear that the best solve is to run your own web server and make it CORS-enabled (like we saw with the wikipedia commons server)... but I don't do that, and I don't know much about it. There are also a few images and skybox 6-packs in the playground's textures/ folder... mainly for doing demos for the community (to support documentation, for example). We also have a github-based materials library, now, but I don't know what the criteria is for making additions to that. Here is the folder of textures located within CORS scope... in the playground's /textures/ folder. All of those images will work fine in the playground using URLs such as "./textures/[imgname]" Read about CORS when you get a moment (not a fun read)... and if you still have questions, I and others will comment and help explain the situation with more clarity. Be well! G'kar 1 Quote Link to comment Share on other sites More sharing options...
Vousk-prod. Posted December 25, 2015 Share Posted December 25, 2015 Hi G'kar, in fact to choose the url for the vertex and fragment code you simply specify BABYLON.Engine.ShadersRepository = "root-http-url-of-your-file".You then put your vertex and fragment files in that location and it's ok.Also FYI some days ago I changed the code for loading shader files to allow http url directly specifiable in the createEffect and in the new ShaderMaterial functions (but you have to use the latest BJS version)To put images on a simple webserver with no CORS restriction, I think dropbox could be easily used (don't use it myself so I'm not sure for CORS enabled but that that would make sense). G'kar and Wingnut 2 Quote Link to comment Share on other sites More sharing options...
G'kar Posted December 25, 2015 Author Share Posted December 25, 2015 @Vousk-prod.You are right "effect.ts" is already updated in latest version as follow(handling the case of http based url that I tested before).I get it to work perfectly (using latest BJS). Thanks. var fragmentShaderUrl; if (fragment[0] === "." || fragment[0] === "/" || fragment.indexOf("http") > -1) { fragmentShaderUrl = fragment; } else { fragmentShaderUrl = Engine.ShadersRepository + fragment; } // Fragment shader Tools.LoadFile(fragmentShaderUrl + ".fragment.fx", callback);@WingnutOf course CYOS ! + ask for a zip => gives me a nice index.html with BABYLON.Effect.ShadersStore["customVertexShader"]= ... BABYLON.Effect.ShadersStore["customFragmentShader"]= ... var shaderMaterial = new BABYLON.ShaderMaterial("shader", scene, { vertex: "custom", fragment: "custom", }, { attributes: ["position", "normal", "uv"], uniforms: ["world", "worldView", "worldViewProjection", "view", "projection"] });Exactly the pattern I was looking for.I tested the 3 options : - embedded in javascript (as CYOS pattern provides) - as local file on relative Url - as remote file on remote absolute URLExcellent, all 3 are working fine (I have a playground in preparation to demonstrate my actual shader,I will add pointer to this code to illustrate as soon as available).@WingnutThanks for the details on CORS.Appreciate the trick to locate such texture on google imageFor server setup to relax CORS, don't worry, I can handle that.(a bit off topic, but for the one interested, on my apache server, it is one line in .htaccess: Header add Access-Control-Allow-Origin "*"OK because I own the server and can do as I want)Thanks also to list the available texture inside playground (didn't know about the details)So now if I look for cool texture, I have solution to explore and find.But when I have to build my own texture (with specific uv mapping for icosphere that nobody knows about for instance),I still have to find a public website with no CORS to store my picture.(facebook friends, get ready to be spamed with ugly texture).Or may be I will stick to my local website as it is fine for me.I also tried a CORS referring image from BJS playground to:- facebook public image : OK- upload.wikimedia.org : OK (as shown by Wingnut)- google blog (blogspot) : OK- dropbox (using sharing link for file) : failed (get load error in log of playground). Probably failed because the link gives you to framework proposing to log in and ... (you don't get a direct image)- google drive : failed : they give file reference is a framework web page allowing to view a file (not a direct image)- probably other solutions, to be tested later ... Wingnut 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.