mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 23:14:34 +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;
|
friend class Backend;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef QSharedPointer< Pipeline > PipelinePointer;
|
typedef std::shared_ptr< Pipeline > PipelinePointer;
|
||||||
typedef std::vector< PipelinePointer > Pipelines;
|
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);
|
_sunLongitude = validateLongitude(lon);
|
||||||
invalidate();
|
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 int NUM_DAYS_PER_YEAR = 365;
|
||||||
const float NUM_HOURS_PER_DAY = 24.0f;
|
const float NUM_HOURS_PER_DAY = 24.0f;
|
||||||
|
|
|
@ -106,6 +106,60 @@ protected:
|
||||||
static Mat4d evalWorldToGeoLocationMat(double longitude, double latitude, double altitude, double scale);
|
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
|
// Sun sky stage generates the rendering primitives to display a scene realistically
|
||||||
// at the specified location and time around earth
|
// at the specified location and time around earth
|
||||||
class SunSkyStage {
|
class SunSkyStage {
|
||||||
|
@ -141,9 +195,11 @@ public:
|
||||||
float getSunIntensity() const { return getSunLight()->getIntensity(); }
|
float getSunIntensity() const { return getSunLight()->getIntensity(); }
|
||||||
|
|
||||||
LightPointer getSunLight() const { valid(); return _sunLight; }
|
LightPointer getSunLight() const { valid(); return _sunLight; }
|
||||||
|
AtmospherePointer getAtmosphere() const { valid(); return _atmosphere; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
LightPointer _sunLight;
|
LightPointer _sunLight;
|
||||||
|
AtmospherePointer _atmosphere;
|
||||||
|
|
||||||
gpu::PipelinePointer _skyPipeline;
|
gpu::PipelinePointer _skyPipeline;
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
<@include DeferredLighting.slh@>
|
<@include DeferredLighting.slh@>
|
||||||
|
|
||||||
|
|
||||||
struct SphericalHarmonics {
|
struct SphericalHarmonics {
|
||||||
vec4 L00;
|
vec4 L00;
|
||||||
vec4 L1m1;
|
vec4 L1m1;
|
||||||
|
@ -50,6 +51,7 @@ uniform SphericalHarmonics ambientSphere;
|
||||||
|
|
||||||
// Everything about light
|
// Everything about light
|
||||||
<@include model/Light.slh@>
|
<@include model/Light.slh@>
|
||||||
|
<@include model/Atmosphere.slh@>
|
||||||
|
|
||||||
// The view Matrix
|
// The view Matrix
|
||||||
uniform mat4 invViewMat;
|
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);
|
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;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -270,6 +270,12 @@ void DeferredLightingEffect::render() {
|
||||||
batch.setUniformBuffer(locations->lightBufferUnit, globalLight->getSchemaBuffer());
|
batch.setUniformBuffer(locations->lightBufferUnit, globalLight->getSchemaBuffer());
|
||||||
gpu::GLBackend::renderBatch(batch);
|
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));
|
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;
|
locations.lightBufferUnit = -1;
|
||||||
}
|
}
|
||||||
#endif
|
#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();
|
program.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "ProgramObject.h"
|
#include "ProgramObject.h"
|
||||||
|
|
||||||
#include "model/Light.h"
|
#include "model/Light.h"
|
||||||
|
#include "model/Stage.h"
|
||||||
|
|
||||||
class AbstractViewStateInterface;
|
class AbstractViewStateInterface;
|
||||||
class PostLightingRenderable;
|
class PostLightingRenderable;
|
||||||
|
@ -73,6 +74,7 @@ public:
|
||||||
// update global lighting
|
// update global lighting
|
||||||
void setAmbientLightMode(int preset);
|
void setAmbientLightMode(int preset);
|
||||||
void setGlobalLight(const glm::vec3& direction, const glm::vec3& diffuse, float intensity);
|
void setGlobalLight(const glm::vec3& direction, const glm::vec3& diffuse, float intensity);
|
||||||
|
void setGlobalAtmosphere(const model::AtmospherePointer& atmosphere) { _atmosphere = atmosphere; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DeferredLightingEffect() {}
|
DeferredLightingEffect() {}
|
||||||
|
@ -89,6 +91,7 @@ private:
|
||||||
int radius;
|
int radius;
|
||||||
int ambientSphere;
|
int ambientSphere;
|
||||||
int lightBufferUnit;
|
int lightBufferUnit;
|
||||||
|
int atmosphereBufferUnit;
|
||||||
int invViewMat;
|
int invViewMat;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -146,6 +149,7 @@ private:
|
||||||
AbstractViewStateInterface* _viewState;
|
AbstractViewStateInterface* _viewState;
|
||||||
|
|
||||||
int _ambientLightMode = 0;
|
int _ambientLightMode = 0;
|
||||||
|
model::AtmospherePointer _atmosphere;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Simple interface for objects that require something to be rendered after deferred lighting.
|
/// 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 << "#ifndef scribe_" << targetName << "_h" << std::endl;
|
||||||
targetStringStream << "#define scribe_" << targetName << "_h" << std::endl << 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;
|
targetStringStream << "#endif" << std::endl;
|
||||||
} else {
|
} else {
|
||||||
targetStringStream << destStringStream.str();
|
targetStringStream << destStringStream.str();
|
||||||
|
|
Loading…
Reference in a new issue