mirror of
https://github.com/AleziaKurdis/overte.git
synced 2025-04-08 11:13:37 +02:00
Merge pull request #12180 from Zvork/locallights
Local lights on translucent objects
This commit is contained in:
commit
1865432b47
27 changed files with 465 additions and 218 deletions
|
@ -56,10 +56,10 @@ Light getLight(int index) {
|
|||
}
|
||||
|
||||
<@else@>
|
||||
uniform lightBuffer {
|
||||
uniform keyLightBuffer {
|
||||
Light light;
|
||||
};
|
||||
Light getLight() {
|
||||
Light getKeyLight() {
|
||||
return light;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,21 +21,25 @@
|
|||
<@include LightDirectional.slh@>
|
||||
|
||||
|
||||
<@func prepareGlobalLight(isScattering)@>
|
||||
// prepareGlobalLight
|
||||
// Transform directions to worldspace
|
||||
vec3 fragNormal = vec3((normal));
|
||||
vec3 fragEyeVector = vec3(invViewMat * vec4(-1.0*position, 0.0));
|
||||
vec3 fragEyeDir = normalize(fragEyeVector);
|
||||
|
||||
<@func fetchGlobalLight()@>
|
||||
// Get light
|
||||
Light light = getLight();
|
||||
Light light = getKeyLight();
|
||||
LightAmbient lightAmbient = getLightAmbient();
|
||||
|
||||
vec3 lightDirection = getLightDirection(light);
|
||||
vec3 lightIrradiance = getLightIrradiance(light);
|
||||
|
||||
vec3 color = vec3(0.0);
|
||||
<@endfunc@>
|
||||
|
||||
<@func prepareGlobalLight(isScattering)@>
|
||||
// prepareGlobalLight
|
||||
// Transform directions to worldspace
|
||||
vec3 fragNormal = vec3((normal));
|
||||
vec3 fragEyeVector = vec3(invViewMat * vec4(-position, 0.0));
|
||||
vec3 fragEyeDir = normalize(fragEyeVector);
|
||||
|
||||
<$fetchGlobalLight()$>
|
||||
|
||||
<@endfunc@>
|
||||
|
||||
|
@ -147,7 +151,7 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu
|
|||
|
||||
<@func declareEvalLightmappedColor()@>
|
||||
vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 normal, vec3 albedo, vec3 lightmap) {
|
||||
Light light = getLight();
|
||||
Light light = getKeyLight();
|
||||
LightAmbient ambient = getLightAmbient();
|
||||
|
||||
// Catch normals perpendicular to the projection plane, hence the magic number for the threshold
|
||||
|
@ -175,11 +179,12 @@ vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, float obscur
|
|||
<$declareLightingAmbient(1, 1, 1)$>
|
||||
<$declareLightingDirectional()$>
|
||||
|
||||
vec3 evalGlobalLightingAlphaBlended(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, vec3 fresnel, float metallic, vec3 emissive, float roughness, float opacity) {
|
||||
vec3 evalGlobalLightingAlphaBlended(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, vec3 fresnel, float metallic, vec3 emissive, float roughness, float opacity, vec3 prevLighting) {
|
||||
<$prepareGlobalLight()$>
|
||||
|
||||
SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir);
|
||||
|
||||
color = prevLighting;
|
||||
color += emissive * isEmissiveEnabled();
|
||||
|
||||
// Ambient
|
||||
|
@ -238,6 +243,44 @@ vec3 evalGlobalLightingAlphaBlendedWithHaze(
|
|||
|
||||
return color;
|
||||
}
|
||||
|
||||
vec3 evalGlobalLightingAlphaBlendedWithHaze(
|
||||
mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position,
|
||||
vec3 albedo, vec3 fresnel, float metallic, vec3 emissive, SurfaceData surface, float opacity, vec3 prevLighting)
|
||||
{
|
||||
<$fetchGlobalLight()$>
|
||||
|
||||
color = prevLighting;
|
||||
color += emissive * isEmissiveEnabled();
|
||||
|
||||
// Ambient
|
||||
vec3 ambientDiffuse;
|
||||
vec3 ambientSpecular;
|
||||
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surface, metallic, fresnel, albedo, obscurance);
|
||||
|
||||
// Directional
|
||||
vec3 directionalDiffuse;
|
||||
vec3 directionalSpecular;
|
||||
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surface, metallic, fresnel, albedo, shadowAttenuation);
|
||||
|
||||
color += ambientDiffuse + directionalDiffuse;
|
||||
color += (ambientSpecular + directionalSpecular) / opacity;
|
||||
|
||||
// Haze
|
||||
if ((hazeParams.hazeMode & HAZE_MODE_IS_ACTIVE) == HAZE_MODE_IS_ACTIVE) {
|
||||
vec4 colorV4 = computeHazeColor(
|
||||
vec4(color, 1.0), // fragment original color
|
||||
position, // fragment position in eye coordinates
|
||||
surface.eyeDir, // fragment eye vector in world coordinates
|
||||
invViewMat[3].y, // eye height in world coordinates
|
||||
lightDirection // keylight direction vector
|
||||
);
|
||||
|
||||
color = colorV4.rgb;
|
||||
}
|
||||
|
||||
return color;
|
||||
}
|
||||
<@endfunc@>
|
||||
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ using namespace render;
|
|||
|
||||
struct LightLocations {
|
||||
int radius{ -1 };
|
||||
int keyLightBufferUnit{ -1 };
|
||||
int lightBufferUnit{ -1 };
|
||||
int ambientBufferUnit { -1 };
|
||||
int lightIndexBufferUnit { -1 };
|
||||
|
@ -147,6 +148,29 @@ void DeferredLightingEffect::unsetKeyLightBatch(gpu::Batch& batch, int lightBuff
|
|||
}
|
||||
}
|
||||
|
||||
void DeferredLightingEffect::setupLocalLightsBatch(gpu::Batch& batch,
|
||||
int clusterGridBufferUnit, int clusterContentBufferUnit, int frustumGridBufferUnit,
|
||||
const LightClustersPointer& lightClusters) {
|
||||
// Bind the global list of lights and the visible lights this frame
|
||||
batch.setUniformBuffer(_localLightLocations->lightBufferUnit, lightClusters->_lightStage->getLightArrayBuffer());
|
||||
|
||||
batch.setUniformBuffer(frustumGridBufferUnit, lightClusters->_frustumGridBuffer);
|
||||
batch.setUniformBuffer(clusterGridBufferUnit, lightClusters->_clusterGridBuffer);
|
||||
batch.setUniformBuffer(clusterContentBufferUnit, lightClusters->_clusterContentBuffer);
|
||||
}
|
||||
|
||||
void DeferredLightingEffect::unsetLocalLightsBatch(gpu::Batch& batch, int clusterGridBufferUnit, int clusterContentBufferUnit, int frustumGridBufferUnit) {
|
||||
if (clusterGridBufferUnit >= 0) {
|
||||
batch.setUniformBuffer(clusterGridBufferUnit, nullptr);
|
||||
}
|
||||
if (clusterContentBufferUnit >= 0) {
|
||||
batch.setUniformBuffer(clusterContentBufferUnit, nullptr);
|
||||
}
|
||||
if (frustumGridBufferUnit >= 0) {
|
||||
batch.setUniformBuffer(frustumGridBufferUnit, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
static gpu::ShaderPointer makeLightProgram(const char* vertSource, const char* fragSource, LightLocationsPtr& locations) {
|
||||
auto VS = gpu::Shader::createVertex(std::string(vertSource));
|
||||
auto PS = gpu::Shader::createPixel(std::string(fragSource));
|
||||
|
@ -189,6 +213,7 @@ static gpu::ShaderPointer makeLightProgram(const char* vertSource, const char* f
|
|||
|
||||
locations->texcoordFrameTransform = program->getUniforms().findLocation("texcoordFrameTransform");
|
||||
|
||||
locations->keyLightBufferUnit = program->getUniformBuffers().findLocation("keyLightBuffer");
|
||||
locations->lightBufferUnit = program->getUniformBuffers().findLocation("lightBuffer");
|
||||
locations->ambientBufferUnit = program->getUniformBuffers().findLocation("lightAmbientBuffer");
|
||||
locations->lightIndexBufferUnit = program->getUniformBuffers().findLocation("lightIndexBuffer");
|
||||
|
@ -561,7 +586,7 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext,
|
|||
batch._glUniform4fv(locations->texcoordFrameTransform, 1, reinterpret_cast< const float* >(&textureFrameTransform));
|
||||
|
||||
// Setup the global lighting
|
||||
deferredLightingEffect->setupKeyLightBatch(args, batch, locations->lightBufferUnit, locations->ambientBufferUnit, SKYBOX_MAP_UNIT);
|
||||
deferredLightingEffect->setupKeyLightBatch(args, batch, locations->keyLightBufferUnit, locations->ambientBufferUnit, SKYBOX_MAP_UNIT);
|
||||
|
||||
// Haze
|
||||
if (haze) {
|
||||
|
@ -570,7 +595,7 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext,
|
|||
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
|
||||
deferredLightingEffect->unsetKeyLightBatch(batch, locations->lightBufferUnit, locations->ambientBufferUnit, SKYBOX_MAP_UNIT);
|
||||
deferredLightingEffect->unsetKeyLightBatch(batch, locations->keyLightBufferUnit, locations->ambientBufferUnit, SKYBOX_MAP_UNIT);
|
||||
|
||||
for (auto i = 0; i < SHADOW_CASCADE_MAX_COUNT; i++) {
|
||||
batch.setResourceTexture(SHADOW_MAP_UNIT+i, nullptr);
|
||||
|
@ -625,12 +650,8 @@ void RenderDeferredLocals::run(const render::RenderContextPointer& renderContext
|
|||
|
||||
auto& lightIndices = lightClusters->_visibleLightIndices;
|
||||
if (!lightIndices.empty() && lightIndices[0] > 0) {
|
||||
// Bind the global list of lights and the visible lights this frame
|
||||
batch.setUniformBuffer(deferredLightingEffect->_localLightLocations->lightBufferUnit, lightClusters->_lightStage->getLightArrayBuffer());
|
||||
|
||||
batch.setUniformBuffer(LIGHT_CLUSTER_GRID_FRUSTUM_GRID_SLOT, lightClusters->_frustumGridBuffer);
|
||||
batch.setUniformBuffer(LIGHT_CLUSTER_GRID_CLUSTER_GRID_SLOT, lightClusters->_clusterGridBuffer);
|
||||
batch.setUniformBuffer(LIGHT_CLUSTER_GRID_CLUSTER_CONTENT_SLOT, lightClusters->_clusterContentBuffer);
|
||||
deferredLightingEffect->setupLocalLightsBatch(batch, LIGHT_CLUSTER_GRID_CLUSTER_GRID_SLOT, LIGHT_CLUSTER_GRID_CLUSTER_CONTENT_SLOT, LIGHT_CLUSTER_GRID_FRUSTUM_GRID_SLOT,
|
||||
lightClusters);
|
||||
|
||||
// Local light pipeline
|
||||
batch.setPipeline(deferredLightingEffect->_localLight);
|
||||
|
|
|
@ -51,6 +51,9 @@ public:
|
|||
void setupKeyLightBatch(const RenderArgs* args, gpu::Batch& batch, int lightBufferUnit, int ambientBufferUnit, int skyboxCubemapUnit);
|
||||
void unsetKeyLightBatch(gpu::Batch& batch, int lightBufferUnit, int ambientBufferUnit, int skyboxCubemapUnit);
|
||||
|
||||
void setupLocalLightsBatch(gpu::Batch& batch, int clusterGridBufferUnit, int clusterContentBufferUnit, int frustumGridBufferUnit, const LightClustersPointer& lightClusters);
|
||||
void unsetLocalLightsBatch(gpu::Batch& batch, int clusterGridBufferUnit, int clusterContentBufferUnit, int frustumGridBufferUnit);
|
||||
|
||||
void setShadowMapEnabled(bool enable) { _shadowMapEnabled = enable; };
|
||||
void setAmbientOcclusionEnabled(bool enable) { _ambientOcclusionEnabled = enable; }
|
||||
bool isAmbientOcclusionEnabled() const { return _ambientOcclusionEnabled; }
|
||||
|
|
|
@ -147,7 +147,7 @@ void DrawHaze::run(const render::RenderContextPointer& renderContext, const Inpu
|
|||
slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), HazeEffect_TransformBufferSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("colorMap"), HazeEffect_ColorMapSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("linearDepthMap"), HazeEffect_LinearDepthMapSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), HazeEffect_LightingMapSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("keyLightBuffer"), HazeEffect_LightingMapSlot));
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
|
||||
_hazePipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, state));
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
vec3 fragEyeDir = normalize(fragEyeVector);
|
||||
|
||||
// Get light
|
||||
Light light = getLight();
|
||||
Light light = getKeyLight();
|
||||
LightAmbient lightAmbient = getLightAmbient();
|
||||
|
||||
vec3 lightDirection = getLightDirection(light);
|
||||
|
@ -143,7 +143,7 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu
|
|||
|
||||
<@func declareEvalLightmappedColor()@>
|
||||
vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 normal, vec3 albedo, vec3 lightmap) {
|
||||
Light light = getLight();
|
||||
Light light = getKeyLight();
|
||||
LightAmbient ambient = getLightAmbient();
|
||||
|
||||
// Catch normals perpendicular to the projection plane, hence the magic number for the threshold
|
||||
|
|
|
@ -53,7 +53,7 @@ void main(void) {
|
|||
vec4 worldFragPos = viewInverse * eyeFragPos;
|
||||
vec4 worldEyePos = viewInverse[3];
|
||||
|
||||
Light light = getLight();
|
||||
Light light = getKeyLight();
|
||||
vec3 lightDirection = getLightDirection(light);
|
||||
|
||||
outFragColor = computeHazeColor(fragColor, eyeFragPos.xyz, worldFragPos.xyz, worldEyePos.y, lightDirection);
|
||||
|
|
|
@ -86,4 +86,24 @@ int clusterGrid_getClusterLightId(int index, int offset) {
|
|||
return (((elementIndex & 0x00000001) == 1) ? (element >> 16) : element) & 0x0000FFFF;
|
||||
}
|
||||
|
||||
|
||||
<@func fetchClusterInfo(fragWorldPos)@>
|
||||
|
||||
// From frag world pos find the cluster
|
||||
vec4 clusterEyePos = frustumGrid_worldToEye(<$fragWorldPos$>);
|
||||
ivec3 clusterPos = frustumGrid_eyeToClusterPos(clusterEyePos.xyz);
|
||||
|
||||
ivec3 cluster = clusterGrid_getCluster(frustumGrid_clusterToIndex(clusterPos));
|
||||
int numLights = cluster.x + cluster.y;
|
||||
ivec3 dims = frustumGrid.dims.xyz;
|
||||
|
||||
<@endfunc@>
|
||||
|
||||
bool hasLocalLights(int numLights, ivec3 clusterPos, ivec3 dims) {
|
||||
return numLights>0
|
||||
&& all(greaterThanEqual(clusterPos, ivec3(0)))
|
||||
&& all(lessThan(clusterPos.xy, dims.xy))
|
||||
&& clusterPos.z <= dims.z;
|
||||
}
|
||||
|
||||
<@endif@>
|
||||
|
|
148
libraries/render-utils/src/LightLocal.slh
Normal file
148
libraries/render-utils/src/LightLocal.slh
Normal file
|
@ -0,0 +1,148 @@
|
|||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// Created by Olivier Prat on 15/01/18.
|
||||
// Copyright 2018 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
|
||||
//
|
||||
|
||||
// Everything about light
|
||||
<@include graphics/Light.slh@>
|
||||
<$declareLightBuffer(256)$>
|
||||
<@include LightingModel.slh@>
|
||||
|
||||
|
||||
<@include LightPoint.slh@>
|
||||
<$declareLightingPoint(supportScattering)$>
|
||||
<@include LightSpot.slh@>
|
||||
<$declareLightingSpot(supportScattering)$>
|
||||
|
||||
<@include LightClusterGrid.slh@>
|
||||
|
||||
vec4 evalLocalLighting(ivec3 cluster, int numLights, vec3 fragWorldPos, SurfaceData surface,
|
||||
float fragMetallic, vec3 fragFresnel, vec3 fragAlbedo, float fragScattering,
|
||||
vec4 midNormalCurvature, vec4 lowNormalCurvature, float opacity) {
|
||||
vec4 fragColor = vec4(0.0);
|
||||
vec3 fragSpecular = vec3(0.0);
|
||||
vec3 fragDiffuse = vec3(0.0);
|
||||
int lightClusterOffset = cluster.z;
|
||||
|
||||
// Compute the rougness into gloss2 once:
|
||||
bool withScattering = (fragScattering * isScatteringEnabled() > 0.0);
|
||||
|
||||
int numLightTouching = 0;
|
||||
for (int i = 0; i < cluster.x; i++) {
|
||||
// Need the light now
|
||||
int theLightIndex = clusterGrid_getClusterLightId(i, lightClusterOffset);
|
||||
Light light = getLight(theLightIndex);
|
||||
|
||||
// Clip againgst the light volume and Make the Light vector going from fragment to light center in world space
|
||||
vec4 fragLightVecLen2;
|
||||
vec4 fragLightDirLen;
|
||||
|
||||
if (!lightVolume_clipFragToLightVolumePoint(light.volume, fragWorldPos.xyz, fragLightVecLen2)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Allright we re in the light sphere volume
|
||||
fragLightDirLen.w = length(fragLightVecLen2.xyz);
|
||||
fragLightDirLen.xyz = fragLightVecLen2.xyz / fragLightDirLen.w;
|
||||
if (dot(surface.normal, fragLightDirLen.xyz) < 0.0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
numLightTouching++;
|
||||
|
||||
vec3 diffuse = vec3(1.0);
|
||||
vec3 specular = vec3(0.1);
|
||||
|
||||
// Allright we re valid in the volume
|
||||
float fragLightDistance = fragLightDirLen.w;
|
||||
vec3 fragLightDir = fragLightDirLen.xyz;
|
||||
|
||||
updateSurfaceDataWithLight(surface, fragLightDir);
|
||||
|
||||
// Eval attenuation
|
||||
float radialAttenuation = lightIrradiance_evalLightAttenuation(light.irradiance, fragLightDistance);
|
||||
vec3 lightEnergy = radialAttenuation * getLightIrradiance(light);
|
||||
|
||||
// Eval shading
|
||||
if (withScattering) {
|
||||
evalFragShadingScattering(diffuse, specular, fragMetallic, fragFresnel, surface, fragAlbedo,
|
||||
fragScattering, midNormalCurvature, lowNormalCurvature );
|
||||
} else {
|
||||
evalFragShadingGloss(diffuse, specular, fragMetallic, fragFresnel, surface, fragAlbedo);
|
||||
}
|
||||
|
||||
diffuse *= lightEnergy;
|
||||
specular *= lightEnergy;
|
||||
|
||||
fragDiffuse.rgb += diffuse;
|
||||
fragSpecular.rgb += specular;
|
||||
}
|
||||
|
||||
for (int i = cluster.x; i < numLights; i++) {
|
||||
// Need the light now
|
||||
int theLightIndex = clusterGrid_getClusterLightId(i, lightClusterOffset);
|
||||
Light light = getLight(theLightIndex);
|
||||
|
||||
// Clip againgst the light volume and Make the Light vector going from fragment to light center in world space
|
||||
vec4 fragLightVecLen2;
|
||||
vec4 fragLightDirLen;
|
||||
float cosSpotAngle;
|
||||
|
||||
if (!lightVolume_clipFragToLightVolumePoint(light.volume, fragWorldPos.xyz, fragLightVecLen2)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Allright we re in the light sphere volume
|
||||
fragLightDirLen.w = length(fragLightVecLen2.xyz);
|
||||
fragLightDirLen.xyz = fragLightVecLen2.xyz / fragLightDirLen.w;
|
||||
if (dot(surface.normal, fragLightDirLen.xyz) < 0.0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check spot
|
||||
if (!lightVolume_clipFragToLightVolumeSpotSide(light.volume, fragLightDirLen, cosSpotAngle)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
numLightTouching++;
|
||||
|
||||
vec3 diffuse = vec3(1.0);
|
||||
vec3 specular = vec3(0.1);
|
||||
|
||||
// Allright we re valid in the volume
|
||||
float fragLightDistance = fragLightDirLen.w;
|
||||
vec3 fragLightDir = fragLightDirLen.xyz;
|
||||
|
||||
updateSurfaceDataWithLight(surface, fragLightDir);
|
||||
|
||||
// Eval attenuation
|
||||
float radialAttenuation = lightIrradiance_evalLightAttenuation(light.irradiance, fragLightDistance);
|
||||
float angularAttenuation = lightIrradiance_evalLightSpotAttenuation(light.irradiance, cosSpotAngle);
|
||||
vec3 lightEnergy = radialAttenuation * angularAttenuation * getLightIrradiance(light);
|
||||
|
||||
// Eval shading
|
||||
if (withScattering) {
|
||||
evalFragShadingScattering(diffuse, specular, fragMetallic, fragFresnel, surface, fragAlbedo,
|
||||
fragScattering, midNormalCurvature, lowNormalCurvature );
|
||||
} else {
|
||||
evalFragShadingGloss(diffuse, specular, fragMetallic, fragFresnel, surface, fragAlbedo);
|
||||
}
|
||||
|
||||
diffuse *= lightEnergy;
|
||||
specular *= lightEnergy;
|
||||
|
||||
fragDiffuse.rgb += diffuse;
|
||||
fragSpecular.rgb += specular;
|
||||
}
|
||||
|
||||
fragDiffuse *= isDiffuseEnabled();
|
||||
fragSpecular *= isSpecularEnabled();
|
||||
|
||||
fragColor.rgb += fragDiffuse;
|
||||
fragColor.rgb += fragSpecular / opacity;
|
||||
return fragColor;
|
||||
}
|
|
@ -289,9 +289,8 @@ void evalFragShading(out vec3 diffuse, out vec3 specular,
|
|||
|
||||
|
||||
void evalFragShadingScattering(out vec3 diffuse, out vec3 specular,
|
||||
float metallic, vec3 fresnel, SurfaceData surface, vec3 albedo
|
||||
,float scattering, vec4 midNormalCurvature, vec4 lowNormalCurvature
|
||||
) {
|
||||
float metallic, vec3 fresnel, SurfaceData surface, vec3 albedo,
|
||||
float scattering, vec4 midNormalCurvature, vec4 lowNormalCurvature) {
|
||||
vec3 brdf = evalSkinBRDF(surface.lightDir, surface.normal, midNormalCurvature.xyz, lowNormalCurvature.xyz, lowNormalCurvature.w);
|
||||
float NdotL = surface.ndotl;
|
||||
diffuse = mix(vec3(NdotL), brdf, scattering);
|
||||
|
@ -305,8 +304,7 @@ void evalFragShadingScattering(out vec3 diffuse, out vec3 specular,
|
|||
}
|
||||
|
||||
void evalFragShadingGloss(out vec3 diffuse, out vec3 specular,
|
||||
float metallic, vec3 fresnel, SurfaceData surface, vec3 albedo
|
||||
) {
|
||||
float metallic, vec3 fresnel, SurfaceData surface, vec3 albedo) {
|
||||
vec4 shading = evalPBRShading(metallic, fresnel, surface);
|
||||
diffuse = vec3(shading.w);
|
||||
diffuse *= mix(vec3(1.0), albedo, isAlbedoEnabled());
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
|
||||
#include "RenderDeferredTask.h"
|
||||
|
||||
#include <DependencyManager.h>
|
||||
|
||||
#include <PerfStat.h>
|
||||
#include <PathUtils.h>
|
||||
#include <ViewFrustum.h>
|
||||
|
@ -168,7 +170,7 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
|
|||
task.addJob<DrawHaze>("DrawHazeDeferred", drawHazeInputs);
|
||||
|
||||
// Render transparent objects forward in LightingBuffer
|
||||
const auto transparentsInputs = DrawDeferred::Inputs(transparents, lightingModel).asVarying();
|
||||
const auto transparentsInputs = DrawDeferred::Inputs(transparents, lightingModel, lightClusters).asVarying();
|
||||
task.addJob<DrawDeferred>("DrawTransparentDeferred", transparentsInputs, shapePlumber);
|
||||
|
||||
// Light Cluster Grid Debuging job
|
||||
|
@ -298,6 +300,8 @@ void DrawDeferred::run(const RenderContextPointer& renderContext, const Inputs&
|
|||
|
||||
const auto& inItems = inputs.get0();
|
||||
const auto& lightingModel = inputs.get1();
|
||||
const auto& lightClusters = inputs.get2();
|
||||
auto deferredLightingEffect = DependencyManager::get<DeferredLightingEffect>();
|
||||
|
||||
RenderArgs* args = renderContext->args;
|
||||
|
||||
|
@ -319,7 +323,13 @@ void DrawDeferred::run(const RenderContextPointer& renderContext, const Inputs&
|
|||
// Setup lighting model for all items;
|
||||
batch.setUniformBuffer(render::ShapePipeline::Slot::LIGHTING_MODEL, lightingModel->getParametersBuffer());
|
||||
|
||||
// Setup haze iff current zone has haze
|
||||
deferredLightingEffect->setupLocalLightsBatch(batch,
|
||||
render::ShapePipeline::Slot::LIGHT_CLUSTER_GRID_CLUSTER_GRID_SLOT,
|
||||
render::ShapePipeline::Slot::LIGHT_CLUSTER_GRID_CLUSTER_CONTENT_SLOT,
|
||||
render::ShapePipeline::Slot::LIGHT_CLUSTER_GRID_FRUSTUM_GRID_SLOT,
|
||||
lightClusters);
|
||||
|
||||
// Setup haze if current zone has haze
|
||||
auto hazeStage = args->_scene->getStage<HazeStage>();
|
||||
if (hazeStage && hazeStage->_currentFrame._hazes.size() > 0) {
|
||||
graphics::HazePointer hazePointer = hazeStage->getHaze(hazeStage->_currentFrame._hazes.front());
|
||||
|
@ -341,6 +351,11 @@ void DrawDeferred::run(const RenderContextPointer& renderContext, const Inputs&
|
|||
|
||||
args->_batch = nullptr;
|
||||
args->_globalShapeKey = 0;
|
||||
|
||||
deferredLightingEffect->unsetLocalLightsBatch(batch,
|
||||
render::ShapePipeline::Slot::LIGHT_CLUSTER_GRID_CLUSTER_GRID_SLOT,
|
||||
render::ShapePipeline::Slot::LIGHT_CLUSTER_GRID_CLUSTER_CONTENT_SLOT,
|
||||
render::ShapePipeline::Slot::LIGHT_CLUSTER_GRID_FRUSTUM_GRID_SLOT);
|
||||
});
|
||||
|
||||
config->setNumDrawn((int)inItems.size());
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <gpu/Pipeline.h>
|
||||
#include <render/RenderFetchCullSortTask.h>
|
||||
#include "LightingModel.h"
|
||||
#include "LightClusters.h"
|
||||
|
||||
class DrawDeferredConfig : public render::Job::Config {
|
||||
Q_OBJECT
|
||||
|
@ -40,7 +41,7 @@ protected:
|
|||
|
||||
class DrawDeferred {
|
||||
public:
|
||||
using Inputs = render::VaryingSet2<render::ItemBounds, LightingModelPointer>;
|
||||
using Inputs = render::VaryingSet3 <render::ItemBounds, LightingModelPointer, LightClustersPointer>;
|
||||
using Config = DrawDeferredConfig;
|
||||
using JobModel = render::Job::ModelI<DrawDeferred, Inputs, Config>;
|
||||
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
|
||||
#include "model_lightmap_fade_vert.h"
|
||||
#include "model_lightmap_normal_map_fade_vert.h"
|
||||
#include "model_translucent_vert.h"
|
||||
#include "model_translucent_fade_vert.h"
|
||||
#include "skin_model_fade_vert.h"
|
||||
#include "skin_model_normal_map_fade_vert.h"
|
||||
|
||||
|
@ -188,6 +190,8 @@ void initDeferredPipelines(render::ShapePlumber& plumber, const render::ShapePip
|
|||
auto modelNormalMapVertex = gpu::Shader::createVertex(std::string(model_normal_map_vert));
|
||||
auto modelLightmapVertex = gpu::Shader::createVertex(std::string(model_lightmap_vert));
|
||||
auto modelLightmapNormalMapVertex = gpu::Shader::createVertex(std::string(model_lightmap_normal_map_vert));
|
||||
auto modelTranslucentVertex = gpu::Shader::createVertex(std::string(model_translucent_vert));
|
||||
auto modelTranslucentFadeVertex = gpu::Shader::createVertex(std::string(model_translucent_fade_vert));
|
||||
auto modelShadowVertex = gpu::Shader::createVertex(std::string(model_shadow_vert));
|
||||
auto skinModelVertex = gpu::Shader::createVertex(std::string(skin_model_vert));
|
||||
auto skinModelNormalMapVertex = gpu::Shader::createVertex(std::string(skin_model_normal_map_vert));
|
||||
|
@ -196,6 +200,8 @@ void initDeferredPipelines(render::ShapePlumber& plumber, const render::ShapePip
|
|||
auto modelLightmapNormalMapFadeVertex = gpu::Shader::createVertex(std::string(model_lightmap_normal_map_fade_vert));
|
||||
auto skinModelFadeVertex = gpu::Shader::createVertex(std::string(skin_model_fade_vert));
|
||||
auto skinModelNormalMapFadeVertex = gpu::Shader::createVertex(std::string(skin_model_normal_map_fade_vert));
|
||||
auto skinModelTranslucentVertex = skinModelFadeVertex; // We use the same because it ouputs world position per vertex
|
||||
auto skinModelNormalMapTranslucentVertex = skinModelNormalMapFadeVertex; // We use the same because it ouputs world position per vertex
|
||||
|
||||
auto modelFadeVertex = gpu::Shader::createVertex(std::string(model_fade_vert));
|
||||
auto modelNormalMapFadeVertex = gpu::Shader::createVertex(std::string(model_normal_map_fade_vert));
|
||||
|
@ -289,7 +295,7 @@ void initDeferredPipelines(render::ShapePlumber& plumber, const render::ShapePip
|
|||
// Translucents
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withTranslucent(),
|
||||
modelVertex, modelTranslucentPixel, nullptr, nullptr);
|
||||
modelTranslucentVertex, modelTranslucentPixel, nullptr, nullptr);
|
||||
addPipeline(
|
||||
Key::Builder().withTranslucent(),
|
||||
simpleVertex, simpleTranslucentPixel, nullptr, nullptr);
|
||||
|
@ -301,21 +307,21 @@ void initDeferredPipelines(render::ShapePlumber& plumber, const render::ShapePip
|
|||
simpleVertex, simpleTranslucentUnlitPixel, nullptr, nullptr);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withTranslucent().withTangents(),
|
||||
modelNormalMapVertex, modelTranslucentPixel, nullptr, nullptr);
|
||||
modelTranslucentVertex, modelTranslucentPixel, nullptr, nullptr);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withTranslucent().withSpecular(),
|
||||
modelVertex, modelTranslucentPixel, nullptr, nullptr);
|
||||
modelTranslucentVertex, modelTranslucentPixel, nullptr, nullptr);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withTranslucent().withTangents().withSpecular(),
|
||||
modelNormalMapVertex, modelTranslucentPixel, nullptr, nullptr);
|
||||
modelTranslucentVertex, modelTranslucentPixel, nullptr, nullptr);
|
||||
addPipeline(
|
||||
// FIXME: Ignore lightmap for translucents meshpart
|
||||
Key::Builder().withMaterial().withTranslucent().withLightmap(),
|
||||
modelVertex, modelTranslucentPixel, nullptr, nullptr);
|
||||
modelTranslucentVertex, modelTranslucentPixel, nullptr, nullptr);
|
||||
// Same thing but with Fade on
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withTranslucent().withFade(),
|
||||
modelFadeVertex, modelTranslucentFadePixel, batchSetter, itemSetter);
|
||||
modelTranslucentFadeVertex, modelTranslucentFadePixel, batchSetter, itemSetter);
|
||||
addPipeline(
|
||||
Key::Builder().withTranslucent().withFade(),
|
||||
simpleFadeVertex, simpleTranslucentFadePixel, batchSetter, itemSetter);
|
||||
|
@ -396,16 +402,16 @@ void initDeferredPipelines(render::ShapePlumber& plumber, const render::ShapePip
|
|||
// Skinned and Translucent
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withTranslucent(),
|
||||
skinModelVertex, modelTranslucentPixel, nullptr, nullptr);
|
||||
skinModelTranslucentVertex, modelTranslucentPixel, nullptr, nullptr);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withTranslucent().withTangents(),
|
||||
skinModelNormalMapVertex, modelTranslucentPixel, nullptr, nullptr);
|
||||
skinModelNormalMapTranslucentVertex, modelTranslucentPixel, nullptr, nullptr);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withTranslucent().withSpecular(),
|
||||
skinModelVertex, modelTranslucentPixel, nullptr, nullptr);
|
||||
skinModelTranslucentVertex, modelTranslucentPixel, nullptr, nullptr);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withTranslucent().withTangents().withSpecular(),
|
||||
skinModelNormalMapVertex, modelTranslucentPixel, nullptr, nullptr);
|
||||
skinModelNormalMapTranslucentVertex, modelTranslucentPixel, nullptr, nullptr);
|
||||
// Same thing but with Fade on
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withTranslucent().withFade(),
|
||||
|
@ -571,9 +577,9 @@ void lightBatchSetter(const ShapePipeline& pipeline, gpu::Batch& batch, RenderAr
|
|||
batchSetter(pipeline, batch, args);
|
||||
|
||||
// Set the light
|
||||
if (pipeline.locations->lightBufferUnit >= 0) {
|
||||
if (pipeline.locations->keyLightBufferUnit >= 0) {
|
||||
DependencyManager::get<DeferredLightingEffect>()->setupKeyLightBatch(args, batch,
|
||||
pipeline.locations->lightBufferUnit,
|
||||
pipeline.locations->keyLightBufferUnit,
|
||||
pipeline.locations->lightAmbientBufferUnit,
|
||||
pipeline.locations->lightAmbientMapUnit);
|
||||
}
|
||||
|
|
|
@ -463,7 +463,7 @@ gpu::PipelinePointer DebugSubsurfaceScattering::getScatteringPipeline() {
|
|||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), ScatteringTask_FrameTransformSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("scatteringParamsBuffer"), ScatteringTask_ParamSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), ScatteringTask_LightSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("keyLightBuffer"), ScatteringTask_LightSlot));
|
||||
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("scatteringLUT"), ScatteringTask_ScatteringTableSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("curvatureMap"), ScatteringTask_CurvatureMapSlot));
|
||||
|
|
|
@ -83,7 +83,7 @@ const gpu::PipelinePointer& DebugZoneLighting::getKeyLightPipeline() {
|
|||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), ZONE_DEFERRED_TRANSFORM_BUFFER));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), ZONE_KEYLIGHT_BUFFER));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("keyLightBuffer"), ZONE_KEYLIGHT_BUFFER));
|
||||
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
|
||||
|
|
|
@ -54,26 +54,8 @@ void main(void) {
|
|||
mat4 invViewMat = getViewInverse();
|
||||
vec4 fragPos = invViewMat * fragPosition;
|
||||
|
||||
// From frag world pos find the cluster
|
||||
vec4 clusterEyePos = frustumGrid_worldToEye(fragPos);
|
||||
ivec3 clusterPos = frustumGrid_eyeToClusterPos(clusterEyePos.xyz);
|
||||
|
||||
ivec3 cluster = clusterGrid_getCluster(frustumGrid_clusterToIndex(clusterPos));
|
||||
int numLights = cluster.x + cluster.y;
|
||||
if (numLights <= 0) {
|
||||
discard;
|
||||
}
|
||||
int lightClusterOffset = cluster.z;
|
||||
|
||||
ivec3 dims = frustumGrid.dims.xyz;
|
||||
if (clusterPos.x < 0 || clusterPos.x >= dims.x) {
|
||||
discard;
|
||||
}
|
||||
|
||||
if (clusterPos.y < 0 || clusterPos.y >= dims.y) {
|
||||
discard;
|
||||
}
|
||||
if (clusterPos.z < 0 || clusterPos.z > dims.z) {
|
||||
<$fetchClusterInfo(fragPos)$>;
|
||||
if (!hasLocalLights(numLights, clusterPos, dims)) {
|
||||
discard;
|
||||
}
|
||||
|
||||
|
@ -82,6 +64,7 @@ void main(void) {
|
|||
vec3 fragEyeDir = normalize(fragEyeVector.xyz);
|
||||
|
||||
int numLightTouching = 0;
|
||||
int lightClusterOffset = cluster.z;
|
||||
for (int i = 0; i < cluster.x; i++) {
|
||||
// Need the light now
|
||||
int theLightIndex = clusterGrid_getClusterLightId(i, lightClusterOffset);
|
||||
|
|
|
@ -17,18 +17,7 @@
|
|||
|
||||
<$declareDeferredCurvature()$>
|
||||
|
||||
// Everything about light
|
||||
<@include graphics/Light.slh@>
|
||||
<$declareLightBuffer(256)$>
|
||||
<@include LightingModel.slh@>
|
||||
|
||||
|
||||
<@include LightPoint.slh@>
|
||||
<$declareLightingPoint(supportScattering)$>
|
||||
<@include LightSpot.slh@>
|
||||
<$declareLightingSpot(supportScattering)$>
|
||||
|
||||
<@include LightClusterGrid.slh@>
|
||||
<@include LightLocal.slh@>
|
||||
|
||||
in vec2 _texCoord0;
|
||||
out vec4 _fragColor;
|
||||
|
@ -49,28 +38,10 @@ void main(void) {
|
|||
|
||||
// Frag pos in world
|
||||
mat4 invViewMat = getViewInverse();
|
||||
vec4 fragPos = invViewMat * fragPosition;
|
||||
vec4 fragWorldPos = invViewMat * fragPosition;
|
||||
|
||||
// From frag world pos find the cluster
|
||||
vec4 clusterEyePos = frustumGrid_worldToEye(fragPos);
|
||||
ivec3 clusterPos = frustumGrid_eyeToClusterPos(clusterEyePos.xyz);
|
||||
|
||||
ivec3 cluster = clusterGrid_getCluster(frustumGrid_clusterToIndex(clusterPos));
|
||||
int numLights = cluster.x + cluster.y;
|
||||
if (numLights <= 0) {
|
||||
discard;
|
||||
}
|
||||
int lightClusterOffset = cluster.z;
|
||||
|
||||
ivec3 dims = frustumGrid.dims.xyz;
|
||||
if (clusterPos.x < 0 || clusterPos.x >= dims.x) {
|
||||
discard;
|
||||
}
|
||||
|
||||
if (clusterPos.y < 0 || clusterPos.y >= dims.y) {
|
||||
discard;
|
||||
}
|
||||
if (clusterPos.z < 0 || clusterPos.z > dims.z) {
|
||||
<$fetchClusterInfo(fragWorldPos)$>;
|
||||
if (!hasLocalLights(numLights, clusterPos, dims)) {
|
||||
discard;
|
||||
}
|
||||
|
||||
|
@ -84,117 +55,11 @@ void main(void) {
|
|||
// Frag to eye vec
|
||||
vec4 fragEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0);
|
||||
vec3 fragEyeDir = normalize(fragEyeVector.xyz);
|
||||
|
||||
SurfaceData surface = initSurfaceData(frag.roughness, frag.normal, fragEyeDir);
|
||||
bool withScattering = (frag.scattering * isScatteringEnabled() > 0.0);
|
||||
|
||||
int numLightTouching = 0;
|
||||
for (int i = 0; i < cluster.x; i++) {
|
||||
// Need the light now
|
||||
int theLightIndex = clusterGrid_getClusterLightId(i, lightClusterOffset);
|
||||
Light light = getLight(theLightIndex);
|
||||
|
||||
// Clip againgst the light volume and Make the Light vector going from fragment to light center in world space
|
||||
vec4 fragLightVecLen2;
|
||||
vec4 fragLightDirLen;
|
||||
|
||||
if (!lightVolume_clipFragToLightVolumePoint(light.volume, fragPos.xyz, fragLightVecLen2)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Allright we re in the light sphere volume
|
||||
fragLightDirLen.w = length(fragLightVecLen2.xyz);
|
||||
fragLightDirLen.xyz = fragLightVecLen2.xyz / fragLightDirLen.w;
|
||||
if (dot(frag.normal, fragLightDirLen.xyz) < 0.0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
numLightTouching++;
|
||||
|
||||
vec3 diffuse = vec3(1.0);
|
||||
vec3 specular = vec3(0.1);
|
||||
|
||||
// Allright we re valid in the volume
|
||||
float fragLightDistance = fragLightDirLen.w;
|
||||
vec3 fragLightDir = fragLightDirLen.xyz;
|
||||
|
||||
updateSurfaceDataWithLight(surface, fragLightDir);
|
||||
|
||||
// Eval attenuation
|
||||
float radialAttenuation = lightIrradiance_evalLightAttenuation(light.irradiance, fragLightDistance);
|
||||
vec3 lightEnergy = radialAttenuation * getLightIrradiance(light);
|
||||
|
||||
// Eval shading
|
||||
if (withScattering) {
|
||||
evalFragShadingScattering(diffuse, specular, frag.metallic, frag.fresnel, surface, frag.albedo
|
||||
,frag.scattering, midNormalCurvature, lowNormalCurvature );
|
||||
} else {
|
||||
evalFragShadingGloss(diffuse, specular, frag.metallic, frag.fresnel, surface, frag.albedo);
|
||||
}
|
||||
|
||||
diffuse *= lightEnergy * isDiffuseEnabled();
|
||||
specular *= lightEnergy * isSpecularEnabled();
|
||||
|
||||
_fragColor.rgb += diffuse;
|
||||
_fragColor.rgb += specular;
|
||||
}
|
||||
|
||||
for (int i = cluster.x; i < numLights; i++) {
|
||||
// Need the light now
|
||||
int theLightIndex = clusterGrid_getClusterLightId(i, lightClusterOffset);
|
||||
Light light = getLight(theLightIndex);
|
||||
|
||||
// Clip againgst the light volume and Make the Light vector going from fragment to light center in world space
|
||||
vec4 fragLightVecLen2;
|
||||
vec4 fragLightDirLen;
|
||||
float cosSpotAngle;
|
||||
|
||||
if (!lightVolume_clipFragToLightVolumePoint(light.volume, fragPos.xyz, fragLightVecLen2)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Allright we re in the light sphere volume
|
||||
fragLightDirLen.w = length(fragLightVecLen2.xyz);
|
||||
fragLightDirLen.xyz = fragLightVecLen2.xyz / fragLightDirLen.w;
|
||||
if (dot(frag.normal, fragLightDirLen.xyz) < 0.0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check spot
|
||||
if (!lightVolume_clipFragToLightVolumeSpotSide(light.volume, fragLightDirLen, cosSpotAngle)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
numLightTouching++;
|
||||
|
||||
vec3 diffuse = vec3(1.0);
|
||||
vec3 specular = vec3(0.1);
|
||||
|
||||
// Allright we re valid in the volume
|
||||
float fragLightDistance = fragLightDirLen.w;
|
||||
vec3 fragLightDir = fragLightDirLen.xyz;
|
||||
|
||||
updateSurfaceDataWithLight(surface, fragLightDir);
|
||||
|
||||
// Eval attenuation
|
||||
float radialAttenuation = lightIrradiance_evalLightAttenuation(light.irradiance, fragLightDistance);
|
||||
float angularAttenuation = lightIrradiance_evalLightSpotAttenuation(light.irradiance, cosSpotAngle);
|
||||
vec3 lightEnergy = radialAttenuation * angularAttenuation * getLightIrradiance(light);
|
||||
|
||||
// Eval shading
|
||||
if (withScattering) {
|
||||
evalFragShadingScattering(diffuse, specular, frag.metallic, frag.fresnel, surface, frag.albedo
|
||||
,frag.scattering, midNormalCurvature, lowNormalCurvature );
|
||||
} else {
|
||||
evalFragShadingGloss(diffuse, specular, frag.metallic, frag.fresnel, surface, frag.albedo);
|
||||
}
|
||||
|
||||
diffuse *= lightEnergy * isDiffuseEnabled();
|
||||
specular *= lightEnergy * isSpecularEnabled();
|
||||
|
||||
_fragColor.rgb += diffuse;
|
||||
_fragColor.rgb += specular;
|
||||
}
|
||||
_fragColor = evalLocalLighting(cluster, numLights, fragWorldPos.xyz, surface,
|
||||
frag.metallic, frag.fresnel, frag.albedo, frag.scattering,
|
||||
midNormalCurvature, lowNormalCurvature, 1.0);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
|
||||
<$declareEvalGlobalLightingAlphaBlended()$>
|
||||
|
||||
<@include LightLocal.slh@>
|
||||
|
||||
<@include gpu/Transform.slh@>
|
||||
<$declareStandardCameraTransform()$>
|
||||
|
||||
|
@ -27,6 +29,7 @@
|
|||
in vec2 _texCoord0;
|
||||
in vec2 _texCoord1;
|
||||
in vec4 _position;
|
||||
in vec4 _worldPosition;
|
||||
in vec3 _normal;
|
||||
in vec3 _color;
|
||||
in float _alpha;
|
||||
|
@ -56,20 +59,32 @@ void main(void) {
|
|||
<$evalMaterialEmissive(emissiveTex, emissive, matKey, emissive)$>;
|
||||
|
||||
vec3 fragPosition = _position.xyz;
|
||||
// Lighting is done in world space
|
||||
vec3 fragNormal = normalize(_normal);
|
||||
|
||||
TransformCamera cam = getTransformCamera();
|
||||
vec3 fragEyeVector = vec3(cam._viewInverse * vec4(-fragPosition, 0.0));
|
||||
vec3 fragEyeDir = normalize(fragEyeVector);
|
||||
SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir);
|
||||
|
||||
vec4 localLighting = vec4(0.0);
|
||||
|
||||
<$fetchClusterInfo(_worldPosition)$>;
|
||||
if (hasLocalLights(numLights, clusterPos, dims)) {
|
||||
localLighting = evalLocalLighting(cluster, numLights, _worldPosition.xyz, surface,
|
||||
metallic, fresnel, albedo, 0.0,
|
||||
vec4(0), vec4(0), opacity);
|
||||
}
|
||||
|
||||
_fragColor = vec4(evalGlobalLightingAlphaBlendedWithHaze(
|
||||
cam._viewInverse,
|
||||
1.0,
|
||||
occlusionTex,
|
||||
fragPosition,
|
||||
fragNormal,
|
||||
albedo,
|
||||
fresnel,
|
||||
metallic,
|
||||
emissive,
|
||||
roughness, opacity),
|
||||
surface, opacity, localLighting.rgb),
|
||||
opacity);
|
||||
}
|
||||
|
|
44
libraries/render-utils/src/model_translucent.slv
Normal file
44
libraries/render-utils/src/model_translucent.slv
Normal file
|
@ -0,0 +1,44 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
// model_translucent.slv
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Olivier Prat on 15/01/18.
|
||||
// Copyright 2018 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
|
||||
//
|
||||
|
||||
<@include gpu/Inputs.slh@>
|
||||
<@include gpu/Color.slh@>
|
||||
<@include gpu/Transform.slh@>
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
<@include MaterialTextures.slh@>
|
||||
<$declareMaterialTexMapArrayBuffer()$>
|
||||
|
||||
out float _alpha;
|
||||
out vec2 _texCoord0;
|
||||
out vec2 _texCoord1;
|
||||
out vec4 _position;
|
||||
out vec4 _worldPosition;
|
||||
out vec3 _normal;
|
||||
out vec3 _color;
|
||||
|
||||
void main(void) {
|
||||
_color = colorToLinearRGB(inColor.xyz);
|
||||
_alpha = inColor.w;
|
||||
|
||||
TexMapArray texMapArray = getTexMapArray();
|
||||
<$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _texCoord0)$>
|
||||
<$evalTexMapArrayTexcoord1(texMapArray, inTexCoord0, _texCoord1)$>
|
||||
|
||||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToEyeAndClipPos(cam, obj, inPosition, _position, gl_Position)$>
|
||||
<$transformModelToWorldPos(obj, inPosition, _worldPosition)$>
|
||||
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normal)$>
|
||||
}
|
|
@ -18,6 +18,8 @@
|
|||
|
||||
<$declareEvalGlobalLightingAlphaBlended()$>
|
||||
|
||||
<@include LightLocal.slh@>
|
||||
|
||||
<@include gpu/Transform.slh@>
|
||||
<$declareStandardCameraTransform()$>
|
||||
|
||||
|
@ -66,20 +68,32 @@ void main(void) {
|
|||
<$evalMaterialEmissive(emissiveTex, emissive, matKey, emissive)$>;
|
||||
|
||||
vec3 fragPosition = _position.xyz;
|
||||
// Lighting is done in world space
|
||||
vec3 fragNormal = normalize(_normal);
|
||||
|
||||
TransformCamera cam = getTransformCamera();
|
||||
vec3 fragEyeVector = vec3(cam._viewInverse * vec4(-fragPosition, 0.0));
|
||||
vec3 fragEyeDir = normalize(fragEyeVector);
|
||||
SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir);
|
||||
|
||||
vec4 localLighting = vec4(0.0);
|
||||
|
||||
<$fetchClusterInfo(_worldPosition)$>;
|
||||
if (hasLocalLights(numLights, clusterPos, dims)) {
|
||||
localLighting = evalLocalLighting(cluster, numLights, _worldPosition.xyz, surface,
|
||||
metallic, fresnel, albedo, 0.0,
|
||||
vec4(0), vec4(0), opacity);
|
||||
}
|
||||
|
||||
_fragColor = vec4(evalGlobalLightingAlphaBlendedWithHaze(
|
||||
cam._viewInverse,
|
||||
1.0,
|
||||
occlusionTex,
|
||||
fragPosition,
|
||||
fragNormal,
|
||||
albedo,
|
||||
fresnel,
|
||||
metallic,
|
||||
emissive+fadeEmissive,
|
||||
roughness, opacity),
|
||||
surface, opacity, localLighting.rgb),
|
||||
opacity);
|
||||
}
|
||||
|
|
44
libraries/render-utils/src/model_translucent_fade.slv
Normal file
44
libraries/render-utils/src/model_translucent_fade.slv
Normal file
|
@ -0,0 +1,44 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
// model_translucent_fade.slv
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Olivier Prat on 15/01/18.
|
||||
// Copyright 2018 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
|
||||
//
|
||||
|
||||
<@include gpu/Inputs.slh@>
|
||||
<@include gpu/Color.slh@>
|
||||
<@include gpu/Transform.slh@>
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
<@include MaterialTextures.slh@>
|
||||
<$declareMaterialTexMapArrayBuffer()$>
|
||||
|
||||
out float _alpha;
|
||||
out vec2 _texCoord0;
|
||||
out vec2 _texCoord1;
|
||||
out vec4 _position;
|
||||
out vec4 _worldPosition;
|
||||
out vec3 _normal;
|
||||
out vec3 _color;
|
||||
|
||||
void main(void) {
|
||||
_color = colorToLinearRGB(inColor.xyz);
|
||||
_alpha = inColor.w;
|
||||
|
||||
TexMapArray texMapArray = getTexMapArray();
|
||||
<$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _texCoord0)$>
|
||||
<$evalTexMapArrayTexcoord1(texMapArray, inTexCoord0, _texCoord1)$>
|
||||
|
||||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToEyeAndClipPos(cam, obj, inPosition, _position, gl_Position)$>
|
||||
<$transformModelToWorldPos(obj, inPosition, _worldPosition)$>
|
||||
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normal)$>
|
||||
}
|
|
@ -27,7 +27,7 @@
|
|||
vec4 evalGlobalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 fresnel, float roughness, float opacity) {
|
||||
|
||||
// Need the light now
|
||||
Light light = getLight();
|
||||
Light light = getKeyLight();
|
||||
vec3 lightDirection = getLightDirection(light);
|
||||
vec3 lightIrradiance = getLightIrradiance(light);
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
vec4 evalGlobalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 fresnel, float roughness, float opacity) {
|
||||
|
||||
// Need the light now
|
||||
Light light = getLight();
|
||||
Light light = getKeyLight();
|
||||
vec3 lightDirection = getLightDirection(light);
|
||||
vec3 lightIrradiance = getLightIrradiance(light);
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ vec3 evalScatteringBRDF(vec2 texcoord) {
|
|||
vec3 fragNormal = vec3((normal));
|
||||
|
||||
// Get light
|
||||
Light light = getLight();
|
||||
Light light = getKeyLight();
|
||||
vec3 fresnel = vec3(0.028); // Default Di-electric fresnel value for skin
|
||||
float metallic = 0.0;
|
||||
|
||||
|
@ -65,7 +65,7 @@ vec3 drawScatteringTableUV(vec2 cursor, vec2 texcoord) {
|
|||
float curvature = unpackCurvature(diffusedCurvature.w);
|
||||
|
||||
// Get light
|
||||
Light light = getLight();
|
||||
Light light = getKeyLight();
|
||||
vec3 fresnel = vec3(0.028); // Default Di-electric fresnel value for skin
|
||||
|
||||
vec3 fragLightDir = -normalize(getLightDirection(light));
|
||||
|
|
|
@ -25,7 +25,7 @@ void main(void) {
|
|||
|
||||
<$evalGlobeWidget()$>
|
||||
|
||||
Light light = getLight();
|
||||
Light light = getKeyLight();
|
||||
vec3 lightDirection = normalize(getLightDirection(light));
|
||||
vec3 lightIrradiance = getLightIrradiance(light);
|
||||
vec3 color = vec3(0.0);
|
||||
|
|
|
@ -70,6 +70,8 @@ void ShapePlumber::addPipeline(const Key& key, const gpu::ShaderPointer& program
|
|||
|
||||
void ShapePlumber::addPipeline(const Filter& filter, const gpu::ShaderPointer& program, const gpu::StatePointer& state,
|
||||
BatchSetter batchSetter, ItemSetter itemSetter) {
|
||||
ShapeKey key{ filter._flags };
|
||||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("lightingModelBuffer"), Slot::BUFFER::LIGHTING_MODEL));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("skinClusterBuffer"), Slot::BUFFER::SKINNING));
|
||||
|
@ -82,6 +84,7 @@ void ShapePlumber::addPipeline(const Filter& filter, const gpu::ShaderPointer& p
|
|||
slotBindings.insert(gpu::Shader::Binding(std::string("emissiveMap"), Slot::MAP::EMISSIVE_LIGHTMAP));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("occlusionMap"), Slot::MAP::OCCLUSION));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("scatteringMap"), Slot::MAP::SCATTERING));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("keyLightBuffer"), Slot::BUFFER::KEY_LIGHT));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), Slot::BUFFER::LIGHT));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("lightAmbientBuffer"), Slot::BUFFER::LIGHT_AMBIENT_BUFFER));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("skyboxMap"), Slot::MAP::LIGHT_AMBIENT));
|
||||
|
@ -89,6 +92,12 @@ void ShapePlumber::addPipeline(const Filter& filter, const gpu::ShaderPointer& p
|
|||
slotBindings.insert(gpu::Shader::Binding(std::string("fadeParametersBuffer"), Slot::BUFFER::FADE_PARAMETERS));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("hazeBuffer"), Slot::BUFFER::HAZE_MODEL));
|
||||
|
||||
if (key.isTranslucent()) {
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("clusterGridBuffer"), Slot::BUFFER::LIGHT_CLUSTER_GRID_CLUSTER_GRID_SLOT));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("clusterContentBuffer"), Slot::BUFFER::LIGHT_CLUSTER_GRID_CLUSTER_CONTENT_SLOT));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("frustumGridBuffer"), Slot::BUFFER::LIGHT_CLUSTER_GRID_FRUSTUM_GRID_SLOT));
|
||||
}
|
||||
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
|
||||
auto locations = std::make_shared<Locations>();
|
||||
|
@ -103,14 +112,23 @@ void ShapePlumber::addPipeline(const Filter& filter, const gpu::ShaderPointer& p
|
|||
locations->skinClusterBufferUnit = program->getUniformBuffers().findLocation("skinClusterBuffer");
|
||||
locations->materialBufferUnit = program->getUniformBuffers().findLocation("materialBuffer");
|
||||
locations->texMapArrayBufferUnit = program->getUniformBuffers().findLocation("texMapArrayBuffer");
|
||||
locations->keyLightBufferUnit = program->getUniformBuffers().findLocation("keyLightBuffer");
|
||||
locations->lightBufferUnit = program->getUniformBuffers().findLocation("lightBuffer");
|
||||
locations->lightAmbientBufferUnit = program->getUniformBuffers().findLocation("lightAmbientBuffer");
|
||||
locations->lightAmbientMapUnit = program->getTextures().findLocation("skyboxMap");
|
||||
locations->fadeMaskTextureUnit = program->getTextures().findLocation("fadeMaskMap");
|
||||
locations->fadeParameterBufferUnit = program->getUniformBuffers().findLocation("fadeParametersBuffer");
|
||||
locations->hazeParameterBufferUnit = program->getUniformBuffers().findLocation("hazeParametersBuffer");
|
||||
if (key.isTranslucent()) {
|
||||
locations->lightClusterGridBufferUnit = program->getUniformBuffers().findLocation("clusterGridBuffer");
|
||||
locations->lightClusterContentBufferUnit = program->getUniformBuffers().findLocation("clusterContentBuffer");
|
||||
locations->lightClusterFrustumBufferUnit = program->getUniformBuffers().findLocation("frustumGridBuffer");
|
||||
} else {
|
||||
locations->lightClusterGridBufferUnit = -1;
|
||||
locations->lightClusterContentBufferUnit = -1;
|
||||
locations->lightClusterFrustumBufferUnit = -1;
|
||||
}
|
||||
|
||||
ShapeKey key{filter._flags};
|
||||
auto gpuPipeline = gpu::Pipeline::create(program, state);
|
||||
auto shapePipeline = std::make_shared<Pipeline>(gpuPipeline, locations, batchSetter, itemSetter);
|
||||
addPipelineHelper(filter, key, 0, shapePipeline);
|
||||
|
|
|
@ -235,10 +235,15 @@ public:
|
|||
MATERIAL,
|
||||
TEXMAPARRAY,
|
||||
LIGHTING_MODEL,
|
||||
KEY_LIGHT,
|
||||
LIGHT,
|
||||
LIGHT_AMBIENT_BUFFER,
|
||||
HAZE_MODEL,
|
||||
FADE_PARAMETERS,
|
||||
LIGHT_CLUSTER_GRID_FRUSTUM_GRID_SLOT,
|
||||
LIGHT_CLUSTER_GRID_CLUSTER_GRID_SLOT,
|
||||
LIGHT_CLUSTER_GRID_CLUSTER_CONTENT_SLOT,
|
||||
|
||||
};
|
||||
|
||||
enum MAP {
|
||||
|
@ -266,12 +271,16 @@ public:
|
|||
int skinClusterBufferUnit;
|
||||
int materialBufferUnit;
|
||||
int texMapArrayBufferUnit;
|
||||
int keyLightBufferUnit;
|
||||
int lightBufferUnit;
|
||||
int lightAmbientBufferUnit;
|
||||
int lightAmbientMapUnit;
|
||||
int fadeMaskTextureUnit;
|
||||
int fadeParameterBufferUnit;
|
||||
int hazeParameterBufferUnit;
|
||||
int lightClusterGridBufferUnit;
|
||||
int lightClusterContentBufferUnit;
|
||||
int lightClusterFrustumBufferUnit;
|
||||
};
|
||||
using LocationsPointer = std::shared_ptr<Locations>;
|
||||
|
||||
|
|
Loading…
Reference in a new issue