shaderMaterial 재질

오늘 우리 가 소개 할 고급 소 재 는 THREE. Shader Material 입 니 다.그것 은 three. js 라 이브 러 리 에서 기능 이 가장 풍부 하고 가장 복잡 한 고급 소재 입 니 다.이 를 통 해 자신의 착색 기 를 정의 하고 WebGL 환경 에서 직접 실행 할 수 있 습 니 다.착색 기 는 three. js 의 자 바스 크 립 트 대상 을 화면의 픽 셀 로 변환 할 수 있 습 니 다.사용자 정의 착색 기 를 통 해 대상 이 어떻게 렌 더 링 하고 가 리 는 지, three. js 라 이브 러 리 의 기본 값 을 수정 하 는 지 명확 하 게 지정 할 수 있 습 니 다.
    그러나 우리 편 은 착색 기 를 어떻게 맞 추 는 지 에 대한 세부 사항 을 언급 하지 않 을 것 이다. 이것 은 이미 다른 전문 적 인 기술 체계 인 'GLSL 착색 기 언어' 에 속 하기 때문에 관심 이 있 는 친구 들 은 이 분야 의 책 을 한 권 사서 자세히 연구 할 수 있다.다음은 Shader Material 가 설정 할 수 있 는 몇 가지 상용 속성 을 살 펴 보 겠 습 니 다. 대부분 다른 기초 소재 와 유사 합 니 다. wireframe, wireframe Linewidth, flatShading, fog, vertexColors 등 이 있 습 니 다.
    특히 vertexcolors 속성 을 들 어 보 세 요. 우 리 는 그것 을 통 해 모든 정점 에 다른 색 을 정의 할 수 있 습 니 다.그것 은 CanvasRenderer 에서 작용 하지 않 고 WebGLRenderer 에서 만 작용 한다.이 속성 에 대해 서 는 뒤에 언급 된 Line Basic Material 에 관 한 예 를 참고 할 수 있 습 니 다.
    위 에서 언급 한 이러한 속성 을 제외 하고 Shader Material 은 몇 가지 특별한 속성 이 있 습 니 다. 이 속성 을 사용 하면 데 이 터 를 전송 하고 착색 기 를 맞 출 수 있 습 니 다.그러나 이들 은 이해 하기 어 려 울 것 같 아서 'GLSL 착색 기 언어' 에 관 한 지식 을 결합 시 켜 야 한다. 다음 표 와 같다.
속성
묘사 하 다.
fragmentShader (픽 셀 착색 기)
이 착색 기 는 들 어 오 는 픽 셀 마다 색상 을 정의 합 니 다.
vertexShader (정점 착색 기)
이 착색 기 는 들 어 오 는 정점 의 위 치 를 수정 할 수 있 습 니 다.
uniforms (통일 값)
이 속성 을 통 해 착색 기 에 메 시 지 를 보 낼 수 있 습 니 다.같은 메 시 지 는 모든 정점 과 세 션 에 보 냅 니 다.
defines
이 속성의 값 은 vertexShader 와 fragment Shader 의 \ # define 코드 로 바 꿀 수 있 습 니 다.이 속성 은 착색 기 프로그램의 전역 변 수 를 설정 하 는 데 사용 할 수 있 습 니 다.
attributes
이 속성 은 모든 정점 과 세 션 을 수정 할 수 있 습 니 다.일반적으로 위치 데이터 와 법 적 벡터 와 관련 된 데 이 터 를 전달 하 는 데 쓰 인 다.이 속성 을 사용 하려 면 기하도형 의 모든 정점 에 정 보 를 제공 해 야 합 니 다.
lights
이 속성 은 빛 데이터 가 착색 기 에 전 달 될 지 여 부 를 정의 합 니 다.기본 값 은 false 입 니 다.
    그 중에서 가장 중요 한 부분 은 Shader Material 소 재 를 사용 하려 면 두 개의 다른 착색 기 를 입력 해 야 한 다 는 것 이다.
  • vertex Shader: 기하도형 의 모든 정점 에서 실 행 됩 니 다.이 착색 기 를 이용 하여 정점 의 위 치 를 바 꾸 어 기 하 체 를 변환 할 수 있다.
  • fragment Shader: 기하도형 의 모든 픽 셀 에서 실 행 됩 니 다.vertex Shader 에서 우 리 는 이 특정한 픽 셀 이 표시 해 야 할 색 을 되 돌려 줍 니 다.

  •     지금까지 우리 가 토론 한 모든 소 재 는 three. js 라 이브 러 리 에서 해당 하 는 vertexShader 와 fragment Shader 를 제공 할 것 이 며, 우리 스스로 정의 할 필요 가 없다.
        다음 에 우리 가 제시 하고 자 하 는 이 예 는 동적 소 재 를 만 들 것 입 니 다. 그 중에서 비교적 간단 한 vertex Shader 를 사용 하여 사각형 각 정점 의 x, y, z 좌 표를 수정 할 것 입 니 다.또 다른 fragment Shader 를 사용 합 니 다. http://glslsandbox.com/ 연속 적 으로 변화 하 는 소 재 를 만 들 기 위해 착색 기 를 많이 제공 합 니 다.전체 코드 는 다음 과 같 습 니 다:
    
    
    
           04.08 - ShaderMaterial
    	
    	
    	
    	
    	
        
    
    
    
    
    
    uniform float time; varying vec2 vUv; void main() { vec3 posChanged = position; posChanged.x = posChanged.x*(abs(sin(time*1.0))); posChanged.y = posChanged.y*(abs(cos(time*1.0))); posChanged.z = posChanged.z*(abs(sin(time*1.0))); gl_Position = projectionMatrix * modelViewMatrix * vec4(position*(abs(sin(time)/2.0)+0.5),1.0); //gl_Position = projectionMatrix * modelViewMatrix * vec4(posChanged,1.0); } precision highp float; uniform float time; uniform float alpha; uniform vec2 resolution; varying vec2 vUv; void main2(void) { vec2 position = vUv; float red = 1.0; float green = 0.25 + sin(time) * 0.25; float blue = 0.0; vec3 rgb = vec3(red, green, blue); vec4 color = vec4(rgb, alpha); gl_FragColor = color; } #define PI 3.14159 #define TWO_PI (PI*2.0) #define N 68.5 void main(void) { vec2 center = (gl_FragCoord.xy); center.x=-10.12*sin(time/200.0); center.y=-10.12*cos(time/200.0); vec2 v = (gl_FragCoord.xy - resolution/20.0) / min(resolution.y,resolution.x) * 15.0; v.x=v.x-10.0; v.y=v.y-200.0; float col = 0.0; for(float i = 0.0; i < N; i++) { float a = i * (TWO_PI/N) * 61.95; col += cos(TWO_PI*(v.y * cos(a) + v.x * sin(a) + sin(time*0.004)*100.0 )); } col /= 5.0; gl_FragColor = vec4(col*1.0, -col*1.0,-col*4.0, 1.0); } // from http://glsl.heroku.com/e#7906.0 uniform float time; uniform vec2 resolution; // 2013-03-30 by @hintz #define CGFloat float #define M_PI 3.14159265359 vec3 hsvtorgb(float h, float s, float v) { float c = v * s; h = mod((h * 6.0), 6.0); float x = c * (1.0 - abs(mod(h, 2.0) - 1.0)); vec3 color; if (0.0 <= h && h < 1.0) { color = vec3(c, x, 0.0); } else if (1.0 <= h && h < 2.0) { color = vec3(x, c, 0.0); } else if (2.0 <= h && h < 3.0) { color = vec3(0.0, c, x); } else if (3.0 <= h && h < 4.0) { color = vec3(0.0, x, c); } else if (4.0 <= h && h < 5.0) { color = vec3(x, 0.0, c); } else if (5.0 <= h && h < 6.0) { color = vec3(c, 0.0, x); } else { color = vec3(0.0); } color += v - c; return color; } void main(void) { vec2 position = (gl_FragCoord.xy - 0.5 * resolution) / resolution.y; float x = position.x; float y = position.y; CGFloat a = atan(x, y); CGFloat d = sqrt(x*x+y*y); CGFloat d0 = 0.5*(sin(d-time)+1.5)*d; CGFloat d1 = 5.0; CGFloat u = mod(a*d1+sin(d*10.0+time), M_PI*2.0)/M_PI*0.5 - 0.5; CGFloat v = mod(pow(d0*4.0, 0.75),1.0) - 0.5; CGFloat dd = sqrt(u*u+v*v); CGFloat aa = atan(u, v); CGFloat uu = mod(aa*3.0+3.0*cos(dd*30.0-time), M_PI*2.0)/M_PI*0.5 - 0.5; // CGFloat vv = mod(dd*4.0,1.0) - 0.5; CGFloat d2 = sqrt(uu*uu+v*v)*1.5; gl_FragColor = vec4( hsvtorgb(dd+time*0.5/d1, sin(dd*time), d2), 1.0 ); } uniform vec2 resolution; uniform float time; vec2 rand(vec2 pos) { return fract( 0.00005 * (pow(pos+2.0, pos.yx + 1.0) * 22222.0)); } vec2 rand2(vec2 pos) { return rand(rand(pos)); } float softnoise(vec2 pos, float scale) { vec2 smplpos = pos * scale; float c0 = rand2((floor(smplpos) + vec2(0.0, 0.0)) / scale).x; float c1 = rand2((floor(smplpos) + vec2(1.0, 0.0)) / scale).x; float c2 = rand2((floor(smplpos) + vec2(0.0, 1.0)) / scale).x; float c3 = rand2((floor(smplpos) + vec2(1.0, 1.0)) / scale).x; vec2 a = fract(smplpos); return mix( mix(c0, c1, smoothstep(0.0, 1.0, a.x)), mix(c2, c3, smoothstep(0.0, 1.0, a.x)), smoothstep(0.0, 1.0, a.y)); } void main(void) { vec2 pos = gl_FragCoord.xy / resolution.y; pos.x += time * 0.1; float color = 0.0; float s = 1.0; for(int i = 0; i < 8; i++) { color += softnoise(pos+vec2(i)*0.02, s * 4.0) / s / 2.0; s *= 2.0; } gl_FragColor = vec4(color); } uniform float time; uniform vec2 resolution; vec2 rand(vec2 pos) { return fract( pow( pos+2.0, pos.yx+2.0 ) * 555555.0 ); } vec2 rand2(vec2 pos) { return rand(rand(pos)); } float softnoise(vec2 pos, float scale) { vec2 smplpos = pos * scale; float c0 = rand2((floor(smplpos) + vec2(0.0, 0.0)) / scale).x; float c1 = rand2((floor(smplpos) + vec2(1.0, 0.0)) / scale).x; float c2 = rand2((floor(smplpos) + vec2(0.0, 1.0)) / scale).x; float c3 = rand2((floor(smplpos) + vec2(1.0, 1.0)) / scale).x; vec2 a = fract(smplpos); return mix(mix(c0, c1, smoothstep(0.0, 1.0, a.x)), mix(c2, c3, smoothstep(0.0, 1.0, a.x)), smoothstep(0.0, 1.0, a.x)); } void main( void ) { vec2 pos = gl_FragCoord.xy / resolution.y - time * 0.4; float color = 0.0; float s = 1.0; for (int i = 0; i < 6; ++i) { color += softnoise(pos + vec2(0.01 * float(i)), s * 4.0) / s / 2.0; s *= 2.0; } gl_FragColor = vec4(color,mix(color,cos(color),sin(color)),color,1); } uniform float time; uniform vec2 resolution; // tie nd die by Snoep Games. void main( void ) { vec3 color = vec3(1.0, 0., 0.); vec2 pos = (( 1.4 * gl_FragCoord.xy - resolution.xy) / resolution.xx)*1.5; float r=sqrt(pos.x*pos.x+pos.y*pos.y)/15.0; float size1=2.0*cos(time/60.0); float size2=2.5*sin(time/12.1); float rot1=13.00; //82.0+16.0*sin(time/4.0); float rot2=-50.00; //82.0+16.0*sin(time/8.0); float t=sin(time); float a = (60.0)*sin(rot1*atan(pos.x-size1*pos.y/r,pos.y+size1*pos.x/r)+time); //a += 200.0*acos(pos.x*2.0+cos(time/2.0))+asin(pos.y*5.0+sin(time/2.0)); a=a*(r/50.0); a=200.0*sin(a*5.0)*(r/30.0); if(a>5.0) a=a/200.0; if(a<0.5) a=a*22.5; gl_FragColor = vec4( cos(a/20.0),a*cos(a/200.0),sin(a/8.0), 1.0 ); } uniform float time; uniform vec2 resolution; void main( void ) { vec2 uPos = ( gl_FragCoord.xy / resolution.xy );//normalize wrt y axis //suPos -= vec2((resolution.x/resolution.y)/2.0, 0.0);//shift origin to center uPos.x -= 1.0; uPos.y -= 0.5; vec3 color = vec3(0.0); float vertColor = 2.0; for( float i = 0.0; i < 15.0; ++i ) { float t = time * (0.9); uPos.y += sin( uPos.x*i + t+i/2.0 ) * 0.1; float fTemp = abs(1.0 / uPos.y / 100.0); vertColor += fTemp; color += vec3( fTemp*(10.0-i)/10.0, fTemp*i/10.0, pow(fTemp,1.5)*1.5 ); } vec4 color_final = vec4(color, 1.0); gl_FragColor = color_final; } var scene; var camera; var render; var webglRender; var canvasRender; var controls; var stats; var guiParams; var ground; var cube; var meshMaterial; var ambientLight; $(function() { stats = initStats(); scene = new THREE.Scene(); webglRender = new THREE.WebGLRenderer( {antialias: true, alpha: true} ); // antialias webglRender.setSize(window.innerWidth, window.innerHeight); webglRender.setClearColor(0x000000, 1.0); webglRender.shadowMap.enabled = true; // render = webglRender; camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 10000); // 2147483647 camera.position.set(30, 30, 30); var target = new THREE.Vector3(0, 0 , 0); controls = new THREE.OrbitControls(camera, render.domElement); controls.target = target; camera.lookAt(target); $('#webgl-output')[0].appendChild(render.domElement); window.addEventListener('resize', onWindowResize, false); ambientLight = new THREE.AmbientLight(0x0c0c0c); scene.add(ambientLight); // var cubeGeometry = new THREE.BoxGeometry(20, 20, 20); // meshMaterial = [ createMaterial('#vertex-shader', '#fragment-shader-1') // ,createMaterial('#vertex-shader', '#fragment-shader-2') // ,createMaterial('#vertex-shader', '#fragment-shader-3') // ,createMaterial('#vertex-shader', '#fragment-shader-4') // ,createMaterial('#vertex-shader', '#fragment-shader-5') // ,createMaterial('#vertex-shader', '#fragment-shader-6') // ] // cube = new THREE.Mesh(cubeGeometry, meshMaterial); scene.add(cube); /** */ guiParams = new function() { this.rotationSpeed = 0.02; this.vertexControl = false; } /** dat.GUI , guiParams */ var gui = new dat.GUI(); gui.add(guiParams, 'vertexControl'); renderScene(); }); /** */ function renderScene() { stats.update(); rotateMesh(); // changeVertex(); requestAnimationFrame(renderScene); render.render(scene, camera); } /** stats */ function initStats() { stats = new Stats(); stats.setMode(0); // 0 FPS;1 $('#stats-output').append(stats.domElement); return stats; } /** */ function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); render.setSize(window.innerWidth, window.innerHeight); } /** */ function rotateMesh() { scene.traverse(function(mesh) { if (mesh instanceof THREE.Mesh && mesh != ground) { mesh.rotation.x += guiParams.rotationSpeed; mesh.rotation.y += guiParams.rotationSpeed; mesh.rotation.z += guiParams.rotationSpeed; } }); } /** */ function changeVertex() { if (!guiParams.vertexControl) return; cube.material.forEach(function (e) { e.uniforms.time.value += 0.01; }); } /** ShaderMaterial */ function createMaterial(vertexShader, fragmentShader) { var vertShader = $(vertexShader).text(); var fragShader = $(fragmentShader).text(); var uniforms = { time: {type: 'f', value: 0.2}, scale: {type: 'f', value: 0.2}, alpha: {type: 'f', value: 0.6}, resolution: {type: 'v2', value: new THREE.Vector2()} }; uniforms.resolution.value.x = window.innerWidth; uniforms.resolution.value.y = window.innerHeight; var shaderMaterial = new THREE.ShaderMaterial({ uniforms: uniforms, vertexShader: vertShader, fragmentShader: fragShader, transparent: true }); return shaderMaterial; }

        그 중에서 id = "vertex - shader" 의 부분 은 vertex Shader 착색 기 스 크 립 트 로 C 와 같은 GLSL 언어 로 만 쓸 수 있 습 니 다.여 기 는 깊이 파고 들 지 않 고 중요 한 부분 에 대해 서 만 약간 설명 한다.자 바스 크 립 트 에서 착색 기와 통신 할 수 있 도록 우 리 는 이른바 통 일 된 값 uniform 을 사용 합 니 다. 예 를 들 어 우리 가 예 에서 사용 한 문장 인 'uniform float time;' 을 외부 데이터 에 전송 합 니 다. 이 데이터 에 따라 우 리 는 정점 에 들 어 오 는 x, y, z 좌표 의 값 (position 변 수 를 통 해 들 어 옵 니 다) 을 바 꿀 것 입 니 다. 코드 세 션 은 다음 과 같 습 니 다.
    vec3 posChanged = position;
    posChanged.x = posChanged.x*(abs(sin(time*1.0)));
    posChanged.y = posChanged.y*(abs(cos(time*1.0)));
    posChanged.z = posChanged.z*(abs(sin(time*1.0)));
    현재 벡터 posChanged 에 포 함 된 것 은 정점 의 새로운 좌표 로 들 어 오 는 time 변 수 를 통 해 계산 할 수 있 습 니 다.마지막 으로, 우 리 는 이 새 좌 표를 three. js 라 이브 러 리 에 전송 합 니 다. 코드 는 다음 과 같 습 니 다.
    gl_Position = projectionMatrix * modelViewMatrix * vec4(position*(abs(sin(time)/2.0)+0.5),1.0);
    gl_Position 은 최종 위 치 를 되 돌려 주 는 특수 한 변수 입 니 다.
        이어서 해 야 할 일 은 Shader Material 대상 을 만 들 고 이 vertex Shader 를 Shader Material 대상 에 게 전달 하 는 것 이다.이 를 위해 저 희 는 간단 한 보조 함수 createMaterial (vertexShader, fragmentShader) 을 만 들 었 습 니 다. 그 중에서 두 개의 매개 변 수 는 HTML 페이지 의 스 크 립 트 요소 ID 를 말 합 니 다.이 함수 에서 우리 가 유 니 버 설 변 수 를 만 든 것 을 볼 수 있 습 니 다. 이것 은 우리 의 렌 더러 에서 착색 기 에 정 보 를 전달 하 는 데 사 용 됩 니 다.렌 더 링 함수 에서 호출 합 니 다. changeVertex () 함수 가 이 목적 에 도달 합 니 다. 이 changeVertex () 함수 에서 매번 순환 할 때마다 time 변수의 값 을 0.01 증가 시 킵 니 다. 그러면 정 보 를 우리 의 vertex Shader 착색 기 에 전달 하여 사각형 의 모든 정점 의 새 위 치 를 계산 할 수 있 습 니 다.
        또한, 이 예 시 를 실행 하면 사각형 의 모든 면 이 끊임없이 변화 하 는 것 을 볼 수 있 습 니 다. 바로 모든 면 의 fragment Shader 세 션 착색 기 가 이러한 변 화 를 만 들 었 습 니 다.fragment Shader 부분 에 대해 서 는 GLSL 착색 기 언어 지식 을 참고 할 수 있 습 니 다. 이것 은 이미 다른 전문 적 인 기술 범주 에 속 하 므 로 독자 가 스스로 발굴 하 시기 바 랍 니 다.
    미 완성 계속 · · ·

    좋은 웹페이지 즐겨찾기