Working on getting particles/entities to work with deferred lighting;

normalize normals from buffer.
This commit is contained in:
Andrzej Kapolka 2014-09-15 16:07:48 -07:00
parent 467a9582c7
commit 0f3a020b5d
12 changed files with 135 additions and 24 deletions

View file

@ -42,7 +42,7 @@ void main(void) {
// get the normal from the map
vec4 normal = texture2D(normalMap, gl_TexCoord[0].st);
vec4 normalizedNormal = normal * 2.0 - vec4(1.0, 1.0, 1.0, 2.0);
vec4 normalizedNormal = normalize(normal * 2.0 - vec4(1.0, 1.0, 1.0, 2.0));
// compute the base color based on OpenGL lighting model
float diffuse = dot(normalizedNormal, gl_LightSource[0].position);

View file

@ -56,7 +56,7 @@ void main(void) {
// get the normal from the map
vec4 normal = texture2D(normalMap, gl_TexCoord[0].st);
vec4 normalizedNormal = normal * 2.0 - vec4(1.0, 1.0, 1.0, 2.0);
vec4 normalizedNormal = normalize(normal * 2.0 - vec4(1.0, 1.0, 1.0, 2.0));
// average values from the shadow map
float diffuse = dot(normalizedNormal, gl_LightSource[0].position);

View file

@ -51,7 +51,7 @@ void main(void) {
// get the normal from the map
vec4 normal = texture2D(normalMap, gl_TexCoord[0].st);
vec4 normalizedNormal = normal * 2.0 - vec4(1.0, 1.0, 1.0, 2.0);
vec4 normalizedNormal = normalize(normal * 2.0 - vec4(1.0, 1.0, 1.0, 2.0));
// average values from the shadow map
float diffuse = dot(normalizedNormal, gl_LightSource[0].position);

View file

@ -0,0 +1,22 @@
#version 120
//
// simple.frag
// fragment shader
//
// Created by Andrzej Kapolka on 9/15/14.
// Copyright 2014 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
// the interpolated normal
varying vec4 normal;
void main(void) {
// set the diffuse, normal, specular data
gl_FragData[0] = vec4(gl_Color.rgb, 0.0);
gl_FragData[1] = normalize(normal) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0);
gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb, gl_FrontMaterial.shininess / 128.0);
}

View file

@ -0,0 +1,26 @@
#version 120
//
// simple.vert
// vertex shader
//
// Created by Andrzej Kapolka on 9/15/14.
// Copyright 2014 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
// the interpolated normal
varying vec4 normal;
void main(void) {
// transform and store the normal for interpolation
normal = normalize(gl_ModelViewMatrix * vec4(gl_Normal, 0.0));
// pass along the diffuse color
gl_FrontColor = gl_Color;
// use standard pipeline transform
gl_Position = ftransform();
}

View file

@ -2844,15 +2844,19 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
glutSolidSphere(originSphereRadius, 15, 15);
glPopMatrix();
// disable specular lighting for ground and voxels
glMaterialfv(GL_FRONT, GL_SPECULAR, NO_SPECULAR_COLOR);
// draw the audio reflector overlay
{
PerformanceTimer perfTimer("audio");
_audioReflector.render();
}
if (Menu::getInstance()->isOptionChecked(MenuOption::BuckyBalls)) {
PerformanceTimer perfTimer("buckyBalls");
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
"Application::displaySide() ... bucky balls...");
_buckyBalls.render();
}
// Draw voxels
if (Menu::getInstance()->isOptionChecked(MenuOption::Voxels)) {
PerformanceTimer perfTimer("voxels");
@ -2869,13 +2873,6 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
_metavoxels.render();
}
if (Menu::getInstance()->isOptionChecked(MenuOption::BuckyBalls)) {
PerformanceTimer perfTimer("buckyBalls");
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
"Application::displaySide() ... bucky balls...");
_buckyBalls.render();
}
// render particles...
if (Menu::getInstance()->isOptionChecked(MenuOption::Particles)) {
PerformanceTimer perfTimer("particles");
@ -2892,9 +2889,6 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
_entities.render();
}
// restore default, white specular
glMaterialfv(GL_FRONT, GL_SPECULAR, WORLD_SPECULAR_COLOR);
// render the ambient occlusion effect if enabled
if (Menu::getInstance()->isOptionChecked(MenuOption::AmbientOcclusion)) {
PerformanceTimer perfTimer("ambientOcclusion");

View file

@ -50,7 +50,7 @@ void RenderableBoxEntityItem::render(RenderArgs* args) {
glm::vec3 positionToCenter = center - position;
glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z);
glScalef(dimensions.x, dimensions.y, dimensions.z);
glutSolidCube(1.0f);
Application::getInstance()->getDeferredLightingEffect()->renderSolidCube(1.0f);
glPopMatrix();
glPopMatrix();
} else {
@ -86,6 +86,8 @@ void RenderableBoxEntityItem::render(RenderArgs* args) {
glColor3ub(getColor()[RED_INDEX], getColor()[GREEN_INDEX], getColor()[BLUE_INDEX]);
Application::getInstance()->getDeferredLightingEffect()->bindSimpleProgram();
glPushMatrix();
glTranslatef(position.x, position.y, position.z);
glm::vec3 axis = glm::axis(rotation);
@ -99,6 +101,8 @@ void RenderableBoxEntityItem::render(RenderArgs* args) {
glPopMatrix();
glPopMatrix();
Application::getInstance()->getDeferredLightingEffect()->releaseSimpleProgram();
glDisableClientState(GL_VERTEX_ARRAY); // disable vertex arrays
glDisableClientState(GL_NORMAL_ARRAY);
}

View file

@ -125,7 +125,7 @@ void RenderableModelEntityItem::render(RenderArgs* args) {
glColor3ub(getColor()[RED_INDEX],getColor()[GREEN_INDEX],getColor()[BLUE_INDEX]);
glPushMatrix();
glTranslatef(position.x, position.y, position.z);
glutWireCube(size);
Application::getInstance()->getDeferredLightingEffect()->renderWireCube(size);
glPopMatrix();
}
} else {
@ -133,7 +133,7 @@ void RenderableModelEntityItem::render(RenderArgs* args) {
glColor3ub(getColor()[RED_INDEX],getColor()[GREEN_INDEX],getColor()[BLUE_INDEX]);
glPushMatrix();
glTranslatef(position.x, position.y, position.z);
glutWireCube(size);
Application::getInstance()->getDeferredLightingEffect()->renderWireCube(size);
glPopMatrix();
}
}
@ -142,7 +142,7 @@ void RenderableModelEntityItem::render(RenderArgs* args) {
glColor3ub(getColor()[RED_INDEX],getColor()[GREEN_INDEX],getColor()[BLUE_INDEX]);
glPushMatrix();
glTranslatef(position.x, position.y, position.z);
glutWireCube(size);
Application::getInstance()->getDeferredLightingEffect()->renderWireCube(size);
glPopMatrix();
}
}

View file

@ -48,7 +48,7 @@ void RenderableSphereEntityItem::render(RenderArgs* args) {
glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z);
glScalef(dimensions.x, dimensions.y, dimensions.z);
glutSolidSphere(0.5f, 15, 15);
Application::getInstance()->getDeferredLightingEffect()->renderSolidSphere(0.5f, 15, 15);
glPopMatrix();
glPopMatrix();
};

View file

@ -11,6 +11,7 @@
#include <glm/gtx/quaternion.hpp>
#include "Application.h"
#include "InterfaceConfig.h"
#include "ParticleTreeRenderer.h"
@ -112,7 +113,7 @@ void ParticleTreeRenderer::renderElement(OctreeElement* element, RenderArgs* arg
if (wantDebugSphere) {
glPushMatrix();
glTranslatef(position.x, position.y, position.z);
glutWireSphere(radius, 15, 15);
Application::getInstance()->getDeferredLightingEffect()->renderWireSphere(radius, 15, 15);
glPopMatrix();
}
@ -120,7 +121,7 @@ void ParticleTreeRenderer::renderElement(OctreeElement* element, RenderArgs* arg
} else {
glPushMatrix();
glTranslatef(position.x, position.y, position.z);
glutSolidSphere(radius, 15, 15);
Application::getInstance()->getDeferredLightingEffect()->renderSolidSphere(radius, 15, 15);
glPopMatrix();
}
}

View file

@ -19,6 +19,10 @@
#include "RenderUtil.h"
void DeferredLightingEffect::init() {
_simpleProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/simple.vert");
_simpleProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + "shaders/simple.frag");
_simpleProgram.link();
loadLightProgram("shaders/directional_light.frag", _directionalLight, _directionalLightLocations);
loadLightProgram("shaders/directional_light_shadow_map.frag", _directionalLightShadowMap,
_directionalLightShadowMapLocations);
@ -26,6 +30,42 @@ void DeferredLightingEffect::init() {
_directionalLightCascadedShadowMapLocations);
}
void DeferredLightingEffect::bindSimpleProgram() {
Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, true, true);
_simpleProgram.bind();
glDisable(GL_BLEND);
}
void DeferredLightingEffect::releaseSimpleProgram() {
glEnable(GL_BLEND);
_simpleProgram.release();
Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false, false);
}
void DeferredLightingEffect::renderSolidSphere(float radius, int slices, int stacks) {
bindSimpleProgram();
glutSolidSphere(radius, slices, stacks);
releaseSimpleProgram();
}
void DeferredLightingEffect::renderWireSphere(float radius, int slices, int stacks) {
bindSimpleProgram();
glutWireSphere(radius, slices, stacks);
releaseSimpleProgram();
}
void DeferredLightingEffect::renderSolidCube(float size) {
bindSimpleProgram();
glutSolidCube(size);
releaseSimpleProgram();
}
void DeferredLightingEffect::renderWireCube(float size) {
bindSimpleProgram();
glutWireCube(size);
releaseSimpleProgram();
}
void DeferredLightingEffect::prepare() {
// clear the normal and specular buffers
Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(false, true, false);

View file

@ -24,6 +24,28 @@ public:
void init();
/// Returns a reference to a simple program suitable for rendering static
/// untextured geometry (such as that generated by glutSolidSphere, etc.)
ProgramObject& getSimpleProgram() { return _simpleProgram; }
/// Sets up the state necessary to render static untextured geometry with the simple program.
void bindSimpleProgram();
/// Tears down the state necessary to render static untextured geometry with the simple program.
void releaseSimpleProgram();
//// Renders a solid sphere with the simple program.
void renderSolidSphere(float radius, int slices, int stacks);
//// Renders a wireframe sphere with the simple program.
void renderWireSphere(float radius, int slices, int stacks);
//// Renders a solid cube with the simple program.
void renderSolidCube(float size);
//// Renders a wireframe cube with the simple program.
void renderWireCube(float size);
/// Adds an object to render after performing the deferred lighting for the current frame (e.g., a translucent object).
void addPostLightingRenderable(PostLightingRenderable* renderable) { _postLightingRenderables.append(renderable); }
@ -43,7 +65,9 @@ private:
};
static void loadLightProgram(const char* name, ProgramObject& program, LightLocations& locations);
ProgramObject _simpleProgram;
ProgramObject _directionalLight;
LightLocations _directionalLightLocations;
ProgramObject _directionalLightShadowMap;