# GLSL Noise Shader



## javaPanther (29. Nov 2011)

Hallo liebe Leute,
ich bin blutiger Anfänger auf dem Gebiet der Shader und versuchte mich daran einen Perlin Noise Shader zu implementieren. Ich war auch soweit erfolgreich, aber das Ergebnis sieht nicht aus wie ich es erwartet habe:







Mein Code:


```
uniform sampler2D permTexture;
uniform float x;
uniform float y;
uniform float z;

varying vec2 v_texCoord2D;

#define ONE 0.00390625
#define ONEHALF 0.001953125


float fade(float t) {
  // return t*t*(3.0-2.0*t); // Old fade, yields discontinuous second derivative
  return t*t*t*(t*(t*6.0-15.0)+10.0); // Improved fade, yields C2-continuous noise
}


/*
 * 3D classic noise. Slower, but a lot more useful than 2D noise.
 */
float noise(vec3 P)
{
  vec3 Pi = ONE*floor(P)+ONEHALF; // Integer part, scaled so +1 moves one texel
                                  // and offset 1/2 texel to sample texel centers
  vec3 Pf = fract(P);     // Fractional part for interpolation

  // Noise contributions from (x=0, y=0), z=0 and z=1
  float perm00 = texture2D(permTexture, Pi.xy).a ;
  vec3  grad000 = texture2D(permTexture, vec2(perm00, Pi.z)).rgb * 4.0 - 1.0;
  float n000 = dot(grad000, Pf);
  vec3  grad001 = texture2D(permTexture, vec2(perm00, Pi.z + ONE)).rgb * 4.0 - 1.0;
  float n001 = dot(grad001, Pf - vec3(0.0, 0.0, 1.0));

  // Noise contributions from (x=0, y=1), z=0 and z=1
  float perm01 = texture2D(permTexture, Pi.xy + vec2(0.0, ONE)).a ;
  vec3  grad010 = texture2D(permTexture, vec2(perm01, Pi.z)).rgb * 4.0 - 1.0;
  float n010 = dot(grad010, Pf - vec3(0.0, 1.0, 0.0));
  vec3  grad011 = texture2D(permTexture, vec2(perm01, Pi.z + ONE)).rgb * 4.0 - 1.0;
  float n011 = dot(grad011, Pf - vec3(0.0, 1.0, 1.0));

  // Noise contributions from (x=1, y=0), z=0 and z=1
  float perm10 = texture2D(permTexture, Pi.xy + vec2(ONE, 0.0)).a ;
  vec3  grad100 = texture2D(permTexture, vec2(perm10, Pi.z)).rgb * 4.0 - 1.0;
  float n100 = dot(grad100, Pf - vec3(1.0, 0.0, 0.0));
  vec3  grad101 = texture2D(permTexture, vec2(perm10, Pi.z + ONE)).rgb * 4.0 - 1.0;
  float n101 = dot(grad101, Pf - vec3(1.0, 0.0, 1.0));

  // Noise contributions from (x=1, y=1), z=0 and z=1
  float perm11 = texture2D(permTexture, Pi.xy + vec2(ONE, ONE)).a ;
  vec3  grad110 = texture2D(permTexture, vec2(perm11, Pi.z)).rgb * 4.0 - 1.0;
  float n110 = dot(grad110, Pf - vec3(1.0, 1.0, 0.0));
  vec3  grad111 = texture2D(permTexture, vec2(perm11, Pi.z + ONE)).rgb * 4.0 - 1.0;
  float n111 = dot(grad111, Pf - vec3(1.0, 1.0, 1.0));

  // Blend contributions along x
  vec4 n_x = mix(vec4(n000, n001, n010, n011),
                 vec4(n100, n101, n110, n111), fade(Pf.x));

  // Blend contributions along y
  vec2 n_xy = mix(n_x.xy, n_x.zw, fade(Pf.y));

  // Blend contributions along z
  float n_xyz = mix(n_xy.x, n_xy.y, fade(Pf.z));

  // We're done, return the final noise value.
  return n_xyz;
}

void main( void )
{
	float n = noise(vec3(x + v_texCoord2D.x * 4f, y + v_texCoord2D.y * 4f, z));
	gl_FragColor = 0.5 + 0.5 * vec4(n, n, n, n);
}
```

Ich hoffe, dass mir Jemand helfen kann, dass mein Ergebnis mehr nach soetwas wie hier aussieht:






Vielen Dank und Gruß im Voraus!


----------



## javaPanther (30. Nov 2011)

Bisher noch Nichts?

Ich würde mich auch über einfache Ideen / Anregungen freuen oder Tutorials wie es richtig gemacht wird!


----------



## Marco13 (30. Nov 2011)

Man müßte sich da mal ein KSKB drumstricken ... Vielleicht hat Fancy aber auch nur diesen Thread übersehen


----------



## javaPanther (30. Nov 2011)

Hier mein kleines "KSKB" (man bemerke, dass es nicht vollständig auf meinem Mist gewachsen ist und es einen kleinen Overhead hat):


```
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;

import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.ARBFragmentShader;
import org.lwjgl.opengl.ARBShaderObjects;
import org.lwjgl.opengl.ARBVertexShader;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL20;
import org.lwjgl.util.glu.GLU;

import com.trivial.graphics.Texture;
import com.trivial.graphics.TextureLoader;

/*
* Sets up the Display, the GL context, and runs the main game
loop.
*
* @author Stephen Jones
*/
public class Main{

    private boolean done=false; //game runs until done is set to true
    Box box;
    
    public Main(){
        init();
        
        while(!done){
            if(Display.isCloseRequested())
            done=true;
            render();
            Display.update();
        }

        Display.destroy();
    }

    private void render(){
        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT |
        GL11.GL_DEPTH_BUFFER_BIT);
        GL11.glLoadIdentity();
        
        box.draw();
    }

    private void init(){
        int w=1024;
        int h=768;
    
        try{
            Display.setDisplayMode(new DisplayMode(w, h));
            Display.setVSyncEnabled(true);
            Display.setTitle("Shader Setup");
            Display.create();
        }catch(Exception e){
            System.out.println("Error setting up display");
            System.exit(0);
        }

        GL11.glViewport(0,0,w,h);
        GL11.glMatrixMode(GL11.GL_PROJECTION);
        GL11.glLoadIdentity();
        GLU.gluPerspective(45.0f, ((float)w/(float)h),0.1f,100.0f);
        GL11.glMatrixMode(GL11.GL_MODELVIEW);
        GL11.glLoadIdentity();
        GL11.glShadeModel(GL11.GL_SMOOTH);
        GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        GL11.glClearDepth(1.0f);
        GL11.glEnable(GL11.GL_DEPTH_TEST);
        

		GL11.glBlendFunc( GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA );
		GL11.glEnable( GL11.GL_BLEND );
        GL11.glEnable(GL11.GL_TEXTURE_2D);
        
        GL11.glDepthFunc(GL11.GL_LEQUAL);
        GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT,
        GL11.GL_NICEST);
        
        box = new Box();
    }

    public static void main(String[] args){
        new Main();
    }
}

class Box {
    
    /*
    * if the shaders are setup ok we can use shaders, otherwise we just
    * use default settings
    */
    private boolean useShader=true;
    
    /*
    * program shader, to which is attached a vertex and fragment shaders.
    * They are set to 0 as a check because GL will assign unique int
    * values to each
    */
    private int shader=0;
    private int vertShader=0;
    private int fragShader=0;
    
    Texture target;

    public Box(){
    
    	TextureLoader textureLoader = new TextureLoader();
    	
    	
    	
        try {
			target = textureLoader.getTexture("pano_l.png");
		} catch (IOException e) {
			e.printStackTrace();
		}
    	
        /*
        * create the shader program. If OK, create vertex
        * and fragment shaders
        */
        shader=ARBShaderObjects.glCreateProgramObjectARB();
        
        if(shader!=0){
            vertShader=createVertShader("shaders/noise.vert");
            fragShader=createFragShader("shaders/noise.frag");
        }
        else useShader=false;

        /*
        * if the vertex and fragment shaders setup sucessfully,
        * attach them to the shader program, link the sahder program
        * (into the GL context I suppose), and validate
        */
        if(vertShader !=0 && fragShader !=0){
            ARBShaderObjects.glAttachObjectARB(shader, vertShader);
            ARBShaderObjects.glAttachObjectARB(shader, fragShader);
            ARBShaderObjects.glLinkProgramARB(shader);
            ARBShaderObjects.glValidateProgramARB(shader);
            useShader=printLogInfo(shader);
        }else useShader=false;
    }

    /*
    * If the shader was setup succesfully, we use the shader. Otherwise
    * we run normal drawing code.
    */
    float x = 0f, y = 0f, z = 0f;
    public void draw(){
    	/**
        target.bind();
    	GL11.glLoadIdentity();
        GL11.glTranslatef(1.0f, 0.0f, -5.0f);
        
        GL11.glBegin(GL11.GL_QUADS);
        GL11.glTexCoord2f(1.0f, 1.0f);
        GL11.glVertex3f(-1.0f, 1.0f, 0.0f);
        GL11.glTexCoord2f(0.0f, 1.0f);
        GL11.glVertex3f(1.0f, 1.0f, 0.0f);
        GL11.glTexCoord2f(0.0f, 0.0f);
        GL11.glVertex3f(1.0f, -1.0f, 0.0f);
        GL11.glTexCoord2f(1.0f, 0.0f);
        GL11.glVertex3f(-1.0f, -1.0f, 0.0f);
        GL11.glEnd();
        */
    	
    	if(useShader) {
            ARBShaderObjects.glUseProgramObjectARB(shader);
            
        	GL20.glUniform1f(GL20.glGetUniformLocation(shader, "z"), z += 0.01f);
        	GL20.glUniform1f(GL20.glGetUniformLocation(shader, "x"), x += 0.01f);
        	GL20.glUniform1f(GL20.glGetUniformLocation(shader, "y"), y += 0.01f);
        }

        GL11.glLoadIdentity();
        GL11.glTranslatef(-1.0f, 0.0f, -5.0f);
        
        GL11.glBegin(GL11.GL_QUADS);
        GL11.glTexCoord2f(1.0f, 1.0f);
        GL11.glVertex3f(-1.0f, 1.0f, 0.0f);
        GL11.glTexCoord2f(0.0f, 1.0f);
        GL11.glVertex3f(1.0f, 1.0f, 0.0f);
        GL11.glTexCoord2f(0.0f, 0.0f);
        GL11.glVertex3f(1.0f, -1.0f, 0.0f);
        GL11.glTexCoord2f(1.0f, 0.0f);
        GL11.glVertex3f(-1.0f, -1.0f, 0.0f);
        GL11.glEnd();

                
      //release the shader
        ARBShaderObjects.glUseProgramObjectARB(0);

    }

    /*
    * With the exception of syntax, setting up vertex and fragment shaders
    * is the same.
    * @param the name and path to the vertex shader
    */
    private int createVertShader(String filename){
        //vertShader will be non zero if succefully created

        vertShader=ARBShaderObjects.glCreateShaderObjectARB(ARBVertexShader.GL_VERTEX_SHADER_ARB);
        //if created, convert the vertex shader code to a String
        if(vertShader==0){return 0;}
        String vertexCode="";
        String line;
        try{
            BufferedReader reader=new BufferedReader(new FileReader(filename));
            while((line=reader.readLine())!=null){
                vertexCode+=line + "\n";
            }
        }catch(Exception e){
            System.out.println("Fail reading vertex shading code");
            return 0;
        }
        /*
        * associate the vertex code String with the created vertex shader
        * and compile
        */
        ARBShaderObjects.glShaderSourceARB(vertShader, vertexCode);
        ARBShaderObjects.glCompileShaderARB(vertShader);
        //if there was a problem compiling, reset vertShader to zero
        if(!printLogInfo(vertShader)){
            vertShader=0;
        }
        //if zero we won't be using the shader
        return vertShader;
    }

    //same as per the vertex shader except for method syntax
    private int createFragShader(String filename){

        fragShader=ARBShaderObjects.glCreateShaderObjectARB(ARBFragmentShader.GL_FRAGMENT_SHADER_ARB);
        if(fragShader==0){return 0;}
            String fragCode="";
            String line;
        try{
            BufferedReader reader=new BufferedReader(new FileReader(filename));
            while((line=reader.readLine())!=null){
                fragCode+=line + "\n";
            }
        }catch(Exception e){
            System.out.println("Fail reading fragment shading code");
            return 0;
        }
        ARBShaderObjects.glShaderSourceARB(fragShader, fragCode);
        ARBShaderObjects.glCompileShaderARB(fragShader);
        if(!printLogInfo(fragShader)){
            fragShader=0;
        }

        return fragShader;
    }
    
    private static boolean printLogInfo(int obj){
        IntBuffer iVal = BufferUtils.createIntBuffer(1);
        ARBShaderObjects.glGetObjectParameterARB(obj,
        ARBShaderObjects.GL_OBJECT_INFO_LOG_LENGTH_ARB, iVal);

        int length = iVal.get();
        if (length > 1) {
            // We have some info we need to output.
            ByteBuffer infoLog = BufferUtils.createByteBuffer(length);
            iVal.flip();
            ARBShaderObjects.glGetInfoLogARB(obj, iVal, infoLog);
            byte[] infoBytes = new byte[length];
            infoLog.get(infoBytes);
            String out = new String(infoBytes);
            System.out.println("Info log:\n"+out);
        }
        else return true;
        return false;
    }

}
```

Vertex Shader

```
uniform float time;

/*
 * Both 2D and 3D texture coordinates are defined, for testing purposes.
 */
varying vec2 v_texCoord2D;
varying vec3 v_texCoord3D;
varying vec4 v_color;

void main( void )
{
	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

	v_texCoord2D = gl_MultiTexCoord0.xy;
	
	v_color = gl_Color;

}
```

FragShader

```
uniform sampler2D permTexture;
uniform float x;
uniform float y;
uniform float z;

varying vec2 v_texCoord2D;

#define ONE 0.00390625
#define ONEHALF 0.001953125


float fade(float t) {
  // return t*t*(3.0-2.0*t); // Old fade, yields discontinuous second derivative
  return t*t*t*(t*(t*6.0-15.0)+10.0); // Improved fade, yields C2-continuous noise
}


/*
 * 3D classic noise. Slower, but a lot more useful than 2D noise.
 */
float noise(vec3 P)
{
  vec3 Pi = ONE*floor(P)+ONEHALF; // Integer part, scaled so +1 moves one texel
                                  // and offset 1/2 texel to sample texel centers
  vec3 Pf = fract(P);     // Fractional part for interpolation

  // Noise contributions from (x=0, y=0), z=0 and z=1
  float perm00 = texture2D(permTexture, Pi.xy).a ;
  vec3  grad000 = texture2D(permTexture, vec2(perm00, Pi.z)).rgb * 4.0 - 1.0;
  float n000 = dot(grad000, Pf);
  vec3  grad001 = texture2D(permTexture, vec2(perm00, Pi.z + ONE)).rgb * 4.0 - 1.0;
  float n001 = dot(grad001, Pf - vec3(0.0, 0.0, 1.0));

  // Noise contributions from (x=0, y=1), z=0 and z=1
  float perm01 = texture2D(permTexture, Pi.xy + vec2(0.0, ONE)).a ;
  vec3  grad010 = texture2D(permTexture, vec2(perm01, Pi.z)).rgb * 4.0 - 1.0;
  float n010 = dot(grad010, Pf - vec3(0.0, 1.0, 0.0));
  vec3  grad011 = texture2D(permTexture, vec2(perm01, Pi.z + ONE)).rgb * 4.0 - 1.0;
  float n011 = dot(grad011, Pf - vec3(0.0, 1.0, 1.0));

  // Noise contributions from (x=1, y=0), z=0 and z=1
  float perm10 = texture2D(permTexture, Pi.xy + vec2(ONE, 0.0)).a ;
  vec3  grad100 = texture2D(permTexture, vec2(perm10, Pi.z)).rgb * 4.0 - 1.0;
  float n100 = dot(grad100, Pf - vec3(1.0, 0.0, 0.0));
  vec3  grad101 = texture2D(permTexture, vec2(perm10, Pi.z + ONE)).rgb * 4.0 - 1.0;
  float n101 = dot(grad101, Pf - vec3(1.0, 0.0, 1.0));

  // Noise contributions from (x=1, y=1), z=0 and z=1
  float perm11 = texture2D(permTexture, Pi.xy + vec2(ONE, ONE)).a ;
  vec3  grad110 = texture2D(permTexture, vec2(perm11, Pi.z)).rgb * 4.0 - 1.0;
  float n110 = dot(grad110, Pf - vec3(1.0, 1.0, 0.0));
  vec3  grad111 = texture2D(permTexture, vec2(perm11, Pi.z + ONE)).rgb * 4.0 - 1.0;
  float n111 = dot(grad111, Pf - vec3(1.0, 1.0, 1.0));

  // Blend contributions along x
  vec4 n_x = mix(vec4(n000, n001, n010, n011),
                 vec4(n100, n101, n110, n111), fade(Pf.x));

  // Blend contributions along y
  vec2 n_xy = mix(n_x.xy, n_x.zw, fade(Pf.y));

  // Blend contributions along z
  float n_xyz = mix(n_xy.x, n_xy.y, fade(Pf.z));

  // We're done, return the final noise value.
  return n_xyz;
}

void main( void )
{
	float n = noise(vec3(x + v_texCoord2D.x * 4f, y + v_texCoord2D.y * 4f, z));
	gl_FragColor = 0.5 + 0.5 * vec4(n, n, n, n);
}
```

Das Ganze läuft vermutlich in einer handelsüblichen Eclipse + LWJGL Umgebung.

Ich hoffe das hilft.


----------



## Guest2 (30. Nov 2011)

Moin,

ich muss zugeben, dass ich den shader nur überflogen habe. Es scheint mir aber so, das der weitgehend der Implementation von Stefan Gustavson entspricht (~stegu/simplexnoise - noisebench-old3dc.frac im jeweiligen zip). Das Ergebnis wirkt aber tatsächlich etwas unerwartet, ist die permTexture mit sinnvollen Werten gefüllt?

Grundsätzlich sind noise schader auch nicht einfach. Es gibt z.B. (imho seit OpenGL 2.1) in GLSL eine noise[1|2|3|4] Definition, welche aber imho noch von keinem Hersteller implementiert wurde (die geben alle einfach 0 zurück). Zu den verschiedenen Implementationen gibt es auch einen interessanten Thread von Stefan Gustavson auf opengl.org. Viele der dort verlinkten Varianten sind einen Blick wert (insbesondere die, welche ohne texture lookups auskommen).

Viele Grüße,
Fancy

(P.S.: gesehen hab ich ihn schon gestern, nur da hatte ich die Links nicht parat. 
Ein KSKB wäre in der Tat sinnvoll, dann könnte man die einzelnen Implementierungen einfacher ausprobieren.)


----------



## Guest2 (30. Nov 2011)

Ja, da fehlt der ganze Teil zur Erzeugung der perm texture.

Wenn ich das kurz in Dein KSKB rein dengel, sieht das etwa so aus:


```
import java.io.BufferedReader;
import java.io.FileReader;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;

import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.ARBFragmentShader;
import org.lwjgl.opengl.ARBShaderObjects;
import org.lwjgl.opengl.ARBVertexShader;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL20;
import org.lwjgl.util.glu.GLU;


public class Main {

    private static final int viewportWidth  = 1024;
    private static final int viewportHeight = 786;

    private Box              box;


    public static void main(final String[] args) {

        final Main main = new Main();
        main.init();
        main.loop();

    }


    public void init() {

        try {

            Display.setDisplayMode(new DisplayMode(viewportWidth, viewportHeight));
            Display.setVSyncEnabled(true);
            Display.create();

        } catch (final LWJGLException e) {

            e.printStackTrace();
            System.exit(0);

        }

        GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        GL11.glClearDepth(1.0f);

        GL11.glEnable(GL11.GL_DEPTH_TEST);
        GL11.glEnable(GL11.GL_TEXTURE_2D);
        GL11.glEnable(GL11.GL_BLEND);

        GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);

        GL11.glShadeModel(GL11.GL_SMOOTH);
        GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST);

        GL11.glViewport(0, 0, viewportWidth, viewportHeight);

        GL11.glMatrixMode(GL11.GL_PROJECTION);
        GL11.glLoadIdentity();
        GLU.gluPerspective(45.0f, ((float) viewportWidth / (float) viewportHeight), 0.1f, 100.0f);

        GL11.glMatrixMode(GL11.GL_MODELVIEW);
        GL11.glLoadIdentity();

        box = new Box();

    }


    public void loop() {

        while (!Display.isCloseRequested()) {

            GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
            GL11.glLoadIdentity();

            box.draw();

            Display.update();

        }

        Display.destroy();

    }


}


class Box {

    private static final int permTextureUnit = 1;

    private int              shader          = 0;
    private int              vertShader      = 0;
    private int              fragShader      = 0;

    private int              permTextureID   = 0;

    private float            x               = 0f;
    private float            y               = 0f;
    private float            z               = 0f;


    public Box() {

        permTextureID = initPermTexture();

        shader = ARBShaderObjects.glCreateProgramObjectARB();

        if (shader != 0) {

            vertShader = createVertShader("shaders/noise.vert");
            fragShader = createFragShader("shaders/noise.frag");

        }

        if (vertShader != 0 && fragShader != 0) {

            ARBShaderObjects.glAttachObjectARB(shader, vertShader);
            ARBShaderObjects.glAttachObjectARB(shader, fragShader);
            ARBShaderObjects.glLinkProgramARB(shader);
            ARBShaderObjects.glValidateProgramARB(shader);
            printLogInfo(shader);

        }

    }


    public void draw() {

        ARBShaderObjects.glUseProgramObjectARB(shader);

        GL20.glUniform1f(GL20.glGetUniformLocation(shader, "z"), z += 0.01f);
        GL20.glUniform1f(GL20.glGetUniformLocation(shader, "x"), x += 0.01f);
        GL20.glUniform1f(GL20.glGetUniformLocation(shader, "y"), y += 0.01f);

        final int permTextureLocation = GL20.glGetUniformLocation(shader, "permTexture");

        GL13.glActiveTexture(GL13.GL_TEXTURE0 + permTextureUnit);
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, permTextureID);
        GL20.glUniform1i(permTextureLocation, permTextureUnit);


        GL11.glLoadIdentity();
        GL11.glTranslatef(-1.0f, 0.0f, -5.0f);

        GL11.glBegin(GL11.GL_QUADS);
        GL11.glTexCoord2f(1.0f, 1.0f);
        GL11.glVertex3f(-1.0f, 1.0f, 0.0f);
        GL11.glTexCoord2f(0.0f, 1.0f);
        GL11.glVertex3f(1.0f, 1.0f, 0.0f);
        GL11.glTexCoord2f(0.0f, 0.0f);
        GL11.glVertex3f(1.0f, -1.0f, 0.0f);
        GL11.glTexCoord2f(1.0f, 0.0f);
        GL11.glVertex3f(-1.0f, -1.0f, 0.0f);
        GL11.glEnd();

        ARBShaderObjects.glUseProgramObjectARB(0);

    }


    private int initPermTexture() {

        int texID;

        final int perm[] = { 151, 160, 137, 91, 90, 15,
                131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23,
                190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33,
                88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166,
                77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244,
                102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196,
                135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123,
                5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42,
                223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9,
                129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, 228,
                251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, 239, 107,
                49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254,
                138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180 };

        final int grad3[][] = { { 0, 1, 1 }, { 0, 1, -1 }, { 0, -1, 1 }, { 0, -1, -1 },
                { 1, 0, 1 }, { 1, 0, -1 }, { -1, 0, 1 }, { -1, 0, -1 },
                { 1, 1, 0 }, { 1, -1, 0 }, { -1, 1, 0 }, { -1, -1, 0 },
                { 1, 0, -1 }, { -1, 0, -1 }, { 0, -1, 1 }, { 0, 1, 1 } };

        GL13.glActiveTexture(GL13.GL_TEXTURE0 + permTextureUnit);

        texID = GL11.glGenTextures();
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, texID);

        final byte[] pixels = new byte[256 * 256 * 4];
        for (int i = 0; i < 256; i++)
            for (int j = 0; j < 256; j++) {

                final int offset = (i * 256 + j) * 4;
                final byte value = (byte) perm[(j + perm[i]) & 0xFF];
                pixels[offset] = (byte) (grad3[value & 0x0F][0] * 64 + 64);
                pixels[offset + 1] = (byte) (grad3[value & 0x0F][1] * 64 + 64);
                pixels[offset + 2] = (byte) (grad3[value & 0x0F][2] * 64 + 64);
                pixels[offset + 3] = value;

            }

        final ByteBuffer buffer = ByteBuffer.allocateDirect(256 * 256 * 4);
        buffer.put(pixels);
        buffer.rewind();

        GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, 256, 256, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);

        return texID;

    }


    private int createVertShader(final String filename) {

        vertShader = ARBShaderObjects.glCreateShaderObjectARB(ARBVertexShader.GL_VERTEX_SHADER_ARB);

        if (vertShader == 0)
            return 0;

        String vertexCode = "";
        String line;

        try {

            final BufferedReader reader = new BufferedReader(new FileReader(filename));
            while ((line = reader.readLine()) != null)
                vertexCode += line + "\n";

        } catch (final Exception e) {

            System.out.println("Fail reading vertex shading code");
            return 0;

        }

        ARBShaderObjects.glShaderSourceARB(vertShader, vertexCode);
        ARBShaderObjects.glCompileShaderARB(vertShader);

        printLogInfo(vertShader);

        return vertShader;

    }


    private int createFragShader(final String filename) {

        fragShader = ARBShaderObjects.glCreateShaderObjectARB(ARBFragmentShader.GL_FRAGMENT_SHADER_ARB);

        if (fragShader == 0)
            return 0;

        String fragCode = "";
        String line;

        try {

            final BufferedReader reader = new BufferedReader(new FileReader(filename));
            while ((line = reader.readLine()) != null)
                fragCode += line + "\n";

        } catch (final Exception e) {

            System.out.println("Fail reading fragment shading code");
            return 0;

        }
        ARBShaderObjects.glShaderSourceARB(fragShader, fragCode);
        ARBShaderObjects.glCompileShaderARB(fragShader);

        printLogInfo(fragShader);

        return fragShader;
    }


    private void printLogInfo(final int obj) {

        final IntBuffer iVal = BufferUtils.createIntBuffer(1);
        ARBShaderObjects.glGetObjectParameterARB(obj, ARBShaderObjects.GL_OBJECT_INFO_LOG_LENGTH_ARB, iVal);

        final int length = iVal.get();
        if (length > 1) {

            final ByteBuffer infoLog = BufferUtils.createByteBuffer(length);
            iVal.flip();
            ARBShaderObjects.glGetInfoLogARB(obj, iVal, infoLog);
            final byte[] infoBytes = new byte[length];
            infoLog.get(infoBytes);
            final String out = new String(infoBytes);
            System.out.println("Info log:\n" + out);

        }

    }

}
```

Die Fehlerbehandlung, so wie sie oben stand, ist auch nicht ganz korrekt, einige GLSL-Compiler geben auch im Erfolgsfall eine Meldung aus, deshalb ist der ganze Schmu rausgekürzt)

Außerdem vertragen einige Karten das "4f" im Fragmentshader nicht, dann muss die main einfach so aussehen:


```
void main( void )
{
	float n = noise(vec3(x + v_texCoord2D.x * 4, y + v_texCoord2D.y * 4, z));
	gl_FragColor = 0.5 + 0.5 * vec4(n, n, n, n);
}
```

Gruß,
Fancy


----------



## javaPanther (30. Nov 2011)

Oh Mann das ist superklasse ^^ Einige Ergänzungen haben mir auch bei meinen anderen Shadern sehr geholfen und die Tipps übernehme ich gerne.

Vielen Dank dafür!


----------

