Reflection is working correctly with the PBR property, ship t

This commit is contained in:
samcake 2016-02-29 18:54:43 -08:00
parent 4bec6ddf52
commit 630c61e61d
14 changed files with 71 additions and 24 deletions

View file

@ -325,6 +325,7 @@ void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptr<ZoneEntityIt
_pendingAmbientTexture = false; _pendingAmbientTexture = false;
if (_ambientTexture->getGPUTexture()->getIrradiance()) { if (_ambientTexture->getGPUTexture()->getIrradiance()) {
sceneKeyLight->setAmbientSphere(_ambientTexture->getGPUTexture()->getIrradiance()); sceneKeyLight->setAmbientSphere(_ambientTexture->getGPUTexture()->getIrradiance());
sceneKeyLight->setAmbientMap(_ambientTexture->getGPUTexture());
isAmbientTextureSet = true; isAmbientTextureSet = true;
} }
} else { } else {
@ -360,6 +361,7 @@ void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptr<ZoneEntityIt
_pendingSkyboxTexture = false; _pendingSkyboxTexture = false;
if (!isAmbientTextureSet && texture->getIrradiance()) { if (!isAmbientTextureSet && texture->getIrradiance()) {
sceneKeyLight->setAmbientSphere(texture->getIrradiance()); sceneKeyLight->setAmbientSphere(texture->getIrradiance());
sceneKeyLight->setAmbientMap(texture);
isAmbientTextureSet = true; isAmbientTextureSet = true;
} }
} else { } else {

View file

@ -141,6 +141,15 @@ void Light::setAmbientSpherePreset(gpu::SphericalHarmonics::Preset preset) {
editSchema()._ambientSphere.assignPreset(preset); editSchema()._ambientSphere.assignPreset(preset);
} }
void Light::setAmbientMapNumMips(int numMips) { void Light::setAmbientMap(gpu::TexturePointer ambientMap) {
editSchema()._ambientMapNumMips = numMips; _ambientMap = ambientMap;
if (ambientMap) {
setAmbientMapNumMips(_ambientMap->evalNumMips());
} else {
setAmbientMapNumMips(0);
}
}
void Light::setAmbientMapNumMips(int numMips) {
editSchema()._ambientMapNumMips = (float)numMips;
} }

View file

@ -108,6 +108,9 @@ public:
const gpu::SphericalHarmonics& getAmbientSphere() const { return getSchema()._ambientSphere; } const gpu::SphericalHarmonics& getAmbientSphere() const { return getSchema()._ambientSphere; }
void setAmbientSpherePreset(gpu::SphericalHarmonics::Preset preset); void setAmbientSpherePreset(gpu::SphericalHarmonics::Preset preset);
void setAmbientMap(gpu::TexturePointer ambientMap);
gpu::TexturePointer getAmbientMap() const { return _ambientMap; }
void setAmbientMapNumMips(int numMips); void setAmbientMapNumMips(int numMips);
int getAmbientMapNumMips() const { return getSchema()._ambientMapNumMips; } int getAmbientMapNumMips() const { return getSchema()._ambientMapNumMips; }
@ -123,7 +126,7 @@ public:
Vec4 _spot{0.0f, 0.0f, 0.0f, 0.0f}; Vec4 _spot{0.0f, 0.0f, 0.0f, 0.0f};
Vec4 _shadow{0.0f}; Vec4 _shadow{0.0f};
int _ambientMapNumMips{ 0 }; float _ambientMapNumMips{ 0 };
Vec3 _control{ 0.0f, 0.0f, 0.0f }; Vec3 _control{ 0.0f, 0.0f, 0.0f };
gpu::SphericalHarmonics _ambientSphere; gpu::SphericalHarmonics _ambientSphere;
@ -137,6 +140,8 @@ protected:
UniformBufferView _schemaBuffer; UniformBufferView _schemaBuffer;
Transform _transform; Transform _transform;
gpu::TexturePointer _ambientMap;
const Schema& getSchema() const { return _schemaBuffer.get<Schema>(); } const Schema& getSchema() const { return _schemaBuffer.get<Schema>(); }
Schema& editSchema() { return _schemaBuffer.edit<Schema>(); } Schema& editSchema() { return _schemaBuffer.edit<Schema>(); }

View file

@ -277,7 +277,7 @@ public:
const TextureMaps& getTextureMaps() const { return _textureMaps; } const TextureMaps& getTextureMaps() const { return _textureMaps; }
// conversion from legacy material properties to PBR equivalent // conversion from legacy material properties to PBR equivalent
static float shininessToRoughness(float shininess) { return 1.0f - shininess / 128.0f; } static float shininessToRoughness(float shininess) { return 1.0f - shininess / 100.0f; }
protected: protected:

View file

@ -212,6 +212,9 @@ void SunSkyStage::setSunAmbientSphere(const gpu::SHPointer& sphere) {
_sunLight->setAmbientSpherePreset(DEFAULT_AMBIENT_SPHERE); _sunLight->setAmbientSpherePreset(DEFAULT_AMBIENT_SPHERE);
} }
} }
void SunSkyStage::setSunAmbientMap(const gpu::TexturePointer& map) {
_sunLight->setAmbientMap(map);
}
void SunSkyStage::setSunDirection(const Vec3& direction) { void SunSkyStage::setSunDirection(const Vec3& direction) {
if (!isSunModelEnabled()) { if (!isSunModelEnabled()) {

View file

@ -150,6 +150,7 @@ public:
void setSunAmbientIntensity(float intensity) { _sunLight->setAmbientIntensity(intensity); } void setSunAmbientIntensity(float intensity) { _sunLight->setAmbientIntensity(intensity); }
float getSunAmbientIntensity() const { return getSunLight()->getAmbientIntensity(); } float getSunAmbientIntensity() const { return getSunLight()->getAmbientIntensity(); }
void setSunAmbientSphere(const gpu::SHPointer& sphere); void setSunAmbientSphere(const gpu::SHPointer& sphere);
void setSunAmbientMap(const gpu::TexturePointer& map);
// The sun direction is expressed in the world space // The sun direction is expressed in the world space
void setSunDirection(const Vec3& direction); void setSunDirection(const Vec3& direction);

View file

@ -593,8 +593,8 @@ gpu::Texture* TextureUsage::createCubeTextureFromImage(const QImage& srcImage, c
theTexture->assignStoredMipFace(0, formatMip, face.byteCount(), face.constBits(), f); theTexture->assignStoredMipFace(0, formatMip, face.byteCount(), face.constBits(), f);
f++; f++;
} }
// GEnerate irradiance while we are at it // Generate irradiance while we are at it
theTexture->generateIrradiance(); theTexture->generateIrradiance();
} }
} }

View file

@ -115,7 +115,13 @@ DeferredFragment unpackDeferredFragmentNoPosition(vec2 texcoord) {
frag.metallic = frag.diffuseVal.a; frag.metallic = frag.diffuseVal.a;
frag.diffuse = frag.diffuseVal.xyz; frag.diffuse = frag.diffuseVal.xyz;
frag.specular = vec3(frag.metallic); if (frag.metallic <= 0.5) {
frag.metallic = 0.0;
frag.specular = vec3(0.03); // Default Di-electric fresnel value
} else {
frag.specular = vec3(frag.diffuseVal.xyz);
frag.metallic = 1.0;
}
frag.obscurance = min(frag.specularVal.w, frag.obscurance); frag.obscurance = min(frag.specularVal.w, frag.obscurance);
return frag; return frag;

View file

@ -35,8 +35,12 @@ vec4 evalSkyboxLight(vec3 direction, float lod) {
// Get light // Get light
Light light = getLight(); Light light = getLight();
vec3 fresnel = vec3(0.03); // Default Di-electric fresnel value
vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, metallic, vec3(metallic), roughness); if (metallic > 0.5) {
fresnel = albedo;
metallic = 1.0;
}
vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, metallic, fresnel, roughness);
vec3 color = vec3(albedo * shading.w + shading.rgb) * min(shadowAttenuation, obscurance) * getLightColor(light) * getLightIntensity(light); vec3 color = vec3(albedo * shading.w + shading.rgb) * min(shadowAttenuation, obscurance) * getLightColor(light) * getLightIntensity(light);
color += emissive; color += emissive;
<@endfunc@> <@endfunc@>
@ -52,21 +56,28 @@ vec3 evalAmbientGlobalColor(mat4 invViewMat, float shadowAttenuation, float obsc
<@func declareEvalAmbientSphereGlobalColor()@> <@func declareEvalAmbientSphereGlobalColor()@>
vec3 evalAmbientSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 emissive, float roughness) { vec3 evalAmbientSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 emissive, float roughness) {
<$prepareGlobalLight()$> <$prepareGlobalLight()$>
color += albedo * evalSphericalLight(getLightAmbientSphere(light), fragNormal).xyz * obscurance * getLightAmbientIntensity(light); color += (1 - (metallic * 0.5)) * albedo * evalSphericalLight(getLightAmbientSphere(light), fragNormal).xyz * obscurance * getLightAmbientIntensity(light);
return color; return color;
} }
<@endfunc@> <@endfunc@>
<@func declareEvalSkyboxGlobalColor()@> <@func declareEvalSkyboxGlobalColor()@>
<$declareSkyboxMap()$> <$declareSkyboxMap()$>
vec3 fresnelSchlickAmbient(vec3 fresnelColor, vec3 lightDir, vec3 halfDir, float gloss) {
return fresnelColor + (max(vec3(gloss), fresnelColor) - fresnelColor) * pow(1.0f - clamp(dot(lightDir, halfDir), 0.0, 1.0), 5);
}
vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 emissive, float roughness) { vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 emissive, float roughness) {
<$prepareGlobalLight()$> <$prepareGlobalLight()$>
color += (1 - metallic) * albedo * evalSphericalLight(getLightAmbientSphere(light), fragNormal).xyz * obscurance * getLightAmbientIntensity(light);
vec3 direction = -reflect(fragEyeDir, fragNormal); vec3 direction = -reflect(fragEyeDir, fragNormal);
float levels = getLightAmbientMapNumMips(light); float levels = getLightAmbientMapNumMips(light);
float lod = min(1.0 + floor((roughness) * levels), levels); float lod = min(floor((roughness) * levels), levels);
vec4 skyboxLight = evalSkyboxLight(direction, lod); vec4 skyboxLight = evalSkyboxLight(direction, lod);
color += albedo * skyboxLight.rgb * skyboxLight.a * obscurance * getLightAmbientIntensity(light); vec3 ambientFresnel = fresnelSchlickAmbient(fresnel, fragEyeDir, fragNormal, 1 - roughness);
color += ambientFresnel * skyboxLight.rgb * obscurance * getLightAmbientIntensity(light);
return color; return color;
} }

View file

@ -37,7 +37,7 @@ vec4 evalPBRShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, float m
float power = specularDistribution(roughness, fragNormal, halfDir); float power = specularDistribution(roughness, fragNormal, halfDir);
vec3 specular = power * fresnelColor * diffuse; vec3 specular = power * fresnelColor * diffuse;
return vec4(specular, diffuse * (1 - fresnelColor.x)); return vec4(specular, (1.0 - metallic) * diffuse * (1 - fresnelColor.x));
} }
<@endfunc@> <@endfunc@>

View file

@ -320,18 +320,19 @@ void DeferredLightingEffect::render(const render::RenderContextPointer& renderCo
// Setup the global directional pass pipeline // Setup the global directional pass pipeline
{ {
if (_shadowMapEnabled) { if (_shadowMapEnabled) {
/* if (_skyboxTexture) { //if (_skyboxTexture) {
if (_skyboxTexture) {
program = _directionalSkyboxLightShadow; program = _directionalSkyboxLightShadow;
locations = _directionalSkyboxLightShadowLocations; locations = _directionalSkyboxLightShadowLocations;
} else*/ { } else {
program = _directionalAmbientSphereLightShadow; program = _directionalAmbientSphereLightShadow;
locations = _directionalAmbientSphereLightShadowLocations; locations = _directionalAmbientSphereLightShadowLocations;
} }
} else { } else {
/* if (_skyboxTexture) { if (_skyboxTexture) {
program = _directionalSkyboxLight; program = _directionalSkyboxLight;
locations = _directionalSkyboxLightLocations; locations = _directionalSkyboxLightLocations;
} else*/ { } else {
program = _directionalAmbientSphereLight; program = _directionalAmbientSphereLight;
locations = _directionalAmbientSphereLightLocations; locations = _directionalAmbientSphereLightLocations;
} }
@ -501,8 +502,9 @@ void DeferredLightingEffect::setupKeyLightBatch(gpu::Batch& batch, int lightBuff
batch.setUniformBuffer(lightBufferUnit, globalLight->getSchemaBuffer()); batch.setUniformBuffer(lightBufferUnit, globalLight->getSchemaBuffer());
} }
if (_skyboxTexture && (skyboxCubemapUnit >= 0)) { // if (_skyboxTexture && (skyboxCubemapUnit >= 0)) {
batch.setResourceTexture(skyboxCubemapUnit, _skyboxTexture); if (globalLight->getAmbientMap() && (skyboxCubemapUnit >= 0)) {
batch.setResourceTexture(skyboxCubemapUnit, globalLight->getAmbientMap());
} }
} }
@ -569,10 +571,12 @@ void DeferredLightingEffect::setGlobalLight(const model::LightPointer& light, co
globalLight->setAmbientIntensity(light->getAmbientIntensity()); globalLight->setAmbientIntensity(light->getAmbientIntensity());
globalLight->setAmbientSphere(light->getAmbientSphere()); globalLight->setAmbientSphere(light->getAmbientSphere());
_skyboxTexture = skyboxTexture; // _skyboxTexture = skyboxTexture;
_skyboxTexture = (light->getAmbientMap() ? light->getAmbientMap() : _skyboxTexture);
// Update the available mipmap levels // Update the available mipmap levels
globalLight->setAmbientMapNumMips((_skyboxTexture ? _skyboxTexture->evalNumMips() : 0)); globalLight->setAmbientMap((light->getAmbientMap() ? light->getAmbientMap() : _skyboxTexture));
// globalLight->setAmbientMapNumMips((_skyboxTexture ? _skyboxTexture->evalNumMips() : 0));
} }
model::MeshPointer DeferredLightingEffect::getSpotLightMesh() { model::MeshPointer DeferredLightingEffect::getSpotLightMesh() {

View file

@ -23,7 +23,7 @@ vec4 fetchAlbedoMap(vec2 uv) {
<@if withRoughness@> <@if withRoughness@>
uniform sampler2D roughnessMap; uniform sampler2D roughnessMap;
float fetchRoughnessMap(vec2 uv) { float fetchRoughnessMap(vec2 uv) {
return pow(texture(roughnessMap, uv).r, 2.2); return (texture(roughnessMap, uv).r);
} }
<@endif@> <@endif@>
@ -37,7 +37,7 @@ vec3 fetchNormalMap(vec2 uv) {
<@if withMetallic@> <@if withMetallic@>
uniform sampler2D specularMap; uniform sampler2D specularMap;
float fetchMetallicMap(vec2 uv) { float fetchMetallicMap(vec2 uv) {
return pow(texture(specularMap, uv).r, 2.2); return (texture(specularMap, uv).r);
} }
<@endif@> <@endif@>

View file

@ -81,6 +81,11 @@ void SceneScripting::KeyLight::setAmbientSphere(const gpu::SHPointer& sphere) {
_skyStage->setSunAmbientSphere(sphere); _skyStage->setSunAmbientSphere(sphere);
} }
void SceneScripting::KeyLight::setAmbientMap(const gpu::TexturePointer& map) {
_skyStage->setSunAmbientMap(map);
}
glm::vec3 SceneScripting::KeyLight::getDirection() const { glm::vec3 SceneScripting::KeyLight::getDirection() const {
return _skyStage->getSunDirection(); return _skyStage->getSunDirection();
} }

View file

@ -84,6 +84,7 @@ namespace SceneScripting {
// AmbientTexture is unscriptable - it must be set through the zone entity // AmbientTexture is unscriptable - it must be set through the zone entity
void setAmbientSphere(const gpu::SHPointer& sphere); void setAmbientSphere(const gpu::SHPointer& sphere);
void resetAmbientSphere() { setAmbientSphere(nullptr); } void resetAmbientSphere() { setAmbientSphere(nullptr); }
void setAmbientMap(const gpu::TexturePointer& map);
protected: protected:
model::SunSkyStagePointer _skyStage; model::SunSkyStagePointer _skyStage;