var: GLSL ES → JavaScript

Hallo miteinander!

Ich bin auf der Suche nach etwas Inspiration, wie ich in GLSL ES geschriebene Shader am besten in meinen JavaScript-Code einbauen kann.

Für diejenigen, die sich mit WebGL oder OpenGL bislang noch nicht beschäftigt haben, hier mal ein kurzer Umriss des Problems:

Zunächst braucht man für die Darstellung von 3D-Grafik via WebGL zwei Dinge, nämlich ein canvas Element und ein Object, dass den WebGLRenderingContext repräsentiert, etwas vereinfacht also...

var scene = document.getElementsByTagName( 'CANVAS' )[ 0 ];  
  
var GL = scene.getContext( 'experimental-webgl' );

Die folgenden Schritte zum Einbau eines Shaders erklären sich dann mehr oder weniger von selbst, wobei ich das hier nur mal am Beispiel eines vShaders darstellen will...

var shaderProgram = GL.createProgram( );  
  
var vertexShader = GL.createShader( GL.VERTEX_SHADER );  
  
GL.shaderSource( vertexShader, vertexShaderSource );  
  
GL.compileShader( vertexShader );  
  
GL.attachShader( shaderProgram, vertexShader );  
  
GL.linkProgram( shaderProgram );  
  
GL.useProgram( shaderProgram );

Der aufmerksame Leser wird sich nun fragen, wo vertexShaderSource herkommt, - und genau da liegt das Problem! ;-)

Die Variable vertexShaderSource beinhaltet (hier) den in GLSL ES geschriebenen Code des Shaders, und wie der in diese Variable reinkommt, dafür gibt es zwei Möglichkeiten, nämlich erstens als String direkt in JS...

var vertexShaderSource =  
  
'attribute vec3 aVertexPosition; \n\  
 attribute vec4 aVertexColor; \n\  
 \n\  
 uniform mat4 uMVMatrix; \n\  
 uniform mat4 uPMatrix; \n\  
 \n\  
 varying vec4 vColor; \n\  
 \n\  
 void main ( void ) { \n\  
   \n\  
   gl_Position = uPMatrix * uMVMatrix * vec4( aVertexPosition, 1.0 ); \n\  
   \n\  
   vColor = aVertexColor; \n\  
   \n\  
 }';

...oder zweitens im HTML als zusätzliches script, dem man einen type zuweist, mit dem der Browser nichts anfangen kann und das er deshalb ignoriert...

<script id="vShader" type="x-shader/x-vertex">  
  
attribute vec3 aVertexPosition;  
attribute vec4 aVertexColor;  
  
uniform mat4 uMVMatrix;  
uniform mat4 uPMatrix;  
  
varying vec4 vColor;  
  
void main ( void ) {  
  
  gl_Position = uPMatrix * uMVMatrix * vec4( aVertexPosition, 1.0 );  
  
  vColor = aVertexColor;  
  
}  
  
</script>

...und welches man dann mit einer Funktion ins JS script läd.

Beide Methoden sind zwar einigermaßen unhandlich, aber doch eigentlich unproblematisch, wenn es nur darum geht, eine einzelne 3D-Szene zu zeichnen.

Wenn man jedoch innerhalb eines Programms die Shader möglichst variabel anpassen will, wäre es natürlich gut, wenn man das Hinzufügen und Entfernen von zum Beispiel attributes und uniforms irgendwie standardisieren könnte...

Man müsste also quasi den GLSL ES Code in JS Code 'übersetzen', und wie das am besten anzugehen wäre ist nun das Problem, für dessen Lösung ich mir eure Mithilfe erhoffe. ;-)

Schonmal Dank im Voraus für die Mühe und wie immer beste Grüße

var

  1. Hakuna matata!

    Wenn man jedoch innerhalb eines Programms die Shader möglichst variabel anpassen will, wäre es natürlich gut, wenn man das Hinzufügen und Entfernen von zum Beispiel attributes und uniforms irgendwie standardisieren könnte...

    Wenn ich dich richtig verstehe, willst du solche Shader später dynamisch erzeugen und bearbeiten können. Dafür suchst du nach einer programmatischen API, weil String-Konkatenation dafür offensichtlich ungeeignet ist. Du suchst quasi sowas wie das DOM, nur nicht für HTML, sondern für GLSL ES. Richtig soweit?

    --
    “All right, then, I'll go to hell.” – Huck Finn
    1. Hakuna matata!

      Hallo 1UnitedPower!

      Wenn ich dich richtig verstehe, willst du solche Shader später dynamisch erzeugen und bearbeiten können. Dafür suchst du nach einer programmatischen API, weil String-Konkatenation dafür offensichtlich ungeeignet ist. Du suchst quasi sowas wie das DOM, nur nicht für HTML, sondern für GLSL ES. Richtig soweit?

      Richtig. ;-)

      Ich suche nach der richtigen Herangehensweise, um genau so eine API zu erstellen.

      Gruß.

      var

      1. Hakuna matata!

        Ich suche nach der richtigen Herangehensweise, um genau so eine API zu erstellen.

        Hui, ich nehm an, du willst das wirklich selber machen und nichts Vorgefertigtes nehmen? Du arbeitest immerhin auch mit rohem WebGL, anstatt mit irgendeiner Bibliothek. Vielleicht ist der Mozilla Shader Editor trotzdem eine gute Anlaufstelle für dich.

        Das klingt auf alle Fälle nach einer sehr anspruchsvollen Aufgabe, du musst dich wohl sehr gut mit dem Sprachstandard der Shader-Sprache vertraut machen. Dort ist die Syntax und der Semantik der einzelnen Sprachbausteine akribisch genau definiert. Für dich dürfte vor allem die Syntax interessant sein, weil du ja keinen standardkonformen Interpreter oder Renderer bauen willst, sondern "nur" einen Editor, um Shader zu bearbeiten. Deine API muss also die richtigen Klassen und Funktionen bereitstellen, um valide Syntax zu erzeugen. Beim umgekehrten Vorgang, also dem Parsen, baut man nach und nach einen abstrakten Syntaxbaum aus der textuelle Repräsentation zusammen. Ich würde so ähnlich vorgehen und die API so gestalten, dass man programmatisch einen abstrakten Syntaxbaum erzeugen muss, der dann später in eine textuelle Repräsentation serialisiert werden kann. Die API wird sich dann vermutlich sehr an den Produktionsregeln der Sprachsyntax orientieren. Bestimmte Produktionsregeln könnten zum Beispiel durch bestimmte Klassen oder Funktionen reflektiert werden.

        --
        “All right, then, I'll go to hell.” – Huck Finn
        1. Hakuna matata!

          Hallo

          Schön formuliert. So in etwa hatte ich mir das auch vorgestellt. In groben Zügen zumindest. ;-)

          Eine anspruchsvolle Aufgabe ist es natürlich, aber extrem interessant, wie ich finde.

          Im Übrigen nehme ich Literaturvorschläge gerne entgegen, denn auch über das Sprachstudium hinaus dürfte sich hier sicher der ein oder andere nützliche Gedanke finden.

          Gruß

          var