é·å¹Žã«ããããäžè¬çãªæ©èœã®èŠæ±ã¯ãçµã¿èŸŒã¿ã®ãããªã¢ã«ãå€æŽã§ããããã«ããããšã§ããã ä»æ¥ãç§ã¯ãããObject3D
ã®onBeforeRender()
ãšåæ§ã®æ¹æ³ã§å®è£
ã§ããããšã«æ°ã¥ããŸããã
https://github.com/mrdoob/three.js/commit/e55898c27a843f69a47e602761c60d9bbe91ee35
WebGLPrograms
ã¯ãããã°ã©ã ããã·ã¥ã«onBeforeCompile.toString()
ãè¿œå ãããããã·ãŒã³ã§äœ¿çšãããä»ã®çµã¿èŸŒã¿ãããªã¢ã«ã«åœ±é¿ãäžããããšã¯ãããŸããã
åäœäžã®æ©èœã®äŸã次ã«ç€ºããŸãã
http://rawgit.com/mrdoob/three.js/dev/examples/webgl_materials_modified.html
material.onBeforeCompile = function ( shader ) {
// console.log( shader )
shader.uniforms.time = { value: 0 };
shader.vertexShader = 'uniform float time;\n' + shader.vertexShader;
shader.vertexShader = shader.vertexShader.replace(
'#include <begin_vertex>',
'vec3 transformed = vec3( position.x + sin( time + position.y ) / 2.0, position.y, position.z );'
);
materialShader = shader;
};
ã·ã§ãŒããŒã³ãŒãããããã ãã§ãªããã«ã¹ã¿ã ãŠããã©ãŒã ãè¿œå ããããšãã§ããŸãã
if ( materialShader ) {
materialShader.uniforms.time.value = performance.now() / 1000;
}
ããããŒãããŸããïŒ
/ cc @WestLangley @bhouston @tschw
WebGLProgram.jsããã§ã«å€ãã®åŠçãè¡ã£ãŠããå Žåãã«ã¹ã¿ã ã®æååæäœãèŠæ±ããã®ã¯å°ãããããŒã«æããŸãã é¢é£ãããŠãŒã¹ã±ãŒã¹ããããŸããããã¯ãæ¢åã®#includeããªãŒããŒã©ã€ãããã®ã§ã¯ãªããæ°ãã#includeãè¿œå ããããšã§ãã å®è¡æã«THREE.ShaderLibãå€æŽããããšã§ãä»æ¥ãããè¡ãããšãã§ããŸãããåæ§ã«æ±ããŠããããã«æããŸãã
ãããããäž¡æ¹ã®ããè¯ã解決çã¯ããããªã¢ã«ã«ã«ã¹ã¿ã ShaderLibãæäŸã§ããããã«ããããšã§ããããã«ãããæåã®æååæäœãæ°žç¶çãªç Žå£ãªãã«ãçµã¿èŸŒã¿ãã£ã³ã¯ããªãŒããŒã©ã€ã/æ¡åŒµââã§ããŸãã ããã¯ä»ã®çšéã®ããã®onBeforeCompileããã¯ãæé€ãããã®ã§ã¯ãããŸããããããªãã®äŸãããããšããŠããããšãšããäžèŽããŠããããã§ãã
ãšã¯ãããrawã€ã³ã¯ã«ãŒãã«åºã¥ãã·ã§ãŒããŒæ§æã¯ãããŒãžã§ã³ããšã«åžžã«éåžžã«è匱ã«ãªããŸãã ãã¹ãŠã®ã¹ã±ã«ãã³ã³ãŒãïŒ meshphong_vert.glsl
ïŒãå«ããŠãããŸããªãå Žåã¯ãçµã¿èŸŒã¿ã®ãããªã¢ã«ã次ã®ããã«æ¡åŒµã§ããŸãã
export class MyPhongMaterial extends ShaderMaterial {
constructor({ color, radius, map, normalMap, emissiveMap }) {
super();
this.vertexShader = "...."
this.fragmentShader = "....";
this.uniforms = UniformsUtils.clone(ShaderLib.phong.uniforms);
this.isMeshPhongMaterial = true;
this.lights = true;
this.uniforms.time = { value: 1 };
//...
}
}
ãããã®å ŽåãããªãªãŒã¹ããšã«ããŸãå€æŽããªãããã«ãçµã¿èŸŒã¿ã®ã·ã§ãŒããŒã®å éšæ§æã«äŸåããå¿ èŠããããŸãã åã€ã³ã¯ã«ãŒãã¯ãã§ã«åœè£ ãããé¢æ°ã§ããã眲åãæ£ããæå®ãããŠããŸããã ã€ã³ã¯ã«ãŒãã¬ãã«ã®ãªãŒããŒã©ã€ãã§ã¯ãªããé¢æ°ã¬ãã«ã®ãªãŒããŒã©ã€ããæäŸããããšã§ãäž¡åŽã§ã¯ããã«ã¯ãªãŒã³ã§ä¿å®ãããããªããšæããŸãã
ä»æ¥ã¯æã£ãã
è¯ãïŒ 2æ10æ¥ã«ãã®ãã«ãªã¯ãšã¹ããè¡ã£ããšããããæããŸããã
https://github.com/mrdoob/three.js/pull/10791
å¯äžã®éãã¯ãã³ãŒã«ããã¯ãä»ããŠãããè¡ã£ãŠããããšã ãšæãããŸããïŒ WebGLRendererã®æªäœ¿çšã®åŒæ°ãå©çšããŸããã
ããšãã°ãthreejsãæ³ç·ãããã§åäœãããããã«ããã䜿çšããã®ã奜ãã§ãããããã§è§£æ±ºããã®ã¯ç°¡åã ãšæãããããã€ãã®åé¡ããªã³ã¯ããŸããã
ç§ã®ãã©ã³ããèŠãŠããããè©ŠããŠã¿ããããã®éåžžã«åçŽãªäŸã確èªããŠãã ããïŒç §æ/圱ãªã©ã䜿çšããŠã«ã¹ã¿ã å€åœ¢ããã¹ãããããã€ãã®ãŠããã©ãŒã ãè¿œå ããã ãã§ãïŒã
ãããããäž¡æ¹ã®ããè¯ã解決çã¯ããããªã¢ã«ã«ã«ã¹ã¿ã ShaderLibãæäŸã§ããããã«ããããšã§ããããã«ãããæåã®æååæäœãæ°žç¶çãªç Žå£ãªãã«ãçµã¿èŸŒã¿ãã£ã³ã¯ããªãŒããŒã©ã€ã/æ¡åŒµââã§ããŸãã
https://github.com/mrdoob/three.js/pull/10791ã§äœãèµ·ãã£ãŠããããæ£ç¢ºã«èŠçŽããŸãããã£ãšè¯ã説æãæžãããããã®ã«ãšæããŸã:)
ç§ã¯ããã§äœãèµ·ãã£ãŠããã®ãããããªãããšãèªããªããã°ãªããŸããã 3ã€ã«è²¢ç®ããããšããããããŠããããç解ããŠããªãã£ã人ãç¥ã£ãŠãããšæããŸãããä»ã§ã¯ã¡ãã£ãšã€ã©ã€ã©ããŠããŸãã
ç§ãæåã®æ®µèœãèªãã ãšãã«æ¢èŠæãæã£ãŠããã®ã§ãäž»ã«ã€ã©ã€ã©ããŸãïŒ
... Object3Dã®onBeforeRenderïŒïŒãšåæ§ã®æ¹æ³ã
ãããšãŸã£ããåãããšãonBeforeRender()
https://github.com/mrdoob/three.js/pull/9738ã§ãçºçããŸããããã®æ©èœãå°å
¥ããã«ã¯ã説åŸåã®ãã1幎ãããããŸããã
ãããã2åãåãéçºè ã§ïŒ ç§ã¯æããã«ããã§äœãééã£ãããšãããŠããŸãããäœã§ããïŒ åããŠãã«ããã¡ã€ã«ããã§ãã¯ã€ã³ããããšããã©ãããããããããããªãã£ãã®ã§ãå¿ããŠããŸããŸããã ããããä»åã¯ãã®ãã«ãªã¯ãšã¹ãã«å ããŠãçŸåšç«¶åãçºçããŠããŸãããç°¡åã«è§£æ±ºã§ããæ°ãæé競åã¯çºçããŸããã§ããã
誀解ããªãã§ãã ãããç§ã¯ããã®äœåã®èæ å¿ã§ã¯ãªããšæããŸããç§ã¯ãã 人ã ã«ãã£ãŠã¢ã€ãã¢ãå®è¡ããŠãã£ãŒãããã¯ãåŸãããšæããŸãã @unconedããªããåé¡ã«ç²ŸéããŠããŠãããããå¥ã®ããšãè©Šããããšãããããšã¯æããã§ãã ããªãã®ãããªãŠãŒã¶ãŒãä»ã®PRãèŠéããåå ã¯äœã§ããïŒ
ãããªã¢ã«ããšã®shaderlibã«ã€ããŠã¯ããªãè¯ããšæããŸããããã·ã§ãŒããŒå šäœãæååãšããŠè¡šç€º/æ¯èŒããŠãã£ãã·ã¥ãææ¡ããé¢æ°ãã¬ã³ãã©ãŒã«1ã€èŠã€ãããŸããããããã«ã€ããŠã¯ããã»ã©æ°åãè¯ããããŸããã§ããã ãã£ãŒãããã¯ããã£ããããã®ã«...
äŸã«æ¬ é¥ããããŸãããïŒ é ã¯ç§ã®æœè±¡çãªã¹ãã€ã¯ããŒã«ãããäœãèµ·ãã£ãŠããã®ããã¯ããã«æçœã«ãããããããŸããããäŸå šäœã¯ããå€ãã®å°é¢ãèŠã圱ã§æ©èœããŸãã ã©ããããããéãã§ãããå€ãã®é ç¹ã§sin / cosãåå ã ãšæããŸãã
æåããããçŽããŠãããšæããŸã...ã·ãŒã³ãããã¯çµ¶å¯Ÿã«æãããã§ããããã®APIã¯æ¬åœã«çŽ æŽãããã§ãïŒ
https://developer.apple.com/documentation/scenekit/scnshadable
ã²ã©ãææžåãããŠããŸããããã£ãšèå³ã®ããéšåãèŠã€ããããšã¯ã§ããŸããããåºæ¬çã«ã¯ãã·ã§ãŒããŒã®ããŸããŸãªæ®µéã§ããã¯ãæœè±¡åããŠããŸãã
ä»å¹Žã®åãã«ããŸã£ããåãã§ã¯ãªãã«ããŠãã䌌ããããªããšãããããã«èŠãããã«ãªã¯ãšã¹ããè¡ããŸããã
https://github.com/mrdoob/three.js/pull/10791
å¯äžã®éãã¯ãã³ãŒã«ããã¯ãä»ããŠãããè¡ã£ãŠããããšã ãšæãããŸããïŒ WebGLRendererã®æªäœ¿çšã®åŒæ°ãå©çšããŸããã
ãŸã ãã®PRã®äžè©±ãããããšãã§ããªããŠãã¿ãŸãã@pailheadã ç§ã®ã¢ãããŒãã®äž»ãªå©ç¹ã¯ã3ã€ã®æ°ããè¡ããå¿ èŠãšããªãããšã ãšæããŸãã
ããã¯èšã£ãŠããç§ã¯ããªããš@unconedã®ææ¡ãç 究ããããã«å°ãæéãè²»ãããŸãã
ããã¯ééããªããããšã¬ã¬ã³ããªæãã§ããã£ã3è¡ã§ãã ç§ã¯ããäžæ¹ã®ãã¿ãŒã³ãšã¯ç°ãªããã¿ãŒã³ã«åŸã£ãŠããŸããã ããå°ãåé·ãããããªããšèšãã€ããã§ãããã確ãã§ã¯ãããŸããã ãã1ã€ã®å©ç¹ã¯ãæ°ãæåã«è¡ã£ãŠè¯ãã£ãããšã ãã ãšæããŸã:)
ãããã2åãåãéçºè ã§ïŒ ç§ã¯æããã«ããã§äœãééã£ãããšãããŠããŸãããäœã§ããïŒ
ç³ãèš³ãããŸããã ç§ãèããããšãã§ããå¯äžã®ããšã¯ãããããç§ãå§åããããšããããšã§ãã é·ãè°è«ãè€éãªPRã§ãšãã«ã®ãŒãæ¶è²»ãããããããããªãã®ã§ãåŸã§ãããæ®ããŠãããåçŽãªPRã«ç§»è¡ããããšã«ããŸããã
@pailheadã¯ããªãã ãã§ã¯ãããŸããã @bhoustonã¯ããã®ãããªã®PRãã§ã@WestLangleyãšMugen87 @ã®å€ããæã£ãŠããŸããã
ç¹°ãè¿ãã«ãªããŸãããç§ãPRã奜ãã§ã¯ãªããšããããšã§ã¯ãªããPRã«ã¯ããã®æç¹ã§ã¯æäŸã§ããªã泚æãå¿ èŠã§ãããšããããšã§ãã è¯ãäŸã¯ã€ã³ã¹ã¿ã³ã¹åPRã§ãã ç§ã¯ãªããšããããèªãæéãèŠã€ããç§èªèº«ã®å®éšãè¡ããåçŽåãææ¡ããŸããã ããŸãããã°ãç§ã¯ããã«ãããå蚪ããããšãã§ããã§ãããã
ããããã¹ãŠã管çãããã¹ãŠã®PRã«åœŒããå€ãã泚æãæãããšã¯å°é£ã§ãã
äŸã«æ¬ é¥ããããŸãããïŒ é ã¯ç§ã®æœè±¡çãªã¹ãã€ã¯ããŒã«ãããäœãèµ·ãã£ãŠããã®ããã¯ããã«æçœã«ãããããããŸããããäŸå šäœã¯ããå€ãã®å°é¢ãèŠã圱ã§æ©èœããŸãã ã©ããããããéãã§ãããå€ãã®é ç¹ã§sin / cosãåå ã ãšæããŸãã
ä»ããªãã¯ããã«ã€ããŠèšåããŸã...ããããºãŒã ã€ã³ãããšæ°ããMacBookProã§10fpsã§åäœããŸãð®
圱ãšã©ã³ãã眪ã®ã³ã¹ãªã©ã ãšæããŸãããããããå€ãããããã§ãã
ãããã«ãããããã3è¡ã§å®è¡ããããšã«é©ããŠããŸããç§ã¯ããããªã¢ã«ãã©ã¡ãŒã¿ãã©ã®ããã«ãŠããã©ãŒã ã«å€æããããã®ãã¿ãŒã³ã«åŸããã«çŠç¹ãåãããããŠããŸããã éãã¯ãèŸæžã®ãããªä»£æ¿ã®ShaderLib
ãæäŸããããã #include <>
ã¯ç°ãªãã³ãŒããåã蟌ãããšã§ãã ãããçºçããåã«ã€ã³ã¯ã«ãŒããåé€ããglslã«çœ®ãæããŸãã ã·ã§ãŒããŒã®åšãã«ããçš®ã®ã©ãããŒãè¿ãå Žåããããããã®æ§æã¯ããã¯ãªãŒã³ã«ãªãå¯èœæ§ããããŸãïŒ replace()
代ããã«ãã£ã³ã¯å+ glslãæå®ããã ãã§ããããããä»ã®æ§æã®ããã«èŠããå¯èœæ§ããããŸãã ã
ãããããã°æ¬åœã«ããã§ããç§ã¯ããã»ã©å€ãã®3Dãšã³ãžã³ã䜿ã£ãããšããããŸãããããŠããã£ãšã·ãŒã³ãããã«ã¯ãã®ãããªãã®ãããããã§ãã
@unconed
onBeforeCompile()
å©ç¹ã®1ã€ã¯ãææç¹æ§ãå€ãããªãããšã ãšæããŸãã ãã®ãããçµã¿èŸŒã¿ã®ãããªã¢ã«ãæ¡åŒµãããããªæããããŸãã
export class MyMeshPhongMaterial extends MeshPhongMaterial {
constructor( parameters ) {
super( parameters );
this.onBeforeCompile = function ( shader ) {
shader.vertexShader = shader.vertexShader.replace(
'#include <begin_vertex>',
'vec3 transformed = vec3( position.x + sin( position.y ) / 2.0, position.y, position.z );'
);
};
}
}
var material = new MyMeshPhongMaterial();
material.color.setRGB( 1, 0, 0 ); // this still works
ShaderLib
ããããã®ã¯ç¢ºãã«æ³šæãå¿
èŠã§ãã ãã ããæ°žé ã«å€ãããªãããã¯ãè¿œå ããããšã¯å¯èœã§ãã
#include <begin_vertex>
% vertex %
#include <morphtarget_vertex>
#include <skinning_vertex>
% transformed_vertex %
#include <project_vertex>
% projected_vertex %
眮æã³ãŒãã¯æ¬¡ã®ããã«ãªããŸãã
this.onBeforeCompile = function ( shader ) {
shader.vertexShader = shader.vertexShader.replace(
'% vertex %',
'transformed.x += sin( position.y ) / 2.0;'
);
);
ãã¡ãããã³ã³ãã€ã«ããåã«äœ¿çšãããŠããªãããã¯ã¯ãã¹ãŠåé€ããŸãã
ã€ã³ã¹ã¿ã³ã¹ããšã®ShaderChunksãšæ¯èŒãããšæ¬¡ã®ããã«ãªããŸã
//given some material
var material = new THREE.MeshNormalMaterial();
//and some shader snippet
var myShader = [
'float theta = sin( time + position.y ) / 2.0;',
'float c = cos( theta );',
'float s = sin( theta );',
'mat3 m = mat3( c, 0, s, 0, 1, 0, -s, 0, c );',
'vec3 transformed = vec3( position ) * m;', //and making assumptions about THREE's shader framework
'vNormal = vNormal * m;'
].join( '\n' );
https://github.com/mrdoob/three.js/pull/10791 Material.defines
ã¢ãããŒããšåãïŒ
material.shaderIncludes = {
begin_vertex: myShader,
//uv_pars_vertex: [
// THREE.ShaderChunk['uv_pars_vertex'], //this doesn't have to be
// "uniform float time;",
//].join('\n')
};
material.shaderUniforms = { time: { value: 0, type: 'f' || 'float' } }; //because this could just inject it in the right place (but needs type)
_ããã¯ãã£ã³ã¯åãšãŠããã©ãŒã ãªããžã§ã¯ãã®èŸæžã«ãããŸããã ããã§ã®æååæäœã¯ãããã®ãã£ã³ã¯ãåå©çšããŠããã®äžã§äœããå®è¡ãããããšããæ¹éã«æ²¿ã£ãŠããŸãã
ãã®PRïŒ
material.onBeforeCompile = function ( shader ) {
shader.uniforms.time = { value: 0 };
shader.vertexShader = 'uniform float time;\n' + shader.vertexShader; //this feels hacky
shader.vertexShader = shader.vertexShader.replace( //this is more verbose
'#include <begin_vertex>',
myShader
);
};
onBeforeCompileïŒïŒã®å©ç¹ã®1ã€ã¯ãææç¹æ§ãå€æŽãããªãããšã ãšæããŸãã
ä»ã®PRã§ãåãããã«åäœããã®ã§ãã©ã®ããã«è¡ã£ãŠãããŸããªããšæããŸãã
ç§ãèããããšãã§ããããããç¡é¢ä¿ãªå©ç¹ã®1ã€ã¯ãåããããã¯å
ã®åãã¬ãã«ã§ãããªã¢ã«ãæäœããããã®ããžãã¯ãç¶æã§ããããšã§ãã ã©ããã«è²ãå€æŽããã³ãŒãããããåŸã§ãã®ãããªã¢ã«ã«ã«ã¹ã¿ã GLSLãè¿œå ããå Žåã¯ãã³ãŒããè¿œå ããŠè²ã®ãŠããã©ãŒã ãå€æŽã§ããŸãã ïŒããã¹ãã®å£ãã¹ãããïŒ
uv_pars_vertex
ãçŽããããå Žåã¯ã次ã®è³ªåãããããšããå§ãããŸãã
ã
float rand( vec2)
ãããªã«ã¹ã¿ã GLSLé¢æ°ãã©ãã«æ¿å ¥ããŸããïŒã
次ã«ãããã¯çã«ããªã£ãŠãããããããŸããhttps://github.com/mrdoob/three.js/pull/11050
ãã1ã€ã®è°è«ã¯ãGLSLãç¥ã£ãŠãããšä»®å®ããTHREEã®ã·ã§ãŒããŒãã¬ãŒã ã¯ãŒã¯ãç¥ã£ãŠãããšä»®å®ãããšãåµé æ§ãçºæ®ããã©ãã«äœã泚å
¥ããããèããå¿
èŠããããŸãã uv_pars_vertex
ããããªã¢ã«ã®æ¡åŒµãè¡ãã®ã«äŸ¿å©ãªå Žæã§ããããšãç解ããããã«ãå°ãèããŠã»ãšãã©ã®ã·ã§ãŒããŒã調ã¹ãå¿
èŠããããŸããã
ãã®ãããªãã®ããæœè±¡åã«ç§»è¡ãã lightingPhase
ã objectTransformation
ã perspectiveTransformation
ãªã©ã®ããã¯ã䜿çšããããšããå§ãããŸãã ãŸãã¯ããã¹ãŠã®ã·ã§ãŒããŒããã°ã©ã ã«å«ãŸããŠããå°ãªããšãguaranteedToBeAboveMainButBelowCommonsAndExtensionCalls
ãããŒãã£ã³ã¯ã % vertex %
ã§ãããç®æããŠããããã§ããïŒ ããããç§ã¯ãã®æ§æã«æ
£ããŠããŸããã
ãã®PRã¯ãçŸç¶ã§ã¯éæ¹åã«é²ãã§ããããã§ãã ã©ããã¿ããããå¿ èŠãããããç¥ãããšã«å ããŠãæ瀺çã«æååãæäœããã¬ã³ãã©ãŒããã§ã«è¡ã£ãŠããäœæ¥ã®äžéšãç¹°ãè¿ãå¿ èŠããããŸãã ãŸããæåã®è³ªåã«å ããŠå¥ã®è³ªåãããå Žå
æ¿å ¥ããŠããé¢æ°å ã§ãcommonsãã£ã³ã¯ã§å®£èšãããŠããé¢æ°ã䜿çšããã«ã¯ã©ãããã°ããã§ããïŒ
ã·ã§ãŒããŒå šäœã«ãŠããã©ãŒã ãè¿œå ããã ãã§ãªããããå€ãã®æååæäœãè¡ã£ãŠããããšã«æ°ä»ããããããŸããã
uv_pars_vertex
ããããªã¢ã«ã®æ¡åŒµãè¡ãã®ã«äŸ¿å©ãªå Žæã§ããããšãç解ããããã«ãå°ãèããŠã»ãšãã©ã®ã·ã§ãŒããŒã調ã¹ãå¿ èŠããããŸããã
ç§ãã¡ããªãŒããŒãšã³ãžãã¢ãªã³ã°ããªãéãããããåé¿ããæ¹æ³ã¯ãªããšæããŸãã % vertex %
ã®ã¢ã€ãã¢ã¯ãããã¯ã«ååãä»ããŠãã³ãŒããæ¿å
¥ããŠããç¶æ
ãå€ããå°ãªããæããŠãããããšã§ãããã©ã®å€æ°ãã©ã®æç¹ã§äœ¿çšå¯èœã§ããããææžåããã®ã¯é£ããã§ãããã ã
çµã¿èŸŒã¿ã®ãããªã¢ã«ãããã³ã°ãèš±å¯ããããã®æãéããŠããŸãããé©åãªããµããŒãããæäŸã§ãããšã¯æããŸããã ãŠãŒã¶ãŒã¯ãç©äºãå£ããå¯èœæ§ãããããšã«æ³šæããå¿ èŠããããŸãã
ä»ã®PRã§åãçµãã§ã¿ãŸããã å°ãªããšãé¢æ°ãããªãšãŒã·ã§ã³ãå±æ§ããŠããã©ãŒã çšã«ãããŒããã¯ãè¿œå ããŸããã GLSLããžãã¯ã®å€ãã¯ãã§ã«æ§é äœã§çºçããŠãããã·ãŒã³ãããã¯åå€æ°ãææžåããŠããŸãïŒãã ããåãææžãèŠã€ããããšã¯ã§ããŸããïŒã
ç§ãã¡ãé²ãã«ã€ããŠããããããªãã¡ã¯ã¿ãªã³ã°ããå¿ èŠããããŸããããããã®ç·ã«æ²¿ã£ãŠäœãããããŸãïŒ
#ifdef PHASE_FOO
#include <shader_foo>
//someGlobalStruct.mvPosition = modelViewMatrix * myLogic( transformed );
//if there is glsl provided for phase "foo" document that it should operate on "transformed"
//and that it should return "mvPosition"
#end including <shader_foo>
#else
//default
#ifdef USE_SKINNING
vec4 mvPosition = modelViewMatrix * skinned;
#else
vec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 );
#endif
#ifdef PHASE_BAR
#include <something_like_this>
//mvPosition = myPostDefaultTransformationLogic( mvPosition );
#endif
gl_Position = projectionMatrix * mvPosition;
#endif
ãã¡ãããifdefsãšincludesã¯ãããããã®ããã«ã¯æ©èœããŸããã ããããä»ã®ã¢ãããŒãã§ã¯æ¯èŒçç°¡åã§ããããšãããããŸãã 空ã®æååã䜿çšããŠãåžžã«#include <some_phase>
è¿œå ã§ããŸãã #ifdef
ã䜿çšããŠãããªã¬ãŒããããã®ã管çããã®ã«åœ¹ç«ã€å¯èœæ§ããããŸãã ãããã£ãŠãããšãã°ããvertex_transformationããã§ãŒãºã®ããžãã¯ãæäŸããå Žåãã·ã§ãŒããŒã¯æäŸãããã®ããã¹ãŠå®çŸ©ããŸãã åãã£ã³ã¯ãGLSLã§äœãããããææžåãããšãå
šäœçã«åœ¹ç«ã¡ãŸãã æœè±¡åãããã«é²ããããšãªãããã£ã³ã¯ãçŸåšã©ã®ããã«æ§é åãããŠãããã«ã€ããŠããã®ããããããã°çŽ æŽããããšæããŸãã
çµã¿èŸŒã¿ã®ãããªã¢ã«ãããã³ã°ãèš±å¯ããããã®æãéããŠããŸãããé©åãªããµããŒãããæäŸã§ãããšã¯æããŸããã ãŠãŒã¶ãŒã¯ãç©äºãå£ããå¯èœæ§ãããããšã«æ³šæããå¿ èŠããããŸãã
ç§ãã¡ã¯ãã§ã«ãã¹ãŠã®çŽ æã§å©çšå¯èœãªå®çŸ©ã®ãã®ãæã£ãŠããŸãã https://github.com/mrdoob/three.js/issues/10764ã¯ã THREE.ShaderLib
ãå€æŽããŠããã Material
ã€ã³ã¹ã¿ã³ã¹ã§.defines
ããããã£ãå®çŸ©ããããšãææ¡ããŸããã 確ãã«ãç§ããšã³ããªãæžããŸã§ããããã£ã¯ææžåãããŠããŸããã§ããïŒãããããªãã¯ãããæ¿èªããŸãã:)ïŒããããŠãŸã å®çŸ©ãããŠããŸããã
ãããããããçŸåšæ©èœãããã¹ãŠã®ãããªã¢ã«ã«ç¶æ¿ãããŠããæ¹æ³ã¯ãµããŒããããŠããŸããããã«äœããå ¥ãããšããã®ãããªã¢ã«ã®ã·ã§ãŒããŒã«åœ±é¿ããŸãã ããã«ããã§ã«ã·ã§ãŒããŒã©ã€ãã©ãªã®äžéšã§ãããã®ãå®çŸ©ãããšãåé¡ãçºçããå¯èœæ§ããããŸãã
è³¢ããå°»ã«ãªãããšããŠããã®ã§ã¯ãªããäŸãèãåºãããšããŠããã ç§ã¯äž»ã«å®çŸ©ã䜿çšShaderMaterial
ããããã¯ãã¹ãŠã®ææã«åœ±é¿ãäžããªããã©ãã ãã®ã§WebGLRenderer
äœåã 次ã®ãããªããžãã¯ã¯ãããŸããã
Phong
ãããªãããªã¢ã«ã®æœè±¡åã®ãããªãã¯ããã«è³¢ãè¡šé¢ã®å Žåã¯ãå®çŸ©ãèæ ®ããªãã§ãã ããã 3ã€ã¯ã·ã§ãŒããŒãã£ã³ã¯ããªãŒããŒã©ã€ãããããã«èšèšãããŠããããPhongãã³ãã¬ãŒãã¯GLSLãå®è¡ããå¿ èŠãããããšã®æçµçãªæš©éã§ãããããã䜿çšããé ãã®ã«åœ¹ç«ã€ãããGLSLå®çŸ©ãããã«å¹²æžããªãããã«ããããšã¯çã«ããªã£ãŠããŸãã
ãããå£ãããã©ããã¯å®å šã«ã¯ããããŸããããè©ŠããŠã¿ãå¿ èŠããããŸãã
ããã¯èšã£ãŠãããããå€ãã®å©çãããããã®ã§ããã°ãç§ã¯ç©äºãå£ããªãã·ã§ã³ã欲ããã§ãã ããªãã«ãã»ã«åãããå°ããªGLSLã¹ããããã䜿çšãããšã3ã€ã®ããŒãžã§ã³ãç°¡åã«å€æŽããŠãæ³ç·ããããç°ãªãæ¹æ³ã§ã¬ã³ããªã³ã°ã§ããŸãã æ³ç·ãåãããããå¥ã®æ³ç·ã«å€æããããšã¯éåžžã«ç°¡åã§ããå®å šã«ç°ãªãæ¹æ³ã§ã³ã³ãã¥ãŒã¿ã°ã©ãã£ãã¯ã¹ãå§ããªãéãããããå£ããã®ãèŠãããšãã§ããŸãã:)
ã€ã³ã¹ã¿ã³ã¹åã¯å¥ã®äŸã§ããïŒ
ãããANGLE_INSTANCED_ARRAYSã䜿çšãããã®ã§ããã3ã€ã¯ã·ã£ããŠãŸãã¯PBRãããªã¢ã«ã§ã¯ãµããŒããããŠããªãããã§ãããããã®2è¡ãè¿œå ããŠãæ©èœãããŠãã ãããã
ãã®æ©èœãã€ãã«three.jsã«ç»å Žããã®ãèŠãŠããããã§ã:)ã ã¯ãã yet another material modifier PR
ãäœæããŸããïŒhttps://github.com/mrdoob/three.js/pull/7581ïŒå€ãããŠã³ãŒãã¯ããé¢ä¿ãããŸããããåºæ¬çã«ã¯@mrdoobã®ãããªããã¯ã
ãã®æ©èœã䜿çšãããã»ãšãã©ã®äººã¯ãããã©ã«ãã®ãããªã¢ã«ãå®å
šã«æžãçŽãã®ã§ã¯ãªããããããã«ãå€æŽããããšæãã®ã§ãå€æŽå
容ãç°¡åã«ç解ã§ããã®ã§ãäºåå®çŸ©ãããããã¯ã®ã¢ã€ãã¢ã奜ãã§ãã
ç§ã¯ãã®PRã®ã·ã³ãã«ãã奜ãã§ãããããæ§é åãããã¯ãªãŒã³ãªæ¹æ³ã§ç©äºãè¡ãå Žåã¯ãã³ãŒãã«çœ®ãæããããã¯ã®èŸæžãšããŠããã©ãŒã ãã«ã¹ã¿ã ã³ãŒããè¿œå ããç°¡åãªæ¹æ³ããã§ã«çšæããŠããããšããå§ãããŸããæååã眮ãæããã ãã§ãã
@ fernandojsg ïŒ10791ããã§ãã¯ããŠãã£ãŒãããã¯ãæäŸã§ããå¯èœæ§ããããŸããã¡ã€ã³ã®ããå€åŽã«è¿œå ã®ããã¯ïŒãpre_vertexããªã©ïŒãé 眮ãã管çãå°ãå¢ããŠããããšãé€ãã°ãããã¯éåžžã«ãã䌌ãŠããŸãã
@fernandojsgããªãã®PRãå¿ããŠããŸããðã ããªãã®PRã¯ãç§ããããæ©èœããŠããã®ãèŠå§ããæ¹æ³ãšéåžžã«ãã䌌ãŠãããšæããŸãã æœåšæèïŒ
è³¢ããå°»ã«ãªãããšããŠããã®ã§ã¯ãªããäŸãèãåºãããšããŠããã ç§ã¯äž»ã«å®çŸ©ã䜿çš
ShaderMaterial
ããããã¯ãã¹ãŠã®ææã«åœ±é¿ãäžããªããã©ãã ãã®ã§WebGLRenderer
äœåã
ã©ã€ãã©ãªããã®ããã«ãããã³ã°å¯èœã§ããããšãå¬ããæããŸãããæå³ãããŠããªããã®ã«äžæ£äœ¿çšæ©èœãå éšçã«äœ¿çšããã¹ãã§ã¯ãããŸããã ããããã°ãå£ããããã³ãŒãã«ãªã£ãŠããŸãã®ã¯ç°¡åã§ãã
ïŒ7581ãããäžåºŠèªãã§ããŸã... % HOOKS %
ãè¿œå ããŠã次ã®ãããªã¯ã©ã¹ãäœæã§ããŸãã
THREE.ExtendedMaterial = function ( material, hooks ) {
material.onBeforeCompile = function ( shader ) {
var vertexShader = shader.vertexShader;
var fragmentShader = parameters.fragmentShader;
for ( var name in hooks ) {
vertexShader = vertexShader.replace( '%' + name + '%', hooks[ name ] );
fragmentShader = fragmentShader.replace( '%' + name + '%', hooks[ name ] );
}
shader.vertexShader = vertexShader;
shader.fragmentShader = fragmentShader;
};
return material;
};
次ã«ããããè¡ãããšãã§ããŸãïŒ
`` `js
var material = new THREE.ExtendedMaterialïŒ
æ°ããTHREE.MeshBasicMaterialïŒïŒã
{é ç¹ïŒ 'transformed.x + = sinïŒposition.yïŒ/ 2.0;' }
ïŒ;
ã ããåé¡ã¯ãã©ã®ããã¯ãå¿ èŠããšããããšã§ãã
VERTEX
TRANSFORMED_VERTEX
PROJECTED_VERTEX
NORMAL
TRANSFORMED_NORMAL
FRAGMENT_UNIFORMS
INPUT_FRAGMENT
OUTPUT_FRAGMENT
@mrdoobäŸãšããŠãMeshBasicMaterial
é ç¹ã·ã§ãŒããŒã«æ¿å
¥ããå¿
èŠãããå Žæããã®èŠç¹ã§ç¢ºèªã§ããŸãã
ãããŠãæ®ãã®è³æã«ã€ããŠã¯ããã«ãããŸã:)
VERTEX_UNIFORMS
ã¯ããŸãã«ãæèŠãåãããŠããããã«èãããŸãããé¢æ°ãå±æ§ããŸãã¯å€åãã©ãã«è¿œå ããå¿
èŠããããŸããïŒ PRE_VERTEX
ãäœãïŒ
NORMAL_MAP
ã¯ééããªãå¿
èŠã§ã
vert:
PRE_VERTEX
VERTEX
TRANSFORMED_VERTEX
PROJECTED_VERTEX
NORMAL
TRANSFORMED_NORMAL
UV
fragment:
PRE_FRAGMENT
INPUT_FRAGMENT
LIGHT
NORMAL
OUTPUT_FRAGMENT
VERTEX_UNIFORMS
ã¯ããŸãã«ãæèŠãåãããŠããããã«èãããŸãããé¢æ°ãå±æ§ããŸãã¯å€åãã©ãã«è¿œå ããå¿ èŠããããŸããïŒPRE_VERTEX
ãäœãïŒ
ããŒããæèŠã¯ïŒ ã©ãããŠïŒ
attribute vec4 aMyAttribute;
ã¯ãŠããã©ãŒã ã§ã¯ãããŸãã:)
float myRand( vec4 foo ) { /*logic*/ return vec4(bar,baz)}
ã¯ãŠããã©ãŒã ã§ã¯ãããŸãã
varying vec3 vMyVarying;
ããŠããã©ãŒã ã§ã¯ãããŸãã
è€æ°åœ¢ã§ã¯ãªããããŠããã©ãŒã ã§ã¯ãªã
å±æ§ãã泚å
¥ãããããã®ãŠãŒã¹ã±ãŒã¹ã¯äœã§ããïŒ
代ããã«geometry.addAttribute( 'aMyAttribute', ... )
ã䜿çšããã¹ãã§ã¯ãããŸãããïŒ
ããªããããã宣èšããå¿ èŠããªãããšãç§ã¯ç¥ããŸããã§ããã ãŸã å€åãšæ©èœãæ®ããŠããŸããïŒ
ãŸã å€åãšæ©èœãæ®ããŠããŸããïŒ
ããèŠç¹ãã
GLSLã§å±æ§ã宣èšããå¿ èŠã¯ãããããŸãããïŒ ãŠããã©ãŒã ã®ããã«æ©èœãããšæããŸãããGLSLã§å®£èšããŸãããJSã§å ¥åããå¿ èŠã¯ãããŸããã
ãã®ãªã¹ãã¯ãã³ãŒããããªãæ£ãã°ã£ãŠããŸãç¹å®ã®äºæã«é¢ããŠã¯ãããªãæ¥éã«å€§ãããªãå¯èœæ§ããããšæããŸãã æ³ç·ããããå®è¡ãã1ã€ã®æ¹æ³ã«ã¯ãvertãšfragã®äž¡æ¹ã§ã®å€åãšå€æããžãã¯ãšãã2ã€ã®è¿œå å±æ§ãå«ãŸããŸãã
ã·ã³ãã«ã§ãšã¬ã¬ã³ããªææ°ã®å€æŽãæ°ã«å
¥ã£ãŠããŸãã ç§ã¯@pailheadã«åæããã°ããŒãã«ã¹ã³ãŒãã«ã³ãŒããé
眮ããå Žæãå¿
èŠã§ãã https://github.com/mrdoob/three.js/pull/7581ã§ã preMainVertex
preMainFragment
ãã°ããŒãã«ã«æ³šå
¥ããŠãããŸããŸãªæ©èœã«äœ¿çšã§ããããã«ããŸããã ããããglobalVertex/Fragment
ãªã©ã®ååã®æ¹ãè¯ãã§ãããã
GLOBAL_VERTEX
ãšGLOBAL_FRAGMENT
ããã§ããð
æ£ç¢ºã«ç§ãä»ã®PRã§ãããã«ååãä»ããæ¹æ³ðð
@pailheadããããã³ãŒããããŒãžããç§èš£ã¯ããã£ãŠããŸã@ mrdoobãæçµçã«åæ§ã®ããšãè¡ãããšã
ä»ãç§ããã®ååã奜ãã§ãããã§ç§ãã¡ã¯è¡ãæºåãã§ããŠãããšä¿¡ããŠããŸããããããšãäœãã足ããŸãããïŒ äŸãPRãããã®æ°ããã³ãŒãã«å€æããŠã¿ãŸã;ïŒ
ã³ãŒããå ¥ãéšåã¯åé¡ãããŸãããã¿ã€ã ã©ã€ã³ã¯å°ããããŠããŸãã ïŒ7581ã¯ã»ãŒ2幎åã«ææ¡ãããŸããã https://github.com/mrdoob/three.js/issues/10789ã§åç §ãããŠããªãã£ããããããããã¬ãŒããŒããå€ããŸããã ç§ã¯ãããã¶ã€ãããããã©ãŒã¯ãããããã§ãããã
ã¢ãžã¥ãŒã«ãã€ã³ããŒãããŠèªåã®3ã€ãéžãã ãšããŠããéå ¬åŒã®ã³ã¢ã¢ãžã¥ãŒã«ã䜿çšããããšã«ããŸãæºè¶³ããŠããŸããã ããããfooãåŠçããnpmããã±ãŒãžããããŸãããšèšãã®ã¯ã¯ããã«ç°¡åã§ãã ãã®ããããã®ãããªPRã¯éèŠã ãšæããŠããŸããã3ã€ã§ã¯ååãªæè»æ§ããããŸããã
å©çïŒ
ã©ã®ãããªå©çããããŸããïŒ ð
ã³ãŒããå ¥ãéšåã¯åé¡ãããŸãããã¿ã€ã ã©ã€ã³ã¯å°ããããŠããŸãã ïŒ7581ã¯ã»ãŒ2幎åã«ææ¡ãããŸããã https://github.com/mrdoob/three.js/issues/10789ã§åç §ãããŠããªãã£ããããããããã¬ãŒããŒããå€ããŸããã ç§ã¯ãããã¶ã€ãããããã©ãŒã¯ãããããã§ãããã
äœïŒ æ°ããPRãäœæããåã«ãéããŠãããã¹ãŠã®PRããã§ãã¯ããŠããŸãããïŒ #trololol
NS ïŒïŒ
ãªã¹ãã«ãã€ã€ã«ããŠãã§ããã ãæ©ãïŒD
ãã®ã·ã§ãŒããŒã¯ïŒããšãã°ïŒïŒ
#include <shadowmap_pars_vertex>
void main() {
#include <begin_vertex>
#include <project_vertex>
#include <worldpos_vertex>
#include <shadowmap_vertex>
}
ãããªé¢šã«èŠããïŒ
#include <shadowmap_pars_vertex>
void main() {
% begin_vertex %
% project_vertex %
% worldpos_vertex %
% shadowmap_vertex %
}
ããŒããããããã¹ãŠã眮ãæããã®ãããããšãçŸåšã®åäœã®äžéšãæ®ããŠã³ãŒããæ¿å ¥ããã ããªã®ãã¯ããããŸããã
#include <shadowmap_pars_vertex>
%GLOBAL_VERTEX%
void main() {
%PRE_VERTEX%
#include <begin_vertex>
...
}
ç§ã®æåã®ã¢ãããŒãã¯ãã€ã³ã¯ã«ãŒãã®æ®ãã®éšåããã®ãŸãŸã«ããŠãäœåãªã³ãŒããæ¿å ¥ããããšã§ããã
ãããã£ãŠã % hook %
ã¯å®éã®ããã¯å°çšã§ãã <begin_vertex>
ã眮ãæãããå Žåã§ããæååã§ãããæ¢ãå¿
èŠããããŸãã begin_vertex
ããã¯ã¯ãããŸãããïŒ
ç§ã®PRã§ã¯ããããªã¢ã«ã®åäœãå°ãå€æŽãããã£ãã ãã§ããéåžžãfsãå®å
šã«å®è¡ãããåŸããŸãã¯@mrdoobã圌ã®äŸã§ç€ºãããã®ãšåæ§ã®å€æã«å¯ŸããŠãããã€ãã®è²è£æ£ãè¡ããŸãã
ãã ããåã€ã³ã¯ã«ãŒããå®å
šã«çœ®ãæãããå Žåã¯ãã€ã³ã¯ã«ãŒãã®ä»£ããã«ããã¯ã䜿çšããããã¯ããã€ã³ãããªãã£ãå Žåã«åããŠãã€ã³ã¯ã«ãŒãèªäœãæ¿å
¥ããããžãã¯ãè¿œå ããå¿
èŠããããŸãã
æ³ç·ã«å¯ŸããŠãããå®è¡ããããšæããŸãïŒå°é¢æ°ã䜿çšããã3ds maxãŸãã¯mayaããŸãã¯æ³ç·ããããçæãããŠããå Žæããã®å®éã®TBNæ
å ±ã䜿çšããŸãïŒã MeshPhongMaterial
ãã€ã³ã¹ã¿ã³ã¹ã§æ©èœããããã«é©åãããã«ã¯ãããã€ãã®ãã£ã³ã¯ãå®å
šã«çœ®ãæããå¿
èŠããããŸããããããã¯ãã®ãããªãšããžã±ãŒã¹ã®ããã«æããŸãã
ãããã¯ç§ãèããããšãã§ãã2ã€ã§ããç§ã¯ãã£ãšããã®ã ããããšæããŸãã
ãããã£ãŠã
% hook %
ã¯å®éã®ããã¯å°çšã§ãã<begin_vertex>
ã眮ãæãããå Žåã§ããæååã§ãããæ¢ãå¿ èŠããããŸããbegin_vertex
ããã¯ã¯ãããŸãããïŒ
äž¡æ¹ã亀æã§ããŸãã çŸåšã®ã³ãŒãã§ã¯ããã§ã«äœã§ã眮ãæããããšãã§ããŸãã %HOOK%
ãã®ã¯äŸ¿å®äžã®ãã®ã§ãã
ïŒ11562ã§è¿°ã¹ãããã«ã亀æå¯èœãªã·ã§ãŒããŒãã£ã³ã¯ã®æŠå¿µã¯ã©ãã§ããïŒ
äŸïŒ
const material = new THREE.MeshPhongMaterial({
color: 0xffffff,
map: texture,
parts: {
frag: {
map_pars_fragment: `
uniform sampler2D map;
uniform sampler2D map2;
`,
map_fragment: `
vec4 texelColor = texture2D( map, vUv );
vec4 texelColor2 = texture2D( map2, vUv );
texelColor = mapTexelToLinear(
mix( texelColor, texelColor2, progress)
);
diffuseColor *= texelColor;
`
}
}
});
material.uniforms.progress = {value: 1};
material.uniforms.map2 = {value: texture2};
ããã¯ã1ã€ã®ãããªã¢ã«äžã®è€æ°ã®ãã¯ã¹ãã£éã®é·ç§»ã®ã³ãŒããããã«ç°¡åã§ãããã瀺ããŠããŸãã
ç°¡åã«å®è£ ã§ããäžèŠãªã³ãŒããäœæããå¿ èŠããããŸããã
@ sasha240100
https://github.com/mrdoob/three.js/pull/10791ã¯ã parts
ãshaderChunks
ãšåŒã°ãããããå£è«ã
ïŒroll_eyesïŒð
ãã£ã³ã¯ã¯ãã§ã«ããŒã¯ãããŠããã®ã§ã frag{}
èŸæžãå¿
èŠãããŸããã ãããã¯ãã¹ãŠ_fragment
ãš_vertex
æã£ãŠããŸãã
ããã¯ãæååãæ€çŽ¢ããŠçœ®ãæããå¿ èŠããããã®ãèŠã€ããå¿ èŠãããããšãé€ããŠãåãããšãè¡ããŸãã
@pailheadã¯ãã frag: {}
åé€ããŸãããã ãããªã¢ã«ã·ã§ãŒããŒãé£çµããåã«æž¡ãå¿
èŠããããããåŒæ°ãšããŠäœ¿çšããŸããã ãã®å Žåãé£çµåŸã«æ¢åã®ããŒãã亀æããããšãç°¡åã«åé¿ã§ããŸãã
å®éã«ã¯ãåŒæ°ãšããããã£ã®äž¡æ¹ãè¿œå ã§ããŸãã color
ããã«
ããã¯ä»ã©ãã«ãããŸããïŒ äŸã.replace()
ãå®è¡ããŠããã®ãããããŸãããããã¯/亀æå¯èœãªãã£ã³ã¯ã衚瀺ãããŸãããïŒ @mrdoob
ãŸã ããã«æ»ãããšãã§ããŠããŸããã
% hook %
PRããããã§ããïŒ
äžèšã®ã³ã¡ã³ããããæ¡åŒµãããè³æãå¿ èŠã§ããïŒ
THREE.ExtendedMaterial = function ( material, hooks ) {
material.onBeforeCompile = function ( shader ) {
var vertexShader = shader.vertexShader;
var fragmentShader = parameters.fragmentShader;
for ( var name in hooks ) {
vertexShader = vertexShader.replace( '%' + name + '%', hooks[ name ] );
fragmentShader = fragmentShader.replace( '%' + name + '%', hooks[ name ] );
}
shader.vertexShader = vertexShader;
shader.fragmentShader = fragmentShader;
};
return material;
};
ããã¯ã®å ŽæãéžæããŠææžåããããšã¯ãå®éã«ã¯ããã»ã©ç°¡åã§ã¯ãªããããããŸãããïŒ æž¡ãããhooks
ãchunks
眮ãæããŠãä»ã®ãšããglobal_vert
ãšglobal_frag
ãè¿œå ããŠãã€ã³ã¯ã«ãŒããæ¢ããŸããïŒ ç§ãæžããä»ãããã¯3人ã®è²¬ä»»ã§ããããã¹ãã§ã¯ãªãããã«æããŸãããäžæ¹ã§ãå°æ¥çã«ã¯THREE.ExtendedMaterial
ã% hook %
ã¹ã¿ãããã§ããããïŒ
ããªããTHREE.BASæ¡åŒµåãç¥ã£ãŠãããã©ããã¯ããããŸããã 次ã®ããã«ãã«ã¹ã¿ãã€ãºããããããªã¢ã«ããé åãšããŠã¢ã¯ã»ã¹ã§ããå ã®ãããªã¢ã«ã®ãã¬ãŒã¹ãã«ããŒã䜿çšããŸãã
var material = new BAS.PhongAnimationMaterial({
flatShading: true,
vertexColors: THREE.VertexColors,
side: THREE.DoubleSide,
uniforms: {
uTime: {type: 'f', value: 0}
},
vertexFunctions: [
// cubic_bezier defines the cubicBezier function used in the vertexPosition chunk
BAS.ShaderChunk['cubic_bezier'],
BAS.ShaderChunk['quaternion_rotation']
],
vertexParameters: [
'uniform float uTime;',
'attribute vec2 aDelayDuration;',
'attribute vec3 aStartPosition;',
'attribute vec3 aEndPosition;',
'attribute vec3 aControl0;',
'attribute vec3 aControl1;',
'attribute vec4 aAxisAngle;'
],
vertexInit: [
'float tProgress = mod((uTime + aDelayDuration.x), aDelayDuration.y) / aDelayDuration.y;',
'vec4 tQuat = quatFromAxisAngle(aAxisAngle.xyz, aAxisAngle.w * tProgress);'
],
vertexPosition: [
'transformed = rotateVector(tQuat, transformed);',
'transformed += cubicBezier(aStartPosition, aControl0, aControl1, aEndPosition, tProgress);'
]
});
åçŽãªèŠåã«åºã¥ããŠãããšããäºå®ãæ°ã«å
¥ã£ãŠããŸããããšãã°ã vertexInit
ãšfragmentInit
ã¯mainïŒïŒé¢æ°ã®å
é ã«ãããŸãã vertexParameters
ãšfragmentParameters
ã¯ã·ã§ãŒããŒã®äžéšã«ããããŠããã©ãŒã ãŸãã¯å±æ§ãå®çŸ©ããŸãã vertexFunctions
ãšfragmentFunctions
ã¯ãmainïŒïŒé¢æ°ã®åã«ãããŸãã æ³ç·ãäœçœ®ãªã©ã«ã€ããŠã¯ã以äžåæ§ã§ãã
äœçœ®ã§ãããããã«ãå€æ°transformed
ãå€æŽããŠãæçµçãªäœçœ®ãå€æŽããŸãã ããšãã°ããã©ã°ã¡ã³ãã·ã§ãŒããŒã®æ³ç·ïŒ objectNormal
ïŒãŸãã¯è²ïŒ diffuseColor
ïŒã«ã€ããŠãåæ§ã§ãã
ããã¯Phongãããªã¢ã«ãã©ã®ããã«èŠãããã§ããããã¬ãŒã¹ãã«ããŒã®ã¿ãè¿œå ããŸãïŒ //github.com/zadvorsky/three.bas/blob/master/src/materials/PhongAnimationMaterial.js
ããã«ã¡ã¯ã¿ããªãç§ã¯ã³ã³ãããã©ããŒããããšããŠããŸããããæ£çŽãªãšãããç§ã¯ã²ãŒã éçºè ã§ã¯ãªãããã³ããšã³ãããæ¥ãã®ã§ãç§ã¯è² ããŸããã
MTLãããŒãããããšãããšã次ã®ããã«ãªããŸãã
material.onBeforeCompile.toStringïŒïŒã¯æªå®çŸ©ã§ãã
ç§ã®MTLãã¡ã€ã«ã¯å ã .psdãã¡ã€ã«ãæããŠããŠãåããã©ã«ããŒãå«ãæ°å°ãªãpngã®1ã€ã«å€æŽããŸããïŒéåžžïŒpsdãããŒãããããšã¯ã§ããªããšæããŸããããšã«ããpsdã§ã倱æããŸãã
# Blender MTL File: 'goblin.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.001617 0.005682 0.002517
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
map_Kd Normal.png
ã³ã³ãœãŒã«åºåã¯æ¬¡ã®ãšããã§ãã
THREE.WebGLRenderer 87
bundle.js:54570 OBJLoader: 29.447998046875ms
bundle.js:28429 Uncaught TypeError: Cannot read property 'toString' of undefined
at WebGLPrograms.getProgramCode (bundle.js:28429)
at initMaterial (bundle.js:32350)
at setProgram (bundle.js:32542)
at WebGLRenderer.renderBufferDirect (bundle.js:31605)
at renderObject (bundle.js:32335)
at renderObjects (bundle.js:32308)
at WebGLRenderer.render (bundle.js:32072)
at bundle.js:9658
at bundle.js:53976
at XMLHttpRequest.<anonymous> (bundle.js:40153)
䜿çšããŠããã³ãŒãã¯äž»ã«æ¬¡ã®ãšããã§ãã
OBJLoader(THREE);
const modelLoader = new THREE.OBJLoader();
const textureLoader = new MTLLoader();
textureLoader.setTexturePath( 'models/' );
textureLoader.load('models/goblin.mtl', function( materials ) {
materials.preload();
modelLoader.setMaterials( materials );
modelLoader.load('models/goblin.obj', function ( obj ) {
scene.add( obj );
renderer.render( scene, camera );
});
});
renderer.render( scene, camera );
}
ããã¯ã¢ãã«ã®åé¡ã§ããïŒ ã¹ãªãŒã§ïŒ mtlããŒããŒã§ïŒ 解決çã¯ãããŸããïŒ
ã©ããªå©ãã§ãããã ããã°å¹žãã§ãã
ããããšãã
material.shader = shader
ã§material.onBeforeCompile(shader=>...)
material.shader = shader
ãããªããšãããå¿
èŠããããŸããïŒ
ç§ã¯ãããããäžæ Œå¥œã«æãããšæããŸããããæç¹ã§ä»ã®ææ¡ãåæ€èšãã䟡å€ããããããããŸãã:)
@jjalonso
ããã¯ãã°ã®ããã§ãïŒ
ãããåå ã§ããã Material
ã«ãã®æ©èœããªãåå ã¯äœã§ããïŒ
https://github.com/mrdoob/three.js/blob/35a26f178c523514673d992da1aece23c1cfca6e/src/renderers/webgl/WebGLPrograms.js#L244
@mrdoob
ãããã®æ¡åŒµã·ã§ãŒããŒãæ£ãããã£ãã·ã¥ãããŠããªãå¯èœæ§ã¯ãããŸããïŒ 2ã€ã®ç°ãªããããªã¢ã«ã䜿çšããããšããŠããŸãã1ã€ã¯dithering_fragment
å€æŽãããŠããããã1ã€ã¯å€æŽãããŠãdithering_fragment
ãã£ã³ã¯ã®ãªããã®ã ãã䜿çšãããŠããããã«èŠããŸãã
ç§ã¯ãã®ãã£ãã«ã§ãããåçŸããããšãã§ããŸããã§ãã
https://codepen.io/anon/pen/KQPBjd
ããããç§ã®äŸã§ã¯ãã®ã³ãŒãã䜿çšããŸã
const dithering_fragment =
`
gl_FragColor.xyz *= foobar
`
// in onBeforeCompile
console.log(shader.fragmentShader)
md5-0f1a3ac67268b230968df20abdbd03d1
/**
#if defined( DITHERING )
gl_FragColor.rgb = dithering( gl_FragColor.rgb );
#endif
gl_FragColor.xyz *= foobar
}
*/
ããããä»ã®ã€ã³ã¯ã«ãŒããšå®çŸ©ãå ±æããã·ãŒã³ã«å¥ã®ãããªã¢ã«ãè¿œå ããŠããšã©ãŒã¯çºçããŸããã
ãããåå ã§ãïŒ
äž¡æ¹ã®ãããªã¢ã«ã«ããã€ãã®ããžãã¯ãæäŸãããŠããåãé¢æ°ããããããžãã¯ã®å€æ°ãã³ãŒã«ããã¯ã®ç¯å²å€ã§ãããããäž¡æ¹ã®ãããªã¢ã«ãåãããã·ã¥ãååŸããŸããïŒ
array.push( material.onBeforeCompile( obtainShaderSomehow ) )
https://github.com/mrdoob/three.js/pull/10791ã¯æ¬¡ã®ããã«è§£æ±ºããŸããïŒ
global_vertex
ãšglobal_fragment
ãã¬ãŒã¹ãã«ããŒ/ããã¯ãåé€ããå Žåãä»ã®ãã«ãªã¯ãšã¹ããåæ€èšããŸããïŒ ããããããã°ãå€ãã®ãã¡ã€ã«ã«è§ŠããŸãããããããããªããã°ãã³ãŒãã¯å°ãªããªããŸãã 3è¡ã§ã¯ãããŸããããæ£ããããã·ã¥ãããŸã:)
ãã®ãã£ãã«ã§#41
ã«ã³ã¡ã³ãããhttps://codepen.io/anon/pen/KQPBjd
ã·ãŒã³å
ã®ä»ã®ã¡ãã·ã¥ã®ãããªã¢ã«ãå€æŽãããŸãã
ããã¯æè¿ã®ãªãªãŒã¹ã«å«ãŸããŠããŸããããããšããã¹ãŠãŸã éçºäžã§ããïŒ
@mrdoob .onBeforeCompile()
ãããã³ã°ããããããªã¢ã«ãã·ãªã¢ã«åããã®ã¯é£ããïŒãŸãã¯äžå¯èœïŒãšæããŸãã å®å
šã«æ©èœããïŒã¬ã³ããªã³ã°ãã³ããŒãã¯ããŒã³ãã·ãªã¢ã«åãªã©ïŒå€æŽãããçµã¿èŸŒã¿ãããªã¢ã«ãå¿
èŠãªå ŽåããŠãŒã¶ãŒã¯ShaderMaterial
ã䜿çšããå¿
èŠããããšæããŸããïŒ
_以äžãå¯èœãªéãçŽ æŽãããã建èšçã§ã察ç«ã®ãªãæ¹æ³ã§èªãã§ãã ãã_ :)
@takahiroxãªãããã䞻匵ããç¶ããã®ã§ããïŒ
ãããã³ã°ããããããªã¢ã«ãã·ãªã¢ã«åããã®ã¯é£ããïŒãŸãã¯äžå¯èœïŒãšæããŸã
ããªããæã€çŽ æãããã¯ããããšonBeforeCompile
ããªãã ãã®ä»»æã®ä»ã®ææãšåãã§ãããŠããã©ãŒã ãè¿œå ããŸãã éãã¯ãããŸããã material.color
ãã·ãªã¢ã«åã§ããã®ãªãããªãmaterial.userData.myColor
ãã·ãªã¢ã«åã§ããªãã®ã§ããïŒ
ç§ã¯æŠããããã¹ãã®å£ãªã©ãå§ããããšã¯ããŠããŸããã æçã§ç°¡åã«èª¬æããŠããã ããŸããããããšãäžå¯èœãŸãã¯å°é£ãªçç±ã«ã€ããŠãå°ãªããšãæ£ããæ¹åã«åããŠãã ããã ç§ã¯æãããªäœããèŠéããŠããå¯èœæ§ãåãå ¥ããŠããŸãããç§ãããã§ããã°ããããäœã§ããããç解ããããšæããŸã:)
èšäºã«ãã£ãŠçæãããéåžžã«å°ããªãµã³ãã«ããããã®å®éšã§ã¯ã人ã
ãShaderMaterial
ã¢ãããŒãã䜿çšããããšã¯æããªãããã§ãã
ããã¯ã¡ããã©é ã«æµ®ããã ïŒ ãããé£ãããäžå¯èœã§ããããšã蚌æããããçš®ã®ãã¹ãã¯ãããŸããïŒ ãæ°ã«å ¥ãïŒ
runSerializationTest( someMaterialWithOnBeforeCompile ).expect( something )
onBeforeCompile
ã¡ãœããã«ã¯éåžžã«ä»»æã®ã³ãŒããå«ãŸããŠããå¯èœæ§ãããããããã®ã³ãŒã«ããã¯ãå
ç¢ã«ã·ãªã¢ã«åããããšã¯ç¢ºãã«äžå¯èœã§ãã ããšãã°ãã¡ãœããã¯åæXMLHttpRequestãäœæãããã®çµæãåŠçããããšãã§ããŸãã ð
ãã ã...å®éã«äœ¿çšãããŠããæ¹æ³ïŒã·ã§ãŒããŒã«ããããé©çšããããïŒã«ã€ããŠã¯ãäžå¯èœã§ã¯ãªãããšã«åæããŸãã ããããç°¡åãªAPIïŒ fn.toString()
ïŒã¯ããããŒã§ãããå
ç¢ãªAPIã¯ããè€éã§ãã
ç§ã¯ãŸã åé¡ãç解ããŠããŸããã ãã®èŠ³ç¹ã¯ã©ãã§ããïŒ
MeshPhongMaterial
ãããMeshStandardMaterial
ããªãrNãåããŸãã
MeshPhongMaterial
ãã·ãªã¢ã«åã§ããŸãã 次ã®ãããªJSONãèšè¿°ããŸãã
{
color: 'red',
specular: 'very',
glossy: 'not much'
}
äž¡æ¹ã®ææãæã€rN + 1ãåããŸãã
äž¡æ¹ãåãæ¹æ³ã§ã·ãªã¢ã«åããããšãã§ããŸãã
//phong
{
color: 'red',
specular: 'very',
glossy: 'not much'
}
//standard
{
color:'red',
shininess: 'shiny',
metalness: 'not much'
}
MeshStandardMaterial
ããGLSLãã·ãªã¢ã«åããå Žæã¯ã©ãã«ããããŸããã
åãããã«ãæ¡åŒµãããçŽ æãã·ãªã¢ã«åããŸãã
//extended PhongMaterial
{
color: 'red',
specular: 'very',
glossy: 'not much',
hamburger: 'medium rare'
}
ãã·ãªã¢ã©ã€ãºïŒ
if ( data.userData.hamburger && HamburgerPhongMaterial )
mat = new HamburgerPhongMaterial( data )
else{
console.warn(`I'm terribly sorry, but you don't have the HamburgerPhongMaterial extension, using default fallback`)
mat = new PhongMaterial( data )
}
ããã§äœãæ¬ ããŠããŸããïŒ
onBeforeCompileãšããŠ...ãã®ã³ãŒã«ããã¯ãã·ãªã¢ã«åããŸãã
ãªãããªãããªãã¯ãããèããã®ã§ãã:)ãããç§ã®æ··ä¹±ã®æ žå¿ã ãšæããŸãããªããã®ããã¯ã«äœãèããäžããããŠããã®ã§ãããããã¯ææã®å®çŸ©ã説æãäœã®äžéšã§ããããŸããã ããŒã¿ã§ã¯ãªãããšã³ãžã³ããã©ã°ã€ã³ãã¢ããªãªã©ãšé¢ä¿ããããŸãã
äžèšã®äŸã¯ç§ã«ã¯åé¡ãªãããã«èŠããŸãããããªã¢ã«ãéã·ãªã¢ã«åãããŠãŒã¶ãŒã³ãŒããHamburgerPhongMaterialã®ååšãç¥ã£ãŠããå¿ èŠããããŸããïŒ ç§ã¯ããã§åé¡ã¯ãããŸãããïŒ14099ãšåæ§ã®ã¢ãããŒããåããtoJSONãšfromJSONããªãŒããŒã©ã€ãããå Žåãå¿ ãããAPIã®å€æŽã¯å¿ èŠãããŸããã
ããã§@takahiroxã®è³ªåãå¥ã®æ¹æ³ã§è§£éããã®ã§ã¯ãªãã§ããããã
... .onBeforeCompileïŒïŒã§ãããã³ã°ããããããªã¢ã«ãã·ãªã¢ã«åããããšã¯å°é£ïŒãŸãã¯äžå¯èœïŒã§ãã å®å šã«æ©èœããïŒã¬ã³ããªã³ã°ãã³ããŒãã¯ããŒã³ãã·ãªã¢ã«åãªã©ïŒå€æŽãããçµã¿èŸŒã¿ãããªã¢ã«ãå¿ èŠãªå ŽåããŠãŒã¶ãŒã¯ShaderMaterialã䜿çšããå¿ èŠããããšæããŸããïŒ
ç§ã¯ãããåå²ããããšããŸãïŒ
onBeforeCompile
ã«ãã£ãŠå€æŽãããGLSLã¯ãGLSLãžã®å€æŽãèªåçã«ã·ãªã¢ã«åãããŸãããKHR_techniques_webgl
ã...ïŒã䜿çšããŠãä»»æã®ã«ã¹ã¿ã ãããªã¢ã«ãã·ãªã¢ã«åã§ããŸããç§ãã¡ã話ããŠããã±ãŒã¹ããããã®1ã€ã§ã¯ãªãå Žåãç§ã¯ããã§èª€è§£ããŠãããšæããŸãã ãããçŽïŒ14099ã®å Žåãç§ã¯ïŒãŸã ïŒãããããŒãžããããšã«è³æã§ãã
ããŒããç§ã¯å®éã«ã¯æåã®2ã€ãåºå¥ããŠããŸããã§ããã ç§ã¯ãŠããã©ãŒã ãå¿
èŠãšããªãäœããèããããšããŠããŸããããã¯äŸãã°gl_FragColor.xyz /= gl_FragColor.a;
ãããããŸããã ããããç§ã¯ããªãããã®ãããªãã®ãïŒè³æãšäžç·ã«ïŒ ïŒã·ãªã¢ã«åãããã·ããªãªãæ³åããããšã¯ã§ããŸããã ãããªã¢ã«ããŒã¿ã§ã¯ãªãããšãã§ã¯ãã¬ã³ãã©ãŒãªã©ã®ç¯å²ã«å«ãŸããããã§ãã
materials = loadSerializedMaterials()
effect = new Effect()
effect.load( 'alphaDivide').then(()=>materials.forEach(mat.onBeforeCompile = effect.getOnBeforeCompile('alphaDivide')))
2çªç®ã®äŸã¯ç§ããã£ãšèããŠãããã®ã§ãã ããŸããŸãªå
¥åãšãšãã«ãããããã©ãåŠçãããã«ã€ããŠã®ãã³ããã·ãªã¢ã«åããŸãuserData.extension === 'hamburger'
ã
ç§ã¯äžæã«æžãããšæããŸãã ç§ãèšãããã£ãã®ã¯
.onBeforeCompile()
ãããã³ã°ãããçµã¿èŸŒã¿ãããªã¢ã«ã¯ãçµã¿èŸŒã¿ãããªã¢ã«ãšåãAPIã§æ£ããã³ããŒãè€è£œãã·ãªã¢ã«åãããŸããã ãããã³ã°ãããŠããªãçŽ æãšããŠæ±ãããŸããShaderMaterial
ãªã©ã®ä»ã®ãªãã·ã§ã³ãæ€èšããå¿
èŠããããŸããç§ã®è³ªåã¯ãç¹å®ã®ã±ãŒã¹ã§ã¯ãªãã .onBeforeCompile()
ã®ããªã·ãŒã«é¢ãããã®ã§ãã å¶éãæ確ã«ããŠãããã¥ã¡ã³ãã«ã¡ã¢ãè¿œå ããããšæããŸããã
three.jsãšã¬ã³ããªã³ã°ã·ã¹ãã å
šäœãå¿ããå Žåãç§ã¯ãã®èŠç¹ãç解ããŠãããšæããŸãã æ±çšãªããžã§ã¯ããšããŠã .clone()
å Žåã¯ãã¯ããŒã³ãäœæããŠäžè²«ããæåŸ
ãæãããå¿
èŠããããŸãã åé¡ã¯ãäž¡æ¹ã®è§£æ±ºçïŒãããè€è£œããã®ã§ã¯ãªãè€è£œããïŒã«æå¹ãªåŒæ°ãããããã«èŠããããšã§ãã ãªã¹ããŒã®ã¯ããŒã³ãäœæããŸããããæç»ã«åœ±é¿ãäžããäœããäžè²«ããŠããããšãããçšåºŠæåŸ
ããŸãã
ä»ã®é åã§ãåãåé¡ãçºçãããããäžèšã®ææ¡ã¯ãããè¡ãããã®æå¹ãªæ¹æ³ã ãšæããŸãïŒããšãã°ãã¿ãŒã²ããéã§æ·±åºŠãããã¡ãŒãå
±æããããšãownThing || outsideThing
ã§è§£æ±ºã§ããŸãïŒã
æ©èœããªãé¢æ°ããã£ãã·ã¥ãã代ããã«ãåºæ¬çã«userData
ãã£ãã·ã¥ããŸããããã®ãµãã»ããããã£ãã·ã¥ããŸãã userData.hamburger: 'rare'
ããã£ãã·ã¥ããããšã¯æå³ããããŸãããã userData.effectOn: true". The
ãã£ãã·ã¥ããŸãã ownChunks | ownWhatever`ã¯ãã®åé¡ã解決ããŸãã
ãŸãã次ã®åé¡ã解決ããŸãã
onBeforeCompileã¡ãœããã«ã¯éåžžã«ä»»æã®ã³ãŒããå«ãŸããŠããå¯èœæ§ãããããããã®ã³ãŒã«ããã¯ãå ç¢ã«ã·ãªã¢ã«åããããšã¯ç¢ºãã«äžå¯èœã§ãã
é·ãéã人ã
ã¯onBeforeCompile
ã䜿çšããŠããŸããããããã«ã¯ã©ã®ãããªä»»æã®ã³ãŒããå«ãŸããŠããã®ããç¥ãå¿
èŠããããŸãã æž¡ãããshader
ãªããžã§ã¯ãã§ã®ã¿åäœãããšæããŸãããã®ãªããžã§ã¯ããå€æŽããŸããããšã«ããShaderMaterial
æå³ã®ããå€æŽã®ã¿ã圱é¿ããŸãã èªåã§gl
ãã®ãèšå®ãããšããããããªãŒããŒã©ã€ããããŸãããããç§ã®é ã«æµ®ãã¶å¯äžã®ããšã§ãã
ããã¯åºæ¬çã«pre three parse
ã¹ãããã§ããã Material
ïŒ defines:{}
ã§äœ¿çšã§ããªããããå¿
é ã®uniforms:{}
ã€ã³ã¿ãŒãã§ã€ã¹ãšãšãã«ã·ã§ãŒããŒãèªåã§è§£æããæ©äŒãåŸãããŸããäžæ¹ã defines:{}
ãå®è¡ãããšãã©ã¡ããShaderMaterial
å
åŒã«ãªããŸãïŒã
ãããã©ã®ããã«è¡ãããã€ãŸãä»»æã®ã³ãŒããäœã§ãããåé¡ã§ã¯ãããŸããã äœãè¿ããŸãããã shader:{}
ãã¬ã³ãã©ãŒãããã䜿çšããŸãã
ç§ãææ¡ããã¢ãããŒãïŒ
ownThing
ãè¿œå ããŸãã THREE.WebGLRenderTarget
ã¯.ownStencilDepthBuffer
æã€ããšãã§ããŸãã ããã§ãç§ãäžã§ææ¡ããããã«ãããã¯ownGLSL:{}
ownInput | ownUniforms
ããã€ãã®ããŒãžã§ã³ã«ãªããŸãã shader:{}
ãªããžã§ã¯ããå€æŽããããã®ä»»æã®ã³ãŒãã®å¿
èŠæ§ãæé€ããŸããWebGLRenderer
ïŒã¹ãŒããŒãã©ã€ããŒãïŒã®å
éšããçºçãããã®ãããªå
¥åãäžããããå ŽåïŒ
const shader = {
uniforms: buildFromMaterial(mat),
vs: getVSTemplate(key),
fs: getFSTemplate(key)
}
ãããæ žå µåšïŒ
shader = onBeforeCompile( shader )
shader.vs //invalid GLSL
shader.uniforms //you got some extra ones that onBeforeCompile may have mutated, maybe removed some others
shader = ___parse(shader) //private step
shader.vs //valid glsl, (not a template)
compile(shader)
ããã䜿ã£ãŠïŒ
function parseShader(shader){
return {
uniforms: shader.uniforms,
vs: parseChunks(shader.vs)
fs: parseChunks(shader.fs)
}
}
//FIX FOR HASHING BUG
function parseChunk( material, chunkName ){
return material.ownChunks[chunkName] || THREE.ShaderChunks[chunkName]
}
//do whatever you want with the templates, maybe remove an `#include <>`
shader = onBeforeParse(shader)
shader.vs //template || valid glsl
shader = parseShader(shader) //sample OWN || PRIVATE
shader.vs //valid GLSL
//if you want to apply a regex on the entire valid glsl, or compile node material or something else
shader = onBeforeCompile( shader )
compile(shader)
WebGLRenderer
ShaderMaterial
以å€ã®ããšãç¥ããªãããã«ããŸããã©ãã«ã§ã
const mat = new THREE.MeshBasicMaterial()
const sm = new THREE.ShaderMaterial()
ãã€
const mat = nodeMaterial.compile() //returns ShaderMaterial, with a friendly interface (same as StandardMaterial for example)
const mat = chunkMaterial.compile()
TLïŒãã®ã®DRã¯ãäžèšã®ãã³ã³ãã€ã«ãïŒããŒã¹ïŒãçºçãããšãã«ãç¹å®ã®æç¹æ°ã«ããªããŠãŒã¶ãŒã§ãã 圌ãã¯äœãèµ·ãããããã£ãšæ°ã«ãããŠãããšæããŸãããããŠãäœãèµ·ãããã¯ãåäžã®ãŠãŒã¹ã±ãŒã¹ã§ã¯ãªãã«ããŠããã»ãã®äžæ¡ãã«åé¢ããããšãã§ããŸãin: shaderString, out: shaderString
ã ãã€ãã©ã€ã³ã®ç¹å®ã®ãã€ã³ãã§å®è¡ããå¿
èŠãããçç±ã¯ã調æ»ããŠç解ãã䟡å€ããããšæããŸãã ããã¯ãã®å©ã以äžã«ç©äºã®éªéãããŠããããã§ãã
@mrdoob
.onBeforeCompile()
ãããã³ã°ããããããªã¢ã«ãã·ãªã¢ã«åããã®ã¯é£ããïŒãŸãã¯äžå¯èœïŒãšæããŸãã å®å šã«æ©èœããïŒã¬ã³ããªã³ã°ãã³ããŒãã¯ããŒã³ãã·ãªã¢ã«åãªã©ïŒå€æŽãããçµã¿èŸŒã¿ãããªã¢ã«ãå¿ èŠãªå ŽåããŠãŒã¶ãŒã¯ShaderMaterial
ã䜿çšããå¿ èŠããããšæããŸããïŒ
onBeforeCompile()
ã®äœ¿çšãã·ãªã¢ã«åããããšã¯æã£ãŠããŸããã§ãã...
onBeforeCompileã䜿çšããŠæ¿ããåãŸããŸããã çµã¿èŸŒã¿ã®ã·ã§ãŒããŒãå®çŸ©ãããæ¹æ³ã§å€æŽã§ããã·ã§ãŒããŒãã«ããŒã¯ã©ã¹ããããŸãã ãããè¡ãã«ã¯ãonBeforeCompileã¡ãœããã䜿çšããŸãã ã©ããããæåã®ã³ã¡ã³ãã§è¿°ã¹ãããã«ãWebGLProgramã¯onBeforeCompile.toStringïŒïŒãããã·ã¥ãšããŠäœ¿çšããŸãã ããããç§ã®é¢æ°ã¯ãžã§ããªãã¯ã§ããããïŒé ç¹ã·ã§ãŒããŒãšãã©ã°ã¡ã³ãã·ã§ãŒããŒã®äžéšãå€æ°ã«çœ®ãæããŸãïŒãonBeforeCompile.toStringïŒïŒã¯ã·ã§ãŒããŒããšã«ç°ãªã£ãŠèŠããŸããã ããã¯ãç§ã®ç°ãªãã·ã§ãŒããŒããã¹ãŠåãããã°ã©ã ãšããŠãã£ãã·ã¥ãããããšãæå³ããŸããã evalåŒã³åºããšuuidããããŠä»ã§ã¯ç§ã®é¢æ°ã¯ãã¹ãŠç°ãªã£ãŠèŠããŸãã ãããç解ããããã«æ°žé ã«ããããŸããã
@donaldrhttps ïŒ //github.com/mrdoob/three.js/issues/13192ãåç §ããŠãã ããã ãããã®å¶éãææžåãããšãããšæããŸãã
evalã®äœ¿çšæ¹æ³ãæããŠãã ããã ãã£ãšèããŠããã®ã§ãããæ±ããããããã§ãã åºæ¬çã«ãããã£ã®äžéšã«const fdscxnmdrek435rkjl
ãè¿œå ããŠãããè©äŸ¡ããããšãã§ããŸããïŒ
ããã¯ãç§ã®ç°ãªãã·ã§ãŒããŒããã¹ãŠåãããã°ã©ã ãšããŠãã£ãã·ã¥ãããããšãæå³ããŸããã evalåŒã³åºããšuuidããããŠä»ã§ã¯ç§ã®é¢æ°ã¯ãã¹ãŠç°ãªã£ãŠèŠããŸãã ãããç解ããããã«æ°žé ã«ããããŸããã
ããã¯éåžžã«ã€ã©ã€ã©ããããã«èãããŸããããããªããã ðå¿ èŠãªå€æŽãã©ã€ãã©ãªèªäœã§æå³ãããããã«æãããå Žåã¯ãæªè§£æ±ºã®åé¡ãæè¿ããŸãã
æªè§£æ±ºã®åé¡ãæè¿ããŸãã
æ¢åã®ãã®ãåéããããšãæ€èšããŸããïŒ ïŒ13192ã¯åãããã«èŠããŸãããéããããŸããïŒcrying_cat_faceïŒæ©èœãšèŠãªãããå Žåãåé¿çãããã«æçš¿ãããŠããã°æ¬åœã«ããã§ãããã
ããŒã...
const _obc = shader => {...}
const obc = `
function (shader){
const _${ hash() }
${ _obc.toString() }
_obc(shader)
}
`
material.onBeforeCompile = eval(obc)
^ããã¯æ©èœããŸããïŒ eval
䜿çšããããšã¯ãããŸããã
ïŒ17567ãä»ããMaterial.customProgramCacheKeyïŒïŒã®å°å
¥ã«ãããéçºè
ã¯ãæ¡ä»¶ã¹ããŒãã¡ã³ãã䜿çšããŠonBeforeCompile()
ãä»ããŠå€æŽããããããªã¢ã«ã«å¯ŸããŠã·ã§ãŒããŒããã°ã©ã ãå
±æãããªãå¯èœæ§ããããŸãã
æ°ããã¹ã¬ããïŒïŒ13446ãªã©ïŒã®onBeforeCompile()
ã³ã³ããã¹ãã§ãä»ã®æ¢åã®åé¡ãŸãã¯æ¡åŒµæ©èœã«ã€ããŠèª¬æããŠãã ããã
æãåèã«ãªãã³ã¡ã³ã
onBeforeCompile()
ã®äœ¿çšãã·ãªã¢ã«åããããšã¯æã£ãŠããŸããã§ãã...