Move towards geometry instancing for shadows

This commit is contained in:
2023-03-10 13:55:41 +00:00
parent cda7116930
commit c8b256c939
14 changed files with 303 additions and 17 deletions
+6
View File
@@ -0,0 +1,6 @@
#version 450 core
out vec4 fColor;
void main()
{
fColor = vec4 (0,0,0,0);
}
+6
View File
@@ -0,0 +1,6 @@
#version 450 core
layout (location = 0) in vec3 pos;
layout (std140, binding = 0) uniform TheMat { mat4 theMat; } ;
void main() {
gl_Position = theMat * vec4(pos,1);
}
+42
View File
@@ -0,0 +1,42 @@
#version 450 core
layout (triangles) in;
layout (triangle_strip, max_vertices = 3) out;
layout (std140, binding = 0) uniform TheMat { mat4 theMat; } ;
//layout (std140, binding = 1) uniform LightsBlock
//{
// vec4 posBool[20];
// vec4 colRad[20];
//} ;
uniform vec3 lightPos;
uniform int lightID;
// this code is duplicated in lineShadow.geom, should not be changed on its own
vec4 projNear (vec4 pos)
{
// note we project to a specific height
// this is quite brittle, not ideal
vec3 dir = pos.xyz - lightPos ;
float a = (140 - pos.z) / dir.z ;
vec2 xy = (pos.xyz + a * dir).xy ;
return vec4 ( xy, 140 , 1) ;
}
void main()
{
vec4 p0 = gl_in[0].gl_Position ;
vec4 p1 = gl_in[1].gl_Position ;
vec4 p2 = gl_in[2].gl_Position ;
if ( //if Light Source is below all vertices, draw cap
// TODO think about when LS is beside the object
( p0.z - lightPos.z > 0 )
&& ( p1.z - lightPos.z > 0 )
&& ( p2.z - lightPos.z > 0 )
)
{
// the front cap
vec4 v1 = vec4 (0,0,1,0) ;
gl_Position = theMat * projNear(p0); EmitVertex();
gl_Position = theMat * projNear(p1); EmitVertex();
gl_Position = theMat * projNear(p2); EmitVertex();
EndPrimitive();
}
else {}
}
+11
View File
@@ -0,0 +1,11 @@
#version 450 core
layout (location = 0) in vec3 position;
layout (std140, binding = 0) uniform TheMat { mat4 theMat; } ;
uniform vec3 lightPos;
uniform vec4 lumRad;
out vec3 dField;
out vec3 lum;
void main()
{
gl_Position = vec4(position,1);
}
+81
View File
@@ -0,0 +1,81 @@
#version 450 core
layout (lines_adjacency) in;
layout (triangle_strip, max_vertices = 4) out;
layout (std140, binding = 0) uniform TheMat { mat4 theMat; } ;
layout (std140, binding = 1) uniform LightsBlock
{
vec4 posBool[20];
vec4 colRad[20];
} ;
//uniform vec3 lightPos;
//uniform float radiusUniform;
uniform int lightID;
vec3 lightPos1 = posBool[lightID].xyz;
//vec3 lightPos1 = lightPos;
float theBool = posBool[lightID].w;
vec4 shift (vec4 p) { return (vec4 (p.xyz + (100000*(p.xyz-lightPos1)), 1));} ;
vec4 shiftBy (float x,vec4 p) { return (vec4 (lightPos1 + (x*normalize(p.xyz-lightPos1)), 1));} ;
// copied from lighting/cap.geom, should not be changed on its own
vec4 projNear (vec4 pos)
{
// note we project to a specific height
// this is quite brittle, not ideal
vec3 dir = pos.xyz - lightPos1 ;
float a = (140 - pos.z) / dir.z ;
vec2 xy = (pos.xyz + a * dir).xy ;
return vec4 ( xy, 140 , 1) ;
} ;
vec4 shiftNear (vec4 pos)
{ vec4 sp = shift(pos);
if (sp.z > 140)
{ return projNear(pos) ; }
else
{ return sp ; }
} ;
vec4 f (vec4 p) {return (theMat * p);} ;
void main()
{
if (theBool == 1){
// float ru2 = radiusUniform * radiusUniform ;
float ru = colRad[lightID].w ;
float ru2 = ru * ru;
vec4 p0 = gl_in[0].gl_Position;
vec4 p1 = gl_in[1].gl_Position;
vec4 mid = 0.5*(p0 + p1);
vec3 n0a = gl_in[2].gl_Position.xyz;
vec3 n1a = gl_in[3].gl_Position.xyz;
vec3 n0 = cross(p1.xyz - p0.xyz, n0a - p0.xyz) ;
vec3 n1 = cross(p0.xyz - p1.xyz, n1a - p1.xyz) ;
//vec3 n2 = n0 + n1; // assumes the summands are normalized
vec3 lightDir = p0.xyz - lightPos1.xyz;
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
// "different directions" wrt the light direction
if ( dot(n0 , lightDir) * dot(n1 , lightDir) <= 0 &&
(dot(lightDir,lightDir) < ru2 || dot(lightDir2,lightDir2) < ru2) )
// using <= rather than < seems to get rid of overlapping shadow
// artefacts
{
vec4 p2 = shiftNear(p0);
vec4 p3 = shiftNear(p1);
if ( dot(n0 , lightDir) > 0)
{
gl_Position = f(p0); EmitVertex();
gl_Position = f(p1); EmitVertex();
gl_Position = f(p2); EmitVertex();
gl_Position = f(p3); EmitVertex();
}
else
{
gl_Position = f(p1); EmitVertex();
gl_Position = f(p0); EmitVertex();
gl_Position = f(p3); EmitVertex();
gl_Position = f(p2); EmitVertex();
}
EndPrimitive();
}
else { }
}else {}
}
+6
View File
@@ -0,0 +1,6 @@
#version 450 core
layout (location = 0) in vec3 pos;
void main()
{
gl_Position = vec4(pos,1);
}
+20
View File
@@ -0,0 +1,20 @@
#version 450 core
layout (std140, binding = 1) uniform LightsBlock
{
vec4 posBool[20];
vec4 colRad[20];
} ;
uniform vec3 lightPos;
uniform vec4 lumRad;
uniform sampler2D screenTexture;
in vec2 vTexPos;
out vec4 fColor;
void main()
{
vec3 distVec = texture(screenTexture,vTexPos).xyz - lightPos;
float dist = dot(distVec,distVec);
if (dist > lumRad.a) {discard;}
float x = 1 - dist / lumRad.a ;
vec3 c = (x * x * x) * lumRad.rgb ;
fColor = vec4(c,0);
}
+9
View File
@@ -0,0 +1,9 @@
#version 450 core
layout (location = 0) in vec2 pos;
layout (location = 1) in vec2 texPos;
out vec2 vTexPos;
void main()
{
gl_Position = vec4(pos,0,1);
vTexPos = texPos;
}
+74
View File
@@ -0,0 +1,74 @@
#version 450 core
layout (points) in;
layout (triangle_strip, max_vertices = 8) out;
layout (std140, binding = 0) uniform TheMat { mat4 theMat; } ;
layout (std140, binding = 1) uniform LightsBlock
{
vec4 posBool[20];
vec4 colRad[20];
} ;
uniform vec3 lightPos;
uniform int lightID;
vec4 shift (vec4 p)
{ 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);
}
// construct a box with openings on bottom face and face away from wall
void main()
{
vec4 p1 = vec4 (gl_in[0].gl_Position.xy,0,1);
vec4 p2 = vec4 (gl_in[0].gl_Position.zw,0,1);
if (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 p5 = shift(p1);
vec4 p6 = shift(p2);
vec4 p7 = vec4 (p6.xy,100,1);
vec4 p8 = vec4 (p5.xy,100,1);
vec4 a1 = theMat * p1;
vec4 a2 = theMat * p2;
vec4 a3 = theMat * p3;
vec4 a4 = theMat * p4;
vec4 a5 = theMat * p5;
vec4 a6 = theMat * p6;
vec4 a7 = theMat * p7;
vec4 a8 = theMat * p8;
//gl_Position = a4; EmitVertex();
//gl_Position = a3; EmitVertex();
//gl_Position = a7; EmitVertex();
//gl_Position = a8; EmitVertex();
//gl_Position = a5; EmitVertex();
//gl_Position = a3; EmitVertex();
//gl_Position = a1; EmitVertex();
//gl_Position = a4; EmitVertex();
//gl_Position = a2; EmitVertex();
//gl_Position = a7; EmitVertex();
//gl_Position = a6; EmitVertex();
gl_Position = a1; EmitVertex();
gl_Position = a5; EmitVertex();
gl_Position = a3; EmitVertex();
gl_Position = a8; EmitVertex();
gl_Position = a4; EmitVertex();
gl_Position = a7; EmitVertex();
gl_Position = a2; EmitVertex();
gl_Position = a6; EmitVertex();
//gl_Position = a5; EmitVertex();
//gl_Position = a1; EmitVertex();
//gl_Position = a8; EmitVertex();
//gl_Position = a3; EmitVertex();
//gl_Position = a7; EmitVertex();
//gl_Position = a4; EmitVertex();
//gl_Position = a6; EmitVertex();
//gl_Position = a2; EmitVertex();
EndPrimitive();
} else {}
}
+6
View File
@@ -0,0 +1,6 @@
#version 450 core
layout (location = 0) in vec4 poss;
void main()
{
gl_Position = poss;
}
+2 -2
View File
@@ -32,7 +32,7 @@ import Shader.Poke
doDrawing :: SDL.Window -> RenderData -> Universe -> IO () doDrawing :: SDL.Window -> RenderData -> Universe -> IO ()
doDrawing win pdata u = do doDrawing win pdata u = do
-- sTicks <- SDL.ticks --sTicks <- SDL.ticks
let w = _uvWorld u let w = _uvWorld u
cfig = _uvConfig u cfig = _uvConfig u
rot = w ^. cWorld . camPos . camRot rot = w ^. cWorld . camPos . camRot
@@ -100,7 +100,7 @@ doDrawing win pdata u = do
setViewportSize (round winx `div` resFact) (round winy `div` resFact) setViewportSize (round winx `div` resFact) (round winy `div` resFact)
--bindFramebuffer Framebuffer $= fst (_fboBase pdata) --bindFramebuffer Framebuffer $= fst (_fboBase pdata)
glBindFramebuffer GL_FRAMEBUFFER (_unFBO (fst (_fboBase pdata))) glBindFramebuffer GL_FRAMEBUFFER (_unFBO (fst (_fboBase pdata)))
glClearColor 0 0 0 0 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
+17 -6
View File
@@ -37,7 +37,7 @@ preloadRender = do
glNamedBufferStorage isoUBO 64 ptr 0 glNamedBufferStorage isoUBO 64 ptr 0
lightsubo <- mglCreate glCreateBuffers lightsubo <- mglCreate glCreateBuffers
glNamedBufferData lightsubo 560 nullPtr GL_STREAM_DRAW glNamedBufferData lightsubo 640 nullPtr GL_STREAM_DRAW
glBindBufferBase GL_UNIFORM_BUFFER 1 lightsubo glBindBufferBase GL_UNIFORM_BUFFER 1 lightsubo
-- setup wall points VBO, VAOs and shaders -- setup wall points VBO, VAOs and shaders
@@ -140,8 +140,16 @@ preloadRender = do
>>= addUniforms ["lightPos", "radiusUniform"] >>= addUniforms ["lightPos", "radiusUniform"]
shadowedgeshader <- shadowedgeshader <-
makeShaderUsingVAO "lighting/lineShadow" [vert, geom] ELinesAdjacency shEdgeVAO makeShaderUsingVAO "shadow/edge" [vert, geom] ELinesAdjacency shEdgeVAO
>>= addUniforms ["lightPos", "radiusUniform"] >>= addUniforms ["lightID"]
-- >>= addUniforms ["lightPos", "radiusUniform","lightID"]
shadowcapshader <-
makeShaderUsingVAO "shadow/cap" [vert, geom] ETriangles shPosVAO
>>= addUniforms ["lightPos", "lightID"]
-- >>= addUniforms ["lightPos"]
shadowwallshader <-
makeShaderUsingVAO "shadow/wallShadow" [vert, geom] EPoints wpVAO
>>= addUniforms ["lightPos","lightID"]
-- positional shader -- positional shader
positionalBlankShad <- makeShader "positional/blank" [vert, frag] [3] ETriangles positionalBlankShad <- makeShader "positional/blank" [vert, frag] [3] ETriangles
@@ -173,6 +181,9 @@ preloadRender = do
lightingTextureShad <- lightingTextureShad <-
makeShaderUsingVAO "lighting/texture" [vert, frag] ETriangleStrip fsshadvao makeShaderUsingVAO "lighting/texture" [vert, frag] ETriangleStrip fsshadvao
>>= addUniforms ["lightPos", "lumRad"] >>= addUniforms ["lightPos", "lumRad"]
shadowlightshader <-
makeShaderUsingVAO "shadow/light" [vert, frag] ETriangleStrip fsshadvao
>>= addUniforms ["lightPos", "lumRad"]
barrelShad <- makeShader "texture/barrel" [vert, geom, frag] [2, 2, 2, 1] EPoints barrelShad <- makeShader "texture/barrel" [vert, geom, frag] [2, 2, 2, 1] EPoints
-- blank wallShader -- blank wallShader
wallBlankShad <- makeShaderUsingVAO "wall/blank" [vert, geom, frag] EPoints wpColVAO wallBlankShad <- makeShaderUsingVAO "wall/blank" [vert, geom, frag] EPoints wpColVAO
@@ -239,9 +250,9 @@ preloadRender = do
, _lightingLineShadowShader = lightingLineShadowShad , _lightingLineShadowShader = lightingLineShadowShad
, _lightingWallShadShader = lightingWallShadShad , _lightingWallShadShader = lightingWallShadShad
, _shadowEdgeShader = shadowedgeshader , _shadowEdgeShader = shadowedgeshader
, _shadowCapShader = shadowedgeshader , _shadowCapShader = shadowcapshader
, _shadowWallShader = shadowedgeshader , _shadowWallShader = shadowwallshader
, _shadowLightShader = shadowedgeshader , _shadowLightShader = shadowlightshader
, _positionalBlankShader = positionalBlankShad , _positionalBlankShader = positionalBlankShad
, _wallBlankShader = wallBlankShad , _wallBlankShader = wallBlankShad
, _wallTextureShader = wallTextureShad , _wallTextureShader = wallTextureShad
+20 -8
View File
@@ -18,7 +18,7 @@ import qualified Data.Vector.Unboxed.Mutable as UMV
import Dodge.Data.Config import Dodge.Data.Config
import Foreign hiding (rotate) import Foreign hiding (rotate)
import Geometry.Data import Geometry.Data
import Graphics.GL.Core43 import Graphics.GL.Core45
import Picture.Data import Picture.Data
import Shader import Shader
import Shader.Data import Shader.Data
@@ -137,6 +137,14 @@ createLightMap pdata lightPoints nWalls nSils nCaps shadsdrawtype toPos drawCPUS
glDisable GL_CULL_FACE glDisable GL_CULL_FACE
glDisable GL_STENCIL_TEST glDisable GL_STENCIL_TEST
lightsToArray :: [(Point3,Float,Point3)] -> [Float]
lightsToArray xs = concat (take 20 $ map t xs ++ repeat [0,0,0,0])
++ concat (take 20 $ map s xs ++ repeat [0,0,0,0])
where
t (V3 a b c,_,_) = [a,b,c,1]
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 ::
RenderData -> RenderData ->
[(Point3, Float, Point3)] -> -- Lights [(Point3, Float, Point3)] -> -- Lights
@@ -150,10 +158,13 @@ instanceLightMap ::
TO -> TO ->
IO () IO ()
instanceLightMap pdata lightPoints nWalls nSils nCaps toPos = do instanceLightMap pdata lightPoints nWalls nSils nCaps toPos = do
let llinesShad = _lightingLineShadowShader pdata let llinesShad = _shadowEdgeShader pdata
lcapShad = _lightingCapShader pdata lcapShad = _shadowCapShader pdata
lwallShad = _lightingWallShadShader pdata lwallShad = _shadowWallShader pdata
ltextShad = _lightingTextureShader pdata --llinesShad = _lightingLineShadowShader pdata
ltextShad = _shadowLightShader pdata
withArray (lightsToArray lightPoints) $ \ptr ->
glNamedBufferSubData (pdata ^. lightsUBO) 0 620 ptr
-- we assume that the renderbuffer's depth has been correctly set elsewhere -- we assume that the renderbuffer's depth has been correctly set elsewhere
-- we will not be changing that here -- we will not be changing that here
glDepthMask GL_FALSE glDepthMask GL_FALSE
@@ -172,7 +183,7 @@ instanceLightMap pdata lightPoints nWalls nSils nCaps toPos = do
--stencilOpSeparate Front $= (OpKeep, OpKeep, OpIncrWrap) --stencilOpSeparate Front $= (OpKeep, OpKeep, OpIncrWrap)
--stencilOpSeparate Back $= (OpKeep, OpKeep, OpDecrWrap) --stencilOpSeparate Back $= (OpKeep, OpKeep, OpDecrWrap)
glStencilOpSeparate GL_BACK GL_KEEP GL_KEEP GL_DECR_WRAP 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 flip VFSM.mapM_ (VFSM.fromList (zip lightPoints [(0::Int)..])) $ \((V3 x y z, rad, V3 r g b),i) -> do
glDepthFunc GL_LESS glDepthFunc GL_LESS
-- setup stencil -- setup stencil
glColorMask GL_FALSE GL_FALSE GL_FALSE GL_FALSE glColorMask GL_FALSE GL_FALSE GL_FALSE GL_FALSE
@@ -186,6 +197,7 @@ instanceLightMap pdata lightPoints nWalls nSils nCaps toPos = do
--uniform (_shadUnis lwallShad V.! 0) --uniform (_shadUnis lwallShad V.! 0)
-- $= Vector3 x y z -- $= Vector3 x y z
glUniform3f (_shadUnis' lwallShad V.! 0) x y z glUniform3f (_shadUnis' lwallShad V.! 0) x y z
glUniform1i (_shadUnis' lwallShad V.! 1) (fromIntegral i)
--bindVertexArrayObject $= lwallShad ^? shadVAO' . vaoName -- Just (_vao $ _shadVAO lwallShad) --bindVertexArrayObject $= lwallShad ^? shadVAO' . vaoName -- Just (_vao $ _shadVAO lwallShad)
glBindVertexArray $ lwallShad ^. shadVAO' . vaoName -- Just (_vao $ _shadVAO lwallShad) glBindVertexArray $ lwallShad ^. shadVAO' . vaoName -- Just (_vao $ _shadVAO lwallShad)
glDrawArrays glDrawArrays
@@ -194,8 +206,7 @@ instanceLightMap pdata lightPoints nWalls nSils nCaps toPos = do
(fromIntegral nWalls) (fromIntegral nWalls)
--draw silhouette shadows --draw silhouette shadows
glUseProgram (_shadProg' llinesShad) glUseProgram (_shadProg' llinesShad)
glUniform3f (_shadUnis' llinesShad V.! 0) x y z glUniform1i (_shadUnis' llinesShad V.! 0) (fromIntegral i)
glUniform1f (_shadUnis' llinesShad V.! 1) rad
glBindVertexArray (_vaoName $ _shadVAO' llinesShad) glBindVertexArray (_vaoName $ _shadVAO' llinesShad)
glDrawElements glDrawElements
(marshalEPrimitiveMode $ _shadPrim' llinesShad) (marshalEPrimitiveMode $ _shadPrim' llinesShad)
@@ -207,6 +218,7 @@ instanceLightMap pdata lightPoints nWalls nSils nCaps toPos = do
glCullFace GL_BACK glCullFace GL_BACK
glUseProgram (_shadProg' lcapShad) glUseProgram (_shadProg' lcapShad)
glUniform3f (_shadUnis' lcapShad V.! 0) x y z glUniform3f (_shadUnis' lcapShad V.! 0) x y z
glUniform1i (_shadUnis' lcapShad V.! 1) (fromIntegral i)
glBindVertexArray $ lcapShad ^. shadVAO' . vaoName --Just (_vao $ _shadVAO lcapShad) glBindVertexArray $ lcapShad ^. shadVAO' . vaoName --Just (_vao $ _shadVAO lcapShad)
glDrawElements glDrawElements
(marshalEPrimitiveMode $ _shadPrim' lcapShad) (marshalEPrimitiveMode $ _shadPrim' lcapShad)
+3 -1
View File
@@ -162,13 +162,15 @@ topPrismIndices n = concatMap f [1..n-2] -- triangles on top face
g x = [2*x,2*x+1,2*x+3 g x = [2*x,2*x+1,2*x+3
,2*x,2*x+3,2*x+2] ,2*x,2*x+3,2*x+2]
-- consider changing the position to a vec4
-- and just doing two pokes rather than seven
-- (especially if adding normal data)
pokeJustV :: Ptr Float pokeJustV :: Ptr Float
-> Int -> Int
-> ShapeV -> ShapeV
-> IO Int -> IO Int
{-# INLINE pokeJustV #-} {-# INLINE pokeJustV #-}
pokeJustV ptr nv sh = do pokeJustV ptr nv sh = do
-- pokeArray (advancePtr ptr (off 0)) [a,b,c,d,e,f,g]
pokeElemOff ptr (off 0) a pokeElemOff ptr (off 0) a
pokeElemOff ptr (off 1) b pokeElemOff ptr (off 1) b
pokeElemOff ptr (off 2) c pokeElemOff ptr (off 2) c