0
쉐이더의 서브 루틴을 Phong에서 Diffuse 조명으로 "전환"하는 데 어려움을 겪고 있습니다. 그러나 모든 기능이 항상 내 쉐이더에서 항상 호출되도록 선언되었습니다.LWJGL GLSL 서브 루틴이 변경되지 않습니다
는 여기에 내가
sub1 = GL40.glGetSubroutineIndex(programID, GL20.GL_VERTEX_SHADER, "diffuseOnly");
sub2 = GL40.glGetSubroutineIndex(programID, GL20.GL_VERTEX_SHADER, "phongModel");
는 각각 0과 1의 위치를 생산하는이 단지 GLdrawelements 전에 내 렌더링 방법에 내 쉐이더
#version 430
subroutine vec3 shadeModelType(vec4 position, vec3 normal);
subroutine uniform shadeModelType shadeModel;
layout (location = 0) in vec3 VertexPosition;
layout (location = 1) in vec3 VertexNormal;
out vec3 LightIntensity;
struct LightInfo {
vec4 Position; // Light position in eye coords.
vec3 La; // Ambient light intensity
vec3 Ld; // Diffuse light intensity
vec3 Ls; // Specular light intensity
};
uniform LightInfo Light;
struct MaterialInfo {
vec3 Ka; // Ambient reflectivity
vec3 Kd; // Diffuse reflectivity
vec3 Ks; // Specular reflectivity
float Shininess; // Specular shininess factor
};
uniform MaterialInfo Material;
uniform mat4 viewMatrix;
uniform mat4 transformationMatrix;
uniform mat3 normalMatrix;
uniform mat4 ProjectionMatrix;
void getEyeSpace(out vec3 norm, out vec4 position)
{
norm = normalize( mat3(transpose(inverse(viewMatrix *transformationMatrix))) *
VertexNormal);
position = viewMatrix * transformationMatrix * vec4(VertexPosition,1.0);
}
subroutine(shadeModelType)
vec3 phongModel(vec4 position, vec3 norm)
{
vec3 s = normalize(vec3(Light.Position - position));
vec3 v = normalize(-position.xyz);
vec3 r = reflect(-s, norm);
vec3 ambient = Light.La * Material.Ka;
float sDotN = max(dot(s,norm), 0.0);
vec3 diffuse = Light.Ld * Material.Kd * sDotN;
vec3 spec = vec3(0.0);
if(sDotN > 0.0)
spec = Light.Ls * Material.Ks *
pow(max(dot(r,v), 0.0), Material.Shininess);
return ambient + diffuse + spec;
}
subroutine(shadeModelType)
vec3 diffuseOnly(vec4 position, vec3 norm)
{
vec3 s = normalize(vec3(Light.Position - position));
return
Light.Ld * Material.Kd * max(dot(s, norm), 0.0);
}
void main()
{
mat4 modelViewProject = ProjectionMatrix * viewMatrix *transformationMatrix ;
mat4 normalMatrix = transpose(inverse(viewMatrix *transformationMatrix));
vec3 eyeNorm;
vec4 eyePosition;
// Get the position and normal in eye space
getEyeSpace(eyeNorm, eyePosition);
// Evaluate the shading equation. This will call one of
// the functions: diffuseOnly or phongModel.
LightIntensity = shadeModel(eyePosition, eyeNorm);
gl_Position = modelViewProject * vec4(VertexPosition,1.0);
}
입니다.
int routineUniform = GL40.glGetSubroutineUniformLocation(programID,
GL20.GL_VERTEX_SHADER, "shadeModel");
IntBuffer subroutineBuffer = BufferUtils.createIntBuffer(1).put(sub1);
System.out.println(routineUniform); //produces a 0;
System.out.println(GL40.glGetProgramStagei(programID,
GL20.GL_VERTEX_SHADER, GL40.GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS));
//prints 1;
GL40.glUniformSubroutinesu(GL20.GL_VERTEX_SHADER, subroutineBuffer);
버퍼 utils.createIntBuffer (2)를 시도하고 두 가지를 모두 넣었으므로 2 개의 별도의 int 버퍼를 만들었습니다. 사실 sub1과 sub2 위치를 완전히 제거했으며 기본값은 선언 된 첫 번째 함수로 돌아갑니다.
와우가 완전히 옳습니다. 매력처럼 작동합니다. 문제를 단순히 subroutineBuffer.flip(); 당신이 원하는 루틴을 넣은 후 그것을 전환합니다!. 감사 Brian 좋은 추수 감사절!. –