Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to load shaders from external file? #283

Closed
nardove opened this issue Jun 21, 2011 · 10 comments
Closed

How to load shaders from external file? #283

nardove opened this issue Jun 21, 2011 · 10 comments
Labels

Comments

@nardove
Copy link

nardove commented Jun 21, 2011

Hi,

I wonder if is posible to load the shader files from a external source? I am on a Mac and setup apache to avoid the security issues but I get lots of error like "ERROR: Parser found no code to compile in source strings." in Three.js line 295 when I try to render the page.

The first thing I get is a couple of warnings on both files(vertex and fragment) "Resource interpreted as Script but transferred with MIME type text/plain."
I found this http://stackoverflow.com/questions/5878703/webgl-is-there-an-alternative-to-embedding-shaders-in-html and apparently he manage to get it working, I try with different file extensions but always the same problem, any ideas?

Thanks

  • rS
@mrdoob
Copy link
Owner

mrdoob commented Jun 22, 2011

How are you loading the shader?

@nardove
Copy link
Author

nardove commented Jun 22, 2011

I have the following

<script> src="scripts/shaders_intro.js" type="text/javascript" </script>
<script> data-src="scripts/simple_vertex.js" type="x-shader/x-vertex" id="vertexshader" </script>
<script> data-src="scripts/simple_fragment.js" type="x-shader/x-fragment" id="fragmentshader" </script>

And in side the shaders_intro.js I simply do

var material = new THREE.MeshShaderMaterial( {
    vertexShader:   $("#vertexshader").text(),
    fragmentShader: $("#fragmentshader").text()
 } );

@mrdoob
Copy link
Owner

mrdoob commented Jun 22, 2011

Try with this and see it removes the errors...

var material = new THREE.MeshShaderMaterial( {
    vertexShader:   $("#vertexshader").textContent,
    fragmentShader: $("#fragmentshader").textContent
 } );

@nardove
Copy link
Author

nardove commented Jun 22, 2011

Now I get "Uncaught TypeError: Cannot read property 'undefined' of undefined" in Three.js line 238

@mrdoob
Copy link
Owner

mrdoob commented Jun 22, 2011

Meh... could you put the thing live somewhere?

@mrdoob
Copy link
Owner

mrdoob commented Jun 22, 2011

Ah wait... the script loading part is wrong... for starters, these two are incorrect:

<script> data-src="scripts/simple_vertex.js" type="x-shader/x-vertex" id="vertexshader" </script>
<script> data-src="scripts/simple_fragment.js" type="x-shader/x-fragment" id="fragmentshader" </script>

Maybe it'll work this way:

<script src="scripts/simple_vertex.js" type="x-shader/x-vertex" id="vertexshader"></script>
<script src="scripts/simple_fragment.js" type="x-shader/x-fragment" id="fragmentshader"></script>

@nardove
Copy link
Author

nardove commented Jun 22, 2011

My bad the <script> tag error I had to edit the pasted copy in the comment and I miss it, I did change data-src to src but the error persist, I will put it online and share the link later on

Cheers!

@nardove
Copy link
Author

nardove commented Jun 22, 2011

Here it is, have to say the error is different online but points to the material shader as well so it may be related
http://nardove.com/webgl-experiments/Shaders01/

@alteredq
Copy link
Contributor

Seems like you can't get content of externally linked <script> (at least I didn't manage to find any way in Chrome console).

You can try to load shaders yourself via ajax, string like string, and if you already use jquery, there should be some helpers for this.

@nardove
Copy link
Author

nardove commented Jun 28, 2011

Yes jQuery.ajax() did the trick, here is a simplified version from another source code I found here http://lab.aerotwist.com/webgl/easing/js/ShaderLoader.js

var vertexShaders       = $('script[type="x-shader/x-vertex"]');
var fragmentShaders     = $('script[type="x-shader/x-fragment"]');
var shadersLoaderCount  = vertexShaders.length + fragmentShaders.length;

var shadersHolder = { vertex: '', fragment: '' };

function loadShader(shader, type) {
    var $shader = $(shader);

    $.ajax({
        url: $shader.data('src'),
        dataType: 'text',
        context: {
            name: $shader.data('name'),
            type: type
        },
        complete: processShader
    });
}

function processShader( jqXHR, textStatus ) {
    shadersLoaderCount--;
    shadersHolder[this.type] = jqXHR.responseText;

    if ( !shadersLoaderCount ) {
        shadersLoadComplete();
    }
}

function shadersLoadComplete() {
    init();
}
// Use a for loop if there is more than one
loadShader( vertexShaders[0], 'vertex' );
loadShader( fragmentShaders[0], 'fragment' );

And here is the code to use them
var material = new THREE.MeshShaderMaterial( { vertexShader: shadersHolder.vertex, fragmentShader: shadersHolder.fragment } );

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants