我有興趣學習如何在OpenGL着色語言中編寫toon shaders。我發現了一個demo,但一直未能在我的電腦上運行該演示程序。我遇到的麻煩是編寫將使用此着色器的應用程序。有人請告訴我如何寫一個簡單的應用程序這將使用這個着色器?我在Linux上使用GLSL 1.2(OpenGL 2.1)。在GLSL中使用OpenGL的Toon着色器
8
A
回答
11
這裏是主草圖:
/*
* 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;
}
下面是所用的GLSL類:
/*
* 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);
}
}
而GLSL代碼, 頂點着色器: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;
}
和片段着色器: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;
}
如果有幫助,here是壓縮的Processing項目。一旦你安裝了處理,解壓到默認的文件處理的文件夾(〜/文檔/處理),並運行處理>應該在文件顯示>寫生
這裏是截圖:
HTH
更新
處理現在提供了一個很好PShader class and comprehensive tutorial。 它incluses一個卡通着色器:
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
謝謝!但沒有鏈接到zip文件... – 2011-04-26 20:55:56
+0
@本安德森哎呀!現在修復:) – 2011-04-26 21:17:05
相關問題
- 1. C++在OpenGL着色器(GLSL)位標誌
- 2. OpenGL渲染不使用OpenCV的GLSL着色器
- 3. 使用lines_adjacency的GLSL幾何着色器
- 4. 在OpenGL引擎中組織GLSL着色器
- 5. 在opengl着色器中使用emscripten
- 6. openGL的GLSL着色器:在平坦的多邊形
- 7. 你如何測試用GLSL編寫的OpenGL着色器?
- 8. 使用帶GLSL着色器的紋理適用於使用OpenGL ES 2的iOS
- 9. GLSL:頂點着色器無片段着色片段着色器
- 10. OpenGL着色器?
- 11. 使用OpenGL着色器語言編寫簡單的着色器
- 12. 傳遞一個變量到OpenGL的GLSL着色器
- 13. Vulkan中的實例化GLSL着色器?
- 14. 在GLSL頂點着色器中使用正確的座標系
- 15. 使用CL-的OpenGL着色器
- 16. 使用glVertexAttribPointer的OpenGL着色器
- 17. OpenGL VBO着色器
- 18. Android中的着色器在OpenGL ES中
- 19. 爲什麼OpenGL + GLSL着色器不輸出任何內容?
- 20. 使用GLSL着色器在PyOpenGL中進行多紋理化
- 21. 在GLSL着色器中使用小查找表
- 22. 通用GLSL照明着色器
- 23. 如何在使用iPhone SDK的OpenGL ES中使用着色器
- 24. 在着色器中設置矢量,它是如何工作的? OpenGL GLSL
- 25. 如何編寫通用GLSL着色器來着色對象
- 26. opengl着色器使顏色「消失」
- 27. OpenGL - 對glDrawElements使用着色器
- 28. 的OpenGL着色器輸入
- 29. 在片段着色器(iOS 5 + OpenGL ES 2.0)中優化GLSL代碼
- 30. GLSL將着色的法線傳遞給着色器
「一直沒能得到我的計算機上運行演示」 ,你做了什麼,它怎麼沒有工作? – genpfault 2011-04-26 20:35:41