first cut at atmospheres in batch (doesn't work)

This commit is contained in:
ZappoMan 2015-06-16 14:05:14 -07:00
parent 03409fa7d8
commit 167e7d1377
9 changed files with 217 additions and 46 deletions

View file

@ -3255,6 +3255,9 @@ namespace render {
template <> const Item::Bound payloadGetBound(const BackgroundRenderData::Pointer& stuff) { return Item::Bound(); }
template <> void payloadRender(const BackgroundRenderData::Pointer& background, RenderArgs* args) {
Q_ASSERT(args->_batch);
gpu::Batch& batch = *args->_batch;
// Background rendering decision
auto skyStage = DependencyManager::get<SceneScriptingInterface>()->getSkyStage();
auto skybox = model::SkyboxPointer();
@ -3322,7 +3325,11 @@ namespace render {
PerformanceTimer perfTimer("atmosphere");
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
"Application::displaySide() ... atmosphere...");
background->_environment->renderAtmospheres(*(args->_viewFrustum));
//gpu::Batch batch;
background->_environment->renderAtmospheres(batch, *(args->_viewFrustum));
//gpu::GLBackend::renderBatch(batch, true);
//glUseProgram(0);
}
}
@ -3333,7 +3340,6 @@ namespace render {
if (skybox) {
gpu::Batch batch;
model::Skybox::render(batch, *(Application::getInstance()->getDisplayViewFrustum()), *skybox);
gpu::GLBackend::renderBatch(batch, true);
glUseProgram(0);
}

View file

@ -28,6 +28,11 @@
#include "Environment.h"
#include "../../build/libraries/model/SkyFromSpace_vert.h"
#include "../../build/libraries/model/SkyFromSpace_frag.h"
#include "../../build/libraries/model/SkyFromAtmosphere_vert.h"
#include "../../build/libraries/model/SkyFromAtmosphere_frag.h"
uint qHash(const HifiSockAddr& sockAddr) {
if (sockAddr.getAddress().isNull()) {
return 0; // shouldn't happen, but if it does, zero is a perfectly valid hash
@ -56,6 +61,15 @@ void Environment::init() {
_skyFromAtmosphereProgram = createSkyProgram("Atmosphere", _skyFromAtmosphereUniformLocations);
_skyFromSpaceProgram = createSkyProgram("Space", _skyFromSpaceUniformLocations);
qDebug() << "line:" << __LINE__;
setupAtmosphereProgram(SkyFromSpace_vert, SkyFromSpace_frag, _newSkyFromSpaceProgram, _newSkyFromSpaceUniformLocations);
qDebug() << "line:" << __LINE__;
setupAtmosphereProgram(SkyFromAtmosphere_vert, SkyFromAtmosphere_frag, _newSkyFromAtmosphereProgram, _newSkyFromAtmosphereUniformLocations);
qDebug() << "line:" << __LINE__;
// start off with a default-constructed environment data
_data[HifiSockAddr()][0];
@ -63,22 +77,84 @@ void Environment::init() {
_initialized = true;
}
void Environment::setupAtmosphereProgram(const char* vertSource, const char* fragSource, gpu::PipelinePointer& pipelineProgram, int* locations) {
auto VS = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(vertSource)));
auto PS = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(fragSource)));
gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(VS, PS));
gpu::Shader::BindingSet slotBindings;
gpu::Shader::makeProgram(*program, slotBindings);
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
state->setCullMode(gpu::State::CULL_NONE);
state->setDepthTest(false);
state->setBlendFunction(true,gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA);
pipelineProgram = gpu::PipelinePointer(gpu::Pipeline::create(program, state));
locations[CAMERA_POS_LOCATION] = program->getUniforms().findLocation("v3CameraPos");
locations[LIGHT_POS_LOCATION] = program->getUniforms().findLocation("v3LightPos");
locations[INV_WAVELENGTH_LOCATION] = program->getUniforms().findLocation("v3InvWavelength");
locations[CAMERA_HEIGHT2_LOCATION] = program->getUniforms().findLocation("fCameraHeight2");
locations[OUTER_RADIUS_LOCATION] = program->getUniforms().findLocation("fOuterRadius");
locations[OUTER_RADIUS2_LOCATION] = program->getUniforms().findLocation("fOuterRadius2");
locations[INNER_RADIUS_LOCATION] = program->getUniforms().findLocation("fInnerRadius");
locations[KR_ESUN_LOCATION] = program->getUniforms().findLocation("fKrESun");
locations[KM_ESUN_LOCATION] = program->getUniforms().findLocation("fKmESun");
locations[KR_4PI_LOCATION] = program->getUniforms().findLocation("fKr4PI");
locations[KM_4PI_LOCATION] = program->getUniforms().findLocation("fKm4PI");
locations[SCALE_LOCATION] = program->getUniforms().findLocation("fScale");
locations[SCALE_DEPTH_LOCATION] = program->getUniforms().findLocation("fScaleDepth");
locations[SCALE_OVER_SCALE_DEPTH_LOCATION] = program->getUniforms().findLocation("fScaleOverScaleDepth");
locations[G_LOCATION] = program->getUniforms().findLocation("g");
locations[G2_LOCATION] = program->getUniforms().findLocation("g2");
/*
program.addShaderFromSourceCode(QGLShader::Vertex, vertSource);
program.addShaderFromSourceCode(QGLShader::Fragment, fragSource);
program.link();
program.bind();
locations[CAMERA_POS_LOCATION] = program.uniformLocation("v3CameraPos");
locations[LIGHT_POS_LOCATION] = program.uniformLocation("v3LightPos");
locations[INV_WAVELENGTH_LOCATION] = program.uniformLocation("v3InvWavelength");
locations[CAMERA_HEIGHT2_LOCATION] = program.uniformLocation("fCameraHeight2");
locations[OUTER_RADIUS_LOCATION] = program.uniformLocation("fOuterRadius");
locations[OUTER_RADIUS2_LOCATION] = program.uniformLocation("fOuterRadius2");
locations[INNER_RADIUS_LOCATION] = program.uniformLocation("fInnerRadius");
locations[KR_ESUN_LOCATION] = program.uniformLocation("fKrESun");
locations[KM_ESUN_LOCATION] = program.uniformLocation("fKmESun");
locations[KR_4PI_LOCATION] = program.uniformLocation("fKr4PI");
locations[KM_4PI_LOCATION] = program.uniformLocation("fKm4PI");
locations[SCALE_LOCATION] = program.uniformLocation("fScale");
locations[SCALE_DEPTH_LOCATION] = program.uniformLocation("fScaleDepth");
locations[SCALE_OVER_SCALE_DEPTH_LOCATION] = program.uniformLocation("fScaleOverScaleDepth");
locations[G_LOCATION] = program.uniformLocation("g");
locations[G2_LOCATION] = program.uniformLocation("g2");
program.release();
*/
}
void Environment::resetToDefault() {
_data.clear();
_data[HifiSockAddr()][0];
}
void Environment::renderAtmospheres(ViewFrustum& camera) {
void Environment::renderAtmospheres(gpu::Batch& batch, ViewFrustum& camera) {
// get the lock for the duration of the call
QMutexLocker locker(&_mutex);
if (_environmentIsOverridden) {
renderAtmosphere(camera, _overrideData);
renderAtmosphere(batch, camera, _overrideData);
} else {
foreach (const ServerData& serverData, _data) {
// TODO: do something about EnvironmentData
foreach (const EnvironmentData& environmentData, serverData) {
renderAtmosphere(camera, environmentData);
renderAtmosphere(batch, camera, environmentData);
}
}
}
@ -228,30 +304,39 @@ ProgramObject* Environment::createSkyProgram(const char* from, int* locations) {
return program;
}
void Environment::renderAtmosphere(ViewFrustum& camera, const EnvironmentData& data) {
void Environment::renderAtmosphere(gpu::Batch& batch, ViewFrustum& camera, const EnvironmentData& data) {
glm::vec3 center = data.getAtmosphereCenter();
glPushMatrix();
glTranslatef(center.x, center.y, center.z);
//glPushMatrix();
//glTranslatef(center.x, center.y, center.z);
Transform transform;
transform.setTranslation(center);
transform.setScale(1.0f);
batch.setModelTransform(transform);
glm::vec3 relativeCameraPos = camera.getPosition() - center;
float height = glm::length(relativeCameraPos);
// use the appropriate shader depending on whether we're inside or outside
ProgramObject* program;
//ProgramObject* program;
int* locations;
if (height < data.getAtmosphereOuterRadius()) {
program = _skyFromAtmosphereProgram;
locations = _skyFromAtmosphereUniformLocations;
//program = &_newSkyFromAtmosphereProgram;
batch.setPipeline(_newSkyFromAtmosphereProgram);
locations = _newSkyFromAtmosphereUniformLocations;
} else {
program = _skyFromSpaceProgram;
locations = _skyFromSpaceUniformLocations;
//program = &_newSkyFromSpaceProgram;
batch.setPipeline(_newSkyFromSpaceProgram);
locations = _newSkyFromSpaceUniformLocations;
}
// the constants here are from Sean O'Neil's GPU Gems entry
// (http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter16.html), GameEngine.cpp
program->bind();
//program->bind();
/*
program->setUniform(locations[CAMERA_POS_LOCATION], relativeCameraPos);
glm::vec3 lightDirection = glm::normalize(data.getSunLocation());
program->setUniform(locations[LIGHT_POS_LOCATION], lightDirection);
@ -273,15 +358,40 @@ void Environment::renderAtmosphere(ViewFrustum& camera, const EnvironmentData& d
(1.0f / (data.getAtmosphereOuterRadius() - data.getAtmosphereInnerRadius())) / 0.25f);
program->setUniformValue(locations[G_LOCATION], -0.990f);
program->setUniformValue(locations[G2_LOCATION], -0.990f * -0.990f);
*/
glDepthMask(GL_FALSE);
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glEnable(GL_BLEND);
DependencyManager::get<GeometryCache>()->renderSphere(1.0f, 100, 50, glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)); //Draw a unit sphere
glDepthMask(GL_TRUE);
batch._glUniform3fv(locations[CAMERA_POS_LOCATION], relativeCameraPos);
glm::vec3 lightDirection = glm::normalize(data.getSunLocation());
batch._glUniform3fv(locations[LIGHT_POS_LOCATION], lightDirection);
batch._glUniform3f(locations[INV_WAVELENGTH_LOCATION],
1 / powf(data.getScatteringWavelengths().r, 4.0f),
1 / powf(data.getScatteringWavelengths().g, 4.0f),
1 / powf(data.getScatteringWavelengths().b, 4.0f));
batch._glUniform1f(locations[CAMERA_HEIGHT2_LOCATION], height * height);
batch._glUniform1f(locations[OUTER_RADIUS_LOCATION], data.getAtmosphereOuterRadius());
batch._glUniform1f(locations[OUTER_RADIUS2_LOCATION], data.getAtmosphereOuterRadius() * data.getAtmosphereOuterRadius());
batch._glUniform1f(locations[INNER_RADIUS_LOCATION], data.getAtmosphereInnerRadius());
batch._glUniform1f(locations[KR_ESUN_LOCATION], data.getRayleighScattering() * data.getSunBrightness());
batch._glUniform1f(locations[KM_ESUN_LOCATION], data.getMieScattering() * data.getSunBrightness());
batch._glUniform1f(locations[KR_4PI_LOCATION], data.getRayleighScattering() * 4.0f * PI);
batch._glUniform1f(locations[KM_4PI_LOCATION], data.getMieScattering() * 4.0f * PI);
batch._glUniform1f(locations[SCALE_LOCATION], 1.0f / (data.getAtmosphereOuterRadius() - data.getAtmosphereInnerRadius()));
batch._glUniform1f(locations[SCALE_DEPTH_LOCATION], 0.25f);
batch._glUniform1f(locations[SCALE_OVER_SCALE_DEPTH_LOCATION],
(1.0f / (data.getAtmosphereOuterRadius() - data.getAtmosphereInnerRadius())) / 0.25f);
batch._glUniform1f(locations[G_LOCATION], -0.990f);
batch._glUniform1f(locations[G2_LOCATION], -0.990f * -0.990f);
//glDepthMask(GL_FALSE);
//glDisable(GL_DEPTH_TEST);
//glDisable(GL_CULL_FACE);
//glEnable(GL_BLEND);
DependencyManager::get<GeometryCache>()->renderSphere(batch,1.0f, 100, 50, glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)); //Draw a unit sphere
//glDepthMask(GL_TRUE);
program->release();
//program->release();
glPopMatrix();
//glPopMatrix();
}

View file

@ -16,6 +16,9 @@
#include <QMutex>
#include <HifiSockAddr.h>
#include <gpu/Batch.h>
#include <ProgramObject.h>
#include "EnvironmentData.h"
@ -29,7 +32,7 @@ public:
void init();
void resetToDefault();
void renderAtmospheres(ViewFrustum& camera);
void renderAtmospheres(gpu::Batch& batch, ViewFrustum& camera);
void override(const EnvironmentData& overrideData) { _overrideData = overrideData; _environmentIsOverridden = true; }
void endOverride() { _environmentIsOverridden = false; }
@ -46,12 +49,12 @@ private:
ProgramObject* createSkyProgram(const char* from, int* locations);
void renderAtmosphere(ViewFrustum& camera, const EnvironmentData& data);
void renderAtmosphere(gpu::Batch& batch, ViewFrustum& camera, const EnvironmentData& data);
bool _initialized;
ProgramObject* _skyFromAtmosphereProgram;
ProgramObject* _skyFromSpaceProgram;
enum {
CAMERA_POS_LOCATION,
LIGHT_POS_LOCATION,
@ -74,6 +77,14 @@ private:
int _skyFromAtmosphereUniformLocations[LOCATION_COUNT];
int _skyFromSpaceUniformLocations[LOCATION_COUNT];
void setupAtmosphereProgram(const char* vertSource, const char* fragSource, gpu::PipelinePointer& pipelineProgram, int* locations);
gpu::PipelinePointer _newSkyFromAtmosphereProgram;
gpu::PipelinePointer _newSkyFromSpaceProgram;
int _newSkyFromAtmosphereUniformLocations[LOCATION_COUNT];
int _newSkyFromSpaceUniformLocations[LOCATION_COUNT];
typedef QHash<int, EnvironmentData> ServerData;

View file

@ -150,6 +150,7 @@ public:
void _glUseProgram(GLuint program);
void _glUniform1f(GLint location, GLfloat v0);
void _glUniform2f(GLint location, GLfloat v0, GLfloat v1);
void _glUniform3f(GLint location, GLfloat v0, GLfloat v1);
void _glUniform4fv(GLint location, GLsizei count, const GLfloat* value);
void _glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
@ -210,6 +211,7 @@ public:
COMMAND_glUseProgram,
COMMAND_glUniform1f,
COMMAND_glUniform2f,
COMMAND_glUniform3f,
COMMAND_glUniform4fv,
COMMAND_glUniformMatrix4fv,

View file

@ -61,6 +61,7 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
(&::gpu::GLBackend::do_glUseProgram),
(&::gpu::GLBackend::do_glUniform1f),
(&::gpu::GLBackend::do_glUniform2f),
(&::gpu::GLBackend::do_glUniform3f),
(&::gpu::GLBackend::do_glUniform4fv),
(&::gpu::GLBackend::do_glUniformMatrix4fv),
@ -462,6 +463,7 @@ void Batch::_glUniform2f(GLint location, GLfloat v0, GLfloat v1) {
DO_IT_NOW(_glUniform2f, 1);
}
void GLBackend::do_glUniform2f(Batch& batch, uint32 paramOffset) {
if (_pipeline._program == 0) {
// We should call updatePipeline() to bind the program but we are not doing that
@ -475,6 +477,32 @@ void GLBackend::do_glUniform2f(Batch& batch, uint32 paramOffset) {
(void) CHECK_GL_ERROR();
}
void Batch::_glUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) {
ADD_COMMAND_GL(glUniform3f);
_params.push_back(v2);
_params.push_back(v1);
_params.push_back(v0);
_params.push_back(location);
DO_IT_NOW(_glUniform3f, 1);
}
void GLBackend::do_glUniform3f(Batch& batch, uint32 paramOffset) {
if (_pipeline._program == 0) {
// We should call updatePipeline() to bind the program but we are not doing that
// because these uniform setters are deprecated and we don;t want to create side effect
return;
}
glUniform3f(
batch._params[paramOffset + 3]._int,
batch._params[paramOffset + 2]._float,
batch._params[paramOffset + 1]._float,
batch._params[paramOffset + 0]._float);
(void) CHECK_GL_ERROR();
}
void Batch::_glUniform4fv(GLint location, GLsizei count, const GLfloat* value) {
ADD_COMMAND_GL(glUniform4fv);

View file

@ -51,7 +51,8 @@ uniform vec3 v3LightPos;
uniform float g;
uniform float g2;
varying vec3 position;
varying vec3 myPosition;
float scale(float fCos)
{
@ -59,10 +60,11 @@ float scale(float fCos)
return fScaleDepth * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25))));
}
void main (void)
{
// Get the ray from the camera to the vertex, and its length (which is the far point of the ray passing through the atmosphere)
vec3 v3Pos = position;
vec3 v3Pos = myPosition;
vec3 v3Ray = v3Pos - v3CameraPos;
float fFar = length(v3Ray);
v3Ray /= fFar;

View file

@ -33,6 +33,9 @@
// Copyright (c) 2004 Sean O'Neil
//
<@include gpu/Transform.slh@>
<$declareStandardTransform()$>
uniform vec3 v3CameraPos; // The camera's current position
uniform vec3 v3LightPos; // The direction vector to the light source
uniform vec3 v3InvWavelength; // 1 / pow(wavelength, 4) for the red, green, and blue channels
@ -50,19 +53,19 @@ uniform float fScaleOverScaleDepth; // fScale / fScaleDepth
const int nSamples = 2;
const float fSamples = 2.0;
varying vec3 position;
varying vec3 myPosition;
float scale(float fCos)
{
float x = 1.0 - fCos;
return fScaleDepth * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25))));
}
void main(void)
{
// Get the ray from the camera to the vertex, and its length (which is the far point of the ray passing through the atmosphere)
position = gl_Vertex.xyz * fOuterRadius;
myPosition = gl_Vertex.xyz * fOuterRadius;
gl_Position = gl_ModelViewProjectionMatrix * vec4(position, 1.0);
//gl_Position = gl_ModelViewProjectionMatrix * vec4(position, 1.0);
// standard transform
TransformCamera cam = getTransformCamera();
TransformObject obj = getTransformObject();
vec4 v4pos = vec4(myPosition, 1.0);
<$transformModelToClipPos(cam, obj, v4pos, gl_Position)$>
}

View file

@ -53,7 +53,7 @@ uniform float g2;
const int nSamples = 2;
const float fSamples = 2.0;
varying vec3 position;
varying vec3 myPosition;
float scale(float fCos)
{
@ -65,7 +65,7 @@ float scale(float fCos)
void main (void)
{
// Get the ray from the camera to the vertex and its length (which is the far point of the ray passing through the atmosphere)
vec3 v3Pos = position;
vec3 v3Pos = myPosition;
vec3 v3Ray = v3Pos - v3CameraPos;
float fFar = length(v3Ray);
v3Ray /= fFar;

View file

@ -1,5 +1,6 @@
#version 120
<@include gpu/Config.slh@>
<$VERSION_HEADER$>
// Generated on <$_SCRIBE_DATE$>
//
// For licensing information, see http://http.developer.nvidia.com/GPUGems/gpugems_app01.html:
//
@ -32,12 +33,20 @@
// Copyright (c) 2004 Sean O'Neil
//
<@include gpu/Transform.slh@>
<$declareStandardTransform()$>
uniform float fOuterRadius; // The outer (atmosphere) radius
varying vec3 position;
varying vec3 myPosition;
void main(void)
{
position = gl_Vertex.xyz * fOuterRadius;
gl_Position = gl_ModelViewProjectionMatrix * vec4(position, 1.0);
}
void main(void) {
myPosition = gl_Vertex.xyz * fOuterRadius;
// standard transform
TransformCamera cam = getTransformCamera();
TransformObject obj = getTransformObject();
vec4 v4pos = vec4(myPosition, 1.0);
<$transformModelToClipPos(cam, obj, v4pos, gl_Position)$>
}