2011-04-26 37 views
8

Estoy interesado en aprender a escribir toon shaders en OpenGL Shading Language. Encontré un demo, pero no he podido ejecutar la demostración en mi computadora. El problema que estoy teniendo es escribir una aplicación que usará este sombreador. ¿Podría alguien por favor mostrarme cómo escribir una aplicación simple que usaría este sombreador? Estoy usando GLSL 1.2 (OpenGL 2.1) en Linux.Uso de OpenGL Toon Shader en GLSL

+2

"no han sido capaces de conseguir la demo que se ejecuta en el ordenador" , ¿qué hiciste y cómo no funcionó? – genpfault

Respuesta

11

Aquí está el boceto principal:

/* 
* Use keys 1 - 8 to play with different GLUT Solids 
* mouse affects light position 
* Toon Shader by Philip Rideout: 
* http://www.lighthouse3d.com/opengl/glsl/index.php?toon2 
*/ 
import processing.opengl.*; 
import javax.media.opengl.*; 
import javax.media.opengl.glu.*; 
import com.sun.opengl.util.*; 

PGraphicsOpenGL pgl; 
GL gl; 
GLSL toon; 
GLU glu; 
GLUT glut; 
boolean glInit; 
int glutSolidIndex = 7; 

void setup() 
{ 
    size(600, 500, OPENGL); 

    glu = new GLU(); 
    glut = new GLUT(); 

    pgl = (PGraphicsOpenGL) g; 
    gl = pgl.gl; 
} 

void draw() 
{ 
    background(0); 
    PGraphicsOpenGL pgl = (PGraphicsOpenGL) g; 
    GL gl = pgl.beginGL(); 

    if(!glInit){ 
    toon=new GLSL(); 
    toon.loadVertexShader("toon.vs"); 
    toon.loadFragmentShader("toon.fs"); 
    toon.useShaders(); 

    glInit = true; 
    } 

    gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT); 

//TRS 
    gl.glTranslatef(width * .5, height * .5,0.0f); 
    gl.glRotatef(160,1,0,0); 
    gl.glRotatef(frameCount * .5,0,1,0); 
    gl.glRotatef(frameCount * .5,0,0,1); 
    gl.glScalef(80,80,80); 
    // draw 
    toon.startShader(); 
    toon.uniform3f(toon.getUniformLocation("LightPosition"), mouseX-width*.5, -(mouseY-height*.5), 20.0f); 
    gl.glColor3f(1.0f, 0.5f, 0.0f); 
    glutSolid(); 
    toon.endShader(); 

    pgl.endGL(); 
} 

void glutSolid(){ 
switch(glutSolidIndex){ 
    case 0: 
    glut.glutSolidCube(1); 
    break; 
    case 1: 
    glut.glutSolidTetrahedron(); 
    break; 
    case 2: 
    glut.glutSolidOctahedron(); 
    break; 
    case 3: 
    glut.glutSolidDodecahedron(); 
    break; 
    case 4: 
    glut.glutSolidIcosahedron(); 
    break; 
    case 5: 
    glut.glutSolidSphere(1,16,8); 
    break; 
    case 6: 
    glut.glutSolidTorus(.5,1,32,24); 
    break; 
    case 7: 
    glut.glutSolidTeapot(1); 
    break; 
} 
} 
void keyPressed(){ 
    if((int)key >= 49 && (int)key <= 56) glutSolidIndex = (int)(key) - 49; 
} 

Aquí es la clase GLSL utilizado:

/* 
* Class posted by JohnG on the Processing forums: 
* http://processing.org/discourse/yabb2/YaBB.pl?board=OpenGL;action=display;num=1159494801 
* check it out for more details 
*/ 
import processing.opengl.*; 
import javax.media.opengl.*; 
import java.nio.IntBuffer; 
import java.nio.ByteBuffer; 
import com.sun.opengl.util.BufferUtil; 

class GLSL 
{ 
    int programObject; 
    GL gl; 
    boolean vertexShaderEnabled; 
    boolean vertexShaderSupported; 
    int vs; 
    int fs; 

    GLSL() 
    { 
    PGraphicsOpenGL pgl = (PGraphicsOpenGL) g; 
    gl = pgl.gl; 
    //gl=((PGraphicsGL)g).gl; 
    String extensions = gl.glGetString(GL.GL_EXTENSIONS); 
    vertexShaderSupported = extensions.indexOf("GL_ARB_vertex_shader") != -1; 
    vertexShaderEnabled = true;  
    programObject = gl.glCreateProgramObjectARB(); 
    vs=-1; 
    fs=-1; 
    } 

    void loadVertexShader(String file) 
    { 
    String shaderSource=join(loadStrings(file),"\n"); 
    vs = gl.glCreateShaderObjectARB(GL.GL_VERTEX_SHADER_ARB); 
    gl.glShaderSourceARB(vs, 1, new String[]{ 
     shaderSource } 
    ,(int[]) null, 0); 
    gl.glCompileShaderARB(vs); 
    checkLogInfo(gl, vs); 
    gl.glAttachObjectARB(programObject, vs); 
    } 

    void loadFragmentShader(String file) 
    { 
    String shaderSource=join(loadStrings(file),"\n"); 
    fs = gl.glCreateShaderObjectARB(GL.GL_FRAGMENT_SHADER_ARB); 
    gl.glShaderSourceARB(fs, 1, new String[]{ 
     shaderSource } 
    ,(int[]) null, 0); 
    gl.glCompileShaderARB(fs); 
    checkLogInfo(gl, fs); 
    gl.glAttachObjectARB(programObject, fs); 
    } 

    int getAttribLocation(String name) 
    { 
    return(gl.glGetAttribLocationARB(programObject,name)); 
    } 

    int getUniformLocation(String name) 
    { 
    return(gl.glGetUniformLocationARB(programObject,name)); 
    } 

    void useShaders() 
    { 
    gl.glLinkProgramARB(programObject); 
    gl.glValidateProgramARB(programObject); 
    checkLogInfo(gl, programObject); 
    } 

    void startShader() 
    { 
    gl.glUseProgramObjectARB(programObject); 
    } 

    void endShader() 
    { 
    gl.glUseProgramObjectARB(0); 
    } 

    void checkLogInfo(GL gl, int obj) 
    { 
    IntBuffer iVal = BufferUtil.newIntBuffer(1); 
    gl.glGetObjectParameterivARB(obj, GL.GL_OBJECT_INFO_LOG_LENGTH_ARB, iVal); 

    int length = iVal.get(); 
    if (length <= 1) 
    { 
     return; 
    } 
    ByteBuffer infoLog = BufferUtil.newByteBuffer(length); 
    iVal.flip(); 
    gl.glGetInfoLogARB(obj, length, iVal, infoLog); 
    byte[] infoBytes = new byte[length]; 
    infoLog.get(infoBytes); 
    println("GLSL Validation >> " + new String(infoBytes)); 
    } 

    void uniform3f(int location, float v0, float v1, float v2) 
    { 
    gl.glUniform3fARB(location, v0, v1, v2); 
    } 

    void uniform1i(int location, int v0) 
    { 
    gl.glUniform1iARB(location, v0); 
    } 

} 

Y el código GLSL, el vertex shader: toon.vs

// 
// Vertex shader for cartoon-style shading 
// 
// Author: Philip Rideout 
// 
// Copyright (c) 2005-2006 3Dlabs Inc. Ltd. 
// 
// See 3Dlabs-License.txt for license information 
// 

varying vec3 Normal; 

void main(void) 
{ 
    Normal = normalize(gl_NormalMatrix * gl_Normal); 
    #ifdef __GLSL_CG_DATA_TYPES // Fix clipping for Nvidia and ATI 
    gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex; 
    #endif 
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; 
} 

Y el fragmento sombreador: toon.fs

/* http://www.lighthouse3d.com/opengl/glsl/index.php?toon2 */ 

varying vec3 Normal; 

uniform vec3 LightPosition;// = vec3(10.0, 10.0, 20.0); 

void main() 
{ 
    vec4 color1 = gl_FrontMaterial.diffuse; 
    vec4 color2; 

    float intensity = dot(normalize(LightPosition),Normal); 

    if (intensity > 0.95)  color2 = vec4(1.0, 1.0, 1.0, 1.0); 
    else if (intensity > 0.75) color2 = vec4(0.8, 0.8, 0.8, 1.0); 
    else if (intensity > 0.50) color2 = vec4(0.6, 0.6, 0.6, 1.0); 
    else if (intensity > 0.25) color2 = vec4(0.4, 0.4, 0.4, 1.0); 
    else      color2 = vec4(0.2, 0.2, 0.2, 1.0); 

    gl_FragColor = color1 * color2; 
} 

Si ayuda, here es el proyecto de procesamiento comprimido. Una vez que haya instalado procesamiento, descomprimir el archivo en la carpeta de procesamiento por defecto (~/Documentos/Procesamiento) y ejecutar producción> debe mostrar en Archivo> Sketchbook

Y aquí una muestra: GLSL toon shader example

HTH

actualización

Procesamiento ahora proporciona un buen PShader class and comprehensive tutorial. Se Incluses un sombreado Toon:

PShader toon; 

void setup() { 
    size(640, 360, P3D); 
    noStroke(); 
    fill(204); 
    toon = loadShader("ToonFrag.glsl", "ToonVert.glsl"); 
    toon.set("fraction", 1.0); 
} 

void draw() { 
    shader(toon); 
    background(0); 
    float dirY = (mouseY/float(height) - 0.5) * 2; 
    float dirX = (mouseX/float(width) - 0.5) * 2; 
    directionalLight(204, 204, 204, -dirX, -dirY, -1); 
    translate(width/2, height/2); 
    sphere(120); 
} 

ToonVert.glsl:

uniform mat4 transform; 
uniform mat3 normalMatrix; 
uniform vec3 lightNormal; 

attribute vec4 vertex; 
attribute vec4 color; 
attribute vec3 normal; 

varying vec4 vertColor; 
varying vec3 vertNormal; 
varying vec3 vertLightDir; 

void main() { 
    gl_Position = transform * vertex; 
    vertColor = color; 
    vertNormal = normalize(normalMatrix * normal); 
    vertLightDir = -lightNormal; 
} 

ToonFrag.glsl:

#ifdef GL_ES 
precision mediump float; 
precision mediump int; 
#endif 

#define PROCESSING_LIGHT_SHADER 

uniform float fraction; 

varying vec4 vertColor; 
varying vec3 vertNormal; 
varying vec3 vertLightDir; 

void main() { 
    float intensity; 
    vec4 color; 
    intensity = max(0.0, dot(vertLightDir, vertNormal)); 

    if (intensity > pow(0.95, fraction)) { 
    color = vec4(vec3(1.0), 1.0); 
    } else if (intensity > pow(0.5, fraction)) { 
    color = vec4(vec3(0.6), 1.0); 
    } else if (intensity > pow(0.25, fraction)) { 
    color = vec4(vec3(0.4), 1.0); 
    } else { 
    color = vec4(vec3(0.2), 1.0); 
    } 

    gl_FragColor = color * vertColor; 
} 
+0

Gracias! pero no hay ningún enlace al archivo zip ... –

+0

@Ben Anderson ¡Vaya! arreglado eso ahora :) –

Cuestiones relacionadas