mirror of
https://github.com/lubosz/overte.git
synced 2025-04-16 09:29:16 +02:00
trying to put the atmospheric effect in a shader header and use it on the directional lighting pass
This commit is contained in:
parent
ee5409b0a8
commit
d9c071a2a9
8 changed files with 406 additions and 3 deletions
|
@ -44,7 +44,7 @@ protected:
|
|||
friend class Backend;
|
||||
};
|
||||
|
||||
typedef QSharedPointer< Pipeline > PipelinePointer;
|
||||
typedef std::shared_ptr< Pipeline > PipelinePointer;
|
||||
typedef std::vector< PipelinePointer > Pipelines;
|
||||
|
||||
};
|
||||
|
|
244
libraries/model/src/model/Atmosphere.slh
Executable file
244
libraries/model/src/model/Atmosphere.slh
Executable file
|
@ -0,0 +1,244 @@
|
|||
<!
|
||||
// Atmospheric.slh
|
||||
//
|
||||
// Created by Sam Gateau on 3/9/15.
|
||||
// Copyright 2015 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
|
||||
!>
|
||||
<@if not MODEL_ATMOSPHERE_SLH@>
|
||||
<@def MODEL_ATMOSPHERE_SLH@>
|
||||
|
||||
<!
|
||||
// Code is a modified version of:
|
||||
// http://http.developer.nvidia.com/GPUGems/gpugems_app01.html
|
||||
// Atmospheric scattering fragment shader
|
||||
//
|
||||
// Author: Sean O'Neil
|
||||
//
|
||||
// Copyright (c) 2004 Sean O'Neil
|
||||
|
||||
//
|
||||
// For licensing information, see http://http.developer.nvidia.com/GPUGems/gpugems_app01.html:
|
||||
//
|
||||
// NVIDIA Statement on the Software
|
||||
//
|
||||
// The source code provided is freely distributable, so long as the NVIDIA header remains unaltered and user modifications are
|
||||
// detailed.
|
||||
//
|
||||
// No Warranty
|
||||
//
|
||||
// THE SOFTWARE AND ANY OTHER MATERIALS PROVIDED BY NVIDIA ON THE ENCLOSED CD-ROM ARE PROVIDED "AS IS." NVIDIA DISCLAIMS ALL
|
||||
// WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
//
|
||||
// Limitation of Liability
|
||||
//
|
||||
// NVIDIA SHALL NOT BE LIABLE TO ANY USER, DEVELOPER, DEVELOPER'S CUSTOMERS, OR ANY OTHER PERSON OR ENTITY CLAIMING THROUGH OR
|
||||
// UNDER DEVELOPER FOR ANY LOSS OF PROFITS, INCOME, SAVINGS, OR ANY OTHER CONSEQUENTIAL, INCIDENTAL, SPECIAL, PUNITIVE, DIRECT
|
||||
// OR INDIRECT DAMAGES (WHETHER IN AN ACTION IN CONTRACT, TORT OR BASED ON A WARRANTY), EVEN IF NVIDIA HAS BEEN ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF THE ESSENTIAL PURPOSE OF ANY
|
||||
// LIMITED REMEDY. IN NO EVENT SHALL NVIDIA'S AGGREGATE LIABILITY TO DEVELOPER OR ANY OTHER PERSON OR ENTITY CLAIMING THROUGH
|
||||
// OR UNDER DEVELOPER EXCEED THE AMOUNT OF MONEY ACTUALLY PAID BY DEVELOPER TO NVIDIA FOR THE SOFTWARE OR ANY OTHER MATERIALS.
|
||||
//
|
||||
!>
|
||||
|
||||
struct Atmosphere {
|
||||
vec4 _invWaveLength;
|
||||
vec4 _radiuses;
|
||||
vec4 _scales;
|
||||
vec4 _scatterings;
|
||||
vec4 _control;
|
||||
};
|
||||
|
||||
const int numSamples = 2;
|
||||
|
||||
vec3 getAtmosphereInvWaveLength(Atmosphere a) { return a._invWaveLength.xyz; } // 1 / pow(wavelength, 4) for the red, green, and blue channels
|
||||
|
||||
float getAtmosphereInnerRadius(Atmosphere a) { return a._radiuses.x; } // The inner (planetary) radius
|
||||
float getAtmosphereOuterRadius(Atmosphere a) { return a._radiuses.y; } // The outer (atmosphere) radius
|
||||
|
||||
float getAtmosphereScale(Atmosphere a) { return a._scales.x; } // 1 / (outerRadius - innerRadius)
|
||||
float getAtmosphereScaleDepth(Atmosphere a) { return a._scales.y; } // The scale depth (i.e. the altitude at which the atmosphere's average density is found)
|
||||
float getAtmosphereScaleOverScaleDepth(Atmosphere a) { return a._scales.z; } // scale / scaleDepth
|
||||
|
||||
vec4 getAtmosphereScattering(Atmosphere a) { return a._scatterings; } // The full Mie and Rayleigh scattering coefficients
|
||||
float getAtmosphereKrESun(Atmosphere a) { return a._scatterings.x; } // Kr * ESun
|
||||
float getAtmosphereKmESun(Atmosphere a) { return a._scatterings.y; } // Km * ESun
|
||||
float getAtmosphereKr4PI(Atmosphere a) { return a._scatterings.z; } // Kr * 4 * PI
|
||||
float getAtmosphereKm4PI(Atmosphere a) { return a._scatterings.w; } // Km * 4 * PI
|
||||
|
||||
float getAtmosphereNumSamples(Atmosphere a) { return a._control.x; } // numSamples
|
||||
vec2 getAtmosphereGAndG2(Atmosphere a) { return a._control.yz; } // g and g2
|
||||
|
||||
float atmosphereScale(float scaleDepth, float fCos)
|
||||
{
|
||||
float x = 1.0 - fCos;
|
||||
return scaleDepth * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25))));
|
||||
}
|
||||
|
||||
vec4 evalAtmosphereContribution(Atmosphere atmospheric, vec3 position, vec3 cameraPos, vec3 lightPos) {
|
||||
float fInnerRadius = getAtmosphereInnerRadius(atmospheric);
|
||||
float fSamples = getAtmosphereNumSamples(atmospheric);
|
||||
|
||||
vec3 v3InvWavelength = getAtmosphereInvWaveLength(atmospheric);
|
||||
vec4 scatteringCoefs = getAtmosphereScattering(atmospheric);
|
||||
float fKrESun = scatteringCoefs.x;
|
||||
float fKmESun = scatteringCoefs.y;
|
||||
float fKr4PI = scatteringCoefs.z;
|
||||
float fKm4PI = scatteringCoefs.w;
|
||||
|
||||
vec2 gAndg2 = getAtmosphereGAndG2(atmospheric);
|
||||
float g = gAndg2.x;
|
||||
float g2 = gAndg2.y;
|
||||
|
||||
float fScale = getAtmosphereScale(atmospheric);
|
||||
float fScaleDepth = getAtmosphereScaleDepth(atmospheric);
|
||||
float fScaleOverScaleDepth = getAtmosphereScaleOverScaleDepth(atmospheric);
|
||||
|
||||
// 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 v3Ray = v3Pos - cameraPos;
|
||||
float fFar = length(v3Ray);
|
||||
v3Ray /= fFar;
|
||||
|
||||
// Calculate the ray's starting position, then calculate its scattering offset
|
||||
vec3 v3Start = cameraPos;
|
||||
float fHeight = length(v3Start);
|
||||
float fDepthStart = exp(fScaleOverScaleDepth * (fInnerRadius - fHeight));
|
||||
float fStartAngle = dot(v3Ray, v3Start) / fHeight;
|
||||
float fStartOffset = fDepthStart * atmosphereScale(fScaleDepth, fStartAngle);
|
||||
|
||||
// Initialize the scattering loop variables
|
||||
//gl_FrontColor = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
float fSampleLength = fFar / fSamples;
|
||||
float fScaledLength = fSampleLength * fScale;
|
||||
vec3 v3SampleRay = v3Ray * fSampleLength;
|
||||
vec3 v3SamplePoint = v3Start + v3SampleRay * 0.5;
|
||||
|
||||
// Now loop through the sample rays
|
||||
vec3 v3FrontColor = vec3(0.0, 0.0, 0.0);
|
||||
int nSamples = numSamples;
|
||||
// int nSamples = int(fSamples);
|
||||
for(int i=0; i<nSamples; i++)
|
||||
{
|
||||
float fHeight = length(v3SamplePoint);
|
||||
float fDepth = exp(fScaleOverScaleDepth * (fInnerRadius - fHeight));
|
||||
float fLightAngle = dot(lightPos, v3SamplePoint) / fHeight;
|
||||
float fCameraAngle = dot((v3Ray), v3SamplePoint) / fHeight * 0.99;
|
||||
float fScatter = (fStartOffset + fDepth * (atmosphereScale(fScaleDepth, fLightAngle) - atmosphereScale(fScaleDepth, fCameraAngle)));
|
||||
vec3 v3Attenuate = exp(-fScatter * (v3InvWavelength * fKr4PI + fKm4PI));
|
||||
v3FrontColor += v3Attenuate * (fDepth * fScaledLength);
|
||||
v3SamplePoint += v3SampleRay;
|
||||
}
|
||||
|
||||
// Finally, scale the Mie and Rayleigh colors and set up the varying variables for the pixel shader
|
||||
vec3 secondaryFrontColor = v3FrontColor * fKmESun;
|
||||
vec3 frontColor = v3FrontColor * (v3InvWavelength * fKrESun);
|
||||
vec3 v3Direction = cameraPos - v3Pos;
|
||||
|
||||
float fCos = dot(lightPos, v3Direction) / length(v3Direction);
|
||||
float fMiePhase = 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + fCos*fCos) / pow(1.0 + g2 - 2.0*g*fCos, 1.5);
|
||||
vec4 finalColor;
|
||||
|
||||
finalColor.rgb = frontColor.rgb + fMiePhase * secondaryFrontColor.rgb;
|
||||
finalColor.a = finalColor.b;
|
||||
finalColor.rgb = pow(finalColor.rgb, vec3(1.0/2.2));
|
||||
|
||||
return finalColor;
|
||||
}
|
||||
|
||||
|
||||
<@if GLPROFILE == PC_GL@>
|
||||
uniform atmosphereBuffer {
|
||||
Atmosphere _atmosphere;
|
||||
};
|
||||
Atmosphere getAtmosphere() {
|
||||
return _atmosphere;
|
||||
}
|
||||
<@else@>
|
||||
uniform vec4 atmosphereBuffer[9];
|
||||
Atmosphere getAtmosphere() {
|
||||
Atmosphere atmosphere;
|
||||
atmosphere._invWaveLength = atmosphereBuffer[0];
|
||||
atmosphere._radiuses = atmosphereBuffer[1];
|
||||
atmosphere._scales = atmosphereBuffer[2];
|
||||
atmosphere._scatterings = atmosphereBuffer[3];
|
||||
atmosphere._control = atmosphereBuffer[4];
|
||||
|
||||
return atmosphere;
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
<!
|
||||
/*
|
||||
// uniform vec3 v3CameraPos; // The camera's current position
|
||||
|
||||
|
||||
const int nSamples = 2;
|
||||
const float fSamples = 2.0;
|
||||
|
||||
uniform vec3 v3LightPos;
|
||||
uniform float g;
|
||||
uniform float g2;
|
||||
|
||||
varying vec3 position;
|
||||
|
||||
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)
|
||||
vec3 v3Pos = position;
|
||||
vec3 v3Ray = v3Pos - v3CameraPos;
|
||||
float fFar = length(v3Ray);
|
||||
v3Ray /= fFar;
|
||||
|
||||
// Calculate the ray's starting position, then calculate its scattering offset
|
||||
vec3 v3Start = v3CameraPos;
|
||||
float fHeight = length(v3Start);
|
||||
float fDepth = exp(fScaleOverScaleDepth * (fInnerRadius - fHeight));
|
||||
float fStartAngle = dot(v3Ray, v3Start) / fHeight;
|
||||
float fStartOffset = fDepth * scale(fStartAngle);
|
||||
|
||||
// Initialize the scattering loop variables
|
||||
//gl_FrontColor = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
float fSampleLength = fFar / fSamples;
|
||||
float fScaledLength = fSampleLength * fScale;
|
||||
vec3 v3SampleRay = v3Ray * fSampleLength;
|
||||
vec3 v3SamplePoint = v3Start + v3SampleRay * 0.5;
|
||||
|
||||
// Now loop through the sample rays
|
||||
vec3 v3FrontColor = vec3(0.0, 0.0, 0.0);
|
||||
for(int i=0; i<nSamples; i++)
|
||||
{
|
||||
float fHeight = length(v3SamplePoint);
|
||||
float fDepth = exp(fScaleOverScaleDepth * (fInnerRadius - fHeight));
|
||||
float fLightAngle = dot(v3LightPos, v3SamplePoint) / fHeight;
|
||||
float fCameraAngle = dot((v3Ray), v3SamplePoint) / fHeight * 0.99;
|
||||
float fScatter = (fStartOffset + fDepth * (scale(fLightAngle) - scale(fCameraAngle)));
|
||||
vec3 v3Attenuate = exp(-fScatter * (v3InvWavelength * fKr4PI + fKm4PI));
|
||||
v3FrontColor += v3Attenuate * (fDepth * fScaledLength);
|
||||
v3SamplePoint += v3SampleRay;
|
||||
}
|
||||
|
||||
// Finally, scale the Mie and Rayleigh colors and set up the varying variables for the pixel shader
|
||||
vec3 secondaryFrontColor = v3FrontColor * fKmESun;
|
||||
vec3 frontColor = v3FrontColor * (v3InvWavelength * fKrESun);
|
||||
vec3 v3Direction = v3CameraPos - v3Pos;
|
||||
|
||||
float fCos = dot(v3LightPos, v3Direction) / length(v3Direction);
|
||||
float fMiePhase = 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + fCos*fCos) / pow(1.0 + g2 - 2.0*g*fCos, 1.5);
|
||||
gl_FragColor.rgb = frontColor.rgb + fMiePhase * secondaryFrontColor.rgb;
|
||||
gl_FragColor.a = gl_FragColor.b;
|
||||
gl_FragColor.rgb = pow(gl_FragColor.rgb, vec3(1.0/2.2));
|
||||
}
|
||||
*/
|
||||
!>
|
||||
|
||||
<@endif@>
|
|
@ -134,6 +134,56 @@ void EarthSunModel::setSunLongitude(float lon) {
|
|||
_sunLongitude = validateLongitude(lon);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
Atmosphere::Atmosphere() {
|
||||
// only if created from nothing shall we create the Buffer to store the properties
|
||||
Data data;
|
||||
_dataBuffer = gpu::BufferView(new gpu::Buffer(sizeof(Data), (const gpu::Buffer::Byte*) &data));
|
||||
|
||||
setScatteringWavelength(_scatteringWavelength);
|
||||
setRayleighScattering(_rayleighScattering);
|
||||
setInnerOuterRadiuses(getInnerRadius(), getOuterRadius());
|
||||
}
|
||||
|
||||
void Atmosphere::setScatteringWavelength(Vec3 wavelength) {
|
||||
_scatteringWavelength = wavelength;
|
||||
Data& data = editData();
|
||||
data._invWaveLength = Vec4(1.0f / powf(wavelength.x, 4.0f), 1.0f / powf(wavelength.y, 4.0f), 1.0f / powf(wavelength.z, 4.0f), 0.0f);
|
||||
}
|
||||
|
||||
void Atmosphere::setRayleighScattering(float scattering) {
|
||||
_rayleighScattering = scattering;
|
||||
updateScattering();
|
||||
}
|
||||
|
||||
void Atmosphere::setMieScattering(float scattering) {
|
||||
_mieScattering = scattering;
|
||||
updateScattering();
|
||||
}
|
||||
|
||||
void Atmosphere::setSunBrightness(float brightness) {
|
||||
_sunBrightness = brightness;
|
||||
updateScattering();
|
||||
}
|
||||
|
||||
void Atmosphere::updateScattering() {
|
||||
Data& data = editData();
|
||||
|
||||
data._scatterings.x = getRayleighScattering() * getSunBrightness();
|
||||
data._scatterings.y = getMieScattering() * getSunBrightness();
|
||||
|
||||
data._scatterings.z = getRayleighScattering() * 4.0f * glm::pi<float>();
|
||||
data._scatterings.w = getMieScattering() * 4.0f * glm::pi<float>();
|
||||
}
|
||||
|
||||
void Atmosphere::setInnerOuterRadiuses(float inner, float outer) {
|
||||
Data& data = editData();
|
||||
data._radiuses.x = inner;
|
||||
data._radiuses.y = outer;
|
||||
data._scales.x = 1.0f / (outer - inner);
|
||||
data._scales.z = data._scales.x / data._scales.y;
|
||||
}
|
||||
|
||||
|
||||
const int NUM_DAYS_PER_YEAR = 365;
|
||||
const float NUM_HOURS_PER_DAY = 24.0f;
|
||||
|
|
|
@ -106,6 +106,60 @@ protected:
|
|||
static Mat4d evalWorldToGeoLocationMat(double longitude, double latitude, double altitude, double scale);
|
||||
};
|
||||
|
||||
|
||||
class Atmosphere {
|
||||
public:
|
||||
|
||||
Atmosphere();
|
||||
Atmosphere(const Atmosphere& atmosphere);
|
||||
Atmosphere& operator= (const Atmosphere& atmosphere);
|
||||
virtual ~Atmosphere() {};
|
||||
|
||||
|
||||
void setScatteringWavelength(Vec3 wavelength);
|
||||
const Vec3& getScatteringWavelength() const { return _scatteringWavelength; }
|
||||
|
||||
void setRayleighScattering(float scattering);
|
||||
float getRayleighScattering() const { return _rayleighScattering; }
|
||||
|
||||
void setMieScattering(float scattering);
|
||||
float getMieScattering() const { return _mieScattering; }
|
||||
|
||||
void setSunBrightness(float brightness);
|
||||
float getSunBrightness() const { return _sunBrightness; }
|
||||
|
||||
void setInnerOuterRadiuses(float inner, float outer);
|
||||
float getInnerRadius() const { return getData()._radiuses.x; }
|
||||
float getOuterRadius() const { return getData()._radiuses.y; }
|
||||
|
||||
// Data to access the attribute values of the atmosphere
|
||||
class Data {
|
||||
public:
|
||||
Vec4 _invWaveLength = Vec4(0.0f);
|
||||
Vec4 _radiuses = Vec4(6000.0f, 6025.0f, 0.0f, 0.0f);
|
||||
Vec4 _scales = Vec4(0.0f, 0.25f, 0.0f, 0.0f);
|
||||
Vec4 _scatterings = Vec4(0.0f);
|
||||
Vec4 _control = Vec4(2.0f, -0.990f, -0.990f*-0.990f, 0.f);
|
||||
|
||||
Data() {}
|
||||
};
|
||||
|
||||
const UniformBufferView& getDataBuffer() const { return _dataBuffer; }
|
||||
|
||||
protected:
|
||||
UniformBufferView _dataBuffer;
|
||||
Vec3 _scatteringWavelength = Vec3(0.650f, 0.570f, 0.475f);
|
||||
float _rayleighScattering = 0.0025f;
|
||||
float _mieScattering = 0.0010f;
|
||||
float _sunBrightness = 20.0f;
|
||||
|
||||
const Data& getData() const { return _dataBuffer.get<Data>(); }
|
||||
Data& editData() { return _dataBuffer.edit<Data>(); }
|
||||
|
||||
void updateScattering();
|
||||
};
|
||||
typedef QSharedPointer< Atmosphere > AtmospherePointer;
|
||||
|
||||
// Sun sky stage generates the rendering primitives to display a scene realistically
|
||||
// at the specified location and time around earth
|
||||
class SunSkyStage {
|
||||
|
@ -141,9 +195,11 @@ public:
|
|||
float getSunIntensity() const { return getSunLight()->getIntensity(); }
|
||||
|
||||
LightPointer getSunLight() const { valid(); return _sunLight; }
|
||||
AtmospherePointer getAtmosphere() const { valid(); return _atmosphere; }
|
||||
|
||||
protected:
|
||||
LightPointer _sunLight;
|
||||
AtmospherePointer _atmosphere;
|
||||
|
||||
gpu::PipelinePointer _skyPipeline;
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
<@include DeferredLighting.slh@>
|
||||
|
||||
|
||||
struct SphericalHarmonics {
|
||||
vec4 L00;
|
||||
vec4 L1m1;
|
||||
|
@ -50,6 +51,7 @@ uniform SphericalHarmonics ambientSphere;
|
|||
|
||||
// Everything about light
|
||||
<@include model/Light.slh@>
|
||||
<@include model/Atmosphere.slh@>
|
||||
|
||||
// The view Matrix
|
||||
uniform mat4 invViewMat;
|
||||
|
@ -89,6 +91,14 @@ vec3 evalAmbienSphereGlobalColor(float shadowAttenuation, vec3 position, vec3 no
|
|||
|
||||
color += vec3(diffuse + shading.rgb) * shading.w * shadowAttenuation * getLightColor(light) * getLightIntensity(light);
|
||||
|
||||
|
||||
vec3 fragPos = vec3(invViewMat * vec4(position, 1.0));
|
||||
vec3 cameraPos = invViewMat[3].xyz;
|
||||
vec3 lightPos = 10000.0 * getLightDirection(light);
|
||||
|
||||
Atmosphere atmo = getAtmosphere();
|
||||
vec4 atmoColor = evalAtmosphereContribution(atmo, fragPos, cameraPos, lightPos);
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
|
|
|
@ -270,6 +270,12 @@ void DeferredLightingEffect::render() {
|
|||
batch.setUniformBuffer(locations->lightBufferUnit, globalLight->getSchemaBuffer());
|
||||
gpu::GLBackend::renderBatch(batch);
|
||||
}
|
||||
|
||||
if (_atmosphere && (locations->atmosphereBufferUnit >= 0)) {
|
||||
gpu::Batch batch;
|
||||
batch.setUniformBuffer(locations->atmosphereBufferUnit, _atmosphere->getDataBuffer());
|
||||
gpu::GLBackend::renderBatch(batch);
|
||||
}
|
||||
glUniformMatrix4fv(locations->invViewMat, 1, false, reinterpret_cast< const GLfloat* >(&invViewMat));
|
||||
}
|
||||
|
||||
|
@ -511,6 +517,31 @@ void DeferredLightingEffect::loadLightProgram(const char* fragSource, bool limit
|
|||
locations.lightBufferUnit = -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_MAC)
|
||||
loc = program.uniformLocation("atmosphereBufferUnit");
|
||||
if (loc >= 0) {
|
||||
locations.atmosphereBufferUnit = loc;
|
||||
} else {
|
||||
locations.atmosphereBufferUnit = -1;
|
||||
}
|
||||
#elif defined(Q_OS_WIN)
|
||||
loc = glGetUniformBlockIndex(program.programId(), "atmosphereBufferUnit");
|
||||
if (loc >= 0) {
|
||||
glUniformBlockBinding(program.programId(), loc, 1);
|
||||
locations.atmosphereBufferUnit = 1;
|
||||
} else {
|
||||
locations.atmosphereBufferUnit = -1;
|
||||
}
|
||||
#else
|
||||
loc = program.uniformLocation("atmosphereBufferUnit");
|
||||
if (loc >= 0) {
|
||||
locations.atmosphereBufferUnit = loc;
|
||||
} else {
|
||||
locations.atmosphereBufferUnit = -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
program.release();
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "ProgramObject.h"
|
||||
|
||||
#include "model/Light.h"
|
||||
#include "model/Stage.h"
|
||||
|
||||
class AbstractViewStateInterface;
|
||||
class PostLightingRenderable;
|
||||
|
@ -73,6 +74,7 @@ public:
|
|||
// update global lighting
|
||||
void setAmbientLightMode(int preset);
|
||||
void setGlobalLight(const glm::vec3& direction, const glm::vec3& diffuse, float intensity);
|
||||
void setGlobalAtmosphere(const model::AtmospherePointer& atmosphere) { _atmosphere = atmosphere; }
|
||||
|
||||
private:
|
||||
DeferredLightingEffect() {}
|
||||
|
@ -89,6 +91,7 @@ private:
|
|||
int radius;
|
||||
int ambientSphere;
|
||||
int lightBufferUnit;
|
||||
int atmosphereBufferUnit;
|
||||
int invViewMat;
|
||||
};
|
||||
|
||||
|
@ -146,6 +149,7 @@ private:
|
|||
AbstractViewStateInterface* _viewState;
|
||||
|
||||
int _ambientLightMode = 0;
|
||||
model::AtmospherePointer _atmosphere;
|
||||
};
|
||||
|
||||
/// Simple interface for objects that require something to be rendered after deferred lighting.
|
||||
|
|
|
@ -192,9 +192,17 @@ int main (int argc, char** argv) {
|
|||
targetStringStream << "#ifndef scribe_" << targetName << "_h" << std::endl;
|
||||
targetStringStream << "#define scribe_" << targetName << "_h" << std::endl << std::endl;
|
||||
|
||||
targetStringStream << "const char " << targetName << "[] = R\"XXXX(" << destStringStream.str() << ")XXXX\";";
|
||||
// targetStringStream << "const char " << targetName << "[] = R\"XXXX(" << destStringStream.str() << ")XXXX\";";
|
||||
std::istringstream destStringStreamAgain(destStringStream.str());
|
||||
targetStringStream << "const char " << targetName << "[] = \n";
|
||||
while (!destStringStreamAgain.eof()) {
|
||||
std::string lineToken;
|
||||
std::getline(destStringStreamAgain, lineToken);
|
||||
// targetStringStream << "\"" << lineToken << "\"\n";
|
||||
targetStringStream << "R\"X(" << lineToken << ")X\"\"\\n\"\n";
|
||||
}
|
||||
|
||||
targetStringStream << std::endl << std::endl;
|
||||
targetStringStream << ";\n" << std::endl << std::endl;
|
||||
targetStringStream << "#endif" << std::endl;
|
||||
} else {
|
||||
targetStringStream << destStringStream.str();
|
||||
|
|
Loading…
Reference in a new issue