Three.js: ์ž๋ฃŒ: onBeforeCompile() ์ถ”๊ฐ€๋จ

์— ๋งŒ๋“  2017๋…„ 06์›” 09์ผ  ยท  75์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: mrdoob/three.js

์ˆ˜๋…„ ๋™์•ˆ ๊ณตํ†ต ๊ธฐ๋Šฅ ์š”์ฒญ์€ ๋‚ด์žฅ ์žฌ๋ฃŒ๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ์˜ค๋Š˜ ๋‚˜๋Š” ๊ทธ๊ฒƒ์ด 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

Enhancement

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

@mrdoob .onBeforeCompile() ํ•ดํ‚น๋œ ์ž๋ฃŒ๋ฅผ ์ง๋ ฌํ™”ํ•˜๋Š” ๊ฒƒ์€ ์–ด๋ ต๊ฑฐ๋‚˜ ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ์™„์ „ํ•œ ๊ธฐ๋Šฅ(๋ Œ๋”๋ง, ๋ณต์‚ฌ, ๋ณต์ œ, ์ง๋ ฌํ™” ๋“ฑ)์œผ๋กœ ์ˆ˜์ •๋œ ๋‚ด์žฅ ์žฌ๋ฃŒ๋ฅผ ์›ํ•  ๊ฒฝ์šฐ ShaderMaterial ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์‹ญ๋‹ˆ๊นŒ?

๋‚˜๋Š” onBeforeCompile() ์ด ์ง๋ ฌํ™”๋  ๊ฒƒ์ด๋ผ๊ณ  (๊ณ ๋ คํ•˜์ง€ ์•Š์•˜๋‹ค)...

๋ชจ๋“  75 ๋Œ“๊ธ€

WebGLProgram.js๊ฐ€ ์ด๋ฏธ ๋งŽ์€ ์ฒ˜๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•  ๋•Œ ์‚ฌ์šฉ์ž ์ง€์ • ๋ฌธ์ž์—ด ์กฐ์ž‘์„ ์š”๊ตฌํ•˜๋Š” ๊ฒƒ์€ ์•ฝ๊ฐ„ ํ•ดํ‚คํ•ด ๋ณด์ž…๋‹ˆ๋‹ค. ๊ธฐ์กด ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ์žฌ์ •์˜ํ•˜๋Š” ๋Œ€์‹  ์ƒˆ #include๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ด€๋ จ ์‚ฌ์šฉ ์‚ฌ๋ก€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋Ÿฐํƒ€์ž„์— THREE.ShaderLib๋ฅผ ์ˆ˜์ •ํ•˜์—ฌ ์˜ค๋Š˜ ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๋˜‘๊ฐ™์ด ๋”๋Ÿฝ๊ฒŒ ๋Š๊ปด์ง‘๋‹ˆ๋‹ค.

์•„๋งˆ๋„ ๋‘ ๊ฐ€์ง€ ๋ชจ๋‘์— ๋” ์ข‹์€ ์†”๋ฃจ์…˜์€ ์ˆ˜๋™ ๋ฌธ์ž์—ด ์กฐ์ž‘ ์—†์ด ์˜๊ตฌ์ ์œผ๋กœ ๋ฐฉํ•ดํ•˜์ง€ ์•Š๊ณ  ๋‚ด์žฅ ์ฒญํฌ๋ฅผ ์žฌ์ •์˜/์ฆ๊ฐ€ํ•˜๋Š” ์žฌ์งˆ์— ๋Œ€ํ•œ ์‚ฌ์šฉ์ž ์ •์˜ ShaderLib๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๋‹ค๋ฅธ ์šฉ๋„๋กœ onBeforeCompile ํ›„ํฌ๋ฅผ ๋ฐฐ์ œํ•˜์ง€๋Š” ์•Š์ง€๋งŒ ๊ท€ํ•˜์˜ ์˜ˆ์ œ๊ฐ€ ์ˆ˜ํ–‰ํ•˜๋ ค๋Š” ์ž‘์—…๊ณผ ๋” ์ผ์น˜ํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์ฆ‰, ์›์‹œ ํฌํ•จ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋Š” ์…ฐ์ด๋” ๊ตฌ์„ฑ์€ ํ•ญ์ƒ ํ•œ ๋ฒ„์ „์—์„œ ๋‹ค์Œ ๋ฒ„์ „์œผ๋กœ ๋งค์šฐ ์ทจ์•ฝํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ์Šค์ผˆ๋ ˆํ†ค ์ฝ”๋“œ(์˜ˆ 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๊ฐ€ ๋…ธ๋ฉ€ ๋งต๊ณผ ํ•จ๊ป˜ ์ž‘๋™ํ•˜๋„๋ก ํ•˜๋Š” ๊ฒƒ์„ ์ข‹์•„ํ•˜์ง€๋งŒ ์ด๊ฒƒ์œผ๋กœ ํ•ด๊ฒฐํ•˜๊ธฐ ์‰ฌ์šด ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๋Š” ๋ช‡ ๊ฐ€์ง€ ๋ฌธ์ œ๋ฅผ ์—ฐ๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค.

๋‚ด ๋ธŒ๋žœ์น˜๋ฅผ ๋ณด๊ณ  ์ด๊ฒƒ์„ ์Šคํ•€ํ•˜๊ฑฐ๋‚˜ ์ด ๋งค์šฐ ๊ฐ„๋‹จํ•œ ์˜ˆ์ œ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์กฐ๋ช…/๊ทธ๋ฆผ์ž ๋“ฑ์œผ๋กœ ์‚ฌ์šฉ์ž ์ •์˜ ๋ณ€ํ˜•์„ ํ…Œ์ŠคํŠธํ•˜๊ณ  ๋ช‡ ๊ฐ€์ง€ ์œ ๋‹ˆํผ์„ ์ถ”๊ฐ€ํ•จ).

http://dusanbosnjak.com/test/webGL/three-material-shader-override/webgl_materials_shader_override.html

์•„๋งˆ๋„ ๋‘ ๊ฐ€์ง€ ๋ชจ๋‘์— ๋” ์ข‹์€ ์†”๋ฃจ์…˜์€ ์ˆ˜๋™ ๋ฌธ์ž์—ด ์กฐ์ž‘ ์—†์ด ์˜๊ตฌ์ ์œผ๋กœ ๋ฐฉํ•ดํ•˜์ง€ ์•Š๊ณ  ๋‚ด์žฅ ์ฒญํฌ๋ฅผ ์žฌ์ •์˜/์ฆ๊ฐ€ํ•˜๋Š” ์žฌ์งˆ์— ๋Œ€ํ•œ ์‚ฌ์šฉ์ž ์ •์˜ ShaderLib๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

https://github.com/mrdoob/three.js/pull/10791์—์„œ ์ผ์–ด๋‚˜๋Š” ์ผ์„ ์ •ํ™•ํžˆ ์š”์•ฝํ•˜๋ฉด ๋” ๋‚˜์€ ์„ค๋ช…์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. :)


๋‚˜๋Š” ์—ฌ๊ธฐ์„œ ๋ฌด์Šจ ์ผ์ด ์ผ์–ด๋‚˜๊ณ  ์žˆ๋Š”์ง€ ๋ชจ๋ฅธ๋‹ค๋Š” ๊ฒƒ์„ ์ธ์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” 3์— ๊ธฐ์—ฌํ•˜๋Š” ๊ฒƒ์„ ํฌ๊ธฐํ•œ ์‚ฌ๋žŒ์„ ์•Œ๊ณ  ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋‹น์‹œ์—๋Š” ๊ทธ๊ฒƒ์„ ์ดํ•ดํ•˜์ง€ ๋ชปํ–ˆ์ง€๋งŒ ์ง€๊ธˆ์€ ๋‹ค์†Œ ์‹ค๋ง์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค.

์ฒซ ๋ฒˆ์งธ ๋‹จ๋ฝ์„ ์ฝ์„ ๋•Œ ๋ฐ์ž๋ทฐ๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋Œ€๋ถ€๋ถ„ ์ขŒ์ ˆํ•ฉ๋‹ˆ๋‹ค.

...Object3D์˜ onBeforeRender()์™€ ์œ ์‚ฌํ•œ ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.

onBeforeRender() https://github.com/mrdoob/three.js/pull/9738 ์—์„œ ๊ธฐ๋Šฅ์„ ๋„์ž…ํ•˜๋Š” ๋ฐ 1๋…„์ด ๊ฑธ๋ ธ์„ ๋•Œ ๋˜‘๊ฐ™์€ ์ผ์ด ์ผ์–ด๋‚ฌ์Šต๋‹ˆ๋‹ค.

์ด๋Ÿฐ, ๊ฐ™์€ ๊ฐœ๋ฐœ์ž์™€ ๋‘ ๋ฒˆ? ๋‚ด๊ฐ€ ์—ฌ๊ธฐ์„œ ๋ญ”๊ฐ€ ์ž˜๋ชปํ•˜๊ณ  ์žˆ๋Š” ๊ฒŒ ๋ถ„๋ช…ํ•ด, ํ•˜์ง€๋งŒ ์–ด์ฉŒ์ง€? ์ฒ˜์Œ์œผ๋กœ ๋นŒ๋“œ ํŒŒ์ผ์ด ์ฒดํฌ์ธ๋˜๊ณ  ์žˆ์—ˆ๋Š”๋ฐ ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ• ์ง€ ๋ชฐ๋ž๊ณ  ๊ทธ๋ƒฅ ์žŠ์–ด ๋ฒ„๋ ธ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด๋ฒˆ์—๋Š” ์ด ํ’€ ๋ฆฌํ€˜์ŠคํŠธ์˜ ๋งจ ์œ„์— ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ ์ถฉ๋Œ์ด ์žˆ์ง€๋งŒ ์‰ฝ๊ฒŒ ํ•ด๊ฒฐ๋˜๋ฉฐ ๋ช‡ ๋‹ฌ ๋™์•ˆ ์ถฉ๋Œ์ด ์—†์—ˆ์Šต๋‹ˆ๋‹ค.

์˜คํ•ดํ•˜์ง€ ๋งˆ์„ธ์š”. ์—ฌ๊ธฐ ์ž‘์—…์—์„œ ํ—ˆ์˜์‹ฌ์ด ์•„๋‹ˆ๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ €๋Š” ์‚ฌ๋žŒ๋“ค์ด ์•„์ด๋””์–ด๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ›๊ณ  ์‹ถ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. @unconed ๋‹น์‹ ์ด ๋ฌธ์ œ์— ๋Œ€ํ•ด ์ž˜ ์•Œ๊ณ  ์žˆ๊ณ  ์•„๋งˆ๋„ ๋‹ค๋ฅธ ๊ฒƒ์„ ์‹œ๋„ํ–ˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ท€ํ•˜์™€ ๊ฐ™์€ ์‚ฌ์šฉ์ž๊ฐ€ ๋‹ค๋ฅธ PR์„ ๋†“์นœ ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

์žฌ๋ฃŒ๋ณ„ shaderlib์— ๋Œ€ํ•ด ๊ฝค ์ข‹์€ ๋Š๋‚Œ์„ ๋ฐ›์•˜์ง€๋งŒ ์บ์‹ฑ์„ ํŒŒ์•…ํ•˜๊ธฐ ์œ„ํ•ด ์ „์ฒด ์…ฐ์ด๋”๋ฅผ ๋ฌธ์ž์—ด๋กœ ๋ณด๊ฑฐ๋‚˜ ๋น„๊ตํ•˜๋Š” ๋ Œ๋”๋Ÿฌ์˜ ๊ธฐ๋Šฅ ํ•˜๋‚˜๋ฅผ ์ฐพ์•˜์ง€๋งŒ ๊ทธ๋‹ค์ง€ ์ข‹์ง€๋Š” ์•Š์•˜์Šต๋‹ˆ๋‹ค. ํ”ผ๋“œ๋ฐฑ์ด ์ข€ ์žˆ์—ˆ์œผ๋ฉด...

์˜ˆ์‹œ๊ฐ€ ์ž˜๋ชป๋˜์—ˆ๋‚˜์š”? ๋จธ๋ฆฌ๋Š” ์ถ”์ƒ ์ŠคํŒŒ์ดํฌ ๋ณผ๋ณด๋‹ค ๋ฌด์Šจ ์ผ์ด ์ผ์–ด๋‚˜๊ณ  ์žˆ๋Š”์ง€ ํ›จ์”ฌ ๋” ๋ช…ํ™•ํ•˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์ง€๋งŒ ์ „์ฒด ์˜ˆ์ œ๋Š” ๋” ๋งŽ์€ ๋•…์„ ๋ฎ๋Š” ๊ทธ๋ฆผ์ž์™€ ํ•จ๊ป˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ์–ด๋–ค ์ด์œ ๋กœ ๋ฌด๊ฒ์ง€๋งŒ ๋งŽ์€ verts์—์„œ sin/cos ๋•Œ๋ฌธ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์ฒ˜์Œ๋ถ€ํ„ฐ ๋‹ค์‹œ ์‹œ์ž‘ํ•œ๋‹ค๋ฉด... ์”ฌ ํ‚คํŠธ๊ฐ€ ์ ˆ๋Œ€์ ์œผ๋กœ ๋”์ฐํ•˜์ง€๋งŒ ์ด API๋Š” ์ •๋ง ์ข‹์Šต๋‹ˆ๋‹ค.

https://developer.apple.com/documentation/scenekit/scnshadable

๋”์ฐํ•˜๊ฒŒ ๋ฌธ์„œํ™”๋˜์—ˆ์ง€๋งŒ ๋” ํฅ๋ฏธ๋กœ์šด ๋ถ€๋ถ„์„ ์ฐพ์„ ์ˆ˜๋Š” ์—†์ง€๋งŒ ๊ธฐ๋ณธ์ ์œผ๋กœ ์…ฐ์ด๋”์˜ ์—ฌ๋Ÿฌ ๋‹จ๊ณ„์—์„œ ํ›„ํฌ๋ฅผ ์ถ”์ƒํ™”ํ–ˆ์Šต๋‹ˆ๋‹ค.

์˜ฌํ•ด ์ดˆ ๋‚˜๋Š” ์ •ํ™•ํžˆ ๊ฐ™์€ ๊ฒƒ์€ ์•„๋‹ˆ์ง€๋งŒ ๋น„์Šทํ•œ ๊ฒƒ์„ ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋ณด์ด๋Š” ํ’€ ๋ฆฌํ€˜์ŠคํŠธ๋ฅผ ํ–ˆ์Šต๋‹ˆ๋‹ค.

https://github.com/mrdoob/three.js/pull/10791

์œ ์ผํ•œ ์ฐจ์ด์ ์€ ์ฝœ๋ฐฑ์„ ํ†ตํ•ด ์ˆ˜ํ–‰ํ•œ๋‹ค๋Š” ๊ฒƒ๋ฟ์ž…๋‹ˆ๊นŒ? WebGLRenderer์—์„œ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ธ์ˆ˜๋ฅผ ํƒญํ–ˆ์Šต๋‹ˆ๋‹ค.

@pailhead ์•„์ง ํ™๋ณด ๋ชปํ•ด์„œ ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ๋‚ด ์ ‘๊ทผ ๋ฐฉ์‹์˜ ์ฃผ์š” ์ด์ ์€ 3๊ฐœ์˜ ์ƒˆ ๋ผ์ธ๋งŒ ํ•„์š”ํ•˜๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ทธ๋ ‡๊ฒŒ ๋งํ•˜๋ฉด์„œ, ๋‚˜๋Š” ์ด์ œ ๋‹น์‹ ๊ณผ @unconed ์ œ์•ˆ์„ ์—ฐ๊ตฌํ•˜๋Š” ๋ฐ ์‹œ๊ฐ„์„ ํ• ์• ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ํ™•์‹คํžˆ ๋” ์šฐ์•„ํ•˜๊ฒŒ ๋Š๊ปด์ง‘๋‹ˆ๋‹ค. ๋‹จ ์„ธ ์ค„์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋‹ค๋ฅธ ํ•˜๋‚˜์—์„œ ๋‹ค๋ฅธ ํŒจํ„ด์„ ๋”ฐ๋ฅด๊ณ  ์žˆ์—ˆ๋‹ค. ์กฐ๊ธˆ ๋” ์žฅํ™ฉํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ๋งํ•˜๋ ค๊ณ  ํ–ˆ์ง€๋งŒ ํ™•์‹คํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ํ•˜๋‚˜์˜ ์œ ์ผํ•œ ์žฅ์ ์€ ๋ช‡๋‹ฌ์ „์— ๊ฐ€๊ธธ ์ž˜ํ–ˆ๋‹ค๋Š” ๊ฒƒ :)

์ด๋Ÿฐ, ๊ฐ™์€ ๊ฐœ๋ฐœ์ž์™€ ๋‘ ๋ฒˆ? ๋‚ด๊ฐ€ ์—ฌ๊ธฐ์„œ ๋ญ”๊ฐ€ ์ž˜๋ชปํ•˜๊ณ  ์žˆ๋Š” ๊ฒŒ ๋ถ„๋ช…ํ•ด, ํ•˜์ง€๋งŒ ์–ด์ฉŒ์ง€?

๋ฏธ์•ˆํ•ฉ๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ์ƒ๊ฐํ•  ์ˆ˜์žˆ๋Š” ์œ ์ผํ•œ ๊ฒƒ์€ ์•„๋งˆ๋„ ๋‚ด๊ฐ€ ์••๋„ ๋‹นํ–ˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์–ด์ฉŒ๋ฉด ๊ธด ํ† ๋ก ์ด๋‚˜ ๋ณต์žกํ•œ PR์ด ๋‚ด ์—๋„ˆ์ง€๋ฅผ ๋„ˆ๋ฌด ๋งŽ์ด ์†Œ๋ชจํ•  ์ˆ˜๋„ ์žˆ์œผ๋ฏ€๋กœ ๋‚˜์ค‘์œผ๋กœ ๋ฏธ๋ฃจ๊ณ  ๋” ๊ฐ„๋‹จํ•œ PR๋กœ ์ด๋™ํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค.

@pailhead ๋‹˜๋ฟ๋งŒ์ด ์•„๋‹™๋‹ˆ๋‹ค. @bhouston ์€ @WestLangley ์™€ @Mugen87์„ ํฌํ•จํ•ด ์ด๋Ÿฐ PR์„ ๋งŽ์ด ํ–ˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์‹œ ๋งํ•˜์ง€๋งŒ, ๋‚ด๊ฐ€ PR์„ ์ข‹์•„ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ PR์— ๋‚ด๊ฐ€ ๋‹น์‹œ์— ์ œ๊ณตํ•  ์ˆ˜ ์—†๋Š” ์•ฝ๊ฐ„์˜ ๊ด€์‹ฌ์ด ํ•„์š”ํ•˜๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ข‹์€ ์˜ˆ๋Š” ์ธ์Šคํ„ด์‹ฑ PR์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ์ฝ์„ ์‹œ๊ฐ„์„ ์ฐพ์•˜๊ณ , ๋‚ด ์ž์‹ ์˜ ์‹คํ—˜์„ ํ–ˆ๊ณ , ๋‹จ์ˆœํ™”๋ฅผ ์ œ์•ˆํ–ˆ์Šต๋‹ˆ๋‹ค. ์กฐ๋งŒ๊ฐ„ ๋‹ค์‹œ ๋ณผ ์ˆ˜ ์žˆ์ง€ ์•Š์„๊นŒ ์‹ถ์Šต๋‹ˆ๋‹ค.

์ด ๋ชจ๋“  ๊ฒƒ์„ ๊ด€๋ฆฌํ•˜๊ณ  ๋ชจ๋“  PR์— ๊ฐ€์น˜ ์žˆ๋Š” ๊ด€์‹ฌ์„ ๊ธฐ์šธ์ด๋Š” ๊ฒƒ์€ ์–ด๋ ต์Šต๋‹ˆ๋‹ค.

์˜ˆ์‹œ๊ฐ€ ์ž˜๋ชป๋˜์—ˆ๋‚˜์š”? ๋จธ๋ฆฌ๋Š” ์ถ”์ƒ ์ŠคํŒŒ์ดํฌ ๋ณผ๋ณด๋‹ค ๋ฌด์Šจ ์ผ์ด ์ผ์–ด๋‚˜๊ณ  ์žˆ๋Š”์ง€ ํ›จ์”ฌ ๋” ๋ช…ํ™•ํ•˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์ง€๋งŒ ์ „์ฒด ์˜ˆ์ œ๋Š” ๋” ๋งŽ์€ ๋•…์„ ๋ฎ๋Š” ๊ทธ๋ฆผ์ž์™€ ํ•จ๊ป˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ์–ด๋–ค ์ด์œ ๋กœ ๋ฌด๊ฒ์ง€๋งŒ ๋งŽ์€ verts์—์„œ sin/cos ๋•Œ๋ฌธ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์ด์ œ ๋‹น์‹ ์ด ๊ทธ๊ฒƒ์„ ์–ธ๊ธ‰ํ•ฉ๋‹ˆ๋‹ค ... ์˜ˆ, ํ™•๋Œ€ ํ•  ๋•Œ ์ƒˆ๋กœ์šด MacBook Pro์—์„œ 10fps๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค ๐Ÿ˜ฎ

๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ๊ทธ๋ฆผ์ž์™€ ๋žœ๋“œ, ์ฃ„๊ฐ’๊ณผ ๋ฌผ๊ฑด์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€๋งŒ ์˜ˆ, ๊ทธ๊ฒƒ์€ ๋„ˆ๋ฌด ๋งŽ์€ ํžˆํŠธ๋ฅผ ์น˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์–ด๋Š ์ชฝ์ด๋“ , ๋‚˜๋Š” ๋‹น์‹ ์ด ์ด๊ฒƒ์„ ์„ธ ์ค„๋กœ ์š”์•ฝํ–ˆ๋‹ค๋Š” ๊ฒƒ์— ๋†€๋ž์Šต๋‹ˆ๋‹ค. ์ €๋Š” ์žฌ๋ฃŒ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์–ด๋–ป๊ฒŒ ์œ ๋‹ˆํผ์œผ๋กœ ๋ฐ”๋€Œ๊ณ  ๊ทธ ํŒจํ„ด์„ ๋”ฐ๋ž๋Š”์ง€์— ๋„ˆ๋ฌด ์ง‘์ค‘ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ฐจ์ด์ ์€ ์‚ฌ์ „๊ณผ ๊ฐ™์€ ๋Œ€์•ˆ ShaderLib ํ•˜๋ฏ€๋กœ #include <> ๊ฐ€ ๋‹ค๋ฅธ ์ฝ”๋“œ๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ์ผ์ด ๋ฐœ์ƒํ•˜๊ธฐ ์ „์— ํฌํ•จ์„ ์ œ๊ฑฐํ•˜๊ณ  glsl๋กœ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค. ์…ฐ์ด๋” ์ฃผ์œ„์— ์ผ์ข…์˜ ๋ž˜ํผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉด ์•„๋งˆ๋„ ์ด ๊ตฌ๋ฌธ์ด ๋” ๊น”๋”ํ•ด์งˆ ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค( replace() ๋Œ€์‹ ์— ์ฒญํฌ ์ด๋ฆ„ + glsl์„ ์ œ๊ณตํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. .

์ด๊ฒŒ ์žˆ์œผ๋ฉด ์ •๋ง ์ข‹๊ฒ ์ง€๋งŒ, ๊ทธ๋ ‡๊ฒŒ ๋งŽ์€ 3D ์—”์ง„์œผ๋กœ ์ž‘์—…ํ•˜์ง€ ์•Š์•˜์ง€๋งŒ Unity์™€ Scene Kit์—๋Š” ์ด์™€ ๋น„์Šทํ•œ ๊ธฐ๋Šฅ์ด ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

@unconed

onBeforeCompile() ์žฅ์  ์ค‘ ํ•˜๋‚˜๋Š” ์žฌ์งˆ ์†์„ฑ์ด ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์€ ์ƒํƒœ๋กœ ์œ ์ง€๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๋‚ด์žฅ์žฌ๋ฅผ ํ™•์žฅํ•˜๋Š” ๋Š๋‚Œ์ด ๋” ํฝ๋‹ˆ๋‹ค.

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)

_์ฒญํฌ ์ด๋ฆ„์˜ ์‚ฌ์ „๊ณผ uniforms ๊ฐœ์ฒด์ž…๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ๋ฌธ์ž์—ด ์กฐ์ž‘์€ "์ด ๋ฉ์–ด๋ฆฌ๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๊ณ  ๊ทธ ์œ„์— ๋ฌด์–ธ๊ฐ€๋ฅผ ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค"์˜ ๋ผ์ธ์„ ๋” ๋งŽ์ด ๋”ฐ๋ฆ…๋‹ˆ๋‹ค.

์ด ํ™๋ณด:

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()์˜ ํ•œ ๊ฐ€์ง€ ์ด์ ์€ ์žฌ๋ฃŒ ์†์„ฑ์ด ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์€ ์ƒํƒœ๋กœ ์œ ์ง€๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‹ค๋ฅธ PR์—์„œ๋„ ๋™์ผํ•˜๊ฒŒ ์ž‘๋™ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์–ด๋–ป๊ฒŒ ํ•˜๋“  ์ƒ๊ด€์—†๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.


๋‚ด๊ฐ€ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋Š” ๊ด€๋ จ์ด ์—†๋Š” ์ด์  ์ค‘ ํ•˜๋‚˜๋Š” ์žฌ๋ฃŒ๋ฅผ ์กฐ์ž‘ํ•˜๋Š” ๋…ผ๋ฆฌ๋ฅผ ๋™์ผํ•œ ๋ธ”๋ก๊ณผ ๋™์ผํ•œ ์ˆ˜์ค€์—์„œ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์–ด๋”˜๊ฐ€์— ์ƒ‰์ƒ์ด ๋ณ€๊ฒฝ๋˜๋Š” ์ฝ”๋“œ๊ฐ€ ์žˆ๊ณ  ๋‚˜์ค‘์— ํ•ด๋‹น ์ž๋ฃŒ์— ์‚ฌ์šฉ์ž ์ •์˜ GLSL์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒฝ์šฐ ์ƒ‰์ƒ์œผ๋กœ ์œ ๋‹ˆํผ์„ ๋ณ€๊ฒฝํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (ํ…์ŠคํŠธ ๋ฒฝ ๊ฑด๋„ˆ๋›ฐ๊ธฐ)


uv_pars_vertex ์ด ํ˜ผ๋ž€์Šค๋Ÿฝ๋‹ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์งˆ๋ฌธ์„ ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

" float rand( vec2) ์™€ ๊ฐ™์€ ์‚ฌ์šฉ์ž ์ง€์ • GLSL ํ•จ์ˆ˜๋ฅผ ์–ด๋””์— ์‚ฝ์ž…ํ•ฉ๋‹ˆ๊นŒ?"

๊ทธ๋ ‡๋‹ค๋ฉด ์ด๊ฒƒ์€ ์˜๋ฏธ๊ฐ€์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค https://github.com/mrdoob/three.js/pull/11050


๋˜ ๋‹ค๋ฅธ ์ฃผ์žฅ์€ - GLSL์„ ์•Œ๊ณ  ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ณ  THREE์˜ ์…ฐ์ด๋” ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์•Œ๊ณ  ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•  ๋•Œ ์—ฌ์ „ํžˆ ์ฐฝ์˜์ ์ด์–ด์•ผ ํ•˜๋ฉฐ ์–ด๋””์— ๋ฌด์—‡์„ ์ฃผ์ž…ํ• ์ง€ ์ƒ๊ฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. uv_pars_vertex ๊ฐ€ ๋‚ด ๋จธํ‹ฐ๋ฆฌ์–ผ ํ™•์žฅ์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ์— ํŽธ๋ฆฌํ•œ ์žฅ์†Œ๋ผ๋Š” ๊ฒƒ์„ ์•Œ์•„๋‚ด๊ธฐ ์œ„ํ•ด ์•ฝ๊ฐ„ ์ƒ๊ฐํ•˜๊ณ  ๋Œ€๋ถ€๋ถ„์˜ ์…ฐ์ด๋”๋ฅผ ์‚ดํŽด๋ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด์™€ ๊ฐ™์€ ๊ฒƒ์—์„œ ์ถ”์ƒํ™”๋กœ ์ด๋™ํ•˜๊ณ  lightingPhase , objectTransformation , perspectiveTransformation ๋“ฑ์˜ ํ›„ํฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ๋˜๋Š” ๋ชจ๋“  ์…ฐ์ด๋” ํ”„๋กœ๊ทธ๋žจ์— ํฌํ•จ๋œ ์ ์–ด๋„ guaranteedToBeAboveMainButBelowCommonsAndExtensionCalls ๋”๋ฏธ ์ฒญํฌ. % vertex % ๋ฅผ) ์‚ฌ์šฉํ•˜๋ ค๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๊นŒ? ๊ทธ๋Ÿฌ๋‚˜ ๋‚˜๋Š” ๊ทธ ๊ตฌ๋ฌธ์— ์ต์ˆ™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด PR์€ ์žˆ๋Š” ๊ทธ๋Œ€๋กœ ๋ฐ˜๋Œ€ ๋ฐฉํ–ฅ์œผ๋กœ ๊ฐ€๊ณ  ์žˆ๋Š” ๊ฒƒ ๊ฐ™๋‹ค. ํƒญํ•ด์•ผ ํ•  ์œ„์น˜๋ฅผ ์•„๋Š” ๊ฒƒ ์™ธ์—๋„ ๋ช…์‹œ์ ์œผ๋กœ ๋ฌธ์ž์—ด์„ ์กฐ์ž‘ํ•˜๊ณ  ๋ Œ๋”๋Ÿฌ๊ฐ€ ์ด๋ฏธ ์ˆ˜ํ–‰ํ•˜๋Š” ์ž‘์—… ์ค‘ ์ผ๋ถ€๋ฅผ ๋ฐ˜๋ณตํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ์ฒซ ๋ฒˆ์งธ ์งˆ๋ฌธ ์™ธ์— ๋‹ค๋ฅธ ์งˆ๋ฌธ์„ ํ•˜๋ฉด

๋‚ด๊ฐ€ ์ฃผ์ž…ํ•˜๋Š” ํ•จ์ˆ˜ ๋‚ด์—์„œ commons ์ฒญํฌ์— ์„ ์–ธ๋œ ํ•จ์ˆ˜๋ฅผ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•ฉ๋‹ˆ๊นŒ?

์ „์ฒด ์…ฐ์ด๋”์— ์œ ๋‹ˆํผ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋” ๋งŽ์€ ๋ฌธ์ž์—ด ์กฐ์ž‘์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์ž์‹ ์„ ๋ฐœ๊ฒฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

uv_pars_vertex ๊ฐ€ ๋‚ด ๋จธํ‹ฐ๋ฆฌ์–ผ ํ™•์žฅ์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ์— ํŽธ๋ฆฌํ•œ ์žฅ์†Œ๋ผ๋Š” ๊ฒƒ์„ ์•Œ์•„๋‚ด๊ธฐ ์œ„ํ•ด ์•ฝ๊ฐ„์˜ ์ƒ๊ฐ์„ ํ•˜๊ณ  ๋Œ€๋ถ€๋ถ„์˜ ์…ฐ์ด๋”๋ฅผ ์‚ดํŽด๋ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๊ฐ€ ๊ณผ๋„ํ•˜๊ฒŒ ์—”์ง€๋‹ˆ์–ด๋งํ•˜์ง€ ์•Š๋Š” ํ•œ ๊ทธ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ๋ฐฉ๋ฒ•์ด ์—†๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. % vertex % ์˜ ์•„์ด๋””์–ด๋Š” ํ›„ํฌ์˜ ์ด๋ฆ„์„ ์ง€์ •ํ•˜์—ฌ ์•ฝ๊ฐ„์˜ ๋„์›€์„ ์ฃผ๊ณ  ์ฝ”๋“œ๋ฅผ ์ฃผ์ž…ํ•˜๋Š” ์ƒํƒœ๋ฅผ ์–ด๋Š ์ •๋„ ์•Œ๋ ค์ฃผ์ง€๋งŒ ์–ด๋Š ์‹œ์ ์—์„œ ์–ด๋–ค ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ๋ฌธ์„œํ™”ํ•˜๊ธฐ ์–ด๋ ค์šธ ๊ฒƒ์ž…๋‹ˆ๋‹ค. .

๋นŒํŠธ์ธ ๋จธํ‹ฐ๋ฆฌ์–ผ ํ•ดํ‚น์„ ํ—ˆ์šฉํ•˜๋Š” ๋ฌธ์„ ์—ด๊ณ  ์žˆ์ง€๋งŒ ์ ์ ˆํ•œ "์ง€์›"์„ ์ œ๊ณตํ•  ์ˆ˜ ์—†๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” ๋ฌผ๊ฑด์ด ํŒŒ์†๋  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์Œ์„ ์ธ์ง€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋‹ค๋ฅธ PR์—์„œ ๋‹ค๋ฃจ๋ ค๊ณ  ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ ์–ด๋„ ๊ธฐ๋Šฅ, ๋ณ€์ˆ˜, ์†์„ฑ ๋ฐ ์œ ๋‹ˆํผ์— ๋Œ€ํ•ด ๋”๋ฏธ ํ›„ํฌ๋ฅผ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋งŽ์€ GLSL ๋กœ์ง์ด ์ด๋ฏธ ๊ตฌ์กฐ์ฒด์—์„œ ๋ฐœ์ƒํ•˜๊ณ  Scenekit์€ ๊ฐ ๋ณ€์ˆ˜๋ฅผ ๋ฌธ์„œํ™”ํ–ˆ์Šต๋‹ˆ๋‹ค(๋” ์ด์ƒ ๋™์ผํ•œ ๋ฌธ์„œ๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Œ).

์ง„ํ–‰ํ•˜๋ฉด์„œ ๋ฆฌํŒฉํ† ๋งํ•ด์•ผ ํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋‚ด์šฉ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

#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

๋ฌผ๋ก  ifdef ๋ฐ ํฌํ•จ์€ ์•„๋งˆ๋„ ์ด์™€ ๊ฐ™์ด ์ž‘๋™ํ•˜์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‹ค๋ฅธ ์ ‘๊ทผ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๋ฉด ๋น„๊ต์  ๊ฐ„๋‹จํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋นˆ ๋ฌธ์ž์—ด๋กœ ํ•ญ์ƒ #include <some_phase> ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. #ifdef ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŠธ๋ฆฌ๊ฑฐ๋˜๋Š” ํ•ญ๋ชฉ์„ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด "vertex_transformation" ๋‹จ๊ณ„์— ๋Œ€ํ•œ ๋…ผ๋ฆฌ๋ฅผ ์ œ๊ณตํ•˜๋ฉด ์…ฐ์ด๋”๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๋ชจ๋“  ๊ฒƒ์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ ์ฒญํฌ๊ฐ€ GLSL๋กœ ์ˆ˜ํ–‰ํ•˜๋Š” ์ž‘์—…์„ ๋ฌธ์„œํ™”ํ•˜๋ฉด ์ „๋ฐ˜์ ์œผ๋กœ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. ์ถ”์ƒํ™”๋กœ ๋” ์ด์ƒ ์ง„ํ–‰ํ•˜์ง€ ์•Š๊ณ  ์ฒญํฌ๊ฐ€ ํ˜„์žฌ ๊ตฌ์กฐํ™”๋˜๋Š” ๋ฐฉ์‹์— ๋Œ€ํ•œ ์ด ์ง€๋„๋ฅผ ๊ฐ–๋Š” ๊ฒƒ์ด ์ข‹์„ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋นŒํŠธ์ธ ๋จธํ‹ฐ๋ฆฌ์–ผ ํ•ดํ‚น์„ ํ—ˆ์šฉํ•˜๋Š” ๋ฌธ์„ ์—ด๊ณ  ์žˆ์ง€๋งŒ ์ ์ ˆํ•œ "์ง€์›"์„ ์ œ๊ณตํ•  ์ˆ˜ ์—†๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” ๋ฌผ๊ฑด์ด ํŒŒ์†๋  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์Œ์„ ์ธ์ง€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” ์ด๋ฏธ ๋ชจ๋“  ์žฌ๋ฃŒ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ •์˜ ํ•ญ๋ชฉ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. https://github.com/mrdoob/three.js/issues/10764๋Š” ์ˆ˜์ • ์ œ์•ˆ THREE.ShaderLib ๋‹ค์Œ ์ •์˜ .defines ์˜ ์ธ์Šคํ„ด์Šค์— ์†์„ฑ์„ Material . ๋ฌผ๋ก , ๊ทธ ์†์„ฑ์€ ๋‚ด๊ฐ€ ํ•ญ๋ชฉ์„ ์ž‘์„ฑํ•  ๋•Œ๊นŒ์ง€ ๋ฌธ์„œํ™”๋˜์ง€ ์•Š์•˜์œผ๋ฉฐ(ํ•˜์ง€๋งŒ ๋‹น์‹ ์€ ๊ทธ๊ฒƒ์„ ์Šน์ธํ–ˆ์Šต๋‹ˆ๋‹ค :)), ์—ฌ์ „ํžˆ ์ •์˜๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค .

๊ทธ๋Ÿฌ๋‚˜ ์ด๊ฒƒ์ด ํ˜„์žฌ ์ž‘๋™ํ•˜๊ณ  ๋ชจ๋“  ๋จธํ‹ฐ๋ฆฌ์–ผ์— ์˜ํ•ด ์ƒ์†๋˜๋Š” ๋ฐฉ์‹์€ ์ง€์› ๋ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์— ๋ฌด์–ธ๊ฐ€๋ฅผ ๋„ฃ์œผ๋ฉด ํ•ด๋‹น ๋จธํ‹ฐ๋ฆฌ์–ผ์˜ ์…ฐ์ด๋”์— ์˜ํ–ฅ์„ ๋ฏธ์นฉ๋‹ˆ๋‹ค . ๊ฒŒ๋‹ค๊ฐ€ ์ด๋ฏธ ์…ฐ์ด๋” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์ผ๋ถ€์ธ ๋ฌด์–ธ๊ฐ€๋ฅผ ์ •์˜ํ•˜๋ฉด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค .

๋˜‘๋˜‘ํ•œ ์‚ฌ๋žŒ์ด ๋˜๋ ค๊ณ  ํ•˜์ง€ ์•Š๊ณ  ๋ชจ๋ฒ”์„ ๋ณด์ด๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ์ €๋Š” ์ฃผ๋กœ ShaderMaterial ์ •์˜๋ฅผ ์‚ฌ์šฉํ–ˆ์ง€๋งŒ WebGLRenderer ์ž‘๋™ํ•˜๋Š” ๋ฐฉ์‹ ๋•Œ๋ฌธ์— ๋ชจ๋“  ์žฌ๋ฃŒ์— ์˜ํ–ฅ์„ ๋ฏธ์นฉ๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋…ผ๋ฆฌ๋Š” ์—†์Šต๋‹ˆ๋‹ค.

Phong ์™€ ๊ฐ™์€ ์žฌ๋ฃŒ์˜ ์ถ”์ƒํ™”์™€ ๊ฐ™์€ ํ›จ์”ฌ ๋” ๋˜‘๋˜‘ํ•˜๊ณ  ํ‘œ๋ฉด์ ์ด๋ผ๋ฉด ์ •์˜๋ฅผ ๊ณ ๋ คํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค. three๋Š” ์…ฐ์ด๋” ์ฒญํฌ๋ฅผ ์žฌ์ •์˜ํ•˜๋„๋ก ์„ค๊ณ„๋˜์ง€ ์•Š์•˜์œผ๋ฉฐ Phong ํ…œํ”Œ๋ฆฟ์€ GLSL์ด ์ˆ˜ํ–‰ํ•ด์•ผ ํ•˜๋Š” ์ž‘์—…์— ๋Œ€ํ•œ ์ตœ์ข… ๊ถŒํ•œ์ด๋ฉฐ ์ด๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ๋ชปํ•˜๋„๋ก ์ˆจ๊ธฐ๋Š” ์—ญํ• ์„ ํ•˜๋ฏ€๋กœ GLSL ์ •์˜๊ฐ€ ์ด๋ฅผ ๋ฐฉํ•ดํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜๋„ ๊นจ์งˆ ์ˆ˜ ์žˆ์„์ง€๋Š” ๋ชจ๋ฅด๊ฒ ์ง€๋งŒ ์‹œ๋„๋Š” ํ•ด๋ด์•ผ๊ฒ ๋„ค์š”.

๊ทธ๋ ‡๊ฒŒ ๋งํ•˜๋ฉด์„œ ๋งŽ์€ ์ด์ต์„ ์ œ๊ณตํ•œ๋‹ค๋ฉด ๋ฌผ๊ฑด์„ ๋ถ€์ˆ˜๋Š” ์˜ต์…˜์„ ์›ํ•ฉ๋‹ˆ๋‹ค. ๊ฝค ์บก์Šํ™”๋˜๊ณ  ์ž‘์€ GLSL ์Šค๋‹ˆํŽซ์„ ์‚ฌ์šฉํ•˜์—ฌ 3๊ฐœ์˜ ๋ฒ„์ „์„ ์‰ฝ๊ฒŒ ๋ณ€๊ฒฝํ•˜์—ฌ ๋…ธ๋ฉ€ ๋งต์„ ๋‹ค๋ฅด๊ฒŒ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋…ธ๋ฉ€์„ ์ทจํ•˜๊ณ  ๊ทธ๊ฒƒ์„ ๋‹ค๋ฅธ ๋…ธ๋ฉ€์„ ์–ป๊ธฐ ์œ„ํ•ด ๋ณ€ํ™˜ํ•˜๋Š” ๊ฒƒ์€ ๋งค์šฐ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. ์™„์ „ํžˆ ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ ์ปดํ“จํ„ฐ ๊ทธ๋ž˜ํ”ฝ์„ ์‹œ์ž‘ํ•˜์ง€ ์•Š๋Š” ํ•œ, ์ €๋Š” ์ด๊ฒƒ์ด ๊นจ์ง€๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. :)

์ธ์Šคํ„ด์Šคํ™”๋Š” ๋˜ ๋‹ค๋ฅธ ์˜ˆ์ž…๋‹ˆ๋‹ค.

์˜ค ANGLE_INSTANCED_ARRAYS๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. 3๊ฐœ๋Š” ๊ทธ๋ฆผ์ž ๋˜๋Š” PBR ์žฌ์งˆ๋กœ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ด ๋‘ ์ค„์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์ €์—๊ฒŒ ์ ํ•ฉํ•˜๊ฒŒ ๋งŒ๋“ค๊ฒ ์Šต๋‹ˆ๋‹ค."

์ด ๊ธฐ๋Šฅ์ด ๋งˆ์นจ๋‚ด three.js์— ์ œ๊ณต๋œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋˜์–ด ๊ธฐ์ฉ๋‹ˆ๋‹ค. :). ์˜ˆ, yet another material modifier PR ๋„ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. (https://github.com/mrdoob/three.js/pull/7581) ๋„ˆ๋ฌด ์˜ค๋ž˜๋˜์–ด ์ฝ”๋“œ๊ฐ€ ๋” ์ด์ƒ ๊ด€๋ จ์ด ์—†์ง€๋งŒ ๊ธฐ๋ณธ์ ์œผ๋กœ @mrdoob ๊ณผ ๊ฐ™์€ ํ›„ํฌ๋ฅผ ์ฃผ์ž…ํ•˜๊ณ 
๋‚˜๋Š” ์ด ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๊ณ ์ž ํ•˜๋Š” ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ๋žŒ๋“ค์ด ๊ธฐ๋ณธ ์ž๋ฃŒ๋ฅผ ์™„์ „ํžˆ ๋‹ค์‹œ ์ž‘์„ฑํ•˜๋Š” ๋Œ€์‹  "์•ฝ๊ฐ„" ์ˆ˜์ •ํ•˜๊ธฐ๋ฅผ ์›ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ˆ˜์ •ํ•˜๋Š” ๋‚ด์šฉ์„ ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๊ธฐ ๋•Œ๋ฌธ์— ๋ฏธ๋ฆฌ ์ •์˜๋œ ํ›„ํฌ์˜ ์•„์ด๋””์–ด๋ฅผ ์ข‹์•„ํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ด PR์˜ ๋‹จ์ˆœํ•จ์„ ์ข‹์•„ํ•˜์ง€๋งŒ ์šฐ๋ฆฌ๊ฐ€ ์ผ์„ ํ•˜๊ธฐ ์œ„ํ•ด ๋” ๊ตฌ์กฐํ™”๋˜๊ณ  ๊นจ๋—ํ•œ ๋ฐฉ๋ฒ•์„ ์›ํ•œ๋‹ค๋ฉด ๋‚˜๋Š” ์ด๋ฏธ ๋‹น์‹ ์˜ ์ฝ”๋“œ๋กœ ๋Œ€์ฒดํ•  ํ›„ํฌ ์‚ฌ์ „๊ณผ ์œ ๋‹ˆํผ์ด๋‚˜ ์‚ฌ์šฉ์ž ์ •์˜ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋” ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์„ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค. ๋ฌธ์ž์—ด๋งŒ ๊ต์ฒดํ•ฉ๋‹ˆ๋‹ค.

@fernandojsg #10791์„ ํ™•์ธํ•˜๊ณ  ํ”ผ๋“œ๋ฐฑ์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐํšŒ๊ฐ€ ์žˆ์œผ๋ฉด ๋ฉ”์ธ ๋ฐ”๋กœ ์™ธ๋ถ€์— ์ถ”๊ฐ€ ํ›„ํฌ(๊ท€ํ•˜์˜ "pre_vertex"์™€ ๊ฐ™์€ ๊ฒƒ)๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ๊ด€๋ฆฌ๊ฐ€ ์•ฝ๊ฐ„ ๋” ์žˆ๋‹ค๋Š” ์ ์„ ์ œ์™ธํ•˜๊ณ ๋Š” ๊ท€ํ•˜๊ฐ€ ํ•œ ๊ฒƒ๊ณผ ๋งค์šฐ ์œ ์‚ฌํ•ด ๋ณด์ž…๋‹ˆ๋‹ค.

@fernandojsg ๋‹น์‹ ์˜ ํ™๋ณด๋ฅผ ์žŠ์–ด๋ฒ„๋ ธ์Šต๋‹ˆ๋‹ค ๐Ÿ˜š. ๋‚˜๋Š” ๋‹น์‹ ์˜ PR์ด ๋‚ด๊ฐ€ ์ด ์ผ์„ ๋ณด๊ธฐ ์‹œ์ž‘ํ–ˆ๋˜ ๋ฐฉ์‹๊ณผ ๊ฝค ๋งŽ์ด ๋‹ฎ์•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ž ์žฌ์˜์‹?

๋˜‘๋˜‘ํ•œ ์‚ฌ๋žŒ์ด ๋˜๋ ค๊ณ  ํ•˜์ง€ ์•Š๊ณ  ๋ชจ๋ฒ”์„ ๋ณด์ด๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ฃผ๋กœ ShaderMaterial ์ •์˜๋ฅผ ์‚ฌ์šฉํ–ˆ์ง€๋งŒ WebGLRenderer ์ž‘๋™ํ•˜๋Š” ๋ฐฉ์‹ ๋•Œ๋ฌธ์— ๋ชจ๋“  ์žฌ๋ฃŒ์— ์˜ํ–ฅ์„ ๋ฏธ์นฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ ์‹์œผ๋กœ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ•ดํ‚นํ•  ์ˆ˜ ์žˆ์–ด์„œ ๋‹คํ–‰์ด์ง€๋งŒ ์˜๋„ํ•˜์ง€ ์•Š์€ ์šฉ๋„๋กœ ๋‚ด๋ถ€์ ์œผ๋กœ ๋‚จ์šฉ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ์‹์œผ๋กœ ๊นจ์ง€๊ธฐ ์‰ฌ์šด ์ฝ”๋“œ๋กœ ๋๋‚˜๋Š” ๊ฒƒ์€ ์‰ฝ์Šต๋‹ˆ๋‹ค.

#7581์„ ๋‹ค์‹œ ์ฝ๋Š” ์ค‘... https://github.com/mrdoob/three.js/commit/e55898c27a843f69a47e602761c60d9bbe91ee35 ์œ„์— % 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 ์žฌ๋ฃŒ = ์ƒˆ๋กœ์šด 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 ์ •์  ์…ฐ์ด๋”์— ์ฝ”๋“œ๋ฅผ ์‚ฝ์ž…ํ•ด์•ผ ํ•˜๋Š” ์œ„์น˜๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ๋‚˜๋จธ์ง€ ์ž๋ฃŒ๋Š” ์—ฌ๊ธฐ์—์„œ:)

https://github.com/mrdoob/three.js/pull/10750

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๋กœ ์ž…๋ ฅ ํ•  ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค.

์ฝ”๋“œ๊ฐ€ ๊ฝค ํฉ์–ด์ ธ ์žˆ๋Š” ํŠน์ • ํ•ญ๋ชฉ์— ๊ด€ํ•ด์„œ๋Š” ์ด ๋ชฉ๋ก์ด ๊ฝค ๋น ๋ฅด๊ฒŒ ์ปค์งˆ ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋…ธ๋ฉ€ ๋งต์„ ์ˆ˜ํ–‰ํ•˜๋Š” ํ•œ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์€ vert์™€ frag ๋ชจ๋‘์—์„œ ๋‘ ๊ฐ€์ง€ ์ถ”๊ฐ€ ์†์„ฑ, ๊ฐ€๋ณ€ ๋ฐ ๋ณ€ํ™˜ ๋…ผ๋ฆฌ๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ์—ฌ์ „ํžˆ ๊ฐ„๋‹จํ•˜๊ณ  ์šฐ์•„ํ•œ ์ตœ์‹  ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ข‹์•„ํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ์šฐ๋ฆฌ๊ฐ€ ์ „์—ญ ๋ฒ”์œ„์— ์ฝ”๋“œ๋ฅผ ๋„ฃ์„ ์žฅ์†Œ๊ฐ€ ํ•„์š”ํ•˜๋‹ค๋Š” @pailhead์— ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. https://github.com/mrdoob/three.js/pull/7581์—์„œ preMainVertex preMainFragment ๋ฅผ ์ „์—ญ์ ์œผ๋กœ ์ฃผ์ž…ํ•˜์—ฌ ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ๊ณผ ๊ธฐ๋Šฅ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ–ˆ์Šต๋‹ˆ๋‹ค. ์•„๋งˆ๋„ globalVertex/Fragment ๋˜๋Š” ์ด์™€ ์œ ์‚ฌํ•œ ์ด๋ฆ„์ด ๋” ๋‚˜์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

GLOBAL_VERTEX ๋ฐ GLOBAL_FRAGMENT ์ข‹์€ ์†Œ๋ฆฌ ๐Ÿ‘Œ

๋‹ค๋ฅธ ํ™๋ณด์—์„œ ์ด๋ฆ„์„ ์ •ํ™•ํžˆ ์–ด๋–ป๊ฒŒ ์ง€์—ˆ๋Š”์ง€ ๐Ÿ˜† ๐Ÿ‘

@pailhead ํ•˜์ง€๋งŒ ์ด์ œ ์ฝ”๋“œ๋ฅผ ๋ณ‘ํ•ฉํ•˜๋Š” ๋น„๋ฐ€์„ ์•Œ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. PR์„ ์—ด๊ณ  ์ž ์‹œ ๊ทธ๋Œ€๋กœ ๋‘” ๋‹ค์Œ

image

์ด์ œ ์ง„์ง€ํ•˜๊ฒŒ ๋‚˜๋„ ๊ทธ ์ด๋ฆ„์„ ์ข‹์•„ํ•˜๊ณ  ๊ทธ๊ฒƒ์œผ๋กœ ์šฐ๋ฆฌ๊ฐ€ ๊ฐˆ ์ค€๋น„๊ฐ€ ๋˜์—ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๊นŒ, ์•„๋‹ˆ๋ฉด ๋‚ด๊ฐ€ ๋ญ”๊ฐ€๋ฅผ ๋†“์น˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ? ๋‚ด PR์˜ ์˜ˆ์ œ๋ฅผ ์ด ์ƒˆ ์ฝ”๋“œ๋กœ ๋ณ€ํ™˜ํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.)

์ฝ”๋“œ๊ฐ€ ๋“ค์–ด๊ฐ€๋Š” ๋ถ€๋ถ„์€ ๊ดœ์ฐฎ๊ณ  ํƒ€์ž„๋ผ์ธ์ด ์ข€ ์–ด๊ธ‹๋‚˜ ์žˆ์Šต๋‹ˆ๋‹ค. #7581์€ ๊ฑฐ์˜ 2๋…„ ์ „์— ์ œ์•ˆ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. https://github.com/mrdoob/three.js/issues/10789 ์—์„œ ์ฐธ์กฐ๋˜์ง€ ์•Š์•˜์œผ๋ฏ€๋กœ ์•„๋งˆ๋„ ๋ ˆ์ด๋”์—์„œ ๋ฒ—์–ด๋‚ฌ์Šต๋‹ˆ๋‹ค. ๋ถ€๋”ชํžˆ๊ฑฐ๋‚˜ ๊ฐˆํ€ด๋ฅผ ์ณค์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ชจ๋“ˆ์„ ๊ฐ€์ ธ์˜ค๊ณ  ์ž์‹ ์˜ ์„ธ ๊ฐ€์ง€๋ฅผ ์ฒด๋ฆฌํ”ผํ‚นํ•˜๋Š” ๊ฒฝ์šฐ์—๋„ ์‚ฌ๋žŒ๋“ค์€ ๋น„๊ณต์‹ ํ•ต์‹ฌ ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ๊ทธ๋‹ค์ง€ ๋งŒ์กฑํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. "์ด๋ด, foo๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” npm ํŒจํ‚ค์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค"๋ผ๊ณ  ๋งํ•˜๋Š” ๊ฒƒ์ด ํ›จ์”ฌ ์‰ฝ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๋‚ด๊ฐ€ ์ด์™€ ๊ฐ™์€ PR์„ ์ค‘์š”ํ•˜๊ฒŒ ์ƒ๊ฐํ•˜๋Š” ์ด์œ ์ž…๋‹ˆ๋‹ค. ์„ธ ๊ฐ€์ง€๋Š” ์ถฉ๋ถ„ํžˆ ์œ ์—ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด์ต!

๋ฌด์Šจ ์ด์ต? ๐Ÿ˜†

์ฝ”๋“œ๊ฐ€ ๋“ค์–ด๊ฐ€๋Š” ๋ถ€๋ถ„์€ ๊ดœ์ฐฎ๊ณ  ํƒ€์ž„๋ผ์ธ์ด ์ข€ ์–ด๊ธ‹๋‚˜ ์žˆ์Šต๋‹ˆ๋‹ค. #7581์€ ๊ฑฐ์˜ 2๋…„ ์ „์— ์ œ์•ˆ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. https://github.com/mrdoob/three.js/issues/10789 ์—์„œ ์ฐธ์กฐ๋˜์ง€ ์•Š์•˜์œผ๋ฏ€๋กœ ์•„๋งˆ๋„ ๋ ˆ์ด๋”์—์„œ ๋ฒ—์–ด๋‚ฌ์Šต๋‹ˆ๋‹ค. ๋ถ€๋”ชํžˆ๊ฑฐ๋‚˜ ๊ฐˆํ€ด๋ฅผ ์ณค์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ญ๋ผ๊ณ  ์š”? ์ƒˆ PR์„ ๋งŒ๋“ค๊ธฐ ์ „์— ์—ด๋ ค ์žˆ๋Š” ๋ชจ๋“  PR์„ ํ™•์ธํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๊นŒ? #ํŠธ๋กค๋กค

์ง„์‹ค :)

ํ™•์ธ์„ ๋ˆŒ๋Ÿฌ ๋ชฉ๋ก์—์„œ ์ „ํ™”๋ฅผ ๊ฑธ๊ณ  ์ตœ๋Œ€ํ•œ ๋นจ๋ฆฌ ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.: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 ๋ฅผ ์กฐ์ •ํ•˜๋ ค๋ฉด ์ผ๋ถ€ ์ฒญํฌ๋ฅผ ๋ชจ๋‘ ๊ต์ฒดํ•ด์•ผ ํ•˜์ง€๋งŒ, ์ด๊ฒƒ์€ ๋งค์šฐ ๊ทน๋‹จ์ ์ธ ๊ฒฝ์šฐ์ฒ˜๋Ÿผ ๋Š๊ปด์ง‘๋‹ˆ๋‹ค.

์ƒ๊ฐ๋‚˜๋Š”๊ฒŒ ์ด ๋‘๊ฐ€์ง€์ธ๋ฐ ๋” ์žˆ๋Š”์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ % 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};

์ด๊ฒƒ์€ ํ•˜๋‚˜์˜ ์žฌ๋ฃŒ์—์„œ ์—ฌ๋Ÿฌ ํ…์Šค์ฒ˜ ์‚ฌ์ด์˜ ์ „ํ™˜ ์ฝ”๋“œ๊ฐ€ ์–ผ๋งˆ๋‚˜ ๊ฐ„๋‹จํ•  ์ˆ˜ ์žˆ๋Š”์ง€์ž…๋‹ˆ๋‹ค.

๊ทธ๊ฒƒ์€ ์‰ฝ๊ฒŒ ๊ตฌํ˜„๋  ์ˆ˜ ์žˆ๊ณ  ๋ถˆํ•„์š”ํ•œ ์ฝ”๋“œ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์„ ํ”ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@sasha240100

https://github.com/mrdoob/three.js/pull/10791 ์€ parts ๋ฅผ shaderChunks ํ•˜๊ณ  ์ด๋ฅผ ๋…ผ์Ÿ.
:roll_eyes: ๐Ÿ˜†

์ฒญํฌ๊ฐ€ ์ด๋ฏธ ํ‘œ์‹œ๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ frag{} ์‚ฌ์ „๋„ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ชจ๋‘ _fragment ๋ฐ _vertex ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ๋Œ€์ฒดํ•ด์•ผ ํ•  ๊ฒƒ์„ ์ฐพ๊ธฐ ์œ„ํ•ด ๋ฌธ์ž์—ด์„ ๊ฒ€์ƒ‰ํ•ด์•ผํ•œ๋‹ค๋Š” ์ ์„ ์ œ์™ธํ•˜๊ณ ๋Š” ๋™์ผํ•ฉ๋‹ˆ๋‹ค.

@pailhead ์˜ˆ, frag: {} ์‚ญ์ œํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ๋จธํ‹ฐ๋ฆฌ์–ผ ์…ฐ์ด๋”๊ฐ€ ์—ฐ๊ฒฐ๋˜๊ธฐ ์ „์— ์ „๋‹ฌ๋˜์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ธ์ˆ˜๋กœ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ ์—ฐ๊ฒฐ ํ›„ ๊ธฐ์กด ๋ถ€ํ’ˆ์„ ๊ต์ฒดํ•˜์ง€ ์•Š์•„๋„ ๋ฉ๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” ์‹ค์ œ๋กœ ์ธ์ˆ˜์™€ ์†์„ฑ์„ ๋‘˜ ๋‹ค ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. color ์ฒ˜๋Ÿผ

์ง€๊ธˆ ์—ฌ๊ธฐ๊ฐ€ ์–ด๋””์ž…๋‹ˆ๊นŒ? ์˜ˆ์ œ๊ฐ€ .replace() ํ•˜๊ณ  ์žˆ๊ณ  ํ›„ํฌ/๊ต์ฒด ๊ฐ€๋Šฅํ•œ ์ฒญํฌ๊ฐ€ ๋ณด์ด์ง€ ์•Š์Šต๋‹ˆ๊นŒ? @mrdoob

์•„์ง ์ด๊ฒƒ์œผ๋กœ ๋Œ์•„๊ฐ€์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.

% hook % ๋Œ€ํ•œ ํ™๋ณด๋ฅผ ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

์œ„์˜ ์˜๊ฒฌ์—์„œ ํ™•์žฅ๋œ ์ž๋ฃŒ๋ฅผ ์›ํ•˜์‹ญ๋‹ˆ๊นŒ?

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 ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ํฌํ•จ์„ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ๋‚ด๊ฐ€ ์“ด ์ง€๊ธˆ์€ ์„ธ ์‚ฌ๋žŒ์˜ ์ฑ…์ž„์ด ์•„๋‹Œ ๊ฒƒ์ฒ˜๋Ÿผ ๋“ค๋ฆฌ์ง€๋งŒ ๋‹ค๋ฅธ ํ•œํŽธ์œผ๋กœ๋Š” ๋ฏธ๋ž˜์— % hook % ๋Œ€ํ•ด THREE.ExtendedMaterial ์Šคํ…์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

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 ์žฌ๋ฃŒ๊ฐ€ ์–ด๋–ป๊ฒŒ ์ƒ๊ฒผ๋Š”์ง€์ด๋ฉฐ ์ž๋ฆฌ ํ‘œ์‹œ์ž๋งŒ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. https://github.com/zadvorsky/three.bas/blob/master/src/materials/PhongAnimationMaterial.js

์•ˆ๋…•ํ•˜์„ธ์š” ์—ฌ๋Ÿฌ๋ถ„, ์ €๋Š” ๋Œ€ํ™”๋ฅผ ๋”ฐ๋ฅด๋ ค๊ณ ํ–ˆ์ง€๋งŒ ์†”์งํžˆ ๊ฒŒ์ž„ ๊ฐœ๋ฐœ์ž๊ฐ€ ์•„๋‹Œ ํ”„๋ก ํŠธ ์—”๋“œ์—์„œ ์™”๊ธฐ ๋•Œ๋ฌธ์— ๊ธธ์„ ์žƒ์—ˆ์Šต๋‹ˆ๋‹ค.

MTL์„ ๋กœ๋“œํ•˜๋ ค๊ณ  ํ•˜๋Š”๋ฐ ๋‹ค์Œ์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

material.onBeforeCompile.toString()์ด ์ •์˜๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

๋‚ด MTL ํŒŒ์ผ์€ ์›๋ž˜ .psd ํŒŒ์ผ์„ ๊ฐ€๋ฆฌํ‚ค๊ณ  ์žˆ์—ˆ๊ณ  ๋™์ผํ•œ ํด๋”๋ฅผ ํฌํ•จํ•˜๋Š” ๋ช‡ ์•ˆ ๋˜๋Š” png ์ค‘ ํ•˜๋‚˜๋กœ ๋ณ€๊ฒฝํ–ˆ์Šต๋‹ˆ๋‹ค(์ผ๋ฐ˜). 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)

im์„ ์‚ฌ์šฉํ•˜๋Š” ์ฝ”๋“œ๋Š” ์ฃผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

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 );

}

์ด๊ฒƒ์ด ๋ชจ๋ธ์˜ ๋ฌธ์ œ์ž…๋‹ˆ๊นŒ? 3์—? mtl ๋กœ๋”์—์„œ? ์†”๋ฃจ์…˜์ด ์žˆ์Šต๋‹ˆ๊นŒ?

๋„์›€์„ ์ฃผ์‹œ๋ฉด ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.
๊ฐ์‚ฌ ํ•ด์š”.

material.shader = shader ์—์„œ material.onBeforeCompile(shader=>...) material.shader = shader ์™€ ๊ฐ™์€ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ๋‹ค์†Œ ํˆฌ๋ฐ•ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์–ธ์  ๊ฐ€๋Š” ๋‹ค๋ฅธ ์ œ์•ˆ์„ ๋‹ค์‹œ ๋ฐฉ๋ฌธํ•  ๊ฐ€์น˜๊ฐ€ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. :)

@jjalonso

์ด๊ฒƒ์€ ๋ฒ„๊ทธ์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค:

https://stackoverflow.com/questions/46787166/react-and-three-js-mtlloader-material-onbeforecompile-is-undefined

์ด๊ฒƒ์œผ๋กœ ์ธํ•ด ๋ฐœ์ƒํ•˜์ง€๋งŒ Material ์— ์ด ๊ธฐ๋Šฅ์ด ์—†๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?
https://github.com/mrdoob/three.js/blob/35a26f178c523514673d992da1aece23c1cfca6e/src/renderers/webgl/WebGLPrograms.js#L244

@mrdoob

์ด๋Ÿฌํ•œ ํ™•์žฅ๋œ ์…ฐ์ด๋”๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์บ์‹œ๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ๋‘ ๊ฐ€์ง€ ๋‹ค๋ฅธ ์žฌ๋ฃŒ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ํ•˜๋‚˜๋Š” dithering_fragment ๋ณ€๊ฒฝ๋˜์—ˆ๊ณ  ๋‹ค๋ฅธ ํ•˜๋‚˜๋Š” ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๋‘˜ ๋‹ค ์žฅ๋ฉด์— ์ถ”๊ฐ€ํ•˜๋ฉด 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

}
*/

๊ทธ๋Ÿฌ๋‚˜ ๋‹ค๋ฅธ ํฌํ•จ ๋ฐ ์ •์˜๋ฅผ ๊ณต์œ ํ•˜๋Š” ๋‹ค๋ฅธ ์žฌ๋ฃŒ๋ฅผ ์žฅ๋ฉด์— ์ถ”๊ฐ€ํ•˜๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๊ทธ ์ด์œ ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

https://github.com/mrdoob/three.js/blob/35a26f178c523514673d992da1aece23c1cfca6e/src/renderers/webgl/WebGLPrograms.js#L244

๋‘ ์žฌ๋ฃŒ์— ์ผ๋ถ€ ๋…ผ๋ฆฌ๊ฐ€ ์ œ๊ณต๋˜๋Š” ๋™์ผํ•œ ๊ธฐ๋Šฅ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋…ผ๋ฆฌ์— ๋Œ€ํ•œ ๋ณ€์ˆ˜๋Š” ์ฝœ๋ฐฑ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋‘ ์žฌ๋ฃŒ ๋ชจ๋‘ ๋™์ผํ•œ ํ•ด์‹œ๋ฅผ ์–ป์Šต๋‹ˆ๊นŒ?

array.push( material.onBeforeCompile( obtainShaderSomehow ) )

https://github.com/mrdoob/three.js/pull/10791์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค.

https://github.com/pailhead/three.js/blob/879d52349bd5ef72c64fc962d8ca26bacaf489bf/src/renderers/webgl/WebGLPrograms.js#L242

global_vertex ๋ฐ global_fragment ์ž๋ฆฌ ํ‘œ์‹œ์ž/ํ›„ํฌ๋ฅผ ์ œ๊ฑฐํ•˜๋ฉด ๋‹ค๋ฅธ pull ์š”์ฒญ์„ ์žฌ๊ณ ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ๊ทธ๊ฒƒ๋“ค์ด ์—†์œผ๋ฉด ๋งŽ์€ ํŒŒ์ผ์— ์˜ํ–ฅ์„ ๋ฏธ์น˜๊ณ  ์ฝ”๋“œ๊ฐ€ ์ ์Šต๋‹ˆ๋‹ค. ์„ธ ์ค„์€ ์•„๋‹ˆ์ง€๋งŒ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ํ•ด์‹œ๋ฉ๋‹ˆ๋‹ค. :)

์ด ๋ฐ”์ด์˜ฌ๋ฆฐ https://codepen.io/anon/pen/KQPBjd ์—์„œ #41 ๋Œ“๊ธ€
์žฅ๋ฉด์— ์žˆ๋Š” ๋‹ค๋ฅธ ๋ฉ”์‹œ์˜ ์žฌ์งˆ์ด ๋ณ€๊ฒฝ๋ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์ด ์ตœ๊ทผ ๋ฆด๋ฆฌ์Šค์— ํฌํ•จ๋˜์—ˆ์Šต๋‹ˆ๊นŒ, ์•„๋‹ˆ๋ฉด ๋ชจ๋‘ ์•„์ง ๊ฐœ๋ฐœ ์ค‘์ž…๋‹ˆ๊นŒ?

@mrdoob .onBeforeCompile() ํ•ดํ‚น๋œ ์ž๋ฃŒ๋ฅผ ์ง๋ ฌํ™”ํ•˜๋Š” ๊ฒƒ์€ ์–ด๋ ต๊ฑฐ๋‚˜ ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ์™„์ „ํ•œ ๊ธฐ๋Šฅ(๋ Œ๋”๋ง, ๋ณต์‚ฌ, ๋ณต์ œ, ์ง๋ ฌํ™” ๋“ฑ)์œผ๋กœ ์ˆ˜์ •๋œ ๋‚ด์žฅ ์žฌ๋ฃŒ๋ฅผ ์›ํ•  ๊ฒฝ์šฐ ShaderMaterial ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์‹ญ๋‹ˆ๊นŒ?

_๊ฐ€๋Šฅํ•œ ๊ฐ€์žฅ ๋ฉ‹์ง€๊ณ  ๊ฑด์„ค์ ์ด๋ฉฐ ๋Œ€๋ฆฝ์ ์ด์ง€ ์•Š์€ ๋ฐฉ์‹์œผ๋กœ ๋‹ค์Œ์„ ์ฝ์œผ์‹ญ์‹œ์˜ค_ :)

@takahirox ์™œ ๊ณ„์† ์ฒญ๊ตฌ๋˜๋Š” ๊ฑด๊ฐ€์š”?

ํ•ดํ‚น๋œ ์ž๋ฃŒ๋ฅผ ์ง๋ ฌํ™”ํ•˜๋Š” ๊ฒƒ์ด ์–ด๋ ต๊ฑฐ๋‚˜ ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋‹น์‹ ์ด ์žฌ๋ฃŒ "ํ•ดํ‚น"ํ•˜๋ฉด onBeforeCompile ๋‹น์‹ ์€ ๋‹ค๋ฅธ ๋ฌผ์งˆ๊ณผ ๋™์ผํ•œ ์œ ๋‹ˆํผ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์ ์ด ์—†๋‹ค. material.color ์ง๋ ฌํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ์™œ material.userData.myColor ๋ฅผ ์ง๋ ฌํ™”ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๊นŒ?

๋‚˜๋Š” ์‹ธ์›€์„ ์‹œ์ž‘ํ•˜๋ ค๊ณ  ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค, ํ…์ŠคํŠธ์˜ ๋ฒฝ ๋˜๋Š” ๋ฌด์—‡์ด๋“ . ๊ฐ€์žฅ ๊ฐ„๋‹จํ•˜๊ณ  ์งง์€ ์šฉ์–ด๋กœ ์„ค๋ช…ํ•˜๊ฑฐ๋‚˜ ์ ์–ด๋„ ๊ทธ๊ฒƒ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๊ฑฐ๋‚˜ ์–ด๋ ค์šด ์ด์œ ์— ๋Œ€ํ•ด ์˜ฌ๋ฐ”๋ฅธ ๋ฐฉํ–ฅ์„ ์•Œ๋ ค ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ๋‚˜๋Š” ๋ช…๋ฐฑํ•œ ๊ฒƒ์„ ๋†“์น˜๊ณ  ์žˆ๋‹ค๋Š” ๊ฐ€๋Šฅ์„ฑ์— ์—ด๋ ค ์žˆ์ง€๋งŒ, ๋งŒ์•ฝ ๊ทธ๋ ‡๋‹ค๋ฉด ๊ทธ๊ฒƒ์ด ๋ฌด์—‡์ธ์ง€ ์ดํ•ดํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค :)

Articles ์— ์˜ํ•ด ์ƒ์„ฑ๋œ ์•„์ฃผ ์ž‘์€ ์ƒ˜ํ”Œ์—์„œ ์ด ์‹คํ—˜ ์€ ์‚ฌ๋žŒ๋“ค์ด 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์ด ์žˆ๋Š” ์ผ๋ฐ˜ MeshStandardMaterial์—์„œ toJSON()์„ ํ˜ธ์ถœํ•˜๋ฉด GLSL์— ๋Œ€ํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์ž๋™์œผ๋กœ ์ง๋ ฌํ™”๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ์‚ฌ์šฉ์ž๊ฐ€ GLSL์— ๋Œ€ํ•œ ๋ณ€๊ฒฝ์„ ๋‚˜ํƒ€๋‚ด๋Š” ๋ช‡ ๊ฐ€์ง€ ์ถ”๊ฐ€ ์†์„ฑ์œผ๋กœ MeshStandardMaterial์„ ์ง๋ ฌํ™”ํ•˜๊ณ  ์ด๋Ÿฌํ•œ ์ถ”๊ฐ€ ์†์„ฑ์œผ๋กœ ๋ฌด์—‡์„ ํ•ด์•ผ ํ•˜๋Š”์ง€ ์•Œ๊ณ  ์žˆ๋Š” ์‚ฌ์šฉ์ž ์ •์˜ ์ฝ”๋“œ๋กœ ๋กœ๋“œํ•˜๋ฉด ํ™•์‹คํžˆ ๋ฌธ์ œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.
  • ๋‹ค์–‘ํ•œ ๋‹ค๋ฅธ ์˜ต์…˜(ShaderMaterial, NodeMaterial, glTF์˜ KHR_techniques_webgl , ...)์€ ์ž„์˜์˜ ์‚ฌ์šฉ์ž ์ •์˜ ์žฌ๋ฃŒ๋ฅผ ์ง๋ ฌํ™”ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋งŒ์•ฝ ์šฐ๋ฆฌ๊ฐ€ ์ด์•ผ๊ธฐํ•˜๊ณ  ์žˆ๋Š” ์‚ฌ๊ฑด์ด ๊ทธ ์ค‘ ํ•˜๋‚˜๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด, ์ œ๊ฐ€ ์—ฌ๊ธฐ์„œ ์˜คํ•ดํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด #14099์— ๊ด€ํ•œ ๊ฒƒ์ด๋ผ๋ฉด ๋‚˜๋Š” (์—ฌ์ „ํžˆ) ๊ทธ๊ฒƒ์„ ๋ณ‘ํ•ฉํ•˜๋Š” ๋ฐ ์ฐฌ์„ฑํ•ฉ๋‹ˆ๋‹ค.

ํ , ๋‚˜๋Š” ์ฒ˜์Œ ๋‘ ๊ฐ€์ง€๋ฅผ ์‹ค์ œ๋กœ ๊ตฌ๋ณ„ํ•˜์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. ์œ ๋‹ˆํผ์ด ํ•„์š”ํ•˜์ง€ ์•Š์€ ๊ฒƒ์„ ์ƒ๊ฐํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด gl_FragColor.xyz /= gl_FragColor.a; ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‚˜๋Š” ์ด์™€ ๊ฐ™์€ ๊ฒƒ์„ ์ง๋ ฌํ™”ํ•˜๋ ค๋Š” ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ์ƒ์ƒํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค( ์ž๋ฃŒ์™€ ํ•จ๊ป˜? ). ๋จธํ‹ฐ๋ฆฌ์–ผ ๋ฐ์ดํ„ฐ๊ฐ€ ์•„๋‹Œ ์–ด๋–ค ์ดํŽ™ํŠธ ๋ Œ๋”๋Ÿฌ์˜ ๋ฒ”์œ„์— ๋“ค์–ด๊ฐˆ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

materials = loadSerializedMaterials()

effect = new Effect()

effect.load( 'alphaDivide').then(()=>materials.forEach(mat.onBeforeCompile = effect.getOnBeforeCompile('alphaDivide')))

๋‘ ๋ฒˆ์งธ ์˜ˆ๋Š” ๋‚ด๊ฐ€ ํ•ญ์ƒ ์—ผ๋‘์— ๋‘์—ˆ๋˜ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‹ค์–‘ํ•œ ์ž…๋ ฅ๊ณผ ํ•จ๊ป˜ userData.extension === 'hamburger' ๋Œ€ํ•œ ํžŒํŠธ๋ฅผ ์ง๋ ฌํ™”ํ•˜์‹ญ์‹œ์˜ค.

์ œ๊ฐ€ ๊ธ€์„ ์ž˜ ๋ชป์ผ๋‚˜ ๋ด…๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ์–ธ๊ธ‰ํ•˜๊ณ  ์‹ถ์—ˆ๋˜ ๊ฒƒ์€

  • .onBeforeCompile() ๋กœ ํ•ดํ‚น๋œ ๋นŒํŠธ์ธ ๋จธํ‹ฐ๋ฆฌ์–ผ์€ ๋นŒํŠธ์ธ ๋จธํ‹ฐ๋ฆฌ์–ผ๊ณผ ๋™์ผํ•œ API์—์„œ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋ณต์‚ฌ, ๋ณต์ œ, ์ง๋ ฌํ™”๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค'. ํ•ดํ‚น๋˜์ง€ ์•Š์€ ์ž๋ฃŒ๋กœ ์ทจ๊ธ‰๋ฉ๋‹ˆ๋‹ค.
  • ์‚ฌ์šฉ์ž๊ฐ€ ์˜ฌ๋ฐ”๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ์›ํ•˜๋ฉด ์‚ฌ์šฉ์ž ์ธก์—์„œ ์•ฝ๊ฐ„์˜ ์ถ”๊ฐ€ ์ž‘์—…์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
  • ์‚ฌ์šฉ์ž๊ฐ€ ์‚ฌ์šฉ์ž ์ธก ์ถ”๊ฐ€ ์ž‘์—… ์—†์ด Three.js ํ•ต์‹ฌ API๊ฐ€ ํฌํ•จ๋œ ํ•ดํ‚น๋œ ๋‚ด์žฅ ์ž๋ฃŒ๋ฅผ ์›ํ•˜๋Š” ๊ฒฝ์šฐ ShaderMaterial ์™€ ๊ฐ™์€ ๋‹ค๋ฅธ ์˜ต์…˜์„ ๊ณ ๋ คํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋‚ด ์งˆ๋ฌธ์€ ํŠน์ • ์‚ฌ๋ก€๊ฐ€ ์•„๋‹ˆ๋ผ .onBeforeCompile() ์ •์ฑ…์— ๋Œ€ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ œํ•œ ์‚ฌํ•ญ์„ ๋ช…ํ™•ํžˆ ํ•˜๊ณ  ๋ฌธ์„œ์— ๋ฉ”๋ชจ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค.

three.js์™€ ์ „์ฒด โ€‹โ€‹๋ Œ๋”๋ง ์‹œ์Šคํ…œ์„ ์žŠ์–ด๋ฒ„๋ฆฌ๋ฉด ์š”์ ์„ ์•Œ ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ผ๋ฐ˜ ๊ฐœ์ฒด๋กœ์„œ .clone() ์žˆ์œผ๋ฉด ๋ณต์ œํ•  ์ˆ˜ ์žˆ๊ณ  ์ผ๊ด€๋œ ๊ธฐ๋Œ€์น˜๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ๋Š” ๋‘ ์†”๋ฃจ์…˜(๋ณต์ œํ•˜์ง€ ์•Š๊ณ  ๋ณต์ œ)์— ์œ ํšจํ•œ ์ธ์ˆ˜๊ฐ€ ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋ฆฌ์Šค๋„ˆ๋ฅผ ๋ณต์ œํ•˜์ง€ ์•Š์ง€๋งŒ ๋“œ๋กœ์ž‰์— ์˜ํ–ฅ์„ ์ฃผ๋Š” ๋ฌด์–ธ๊ฐ€๊ฐ€ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๊ธฐ๋ฅผ ์–ด๋Š ์ •๋„ ๊ธฐ๋Œ€ํ•ฉ๋‹ˆ๋‹ค.

๋‹ค๋ฅธ ์˜์—ญ์—์„œ ๋™์ผํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์œ„์—์„œ ์ œ์•ˆํ•œ ์ œ์•ˆ์ด ์œ ํšจํ•œ ๋ฐฉ๋ฒ•์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค(์˜ˆ: ๋Œ€์ƒ ๊ฐ„์— ๊นŠ์ด ๋ฒ„ํผ๋ฅผ ๊ณต์œ ํ•˜๋Š” ๊ฒƒ๋„ ownThing || outsideThing ๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Œ).

์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ํ•จ์ˆ˜๋ฅผ ์บ์‹ฑํ•˜๋Š” ๋Œ€์‹  ๊ธฐ๋ณธ์ ์œผ๋กœ userData ๋ฅผ ์บ์‹ฑํ•˜์ง€๋งŒ ๊ทธ ์ผ๋ถ€๋ฅผ ์บ์‹ฑํ•ฉ๋‹ˆ๋‹ค. userData.hamburger: 'rare' ๋ฅผ ์บ์‹œํ•˜๋Š” ๊ฒƒ์€ ์˜๋ฏธ๊ฐ€ ์—†์ง€๋งŒ userData.effectOn: true". The ์บ์‹œํ•ฉ๋‹ˆ๋‹ค. ownInput | ์†Œ์œ  ์ฒญํฌ | ownWhatever`๊ฐ€ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋˜ํ•œ ๋‹ค์Œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค.

onBeforeCompile ๋ฉ”์„œ๋“œ๋Š” ๋งค์šฐ ์ž„์˜์˜ ์ฝ”๋“œ๋ฅผ ํฌํ•จํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ํ•ด๋‹น ์ฝœ๋ฐฑ์„ ๊ฐ•๋ ฅํ•˜๊ฒŒ ์ง๋ ฌํ™”ํ•˜๋Š” ๊ฒƒ์€ ํ™•์‹คํžˆ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

์˜ค๋žœ ์‹œ๊ฐ„ ๋™์•ˆ ์‚ฌ๋žŒ๋“ค์€ onBeforeCompile ๋ฅผ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ ๊ฑฐ๊ธฐ์—์„œ ์–ด๋–ค ์ข…๋ฅ˜์˜ ์ž„์˜ ์ฝ”๋“œ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ „๋‹ฌ๋œ shader ๊ฐœ์ฒด์—์„œ๋งŒ ์ž‘๋™ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ํ•ด๋‹น ๊ฐœ์ฒด๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€๋งŒ ShaderMaterial ์˜๋ฏธ๊ฐ€ ์žˆ๋Š” ๋Œ์—ฐ๋ณ€์ด๋งŒ ์–ด์จŒ๋“  ์˜ํ–ฅ์„ ๋ฏธ์นฉ๋‹ˆ๋‹ค. gl ์ง์ ‘ ์„ค์ •ํ•˜๋Š” ๊ฒƒ์€ ์•„๋งˆ๋„ ๋ฌด์‹œ๋  ๊ฒƒ์ด๋ฉฐ, ๊ทธ๊ฒƒ์ด ๋‚ด ๋งˆ์Œ์— ๋– ์˜ค๋ฅด๋Š” ์œ ์ผํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ทธ๊ฒƒ์€ ๋ณธ์งˆ์ ์œผ๋กœ์˜ pre three parse ๋Š” ํ•„์ˆ˜์™€ ํ•จ๊ป˜ ์‰์ด๋” ์ž์‹ ์„ ๊ตฌ๋ฌธ ๋ถ„์„ ํ•  ์ˆ˜์žˆ๋Š” ๊ธฐํšŒ๋ฅผ ์–ป๋Š” ๋‹จ๊ณ„, uniforms:{} ๋‹น์‹ ์ด ๊ทธ๊ฒƒ์„ ๊ฐ€๋Šฅํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—, ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ Material ( defines:{} ๋‹ค๋ฅธ ํ•œํŽธ์œผ๋กœ๋Š” ShaderMaterial ํ˜•์ œ์ž๋งค์ž…๋‹ˆ๋‹ค.

์–ด๋–ป๊ฒŒ ํ•˜๋Š”์ง€, ์ฆ‰ ์ž„์˜์˜ ์ฝ”๋“œ๊ฐ€ ๋ฌด์—‡์ด๋“  ์ƒ๊ด€์—†์Šต๋‹ˆ๋‹ค. ์•„๋ฌด ๊ฒƒ๋„ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š์ง€๋งŒ shader:{} ํ•˜๊ณ  ๋ Œ๋”๋Ÿฌ๊ฐ€ ์ด๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ์ œ์•ˆํ•˜๋Š” ์ ‘๊ทผ ๋ฐฉ์‹:

  1. ๋‹ค์–‘ํ•œ ํด๋ž˜์Šค์— 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)
  1. 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 : ๋ฌผ๊ฑด์˜ ๋ฐ•์‚ฌ๋Š” ์œ„์˜ "์ปดํŒŒ์ผ"(๊ตฌ๋ฌธ ๋ถ„์„)์ด ๋ฐœ์ƒํ•˜๋ฉด ์‹œ๊ฐ„์— ํŠน์ • ์ง€์ ์— ๋Œ€ํ•ด ์‹ ๊ฒฝ ์“ฐ์ง€ ์•Š๋Š” ์‚ฌ์šฉ์ž์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๋“ค์ด ๋ฌด์Šจ ์ผ์ด ์ผ์–ด๋‚˜๋Š”์ง€์— ๋Œ€ํ•ด ๋” ์‹ ๊ฒฝ์„ ์“ด๋‹ค๊ณ  ์ƒ๊ฐํ•˜๊ณ , ์ผ์–ด๋‚˜๋Š” ์ผ์€ in: shaderString, out: shaderString ๋‹จ์ผ ์‚ฌ์šฉ ์‚ฌ๋ก€๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด ์†Œ์ˆ˜๋กœ ๋ถ„๋ฆฌ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํŒŒ์ดํ”„๋ผ์ธ์˜ ํŠน์ • ์ง€์ ์—์„œ ์ˆ˜ํ–‰๋˜์–ด์•ผ ํ•˜๋Š” ์ด์œ ๋Š” ์กฐ์‚ฌํ•˜๊ณ  ์ดํ•ดํ•  ๊ฐ€์น˜๊ฐ€ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋„์›€์„ ์ฃผ๊ธฐ๋ณด๋‹ค๋Š” ์˜คํžˆ๋ ค ๋ฐฉํ•ด๊ฐ€ ๋˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

@mrdoob .onBeforeCompile() ํ•ดํ‚น๋œ ์ž๋ฃŒ๋ฅผ ์ง๋ ฌํ™”ํ•˜๋Š” ๊ฒƒ์€ ์–ด๋ ต๊ฑฐ๋‚˜ ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ์™„์ „ํ•œ ๊ธฐ๋Šฅ(๋ Œ๋”๋ง, ๋ณต์‚ฌ, ๋ณต์ œ, ์ง๋ ฌํ™” ๋“ฑ)์œผ๋กœ ์ˆ˜์ •๋œ ๋‚ด์žฅ ์žฌ๋ฃŒ๋ฅผ ์›ํ•  ๊ฒฝ์šฐ ShaderMaterial ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์‹ญ๋‹ˆ๊นŒ?

๋‚˜๋Š” onBeforeCompile() ์ด ์ง๋ ฌํ™”๋  ๊ฒƒ์ด๋ผ๊ณ  (๊ณ ๋ คํ•˜์ง€ ์•Š์•˜๋‹ค)...

๋ฐฉ๊ธˆ onBeforeCompile์„ ์‚ฌ์šฉํ•˜์—ฌ ์‹ฌํ•˜๊ฒŒ ๋ฌผ๋ ธ์Šต๋‹ˆ๋‹ค. ์ •์˜๋œ ๋ฐฉ์‹์œผ๋กœ ๋‚ด์žฅ ์…ฐ์ด๋”๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋Š” ์…ฐ์ด๋” ๋„์šฐ๋ฏธ ํด๋ž˜์Šค๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด onBeforeCompile ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋ถ„๋ช…ํžˆ ์ฒซ ๋ฒˆ์งธ ์ฃผ์„์—์„œ ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด WebGLProgram์€ onBeforeCompile.toString()์„ ํ•ด์‹œ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‚ด ํ•จ์ˆ˜๋Š” ์ผ๋ฐ˜์ ์ด๊ธฐ ๋•Œ๋ฌธ์—(๊ผญ์ง“์  ๋ฐ ์กฐ๊ฐ ์…ฐ์ด๋”์˜ ์ผ๋ถ€๋ฅผ ๋ณ€์ˆ˜๋กœ ๋Œ€์ฒดํ•จ) onBeforeCompile.toString()์€ ๋‹ค๋ฅธ ์…ฐ์ด๋”์— ๋Œ€ํ•ด ๋‹ค๋ฅด๊ฒŒ ๋ณด์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋ชจ๋“  ๋‹ค๋ฅธ ์…ฐ์ด๋”๊ฐ€ ๋™์ผํ•œ ํ”„๋กœ๊ทธ๋žจ์œผ๋กœ ์บ์‹œ๋˜์—ˆ์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ํ‰๊ฐ€ ํ˜ธ์ถœ๊ณผ uuid ๋ฐ ์ด์ œ ๋‚ด ๊ธฐ๋Šฅ์ด ๋ชจ๋‘ ๋‹ค๋ฅด๊ฒŒ ๋ณด์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์„ ์•Œ์•„๋‚ด๋Š” ๋ฐ ์˜์›ํžˆ ๊ฑธ๋ ธ์Šต๋‹ˆ๋‹ค.

@donaldr https://github.com/mrdoob/three.js/issues/13192๋ฅผ ์ฐธ์กฐ

ํ‰๊ฐ€ํŒ์„ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š”์ง€ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ๋‚˜๋Š” ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ์ƒ๊ฐํ–ˆ์ง€๋งŒ ๋„ˆ๋ฌด ๋”๋Ÿฌ์šด ๊ฒƒ ๊ฐ™์•˜์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ const fdscxnmdrek435rkjl ๋ฅผ ๋ณธ๋ฌธ ๋งจ ์œ„์— ์ถ”๊ฐ€ํ•œ ๋‹ค์Œ ํ‰๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

์ด๊ฒƒ์€ ๋ชจ๋“  ๋‹ค๋ฅธ ์…ฐ์ด๋”๊ฐ€ ๋™์ผํ•œ ํ”„๋กœ๊ทธ๋žจ์œผ๋กœ ์บ์‹œ๋˜์—ˆ์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ํ‰๊ฐ€ ํ˜ธ์ถœ๊ณผ 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() ์ปจํ…์ŠคํŠธ์—์„œ ๋‹ค๋ฅธ ๊ธฐ์กด ๋ฌธ์ œ ๋˜๋Š” ๊ฐœ์„  ์‚ฌํ•ญ์— ๋Œ€ํ•ด ๋…ผ์˜ํ•˜์‹ญ์‹œ์˜ค.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰