1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-03 17:56:21 +03:00

0032172: Visualization, TKOpenGl - implement simple shadow mapping for a spot light source

added test: opengl/data/shadows/spotlight
This commit is contained in:
mzernova 2022-08-24 15:04:10 +03:00
parent acac44d571
commit 06aa200142
14 changed files with 143 additions and 54 deletions

View File

@ -149,7 +149,8 @@ void Graphic3d_CLight::SetEnabled (Standard_Boolean theIsOn)
// ======================================================================= // =======================================================================
void Graphic3d_CLight::SetCastShadows (Standard_Boolean theToCast) void Graphic3d_CLight::SetCastShadows (Standard_Boolean theToCast)
{ {
if (myType != Graphic3d_TypeOfLightSource_Directional) if (myType != Graphic3d_TypeOfLightSource_Directional
&& myType != Graphic3d_TypeOfLightSource_Spot)
{ {
throw Standard_NotImplemented ("Graphic3d_CLight::SetCastShadows() is not implemented for this light type"); throw Standard_NotImplemented ("Graphic3d_CLight::SetCastShadows() is not implemented for this light type");
} }

View File

@ -18,7 +18,7 @@
#include <Graphic3d_TextureSetBits.hxx> #include <Graphic3d_TextureSetBits.hxx>
#include <Message.hxx> #include <Message.hxx>
#include "../Shaders/Shaders_DirectionalLightShadow_glsl.pxx" #include "../Shaders/Shaders_LightShadow_glsl.pxx"
#include "../Shaders/Shaders_PBRDistribution_glsl.pxx" #include "../Shaders/Shaders_PBRDistribution_glsl.pxx"
#include "../Shaders/Shaders_PBRDirectionalLight_glsl.pxx" #include "../Shaders/Shaders_PBRDirectionalLight_glsl.pxx"
#include "../Shaders/Shaders_PBRGeometry_glsl.pxx" #include "../Shaders/Shaders_PBRGeometry_glsl.pxx"
@ -1165,20 +1165,6 @@ TCollection_AsciiString Graphic3d_ShaderManager::stdComputeLighting (Standard_In
if (theNbLights <= THE_NB_UNROLLED_LIGHTS_MAX) if (theNbLights <= THE_NB_UNROLLED_LIGHTS_MAX)
{ {
Standard_Integer anIndex = 0; Standard_Integer anIndex = 0;
if (theNbShadowMaps > 0)
{
for (Graphic3d_LightSet::Iterator aLightIter (theLights, Graphic3d_LightSet::IterationFilter_ExcludeDisabledAndAmbient);
aLightIter.More(); aLightIter.Next())
{
if (aLightIter.Value()->Type() == Graphic3d_TypeOfLightSource_Directional
&& aLightIter.Value()->ToCastShadows())
{
aLightsLoop = aLightsLoop + EOL" occDirectionalLight (" + anIndex + ", theNormal, theView, theIsFront,"
EOL" occDirectionalLightShadow (occShadowMapSamplers[" + anIndex + "], " + anIndex + ", theNormal));";
++anIndex;
}
}
}
for (Graphic3d_LightSet::Iterator aLightIter (theLights, Graphic3d_LightSet::IterationFilter_ExcludeDisabledAndAmbient); for (Graphic3d_LightSet::Iterator aLightIter (theLights, Graphic3d_LightSet::IterationFilter_ExcludeDisabledAndAmbient);
aLightIter.More(); aLightIter.Next()) aLightIter.More(); aLightIter.Next())
{ {
@ -1193,9 +1179,14 @@ TCollection_AsciiString Graphic3d_ShaderManager::stdComputeLighting (Standard_In
if (theNbShadowMaps > 0 if (theNbShadowMaps > 0
&& aLightIter.Value()->ToCastShadows()) && aLightIter.Value()->ToCastShadows())
{ {
break; aLightsLoop = aLightsLoop +
EOL" occDirectionalLight (" + anIndex + ", theNormal, theView, theIsFront,"
EOL" occLightShadow (occShadowMapSamplers[" + anIndex + "], " + anIndex + ", theNormal));";
}
else
{
aLightsLoop = aLightsLoop + EOL" occDirectionalLight (" + anIndex + ", theNormal, theView, theIsFront, 1.0);";
} }
aLightsLoop = aLightsLoop + EOL" occDirectionalLight (" + anIndex + ", theNormal, theView, theIsFront, 1.0);";
++anIndex; ++anIndex;
break; break;
} }
@ -1207,7 +1198,17 @@ TCollection_AsciiString Graphic3d_ShaderManager::stdComputeLighting (Standard_In
} }
case Graphic3d_TypeOfLightSource_Spot: case Graphic3d_TypeOfLightSource_Spot:
{ {
aLightsLoop = aLightsLoop + EOL" occSpotLight (" + anIndex + ", theNormal, theView, aPoint, theIsFront);"; if (theNbShadowMaps > 0
&& aLightIter.Value()->ToCastShadows())
{
aLightsLoop = aLightsLoop +
EOL" occSpotLight (" + anIndex + ", theNormal, theView, aPoint, theIsFront,"
EOL" occLightShadow (occShadowMapSamplers[" + anIndex + "], " + anIndex + ", theNormal));";
}
else
{
aLightsLoop = aLightsLoop + EOL" occSpotLight (" + anIndex + ", theNormal, theView, aPoint, theIsFront, 1.0);";
}
++anIndex; ++anIndex;
break; break;
} }
@ -1254,7 +1255,7 @@ TCollection_AsciiString Graphic3d_ShaderManager::stdComputeLighting (Standard_In
aLightsLoop += aLightsLoop +=
EOL" if (aType == OccLightType_Spot)" EOL" if (aType == OccLightType_Spot)"
EOL" {" EOL" {"
EOL" occSpotLight (anIndex, theNormal, theView, aPoint, theIsFront);" EOL" occSpotLight (anIndex, theNormal, theView, aPoint, theIsFront, 1.0);"
EOL" }"; EOL" }";
} }
aLightsLoop += EOL" }"; aLightsLoop += EOL" }";
@ -1269,6 +1270,7 @@ TCollection_AsciiString Graphic3d_ShaderManager::stdComputeLighting (Standard_In
aLightsFunc += Shaders_PBRIllumination_glsl; aLightsFunc += Shaders_PBRIllumination_glsl;
} }
bool isShadowShaderAdded = false;
if (theLights->NbEnabledLightsOfType (Graphic3d_TypeOfLightSource_Directional) == 1 if (theLights->NbEnabledLightsOfType (Graphic3d_TypeOfLightSource_Directional) == 1
&& theNbLights == 1 && theNbLights == 1
&& !theIsPBR && !theIsPBR
@ -1280,9 +1282,10 @@ TCollection_AsciiString Graphic3d_ShaderManager::stdComputeLighting (Standard_In
} }
else if (theLights->NbEnabledLightsOfType (Graphic3d_TypeOfLightSource_Directional) > 0) else if (theLights->NbEnabledLightsOfType (Graphic3d_TypeOfLightSource_Directional) > 0)
{ {
if (theNbShadowMaps > 0) if (theNbShadowMaps > 0 && !isShadowShaderAdded)
{ {
aLightsFunc += Shaders_DirectionalLightShadow_glsl; aLightsFunc += Shaders_LightShadow_glsl;
isShadowShaderAdded = true;
} }
aLightsFunc += theIsPBR ? Shaders_PBRDirectionalLight_glsl : Shaders_PhongDirectionalLight_glsl; aLightsFunc += theIsPBR ? Shaders_PBRDirectionalLight_glsl : Shaders_PhongDirectionalLight_glsl;
} }
@ -1292,6 +1295,10 @@ TCollection_AsciiString Graphic3d_ShaderManager::stdComputeLighting (Standard_In
} }
if (theLights->NbEnabledLightsOfType (Graphic3d_TypeOfLightSource_Spot) > 0) if (theLights->NbEnabledLightsOfType (Graphic3d_TypeOfLightSource_Spot) > 0)
{ {
if (theNbShadowMaps > 0 && !isShadowShaderAdded)
{
aLightsFunc += Shaders_LightShadow_glsl;
}
aLightsFunc += theIsPBR ? Shaders_PBRSpotLight_glsl : Shaders_PhongSpotLight_glsl; aLightsFunc += theIsPBR ? Shaders_PBRSpotLight_glsl : Shaders_PhongSpotLight_glsl;
} }
} }

View File

@ -268,7 +268,7 @@ public:
{ {
if (myLightSourceState.ShadowMaps().IsNull() if (myLightSourceState.ShadowMaps().IsNull()
|| myLightSourceState.ToCastShadows() == theToCast) || myLightSourceState.ToCastShadows() == theToCast)
{ {
return myLightSourceState.ToCastShadows(); return myLightSourceState.ToCastShadows();
} }

View File

@ -138,9 +138,41 @@ bool OpenGl_ShadowMap::UpdateCamera (const Graphic3d_CView& theView,
} }
case Graphic3d_TypeOfLightSource_Spot: case Graphic3d_TypeOfLightSource_Spot:
{ {
//myShadowCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective); if (theOrigin != NULL)
//myShadowCamera->SetEye (theCastShadowLight->Position()); {
return false; // not implemented Graphic3d_Mat4d aTrans;
aTrans.Translate (Graphic3d_Vec3d (theOrigin->X(), theOrigin->Y(), theOrigin->Z()));
Graphic3d_Mat4d anOrientMat = myShadowCamera->OrientationMatrix() * aTrans;
myLightMatrix = myShadowCamera->ProjectionMatrixF() * Graphic3d_Mat4 (anOrientMat);
return true;
}
Graphic3d_Vec4d aDir (myShadowLight->Direction().X(), myShadowLight->Direction().Y(), myShadowLight->Direction().Z(), 0.0);
if (myShadowLight->IsHeadlight())
{
Graphic3d_Mat4d anOrientInv;
theView.Camera()->OrientationMatrix().Inverted (anOrientInv);
aDir = anOrientInv * aDir;
}
myShadowCamera->SetZeroToOneDepth (theView.Camera()->IsZeroToOneDepth());
myShadowCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
const gp_Pnt& aLightPos = myShadowLight->Position();
Standard_Real aDistance (aMinMaxBox.Distance (Bnd_Box (aLightPos, aLightPos))
+ aMinMaxBox.CornerMin().Distance (aMinMaxBox.CornerMax()));
myShadowCamera->SetDistance (aDistance);
myShadowCamera->MoveEyeTo (aLightPos);
myShadowCamera->SetDirectionFromEye (myShadowLight->Direction());
myShadowCamera->SetUp (!myShadowCamera->Direction().IsParallel (gp::DY(), Precision::Angular())
? gp::DY()
: gp::DX());
myShadowCamera->OrthogonalizeUp();
myShadowCamera->SetZRange (1.0, aDistance);
myLightMatrix = myShadowCamera->ProjectionMatrixF() * myShadowCamera->OrientationMatrixF();
return true;
} }
} }
return false; return false;

View File

@ -2334,9 +2334,12 @@ void OpenGl_View::renderShadowMap (const Handle(OpenGl_ShadowMap)& theShadowMap)
aCtx->core11fwd->glClearDepth (1.0); aCtx->core11fwd->glClearDepth (1.0);
aCtx->core11fwd->glClear (GL_DEPTH_BUFFER_BIT); aCtx->core11fwd->glClear (GL_DEPTH_BUFFER_BIT);
Graphic3d_Camera::Projection aProjection = theShadowMap->LightSource()->Type() == Graphic3d_TypeOfLightSource_Directional
? Graphic3d_Camera::Projection_Orthographic
: Graphic3d_Camera::Projection_Perspective;
myWorkspace->SetRenderFilter (myWorkspace->RenderFilter() | OpenGl_RenderFilter_SkipTrsfPersistence); myWorkspace->SetRenderFilter (myWorkspace->RenderFilter() | OpenGl_RenderFilter_SkipTrsfPersistence);
renderScene (Graphic3d_Camera::Projection_Orthographic, aShadowBuffer.get(), NULL, false); renderScene (aProjection, aShadowBuffer.get(), NULL, false);
myWorkspace->SetRenderFilter (myWorkspace->RenderFilter() & ~(Standard_Integer )OpenGl_RenderFilter_SkipTrsfPersistence); myWorkspace->SetRenderFilter (myWorkspace->RenderFilter() & ~(Standard_Integer)OpenGl_RenderFilter_SkipTrsfPersistence);
aCtx->SetColorMask (true); aCtx->SetColorMask (true);
myWorkspace->ResetAppliedAspect(); myWorkspace->ResetAppliedAspect();

View File

@ -1,6 +1,6 @@
srcinc:::Declarations.glsl srcinc:::Declarations.glsl
srcinc:::DeclarationsImpl.glsl srcinc:::DeclarationsImpl.glsl
srcinc:::DirectionalLightShadow.glsl srcinc:::LightShadow.glsl
srcinc:::PBRCookTorrance.glsl srcinc:::PBRCookTorrance.glsl
srcinc:::PBRDirectionalLight.glsl srcinc:::PBRDirectionalLight.glsl
srcinc:::PBRDistribution.glsl srcinc:::PBRDistribution.glsl
@ -27,7 +27,7 @@ srcinc:::TangentSpaceNormal.glsl
srcinc:::SkydomBackground.fs srcinc:::SkydomBackground.fs
Shaders_Declarations_glsl.pxx Shaders_Declarations_glsl.pxx
Shaders_DeclarationsImpl_glsl.pxx Shaders_DeclarationsImpl_glsl.pxx
Shaders_DirectionalLightShadow_glsl.pxx Shaders_LightShadow_glsl.pxx
Shaders_Display_fs.pxx Shaders_Display_fs.pxx
Shaders_PBRCookTorrance_glsl.pxx Shaders_PBRCookTorrance_glsl.pxx
Shaders_PBRDirectionalLight_glsl.pxx Shaders_PBRDirectionalLight_glsl.pxx

View File

@ -9,10 +9,10 @@ const vec2 occPoissonDisk16[16] = vec2[](
); );
#endif #endif
//! Function computes directional light shadow attenuation (1.0 means no shadow). //! Function computes directional and spot light shadow attenuation (1.0 means no shadow).
float occDirectionalLightShadow (in sampler2D theShadow, float occLightShadow (in sampler2D theShadow,
in int theId, in int theId,
in vec3 theNormal) in vec3 theNormal)
{ {
vec4 aPosLightSpace = PosLightSpace[occLight_Index(theId)]; vec4 aPosLightSpace = PosLightSpace[occLight_Index(theId)];
vec3 aLightDir = occLight_Position (theId); vec3 aLightDir = occLight_Position (theId);

View File

@ -9,7 +9,8 @@ void occSpotLight (in int theId,
in vec3 theNormal, in vec3 theNormal,
in vec3 theView, in vec3 theView,
in vec3 thePoint, in vec3 thePoint,
in bool theIsFront) in bool theIsFront,
in float theShadow)
{ {
vec3 aLight = occLight_Position (theId) - thePoint; vec3 aLight = occLight_Position (theId) - thePoint;
@ -40,5 +41,5 @@ void occSpotLight (in int theId,
DirectLighting += occPBRIllumination (theView, aLight, theNormal, DirectLighting += occPBRIllumination (theView, aLight, theNormal,
BaseColor, Metallic, Roughness, IOR, BaseColor, Metallic, Roughness, IOR,
occLight_Specular(theId), occLight_Specular(theId),
occLight_Intensity(theId) * anAtten); occLight_Intensity(theId) * anAtten) * theShadow;
} }

View File

@ -5,11 +5,13 @@
//! @param theView view direction //! @param theView view direction
//! @param thePoint 3D position (world space) //! @param thePoint 3D position (world space)
//! @param theIsFront front/back face flag //! @param theIsFront front/back face flag
//! @param theShadow the value from shadow map
void occSpotLight (in int theId, void occSpotLight (in int theId,
in vec3 theNormal, in vec3 theNormal,
in vec3 theView, in vec3 theView,
in vec3 thePoint, in vec3 thePoint,
in bool theIsFront) in bool theIsFront,
in float theShadow)
{ {
vec3 aLight = occLight_Position (theId) - thePoint; vec3 aLight = occLight_Position (theId) - thePoint;
@ -45,6 +47,6 @@ void occSpotLight (in int theId,
aSpecl = pow (aNdotH, occMaterial_Shininess (theIsFront)); aSpecl = pow (aNdotH, occMaterial_Shininess (theIsFront));
} }
Diffuse += occLight_Diffuse (theId) * aNdotL * anAtten; Diffuse += occLight_Diffuse (theId) * aNdotL * anAtten * theShadow;
Specular += occLight_Specular(theId) * aSpecl * anAtten; Specular += occLight_Specular(theId) * aSpecl * anAtten * theShadow;
} }

View File

@ -1,6 +1,6 @@
// This file has been automatically generated from resource file src/Shaders/DirectionalLightShadow.glsl // This file has been automatically generated from resource file src/Shaders/LightShadow.glsl
static const char Shaders_DirectionalLightShadow_glsl[] = static const char Shaders_LightShadow_glsl[] =
"#if (__VERSION__ >= 120)\n" "#if (__VERSION__ >= 120)\n"
"//! Coefficients for gathering close samples for antialiasing.\n" "//! Coefficients for gathering close samples for antialiasing.\n"
"//! Use only with decent OpenGL (array constants cannot be initialized with GLSL 1.1 / GLSL ES 1.1)\n" "//! Use only with decent OpenGL (array constants cannot be initialized with GLSL 1.1 / GLSL ES 1.1)\n"
@ -12,10 +12,10 @@ static const char Shaders_DirectionalLightShadow_glsl[] =
");\n" ");\n"
"#endif\n" "#endif\n"
"\n" "\n"
"//! Function computes directional light shadow attenuation (1.0 means no shadow).\n" "//! Function computes directional and spot light shadow attenuation (1.0 means no shadow).\n"
"float occDirectionalLightShadow (in sampler2D theShadow,\n" "float occLightShadow (in sampler2D theShadow,\n"
" in int theId,\n" " in int theId,\n"
" in vec3 theNormal)\n" " in vec3 theNormal)\n"
"{\n" "{\n"
" vec4 aPosLightSpace = PosLightSpace[occLight_Index(theId)];\n" " vec4 aPosLightSpace = PosLightSpace[occLight_Index(theId)];\n"
" vec3 aLightDir = occLight_Position (theId);\n" " vec3 aLightDir = occLight_Position (theId);\n"

View File

@ -12,7 +12,8 @@ static const char Shaders_PBRSpotLight_glsl[] =
" in vec3 theNormal,\n" " in vec3 theNormal,\n"
" in vec3 theView,\n" " in vec3 theView,\n"
" in vec3 thePoint,\n" " in vec3 thePoint,\n"
" in bool theIsFront)\n" " in bool theIsFront,\n"
" in float theShadow)\n"
"{\n" "{\n"
" vec3 aLight = occLight_Position (theId) - thePoint;\n" " vec3 aLight = occLight_Position (theId) - thePoint;\n"
"\n" "\n"
@ -43,5 +44,5 @@ static const char Shaders_PBRSpotLight_glsl[] =
" DirectLighting += occPBRIllumination (theView, aLight, theNormal,\n" " DirectLighting += occPBRIllumination (theView, aLight, theNormal,\n"
" BaseColor, Metallic, Roughness, IOR,\n" " BaseColor, Metallic, Roughness, IOR,\n"
" occLight_Specular(theId),\n" " occLight_Specular(theId),\n"
" occLight_Intensity(theId) * anAtten);\n" " occLight_Intensity(theId) * anAtten) * theShadow;\n"
"}\n"; "}\n";

View File

@ -8,11 +8,13 @@ static const char Shaders_PhongSpotLight_glsl[] =
"//! @param theView view direction\n" "//! @param theView view direction\n"
"//! @param thePoint 3D position (world space)\n" "//! @param thePoint 3D position (world space)\n"
"//! @param theIsFront front/back face flag\n" "//! @param theIsFront front/back face flag\n"
"//! @param theShadow the value from shadow map\n"
"void occSpotLight (in int theId,\n" "void occSpotLight (in int theId,\n"
" in vec3 theNormal,\n" " in vec3 theNormal,\n"
" in vec3 theView,\n" " in vec3 theView,\n"
" in vec3 thePoint,\n" " in vec3 thePoint,\n"
" in bool theIsFront)\n" " in bool theIsFront,\n"
" in float theShadow)\n"
"{\n" "{\n"
" vec3 aLight = occLight_Position (theId) - thePoint;\n" " vec3 aLight = occLight_Position (theId) - thePoint;\n"
"\n" "\n"
@ -48,6 +50,6 @@ static const char Shaders_PhongSpotLight_glsl[] =
" aSpecl = pow (aNdotH, occMaterial_Shininess (theIsFront));\n" " aSpecl = pow (aNdotH, occMaterial_Shininess (theIsFront));\n"
" }\n" " }\n"
"\n" "\n"
" Diffuse += occLight_Diffuse (theId) * aNdotL * anAtten;\n" " Diffuse += occLight_Diffuse (theId) * aNdotL * anAtten * theShadow;\n"
" Specular += occLight_Specular(theId) * aSpecl * anAtten;\n" " Specular += occLight_Specular(theId) * aSpecl * anAtten * theShadow;\n"
"}\n"; "}\n";

View File

@ -9858,13 +9858,13 @@ static int VLight (Draw_Interpretor& theDi,
<< (aLight->IsEnabled() ? "ON" : "OFF") << "\n"; << (aLight->IsEnabled() ? "ON" : "OFF") << "\n";
switch (aLight->Type()) switch (aLight->Type())
{ {
case V3d_AMBIENT: case Graphic3d_TypeOfLightSource_Ambient:
{ {
theDi << " Type: Ambient\n" theDi << " Type: Ambient\n"
<< " Intensity: " << aLight->Intensity() << "\n"; << " Intensity: " << aLight->Intensity() << "\n";
break; break;
} }
case V3d_DIRECTIONAL: case Graphic3d_TypeOfLightSource_Directional:
{ {
theDi << " Type: Directional\n" theDi << " Type: Directional\n"
<< " Intensity: " << aLight->Intensity() << "\n" << " Intensity: " << aLight->Intensity() << "\n"
@ -9874,7 +9874,7 @@ static int VLight (Draw_Interpretor& theDi,
<< " Direction: " << aLight->PackedDirection().x() << " " << aLight->PackedDirection().y() << " " << aLight->PackedDirection().z() << "\n"; << " Direction: " << aLight->PackedDirection().x() << " " << aLight->PackedDirection().y() << " " << aLight->PackedDirection().z() << "\n";
break; break;
} }
case V3d_POSITIONAL: case Graphic3d_TypeOfLightSource_Positional:
{ {
theDi << " Type: Positional\n" theDi << " Type: Positional\n"
<< " Intensity: " << aLight->Intensity() << "\n" << " Intensity: " << aLight->Intensity() << "\n"
@ -9886,7 +9886,7 @@ static int VLight (Draw_Interpretor& theDi,
<< " Range: " << aLight->Range() << "\n"; << " Range: " << aLight->Range() << "\n";
break; break;
} }
case V3d_SPOT: case Graphic3d_TypeOfLightSource_Spot:
{ {
theDi << " Type: Spot\n" theDi << " Type: Spot\n"
<< " Intensity: " << aLight->Intensity() << "\n" << " Intensity: " << aLight->Intensity() << "\n"
@ -14592,6 +14592,7 @@ Spot light parameters:
-spotAngle sets spotlight angle; -spotAngle sets spotlight angle;
-spotExp sets spotlight exponenta; -spotExp sets spotlight exponenta;
-headlight sets headlight flag; -headlight sets headlight flag;
-castShadows enables/disables shadow casting;
-constAtten (obsolete) sets constant attenuation factor; -constAtten (obsolete) sets constant attenuation factor;
-linearAtten (obsolete) sets linear attenuation factor. -linearAtten (obsolete) sets linear attenuation factor.

View File

@ -0,0 +1,39 @@
puts "========"
puts "0032172: Visualization, TKOpenGl - implement simple shadow mapping for a spot light source"
puts "Test shadow map from a spot light source on a box geometry."
puts "========"
pload MODELING VISUALIZATION
if { $::tcl_platform(os) == "Darwin" } { vcaps -core }
box b 1 2 3
box bb -5 -5 0 10 10 0 -preview
vclear
vinit View1
vrenderparams -shadingModel phong
vdisplay -dispMode 1 b bb
vaspects b -material STONE -color blue
vaspects bb -material STONE -color red
vfit
vlight -clear
vlight lamp1 -add spot -castShadows 1 -direction 1 1 -1 -position -10 -10 10
vlight lamp2 -add spot -castShadows 1 -direction -1 -1 -1 -position 10 10 10 -intensity 1000
vdump $::imagedir/${::casename}_two_spots.png
vlight -remove lamp1
vline lin1 10 10 10 -5 -5 -0.5
vline lin2 10 10 10 -3.5 -5 -0.5
vline lin3 10 10 10 -5 -2 -0.5
if { ![string match "OpenGL ES 2.0*" [vglinfo VERSION]] && ![string match "OpenGL ES 3.0*" [vglinfo VERSION]] } {
vraytrace 1
vdump $::imagedir/${::casename}_raytrace.png
}
vraytrace 0
vrenderparams -shadingModel phong
vrenderparams -shadowMapBias 0.001
vdump $::imagedir/${::casename}_phong.png
vrenderparams -shadingModel pbr
vdump $::imagedir/${::casename}_pbr.png