一个对象上的两个着色器

时间:2015-12-02 16:31:40

标签: c++ opengl rendering shader

我的一个对象上有多个着色器的问题。 那是我的渲染代码:

#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();
    */
}

ambient 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;
}

ambient 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);
}

定向光.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 个答案:

答案 0 :(得分: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)并启用所有相同的顶点设置和深度测试时,两个绘制调用中的一个将胜过另一个。

另外,更重要的是,绘图调用不会“堆叠”。你只是简单地通过多次绘制相同的东西就无法组合着色器;它可能对添加剂过程起作用。但那是在错误的树上咆哮:你没有保存额外的工作,而是重复了要完成的工作量。

您应该做的是将两个着色器合并为单个着色器,并使用合并的着色器仅绘制一次几何体。