STKMesh: Use forward rendering for transparent
Transparent objects may be double sided (like bubble), it doesn't make sense to use a deferred renderer.
This commit is contained in:
parent
f3a9b24880
commit
a67f5bf511
@ -20,14 +20,17 @@
|
||||
#version 130
|
||||
uniform mat4 ModelViewProjectionMatrix;
|
||||
uniform float time;
|
||||
|
||||
in vec3 Position;
|
||||
in vec2 Texcoord;
|
||||
out vec2 uv;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = ModelViewProjectionMatrix * gl_Vertex;
|
||||
gl_Position = ModelViewProjectionMatrix * vec4(Position, 1.);
|
||||
|
||||
float delta_x = cos(time*3.0) * sin( 4.0 * gl_TexCoord[0].st.s * 6.28318531 );
|
||||
float delta_y = cos(time*2.0) * sin( 3.0 * gl_TexCoord[0].st.t * 6.28318531 );
|
||||
float delta_x = cos(time*3.0) * sin( 4.0 * Texcoord.x * 6.28318531 );
|
||||
float delta_y = cos(time*2.0) * sin( 3.0 * Texcoord.y * 6.28318531 );
|
||||
|
||||
uv = gl_MultiTexCoord0.st + vec2(0.02*delta_x, 0.02*delta_y);
|
||||
uv = Texcoord + vec2(0.02*delta_x, 0.02*delta_y);
|
||||
}
|
||||
|
@ -16,5 +16,5 @@ void main(void)
|
||||
vec3 SpecularComponent = texture(SpecularMap, tc).xyz;
|
||||
float ao = texture(SSAO, tc).x;
|
||||
vec3 LightFactor = ao * ambient + DiffuseComponent + SpecularComponent * (1. - color.a);
|
||||
FragColor = vec4(color.xyz * LightFactor, color.a);
|
||||
FragColor = vec4(color.xyz * LightFactor, 1.);
|
||||
}
|
||||
|
@ -17,5 +17,5 @@ void main(void)
|
||||
vec3 SpecularComponent = texture(SpecularMap, tc).xyz;
|
||||
float ao = texture(SSAO, tc).x;
|
||||
vec3 LightFactor = ao * ambient + DiffuseComponent + SpecularComponent;
|
||||
FragColor = vec4(color.xyz * LightFactor, color.a);
|
||||
FragColor = vec4(color.xyz * LightFactor, 1.);
|
||||
}
|
||||
|
10
data/shaders/transparent.frag
Normal file
10
data/shaders/transparent.frag
Normal file
@ -0,0 +1,10 @@
|
||||
#version 130
|
||||
uniform sampler2D tex;
|
||||
|
||||
in vec2 uv;
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = texture(tex, uv);
|
||||
}
|
12
data/shaders/transparent.vert
Normal file
12
data/shaders/transparent.vert
Normal file
@ -0,0 +1,12 @@
|
||||
#version 130
|
||||
uniform mat4 ModelViewProjectionMatrix;
|
||||
|
||||
in vec3 Position;
|
||||
in vec2 Texcoord;
|
||||
out vec2 uv;
|
||||
|
||||
void main()
|
||||
{
|
||||
uv = Texcoord;
|
||||
gl_Position = ModelViewProjectionMatrix * vec4(Position, 1.);
|
||||
}
|
@ -301,18 +301,11 @@ void IrrDriver::renderGLSL(float dt)
|
||||
}
|
||||
|
||||
// We need to re-render camera due to the per-cam-node hack.
|
||||
PROFILER_PUSH_CPU_MARKER("- Transparent Pass 1", 0xFF, 0x00, 0x00);
|
||||
irr_driver->setPhase(0);
|
||||
PROFILER_PUSH_CPU_MARKER("- Transparent Pass", 0xFF, 0x00, 0x00);
|
||||
m_renderpass = scene::ESNRP_CAMERA | scene::ESNRP_TRANSPARENT;
|
||||
m_scene_manager->drawAll(m_renderpass);
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
|
||||
PROFILER_PUSH_CPU_MARKER("- Transparent Pass 2", 0xFF, 0x00, 0x00);
|
||||
irr_driver->setPhase(1);
|
||||
m_renderpass = scene::ESNRP_CAMERA | scene::ESNRP_TRANSPARENT;
|
||||
m_scene_manager->drawAll(m_renderpass);
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
|
||||
PROFILER_PUSH_CPU_MARKER("- Particles", 0xFF, 0x00, 0x00);
|
||||
m_renderpass = scene::ESNRP_CAMERA | scene::ESNRP_TRANSPARENT_EFFECT;
|
||||
m_scene_manager->drawAll(m_renderpass);
|
||||
|
@ -246,6 +246,8 @@ void Shaders::loadShaders()
|
||||
MeshShader::SplattingShader::init();
|
||||
MeshShader::GrassPass1Shader::init();
|
||||
MeshShader::GrassPass2Shader::init();
|
||||
MeshShader::BubbleShader::init();
|
||||
MeshShader::TransparentShader::init();
|
||||
}
|
||||
|
||||
Shaders::~Shaders()
|
||||
@ -574,6 +576,53 @@ namespace MeshShader
|
||||
glUniform3f(uniform_ambient, s.r, s.g, s.b);
|
||||
}
|
||||
|
||||
GLuint BubbleShader::Program;
|
||||
GLuint BubbleShader::attrib_position;
|
||||
GLuint BubbleShader::attrib_texcoord;
|
||||
GLuint BubbleShader::uniform_MVP;
|
||||
GLuint BubbleShader::uniform_tex;
|
||||
GLuint BubbleShader::uniform_time;
|
||||
GLuint BubbleShader::uniform_transparency;
|
||||
|
||||
void BubbleShader::init()
|
||||
{
|
||||
Program = LoadProgram(file_manager->getAsset("shaders/bubble.vert").c_str(), file_manager->getAsset("shaders/bubble.frag").c_str());
|
||||
attrib_position = glGetAttribLocation(Program, "Position");
|
||||
attrib_texcoord = glGetAttribLocation(Program, "Texcoord");
|
||||
uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix");
|
||||
uniform_tex = glGetUniformLocation(Program, "tex");
|
||||
uniform_time = glGetUniformLocation(Program, "time");
|
||||
uniform_transparency = glGetUniformLocation(Program, "transparency");
|
||||
}
|
||||
void BubbleShader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, unsigned TU_tex, float time, float transparency)
|
||||
{
|
||||
glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer());
|
||||
glUniform1i(uniform_tex, TU_tex);
|
||||
glUniform1f(uniform_time, time);
|
||||
glUniform1f(uniform_transparency, transparency);
|
||||
}
|
||||
|
||||
GLuint TransparentShader::Program;
|
||||
GLuint TransparentShader::attrib_position;
|
||||
GLuint TransparentShader::attrib_texcoord;
|
||||
GLuint TransparentShader::uniform_MVP;
|
||||
GLuint TransparentShader::uniform_tex;
|
||||
|
||||
void TransparentShader::init()
|
||||
{
|
||||
Program = LoadProgram(file_manager->getAsset("shaders/transparent.vert").c_str(), file_manager->getAsset("shaders/transparent.frag").c_str());
|
||||
attrib_position = glGetAttribLocation(Program, "Position");
|
||||
attrib_texcoord = glGetAttribLocation(Program, "Texcoord");
|
||||
uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix");
|
||||
uniform_tex = glGetUniformLocation(Program, "tex");
|
||||
}
|
||||
|
||||
void TransparentShader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, unsigned TU_tex)
|
||||
{
|
||||
glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer());
|
||||
glUniform1i(uniform_tex, TU_tex);
|
||||
}
|
||||
|
||||
GLuint ColorizeShader::Program;
|
||||
GLuint ColorizeShader::attrib_position;
|
||||
GLuint ColorizeShader::uniform_MVP;
|
||||
|
@ -125,6 +125,29 @@ public:
|
||||
static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, unsigned TU_tex_layout, unsigned TU_tex_detail0, unsigned TU_tex_detail1, unsigned TU_tex_detail2, unsigned TU_tex_detail3, unsigned TU_DiffuseMap, unsigned TU_SpecularMap, unsigned TU_SSAO);
|
||||
};
|
||||
|
||||
class BubbleShader
|
||||
{
|
||||
public:
|
||||
static GLuint Program;
|
||||
static GLuint attrib_position, attrib_texcoord;
|
||||
static GLuint uniform_MVP, uniform_tex, uniform_time, uniform_transparency;
|
||||
|
||||
static void init();
|
||||
static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, unsigned TU_tex, float time, float transparency);
|
||||
};
|
||||
|
||||
class TransparentShader
|
||||
{
|
||||
public:
|
||||
static GLuint Program;
|
||||
static GLuint attrib_position, attrib_texcoord;
|
||||
static GLuint uniform_MVP, uniform_tex;
|
||||
|
||||
static void init();
|
||||
static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, unsigned TU_tex);
|
||||
};
|
||||
|
||||
|
||||
class ColorizeShader
|
||||
{
|
||||
public:
|
||||
|
@ -415,7 +415,59 @@ void STKMesh::drawGlow(const GLMesh &mesh, float r, float g, float b)
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
void STKMesh::draw(const GLMesh &mesh, video::E_MATERIAL_TYPE type, bool isTransparent)
|
||||
void STKMesh::drawTransparentObject(const GLMesh &mesh)
|
||||
{
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
|
||||
computeMVP(ModelViewProjectionMatrix);
|
||||
setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR);
|
||||
|
||||
glUseProgram(MeshShader::TransparentShader::Program);
|
||||
MeshShader::TransparentShader::setUniforms(ModelViewProjectionMatrix, 0);
|
||||
|
||||
glBindVertexArray(mesh.vao_first_pass);
|
||||
glDrawElements(ptype, count, itype, 0);
|
||||
}
|
||||
|
||||
void STKMesh::drawBubble(const GLMesh &mesh)
|
||||
{
|
||||
const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f;
|
||||
float transparency = 1.;
|
||||
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
|
||||
computeMVP(ModelViewProjectionMatrix);
|
||||
setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR);
|
||||
|
||||
glUseProgram(MeshShader::BubbleShader::Program);
|
||||
MeshShader::BubbleShader::setUniforms(ModelViewProjectionMatrix, 0, time, transparency);
|
||||
|
||||
glBindVertexArray(mesh.vao_first_pass);
|
||||
glDrawElements(ptype, count, itype, 0);
|
||||
}
|
||||
|
||||
void STKMesh::drawTransparent(const GLMesh &mesh, video::E_MATERIAL_TYPE type)
|
||||
{
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
glDepthMask(GL_FALSE);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
if (type == video::EMT_TRANSPARENT_ALPHA_CHANNEL)
|
||||
drawTransparentObject(mesh);
|
||||
if (type == irr_driver->getShader(ES_BUBBLES))
|
||||
drawBubble(mesh);
|
||||
return;
|
||||
}
|
||||
|
||||
void STKMesh::drawSolid(const GLMesh &mesh, video::E_MATERIAL_TYPE type)
|
||||
{
|
||||
|
||||
if (!mesh.textures[0])
|
||||
@ -440,9 +492,6 @@ void STKMesh::draw(const GLMesh &mesh, video::E_MATERIAL_TYPE type, bool isTrans
|
||||
drawGrassPass1(mesh);
|
||||
else
|
||||
drawObjectPass1(mesh);
|
||||
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glStencilFunc(GL_ALWAYS, 1, ~0);
|
||||
irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getMainSetup(), false, false);
|
||||
break;
|
||||
@ -451,23 +500,11 @@ void STKMesh::draw(const GLMesh &mesh, video::E_MATERIAL_TYPE type, bool isTrans
|
||||
{
|
||||
irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false);
|
||||
|
||||
if (isTransparent)
|
||||
{
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
glDepthMask(GL_FALSE);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
else
|
||||
{
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
glDepthMask(GL_FALSE);
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
glDepthMask(GL_FALSE);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
if (type == irr_driver->getShader(ES_SPHERE_MAP))
|
||||
drawSphereMap(mesh);
|
||||
else if (type == irr_driver->getShader(ES_SPLATTING))
|
||||
@ -478,9 +515,6 @@ void STKMesh::draw(const GLMesh &mesh, video::E_MATERIAL_TYPE type, bool isTrans
|
||||
drawGrassPass2(mesh);
|
||||
else
|
||||
drawObjectPass2(mesh);
|
||||
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
@ -490,14 +524,6 @@ void STKMesh::draw(const GLMesh &mesh, video::E_MATERIAL_TYPE type, bool isTrans
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
video::SMaterial material;
|
||||
material.MaterialType = irr_driver->getShader(ES_RAIN);
|
||||
material.BlendOperation = video::EBO_NONE;
|
||||
material.ZWriteEnable = true;
|
||||
material.Lighting = false;
|
||||
irr_driver->getVideoDriver()->setMaterial(material);
|
||||
static_cast<irr::video::COpenGLDriver*>(irr_driver->getVideoDriver())->setRenderStates3DMode();
|
||||
}
|
||||
|
||||
static bool isObject(video::E_MATERIAL_TYPE type)
|
||||
@ -516,6 +542,8 @@ static bool isObject(video::E_MATERIAL_TYPE type)
|
||||
return true;
|
||||
if (type == irr_driver->getShader(ES_GRASS_REF))
|
||||
return true;
|
||||
if (type == irr_driver->getShader(ES_BUBBLES))
|
||||
return true;
|
||||
if (type == video::EMT_TRANSPARENT_ALPHA_CHANNEL)
|
||||
return true;
|
||||
return false;
|
||||
@ -540,6 +568,16 @@ static void initvaostate(GLMesh &mesh, video::E_MATERIAL_TYPE type)
|
||||
mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::GrassPass1Shader::attrib_position, MeshShader::GrassPass1Shader::attrib_texcoord, -1, MeshShader::GrassPass1Shader::attrib_normal, -1, -1, MeshShader::GrassPass1Shader::attrib_color, mesh.Stride);
|
||||
}
|
||||
else if (type == irr_driver->getShader(ES_BUBBLES))
|
||||
{
|
||||
mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::BubbleShader::attrib_position, MeshShader::BubbleShader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride);
|
||||
}
|
||||
else if (type == video::EMT_TRANSPARENT_ALPHA_CHANNEL)
|
||||
{
|
||||
mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::TransparentShader::attrib_position, MeshShader::TransparentShader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride);
|
||||
}
|
||||
else
|
||||
{
|
||||
mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
@ -604,7 +642,19 @@ void STKMesh::render()
|
||||
if (isObject(material.MaterialType) && isTransparentPass == transparent)
|
||||
{
|
||||
initvaostate(GLmeshes[i], material.MaterialType);
|
||||
draw(GLmeshes[i], material.MaterialType, transparent);
|
||||
if (transparent)
|
||||
drawTransparent(GLmeshes[i], material.MaterialType);
|
||||
else
|
||||
drawSolid(GLmeshes[i], material.MaterialType);
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
video::SMaterial material;
|
||||
material.MaterialType = irr_driver->getShader(ES_RAIN);
|
||||
material.BlendOperation = video::EBO_NONE;
|
||||
material.ZWriteEnable = true;
|
||||
material.Lighting = false;
|
||||
irr_driver->getVideoDriver()->setMaterial(material);
|
||||
static_cast<irr::video::COpenGLDriver*>(irr_driver->getVideoDriver())->setRenderStates3DMode();
|
||||
}
|
||||
else if (transparent == isTransparentPass)
|
||||
{
|
||||
|
@ -27,7 +27,8 @@ protected:
|
||||
std::vector<GLMesh> GLmeshes;
|
||||
core::matrix4 ModelViewProjectionMatrix, TransposeInverseModelView;
|
||||
core::vector3df windDir;
|
||||
void draw(const GLMesh &mesh, video::E_MATERIAL_TYPE type, bool isTransparent);
|
||||
void drawSolid(const GLMesh &mesh, video::E_MATERIAL_TYPE type);
|
||||
void drawTransparent(const GLMesh &mesh, video::E_MATERIAL_TYPE type);
|
||||
|
||||
// Pass 1 shader (ie shaders that outputs normals and depth)
|
||||
void drawObjectPass1(const GLMesh &mesh);
|
||||
@ -42,6 +43,10 @@ protected:
|
||||
void drawObjectRefPass2(const GLMesh &mesh);
|
||||
void drawGrassPass2(const GLMesh &mesh);
|
||||
|
||||
// Forward pass (for transparents meshes)
|
||||
void drawTransparentObject(const GLMesh &mesh);
|
||||
void drawBubble(const GLMesh &mesh);
|
||||
|
||||
// Pass 3 shader (glow)
|
||||
void drawGlow(const GLMesh &mesh, float r, float g, float b);
|
||||
public:
|
||||
|
Loading…
Reference in New Issue
Block a user