2015-12-02 4 views
-1

У меня проблема с многократными шейдерами на моем одном объекте. Это мой визуализации код:Два шейдера на одном объекте

#include "MeshRenderer.h" 

ForwardAmbient* shader1; 
ForwardDirectional* shader2; 

MeshRenderer::MeshRenderer(Obj& obj) : 
    meshObject(obj) 
{ 
    shader1 = new ForwardAmbient(vec3(1, 1, 1)); 
    shader2 = new ForwardDirectional(vec3(1, 0, 0), vec3(1, 1, 1)); 
} 

MeshRenderer::~MeshRenderer() 
{ 

} 

void MeshRenderer::Render(RenderingCore* rc) 
{ 
    //for (Shader* shader : meshObject.shaders) 
    //{ 

    //} 

    shader1->Bind(); 
    shader1->UpdateShader(rc, transform, meshObject.material); 
    meshObject.material->GetTexture()->Bind(0); 
    meshObject.mesh->Render(); 

    shader2->Bind(); 
    shader2->UpdateShader(rc, transform, meshObject.material); 
    meshObject.material->GetTexture()->Bind(0); 
    meshObject.mesh->Render(); 

    /* 
    meshObject.shader->Bind(); 
    meshObject.shader->UpdateShader(rc, transform, meshObject.material); 
    meshObject.material->GetTexture()->Bind(0); 
    meshObject.mesh->Render(); 
    */ 
} 

окружающей среды light.vs:

#version 120 
attribute vec3 position; 
attribute vec2 texCoord; 
attribute vec3 normal; 

varying vec2 texCoord0; 

uniform mat4 transform; 
uniform mat4 projection; 

void main() 
{ 
    gl_Position = (projection * transform) * vec4(position, 1); 
    texCoord0 = texCoord; 
} 

окружающей среды light.fs:

#version 120 

varying vec2 texCoord0; 

uniform vec3 ambientLight; 
uniform float alpha; 
uniform sampler2D sampler; 

void main() 
{ 
    gl_FragColor = texture2D(sampler, texCoord0.xy) * vec4(ambientLight, alpha); 
} 

направленного light.vs

#version 120 

attribute vec3 position; 
attribute vec2 texCoord; 
attribute vec3 normal; 

varying vec2 texCoord0; 
varying vec3 normal0; 
varying vec3 worldPos0; 

uniform mat4 transform; 
uniform mat4 projection; 

void main() 
{ 
    gl_Position = (projection * transform) * vec4(position, 1); 
    texCoord0 = texCoord; 
    normal0 = (transform * vec4(normal, 0)).xyz; 
    worldPos0 = (transform * vec4(position, 1)).xyz; 
} 

направленного света .fs

#version 120 

varying vec2 texCoord0; 
varying vec3 normal0; 
varying vec3 worldPos0; 

uniform vec3 color; 
uniform float alpha; 

uniform vec3 direction; 
uniform float specularIntensity; 
uniform float specularPower; 
uniform vec3 eyePosition; 

uniform sampler2D sampler; 

vec4 calcLight(vec3 color, float alpha, vec3 direction, vec3 normal) 
{ 
    float diffuseFactor = dot(normal, -direction); 

    vec4 diffuseColor = vec4(0,0,0,0); 
    vec4 specularColor = vec4(0,0,0,0); 

    if(diffuseFactor > 0) 
    { 
     diffuseColor = vec4(color, 1.0) * diffuseFactor; 

     vec3 directionToEye = normalize(eyePosition - worldPos0); 
     vec3 reflectDirection = normalize(reflect(direction, normal)); 

     float specularFactor = dot(directionToEye, reflectDirection); 
     specularFactor = pow(specularFactor, specularPower); 

     if(specularFactor > 0) 
     { 
      specularColor = vec4(color, 1.0) * specularIntensity * specularFactor; 
     } 
    } 

    return diffuseColor + specularColor; 
} 

vec4 calcDirectionalLight(vec3 color, float alpha, vec3 direction, vec3 normal) 
{ 
    return calcLight(color, alpha, -direction, normal); 
} 

void main() 
{ 
    gl_FragColor = texture2D(sampler, texCoord0.xy) *  calcDirectionalLight(color, 1, direction, normalize(normal0)); 
} 

Вот результат: http://imgur.com/Bawny2P только окружающий свет рендер, направленный свет не

+1

Какие библиотеки вы используете? Похоже, у вас есть два отдельных прохода рендеринга в вашей функции «Render». Похоже, вы предполагаете, что множественные вызовы 'mesh-> Render()' приведут к какой-то агрегации отдельных эффектов шейдера, но я не могу представить, чтобы это было так. –

+0

У вас включено смешение? – BDL

+0

@OpenKastle Я использую библиотеку OpenGL, glew и glfw. BDL Да, glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); – MisterVento3

ответ

1

Ваша проблема не в этом:

shader1->Bind(); 
shader1->UpdateShader(rc, transform, meshObject.material); 
meshObject.material->GetTexture()->Bind(0); 
meshObject.mesh->Render(); 

shader2->Bind(); 
shader2->UpdateShader(rc, transform, meshObject.material); 
meshObject.material->GetTexture()->Bind(0); 
meshObject.mesh->Render(); 

OpenGL не знает, что «объект» есть. Он просто рисует точки, линии и треугольники, по одному за раз. Для определения глубины перекрытия используется метод буфера глубины. Когда вы используете точно такой же вызов рисования (meshObject.mesh->Render) с включенной настройкой и глубиной тестирования вершин, один из двух вызовов рисования будет побеждать над другим.

Кроме того, что еще более важно, призывы вызова не «складываются». Вы просто не можете комбинировать шейдеры просто, рисуя одно и то же несколько раз; это может быть характер работы для аддитивных процессов. Но это лает неправильное дерево: вместо экономии дополнительной работы вы дублируете объем работы.

Вместо этого вы должны слить два шейдера в один и нарисовать геометрию только один раз, с объединенным шейдером.

+0

Спасибо, я исправить это, но у меня есть новая проблема, как исправить этот направленный свет: http://imgur.com/uLEtoVF, мой код: http://pastebin.com/6xyzERqC – MisterVento3

+0

@ MisterVento3: Выглядит не как шейдер но как проблема геометрии. То, что появляется на вашем изображении, обычно является причиной использования общих вершин, т. Е. С использованием одной и той же вершины для всех трех граней куба, с которыми она граничит. Вершина - это весь кортеж '[position, normal, ...]', и если вы измените только один бит if, вы имеете дело с совершенно другой вершиной. И нормаль различается для каждой грани куба, поэтому у вас разные вершины. – datenwolf

Смежные вопросы