Try to improve instancing shadows

This commit is contained in:
2023-03-12 14:06:11 +00:00
parent b88a8d5776
commit 9947979b52
9 changed files with 368 additions and 296 deletions
+1 -1
View File
@@ -10,7 +10,7 @@ layout (std140, binding = 1) uniform LightsBlock
} ; } ;
vec3 lightPos = posBool[gl_InvocationID].xyz ; vec3 lightPos = posBool[gl_InvocationID].xyz ;
float theBool = posBool[gl_InvocationID].w; float theBool = posBool[gl_InvocationID].w;
// this code is duplicated in lineShadow.geom, should not be changed on its own // this code is duplicated in shadow/edge.geom, should not be changed on its own
vec4 projNear (vec4 pos) vec4 projNear (vec4 pos)
{ {
// note we project to a specific height // note we project to a specific height
+64 -57
View File
@@ -1,78 +1,85 @@
#version 450 core #version 450 core
layout (lines_adjacency) in; layout(lines_adjacency) in;
layout (invocations = 20) in; layout(invocations = 20) in;
layout (triangle_strip, max_vertices = 4) out; layout(triangle_strip, max_vertices = 4) out;
layout (std140, binding = 0) uniform TheMat { mat4 theMat; } ; layout(std140, binding = 0) uniform TheMat { mat4 theMat; };
layout (std140, binding = 1) uniform LightsBlock layout(std140, binding = 1) uniform LightsBlock {
{
vec4 posBool[20]; vec4 posBool[20];
vec4 colRad[20]; vec4 colRad[20];
} ; };
vec3 lightPos1 = posBool[gl_InvocationID].xyz; vec3 lightPos = posBool[gl_InvocationID].xyz;
float theBool = posBool[gl_InvocationID].w; float theBool = posBool[gl_InvocationID].w;
vec4 shift (vec4 p) { return (vec4 (p.xyz + (100000*(p.xyz-lightPos1)), 1));} ; float rad = colRad[gl_InvocationID].w;
vec4 shiftBy (float x,vec4 p) { return (vec4 (lightPos1 + (x*normalize(p.xyz-lightPos1)), 1));} ; vec4 shift(vec4 p) { return (vec4(p.xyz + (100000 * (p.xyz - lightPos)), 1)); };
// copied from lighting/cap.geom, should not be changed on its own vec4 shiftBy(float x, vec4 p) {
vec4 projNear (vec4 pos) return (vec4(lightPos + (x * normalize(p.xyz - lightPos)), 1));
{ };
vec4 shift1(vec4 p) {
return (vec4(lightPos + (rad * normalize(p.xyz - lightPos)), 1));
};
// copied from shadow/cap.geom, should not be changed on its own
vec4 projNear(vec4 pos) {
// note we project to a specific height // note we project to a specific height
// this is quite brittle, not ideal // this is quite brittle, not ideal
vec3 dir = pos.xyz - lightPos1 ; vec3 dir = pos.xyz - lightPos;
float a = (140 - pos.z) / dir.z ; float a = (140 - pos.z) / dir.z;
vec2 xy = (pos.xyz + a * dir).xy ; vec2 xy = (pos.xyz + a * dir).xy;
return vec4 ( xy, 140 , 1) ; return vec4(xy, 140, 1);
} ; };
vec4 shiftNear (vec4 pos) vec4 shiftNear(vec4 pos) {
{ vec4 sp = shift(pos); vec4 sp = shift(pos);
if (sp.z > 140) if (sp.z > 140) {
{ return projNear(pos) ; } return projNear(pos);
else } else {
{ return sp ; } return sp;
} ; }
vec4 f (vec4 p) {return (theMat * p);} ; };
void main() void main() {
{ if (theBool == 1) {
if (theBool == 1){
// float ru2 = radiusUniform * radiusUniform ;
float ru = colRad[gl_InvocationID].w ;
float ru2 = ru * ru;
vec4 p0 = gl_in[0].gl_Position; vec4 p0 = gl_in[0].gl_Position;
vec4 p1 = gl_in[1].gl_Position; vec4 p1 = gl_in[1].gl_Position;
vec4 mid = 0.5*(p0 + p1); vec4 mid = 0.5 * (p0 + p1);
vec3 n0a = gl_in[2].gl_Position.xyz; vec3 n0a = gl_in[2].gl_Position.xyz;
vec3 n1a = gl_in[3].gl_Position.xyz; vec3 n1a = gl_in[3].gl_Position.xyz;
vec3 n0 = cross(p1.xyz - p0.xyz, n0a - p0.xyz) ; vec3 n0 = cross(p1.xyz - p0.xyz, n0a - p0.xyz);
vec3 n1 = cross(p0.xyz - p1.xyz, n1a - p1.xyz) ; vec3 n1 = cross(p0.xyz - p1.xyz, n1a - p1.xyz);
vec3 lightDir = p0.xyz - lightPos.xyz;
//vec3 n2 = n0 + n1; // assumes the summands are normalized vec3 lightDir2 = p1.xyz - lightPos.xyz;
vec3 lightDir = p0.xyz - lightPos1.xyz; // test if the edge is part of the silhouette
vec3 lightDir2 = p1.xyz - lightPos1.xyz;
// first test if the edge is part of the silhouette
// that is, if the normals of the faces connected by the edge point are in // that is, if the normals of the faces connected by the edge point are in
// "different directions" wrt the light direction // "different directions" wrt the light direction
if ( dot(n0 , lightDir) * dot(n1 , lightDir) <= 0 && if (dot(n0, lightDir) * dot(n1, lightDir) <= 0 &&
(dot(lightDir,lightDir) < ru2 || dot(lightDir2,lightDir2) < ru2) ) (dot(lightDir, lightDir) < rad * rad ||
dot(lightDir2, lightDir2) < rad * rad))
// using <= rather than < seems to get rid of overlapping shadow // using <= rather than < seems to get rid of overlapping shadow
// artefacts // artefacts
{ {
vec4 p2 = shiftNear(p0); vec4 p2 = shiftNear(p0);
vec4 p3 = shiftNear(p1); vec4 p3 = shiftNear(p1);
if ( dot(n0 , lightDir) > 0) gl_Position = theMat * p0;
{ gl_Layer = gl_InvocationID;
gl_Position = f(p0); gl_Layer = gl_InvocationID; EmitVertex(); EmitVertex();
gl_Position = f(p1); gl_Layer = gl_InvocationID; EmitVertex(); if (dot(n0, lightDir) > 0) {
gl_Position = f(p2); gl_Layer = gl_InvocationID; EmitVertex(); gl_Position = theMat * p1;
gl_Position = f(p3); gl_Layer = gl_InvocationID; EmitVertex(); gl_Layer = gl_InvocationID;
} EmitVertex();
else gl_Position = theMat * p2;
{ gl_Layer = gl_InvocationID;
gl_Position = f(p1); gl_Layer = gl_InvocationID; EmitVertex(); EmitVertex();
gl_Position = f(p0); gl_Layer = gl_InvocationID; EmitVertex(); } else {
gl_Position = f(p3); gl_Layer = gl_InvocationID; EmitVertex(); gl_Position = theMat * p2;
gl_Position = f(p2); gl_Layer = gl_InvocationID; EmitVertex(); gl_Layer = gl_InvocationID;
EmitVertex();
gl_Position = theMat * p1;
gl_Layer = gl_InvocationID;
EmitVertex();
} }
gl_Position = theMat * p3;
gl_Layer = gl_InvocationID;
EmitVertex();
EndPrimitive(); EndPrimitive();
} else {
}
} else {
} }
else { }
}else {}
} }
+53 -42
View File
@@ -1,54 +1,65 @@
#version 450 core #version 450 core
layout (points) in; layout(points) in;
layout (invocations = 20) in; layout(invocations = 20) in;
layout (triangle_strip, max_vertices = 8) out; layout(triangle_strip, max_vertices = 8) out;
layout (std140, binding = 0) uniform TheMat { mat4 theMat; } ; layout(std140, binding = 0) uniform TheMat { mat4 theMat; };
layout (std140, binding = 1) uniform LightsBlock layout(std140, binding = 1) uniform LightsBlock {
{
vec4 posBool[20]; vec4 posBool[20];
vec4 colRad[20]; vec4 colRad[20];
} ; };
vec3 lightPos = posBool[gl_InvocationID].xyz; vec3 lightPos = posBool[gl_InvocationID].xyz;
float theBool = posBool[gl_InvocationID].w; float theBool = posBool[gl_InvocationID].w;
vec4 shift (vec4 p) vec4 shift(vec4 p) { return vec4(p.xy + (200 * (p.xy - lightPos.xy)), 0, 1); }
{ return vec4 (p.xy + (200 * (p.xy-lightPos.xy)), 0 , 1); float isLHS(vec2 startV, vec2 testV) {
} return sign(-startV.x * testV.y + startV.y * testV.x);
float isLHS (vec2 startV, vec2 testV)
{
return sign( -startV.x * testV.y + startV.y * testV.x);
} }
// construct a box with openings on bottom face and face away from wall // construct a box with openings on bottom face and face away from wall
void main() void main() {
{ vec4 p1 = vec4(gl_in[0].gl_Position.xy, 0, 1);
vec4 p1 = vec4 (gl_in[0].gl_Position.xy,0,1); vec4 p2 = vec4(gl_in[0].gl_Position.zw, 0, 1);
vec4 p2 = vec4 (gl_in[0].gl_Position.zw,0,1); if (theBool == 1 && isLHS(p1.xy - lightPos.xy, p2.xy - lightPos.xy) < 0) {
if (theBool==1 && isLHS (p1.xy - lightPos.xy, p2.xy - lightPos.xy) < 0) vec4 p3 = vec4(p1.xy, 100, 1);
{ vec4 p4 = vec4(p2.xy, 100, 1);
vec4 p3 = vec4 (p1.xy,100,1); vec4 p5 = shift(p1);
vec4 p4 = vec4 (p2.xy,100,1); vec4 p6 = shift(p2);
vec4 p5 = shift(p1); vec4 p7 = vec4(p6.xy, 100, 1);
vec4 p6 = shift(p2); vec4 p8 = vec4(p5.xy, 100, 1);
vec4 p7 = vec4 (p6.xy,100,1);
vec4 p8 = vec4 (p5.xy,100,1);
vec4 a1 = theMat * p1; vec4 a1 = theMat * p1;
vec4 a2 = theMat * p2; vec4 a2 = theMat * p2;
vec4 a3 = theMat * p3; vec4 a3 = theMat * p3;
vec4 a4 = theMat * p4; vec4 a4 = theMat * p4;
vec4 a5 = theMat * p5; vec4 a5 = theMat * p5;
vec4 a6 = theMat * p6; vec4 a6 = theMat * p6;
vec4 a7 = theMat * p7; vec4 a7 = theMat * p7;
vec4 a8 = theMat * p8; vec4 a8 = theMat * p8;
gl_Position = a1; gl_Layer = gl_InvocationID; EmitVertex(); gl_Position = a1;
gl_Position = a5; gl_Layer = gl_InvocationID; EmitVertex(); gl_Layer = gl_InvocationID;
gl_Position = a3; gl_Layer = gl_InvocationID; EmitVertex(); EmitVertex();
gl_Position = a8; gl_Layer = gl_InvocationID; EmitVertex(); gl_Position = a5;
gl_Position = a4; gl_Layer = gl_InvocationID; EmitVertex(); gl_Layer = gl_InvocationID;
gl_Position = a7; gl_Layer = gl_InvocationID; EmitVertex(); EmitVertex();
gl_Position = a2; gl_Layer = gl_InvocationID; EmitVertex(); gl_Position = a3;
gl_Position = a6; gl_Layer = gl_InvocationID; EmitVertex(); gl_Layer = gl_InvocationID;
EmitVertex();
gl_Position = a8;
gl_Layer = gl_InvocationID;
EmitVertex();
gl_Position = a4;
gl_Layer = gl_InvocationID;
EmitVertex();
gl_Position = a7;
gl_Layer = gl_InvocationID;
EmitVertex();
gl_Position = a2;
gl_Layer = gl_InvocationID;
EmitVertex();
gl_Position = a6;
gl_Layer = gl_InvocationID;
EmitVertex();
EndPrimitive(); EndPrimitive();
} else {} } else {
}
} }
+1 -1
View File
@@ -50,7 +50,7 @@ data RenderData = RenderData
, _fboColor :: (FBO, TO) , _fboColor :: (FBO, TO)
, _fboPos :: (FBO, TO) , _fboPos :: (FBO, TO)
, _fboLighting :: (FBO, TO) , _fboLighting :: (FBO, TO)
, _fboLightingHigh :: (FBO, TO) --, _fboLightingHigh :: (FBO, TO)
, _fboShadow :: (FBO, (TO, TO)) , _fboShadow :: (FBO, (TO, TO))
, _rboBaseBloom :: GLuint -- RenderbufferObject id , _rboBaseBloom :: GLuint -- RenderbufferObject id
, _matUBO :: GLuint -- BufferObject id , _matUBO :: GLuint -- BufferObject id
+2
View File
@@ -89,6 +89,8 @@ data ObjectShadows = GeoObjShads
| InstancingShads | InstancingShads
| CPUObjShads | CPUObjShads
| NoObjShads | NoObjShads
| NoShadows
| NoLighting
deriving (Show, Eq, Ord, Enum, Bounded) deriving (Show, Eq, Ord, Enum, Bounded)
data RoomClipping = NoRoomClipBoundaries | AllRoomClipBoundaries | IntersectingRoomClipBoundaries data RoomClipping = NoRoomClipBoundaries | AllRoomClipBoundaries | IntersectingRoomClipBoundaries
+18 -29
View File
@@ -3,26 +3,27 @@ module Dodge.Render (
doDrawing, doDrawing,
) where ) where
import qualified Data.Map.Strict as M --import qualified Data.Vector as V
import Picture.Base
import qualified SDL
import qualified Data.Vector as V
import Dodge.Render.Shadow
import Control.Lens import Control.Lens
import Control.Monad import Control.Monad
import qualified Control.Monad.Parallel as MP import qualified Control.Monad.Parallel as MP
import qualified Data.Map.Strict as M
import Data.Preload.Render import Data.Preload.Render
import qualified Data.Vector.Unboxed.Mutable as UMV import qualified Data.Vector.Unboxed.Mutable as UMV
import Dodge.Data.Universe import Dodge.Data.Universe
import Dodge.Render.Lights import Dodge.Render.Lights
import Dodge.Render.Picture import Dodge.Render.Picture
import Dodge.Render.Shadow
import Dodge.Render.ShapePicture import Dodge.Render.ShapePicture
import Dodge.Render.Walls import Dodge.Render.Walls
import Foreign import Foreign
import Geometry import Geometry
import Graphics.GL.Core45 import Graphics.GL.Core45
import MatrixHelper import MatrixHelper
import Picture.Base
import Render import Render
import qualified SDL
--import qualified SDL --import qualified SDL
import Shader import Shader
import Shader.Bind import Shader.Bind
@@ -55,13 +56,11 @@ doDrawing' win pdata u = do
lightPoints = lightsToRender cfig (w ^. cWorld . camPos) (w ^. cWorld . lWorld) lightPoints = lightsToRender cfig (w ^. cWorld . camPos) (w ^. cWorld . lWorld)
viewFroms@(V2 vfx vfy) = w ^. cWorld . camPos . camViewFrom viewFroms@(V2 vfx vfy) = w ^. cWorld . camPos . camViewFrom
shadV = _pictureShaders pdata shadV = _pictureShaders pdata
lwShad = _lightingWallShadShader pdata
-- bind as much data into vbos as feasible at this point -- bind as much data into vbos as feasible at this point
-- count mutable vectors setup -- count mutable vectors setup
layerCounts <- UMV.replicate (numLayers * 6) 0 layerCounts <- UMV.replicate (numLayers * 6) 0
-- attempt to poke in parallel -- attempt to poke in parallel
let (ws, wp) = wallSPics <> worldSPic cfig w let (ws, wp) = wallSPics <> worldSPic cfig w
--( (nWalls, nWins , nFls),(nShapeVs, nIndices, nSilIndices) )
((nWalls, nWins, nFls), (nShapeVs, nIndices, nSilIndices)) <- ((nWalls, nWins, nFls), (nShapeVs, nIndices, nSilIndices)) <-
MP.bindM3 MP.bindM3
(\_ a b -> return (a, b)) (\_ a b -> return (a, b))
@@ -109,21 +108,18 @@ doDrawing' win pdata u = do
withArray (perspectiveMatrixb rot camzoom trans wins viewFroms) $ \ptr -> withArray (perspectiveMatrixb rot camzoom trans wins viewFroms) $ \ptr ->
glNamedBufferSubData (pdata ^. matUBO) 0 64 ptr glNamedBufferSubData (pdata ^. matUBO) 0 64 ptr
setViewportSize (round winx `div` resFact) (round winy `div` resFact) setViewportSize (round winx `div` resFact) (round winy `div` resFact)
--bindFramebuffer Framebuffer $= fst (_fboBase pdata)
glBindFramebuffer GL_FRAMEBUFFER (_unFBO (fst (_fboBase pdata))) glBindFramebuffer GL_FRAMEBUFFER (_unFBO (fst (_fboBase pdata)))
glDepthMask GL_TRUE
glClearColor 0 0 0 1 glClearColor 0 0 0 1
glClear $ sum [GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT] glClear $ sum [GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT]
glDepthFunc GL_LESS glDepthFunc GL_LESS
-- draw wall occlusions from the camera's point of view -- draw wall occlusions from the camera's point of view
-- currentProgram $= lwShad ^? shadProg -- Just (_shadProg lwShad) glUseProgram (pdata ^. lightingWallShadShader . shadProg')
-- uniform (_shadUnis lwShad V.! 0) $= viewFrom3d glUniform3f (pdata ^?! lightingWallShadShader . shadUnis' . ix 0) vfx vfy 20
glUseProgram (lwShad ^. shadProg') glBindVertexArray $ pdata ^. lightingWallShadShader . shadVAO' . vaoName
glUniform3f (_shadUnis' lwShad V.! 0) vfx vfy 20
--bindVertexArrayObject $= lwShad ^? shadVAO' . vaoName -- Just (_vao $ _shadVAO lwShad)
glBindVertexArray $ lwShad ^. shadVAO' . vaoName -- Just (_vao $ _shadVAO lwShad)
unless (debugOn Remove_LOS cfig) $ unless (debugOn Remove_LOS cfig) $
glDrawArrays glDrawArrays
(marshalEPrimitiveMode $ _shadPrim' lwShad) (marshalEPrimitiveMode $ pdata ^. lightingWallShadShader . shadPrim')
0 0
(fromIntegral nWalls) (fromIntegral nWalls)
--draw walls onto base buffer --draw walls onto base buffer
@@ -134,20 +130,16 @@ doDrawing' win pdata u = do
renderLayer BottomLayer shadV layerCounts renderLayer BottomLayer shadV layerCounts
--draw object shapes onto base buffer --draw object shapes onto base buffer
let fs = _shapeShader pdata let fs = _shapeShader pdata
--currentProgram $= Just (_shadProg fs)
glUseProgram (_shadProg' fs) glUseProgram (_shadProg' fs)
--bindVertexArrayObject $= fs ^? shadVAO' . vaoName -- Just (_vao $ _shadVAO fs) glBindVertexArray $ fs ^. shadVAO' . vaoName
glBindVertexArray $ fs ^. shadVAO' . vaoName -- Just (_vao $ _shadVAO fs)
glDrawElements glDrawElements
(marshalEPrimitiveMode $ _shadPrim' fs) (marshalEPrimitiveMode $ _shadPrim' fs)
(fromIntegral nIndices) (fromIntegral nIndices)
GL_UNSIGNED_SHORT GL_UNSIGNED_SHORT
nullPtr nullPtr
--draw floor onto base buffer --draw floor onto base buffer
-- nTextArrayVs <- pokePoint33s (shadVBOptr $ _textureArrayShader pdata) (_floorTiles w)
drawShader (_textureArrayShader pdata) nFls drawShader (_textureArrayShader pdata) nFls
--draw lightmap into its own buffer --draw lightmap into its own buffer
--bindFramebuffer Framebuffer $= fst (_fboLighting pdata)
glBindFramebuffer GL_FRAMEBUFFER (_unFBO (fst (_fboLighting pdata))) glBindFramebuffer GL_FRAMEBUFFER (_unFBO (fst (_fboLighting pdata)))
createLightMap createLightMap
cfig cfig
@@ -156,23 +148,18 @@ doDrawing' win pdata u = do
nWalls nWalls
nSilIndices nSilIndices
nIndices nIndices
--(_graphics_object_shadows $ _uvConfig u)
(u ^. uvConfig . graphics_object_shadows) (u ^. uvConfig . graphics_object_shadows)
(snd $ snd $ pdata ^. fboBase) (snd $ snd $ pdata ^. fboBase)
(drawCPUShadows pdata ws) (drawCPUShadows pdata ws)
glColorMask GL_TRUE GL_TRUE GL_TRUE GL_TRUE glColorMask GL_TRUE GL_TRUE GL_TRUE GL_TRUE
glClearColor 0 0 0 0 glClearColor 0 0 0 0
--apply lightmap to base buffer --apply lightmap to base buffer
--bindFramebuffer Framebuffer $= pdata ^. fboBase . _1 --fst (_fboBase pdata)
glBindFramebuffer GL_FRAMEBUFFER (pdata ^. fboBase . _1 . unFBO) glBindFramebuffer GL_FRAMEBUFFER (pdata ^. fboBase . _1 . unFBO)
--textureBinding Texture2D $= Just (snd $ _fboLighting pdata) glBindTexture GL_TEXTURE_2D (pdata ^. fboLighting . _2 . unTO)
--textureBinding Texture2D $= pdata ^? fboLighting . _2 -- Just (snd $ _fboLighting pdata)
glBindTexture GL_TEXTURE_2D (pdata ^. fboLighting . _2 . unTO) -- Just (snd $ _fboLighting pdata)
glEnable GL_BLEND glEnable GL_BLEND
glBlendFunc GL_ZERO GL_ONE_MINUS_SRC_COLOR glBlendFunc GL_ZERO GL_ONE_MINUS_SRC_COLOR
drawShader (_fullscreenShader pdata) 4 drawShader (_fullscreenShader pdata) 4
--draw bloom onto bloom buffer --draw bloom onto bloom buffer
--bindFramebuffer Framebuffer $= pdata ^. fboBloom . _1 --fst (_fboBloom pdata)
glBindFramebuffer GL_FRAMEBUFFER (pdata ^. fboBloom . _1 . unFBO) glBindFramebuffer GL_FRAMEBUFFER (pdata ^. fboBloom . _1 . unFBO)
glClear GL_COLOR_BUFFER_BIT glClear GL_COLOR_BUFFER_BIT
glDepthFunc GL_LESS glDepthFunc GL_LESS
@@ -315,6 +302,7 @@ doDrawing' win pdata u = do
$ fpsText (u ^. uvFrameTicks - u ^. uvLastFrameTicks) $ fpsText (u ^. uvFrameTicks - u ^. uvLastFrameTicks)
) )
SDL.glSwapWindow win SDL.glSwapWindow win
-- eTicks <- SDL.ticks -- eTicks <- SDL.ticks
-- return (eTicks - sTicks) -- return (eTicks - sTicks)
@@ -328,7 +316,6 @@ fpsText x = color col $ text $ "ms/frame " ++ show x
| x < 50 = orange | x < 50 = orange
| otherwise = red | otherwise = red
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- note: currently assume there is only one UBO, we only bind it once at setup -- note: currently assume there is only one UBO, we only bind it once at setup
--bufferUBO :: GLuint -> [Float] -> IO () --bufferUBO :: GLuint -> [Float] -> IO ()
@@ -350,7 +337,8 @@ renderBlankWalls pdata nWalls = do
--cullFace $= Just Back --cullFace $= Just Back
drawShader (_wallBlankShader pdata) nWalls drawShader (_wallBlankShader pdata) nWalls
glDisable GL_CULL_FACE glDisable GL_CULL_FACE
--cullFace $= Nothing
--cullFace $= Nothing
renderTextureWalls :: renderTextureWalls ::
RenderData -> RenderData ->
@@ -363,7 +351,8 @@ renderTextureWalls pdata nWalls = do
glCullFace GL_BACK glCullFace GL_BACK
drawShader (_wallTextureShader pdata) nWalls drawShader (_wallTextureShader pdata) nWalls
glDisable GL_CULL_FACE glDisable GL_CULL_FACE
--cullFace $= Nothing
--cullFace $= Nothing
checkGLError :: IO () checkGLError :: IO ()
checkGLError = do checkGLError = do
+2 -1
View File
@@ -33,7 +33,8 @@ sizeFBOs xsize ysize xfull yfull rdata = do
foldM (updateFBOTO2 xsize ysize GL_NEAREST GL_NEAREST GL_RGBA8 GL_RGBA16F) rdata [fboBase, fboCloud] foldM (updateFBOTO2 xsize ysize GL_NEAREST GL_NEAREST GL_RGBA8 GL_RGBA16F) rdata [fboBase, fboCloud]
>>= flip >>= flip
(foldM (updateFBOTO xsize ysize GL_NEAREST GL_NEAREST GL_RGBA8)) (foldM (updateFBOTO xsize ysize GL_NEAREST GL_NEAREST GL_RGBA8))
[fboColor, fboLighting, fboLightingHigh] [fboColor, fboLighting]
--[fboColor, fboLighting, fboLightingHigh]
rdata'' <- rdata'' <-
foldM foldM
(updateFBOTO xsize ysize GL_LINEAR_MIPMAP_LINEAR GL_LINEAR GL_RGBA16F) (updateFBOTO xsize ysize GL_LINEAR_MIPMAP_LINEAR GL_LINEAR GL_RGBA16F)
+7 -3
View File
@@ -213,7 +213,7 @@ preloadRender = do
fboColorName <- setupFramebufferGivenStencil rboBaseBloomName fboColorName <- setupFramebufferGivenStencil rboBaseBloomName
fboPosName <- setupFramebufferGivenStencil rboBaseBloomName fboPosName <- setupFramebufferGivenStencil rboBaseBloomName
fboLightingName <- setupFramebufferGivenStencil rboBaseBloomName fboLightingName <- setupFramebufferGivenStencil rboBaseBloomName
fboLightingHighName <- setupFramebufferGivenStencil rboBaseBloomName --fboLightingHighName <- setupFramebufferGivenStencil rboBaseBloomName
fboShadowName <- setupShadowFramebuffer fboShadowName <- setupShadowFramebuffer
@@ -238,7 +238,7 @@ preloadRender = do
, aslist , aslist
, eslist , eslist
] ]
initializeGLState
return $ return $
RenderData RenderData
{ _pictureShaders = shadV { _pictureShaders = shadV
@@ -270,7 +270,7 @@ preloadRender = do
, _fboHalf2 = fboHalf2Name , _fboHalf2 = fboHalf2Name
, _fboHalf3 = fboHalf3Name , _fboHalf3 = fboHalf3Name
, _fboLighting = fboLightingName , _fboLighting = fboLightingName
, _fboLightingHigh = fboLightingHighName --, _fboLightingHigh = fboLightingHighName
, _fboShadow = fboShadowName , _fboShadow = fboShadowName
, _fboBase = fboBaseName , _fboBase = fboBaseName
, _fboCloud = fboCloudName , _fboCloud = fboCloudName
@@ -301,6 +301,10 @@ cornerList =
-- , [1, -1, 1, 0] -- , [1, -1, 1, 0]
-- ] -- ]
initializeGLState :: IO ()
initializeGLState = do
glEnable GL_DEPTH_TEST
cleanUpRenderPreload :: RenderData -> IO () cleanUpRenderPreload :: RenderData -> IO ()
cleanUpRenderPreload pd = do cleanUpRenderPreload pd = do
-- TODO fix this -- TODO fix this
+105 -47
View File
@@ -7,9 +7,8 @@ module Render (
bindFBO, bindFBO,
) where ) where
import Control.Monad
import Dodge.WindowSize
import Control.Lens import Control.Lens
import Control.Monad
import Control.Monad.Primitive import Control.Monad.Primitive
import Data.Preload.Render import Data.Preload.Render
import qualified Data.Vector as V import qualified Data.Vector as V
@@ -18,6 +17,7 @@ import qualified Data.Vector.Fusion.Stream.Monadic as VFSM
import qualified Data.Vector.Mutable as MV import qualified Data.Vector.Mutable as MV
import qualified Data.Vector.Unboxed.Mutable as UMV import qualified Data.Vector.Unboxed.Mutable as UMV
import Dodge.Data.Config import Dodge.Data.Config
import Dodge.WindowSize
import Foreign hiding (rotate) import Foreign hiding (rotate)
import Geometry.Data import Geometry.Data
import Graphics.GL.Core45 import Graphics.GL.Core45
@@ -26,13 +26,15 @@ import Shader
import Shader.Data import Shader.Data
import Shader.ExtraPrimitive import Shader.ExtraPrimitive
-- | Determine where light is shining in the world. {- | Determine where light is shining in the world.
-- think of the produced texture as showing what RGB values should be "taken think of the produced texture as showing what RGB values should be "taken
-- away" from the shape colors. away" from the shape colors.
-}
createLightMap :: createLightMap ::
Configuration -> Configuration ->
RenderData -> RenderData ->
[(Point3, Float, Point3)] -> -- Lights [(Point3, Float, Point3)] -> -- Lights
-- | number of walls -- | number of walls
Int -> Int ->
-- | number of silhoutte lines to draw -- | number of silhoutte lines to draw
@@ -47,6 +49,63 @@ createLightMap ::
IO () IO ()
createLightMap cfig pdata lightPoints nWalls nSils nCaps shadsdrawtype toPos drawCPUShadows = case shadsdrawtype of createLightMap cfig pdata lightPoints nWalls nSils nCaps shadsdrawtype toPos drawCPUShadows = case shadsdrawtype of
InstancingShads -> instanceLightMap cfig pdata lightPoints nWalls nSils nCaps toPos InstancingShads -> instanceLightMap cfig pdata lightPoints nWalls nSils nCaps toPos
NoShadows -> do
let ltextShad = _lightingTextureShader pdata
-- we assume that the renderbuffer's depth has been correctly set elsewhere
-- we will not be changing that here
glDepthMask GL_FALSE
-- clearColor is specified differently in preloadRender
-- the colors are inverted
glClearColor 1 1 1 1
glClear GL_COLOR_BUFFER_BIT
-- for each of the lights:
-- 1. stencil out the shadows from this light's point of view
-- 2. calculate lighting based on each fragment's position
-- to consider: adding normals/a "material" for each fragment
glBlendFunc GL_ZERO GL_ONE_MINUS_SRC_COLOR
glEnable GL_STENCIL_TEST
--stencilTest $= Enabled
glStencilOpSeparate GL_FRONT GL_KEEP GL_KEEP GL_INCR_WRAP
--stencilOpSeparate Front $= (OpKeep, OpKeep, OpIncrWrap)
--stencilOpSeparate Back $= (OpKeep, OpKeep, OpDecrWrap)
glStencilOpSeparate GL_BACK GL_KEEP GL_KEEP GL_DECR_WRAP
flip VFSM.mapM_ (VFSM.fromList lightPoints) $ \(V3 x y z, rad, V3 r g b) -> do
glDepthFunc GL_LESS
-- setup stencil
glColorMask GL_FALSE GL_FALSE GL_FALSE GL_FALSE
glClear GL_STENCIL_BUFFER_BIT
glDisable GL_CULL_FACE
--cullFace $= Nothing
glStencilFunc GL_ALWAYS 0 255
--draw lightmap itself
glDepthFunc GL_ALWAYS
-- bind world position texture
bindTO toPos
glColorMask GL_TRUE GL_TRUE GL_TRUE GL_TRUE
glStencilFunc GL_EQUAL 0 255
glUseProgram (ltextShad ^. shadProg') --Just (_shadProg ltextShad)
glUniform3f (_shadUnis' ltextShad V.! 0) x y z
glUniform4f (_shadUnis' ltextShad V.! 1) r g b rad
--bindVertexArrayObject $= ltextShad ^? shadVAO' . vaoName -- Just (_vao $ _shadVAO ltextShad)
glBindVertexArray $ ltextShad ^. shadVAO' . vaoName -- Just (_vao $ _shadVAO ltextShad)
glDrawArrays
(marshalEPrimitiveMode (_shadPrim' ltextShad))
0
(fromIntegral (4 :: Int))
--cleanup: may not be necessary, depending on what comes after...
glDisable GL_CULL_FACE
glDisable GL_STENCIL_TEST
NoLighting -> do
glBindFramebuffer GL_FRAMEBUFFER (_unFBO (fst (_fboLighting pdata)))
glClearColor 0 0 0 1
-- glClearDepth 0
glBlendFunc GL_ZERO GL_ONE_MINUS_SRC_COLOR
glClear $ GL_COLOR_BUFFER_BIT + GL_DEPTH_BUFFER_BIT
-- glClearDepth 1
glDisable GL_CULL_FACE
bindTO toPos
glDepthFunc GL_ALWAYS
glDepthMask GL_FALSE
_ -> do _ -> do
let llinesShad = _lightingLineShadowShader pdata let llinesShad = _lightingLineShadowShader pdata
lcapShad = _lightingCapShader pdata lcapShad = _lightingCapShader pdata
@@ -116,17 +175,11 @@ createLightMap cfig pdata lightPoints nWalls nSils nCaps shadsdrawtype toPos dra
CPUObjShads -> drawCPUShadows (V3 x y z) rad CPUObjShads -> drawCPUShadows (V3 x y z) rad
NoObjShads -> return () NoObjShads -> return ()
--draw lightmap itself --draw lightmap itself
glEnable GL_DEPTH_TEST
glDepthFunc GL_ALWAYS glDepthFunc GL_ALWAYS
--depthFunc $= Just Always
-- bind world position texture -- bind world position texture
bindTO toPos bindTO toPos
glColorMask GL_TRUE GL_TRUE GL_TRUE GL_TRUE glColorMask GL_TRUE GL_TRUE GL_TRUE GL_TRUE
--stencilOp $= (OpKeep, OpKeep, OpKeep)
glStencilFunc GL_EQUAL 0 255 glStencilFunc GL_EQUAL 0 255
--currentProgram $= ltextShad ^? shadProg --Just (_shadProg ltextShad)
--uniform (_shadUnis ltextShad V.! 0) $= Vector3 x y z
--uniform (_shadUnis ltextShad V.! 1) $= Vector4 r g b rad
glUseProgram (ltextShad ^. shadProg') --Just (_shadProg ltextShad) glUseProgram (ltextShad ^. shadProg') --Just (_shadProg ltextShad)
glUniform3f (_shadUnis' ltextShad V.! 0) x y z glUniform3f (_shadUnis' ltextShad V.! 0) x y z
glUniform4f (_shadUnis' ltextShad V.! 1) r g b rad glUniform4f (_shadUnis' ltextShad V.! 1) r g b rad
@@ -140,13 +193,14 @@ createLightMap cfig pdata lightPoints nWalls nSils nCaps shadsdrawtype toPos dra
glDisable GL_CULL_FACE glDisable GL_CULL_FACE
glDisable GL_STENCIL_TEST glDisable GL_STENCIL_TEST
lightsToArray :: [(Point3,Float,Point3)] -> [Float] lightsToArray :: [(Point3, Float, Point3)] -> [Float]
lightsToArray xs = concat (take 20 $ map t xs ++ repeat [0,0,0,0]) lightsToArray xs =
++ concat (take 20 $ map s xs ++ repeat [0,0,0,0]) concat (take 20 $ map t xs ++ repeat [0, 0, 0, 0])
++ concat (take 20 $ map s xs ++ repeat [0, 0, 0, 0])
where where
t (V3 a b c,_,_) = [a,b,c,1] t (V3 a b c, _, _) = [a, b, c, 1]
s (_,d,V3 e f g) = [e,f,g,d] s (_, d, V3 e f g) = [e, f, g, d]
--t (V3 a b c,d,V3 e f g) = [a,b,c,1]
instanceLightMap :: instanceLightMap ::
Configuration -> Configuration ->
@@ -162,52 +216,53 @@ instanceLightMap ::
TO -> TO ->
IO () IO ()
instanceLightMap cfig pdata lightPoints nWalls nSils nCaps toPos = do instanceLightMap cfig pdata lightPoints nWalls nSils nCaps toPos = do
let llinesShad = _shadowEdgeShader pdata let lcapShad = _shadowCapShader pdata
lcapShad = _shadowCapShader pdata (xsize, ysize) = getWindowSize cfig
lwallShad = _shadowWallShader pdata
(xsize,ysize) = getWindowSize cfig
withArray (lightsToArray lightPoints) $ \ptr -> withArray (lightsToArray lightPoints) $ \ptr ->
glNamedBufferSubData (pdata ^. lightsUBO) 0 620 ptr glNamedBufferSubData (pdata ^. lightsUBO) 0 620 ptr
forM_ [0 .. 19] $ \i ->
forM_ [0..19] $ \i -> glCopyImageSubData glCopyImageSubData
(pdata ^. rboBaseBloom) (pdata ^. rboBaseBloom)
GL_RENDERBUFFER GL_RENDERBUFFER
0 0
0 0 0 0
0
0
(pdata ^. fboShadow . _2 . _2 . unTO) (pdata ^. fboShadow . _2 . _2 . unTO)
GL_TEXTURE_2D_ARRAY 0 0 0 i (fromIntegral xsize) (fromIntegral ysize) GL_TEXTURE_2D_ARRAY
0
0
0
i
(fromIntegral xsize)
(fromIntegral ysize)
1 1
glBindFramebuffer GL_FRAMEBUFFER (_unFBO (fst (_fboShadow pdata))) glBindFramebuffer GL_FRAMEBUFFER $ pdata ^. fboShadow . _1 . unFBO
glDepthMask GL_FALSE glDepthMask GL_FALSE
-- clearColor is specified differently in preloadRender
-- the colors are inverted
glClearColor 0 0 0 0 glClearColor 0 0 0 0
glClear $ GL_COLOR_BUFFER_BIT + GL_STENCIL_BUFFER_BIT glClear $ GL_COLOR_BUFFER_BIT + GL_STENCIL_BUFFER_BIT
-- for each of the lights: -- stencil out the shadows from each light's point of view
-- 1. stencil out the shadows from this light's point of view -- setup stencil
-- 2. calculate lighting based on each fragment's position
-- to consider: adding normals/a "material" for each fragment
glEnable GL_STENCIL_TEST glEnable GL_STENCIL_TEST
glStencilOpSeparate GL_FRONT GL_KEEP GL_KEEP GL_INCR_WRAP glStencilOpSeparate GL_FRONT GL_KEEP GL_KEEP GL_INCR_WRAP
glStencilOpSeparate GL_BACK GL_KEEP GL_KEEP GL_DECR_WRAP glStencilOpSeparate GL_BACK GL_KEEP GL_KEEP GL_DECR_WRAP
-- this was a loop
glDepthFunc GL_LESS glDepthFunc GL_LESS
-- setup stencil
glColorMask GL_FALSE GL_FALSE GL_FALSE GL_FALSE glColorMask GL_FALSE GL_FALSE GL_FALSE GL_FALSE
glDisable GL_BLEND
glDisable GL_CULL_FACE glDisable GL_CULL_FACE
glStencilFunc GL_ALWAYS 0 255 glStencilFunc GL_ALWAYS 0 255
--draw wall shadows --draw wall shadows
glUseProgram (_shadProg' lwallShad) glUseProgram $ pdata ^. shadowWallShader . shadProg'
glBindVertexArray $ lwallShad ^. shadVAO' . vaoName -- Just (_vao $ _shadVAO lwallShad) glBindVertexArray $ pdata ^. shadowWallShader . shadVAO' . vaoName -- Just (_vao $ _shadVAO lwallShad)
glDrawArrays glDrawArrays
(marshalEPrimitiveMode $ _shadPrim' lwallShad) (marshalEPrimitiveMode $ pdata ^. shadowWallShader . shadPrim')
0 0
(fromIntegral nWalls) (fromIntegral nWalls)
--draw silhouette shadows --draw silhouette shadows
glUseProgram (_shadProg' llinesShad) glUseProgram $ pdata ^. shadowEdgeShader . shadProg'
glBindVertexArray (_vaoName $ _shadVAO' llinesShad) glBindVertexArray $ pdata ^. shadowEdgeShader . shadVAO' . vaoName
glDrawElements glDrawElements
(marshalEPrimitiveMode $ _shadPrim' llinesShad) (marshalEPrimitiveMode $ pdata ^. shadowEdgeShader . shadPrim')
(fromIntegral nSils) (fromIntegral nSils)
GL_UNSIGNED_SHORT GL_UNSIGNED_SHORT
nullPtr nullPtr
@@ -215,31 +270,27 @@ instanceLightMap cfig pdata lightPoints nWalls nSils nCaps toPos = do
glEnable GL_CULL_FACE glEnable GL_CULL_FACE
glCullFace GL_BACK glCullFace GL_BACK
glUseProgram (_shadProg' lcapShad) glUseProgram (_shadProg' lcapShad)
glBindVertexArray $ lcapShad ^. shadVAO' . vaoName --Just (_vao $ _shadVAO lcapShad) glBindVertexArray $ lcapShad ^. shadVAO' . vaoName
glDrawElements glDrawElements
(marshalEPrimitiveMode $ _shadPrim' lcapShad) (marshalEPrimitiveMode $ _shadPrim' lcapShad)
(fromIntegral nCaps) (fromIntegral nCaps)
GL_UNSIGNED_SHORT GL_UNSIGNED_SHORT
nullPtr nullPtr
--draw lightmap itself --draw lightmap itself
glEnable GL_DEPTH_TEST
glDepthFunc GL_ALWAYS glDepthFunc GL_ALWAYS
glColorMask GL_TRUE GL_TRUE GL_TRUE GL_TRUE glColorMask GL_TRUE GL_TRUE GL_TRUE GL_TRUE
glStencilFunc GL_EQUAL 0 255 glStencilFunc GL_EQUAL 0 255
glUseProgram (pdata ^. shadowLightShader . shadProg') glUseProgram (pdata ^. shadowLightShader . shadProg')
-- bind world position texture -- bind world position texture
bindTO toPos bindTO toPos
glDisable GL_BLEND
glBindVertexArray $ pdata ^. shadowLightShader . shadVAO' . vaoName glBindVertexArray $ pdata ^. shadowLightShader . shadVAO' . vaoName
glDrawArrays glDrawArrays
(marshalEPrimitiveMode $ pdata ^. shadowLightShader . shadPrim') (marshalEPrimitiveMode $ pdata ^. shadowLightShader . shadPrim')
0 0
1 1
-- this was the end of the loop -- this was the end of the loop
glDisable GL_CULL_FACE glDisable GL_CULL_FACE
glDisable GL_STENCIL_TEST glDisable GL_STENCIL_TEST
--draw to the lighting framebuffer here --draw to the lighting framebuffer here
glBindFramebuffer GL_FRAMEBUFFER (_unFBO (fst (_fboLighting pdata))) glBindFramebuffer GL_FRAMEBUFFER (_unFBO (fst (_fboLighting pdata)))
glClearColor 1 1 1 1 glClearColor 1 1 1 1
@@ -252,6 +303,11 @@ instanceLightMap cfig pdata lightPoints nWalls nSils nCaps toPos = do
(marshalEPrimitiveMode EPoints) (marshalEPrimitiveMode EPoints)
0 0
1 1
withArray [GL_COLOR_ATTACHMENT0, GL_DEPTH_STENCIL_ATTACHMENT] $ \ptr ->
glInvalidateNamedFramebufferData
(pdata ^. fboShadow . _1 . unFBO)
2
ptr
-- assumes that vertices have already been sent to the shader -- assumes that vertices have already been sent to the shader
pingPongBetween :: pingPongBetween ::
@@ -294,8 +350,10 @@ renderLayer layer shads counts = do
bindTO :: TO -> IO () bindTO :: TO -> IO ()
bindTO t = glBindTexture GL_TEXTURE_2D (_unTO t) bindTO t = glBindTexture GL_TEXTURE_2D (_unTO t)
--textureBinding Texture2D $= Just t
--textureBinding Texture2D $= Just t
bindFBO :: FBO -> IO () bindFBO :: FBO -> IO ()
bindFBO fb = --bindFramebuffer Framebuffer $= fb bindFBO fb =
--bindFramebuffer Framebuffer $= fb
glBindFramebuffer GL_FRAMEBUFFER (_unFBO fb) glBindFramebuffer GL_FRAMEBUFFER (_unFBO fb)