diff --git a/samples/tcl/raytrace.tcl b/samples/tcl/raytrace.tcl index efe00e42e2..f203a173b1 100644 --- a/samples/tcl/raytrace.tcl +++ b/samples/tcl/raytrace.tcl @@ -31,7 +31,6 @@ vfit # set ray tracing puts "Trying raytrace mode..." -if { ! [catch {vraytrace 1}] } { +if { ! [catch {vrenderparams -raytrace -shadows -reflections -fsaa -rayDepth 5}] } { vtextureenv on 1 - vsetraytracemode shad=1 refl=1 aa=1 } diff --git a/src/Graphic3d/FILES b/src/Graphic3d/FILES index b17e37547b..84af421dfc 100755 --- a/src/Graphic3d/FILES +++ b/src/Graphic3d/FILES @@ -67,3 +67,4 @@ Graphic3d_SequenceOfHClipPlane_Handle.hxx Graphic3d_Camera.cxx Graphic3d_Camera.hxx Graphic3d_Camera_Handle.hxx +Graphic3d_RenderingParams.hxx diff --git a/src/Graphic3d/Graphic3d.cdl b/src/Graphic3d/Graphic3d.cdl index dcf0a93066..e08f81ae17 100644 --- a/src/Graphic3d/Graphic3d.cdl +++ b/src/Graphic3d/Graphic3d.cdl @@ -339,6 +339,13 @@ is -- - ASPECT_MARKER: aspect for marker primitives; -- - ASPECT_FILL_AREA: aspect for face primitives. + enumeration RenderingMode is + RM_RASTERIZATION, RM_RAYTRACING + end RenderingMode; + ---Purpose: Describes rendering modes. + -- - RM_RASTERIZATION: enables OpenGL rasterization mode; + -- - RM_RAYTRACING: enables GPU ray-tracing mode. + --------------------------- -- Category: Imported types --------------------------- @@ -404,6 +411,10 @@ is imported CView; ---Purpose: Defines the C structure ---Category: Imported types + + imported RenderingParams; + ---Purpose: Describes rendering parameters and effects. + ---Category: Imported types imported CGraduatedTrihedron; ---Purpose: Defines the C structure of a graduated trihedron. diff --git a/src/Graphic3d/Graphic3d_CView.hxx b/src/Graphic3d/Graphic3d_CView.hxx index 980a4ada22..e8d9e73b62 100644 --- a/src/Graphic3d/Graphic3d_CView.hxx +++ b/src/Graphic3d/Graphic3d_CView.hxx @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -96,11 +97,7 @@ public: GDisplayCB (NULL), GClientData (NULL), ptrFBO (NULL), - WasRedrawnGL (0), - IsRaytracing (0), - IsShadowsEnabled (1), - IsReflectionsEnabled (0), - IsAntialiasingEnabled (0) + WasRedrawnGL (0) { memset(&DefWindow,0,sizeof(DefWindow)); } @@ -134,17 +131,8 @@ public: //! Was the window redrawn by standard OpenGL? mutable int WasRedrawnGL; - //! Enables/disables OpenCL-based ray-tracing. - int IsRaytracing; - - //! Enables/disables ray-traced sharp shadows. - int IsShadowsEnabled; - - //! Enables/disables ray-traced reflections. - int IsReflectionsEnabled; - - //! Enables/disables ray-traced adaptive anti-aliasing. - int IsAntialiasingEnabled; + //! Specifies rendering parameters and effects. + Graphic3d_RenderingParams RenderParams; }; diff --git a/src/Graphic3d/Graphic3d_RenderingParams.hxx b/src/Graphic3d/Graphic3d_RenderingParams.hxx new file mode 100644 index 0000000000..12d1fd0cf2 --- /dev/null +++ b/src/Graphic3d/Graphic3d_RenderingParams.hxx @@ -0,0 +1,65 @@ +// Created on: 2014-05-14 +// Created by: Denis BOGOLEPOV +// Copyright (c) 2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _Graphic3d_RenderingParams_HeaderFile +#define _Graphic3d_RenderingParams_HeaderFile + +#include + +//! Helper class to store rendering parameters. +class Graphic3d_RenderingParams +{ +public: + + //! Default ray-tracing depth. + static const Standard_Integer THE_DEFAULT_DEPTH = 3; + +public: + + //! Creates default rendering parameters. + Graphic3d_RenderingParams() + : Method (Graphic3d_RM_RASTERIZATION), + RaytracingDepth (THE_DEFAULT_DEPTH), + IsShadowEnabled (Standard_True), + IsReflectionEnabled (Standard_False), + IsAntialiasingEnabled (Standard_False), + IsTransparentShadowEnabled (Standard_False) + { + // + } + +public: + + //! Specifies rendering mode. + Graphic3d_RenderingMode Method; + + //! Maximum ray-tracing depth. + Standard_Integer RaytracingDepth; + + //! Enables/disables shadows rendering. + Standard_Boolean IsShadowEnabled; + + //! Enables/disables specular reflections. + Standard_Boolean IsReflectionEnabled; + + //! Enables/disables adaptive anti-aliasing. + Standard_Boolean IsAntialiasingEnabled; + + //! Enables/disables light propagation through transparent media. + Standard_Boolean IsTransparentShadowEnabled; + +}; + +#endif // _Graphic3d_RenderingParams_HeaderFile diff --git a/src/OpenGl/OpenGl_GraphicDriver_7.cxx b/src/OpenGl/OpenGl_GraphicDriver_7.cxx index a7087e3094..9eabd7f852 100644 --- a/src/OpenGl/OpenGl_GraphicDriver_7.cxx +++ b/src/OpenGl/OpenGl_GraphicDriver_7.cxx @@ -103,7 +103,7 @@ void OpenGl_GraphicDriver::Redraw (const Graphic3d_CView& ACView, const Standard_Integer /*width*/, const Standard_Integer /*height*/) { - if (!myCaps->vboDisable && ACView.IsRaytracing) + if (!myCaps->vboDisable && ACView.RenderParams.Method == Graphic3d_RM_RAYTRACING) { if (ACView.WasRedrawnGL) { diff --git a/src/OpenGl/OpenGl_Workspace.cxx b/src/OpenGl/OpenGl_Workspace.cxx index 35db132e9d..b6dd1662ae 100644 --- a/src/OpenGl/OpenGl_Workspace.cxx +++ b/src/OpenGl/OpenGl_Workspace.cxx @@ -148,7 +148,6 @@ OpenGl_Workspace::OpenGl_Workspace (const Handle(Aspect_DisplayConnection)& theD // myComputeInitStatus (OpenGl_RT_NONE), myIsRaytraceDataValid (Standard_False), - myTraversalStackSize (THE_DEFAULT_STACK_SIZE), myViewModificationStatus (0), myLayersModificationStatus (0), // @@ -579,7 +578,7 @@ void OpenGl_Workspace::Redraw (const Graphic3d_CView& theCView, toSwap = 0; // no need to swap buffers } - if (!theCView.IsRaytracing || myComputeInitStatus == OpenGl_RT_FAIL) + if (theCView.RenderParams.Method != Graphic3d_RM_RAYTRACING || myComputeInitStatus == OpenGl_RT_FAIL) { const Standard_Boolean isImmediate = !myView->ImmediateStructures().IsEmpty(); redraw1 (theCView, theCUnderLayer, theCOverLayer, isImmediate ? 0 : toSwap); diff --git a/src/OpenGl/OpenGl_Workspace.hxx b/src/OpenGl/OpenGl_Workspace.hxx index c5b7f16c9e..d9f96340c6 100755 --- a/src/OpenGl/OpenGl_Workspace.hxx +++ b/src/OpenGl/OpenGl_Workspace.hxx @@ -363,9 +363,34 @@ protected: }; + //! Default ray-tracing depth. + static const Standard_Integer THE_DEFAULT_RAY_DEPTH = 3; + //! Default size of traversal stack. static const Standard_Integer THE_DEFAULT_STACK_SIZE = 24; + //! Compile-time ray-tracing parameters. + struct RaytracingParams + { + //! Actual size of traversal stack in shader program. + Standard_Integer StackSize; + + //! Actual ray-tracing depth (number of ray bounces). + Standard_Integer TraceDepth; + + //! Sets light propagation through transparent media. + Standard_Boolean TransparentShadows; + + //! Creates default compile-time ray-tracing parameters. + RaytracingParams() + : StackSize (THE_DEFAULT_STACK_SIZE), + TraceDepth (THE_DEFAULT_RAY_DEPTH), + TransparentShadows (Standard_False) + { + // + } + }; + protected: //! @name methods related to ray-tracing //! Updates 3D scene geometry for ray-tracing. @@ -444,7 +469,7 @@ protected: //! @name methods related to ray-tracing Standard_Boolean SafeFailBack (const TCollection_ExtendedString& theMessage); //! Initializes OpenGL/GLSL shader programs. - Standard_Boolean InitRaytraceResources(); + Standard_Boolean InitRaytraceResources (const Graphic3d_CView& theCView); //! Releases OpenGL/GLSL shader programs. void ReleaseRaytraceResources(); @@ -493,8 +518,8 @@ protected: //! @name fields related to ray-tracing //! Scene epsilon to prevent self-intersections. Standard_ShortReal myRaytraceSceneEpsilon; - //! Actual size of traversal stack in shader program. - Standard_Integer myTraversalStackSize; + //! Compile-time ray-tracing parameters. + RaytracingParams myRaytraceParameters; //! OpenGL/GLSL source of ray-tracing fragment shader. ShaderSource myRaytraceShaderSource; diff --git a/src/OpenGl/OpenGl_Workspace_Raytrace.cxx b/src/OpenGl/OpenGl_Workspace_Raytrace.cxx index ab077f41b0..91792ce1b1 100755 --- a/src/OpenGl/OpenGl_Workspace_Raytrace.cxx +++ b/src/OpenGl/OpenGl_Workspace_Raytrace.cxx @@ -467,7 +467,7 @@ OpenGl_TriangleSet* OpenGl_Workspace::AddRaytracePrimitiveArray (const OpenGl_Pr } #ifdef RAY_TRACE_PRINT_INFO - switch (aPArray->DrawMode()) + switch (theArray->DrawMode()) { case GL_POLYGON: std::cout << "\tAdding GL_POLYGON\n"; break; case GL_TRIANGLES: std::cout << "\tAdding GL_TRIANGLES\n"; break; @@ -546,7 +546,7 @@ OpenGl_TriangleSet* OpenGl_Workspace::AddRaytracePrimitiveArray (const OpenGl_Pr if (!aBounds.IsNull()) { #ifdef RAY_TRACE_PRINT_INFO - std::cout << "\tNumber of bounds = " << aPArray->num_bounds << std::endl; + std::cout << "\tNumber of bounds = " << aBounds->NbBounds << std::endl; #endif Standard_Integer aBoundStart = 0; @@ -1119,7 +1119,7 @@ Standard_Boolean OpenGl_Workspace::SafeFailBack (const TCollection_ExtendedStrin // function : InitRaytraceResources // purpose : Initializes OpenGL/GLSL shader programs // ======================================================================= -Standard_Boolean OpenGl_Workspace::InitRaytraceResources() +Standard_Boolean OpenGl_Workspace::InitRaytraceResources (const Graphic3d_CView& theCView) { Standard_Boolean aToRebuildShaders = Standard_False; @@ -1131,39 +1131,60 @@ Standard_Boolean OpenGl_Workspace::InitRaytraceResources() const Standard_Integer aRequiredStackSize = myRaytraceGeometry.HighLevelTreeDepth() + myRaytraceGeometry.BottomLevelTreeDepth(); - if (myTraversalStackSize < aRequiredStackSize) + if (myRaytraceParameters.StackSize < aRequiredStackSize) { - myTraversalStackSize = Max (aRequiredStackSize, THE_DEFAULT_STACK_SIZE); + myRaytraceParameters.StackSize = Max (aRequiredStackSize, THE_DEFAULT_STACK_SIZE); aToRebuildShaders = Standard_True; } else { - if (aRequiredStackSize < myTraversalStackSize) + if (aRequiredStackSize < myRaytraceParameters.StackSize) { - if (myTraversalStackSize > THE_DEFAULT_STACK_SIZE) + if (myRaytraceParameters.StackSize > THE_DEFAULT_STACK_SIZE) { - myTraversalStackSize = Max (aRequiredStackSize, THE_DEFAULT_STACK_SIZE); - + myRaytraceParameters.StackSize = Max (aRequiredStackSize, THE_DEFAULT_STACK_SIZE); aToRebuildShaders = Standard_True; } } } + if (theCView.RenderParams.RaytracingDepth != myRaytraceParameters.TraceDepth) + { + myRaytraceParameters.TraceDepth = theCView.RenderParams.RaytracingDepth; + aToRebuildShaders = Standard_True; + } + + if (theCView.RenderParams.IsTransparentShadowEnabled != myRaytraceParameters.TransparentShadows) + { + myRaytraceParameters.TransparentShadows = theCView.RenderParams.IsTransparentShadowEnabled; + aToRebuildShaders = Standard_True; + } + if (aToRebuildShaders) { #ifdef RAY_TRACE_PRINT_INFO - std::cout << "Info: Rebuild shaders with stack size: " << myTraversalStackSize << std::endl; + std::cout << "Info: Rebuild shaders with stack size: " << myRaytraceParameters.StackSize << std::endl; #endif - // Change state to force update all uniforms. + // Change state to force update all uniforms ++myViewModificationStatus; - TCollection_AsciiString aStackSizeStr = - TCollection_AsciiString ("#define STACK_SIZE ") + TCollection_AsciiString (myTraversalStackSize); + TCollection_AsciiString aPrefixString = + TCollection_AsciiString ("#define STACK_SIZE ") + TCollection_AsciiString (myRaytraceParameters.StackSize) + "\n" + + TCollection_AsciiString ("#define TRACE_DEPTH ") + TCollection_AsciiString (myRaytraceParameters.TraceDepth); - myRaytraceShaderSource.SetPrefix (aStackSizeStr); - myPostFSAAShaderSource.SetPrefix (aStackSizeStr); + if (myRaytraceParameters.TransparentShadows) + { + aPrefixString += TCollection_AsciiString ("\n#define TRANSPARENT_SHADOWS"); + } + +#ifdef RAY_TRACE_PRINT_INFO + std::cout << "GLSL prefix string:" << std::endl << aPrefixString << std::endl; +#endif + + myRaytraceShaderSource.SetPrefix (aPrefixString); + myPostFSAAShaderSource.SetPrefix (aPrefixString); if (!myRaytraceShader->LoadSource (myGlContext, myRaytraceShaderSource.Source()) || !myPostFSAAShader->LoadSource (myGlContext, myPostFSAAShaderSource.Source())) @@ -1197,6 +1218,8 @@ Standard_Boolean OpenGl_Workspace::InitRaytraceResources() return Standard_False; } + myRaytraceParameters.TraceDepth = theCView.RenderParams.RaytracingDepth; + TCollection_AsciiString aFolder = Graphic3d_ShaderProgram::ShadersFolder(); if (aFolder.IsEmpty()) @@ -1211,10 +1234,23 @@ Standard_Boolean OpenGl_Workspace::InitRaytraceResources() if (myIsRaytraceDataValid) { - myTraversalStackSize = Max (THE_DEFAULT_STACK_SIZE, + myRaytraceParameters.StackSize = Max (THE_DEFAULT_STACK_SIZE, myRaytraceGeometry.HighLevelTreeDepth() + myRaytraceGeometry.BottomLevelTreeDepth()); } + TCollection_AsciiString aPrefixString = + TCollection_AsciiString ("#define STACK_SIZE ") + TCollection_AsciiString (myRaytraceParameters.StackSize) + "\n" + + TCollection_AsciiString ("#define TRACE_DEPTH ") + TCollection_AsciiString (myRaytraceParameters.TraceDepth); + + if (myRaytraceParameters.TransparentShadows) + { + aPrefixString += TCollection_AsciiString ("\n#define TRANSPARENT_SHADOWS"); + } + +#ifdef RAY_TRACE_PRINT_INFO + std::cout << "GLSL prefix string:" << std::endl << aPrefixString << std::endl; +#endif + { Handle(OpenGl_ShaderObject) aBasicVertShader = LoadShader ( ShaderSource (aFolder + "/RaytraceBase.vs"), GL_VERTEX_SHADER); @@ -1228,10 +1264,7 @@ Standard_Boolean OpenGl_Workspace::InitRaytraceResources() myRaytraceShaderSource.Load (aFiles, 2); - TCollection_AsciiString aStackSizeStr = - TCollection_AsciiString ("#define STACK_SIZE ") + TCollection_AsciiString (myTraversalStackSize); - - myRaytraceShaderSource.SetPrefix (aStackSizeStr); + myRaytraceShaderSource.SetPrefix (aPrefixString); myRaytraceShader = LoadShader (myRaytraceShaderSource, GL_FRAGMENT_SHADER); @@ -1287,10 +1320,7 @@ Standard_Boolean OpenGl_Workspace::InitRaytraceResources() myPostFSAAShaderSource.Load (aFiles, 2); - TCollection_AsciiString aStackSizeStr = - TCollection_AsciiString ("#define STACK_SIZE ") + TCollection_AsciiString (myTraversalStackSize); - - myPostFSAAShaderSource.SetPrefix (aStackSizeStr); + myPostFSAAShaderSource.SetPrefix (aPrefixString); myPostFSAAShader = LoadShader (myPostFSAAShaderSource, GL_FRAGMENT_SHADER); @@ -1487,8 +1517,6 @@ void OpenGl_Workspace::ReleaseRaytraceResources() NullifyResource (myGlContext, mySceneMinPointTexture); NullifyResource (myGlContext, mySceneMaxPointTexture); - NullifyResource (myGlContext, mySceneTransformTexture); - NullifyResource (myGlContext, myObjectNodeInfoTexture); NullifyResource (myGlContext, myObjectMinPointTexture); NullifyResource (myGlContext, myObjectMaxPointTexture); @@ -1496,6 +1524,7 @@ void OpenGl_Workspace::ReleaseRaytraceResources() NullifyResource (myGlContext, myGeometryVertexTexture); NullifyResource (myGlContext, myGeometryNormalTexture); NullifyResource (myGlContext, myGeometryTriangTexture); + NullifyResource (myGlContext, mySceneTransformTexture); NullifyResource (myGlContext, myRaytraceLightSrcTexture); NullifyResource (myGlContext, myRaytraceMaterialTexture); @@ -1588,7 +1617,7 @@ Standard_Boolean OpenGl_Workspace::UploadRaytraceData() } ///////////////////////////////////////////////////////////////////////////// - // Write OpenGL texture buffers + // Write top-level BVH buffers const NCollection_Handle >& aBVH = myRaytraceGeometry.BVH(); @@ -1637,6 +1666,7 @@ Standard_Boolean OpenGl_Workspace::UploadRaytraceData() delete[] aNodeTransforms; ///////////////////////////////////////////////////////////////////////////// + // Write geometry and bottom-level BVH buffers Standard_Size aTotalVerticesNb = 0; Standard_Size aTotalElementsNb = 0; @@ -1806,9 +1836,6 @@ Standard_Boolean OpenGl_Workspace::UploadRaytraceData() aMemUsed += static_cast ( myRaytraceGeometry.BVH()->MaxPointBuffer().size() * sizeof (BVH_Vec4f)); - aMemUsed += static_cast ( - aTransformsNb * sizeof (BVH_Vec4f) * 4); - std::cout << "GPU Memory Used (MB): ~" << aMemUsed / 1048576 << std::endl; #endif @@ -1844,7 +1871,7 @@ void OpenGl_Workspace::UpdateCamera (const NCollection_Mat4& theOrient { NCollection_Mat4 aInvModelProj; - // compute invserse model-view-projection matrix + // compute inverse model-view-projection matrix (theViewMapping * theOrientation).Inverted (aInvModelProj); Standard_Integer aOriginIndex = 0; @@ -1917,7 +1944,7 @@ Standard_Boolean OpenGl_Workspace::RunRaytraceShaders (const Graphic3d_CView& th myRaytraceLightSrcTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceLightSrcTexture); mySceneTransformTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneTransformTexture); - if (theCView.IsAntialiasingEnabled) // render source image to FBO + if (theCView.RenderParams.IsAntialiasingEnabled) // render source image to FBO { myRaytraceFBO1->BindBuffer (myGlContext); @@ -1954,9 +1981,9 @@ Standard_Boolean OpenGl_Workspace::RunRaytraceShaders (const Graphic3d_CView& th myRaytraceProgram->SetUniform (myGlContext, myUniformLocations[0][OpenGl_RT_uLightAmbnt], myRaytraceGeometry.Ambient); myRaytraceProgram->SetUniform (myGlContext, - myUniformLocations[0][OpenGl_RT_uShadEnabled], theCView.IsShadowsEnabled); + myUniformLocations[0][OpenGl_RT_uShadEnabled], theCView.RenderParams.IsShadowEnabled ? 1 : 0); myRaytraceProgram->SetUniform (myGlContext, - myUniformLocations[0][OpenGl_RT_uReflEnabled], theCView.IsReflectionsEnabled); + myUniformLocations[0][OpenGl_RT_uReflEnabled], theCView.RenderParams.IsReflectionEnabled ? 1 : 0); myGlContext->core20fwd->glEnableVertexAttribArray ( myUniformLocations[0][OpenGl_RT_aPosition]); @@ -1969,7 +1996,7 @@ Standard_Boolean OpenGl_Workspace::RunRaytraceShaders (const Graphic3d_CView& th myGlContext->core20fwd->glDisableVertexAttribArray ( myUniformLocations[0][OpenGl_RT_aPosition]); - if (!theCView.IsAntialiasingEnabled) + if (!theCView.RenderParams.IsAntialiasingEnabled) { myRaytraceProgram->Unbind (myGlContext); @@ -2005,9 +2032,9 @@ Standard_Boolean OpenGl_Workspace::RunRaytraceShaders (const Graphic3d_CView& th myPostFSAAProgram->SetUniform (myGlContext, myUniformLocations[1][OpenGl_RT_uLightAmbnt], myRaytraceGeometry.Ambient); myPostFSAAProgram->SetUniform (myGlContext, - myUniformLocations[1][OpenGl_RT_uShadEnabled], theCView.IsShadowsEnabled); + myUniformLocations[1][OpenGl_RT_uShadEnabled], theCView.RenderParams.IsShadowEnabled ? 1 : 0); myPostFSAAProgram->SetUniform (myGlContext, - myUniformLocations[1][OpenGl_RT_uReflEnabled], theCView.IsReflectionsEnabled); + myUniformLocations[1][OpenGl_RT_uReflEnabled], theCView.RenderParams.IsReflectionEnabled ? 1 : 0); const Standard_ShortReal aMaxOffset = 0.559017f; const Standard_ShortReal aMinOffset = 0.186339f; @@ -2087,7 +2114,7 @@ Standard_Boolean OpenGl_Workspace::Raytrace (const Graphic3d_CView& theCView, if (!UpdateRaytraceGeometry (OpenGl_GUM_CHECK)) return Standard_False; - if (!InitRaytraceResources()) + if (!InitRaytraceResources (theCView)) return Standard_False; if (!ResizeRaytraceBuffers (theSizeX, theSizeY)) diff --git a/src/Shaders/RaytraceBase.fs b/src/Shaders/RaytraceBase.fs index 39d2c779a7..38a8d88c51 100644 --- a/src/Shaders/RaytraceBase.fs +++ b/src/Shaders/RaytraceBase.fs @@ -103,34 +103,47 @@ struct SIntersect // ======================================================================= -// function : MatrixRowMultiply +// function : MatrixRowMultiplyDir // purpose : Multiplies a vector by matrix // ======================================================================= -vec3 MatrixRowMultiply (in vec4 v, - in vec4 m0, - in vec4 m1, - in vec4 m2, - in vec4 m3) +vec3 MatrixRowMultiplyDir (in vec3 v, + in vec4 m0, + in vec4 m1, + in vec4 m2) { - return vec3 (dot (m0, v), - dot (m1, v), - dot (m2, v)); + return vec3 (dot (m0.xyz, v), + dot (m1.xyz, v), + dot (m2.xyz, v)); } - // ======================================================================= -// function : MatrixColMultiply +// function : MatrixColMultiplyPnt // purpose : Multiplies a vector by matrix // ======================================================================= -vec3 MatrixColMultiply (in vec4 v, - in vec4 m0, - in vec4 m1, - in vec4 m2, - in vec4 m3) +vec3 MatrixColMultiplyPnt (in vec3 v, + in vec4 m0, + in vec4 m1, + in vec4 m2, + in vec4 m3) { - return vec3 (m0[0] * v.x + m1[0] * v.y + m2[0] * v.z + m3[0] * v.w, - m0[1] * v.x + m1[1] * v.y + m2[1] * v.z + m3[1] * v.w, - m0[2] * v.x + m1[2] * v.y + m2[2] * v.z + m3[2] * v.w); + return vec3 (m0[0] * v.x + m1[0] * v.y + m2[0] * v.z + m3[0], + m0[1] * v.x + m1[1] * v.y + m2[1] * v.z + m3[1], + m0[2] * v.x + m1[2] * v.y + m2[2] * v.z + m3[2]); +} + +// ======================================================================= +// function : MatrixColMultiplyDir +// purpose : Multiplies a vector by matrix +// ======================================================================= +vec3 MatrixColMultiplyDir (in vec3 v, + in vec4 m0, + in vec4 m1, + in vec4 m2, + in vec4 m3) +{ + return vec3 (m0[0] * v.x + m1[0] * v.y + m2[0] * v.z, + m0[1] * v.x + m1[1] * v.y + m2[1] * v.z, + m0[2] * v.x + m1[2] * v.y + m2[2] * v.z); } ///////////////////////////////////////////////////////////////////////////////////////// @@ -218,25 +231,28 @@ int Stack[STACK_SIZE]; ivec4 ObjectNearestHit (in int theBVHOffset, in int theVrtOffset, in int theTrgOffset, in SRay theRay, in vec3 theInverse, inout SIntersect theHit, in int theSentinel) { - int aHead = theSentinel; // stack pointer - int aNode = 0; // node to visit + int aHead = theSentinel; // stack pointer + int aNode = theBVHOffset; // node to visit ivec4 aTriIndex = INALID_HIT; - float aTimeOut; - float aTimeLft; - float aTimeRgh; - while (true) { - ivec3 aData = texelFetch (uObjectNodeInfoTexture, aNode + theBVHOffset).xyz; + ivec3 aData = texelFetch (uObjectNodeInfoTexture, aNode).xyz; if (aData.x == 0) // if inner node { - vec3 aNodeMinLft = texelFetch (uObjectMinPointTexture, aData.y + theBVHOffset).xyz; - vec3 aNodeMaxLft = texelFetch (uObjectMaxPointTexture, aData.y + theBVHOffset).xyz; - vec3 aNodeMinRgh = texelFetch (uObjectMinPointTexture, aData.z + theBVHOffset).xyz; - vec3 aNodeMaxRgh = texelFetch (uObjectMaxPointTexture, aData.z + theBVHOffset).xyz; + float aTimeOut; + float aTimeLft; + float aTimeRgh; + + aData.y += theBVHOffset; + aData.z += theBVHOffset; + + vec3 aNodeMinLft = texelFetch (uObjectMinPointTexture, aData.y).xyz; + vec3 aNodeMaxLft = texelFetch (uObjectMaxPointTexture, aData.y).xyz; + vec3 aNodeMinRgh = texelFetch (uObjectMinPointTexture, aData.z).xyz; + vec3 aNodeMaxRgh = texelFetch (uObjectMaxPointTexture, aData.z).xyz; vec3 aTime0 = (aNodeMinLft - theRay.Origin) * theInverse; vec3 aTime1 = (aNodeMaxLft - theRay.Origin) * theInverse; @@ -290,9 +306,9 @@ ivec4 ObjectNearestHit (in int theBVHOffset, in int theVrtOffset, in int theTrgO { ivec4 aTriangle = texelFetch (uGeometryTriangTexture, anIdx + theTrgOffset); - vec3 aPoint0 = texelFetch (uGeometryVertexTexture, aTriangle.x + theVrtOffset).xyz; - vec3 aPoint1 = texelFetch (uGeometryVertexTexture, aTriangle.y + theVrtOffset).xyz; - vec3 aPoint2 = texelFetch (uGeometryVertexTexture, aTriangle.z + theVrtOffset).xyz; + vec3 aPoint0 = texelFetch (uGeometryVertexTexture, aTriangle.x += theVrtOffset).xyz; + vec3 aPoint1 = texelFetch (uGeometryVertexTexture, aTriangle.y += theVrtOffset).xyz; + vec3 aPoint2 = texelFetch (uGeometryVertexTexture, aTriangle.z += theVrtOffset).xyz; float aTime = IntersectTriangle (theRay, aPoint0, @@ -319,6 +335,14 @@ ivec4 ObjectNearestHit (in int theBVHOffset, in int theVrtOffset, in int theTrgO return aTriIndex; } +#define MATERIAL_AMBN(index) (7 * index + 0) +#define MATERIAL_DIFF(index) (7 * index + 1) +#define MATERIAL_SPEC(index) (7 * index + 2) +#define MATERIAL_EMIS(index) (7 * index + 3) +#define MATERIAL_REFL(index) (7 * index + 4) +#define MATERIAL_REFR(index) (7 * index + 5) +#define MATERIAL_TRAN(index) (7 * index + 6) + // ======================================================================= // function : ObjectAnyHit // purpose : Finds intersection with any object triangle @@ -326,23 +350,30 @@ ivec4 ObjectNearestHit (in int theBVHOffset, in int theVrtOffset, in int theTrgO float ObjectAnyHit (in int theBVHOffset, in int theVrtOffset, in int theTrgOffset, in SRay theRay, in vec3 theInverse, in float theDistance, in int theSentinel) { - int aHead = theSentinel; // stack pointer - int aNode = 0; // node to visit + int aHead = theSentinel; // stack pointer + int aNode = theBVHOffset; // node to visit - float aTimeOut; - float aTimeLft; - float aTimeRgh; +#ifdef TRANSPARENT_SHADOWS + float aFactor = 1.0f; +#endif while (true) { - ivec4 aData = texelFetch (uObjectNodeInfoTexture, aNode + theBVHOffset); + ivec4 aData = texelFetch (uObjectNodeInfoTexture, aNode); if (aData.x == 0) // if inner node { - vec3 aNodeMinLft = texelFetch (uObjectMinPointTexture, aData.y + theBVHOffset).xyz; - vec3 aNodeMaxLft = texelFetch (uObjectMaxPointTexture, aData.y + theBVHOffset).xyz; - vec3 aNodeMinRgh = texelFetch (uObjectMinPointTexture, aData.z + theBVHOffset).xyz; - vec3 aNodeMaxRgh = texelFetch (uObjectMaxPointTexture, aData.z + theBVHOffset).xyz; + float aTimeOut; + float aTimeLft; + float aTimeRgh; + + aData.y += theBVHOffset; + aData.z += theBVHOffset; + + vec3 aNodeMinLft = texelFetch (uObjectMinPointTexture, aData.y).xyz; + vec3 aNodeMaxLft = texelFetch (uObjectMaxPointTexture, aData.y).xyz; + vec3 aNodeMinRgh = texelFetch (uObjectMinPointTexture, aData.z).xyz; + vec3 aNodeMaxRgh = texelFetch (uObjectMaxPointTexture, aData.z).xyz; vec3 aTime0 = (aNodeMinLft - theRay.Origin) * theInverse; vec3 aTime1 = (aNodeMaxLft - theRay.Origin) * theInverse; @@ -380,8 +411,13 @@ float ObjectAnyHit (in int theBVHOffset, in int theVrtOffset, in int theTrgOffse } else { +#ifdef TRANSPARENT_SHADOWS + if (aHead == theSentinel) + return aFactor; +#else if (aHead == theSentinel) return 1.0f; +#endif aNode = Stack[aHead--]; } @@ -406,19 +442,35 @@ float ObjectAnyHit (in int theBVHOffset, in int theVrtOffset, in int theTrgOffse aPoint2, aParams, aNormal); - + +#ifdef TRANSPARENT_SHADOWS + if (aTime < theDistance) + { + aFactor *= 1.0f - texelFetch (uRaytraceMaterialTexture, MATERIAL_TRAN (aTriangle.w)).x; + } +#else if (aTime < theDistance) return 0.0f; +#endif } +#ifdef TRANSPARENT_SHADOWS + if (aHead == theSentinel || aFactor < 0.1f) + return aFactor; +#else if (aHead == theSentinel) return 1.0f; +#endif aNode = Stack[aHead--]; } } +#ifdef TRANSPARENT_SHADOWS + return aFactor; +#else return 1.0f; +#endif } // ======================================================================= @@ -431,10 +483,6 @@ ivec4 SceneNearestHit (in SRay theRay, in vec3 theInverse, inout SIntersect theH int aNode = 0; // node to visit ivec4 aHitObject = INALID_HIT; - - float aTimeOut; - float aTimeLft; - float aTimeRgh; while (true) { @@ -454,34 +502,31 @@ ivec4 SceneNearestHit (in SRay theRay, in vec3 theInverse, inout SIntersect theH { // fetch object transformation int anObjectId = aData.x - 1; + vec4 aInvTransf0 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 0); vec4 aInvTransf1 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 1); vec4 aInvTransf2 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 2); vec4 aInvTransf3 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 3); - SRay aNewRay; + SRay aTrsfRay = SRay ( + MatrixColMultiplyPnt (theRay.Origin, aInvTransf0, aInvTransf1, aInvTransf2, aInvTransf3), + MatrixColMultiplyDir (theRay.Direct, aInvTransf0, aInvTransf1, aInvTransf2, aInvTransf3)); - aNewRay.Origin = MatrixColMultiply (vec4 (theRay.Origin, 1.0f), - aInvTransf0, aInvTransf1, aInvTransf2, aInvTransf3); + vec3 aTrsfInverse = 1.0f / max (abs (aTrsfRay.Direct), SMALL); - aNewRay.Direct = MatrixColMultiply (vec4 (theRay.Direct, 0.0f), - aInvTransf0, aInvTransf1, aInvTransf2, aInvTransf3); - - vec3 aNewInverse = 1.0f / max (abs (aNewRay.Direct), SMALL); - - aNewInverse.x = aNewRay.Direct.x < 0.0f ? -aNewInverse.x : aNewInverse.x; - aNewInverse.y = aNewRay.Direct.y < 0.0f ? -aNewInverse.y : aNewInverse.y; - aNewInverse.z = aNewRay.Direct.z < 0.0f ? -aNewInverse.z : aNewInverse.z; + aTrsfInverse.x = aTrsfRay.Direct.x < 0.f ? -aTrsfInverse.x : aTrsfInverse.x; + aTrsfInverse.y = aTrsfRay.Direct.y < 0.f ? -aTrsfInverse.y : aTrsfInverse.y; + aTrsfInverse.z = aTrsfRay.Direct.z < 0.f ? -aTrsfInverse.z : aTrsfInverse.z; ivec4 aTriIndex = ObjectNearestHit ( - aData.y, aData.z, aData.w, aNewRay, aNewInverse, theHit, aHead); + aData.y, aData.z, aData.w, aTrsfRay, aTrsfInverse, theHit, aHead); if (aTriIndex.x != -1) { - aHitObject = ivec4 (aTriIndex.x + aData.z, // vertex 0 - aTriIndex.y + aData.z, // vertex 1 - aTriIndex.z + aData.z, // vertex 2 - aTriIndex.w); // material + aHitObject = ivec4 (aTriIndex.x, // vertex 0 + aTriIndex.y, // vertex 1 + aTriIndex.z, // vertex 2 + aTriIndex.w); // material theObjectId = anObjectId; } @@ -494,6 +539,10 @@ ivec4 SceneNearestHit (in SRay theRay, in vec3 theInverse, inout SIntersect theH } else // if inner node { + float aTimeOut; + float aTimeLft; + float aTimeRgh; + vec3 aNodeMinLft = texelFetch (uSceneMinPointTexture, aData.y).xyz; vec3 aNodeMaxLft = texelFetch (uSceneMaxPointTexture, aData.y).xyz; vec3 aNodeMinRgh = texelFetch (uSceneMinPointTexture, aData.z).xyz; @@ -555,10 +604,10 @@ float SceneAnyHit (in SRay theRay, in vec3 theInverse, in float theDistance) { int aHead = -1; // stack pointer int aNode = 0; // node to visit - - float aTimeOut; - float aTimeLft; - float aTimeRgh; + +#ifdef TRANSPARENT_SHADOWS + float aFactor = 1.0f; +#endif while (true) { @@ -568,35 +617,44 @@ float SceneAnyHit (in SRay theRay, in vec3 theInverse, in float theDistance) { // fetch object transformation int anObjectId = aData.x - 1; + vec4 aInvTransf0 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 0); vec4 aInvTransf1 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 1); vec4 aInvTransf2 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 2); vec4 aInvTransf3 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 3); - SRay aNewRay; + SRay aTrsfRay = SRay ( + MatrixColMultiplyPnt (theRay.Origin, aInvTransf0, aInvTransf1, aInvTransf2, aInvTransf3), + MatrixColMultiplyDir (theRay.Direct, aInvTransf0, aInvTransf1, aInvTransf2, aInvTransf3)); - aNewRay.Origin = MatrixColMultiply (vec4 (theRay.Origin, 1.0f), - aInvTransf0, aInvTransf1, aInvTransf2, aInvTransf3); + vec3 aTrsfInverse = 1.0f / max (abs (aTrsfRay.Direct), SMALL); - aNewRay.Direct = MatrixColMultiply (vec4 (theRay.Direct, 0.0f), - aInvTransf0, aInvTransf1, aInvTransf2, aInvTransf3); + aTrsfInverse.x = aTrsfRay.Direct.x < 0.0f ? -aTrsfInverse.x : aTrsfInverse.x; + aTrsfInverse.y = aTrsfRay.Direct.y < 0.0f ? -aTrsfInverse.y : aTrsfInverse.y; + aTrsfInverse.z = aTrsfRay.Direct.z < 0.0f ? -aTrsfInverse.z : aTrsfInverse.z; - vec3 aNewInverse = 1.0f / max (abs (aNewRay.Direct), SMALL); - - aNewInverse.x = aNewRay.Direct.x < 0.0f ? -aNewInverse.x : aNewInverse.x; - aNewInverse.y = aNewRay.Direct.y < 0.0f ? -aNewInverse.y : aNewInverse.y; - aNewInverse.z = aNewRay.Direct.z < 0.0f ? -aNewInverse.z : aNewInverse.z; +#ifdef TRANSPARENT_SHADOWS + aFactor *= ObjectAnyHit ( + aData.y, aData.z, aData.w, aTrsfRay, aTrsfInverse, theDistance, aHead); + if (aHead < 0 || aFactor < 0.1f) + return aFactor; +#else bool isShadow = 0.0f == ObjectAnyHit ( - aData.y, aData.z, aData.w, aNewRay, aNewInverse, theDistance, aHead); + aData.y, aData.z, aData.w, aTrsfRay, aTrsfInverse, theDistance, aHead); if (aHead < 0 || isShadow) return isShadow ? 0.0f : 1.0f; +#endif aNode = Stack[aHead--]; } else // if inner node { + float aTimeOut; + float aTimeLft; + float aTimeRgh; + vec3 aNodeMinLft = texelFetch (uSceneMinPointTexture, aData.y).xyz; vec3 aNodeMaxLft = texelFetch (uSceneMaxPointTexture, aData.y).xyz; vec3 aNodeMinRgh = texelFetch (uSceneMinPointTexture, aData.z).xyz; @@ -638,8 +696,13 @@ float SceneAnyHit (in SRay theRay, in vec3 theInverse, in float theDistance) } else { +#ifdef TRANSPARENT_SHADOWS + if (aHead < 0) + return aFactor; +#else if (aHead < 0) return 1.0f; +#endif aNode = Stack[aHead--]; } @@ -647,7 +710,11 @@ float SceneAnyHit (in SRay theRay, in vec3 theInverse, in float theDistance) } } +#ifdef TRANSPARENT_SHADOWS + return aFactor; +#else return 1.0f; +#endif } #define PI 3.1415926f @@ -683,7 +750,7 @@ vec3 SmoothNormal (in vec2 theUV, in ivec4 theTriangle) // ======================================================================= // function : Refract -// purpose : +// purpose : Computes refraction ray (also handles TIR) // ======================================================================= vec3 Refract (in vec3 theInput, in vec3 theNormal, @@ -706,18 +773,10 @@ vec3 Refract (in vec3 theInput, float aNdotT = sqrt (1.0f - aSquare); return normalize (anIndex * theInput - - (anIndex * aNdotI + (aNdotI < 0.0f ? aNdotT : -aNdotT)) * theNormal); + (anIndex * aNdotI + (aNdotI < 0.0f ? aNdotT : -aNdotT)) * theNormal); } -#define THRESHOLD vec3 (0.1f, 0.1f, 0.1f) - -#define MATERIAL_AMBN(index) (7 * index + 0) -#define MATERIAL_DIFF(index) (7 * index + 1) -#define MATERIAL_SPEC(index) (7 * index + 2) -#define MATERIAL_EMIS(index) (7 * index + 3) -#define MATERIAL_REFL(index) (7 * index + 4) -#define MATERIAL_REFR(index) (7 * index + 5) -#define MATERIAL_TRAN(index) (7 * index + 6) +#define THRESHOLD vec3 (0.1f) #define LIGHT_POS(index) (2 * index + 1) #define LIGHT_PWR(index) (2 * index + 0) @@ -733,7 +792,7 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse) int anObjectId; - for (int aDepth = 0; aDepth < 5; ++aDepth) + for (int aDepth = 0; aDepth < TRACE_DEPTH; ++aDepth) { SIntersect aHit = SIntersect (MAXFLOAT, vec2 (ZERO), ZERO); @@ -779,10 +838,9 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse) vec4 aInvTransf0 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 0); vec4 aInvTransf1 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 1); vec4 aInvTransf2 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 2); - vec4 aInvTransf3 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 3); - aNormal = MatrixRowMultiply (vec4 (aNormal, 0.0f), aInvTransf0, aInvTransf1, aInvTransf2, aInvTransf3); - aNormal = normalize (aNormal); + aNormal = normalize (MatrixRowMultiplyDir ( + aNormal, aInvTransf0, aInvTransf1, aInvTransf2)); aHit.Normal = normalize (aHit.Normal); @@ -825,14 +883,14 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse) float aLdotN = dot (aShadow.Direct, aNormal); - if (aOpacity.y > 0.0f) // force two-sided lighting + if (aOpacity.y > 0.0f) // force two-sided lighting aLdotN = abs (aLdotN); // for transparent surfaces if (aLdotN > 0.0f) { float aRdotV = dot (reflect (aShadow.Direct, aNormal), theRay.Direct); - aResult.xyz += aWeight.xyz * aOpacity.x * aIntensity * + aResult.xyz += aWeight.xyz * (aOpacity.x * aVisibility) * aIntensity * (aDiffuse * aLdotN + aSpecular.xyz * pow (max (0.0f, aRdotV), aSpecular.w)); } } @@ -845,15 +903,18 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse) { aWeight *= aOpacity.y; - theRay.Direct = Refract (theRay.Direct, aNormal, aOpacity.z, aOpacity.w); + if (aOpacity.z != 1.0f) + { + theRay.Direct = Refract (theRay.Direct, aNormal, aOpacity.z, aOpacity.w); - theInverse = 1.0f / max (abs (theRay.Direct), SMALL); - - theInverse.x = theRay.Direct.x < 0.0f ? -theInverse.x : theInverse.x; - theInverse.y = theRay.Direct.y < 0.0f ? -theInverse.y : theInverse.y; - theInverse.z = theRay.Direct.z < 0.0f ? -theInverse.z : theInverse.z; - - aPoint += aHit.Normal * (dot (aHit.Normal, theRay.Direct) >= 0.0f ? uSceneEpsilon : -uSceneEpsilon); + theInverse = 1.0f / max (abs (theRay.Direct), SMALL); + + theInverse.x = theRay.Direct.x < 0.0f ? -theInverse.x : theInverse.x; + theInverse.y = theRay.Direct.y < 0.0f ? -theInverse.y : theInverse.y; + theInverse.z = theRay.Direct.z < 0.0f ? -theInverse.z : theInverse.z; + + aPoint += aHit.Normal * (dot (aHit.Normal, theRay.Direct) >= 0.0f ? uSceneEpsilon : -uSceneEpsilon); + } } else { diff --git a/src/V3d/V3d_View.cdl b/src/V3d/V3d_View.cdl index fab492e139..5a24af687a 100644 --- a/src/V3d/V3d_View.cdl +++ b/src/V3d/V3d_View.cdl @@ -135,6 +135,8 @@ uses PrintAlgo from Aspect, ClipPlane_Handle from Graphic3d, SequenceOfHClipPlane from Graphic3d, + RenderingMode from Graphic3d, + RenderingParams from Graphic3d, XYZ from gp raises @@ -1627,37 +1629,15 @@ is -- @param theDXv [in] the translation in "x" direction. -- @param theDYv [in] the translation in "y" direction. - SetRaytracingMode (me : mutable) is static; - ---Level: Public - ---Purpose: enables OpenCL-based ray-tracing mode - - SetRasterizationMode (me : mutable) is static; - ---Level: Public - ---Purpose: enables OpenGL-based rasterization mode - - EnableRaytracedShadows (me : mutable) is static; - ---Level: Public - ---Purpose: enables sharp shadows in OpenCL-based ray-tracing mode - - EnableRaytracedReflections (me : mutable) is static; - ---Level: Public - ---Purpose: enables specular reflections in OpenCL-based ray-tracing mode - - EnableRaytracedAntialiasing (me : mutable) is static; - ---Level: Public - ---Purpose: enables antialiasing in OpenCL-based ray-tracing mode - - DisableRaytracedShadows (me : mutable) is static; - ---Level: Public - ---Purpose: disables sharp shadows in OpenCL-based ray-tracing mode - - DisableRaytracedReflections (me : mutable) is static; - ---Level: Public - ---Purpose: disables specular reflections in OpenCL-based ray-tracing mode - - DisableRaytracedAntialiasing (me : mutable) is static; - ---Level: Public - ---Purpose: disables antialiasing in OpenCL-based ray-tracing mode + RenderingParams (me) returns RenderingParams from Graphic3d is static; + ---C++: return const & + ---Level: Public + ---Purpose: Returns current rendering parameters and effect settings. + + ChangeRenderingParams (me : mutable) returns RenderingParams from Graphic3d is static; + ---C++: return & + ---Level: Public + ---Purpose: Returns reference to current rendering parameters and effect settings. fields diff --git a/src/V3d/V3d_View_5.cxx b/src/V3d/V3d_View_5.cxx index 2454aa71b8..8433b067a2 100644 --- a/src/V3d/V3d_View_5.cxx +++ b/src/V3d/V3d_View_5.cxx @@ -53,60 +53,14 @@ Standard_Boolean V3d_View::IsGLLightEnabled() const return MyView->IsGLLightEnabled(); } -void V3d_View::SetRaytracingMode() +const Graphic3d_RenderingParams& V3d_View::RenderingParams() const { - Graphic3d_CView* cView = (Graphic3d_CView* )MyView->CView(); - - cView->IsRaytracing = 1; + return static_cast (MyView->CView())->RenderParams; } -void V3d_View::SetRasterizationMode() +Graphic3d_RenderingParams& V3d_View::ChangeRenderingParams() { - Graphic3d_CView* cView = (Graphic3d_CView* )MyView->CView(); - - cView->IsRaytracing = 0; -} - -void V3d_View::EnableRaytracedShadows() -{ - Graphic3d_CView* cView = (Graphic3d_CView* )MyView->CView(); - - cView->IsShadowsEnabled = 1; -} - -void V3d_View::EnableRaytracedReflections() -{ - Graphic3d_CView* cView = (Graphic3d_CView* )MyView->CView(); - - cView->IsReflectionsEnabled = 1; -} - -void V3d_View::EnableRaytracedAntialiasing() -{ - Graphic3d_CView* cView = (Graphic3d_CView* )MyView->CView(); - - cView->IsAntialiasingEnabled = 1; -} - -void V3d_View::DisableRaytracedShadows() -{ - Graphic3d_CView* cView = (Graphic3d_CView* )MyView->CView(); - - cView->IsShadowsEnabled = 0; -} - -void V3d_View::DisableRaytracedReflections() -{ - Graphic3d_CView* cView = (Graphic3d_CView* )MyView->CView(); - - cView->IsReflectionsEnabled = 0; -} - -void V3d_View::DisableRaytracedAntialiasing() -{ - Graphic3d_CView* cView = (Graphic3d_CView* )MyView->CView(); - - cView->IsAntialiasingEnabled = 0; + return static_cast (MyView->CView())->RenderParams; } void V3d_View::SetLayerMgr(const Handle(V3d_LayerMgr)& aMgr) diff --git a/src/ViewerTest/ViewerTest_ViewerCommands.cxx b/src/ViewerTest/ViewerTest_ViewerCommands.cxx index 49943e183c..f60b096966 100644 --- a/src/ViewerTest/ViewerTest_ViewerCommands.cxx +++ b/src/ViewerTest/ViewerTest_ViewerCommands.cxx @@ -6395,84 +6395,207 @@ static int VLight (Draw_Interpretor& theDi, return 0; } -//======================================================================= -//function : VRaytrace -//purpose : Enables/disables OpenCL-based ray-tracing -//======================================================================= - -static Standard_Integer VRaytrace (Draw_Interpretor& , - Standard_Integer theArgNb, - const char** theArgVec) +inline Standard_Boolean parseOnOff (Standard_CString theArg, + Standard_Boolean& theIsOn) { - Handle(V3d_View) aView = ViewerTest::CurrentView(); - if (aView.IsNull()) + TCollection_AsciiString aFlag (theArg); + aFlag.LowerCase(); + if (aFlag == "on") { - std::cerr << "Use 'vinit' command before " << theArgVec[0] << "\n"; - return 1; + theIsOn = Standard_True; + return Standard_True; } - - if (theArgNb < 2 - || Draw::Atoi (theArgVec[1])) + else if (aFlag == "off") { - aView->SetRaytracingMode(); + theIsOn = Standard_False; + return Standard_True; } - else - { - aView->SetRasterizationMode(); - } - aView->Redraw(); - return 0; + return Standard_False; } //======================================================================= -//function : VSetRaytraceMode -//purpose : Enables/disables features of OpenCL-based ray-tracing +//function : VRenderParams +//purpose : Enables/disables rendering features //======================================================================= -static Standard_Integer VSetRaytraceMode (Draw_Interpretor&, - Standard_Integer theArgNb, - const char ** theArgVec) +static Standard_Integer VRenderParams (Draw_Interpretor& theDI, + Standard_Integer theArgNb, + const char** theArgVec) { Handle(V3d_View) aView = ViewerTest::CurrentView(); if (aView.IsNull()) { - std::cerr << "Use 'vinit' command before " << theArgVec[0] << "\n"; - return 1; - } - else if (theArgNb < 2) - { - std::cerr << "Usage : " << theArgVec[0] << " [shad=0|1] [refl=0|1] [aa=0|1]\n"; + std::cerr << "Error: no active viewer!\n"; return 1; } + Graphic3d_RenderingParams& aParams = aView->ChangeRenderingParams(); + + if (theArgNb < 2) + { + theDI << "renderMode: "; + switch (aParams.Method) + { + case Graphic3d_RM_RASTERIZATION: theDI << "rasterization "; break; + case Graphic3d_RM_RAYTRACING: theDI << "raytrace "; break; + } + theDI << "\n"; + theDI << "fsaa: " << (aParams.IsAntialiasingEnabled ? "on" : "off") << "\n"; + theDI << "shadows: " << (aParams.IsShadowEnabled ? "on" : "off") << "\n"; + theDI << "reflections: " << (aParams.IsReflectionEnabled ? "on" : "off") << "\n"; + theDI << "rayDepth: " << aParams.RaytracingDepth << "\n"; + theDI << "gleam: " << (aParams.IsTransparentShadowEnabled ? "on" : "off") << "\n"; + return 0; + } + + Standard_Boolean toPrint = Standard_False; for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter) { - const TCollection_AsciiString anArg (theArgVec[anArgIter]); + Standard_CString anArg (theArgVec[anArgIter]); + TCollection_AsciiString aFlag (anArg); + aFlag.LowerCase(); + if (aFlag == "-echo" + || aFlag == "-print") + { + toPrint = Standard_True; + } + else if (aFlag == "-mode" + || aFlag == "-rendermode" + || aFlag == "-render_mode") + { + if (toPrint) + { + switch (aParams.Method) + { + case Graphic3d_RM_RASTERIZATION: theDI << "rasterization "; break; + case Graphic3d_RM_RAYTRACING: theDI << "ray-tracing "; break; + } + continue; + } + else + { + std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n"; + return 1; + } + } + else if (aFlag == "-ray" + || aFlag == "-raytrace") + { + if (toPrint) + { + theDI << (aParams.Method == Graphic3d_RM_RAYTRACING ? "true" : "false") << " "; + continue; + } - if (anArg.Search ("shad=") > -1) - { - if (anArg.Token ("=", 2).IntegerValue() != 0) - aView->EnableRaytracedShadows(); - else - aView->DisableRaytracedShadows(); + aParams.Method = Graphic3d_RM_RAYTRACING; } - else if (anArg.Search ("refl=") > -1) + else if (aFlag == "-rast" + || aFlag == "-raster" + || aFlag == "-rasterization") { - if (anArg.Token ("=", 2).IntegerValue() != 0) - aView->EnableRaytracedReflections(); - else - aView->DisableRaytracedReflections(); + if (toPrint) + { + theDI << (aParams.Method == Graphic3d_RM_RASTERIZATION ? "true" : "false") << " "; + continue; + } + + aParams.Method = Graphic3d_RM_RASTERIZATION; } - else if (anArg.Search ("aa=") > -1) + else if (aFlag == "-raydepth" + || aFlag == "-ray_depth") { - if (anArg.Token ("=", 2).IntegerValue() != 0) - aView->EnableRaytracedAntialiasing(); + if (toPrint) + { + theDI << aParams.RaytracingDepth << " "; + continue; + } + else if (++anArgIter >= theArgNb) + { + std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n"; + return 1; + } + + const Standard_Integer aDepth = Draw::Atoi (theArgVec[anArgIter]); + if (aDepth < 1 || aDepth > 10) + { + std::cerr << "Error: invalid ray-tracing depth " << aDepth << ". Should be within range [1; 10]\n"; + return 1; + } else - aView->DisableRaytracedAntialiasing(); + { + aParams.RaytracingDepth = aDepth; + } + } + else if (aFlag == "-shad" + || aFlag == "-shadows") + { + if (toPrint) + { + theDI << (aParams.IsShadowEnabled ? "on" : "off") << " "; + continue; + } + + Standard_Boolean toEnable = Standard_True; + if (++anArgIter < theArgNb + && !parseOnOff (theArgVec[anArgIter], toEnable)) + { + --anArgIter; + } + aParams.IsShadowEnabled = toEnable; + } + else if (aFlag == "-refl" + || aFlag == "-reflections") + { + if (toPrint) + { + theDI << (aParams.IsReflectionEnabled ? "on" : "off") << " "; + continue; + } + + Standard_Boolean toEnable = Standard_True; + if (++anArgIter < theArgNb + && !parseOnOff (theArgVec[anArgIter], toEnable)) + { + --anArgIter; + } + aParams.IsReflectionEnabled = toEnable; + } + else if (aFlag == "-fsaa") + { + if (toPrint) + { + theDI << (aParams.IsAntialiasingEnabled ? "on" : "off") << " "; + continue; + } + + Standard_Boolean toEnable = Standard_True; + if (++anArgIter < theArgNb + && !parseOnOff (theArgVec[anArgIter], toEnable)) + { + --anArgIter; + } + aParams.IsAntialiasingEnabled = toEnable; + } + else if (aFlag == "-gleam") + { + if (toPrint) + { + theDI << (aParams.IsTransparentShadowEnabled ? "on" : "off") << " "; + continue; + } + + Standard_Boolean toEnable = Standard_True; + if (++anArgIter < theArgNb + && !parseOnOff (theArgVec[anArgIter], toEnable)) + { + --anArgIter; + } + aParams.IsTransparentShadowEnabled = toEnable; } else { - std::cerr << "Unknown argument: " << anArg << "\n"; + std::cout << "Error: wrong syntax, unknown flag '" << anArg << "'\n"; + return 1; } } @@ -6835,10 +6958,14 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands) "\n\n example: vlight add positional head 1 pos 0 1 1 color red" "\n example: vlight change 0 direction 0 -1 0 linearAttenuation 0.2", __FILE__, VLight, group); - theCommands.Add("vraytrace", - "vraytrace 0|1", - __FILE__,VRaytrace,group); - theCommands.Add("vsetraytracemode", - "vsetraytracemode [shad=0|1] [refl=0|1] [aa=0|1]", - __FILE__,VSetRaytraceMode,group); + theCommands.Add("vrenderparams", + "\n Manages rendering parameters: " + "\n '-rayTrace' Enables GPU ray-tracing" + "\n '-raster' Disables GPU ray-tracing" + "\n '-rayDepth 0..10' Defines maximum ray-tracing depth" + "\n '-shadows on|off' Enables/disables shadows rendering" + "\n '-reflections on|off' Enables/disables specular reflections" + "\n '-fsaa on|off' Enables/disables adaptive anti-aliasing" + "\n '-gleam on|off' Enables/disables transparency shadow effects", + __FILE__, VRenderParams, group); } diff --git a/tests/v3d/materials/bug24855 b/tests/v3d/materials/bug24855 index 8b6a7eadf4..6ed0babcfd 100644 --- a/tests/v3d/materials/bug24855 +++ b/tests/v3d/materials/bug24855 @@ -31,13 +31,12 @@ testmat $imagedir $casename vshaderprog s phong testmat $imagedir ${casename}_phong -vraytrace 1 +vrenderparams -raytrace -reflections -fsaa vtextureenv on 5 -vsetraytracemode aa=1 refl=1 testmat $imagedir ${casename}_rt vclear -vraytrace 0 +vrenderparams -rasterization vtextureenv off source $env(CASROOT)/samples/tcl/materials.tcl diff --git a/tests/v3d/raytrace/bug24130 b/tests/v3d/raytrace/bug24130 index 2837eec3b2..f258d7a261 100644 --- a/tests/v3d/raytrace/bug24130 +++ b/tests/v3d/raytrace/bug24130 @@ -18,17 +18,18 @@ restore $aShape2 s2 vdisplay s1 s2 vsetmaterial s1 Silver vsetmaterial s2 Pewter +vsetlocation s1 0.0 0.1 0.0 vlight change 0 pos -1 1 1 vfit # activate ray-tracing -vraytrace 1 +vrenderparams -raytrace set aModeNum 0 -for { set aAAMode 0 } { $aAAMode <= 1 } { incr aAAMode } { - for { set aReflMode 0 } { $aReflMode <= 1 } { incr aReflMode } { - for { set aShadMode 0 } { $aShadMode <= 1 } { incr aShadMode } { - vsetraytracemode shad=$aShadMode refl=$aReflMode aa=$aAAMode +foreach aFSAAMode {off on} { + foreach aReflMode {off on} { + foreach aShadMode {off on} { + vrenderparams -shadows $aShadMode -reflections $aReflMode -fsaa $aFSAAMode vdump $imagedir/${casename}_${aModeNum}.png incr aModeNum } @@ -36,9 +37,18 @@ for { set aAAMode 0 } { $aAAMode <= 1 } { incr aAAMode } { } vtextureenv on 5 -for { set aAAMode 0 } { $aAAMode <= 1 } { incr aAAMode } { - for { set aShadMode 0 } { $aShadMode <= 1 } { incr aShadMode } { - vsetraytracemode shad=$aShadMode refl=1 aa=$aAAMode +foreach aFSAAMode {off on} { + foreach aShadMode {off on} { + vrenderparams -shadows $aShadMode -reflections -fsaa $aFSAAMode + vdump $imagedir/${casename}_${aModeNum}.png + incr aModeNum + } +} + +vsettransparency s2 0.5 +for { set aDepth 2 } { $aDepth <= 5 } { incr aDepth } { + foreach aFSAAMode {off on} { + vrenderparams -raydepth $aDepth -shadows off -fsaa $aFSAAMode vdump $imagedir/${casename}_${aModeNum}.png incr aModeNum } diff --git a/tests/v3d/raytrace/connected b/tests/v3d/raytrace/connected index 3d67b6076b..b53631d530 100644 --- a/tests/v3d/raytrace/connected +++ b/tests/v3d/raytrace/connected @@ -9,8 +9,8 @@ box b2 3 0 0 3 2 1 # draw box vinit View1 vclear +vrenderparams -rasterization vsetdispmode 1 -vraytrace 0 vaxo vconnectsh b1c -3 0 0 1 0 0 0 0 1 b1 b2 vfit @@ -23,7 +23,7 @@ vconnectsh b1c -3 0 0 1 0 0 0 0 1 b1 b2 vdump $::imagedir/${::casename}_OFF.png # turn on ray tracing -vraytrace 1 +vrenderparams -raytrace vdump $::imagedir/${::casename}_rt1.png vclear diff --git a/tests/v3d/raytrace/plastic b/tests/v3d/raytrace/plastic index b46b862c35..e8cb157cae 100644 --- a/tests/v3d/raytrace/plastic +++ b/tests/v3d/raytrace/plastic @@ -8,6 +8,7 @@ box b 1 2 3 # draw box vinit View1 vclear +vrenderparams -rasterization vsetdispmode 1 vaxo vdisplay b @@ -24,7 +25,7 @@ if { "$aColorL" != "GREEN3" || "$aColorR" != "GREEN4" } { puts "Error: wrong color (fixed pipeline)!" } -vraytrace 1 +vrenderparams -raytrace set aColorL [vreadpixel 150 250 rgb name] set aColorR [vreadpixel 250 250 rgb name] #if { "$aColorL" != "GREEN3" || "$aColorR" != "GREEN4" } { diff --git a/tests/v3d/raytrace/refraction b/tests/v3d/raytrace/refraction index 6ded478ed9..c60be190de 100644 --- a/tests/v3d/raytrace/refraction +++ b/tests/v3d/raytrace/refraction @@ -3,6 +3,8 @@ puts "Ray Tracing - check refraction" puts "========" vinit View1 +vclear +vrenderparams -rasterization vsetdispmode 1 vsetgradientbg 180 200 255 180 180 180 2 @@ -52,7 +54,7 @@ vsetmaterial B3 diamond vsetmaterial wall1 stone vsetmaterial wall2 stone -vsetmaterial wall3 stone +vsetmaterial wall3 pewter vsetcolor wall1 red vsetcolor wall2 green @@ -70,5 +72,4 @@ vturnview 0 -0.3 0 vfit vlight change 0 pos 1 1 1 vlight add directional -vraytrace 1 -vsetraytracemode aa=0 shad=0 refl=0 +vrenderparams -raytrace -raydepth 5 -shadows off -reflections -fsaa