有没有办法从three.js中的json材质格式引用自定义着色器?

时间:2016-11-30 12:52:30

标签: javascript three.js shader

Three.js的JSON对象场景格式4具有此处定义的材质规范:JSON Material Format 4

但目前尚不清楚,至少不是我,如何或天气可以从那里引用自定义着色器。任何想法如何做到这一点?

[UPDATE]

我想我的问题还不够明确我所说的是让JSON加载器能够解释自定义着色器定义的材质。这是JSON对象场景格式4的摘录:

"materials": [
    {
        "uuid": "87D95D6C-6BB4-4B8F-8166-A3A6945BA5E3",
        "type": "MeshPhongMaterial",
        "color": 16777215,
        "ambient": 16777215,
        "emissive": 0,
        "specular": 1118481,
        "shininess": 30,
        "opacity": 1,
        "transparent": false,
        "wireframe": false
    }
],
"object": {
    "uuid": "89529CC6-CBAC-412F-AFD1-FEEAE785BA19",
    "type": "Scene",
    "matrix": [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],
    "children": [
        {
            "uuid": "33FA38D9-0AAC-4657-9BBE-5E5780DDFB2F",
            "name": "Box 1",
            "type": "Mesh",
            "geometry": "C3BF1E70-0BE7-4E6D-B184-C9F1E84A3423",
            "material": "87D95D6C-6BB4-4B8F-8166-A3A6945BA5E3",
            "matrix": [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]
        },

如您所见,网格可以通过其UUID引用材质。加载此文件时,JSON加载程序将检查此材料的类型,并在此基础上使用提供的参数创建该材料的实例。我遇到的问题是材料类型是在WebGLPrograms函数中预定义的,我无法找到一种使用自定义着色器扩展此列表的明确方法。

1 个答案:

答案 0 :(得分:0)

对于自定义着色器,您必须使用属性vertexShaderfragmentShader实现ShaderMaterialRawShaderMaterial,两个着色器的代码都必须包含在html / js source。

只要提供了两个着色器的源代码,您就可以使用JSON格式,ShaderMaterial继承自基础Material对象。

使用无参数ShaderMaterial,您将在JSON输出中看到默认的顶点和片段着色器代码。



var shader = new THREE.ShaderMaterial();
console.log(shader.toJSON());

<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r82/three.js" charset="utf-8"></script>
&#13;
&#13;
&#13;

更新

最后一次尝试。希望我能正确理解您的问题更新和评论。

但目前尚不清楚是否可以告诉它创建自定义ShaderMaterial的实例。

是的,MaterialLoader可以使用自定义顶点和片段着色器加载ShaderMaterialMaterial.toJSON方法和MaterialLoader是镜面反射,它应该是,或者它不会#39;将材质转换为JSON格式是有意义的。

&#13;
&#13;
// specular aspect of saving and loading
var loader = new THREE.MaterialLoader();

var shaderMaterial = new THREE.ShaderMaterial();
var shaderMaterialJSON = JSON.stringify(shaderMaterial.toJSON());

console.log('JSON ' + shaderMaterialJSON);

var loadedShaderMaterial = loader.parse(JSON.parse(shaderMaterialJSON));

console.log(loadedShaderMaterial);

// convert a phong material to a shader material
var phongMatJSON = '{"uuid": "87D95D6C-6BB4-4B8F-8166-A3A6945BA5E3", "type": "MeshPhongMaterial", "color": 16777215, "ambient": 16777215, "emissive": 0, "specular": 1118481, "shininess": 30, "opacity": 1, "transparent": false, "wireframe": false}';

var phongMatObj = JSON.parse(phongMatJSON);
phongMatObj.color = undefined; // not used in a shaderMaterial
phongMatObj.emissive = undefined; // not used in a shaderMaterial
phongMatObj.specular = undefined; // not used in a shaderMaterial
phongMatObj.name = '';
phongMatObj.type = 'ShaderMaterial';
phongMatObj.uniforms = {}
phongMatObj.vertexShader = 'void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}';
phongMatObj.fragmentShader = 'void main() {\n\tgl_FragColor = vec4( 0.0, 0.0, 1.0, 1.0 );\n}';

var shaderMatObj = loader.parse(phongMatObj);

console.log(shaderMatObj);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r82/three.js" charset="utf-8"></script>
&#13;
&#13;
&#13;