Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Mi Mai 15, 2024 01:30

Foren-Übersicht » Programmierung » Shader
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 6 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Einfaches if-Statement?!
BeitragVerfasst: Mo Okt 25, 2010 22:04 
Offline
DGL Member

Registriert: Fr Jul 16, 2010 18:28
Beiträge: 40
Hallo,

mein Vorhaben in Kürze (Achtung, ich benutze WebGL): In der Applikation hat der Benutzer die Möglichkeit eine boolean-Variable zu setzen, um entweder die Farbe des Objektes mit einer Uniform-Variable zu setzen (konstante Farbangabe) oder die Farbangabe pro Vertex anzugeben. Letzteres führt natürlich dazu, dass er einen VBO für die Farbinformationen verwenden muss. Im untenstehenden Code des Vertex-Shaders wird dies durch die boolean-Variable useUniformColor geregelt. Allerdings macht die if-abfrage bzw. dessen Inhalt richtig Probleme. Sobald die if-Abfrage im Code erscheint, funktioniert das ganze Programm (in Chromium) nicht mehr, d.h. die Objekte werden nicht mehr mit dem Wert der Uniform-Farb-Variable gefärbt. In Firefox ist das Ganze kein Ding, es funktioniert, wie gewollt, halt nur nicht in Chromium (9.0.564.0 (63713)).
Zwei blöde Dinge sind zu beobachten: 1. Auch wenn ich z.B. die dauerhafte false-Variable "test" in das if-Statement einsetze (siehe auskommentierte Zeile), so blockiert diese Abfrage das ganze Programm, obwohl die Variable ja immer false ist und der if-Block niemals betreten werden dürfte.
2. Der Hauptblockator ist scheinbar diese Zeile: myColor=vertexColor; Auch wenn ich so etwas (sehr) Merkwürdiges wie

Code:
 if(!useUniformColor){                       
            myColor=vertexColor;      
 }                                 
            myColor=constantColor;

angebe, stoppt die Einfärbung der Objekte mit konstanter Farbe.

Leider bekomme ich keinerlei Fehlermeldungen oder Hinweise vom Chromium-Browser. Deshalb frage ich hier einfach mal nach. Vielleicht habt ihr ja eine Idee, warum die Implementierung ein solches Verhalten zeigt.

Bevor ihr fragt, hier die Initialisierung bzw. Referenzspeicherung der Variablen des Shaders:

Code:
     
shaderProgram.vertexColorAttribute = gl.getAttribLocation(shaderProgram, "vertexColor");
shaderProgram.useUniformColor = gl.getUniformLocation(shaderProgram, "useUniformColor");


Im Programm aktiviere ich das Farbattribut mit gl.enableVertexAttribArray(shaderProgram.vertexColorAttribute); und verwende dann das Farb-VBO. Die entsprechenden Objekte werden mit den angegebenen Farben eingefärbt, allerdings kommen dann die oben beschriebenen Probleme, also das "blockieren" der Uniform-Farbe anderer Objekte.

Wisst ihr was los ist? Vielleicht vergesse ich etwas (bin ein Anfänger) ..


Gesamte Shader-Code

Code:
<script id="shader-fs" type="x-shader/x-fragment">

   #ifdef GL_ES
   precision highp float;
   #endif
 
   varying vec3 vLightWeighting;
   varying vec3 myColor;

   void main(void) {
        gl_FragColor = vec4(myColor * vLightWeighting, 1.0);
   }
</script>

<script id="shader-vs" type="x-shader/x-vertex">
  attribute vec3 vertexPosition;
  attribute vec3 vertexNormale;
  attribute vec3 vertexColor;
  bool test=false;
  uniform mat4 modelViewMatrix;
  uniform mat4 projektionsMatrix;
  uniform mat4 normalenMatrix;
  uniform vec3 ambientLight;
 
  uniform vec3 constantColor;
  uniform bool useUniformColor;
  uniform bool selecting;

  varying vec3 vLightWeighting;
  varying vec3 myColor;

  void main(void) {

      vec4 mvPosition=modelViewMatrix*vec4(vertexPosition,1.0);

      vec3 ambientColor = ambientLight;
      vec3 directionalLightColor = vec3(0.6, 0.6, 0.6);
      vec3 directionalVector = vec3(-0.7, -0.7, 0.9);      

     
      if(selecting){
             vLightWeighting=vec3(1.0,1.0,1.0);
      }else{
             vec3 lightDirection=normalize(directionalVector - mvPosition.xyz);
            vec4 transformedNormal = normalenMatrix * vec4(vertexNormale, 1.0);

             float directionalLightWeighting = max(dot(transformedNormal.xyz, lightDirection), 0.0);   
             vLightWeighting = ambientLight + (directionalLightColor * directionalLightWeighting);
      } 
     
      if(!useUniformColor){                          //BEGINN des Bösen!
    //if(test){
            myColor=vertexColor;      
      }else{                                            //ENDE des Bösen!
            myColor=constantColor;
      }
      gl_Position = projektionsMatrix * mvPosition;

  }

</script>



Danke auf jeden Fall für jedes bisschen Hilfe!


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Einfaches if-Statement?!
BeitragVerfasst: Di Okt 26, 2010 09:35 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
Auch wenn ich so etwas (sehr) Merkwürdiges wie
Code:
if(!useUniformColor){                       
            myColor=vertexColor;     
}                                 
            myColor=constantColor;

angebe, stoppt die Einfärbung der Objekte mit konstanter Farbe.

Klar, weil der else-Zweig fehlt?

Ansonsten wäre ggf. noch interessant wie du die Uniform-Variable setzt.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Einfaches if-Statement?!
BeitragVerfasst: Di Okt 26, 2010 10:15 
Offline
DGL Member

Registriert: Fr Jul 16, 2010 18:28
Beiträge: 40
Coolcat hat geschrieben:
Zitat:
Auch wenn ich so etwas (sehr) Merkwürdiges wie
Code:
if(!useUniformColor){                       
            myColor=vertexColor;     
}                                 
            myColor=constantColor;

angebe, stoppt die Einfärbung der Objekte mit konstanter Farbe.

Klar, weil der else-Zweig fehlt?

:D Das war mit Absicht gemacht, um das Merkwürdige zu demonstrieren, denn: Die konstante Färbung geschieht ja außerhalb der if-Abfrage mit myColor=constantColor; , d.h. es müsste immer gelten. Aber es geht ja eben nicht, weiß der Geier warum nicht. Er stoppt ,nur weil ich die eigentlich wertlose if-Abfrage reingebaut habe.
Zitat:
Ansonsten wäre ggf. noch interessant wie du die Uniform-Variable setzt.



gl.uniform1i(shaderProgram.useUniformColor,true);
gl.uniform3f(shaderProgram.constantColor,1.0,1.0,1.0); //hier nur z.B. Weiß

gl.bindBuffer(gl.ARRAY_BUFFER, this.positionBuffer);
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
...
gl.drawArrays(gl.TRIANGLES, 0, this.vertices.length/3);


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Einfaches if-Statement?!
BeitragVerfasst: Di Okt 26, 2010 10:22 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Versuch mal statt "true" eine 1. Vielleicht testet der Shader statt auf >0 nur auf == 1. Was besseres fällt mir nicht ein.

Edit: Könnte es am "precision highp float;" liegen?

Edit2: Ok, vergiss es :
Zitat:
The fragment language has no default precision qualifier for floating point types. Hence for float, floating
point vector and matrix variable declarations, either the declaration must include a precision qualifier or
the default float precision must have been previously declared.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Einfaches if-Statement?!
BeitragVerfasst: Di Okt 26, 2010 13:52 
Offline
DGL Member

Registriert: Fr Jul 16, 2010 18:28
Beiträge: 40
Coolcat hat geschrieben:
Versuch mal statt "true" eine 1. Vielleicht testet der Shader statt auf >0 nur auf == 1. Was besseres fällt mir nicht ein.


Habe ich soeben versucht, es hilft leider auch nicht. Es ist eher ein Problem des Wechsels von Shader-Attribut-Variablen zu Shader-Uniform-Variablen. Egal wo das myColor=vertexColor im Code und egal mit welchen Bedingungen es umrundet ist: Es blockiert die Färbung aller nachfolgenden Objekte, die mit myColor=constantColor gefärbt werden sollen.

Hä?? WebGl bzw. GLSL ist schon eine sehr komische Stange...
-------

Ich hab mal den Code sehr stark komprimiert und poste ihn mal hier. Auch habe ich erstmal die Färbung mit einer Attribute-Variable wegelassen und nur noch das if-Statement dargelassen (siehe vertex shader). Sobald ich den if-else-Block wegnehme, funktioniert es wieder in Chromium, allerdings dann nur die konstante Uniform-Färbung:

Code:
<html>

<head>
<title>WebGL</title>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">

<script type="text/javascript" src="glMatrix-0.9.4.min.js"></script>

<script id="shader-fs" type="x-shader/x-fragment">

   #ifdef GL_ES
   precision highp float;
   #endif
 
   varying vec3 vLightWeighting;
   varying vec3 myColor;

   // varying float zValue;
   void main(void) {
        gl_FragColor = vec4(myColor * vLightWeighting, 1.0);
   }
</script>

<script id="shader-vs" type="x-shader/x-vertex">
  attribute vec3 vertexPosition;
  attribute vec3 vertexNormale;
  attribute vec3 vertexColor;

  uniform mat4 modelViewMatrix;
  uniform mat4 projektionsMatrix;
  uniform mat4 uNMatrix;
 
 
  uniform vec3 ambientLight;
  uniform vec3 constantColor;
 
  uniform bool useUniformColor;
 
  varying vec3 vLightWeighting;
  varying vec3 myColor;

 void main(void) {

      vec4 mvPosition=modelViewMatrix*vec4(vertexPosition,1.0);
      gl_Position = projektionsMatrix * mvPosition;

      vec3 ambientLightVar = ambientLight;
      vec3 directionalLightColor = vec3(0.6, 0.6, 0.6);
      vec3 directionalVector = vec3(-0.7, -0.7, 0.9);      
 
      vec4 transformedNormal = uNMatrix * vec4(vertexNormale, 1.0);
 
      float directionalLightWeighting = max(dot(transformedNormal.xyz, directionalVector), 0.0);
      vLightWeighting = ambientLightVar + (directionalLightColor * directionalLightWeighting);
     
     
      if(!useUniformColor){
               //tue gar nichts, weil es auch so schon nicht funktioniert
      }
      else{
           myColor=constantColor;
      }
  }

</script>

<script type="text/javascript">

//---------------------------------------------------

//-------------------------------------------------------------------------------------

function glCentral(){                   
   this.models=[];
   this.initialTranslation;
   this.translation;

}
glCentral.prototype={
   addModel: function(obj){
      this.models.push(obj);
   },
   setInitialTranslation: function(x,y,z){
      this.initialTranslation=[x,y,z];
      this.initialTranslation2=[-(x),-(y),-(z)]
   }
}
//-------------------------------------------------------------------------------------

function Model(name){
   this.name=name;
   this.modelColor=[1,0,0];         
   this.type;             
   this.vertices=[];
   this.color=[];      
   this.verticesBuffer;
   this.useUniformColor=true;   
}


Model.prototype={
   setVertices: function(v){
      this.vertices=[];
      this.vertices=v;
   },
   useColorByRGBUniform: function(c){   
      gl.uniform3f(shaderProgram.constantColor,c[0],c[1],c[2]);

   },
   createVerticesBuffer: function(){
   
      this.positionBuffer=gl.createBuffer();
      gl.bindBuffer(gl.ARRAY_BUFFER, this.positionBuffer);
      gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(this.vertices), gl.STATIC_DRAW);
      this.checked=false;
       },
   drawCallVertices: function(type){
      switch(type){
         case "triangle": gl.drawArrays(gl.TRIANGLES, 0, this.vertices.length/6);break;
         case "line":     gl.drawArrays(gl.LINES, 0, this.vertices.length/3);   break;   
         case "point":    gl.drawArrays(gl.POINTS, 0, this.vertices.length/3);   break;
      }
   }
}


function drawClass(name){
      Model.call(this,name); 
   
      this.drawVertexObject=function(){


      mvPushMatrix();

      mvTranslate(allModels.translation);                   
      mvTranslate(allModels.initialTranslation);        
      
      setMatrixUniforms();
       
      this.createVerticesBuffer();
      this.useColorByRGBUniform(this.modelColor);

      gl.bindBuffer(gl.ARRAY_BUFFER, this.positionBuffer);
      gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, 3, gl.FLOAT, false, 6*4, 0*4);

      gl.vertexAttribPointer(shaderProgram.vertexNormalAttribute, 3, gl.FLOAT, false, 6*4, 3*4);
      gl.uniform1i(shaderProgram.useUniformColor,true);
      
      this.drawCallVertices(this.type);
      mvPopMatrix();   
   }
}
drawClass.prototype=new Model();

function triangleObject(name){
   Model.call(this,name);
   gl.uniform1i(shaderProgram.useUniformColor,true);
   this.type="triangle";
   this.draw=function(){
      if(!this.deactivateDraw)this.drawVertexObject();
      if(this.wireframe){this.drawWireframe()};
   }
}

triangleObject.prototype=new drawClass();


//-------------------------------------------------------------------------
//matrix-stoff hier entfernt
//----------
function setMatrixUniforms() {
       gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix);
       gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix);
       var normalMatrix=mat4.inverse(mvMatrix);
       normalMatrix=mat4.transpose(normalMatrix);
       //alert(shaderProgram.nMatrixUniform)
       gl.uniformMatrix4fv(shaderProgram.nMatrixUniform, false, normalMatrix);
}

//----------------------------initialise WebGL----------------------------
 
  var gl;
function initGL(canvas) { 
    try {
         gl = canvas.getContext("experimental-webgl",{ antialias: true} );

          gl.viewportWidth = canvas.width;
          gl.viewportHeight = canvas.height;

    } catch(e) {
      }
    if (!gl) {
      alert("Browser unterstützt kein Webgl!");
    }
}

function getShader(gl, id) {
    var shaderScript = document.getElementById(id);
    if (!shaderScript) {
      return null;
    }

    var str = "";
    var k = shaderScript.firstChild;
    while (k) {
      if (k.nodeType == 3) {
        str += k.textContent;
      }
      k = k.nextSibling;
    }

    var shader;
    if (shaderScript.type == "x-shader/x-fragment") {
      shader = gl.createShader(gl.FRAGMENT_SHADER);
    } else if (shaderScript.type == "x-shader/x-vertex") {
      shader = gl.createShader(gl.VERTEX_SHADER);
    } else {
      return null;
    }

    gl.shaderSource(shader, str);
    gl.compileShader(shader);

    if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
      alert(gl.getShaderInfoLog(shader));
      return null;
    }

    return shader;
}
//-------------------------------------------------------------------

   var shaderProgram;
function initShaders() {
     var fragmentShader = getShader(gl, "shader-fs");
     var vertexShader = getShader(gl, "shader-vs");

     shaderProgram = gl.createProgram();
     gl.attachShader(shaderProgram, vertexShader);
     gl.attachShader(shaderProgram, fragmentShader);
     gl.linkProgram(shaderProgram);

     if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
       alert("Could not initialise shaders");
     }

   gl.useProgram(shaderProgram);
   
     shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "vertexPosition");
     gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);

     shaderProgram.vertexNormalAttribute = gl.getAttribLocation(shaderProgram, "vertexNormale");
     gl.enableVertexAttribArray(shaderProgram.vertexNormalAttribute);
     

     shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "projektionsMatrix");
     shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "modelViewMatrix");
     shaderProgram.nMatrixUniform = gl.getUniformLocation(shaderProgram, "uNMatrix");
     shaderProgram.ambientLight = gl.getUniformLocation(shaderProgram, "ambientLight");
     shaderProgram.constantColor = gl.getUniformLocation(shaderProgram, "constantColor");
     shaderProgram.useUniFormColor = gl.getUniformLocation(shaderProgram, "useUniformColor");
     
 
}

//------------------Globale Variablen-----------------
  var zoom =1;
  var xTrans=0 ;         
  var yTrans=0;         

  //-----------------------------Central Model Collector---------------------------
var allModels=new glCentral();
function initZentraleEinheit(v){
       allModels.setInitialTranslation(-(v[0]),-(v[1]),-(v[2]))
       allModels.additionalTranslation=[0,0,0];
       allModels.selectModus=false; //erst bei buttonklick aktivieren 
}


function drawScene() {

   gl.bindFramebuffer(gl.FRAMEBUFFER,null);
   gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
   gl.clearColor(0.0,0.0,0.0,1.0)
   gl.enable(gl.DEPTH_TEST);
   
   gl.viewport(0, 0, canvas.clientWidth, canvas.clientHeight);
   perspective(45*zoom, gl.viewportWidth / gl.viewportHeight, 1, 140000.0);
   loadIdentity();
   drawModels();

}

//----------------------------AJAX- Request----------------------
var req;
function loadJSON(){
   req = new XMLHttpRequest();
   req.open("GET", "interleaved.json"); req.send(null);
   req.onreadystatechange = loadModels;
   
}

//---------------------load Models-----------------------
var m;
function loadModels(){
   if (req.readyState == 4){
       m = eval('(' + req.responseText + ')');
       
      for(var k=0;k<m.modelle.length;k++){
               var name=m.modelle[k].name;
               var vertices=m.modelle[k].vertices;
               var color=m.modelle[k].color;
               var type=m.modelle[k].type;
               zvalue=m.diagonal;
        
             if(type=="triangle"){
                    var b=new triangleObject(name);
       b.setVertices(vertices);
       b.modelColor=color;
       allModels.addModel(b);
             }
         }
         initZentraleEinheit(m.schwerpunkt);
         drawScene();
   }
}

var zvalue;
function drawModels(){
    gl.uniform3f(shaderProgram.ambientLight,0.3,0.3,0.3);
    allModels.translation=[xTrans,yTrans,-zvalue]
    var ausgabe=" ";
    for(var i=0;i<allModels.models.length;i++){
       allModels.models[i].draw();
    }
}


  var select=true;
  var canvas;
function webGLStart() {
    canvas = document.getElementById("canvas");
    initGL(canvas);
    initShaders();
    //initFBO();
    loadJSON();
    gl.clearColor(0.0, 0.0, 0.0, 1.0);
    gl.clearDepth(1.0);
    gl.enable(gl.DEPTH_TEST);
    gl.depthFunc(gl.LEQUAL);  //gl.lineWidth(3.0);
   // drawScene();
}


</script>
</head>

<body onload="webGLStart();">
  <canvas id="canvas" width="700" height="500" style="border: none;"></canvas><br>
</html>
</body>
</html>



Zuletzt geändert von m.sirin am Di Okt 26, 2010 21:45, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Einfaches if-Statement?!
BeitragVerfasst: Di Okt 26, 2010 14:33 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Lass dir mal das Info-Log vom compilieren und linken der Shader ausgeben. Auch wenn der Status erfolgreich ist, kann es Warnungen geben die sinnvolle Hinweise geben können.

Ein Hinweis nebenbei der mit der Sache nichts zu tun hat...
Code:
vec4 transformedNormal = uNMatrix * vec4(vertexNormale, 1.0);

Normalen transformiert man anders. :) Man nimmt den Rotationsteil der ModelView-Matrix (3x3, oben links) und invertiert diesen und transponiert ihn nochmal. Du kannst auch die 4x4 Matrix invertieren, aber der Aufwand ist wesentlich größer als für eine 3x3 Matrix. In jedem Fall darfst du die Normale aber nicht mit w=1.0 ergänzen, da es ja eine Richtung ist und kein Punkt.
=> 3x3 Matrix benutzt oder mit 0.0 ergänzen.
Darüber hinaus sollte die Normale nach der Multiplikation mit der NormalMatrix normalisiert werden.

Zitat:
Hä?? WebGl bzw. GLSL ist schon eine sehr komische Stange...

GLSL ist eigentlich sehr schön. Wenn es im anderen Browser geht ist es wohl eher Chromium was hier strange ist ;)

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 6 Beiträge ] 
Foren-Übersicht » Programmierung » Shader


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 4 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.026s | 17 Queries | GZIP : On ]