Trying to migrate to a light array instead of each individual lights

This commit is contained in:
samcake 2016-09-02 17:51:35 -07:00
parent 560163bb75
commit d2a15ca82c
15 changed files with 161 additions and 20 deletions

View file

@ -128,6 +128,14 @@ TransformObject getTransformObject() {
}
<@endfunc@>
<@func transformWorldToClipPos(cameraTransform, worldPos, clipPos)@>
{ // transformWorldToClipPos
vec4 eyeWAPos = <$worldPos$> - vec4(<$cameraTransform$>._viewInverse[3].xyz, 0.0);
<$clipPos$> = <$cameraTransform$>._projectionViewUntranslated * eyeWAPos;
}
<@endfunc@>
<@func transformModelToWorldPos(objectTransform, modelPos, worldPos)@>
{ // transformModelToWorldPos
<$worldPos$> = (<$objectTransform$>._model * <$modelPos$>);

View file

@ -131,7 +131,17 @@ float getLightAmbientMapNumMips(Light l) {
return l._control.x;
}
<@func declareLightBuffer(N)@>
<@if N@>
uniform lightBuffer {
Light lightArray[<$N$>];
};
Light getLight(int index) {
return lightArray[index];
}
<@else@>
uniform lightBuffer {
Light light;
};
@ -139,6 +149,10 @@ Light getLight() {
return light;
}
<@endif@>
<@endfunc@>

View file

@ -24,6 +24,7 @@ uniform sampler2D specularMap;
// the depth texture
uniform sampler2D depthMap;
uniform sampler2D linearZeyeMap;
// the obscurance texture
uniform sampler2D obscuranceMap;
@ -86,6 +87,40 @@ DeferredFragment unpackDeferredFragmentNoPosition(vec2 texcoord) {
}
DeferredFragment unpackDeferredFragmentNoPositionNoAmbient(vec2 texcoord) {
vec4 normalVal;
vec4 diffuseVal;
DeferredFragment frag;
frag.depthVal = -1;
normalVal = texture(normalMap, texcoord);
diffuseVal = texture(albedoMap, texcoord);
// Unpack the normal from the map
frag.normal = unpackNormal(normalVal.xyz);
frag.roughness = normalVal.a;
// Diffuse color and unpack the mode and the metallicness
frag.albedo = diffuseVal.xyz;
frag.scattering = 0.0;
unpackModeMetallic(diffuseVal.w, frag.mode, frag.metallic);
//frag.emissive = specularVal.xyz;
frag.obscurance = 1.0;
if (frag.metallic <= 0.5) {
frag.metallic = 0.0;
frag.fresnel = vec3(0.03); // Default Di-electric fresnel value
} else {
frag.fresnel = vec3(diffuseVal.xyz);
frag.metallic = 1.0;
}
return frag;
}
<@include DeferredTransform.slh@>
<$declareDeferredFrameTransform()$>
@ -103,6 +138,19 @@ vec4 unpackDeferredPosition(DeferredFrameTransform deferredTransform, float dept
return vec4(evalEyePositionFromZeye(side, Zeye, texcoord), 1.0);
}
vec4 unpackDeferredPositionFromZeye(vec2 texcoord) {
float Zeye = -texture(linearZeyeMap, texcoord).x;
int side = 0;
if (isStereo()) {
if (texcoord.x > 0.5) {
texcoord.x -= 0.5;
side = 1;
}
texcoord.x *= 2.0;
}
return vec4(evalEyePositionFromZeye(side, Zeye, texcoord), 1.0);
}
DeferredFragment unpackDeferredFragment(DeferredFrameTransform deferredTransform, vec2 texcoord) {
float depthValue = texture(depthMap, texcoord).r;

View file

@ -14,6 +14,7 @@
<@include model/Light.slh@>
<@include LightingModel.slh@>
<$declareLightBuffer()$>
<@include LightAmbient.slh@>
<@include LightDirectional.slh@>

View file

@ -44,9 +44,8 @@ struct LightLocations {
int radius{ -1 };
int ambientSphere{ -1 };
int lightBufferUnit{ -1 };
int lightIndexBufferUnit { -1 };
int texcoordFrameTransform{ -1 };
int sphereParam{ -1 };
int coneParam{ -1 };
int deferredFrameTransformBuffer{ -1 };
int subsurfaceScatteringParametersBuffer{ -1 };
int shadowTransformBuffer{ -1 };
@ -60,6 +59,7 @@ enum DeferredShader_MapSlot {
DEFERRED_BUFFER_OBSCURANCE_UNIT = 4,
SHADOW_MAP_UNIT = 5,
SKYBOX_MAP_UNIT = 6,
DEFERRED_BUFFER_LINEAR_DEPTH_UNIT,
DEFERRED_BUFFER_CURVATURE_UNIT,
DEFERRED_BUFFER_DIFFUSED_CURVATURE_UNIT,
SCATTERING_LUT_UNIT,
@ -71,6 +71,7 @@ enum DeferredShader_BufferSlot {
SCATTERING_PARAMETERS_BUFFER_SLOT,
LIGHTING_MODEL_BUFFER_SLOT = render::ShapePipeline::Slot::LIGHTING_MODEL,
LIGHT_GPU_SLOT = render::ShapePipeline::Slot::LIGHT,
LIGHT_INDEX_GPU_SLOT,
};
static void loadLightProgram(const char* vertSource, const char* fragSource, bool lightVolume, gpu::PipelinePointer& program, LightLocationsPtr& locations);
@ -184,6 +185,7 @@ static void loadLightProgram(const char* vertSource, const char* fragSource, boo
slotBindings.insert(gpu::Shader::Binding(std::string("shadowMap"), SHADOW_MAP_UNIT));
slotBindings.insert(gpu::Shader::Binding(std::string("skyboxMap"), SKYBOX_MAP_UNIT));
slotBindings.insert(gpu::Shader::Binding(std::string("linearZeyeMap"), DEFERRED_BUFFER_LINEAR_DEPTH_UNIT));
slotBindings.insert(gpu::Shader::Binding(std::string("curvatureMap"), DEFERRED_BUFFER_CURVATURE_UNIT));
slotBindings.insert(gpu::Shader::Binding(std::string("diffusedCurvatureMap"), DEFERRED_BUFFER_DIFFUSED_CURVATURE_UNIT));
slotBindings.insert(gpu::Shader::Binding(std::string("scatteringLUT"), SCATTERING_LUT_UNIT));
@ -195,6 +197,7 @@ static void loadLightProgram(const char* vertSource, const char* fragSource, boo
slotBindings.insert(gpu::Shader::Binding(std::string("lightingModelBuffer"), LIGHTING_MODEL_BUFFER_SLOT));
slotBindings.insert(gpu::Shader::Binding(std::string("subsurfaceScatteringParametersBuffer"), SCATTERING_PARAMETERS_BUFFER_SLOT));
slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), LIGHT_GPU_SLOT));
slotBindings.insert(gpu::Shader::Binding(std::string("lightIndexBuffer"), LIGHT_INDEX_GPU_SLOT));
gpu::Shader::makeProgram(*program, slotBindings);
@ -203,10 +206,9 @@ static void loadLightProgram(const char* vertSource, const char* fragSource, boo
locations->ambientSphere = program->getUniforms().findLocation("ambientSphere.L00");
locations->texcoordFrameTransform = program->getUniforms().findLocation("texcoordFrameTransform");
locations->sphereParam = program->getUniforms().findLocation("sphereParam");
locations->coneParam = program->getUniforms().findLocation("coneParam");
locations->lightBufferUnit = program->getBuffers().findLocation("lightBuffer");
locations->lightIndexBufferUnit = program->getBuffers().findLocation("lightIndexBuffer");
locations->deferredFrameTransformBuffer = program->getBuffers().findLocation("deferredFrameTransformBuffer");
locations->subsurfaceScatteringParametersBuffer = program->getBuffers().findLocation("subsurfaceScatteringParametersBuffer");
locations->shadowTransformBuffer = program->getBuffers().findLocation("shadowTransformBuffer");
@ -496,6 +498,7 @@ void RenderDeferredSetup::run(const render::SceneContextPointer& sceneContext, c
// Subsurface scattering specific
if (surfaceGeometryFramebuffer) {
batch.setResourceTexture(DEFERRED_BUFFER_LINEAR_DEPTH_UNIT, surfaceGeometryFramebuffer->getLinearDepthTexture());
batch.setResourceTexture(DEFERRED_BUFFER_CURVATURE_UNIT, surfaceGeometryFramebuffer->getCurvatureTexture());
batch.setResourceTexture(DEFERRED_BUFFER_DIFFUSED_CURVATURE_UNIT, surfaceGeometryFramebuffer->getLowCurvatureTexture());
}
@ -571,7 +574,8 @@ void RenderDeferredSetup::run(const render::SceneContextPointer& sceneContext, c
void RenderDeferredLocals::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext,
const DeferredFrameTransformPointer& frameTransform,
const DeferredFramebufferPointer& deferredFramebuffer,
const LightingModelPointer& lightingModel) {
const LightingModelPointer& lightingModel,
const SurfaceGeometryFramebufferPointer& surfaceGeometryFramebuffer) {
bool points = lightingModel->isPointLightEnabled();
bool spots = lightingModel->isSpotLightEnabled();
@ -638,8 +642,13 @@ void RenderDeferredLocals::run(const render::SceneContextPointer& sceneContext,
}
}
// Splat spot lights
if (spots && !deferredLightingEffect->_spotLights.empty()) {
_spotLightsBuffer._buffer->setData(deferredLightingEffect->_spotLights.size() * sizeof(int), (const gpu::Byte*) deferredLightingEffect->_spotLights.data());
// Spot light pipeline
batch.setPipeline(deferredLightingEffect->_spotLight);
batch._glUniform4fv(deferredLightingEffect->_spotLightLocations->texcoordFrameTransform, 1, reinterpret_cast< const float* >(&textureFrameTransform));
@ -651,6 +660,11 @@ void RenderDeferredLocals::run(const render::SceneContextPointer& sceneContext,
batch.setInputFormat(mesh->getVertexFormat());
auto& conePart = mesh->getPartBuffer().get<model::Mesh::Part>(0);
batch.setUniformBuffer(deferredLightingEffect->_spotLightLocations->lightBufferUnit, deferredLightingEffect->getLightStage()._lightArrayBuffer);
batch.setUniformBuffer(deferredLightingEffect->_spotLightLocations->lightIndexBufferUnit, _spotLightsBuffer);
batch.drawIndexedInstanced(deferredLightingEffect->_spotLights.size(), model::Mesh::topologyToPrimitive(conePart._topology), conePart._numIndices, conePart._startIndex);
/*
for (auto lightID : deferredLightingEffect->_spotLights) {
auto light = deferredLightingEffect->getLightStage().getLight(lightID);
if (!light) {
@ -666,7 +680,7 @@ void RenderDeferredLocals::run(const render::SceneContextPointer& sceneContext,
batch.drawIndexed(model::Mesh::topologyToPrimitive(conePart._topology), conePart._numIndices, conePart._startIndex);
}
}
}*/
}
});
}
@ -681,6 +695,7 @@ void RenderDeferredCleanup::run(const render::SceneContextPointer& sceneContext,
batch.setResourceTexture(DEFERRED_BUFFER_DEPTH_UNIT, nullptr);
batch.setResourceTexture(DEFERRED_BUFFER_OBSCURANCE_UNIT, nullptr);
batch.setResourceTexture(DEFERRED_BUFFER_LINEAR_DEPTH_UNIT, nullptr);
batch.setResourceTexture(DEFERRED_BUFFER_CURVATURE_UNIT, nullptr);
batch.setResourceTexture(DEFERRED_BUFFER_DIFFUSED_CURVATURE_UNIT, nullptr);
batch.setResourceTexture(SCATTERING_LUT_UNIT, nullptr);
@ -731,7 +746,7 @@ void RenderDeferred::run(const SceneContextPointer& sceneContext, const RenderCo
setupJob.run(sceneContext, renderContext, deferredTransform, deferredFramebuffer, lightingModel, surfaceGeometryFramebuffer, ssaoFramebuffer, subsurfaceScatteringResource);
lightsJob.run(sceneContext, renderContext, deferredTransform, deferredFramebuffer, lightingModel);
lightsJob.run(sceneContext, renderContext, deferredTransform, deferredFramebuffer, lightingModel, surfaceGeometryFramebuffer);
cleanupJob.run(sceneContext, renderContext);

View file

@ -106,6 +106,7 @@ private:
std::vector<int> _globalLights;
std::vector<int> _pointLights;
std::vector<int> _spotLights;
friend class RenderDeferredSetup;
friend class RenderDeferredLocals;
@ -155,7 +156,11 @@ public:
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext,
const DeferredFrameTransformPointer& frameTransform,
const DeferredFramebufferPointer& deferredFramebuffer,
const LightingModelPointer& lightingModel);
const LightingModelPointer& lightingModel,
const SurfaceGeometryFramebufferPointer& surfaceGeometryFramebuffer);
gpu::BufferView _spotLightsBuffer;
};

View file

@ -114,9 +114,30 @@ LightStage::Index LightStage::addLight(const LightPointer& light) {
// INsert the light and its index in the reverese map
_lightMap.insert(LightMap::value_type(light, lightId));
updateLightArrayBuffer(lightId);
}
return lightId;
} else {
return (*found).second;
}
}
void LightStage::updateLightArrayBuffer(Index lightId) {
if (!_lightArrayBuffer) {
_lightArrayBuffer = std::make_shared<gpu::Buffer>();
}
assert(checkLightId(lightId));
auto lightSize = sizeof(model::Light::Schema);
if (lightId > _lightArrayBuffer->getTypedSize<model::Light::Schema>()) {
_lightArrayBuffer->resize(lightSize * (lightId + 10));
}
// lightArray is big enough so we can remap
auto& light = _lights._elements[lightId];
auto lightSchema = light->getSchemaBuffer().get<model::Light::Schema>();
_lightArrayBuffer->setSubData<model::Light::Schema>(lightId, lightSchema);
}

View file

@ -240,6 +240,9 @@ public:
LightMap _lightMap;
Descs _descs;
gpu::BufferPointer _lightArrayBuffer;
void updateLightArrayBuffer(Index lightId);
Shadows _shadows;
};

View file

@ -19,6 +19,7 @@
<$declareStandardTransform()$>
<@include model/Light.slh@>
<$declareLightBuffer()$>
out vec4 _texCoord0;

View file

@ -19,12 +19,16 @@
<$declareStandardTransform()$>
<@include model/Light.slh@>
<$declareLightBuffer(32)$>
out vec4 _texCoord0;
void main(void) {
vec4 coneVertex = inPosition;
vec4 coneParam = getLightVolumeGeometry(getLight());
Light light = getLight(gl_InstanceID);
vec3 lightPos = getLightPosition(light);
vec4 coneParam = getLightVolumeGeometry(light);
if(coneVertex.z >= 0.0) {
// Evaluate the true position of the spot volume
@ -37,15 +41,21 @@ void main(void) {
coneVertex.z = -dir.x;
} else {
coneVertex.z = 0.0;
}
}
coneVertex.xyz *= coneParam.w;
coneVertex.xyz += lightPos;
// standard transform
TransformCamera cam = getTransformCamera();
TransformObject obj = getTransformObject();
<$transformModelToClipPos(cam, obj, coneVertex, gl_Position)$>;
vec4 projected = gl_Position / gl_Position.w;
<! TransformObject obj = getTransformObject();
<$transformModelToClipPos(cam, obj, coneVertex, gl_Position)$>; !>
<$transformWorldToClipPos(cam, coneVertex, gl_Position)$>;
vec4 projected = gl_Position / gl_Position.w;
projected.xy = (projected.xy + 1.0) * 0.5;
if (cam_isStereo()) {

View file

@ -13,6 +13,7 @@
<@include model/Light.slh@>
<$declareLightBuffer()$>
<@include LightingModel.slh@>

View file

@ -13,6 +13,7 @@
//
<@include model/Light.slh@>
<$declareLightBuffer()$>
<@include LightingModel.slh@>

View file

@ -19,6 +19,7 @@
// Everything about light
<@include model/Light.slh@>
<$declareLightBuffer()$>
<@include LightingModel.slh@>

View file

@ -19,6 +19,7 @@
// Everything about light
<@include model/Light.slh@>
<$declareLightBuffer(32)$>
<@include LightingModel.slh@>
@ -27,28 +28,27 @@
uniform vec4 texcoordFrameTransform;
in vec4 _texCoord0;
out vec4 _fragColor;
void main(void) {
DeferredFrameTransform deferredTransform = getDeferredFrameTransform();
// DeferredFrameTransform deferredTransform = getDeferredFrameTransform();
// Grab the fragment data from the uv
vec2 texCoord = _texCoord0.st / _texCoord0.q;
texCoord *= texcoordFrameTransform.zw;
texCoord += texcoordFrameTransform.xy;
DeferredFragment frag = unpackDeferredFragment(deferredTransform, texCoord);
if (frag.mode == FRAG_MODE_UNLIT) {
discard;
}
vec4 fragPosition = unpackDeferredPositionFromZeye(texCoord);
// Need the light now
Light light = getLight();
Light light = getLight(0);
// Frag pos in world
mat4 invViewMat = getViewInverse();
vec4 fragPos = invViewMat * frag.position;
vec4 fragPos = invViewMat * fragPosition;
// Clip againgst the light volume and Make the Light vector going from fragment to light center in world space
vec4 fragLightVecLen2;
@ -58,6 +58,17 @@ void main(void) {
discard;
}
// _fragColor.rgb = vec3(0.0, 1.0, 1.0);
// return;
DeferredFragment frag = unpackDeferredFragmentNoPositionNoAmbient(texCoord);
// frag.depthVal = depthValue;
frag.position = fragPosition;
if (frag.mode == FRAG_MODE_UNLIT) {
discard;
}
// Frag to eye vec
vec4 fragEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0);
vec3 fragEyeDir = normalize(fragEyeVector.xyz);

View file

@ -13,6 +13,7 @@
<@include DeferredBufferRead.slh@>
<@include model/Light.slh@>
<$declareLightBuffer()$>
<$declareDeferredCurvature()$>