Merge pull request #5 from zzmp/fix/skybox-light-orange

Fix skybox global color shader
This commit is contained in:
samcake 2016-02-26 14:55:20 -08:00
commit 483f9a4ee3
6 changed files with 63 additions and 79 deletions

View file

@ -34,8 +34,9 @@ uniform sampler2D lightingMap;
struct DeferredTransform {
mat4 projection;
mat4 viewInverse;
vec4 stereoSide_spareABC;
float stereoSide;
float skyboxMipmapLevels;
vec2 _spareAB;
};
layout(std140) uniform deferredTransformBuffer {
@ -46,10 +47,10 @@ DeferredTransform getDeferredTransform() {
}
bool getStereoMode(DeferredTransform deferredTransform) {
return (deferredTransform.stereoSide_spareABC.x != 0.0);
return (deferredTransform.stereoSide != 0.0);
}
float getStereoSide(DeferredTransform deferredTransform) {
return (deferredTransform.stereoSide_spareABC.x);
return (deferredTransform.stereoSide);
}
vec4 evalEyePositionFromZ(DeferredTransform deferredTransform, float depthVal, vec2 texcoord) {

View file

@ -11,88 +11,61 @@
<@if not DEFERRED_GLOBAL_LIGHT_SLH@>
<@def DEFERRED_GLOBAL_LIGHT_SLH@>
<@include model/Light.slh@>
<@include DeferredLighting.slh@>
<@func declareSkyboxMap()@>
// declareSkyboxMap
uniform samplerCube skyboxMap;
vec4 evalSkyboxLight(vec3 direction, float lod) {
// FIXME
//vec4 skytexel = textureLod(skyboxMap, direction, lod * textureQueryLevels(skyboxMap));
vec4 skytexel = texture(skyboxMap, direction);
return skytexel;
// textureQueryLevels is not available until #430, so we require explicit lod
// float mipmapLevel = lod * textureQueryLevels(skyboxMap);
return textureLod(skyboxMap, direction, lod);
}
<@endfunc@>
// Everything about light
<@include model/Light.slh@>
<@func prepareGlobalLight()@>
// prepareGlobalLight
// Transform directions to worldspace
vec3 fragNormal = vec3(invViewMat * vec4(normal, 0.0));
vec3 fragEyeVector = vec3(invViewMat * vec4(-position, 0.0));
vec3 fragEyeDir = normalize(fragEyeVector);
// Get light
Light light = getLight();
vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, metallic, vec3(metallic), roughness);
color = vec3(albedo * shading.w + shading.rgb) * min(shadowAttenuation, obscurance) * getLightColor(light) * getLightIntensity(light);
color += emissive;
<@endfunc@>
<@func declareEvalAmbientGlobalColor()@>
vec3 evalAmbientGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 emissive, float roughness) {
// Need the light now
Light light = getLight();
vec3 fragNormal = vec3(invViewMat * vec4(normal, 0.0));
vec4 fragEyeVector = invViewMat * vec4(-position, 0.0);
vec3 fragEyeDir = normalize(fragEyeVector.xyz);
vec3 color = albedo * getLightColor(light) * obscurance * getLightAmbientIntensity(light);
vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, metallic, vec3(metallic), roughness);
color += vec3(albedo * shading.w + shading.rgb) * min(shadowAttenuation, obscurance) * getLightColor(light) * getLightIntensity(light);
color += emissive;
<$prepareGlobalLight()$>
color += albedo * getLightColor(light) * obscurance * getLightAmbientIntensity(light);
return color;
}
<@endfunc@>
<@func declareEvalAmbientSphereGlobalColor()@>
vec3 evalAmbientSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 emissive, float roughness) {
// Need the light now
Light light = getLight();
vec3 fragNormal = normalize(vec3(invViewMat * vec4(normal, 0.0)));
vec4 fragEyeVector = invViewMat * vec4(-position, 0.0);
vec3 fragEyeDir = normalize(fragEyeVector.xyz);
vec3 ambientNormal = fragNormal.xyz;
vec3 color = albedo * evalSphericalLight(getLightAmbientSphere(light), ambientNormal).xyz * obscurance * getLightAmbientIntensity(light);
vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, metallic, vec3(metallic), roughness);
color += vec3(albedo * shading.w + shading.rgb) * min(shadowAttenuation, obscurance) * getLightColor(light) * getLightIntensity(light);
color += emissive;
<$prepareGlobalLight()$>
color += albedo * evalSphericalLight(getLightAmbientSphere(light), fragNormal).xyz * obscurance * getLightAmbientIntensity(light);
return color;
}
<@endfunc@>
<@func declareEvalSkyboxGlobalColor()@>
<$declareSkyboxMap()$>
vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 emissive, float roughness) {
// Need the light now
Light light = getLight();
vec3 fragNormal = normalize(vec3(invViewMat * vec4(normal, 0.0)));
vec4 fragEyeVector = invViewMat * vec4(-position, 0.0);
vec3 fragEyeDir = normalize(fragEyeVector.xyz);
<$prepareGlobalLight()$>
vec3 color = albedo * evalSphericalLight(getLightAmbientSphere(light), fragNormal).xyz * obscurance * getLightAmbientIntensity(light);
vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, metallic, vec3(metallic), roughness);
color += vec3(albedo * shading.w + shading.rgb) * min(shadowAttenuation, obscurance) * getLightColor(light) * getLightIntensity(light);
color += emissive;
vec3 direction = -reflect(fragEyeDir, fragNormal);
float lod = min(1.0 + floor((1.0 - gloss) * levels), levels);
vec4 skyboxLight = evalSkyboxLight(direction, lod);
color += albedo * skyboxLight.rgb * skyboxLight.a * obscurance * getLightAmbientIntensity(light);
return color;
}
@ -100,26 +73,26 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu
<@func declareEvalLightmappedColor()@>
vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 normal, vec3 albedo, vec3 lightmap) {
vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 normal, vec3 diffuse, vec3 lightmap) {
Light light = getLight();
vec3 fragNormal = vec3(invViewMat * vec4(normal, 0.0));
float diffuseDot = dot(fragNormal, -getLightDirection(light));
// need to catch normals perpendicular to the projection plane hence the magic number for the threshold
// it should be just 0, but we have innacurracy so we need to overshoot
// Catch normals perpendicular to the projection plane, hence the magic number for the threshold
// It should be just 0, but we have inaccuracy so we overshoot
const float PERPENDICULAR_THRESHOLD = -0.005;
vec3 fragNormal = vec3(invViewMat * vec4(normal, 0.0)); // transform to worldspace
float diffuseDot = dot(fragNormal, -getLightDirection(light));
float facingLight = step(PERPENDICULAR_THRESHOLD, diffuseDot);
//float facingLight = step(PERPENDICULAR_THRESHOLD, diffuseDot);
// evaluate the shadow test but only relevant for light facing fragments
// Reevaluate the shadow attenuation for light facing fragments
float lightAttenuation = (1 - facingLight) + facingLight * shadowAttenuation;
// diffuse light is the lightmap dimmed by shadow
// Diffuse light is the lightmap dimmed by shadow
vec3 diffuseLight = lightAttenuation * lightmap;
// ambient is a tiny percentage of the lightmap and only when in the shadow
// Ambient light is the lightmap when in shadow
vec3 ambientLight = (1 - lightAttenuation) * lightmap * getLightAmbientIntensity(light);
return obscurance * albedo * (ambientLight + diffuseLight);
return obscurance * albedo * (diffuseLight + ambientLight);
}
<@endfunc@>

View file

@ -94,7 +94,7 @@ void DeferredLightingEffect::init() {
lp->setColor(glm::vec3(1.0f));
lp->setIntensity(1.0f);
lp->setType(model::Light::SUN);
lp->setAmbientSpherePreset(gpu::SphericalHarmonics::Preset(_ambientLightMode % gpu::SphericalHarmonics::NUM_PRESET));
lp->setAmbientSpherePreset(gpu::SphericalHarmonics::Preset::OLD_TOWN_SQUARE);
}
void DeferredLightingEffect::addPointLight(const glm::vec3& position, float radius, const glm::vec3& color,
@ -321,7 +321,7 @@ void DeferredLightingEffect::render(const render::RenderContextPointer& renderCo
if (_skyboxTexture) {
program = _directionalSkyboxLightShadow;
locations = _directionalSkyboxLightShadowLocations;
} else if (_ambientLightMode > -1) {
} else {
program = _directionalAmbientSphereLightShadow;
locations = _directionalAmbientSphereLightShadowLocations;
}
@ -329,7 +329,7 @@ void DeferredLightingEffect::render(const render::RenderContextPointer& renderCo
if (_skyboxTexture) {
program = _directionalSkyboxLight;
locations = _directionalSkyboxLightLocations;
} else if (_ambientLightMode > -1) {
} else {
program = _directionalAmbientSphereLight;
locations = _directionalAmbientSphereLightLocations;
}
@ -562,6 +562,14 @@ static void loadLightProgram(const char* vertSource, const char* fragSource, boo
void DeferredLightingEffect::setGlobalLight(const model::LightPointer& light, const gpu::TexturePointer& skyboxTexture) {
_allocatedLights.front() = light;
_skyboxTexture = skyboxTexture;
// Update the available mipmap levels
if (_skyboxTexture) {
float dim = glm::max(_skyboxTexture->getHeight(), _skyboxTexture->getWidth(), _skyboxTexture->getDepth());
auto skyboxMipmapLevels = 1 + glm::floor(glm::log2(dim));
_deferredTransformBuffer[0].edit<DeferredTransform>().skyboxMipmapLevels = skyboxMipmapLevels;
_deferredTransformBuffer[1].edit<DeferredTransform>().skyboxMipmapLevels = skyboxMipmapLevels;
}
}
model::MeshPointer DeferredLightingEffect::getSpotLightMesh() {

View file

@ -96,7 +96,6 @@ private:
std::vector<int> _pointLights;
std::vector<int> _spotLights;
int _ambientLightMode = 0;
gpu::TexturePointer _skyboxTexture;
// Class describing the uniform buffer with all the parameters common to the deferred shaders
@ -104,8 +103,9 @@ private:
public:
glm::mat4 projection;
glm::mat4 viewInverse;
float stereoSide{ 0.f };
float spareA, spareB, spareC;
float stereoSide { 0.f };
float skyboxMipmapLevels { 1.0f };
float spareA, spareB;
DeferredTransform() {}
};

View file

@ -47,7 +47,8 @@ void main(void) {
frag.diffuse,
frag.metallic,
frag.emissive,
frag.roughness);
frag.roughness,
deferredTransform.skyboxMipmapLevels);
_fragColor = vec4(color, frag.normalVal.a);
}

View file

@ -49,7 +49,8 @@ void main(void) {
frag.diffuse,
frag.metallic,
frag.emissive,
frag.roughness);
frag.roughness,
deferredTransform.skyboxMipmapLevels);
_fragColor = vec4(color, frag.normalVal.a);
}