์๋
๋์ ๊ณตํต ๊ธฐ๋ฅ ์์ฒญ์ ๋ด์ฅ ์ฌ๋ฃ๋ฅผ ์์ ํ ์ ์๋ค๋ ๊ฒ์ด์์ต๋๋ค. ์ค๋ ๋๋ ๊ทธ๊ฒ์ด 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๋ฅผ ์ถ๊ฐํ๋ ๊ด๋ จ ์ฌ์ฉ ์ฌ๋ก๊ฐ ์์ต๋๋ค. ๋ฐํ์์ 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๊ฐ ๋ ธ๋ฉ ๋งต๊ณผ ํจ๊ป ์๋ํ๋๋ก ํ๋ ๊ฒ์ ์ข์ํ์ง๋ง ์ด๊ฒ์ผ๋ก ํด๊ฒฐํ๊ธฐ ์ฌ์ด ๊ฒ์ฒ๋ผ ๋ณด์ด๋ ๋ช ๊ฐ์ง ๋ฌธ์ ๋ฅผ ์ฐ๊ฒฐํ์ต๋๋ค.
๋ด ๋ธ๋์น๋ฅผ ๋ณด๊ณ ์ด๊ฒ์ ์คํํ๊ฑฐ๋ ์ด ๋งค์ฐ ๊ฐ๋จํ ์์ ๋ฅผ ํ์ธํ ์ ์์ต๋๋ค(์กฐ๋ช /๊ทธ๋ฆผ์ ๋ฑ์ผ๋ก ์ฌ์ฉ์ ์ ์ ๋ณํ์ ํ ์คํธํ๊ณ ๋ช ๊ฐ์ง ์ ๋ํผ์ ์ถ๊ฐํจ).
์๋ง๋ ๋ ๊ฐ์ง ๋ชจ๋์ ๋ ์ข์ ์๋ฃจ์ ์ ์๋ ๋ฌธ์์ด ์กฐ์ ์์ด ์๊ตฌ์ ์ผ๋ก ๋ฐฉํดํ์ง ์๊ณ ๋ด์ฅ ์ฒญํฌ๋ฅผ ์ฌ์ ์/์ฆ๊ฐํ๋ ์ฌ์ง์ ๋ํ ์ฌ์ฉ์ ์ ์ 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
์ ์ ์
ฐ์ด๋์ ์ฝ๋๋ฅผ ์ฝ์
ํด์ผ ํ๋ ์์น๋ฅผ ๋ณผ ์ ์์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ ๋๋จธ์ง ์๋ฃ๋ ์ฌ๊ธฐ์์:)
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์ ์ด๊ณ ์ ์ ๊ทธ๋๋ก ๋ ๋ค์
์ด์ ์ง์งํ๊ฒ ๋๋ ๊ทธ ์ด๋ฆ์ ์ข์ํ๊ณ ๊ทธ๊ฒ์ผ๋ก ์ฐ๋ฆฌ๊ฐ ๊ฐ ์ค๋น๊ฐ ๋์๋ค๊ณ ์๊ฐํฉ๋๊น, ์๋๋ฉด ๋ด๊ฐ ๋ญ๊ฐ๋ฅผ ๋์น๊ณ ์์ต๋๊น? ๋ด 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
์ด๊ฒ์ ๋ฒ๊ทธ์ธ ๊ฒ ๊ฐ์ต๋๋ค:
์ด๊ฒ์ผ๋ก ์ธํด ๋ฐ์ํ์ง๋ง 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
}
*/
๊ทธ๋ฌ๋ ๋ค๋ฅธ ํฌํจ ๋ฐ ์ ์๋ฅผ ๊ณต์ ํ๋ ๋ค๋ฅธ ์ฌ๋ฃ๋ฅผ ์ฅ๋ฉด์ ์ถ๊ฐํ๋ฉด ์ค๋ฅ๊ฐ ๋ฐ์ํ์ง ์์ต๋๋ค.
๊ทธ ์ด์ ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
๋ ์ฌ๋ฃ์ ์ผ๋ถ ๋ ผ๋ฆฌ๊ฐ ์ ๊ณต๋๋ ๋์ผํ ๊ธฐ๋ฅ์ด ์์ต๋๋ค. ๋ ผ๋ฆฌ์ ๋ํ ๋ณ์๋ ์ฝ๋ฐฑ ๋ฒ์๋ฅผ ๋ฒ์ด๋ฉ๋๋ค. ๋ฐ๋ผ์ ๋ ์ฌ๋ฃ ๋ชจ๋ ๋์ผํ ํด์๋ฅผ ์ป์ต๋๊น?
array.push( material.onBeforeCompile( obtainShaderSomehow ) )
https://github.com/mrdoob/three.js/pull/10791์ ๋ค์๊ณผ ๊ฐ์ด ํด๊ฒฐํ์ต๋๋ค.
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์ ๋ํ ๋ณ๊ฒฝ ์ฌํญ์ด ์๋์ผ๋ก ์ง๋ ฌํ๋์ง ์์ต๋๋ค.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์์ ์ฌ๋ฐ๋ฅด๊ฒ ๋ณต์ฌ, ๋ณต์ , ์ง๋ ฌํ๋์ง ์์ต๋๋ค'. ํดํน๋์ง ์์ ์๋ฃ๋ก ์ทจ๊ธ๋ฉ๋๋ค.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:{}
ํ๊ณ ๋ ๋๋ฌ๊ฐ ์ด๋ฅผ ์ฌ์ฉํฉ๋๋ค.
๋ด๊ฐ ์ ์ํ๋ ์ ๊ทผ ๋ฐฉ์:
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 : ๋ฌผ๊ฑด์ ๋ฐ์ฌ๋ ์์ "์ปดํ์ผ"(๊ตฌ๋ฌธ ๋ถ์)์ด ๋ฐ์ํ๋ฉด ์๊ฐ์ ํน์ ์ง์ ์ ๋ํด ์ ๊ฒฝ ์ฐ์ง ์๋ ์ฌ์ฉ์์
๋๋ค. ๋๋ ๊ทธ๋ค์ด ๋ฌด์จ ์ผ์ด ์ผ์ด๋๋์ง์ ๋ํด ๋ ์ ๊ฒฝ์ ์ด๋ค๊ณ ์๊ฐํ๊ณ , ์ผ์ด๋๋ ์ผ์ 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()
์ปจํ
์คํธ์์ ๋ค๋ฅธ ๊ธฐ์กด ๋ฌธ์ ๋๋ ๊ฐ์ ์ฌํญ์ ๋ํด ๋
ผ์ํ์ญ์์ค.
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
๋๋
onBeforeCompile()
์ด ์ง๋ ฌํ๋ ๊ฒ์ด๋ผ๊ณ (๊ณ ๋ คํ์ง ์์๋ค)...