1 /*========================================================================= 2 3 Program: Visualization Toolkit 4 Module: vtkEncodedGradientShader.h 5 6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 7 All rights reserved. 8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details. 9 10 This software is distributed WITHOUT ANY WARRANTY; without even 11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 12 PURPOSE. See the above copyright notice for more information. 13 14 =========================================================================*/ 15 16 /** 17 * @class vtkEncodedGradientShader 18 * @brief Compute shading tables for encoded normals. 19 * 20 * 21 * vtkEncodedGradientShader computes shading tables for encoded normals 22 * that indicates the amount of diffuse and specular illumination that is 23 * received from all light sources at a surface location with that normal. 24 * For diffuse illumination this is accurate, but for specular illumination 25 * it is approximate for perspective projections since the center view 26 * direction is always used as the view direction. Since the shading table is 27 * dependent on the volume (for the transformation that must be applied to 28 * the normals to put them into world coordinates) there is a shading table 29 * per volume. This is necessary because multiple volumes can share a 30 * volume mapper. 31 */ 32 33 #ifndef vtkEncodedGradientShader_h 34 #define vtkEncodedGradientShader_h 35 36 #include "vtkObject.h" 37 #include "vtkRenderingVolumeModule.h" // For export macro 38 39 class vtkVolume; 40 class vtkRenderer; 41 class vtkEncodedGradientEstimator; 42 43 #define VTK_MAX_SHADING_TABLES 100 44 45 class VTKRENDERINGVOLUME_EXPORT vtkEncodedGradientShader : public vtkObject 46 { 47 public: 48 static vtkEncodedGradientShader* New(); 49 vtkTypeMacro(vtkEncodedGradientShader, vtkObject); 50 51 /** 52 * Print the vtkEncodedGradientShader 53 */ 54 void PrintSelf(ostream& os, vtkIndent indent) override; 55 56 ///@{ 57 /** 58 * Set / Get the intensity diffuse / specular light used for the 59 * zero normals. 60 */ 61 vtkSetClampMacro(ZeroNormalDiffuseIntensity, float, 0.0f, 1.0f); 62 vtkGetMacro(ZeroNormalDiffuseIntensity, float); 63 vtkSetClampMacro(ZeroNormalSpecularIntensity, float, 0.0f, 1.0f); 64 vtkGetMacro(ZeroNormalSpecularIntensity, float); 65 ///@} 66 67 /** 68 * Cause the shading table to be updated 69 */ 70 void UpdateShadingTable(vtkRenderer* ren, vtkVolume* vol, vtkEncodedGradientEstimator* gradest); 71 72 ///@{ 73 /** 74 * Get the red/green/blue shading table. 75 */ 76 float* GetRedDiffuseShadingTable(vtkVolume* vol); 77 float* GetGreenDiffuseShadingTable(vtkVolume* vol); 78 float* GetBlueDiffuseShadingTable(vtkVolume* vol); 79 float* GetRedSpecularShadingTable(vtkVolume* vol); 80 float* GetGreenSpecularShadingTable(vtkVolume* vol); 81 float* GetBlueSpecularShadingTable(vtkVolume* vol); 82 ///@} 83 84 ///@{ 85 /** 86 * Set the active component for shading. This component's 87 * ambient / diffuse / specular / specular power values will 88 * be used to create the shading table. The default is 1.0 89 */ 90 vtkSetClampMacro(ActiveComponent, int, 0, 3); 91 vtkGetMacro(ActiveComponent, int); 92 ///@} 93 94 protected: 95 vtkEncodedGradientShader(); 96 ~vtkEncodedGradientShader() override; 97 98 /** 99 * Build a shading table for a light with the specified direction, 100 * and color for an object of the specified material properties. 101 * material[0] = ambient, material[1] = diffuse, material[2] = specular 102 * and material[3] = specular exponent. If the ambient flag is 1, 103 * then ambient illumination is added. If not, then this means we 104 * are calculating the "other side" of two sided lighting, so no 105 * ambient intensity is added in. If the update flag is 0, 106 * the shading table is overwritten with these new shading values. 107 * If the updateFlag is 1, then the computed light contribution is 108 * added to the current shading table values. There is one shading 109 * table per volume, and the index value indicated which index table 110 * should be used. It is computed in the UpdateShadingTable method. 111 */ 112 void BuildShadingTable(int index, double lightDirection[3], double lightAmbientColor[3], 113 double lightDiffuseColor[3], double lightSpecularColor[3], double lightIntensity, 114 double viewDirection[3], double material[4], int twoSided, vtkEncodedGradientEstimator* gradest, 115 int updateFlag); 116 117 // The six shading tables (r diffuse ,g diffuse ,b diffuse, 118 // r specular, g specular, b specular ) - with an entry for each 119 // encoded normal plus one entry at the end for the zero normal 120 // There is one shading table per volume listed in the ShadingTableVolume 121 // array. A null entry indicates an available slot. 122 float* ShadingTable[VTK_MAX_SHADING_TABLES][6]; 123 vtkVolume* ShadingTableVolume[VTK_MAX_SHADING_TABLES]; 124 int ShadingTableSize[VTK_MAX_SHADING_TABLES]; 125 126 int ActiveComponent; 127 128 // The intensity of light used for the zero normals, since it 129 // can not be computed from the normal angles. Defaults to 0.0. 130 float ZeroNormalDiffuseIntensity; 131 float ZeroNormalSpecularIntensity; 132 133 private: 134 vtkEncodedGradientShader(const vtkEncodedGradientShader&) = delete; 135 void operator=(const vtkEncodedGradientShader&) = delete; 136 }; 137 138 #endif 139