Wie ein GLSL Shader-Parameter in Bearbeitung ändern
-
13-09-2019 - |
Frage
Ich spiele mit Shadern in openGL Verarbeitung. Ich bin mir ziemlich Noob in diesem und ein wenig verloren.
Ich fand diesen Thread , das ein Beispiel hat, wie man verwenden GLSL Shadern in Bearbeitung.
Ich versuche nur auf die Änderung LightPosition Parameter im Shader ich verwende. Ich weiß nicht, wie es aber zuzugreifen.
Hier ist mein Code so weit:
import processing.opengl.*;
import javax.media.opengl.*;
import javax.media.opengl.glu.*;
import com.sun.opengl.util.*;
PGraphicsOpenGL pgl;
GL gl;
GLSL glsl;
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){
glsl=new GLSL();
glsl.loadVertexShader("toon.vs");
glsl.loadFragmentShader("toon.fs");
glsl.useShaders();
gl.glEnable(GL.GL_DEPTH_TEST);
gl.glDepthFunc(GL.GL_LESS);
gl.glShadeModel(GL.GL_SMOOTH);
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
glsl.startShader();
gl.glColor3f(1.0f, 0.5f, 0.0f);
gl.glFrontFace(gl.GL_CW);
glutSolid();
gl.glFrontFace(gl.GL_CCW);
glsl.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,8,6);
break;
case 6:
glut.glutSolidTorus(1,1.5,8,6);
break;
case 7:
glut.glutSolidTeapot(1);
break;
}
}
void keyPressed(){
if((int)key >= 49 && (int)key <= 56) glutSolidIndex = (int)(key) - 49;
}
die GLSL-Klasse sieht wie folgt aus:
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));
}
}
Und ich bin mit dem Toon Shader geschrieben von Philip Rideout von 3Dlabs.
Dies ist die Vertex-Shader:
// 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;
}
und hier sind die Fragment-Shader:
/* http://www.lighthouse3d.com/opengl/glsl/index.php?toon2 */
varying vec3 Normal;
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;
}
Für Hinweise hilfreich sein.
Lösung
Ihr Problem ist, dass LightPosition nicht als einheitliches erklärt. Es sollte wie folgt deklariert werden:
uniform vec3 LightPosition;
Fügen Sie diese auf die GLSL-Klasse:
void uniform3f(int location, float v0, float v1, float v2)
{
gl.glUniform3fARB(location, v0, v1, v2);
}
Sie müssen jetzt tatsächlich den LightPosition Parameter initialisieren. Nach startShader()
, aber bevor Sie glutSolid()
nennen, dies zu tun:
glsl.uniform3f(glsl.getUniformLocation("LightPosition"), 10.0, 10.0, 20.0);
Das sollte funktionieren (es für mich gearbeitet).
Andere Tipps
ich nicht Verarbeitung verwenden, sind in C, aber Sie würden etwas tun:
GLint lightPos = glGetUniformLocation(shaderHandle, "LightPosition");
glUniform3f(lightPos, 5.0f, 5.0f, 5.0f);