2013-09-07 2 views
0

WebGL 컨텍스트에서 버텍스 쉐이더를 처음 사용했습니다. 비디오로 프리미티브를 텍스처링하려고하지만 비디오를 표면에 매핑하는 대신 비디오의 루마를 정점 전위로 변환하려고합니다. 이것은 Rutt Etra와 비슷하지만 디지털 형식입니다. 밝은 픽셀은 정점을 앞으로 밀어야하는 반면, 어두운 픽셀은 반전을 수행해야합니다. 아무도 내가 뭘 잘못하고 있다고 말할 수 있습니까? 이 오류에 대한 참조를 찾을 수 없습니다.GLSL 쉐이더를 사용하여 WebRTC 비디오를 지오메트리로 전달

내 코드를 컴파일 할 때, 나는 sampler2D 및 texture2D 사용하는 경우 다음과 같은 얻을 :

모질라/5.0 (매킨토시, 인텔 맥 OS X 10_8_4) AppleWebKit/537.36 (KHTML, 도마뱀 붙이 등) 크롬/29.0.1547.65 사파리 /537.36 | WebGL 1.0 (OpenGL ES 2.0 Chromium) | WebKit | WebKit WebGL | WebGL GLSL ES 1.0 (OpenGL ES GLSL ES 1.0 Chromium) Three.js : 264 오류 : 0:57 : 'ftransform': 일치하는 오버로드 된 함수가 없습니다. 오류 : 0:57 : 'assign': 'const mediump'에서 변환 할 수 없습니다. 0 ':'gl_TextureMatrix ': 선언하지 않은 식별자 오류 : 0:60 :'gl_TextureMatrix ':'[ '의 형식이 배열, 또는 벡터
ERROR : 0:60 : 'gl_MultiTexCoord0': 선언되지 않은 식별자 Three.js를 : 257

<!doctype html> 
<html> 
    <head> 
     <title>boiler plate for three.js</title> 
     <meta charset="utf-8"> 
     <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> 

     <script src="vendor/three.js/Three.js"></script> 
     <script src="vendor/three.js/Detector.js"></script> 
     <script src="vendor/three.js/Stats.js"></script> 
     <script src="vendor/threex/THREEx.screenshot.js"></script> 
     <script src="vendor/threex/THREEx.FullScreen.js"></script> 
     <script src="vendor/threex/THREEx.WindowResize.js"></script> 
     <script src="vendor/threex.dragpancontrols.js"></script> 
     <script src="vendor/headtrackr.js"></script> 

     <style> 
body { 
    overflow : hidden; 
    padding  : 0; 
    margin  : 0; 
    color  : #222; 
    background-color: #BBB; 
    font-family : arial; 
    font-size : 100%; 
} 
#info .top { 
    position : absolute; 
    top  : 0px; 
    width  : 100%; 
    padding  : 5px; 
    text-align : center; 
} 
#info a { 
    color  : #66F; 
    text-decoration : none; 
} 
#info a:hover { 
    text-decoration : underline; 
} 
#info .bottom { 
    position : absolute; 
    bottom  : 0px; 
    right  : 5px; 
    padding  : 5px; 
} 

     </style> 
    </head> 
<body> 
    <!-- three.js container --> 
     <div id="container"></div> 
    <!-- info on screen display --> 
    <div id="info"> 
     <!--<div class="top"> 
      <a href="http://learningthreejs.com/blog/2011/12/20/boilerplate-for-three-js/" target="_blank">LearningThree.js</a> 
      boiler plate for 
      <a href="https://github.com/mrdoob/three.js/" target="_blank">three.js</a> 
     </div>--> 
     <div class="bottom" id="inlineDoc" > 
      - <i>p</i> for screenshot 
     </div> 
    </div> 

<canvas id="compare" width="320" height="240" style="display:none"></canvas> 
<video id="vid" autoplay loop></video> 
<script type="x-shader/x-vertex" id="vertexShader"> 
varying vec2 texcoord0; 


void main() 
{ 
    // perform standard transform on vertex 
    gl_Position = ftransform(); 

    // transform texcoords 
    texcoord0 = vec2(gl_TextureMatrix[0] * gl_MultiTexCoord0); 
}  
    </script> 

    <script type="x-shader/x-vertex" id="fragmentShader"> 
varying vec2 texcoord0; 

uniform sampler2D tex0; 
uniform vec2 imageSize; 
uniform float coef; 

const vec4 lumcoeff = vec4(0.299,0.587,0.114,0.); 

void main (void) 
{ 

    vec4 pixel = texture2D(tex0, texcoord0); 
    float luma = dot(lumcoeff, pixel); 

    gl_FragColor = vec4((texcoord0.x/imageSize.x), luma, (texcoord0.y/imageSize.y) , 1.0); 
} 
    </script> 
    <script type="text/javascript"> 
     var stats, scene, renderer; 
     var camera, cameraControls; 
     var videoInput = document.getElementById('vid'); 
     var canvasInput = document.getElementById('compare'); 
     var projector = new THREE.Projector(); 
     var gl; 
     var mesh, 
     cube, 
    attributes, 
    uniforms, 
    material, 
    materials; 
     var videoTexture = new THREE.Texture(videoInput); 

     if(!init()) animate(); 

     // init the scene 
     function init(){ 

      if(Detector.webgl){ 
       renderer = new THREE.WebGLRenderer({ 
        antialias  : true, // to get smoother output 
        preserveDrawingBuffer : true // to allow screenshot 
       }); 
       renderer.setClearColorHex(0xBBBBBB, 1); 
      // uncomment if webgl is required 
      //}else{ 
      // Detector.addGetWebGLMessage(); 
      // return true; 
      }else{ 
       renderer = new THREE.CanvasRenderer(); 
       gl=renderer; 
      } 
      renderer.setSize(window.innerWidth, window.innerHeight); 
      document.getElementById('container').appendChild(renderer.domElement); 


      // create a scene 
      scene = new THREE.Scene(); 

      // put a camera in the scene 
      camera = new THREE.PerspectiveCamera(23, window.innerWidth/window.innerHeight, 1, 100000); 
      camera.position.z = 0; 
      scene.add(camera); 
// 
//   // create a camera contol 
//   cameraControls = new THREEx.DragPanControls(camera) 

      // transparently support window resize 
//   THREEx.WindowResize.bind(renderer, camera); 
      // allow 'p' to make screenshot 
      THREEx.Screenshot.bindKey(renderer); 
      // allow 'f' to go fullscreen where this feature is supported 
      if(THREEx.FullScreen.available()){ 
       THREEx.FullScreen.bindKey();   
       document.getElementById('inlineDoc').innerHTML += "- <i>f</i> for fullscreen"; 
      } 
      materials = new THREE.MeshLambertMaterial({ 
        map : videoTexture 
      }); 
      attributes = {}; 

      uniforms = { 

       tex0: {type: 'mat2', value: materials}, 

       imageSize: {type: 'f', value: []}, 

       coef: {type: 'f', value: 1.0} 

      }; 


     //Adding a directional light source to see anything.. 
     var directionalLight = new THREE.DirectionalLight(0xffffff); 
     directionalLight.position.set(1, 1, 1).normalize(); 
     scene.add(directionalLight);  



      // video styling 
      videoInput.style.position = 'absolute'; 
      videoInput.style.top = '50px'; 
      videoInput.style.zIndex = '100001'; 
      videoInput.style.display = 'block'; 

      // set up camera controller 
      headtrackr.controllers.three.realisticAbsoluteCameraControl(camera, 1, [0,0,0], new THREE.Vector3(0,0,0), {damping : 1.1}); 
      var htracker = new headtrackr.Tracker(); 
      htracker.init(videoInput, canvasInput); 
      htracker.start(); 

//   var stats = new Stats(); 
//   stats.domElement.style.position = 'absolute'; 
//   stats.domElement.style.top = '0px'; 
//   document.body.appendChild(stats.domElement); 


document.addEventListener('headtrackrStatus', 
    function (event) { 
    if (event.status == "found") { 
     addCube(); 

    } 
    } 
);  

}  
     // animation loop 
     function animate() { 

      // loop on request animation loop 
      // - it has to be at the begining of the function 
      // - see details at http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating 
      requestAnimationFrame(animate); 

      // do the render 
      render(); 

      // update stats 
      //stats.update(); 
     } 

function render() { 

      // convert matrix of every frame of video -> texture 
      uniforms.tex0 = materials; 
      uniforms.coef = 0.2; 
      uniforms.imageSize.x = window.innerWidth; 
      uniforms.imageSize.y = window.innerHeight; 
      // update camera controls 
//   cameraControls.update(); 
      if( videoInput.readyState === videoInput.HAVE_ENOUGH_DATA){ 
       videoTexture.needsUpdate = true; 
      } 

      // actually render the scene 
      renderer.render(scene, camera); 
     } 
function addCube(){ 
     material = new THREE.ShaderMaterial({ 
      uniforms: uniforms, 
      attributes: attributes, 
      vertexShader: document.getElementById('vertexShader').textContent, 
      fragmentShader: document.getElementById('fragmentShader').textContent, 
      transparent: true 
     }); 


      //The cube 
     cube = new THREE.Mesh(new THREE.CubeGeometry(40, 30, 10, 1, 1, 1, material), new THREE.MeshFaceMaterial()); 
     cube.overdraw = true; 
     scene.add(cube); 
} 
</script> 
</body> 
</html> 

답변

0

여기에 주요 문제는 당신이 프로그래밍/F를 대상으로 한 기존의 GLSL 예약 된 단어를 사용하는 것입니다 ixed-function interop. OpenGL ES 2.0에서는 일반 OpenGL에서 처리해야하는 레거시 고정 함수 정점 배열 수하물을 완전히 제거했기 때문에 gl_MultiTexCoord0gl_TextureMatrix [n]과 같은 항목은 정의되지 않았습니다. 이러한 예약어를 사용하면 텍스처 단위 당 행렬/정점 배열 상태를 가질 수 있습니다. 그들은 OpenGL ES에 존재하지 않습니다. 이것은 OpenGL에서의 목적이었습니다.

이 문제를 해결하려면 텍스처 좌표 포인터와 텍스처 단위 사이에 1 : 1 매핑 대신 일반 정점 속성 (예 : attribute vec2 tex_st)을 사용해야합니다. 마찬가지로, 각 텍스처 단위와 관련된 텍스처 매트릭스도 없습니다. 텍스처 행렬의 기능을 복제하려면 정점/조각 셰이더에서 행렬 유니폼을 사용해야합니다.

사실, 셰이더를 사용할 때 각 텍스처 단위에 대해 별도의 텍스처 행렬/텍스처 좌표 포인터를 갖는 것이 유용하다는 것을 실제로 알게된 마지막 시간을 기억하지 못합니다 ... 나는 종종 4 개 또는 5 개의 텍스처와 1 또는 2 세트의 텍스처 좌표가 필요합니다. 큰 손실이 아닙니다.

여기 키커는 ftransform (...)입니다. 이는 고정 함수 파이프 라인과 동일한 방식으로 동작하는 OpenGL에서 단선 정점 셰이더를 작성할 수 있도록하기위한 것입니다. OpenGL 2.x 또는 3.x (호환성) 용으로 작성된 셰이더를 복사하여 붙여 넣었어야합니다. 이 쉐이더에서 모든 것을 고치는 방법을 설명하는 것은 정말 어려운 일일 수 있습니다. 방금 쓴 것의 대부분이 이해되기 전에 GLSL에 대해 더 많이 배워야 할 수도 있습니다. - \

+0

나는 GLSL에 관해 더 많이 배워야한다는 것에 동의합니다. 매우 기꺼이. 조언 해 주셔서 감사합니다. OpenGL과 OpenGL ES간에 GLSL의 세부 사항이 변경되는 참조가 있습니까? – codescholar

+0

@ user2752996 : 알고 있지 않습니다. 나는 OpenGL의 모든 버전에 대한 전체 사양을 읽는 그 사람의 한 사람이다. 이것은 매우 *** 시간이 많이 걸리고, 그것이 당신의 일의 일부가 아니라면 나는 당신이 미쳐 갈 것이라고 생각합니다. GLES GLSL 명세서에 몇 가지 paragaph가 있습니다 : http://www.opengl.org/registry/gles/OpenGL GLSL과 OpenGL ES GLSL의 차이점은 아직까지 다릅니다. - \ –

관련 문제