/// <summary> /// Update automatic parameters. /// </summary> /// <param name="source">The source of the parameters</param> /// <param name="mask">A mask of GpuParamVariability which identifies which autos will need updating</param> public void UpdateAutoParams( AutoParamDataSource source, GpuParamVariability mask ) { // abort early if no autos if (!HasAutoConstantType) return; if ((mask & _combinedVariability) == 0) return; PassIterationNumberIndex = int.MaxValue; Matrix3 m3; Vector4 vec4; Vector3 vec3; // loop through and update all constants based on their type foreach ( var entry in autoConstants ) { // Only update needed slots if ( ( entry.Variability & mask ) == 0 ) continue; switch ( entry.Type ) { case AutoConstantType.ViewMatrix: WriteRawConstant( entry.PhysicalIndex, source.ViewMatrix, entry.ElementCount ); break; case AutoConstantType.InverseViewMatrix: WriteRawConstant( entry.PhysicalIndex, source.InverseViewMatrix, entry.ElementCount ); break; /* case AutoConstantType.TransposeViewMatrix: WriteRawConstant( entry.PhysicalIndex, source.TransposeViewMatrix, entry.ElementCount ); break; */ case AutoConstantType.InverseTransposeViewMatrix: WriteRawConstant( entry.PhysicalIndex, source.InverseTransposeViewMatrix, entry.ElementCount ); break; case AutoConstantType.ProjectionMatrix: WriteRawConstant( entry.PhysicalIndex, source.ProjectionMatrix, entry.ElementCount ); break; /* case AutoConstantType.InverseProjectionMatrix: WriteRawConstant(entry.PhysicalIndex, source.InverseProjectionMatrix, entry.ElementCount); break; case AutoConstantType.TransposeProjectionMatrix: WriteRawConstant(entry.PhysicalIndex, source.TransposeProjectionMatrix, entry.ElementCount); break; case AutoConstantType.InverseTransposeProjectionMatrix: WriteRawConstant(entry.PhysicalIndex, source.InverseTransposeProjectionMatrix, entry.ElementCount); break; */ case AutoConstantType.ViewProjMatrix: WriteRawConstant( entry.PhysicalIndex, source.ViewProjectionMatrix, entry.ElementCount ); break; /* case AutoConstantType.InverseViewProjMatrix: WriteRawConstant(entry.PhysicalIndex, source.InverseViewProjectionMatrix, entry.ElementCount); break; case AutoConstantType.TransposeViewProjMatrix: WriteRawConstant(entry.PhysicalIndex, source.TransposeViewProjectionMatrix, entry.ElementCount); break; case AutoConstantType.InverseTransposeViewProjMatrix: WriteRawConstant(entry.PhysicalIndex, source.InverseTransposeViewProjectionMatrix, entry.ElementCount); break; */ case AutoConstantType.RenderTargetFlipping: WriteRawConstant( entry.PhysicalIndex, source.RenderTarget.RequiresTextureFlipping ? -1.0f : 1.0f ); break; case AutoConstantType.VertexWinding: { var rsys = Root.Instance.RenderSystem; WriteRawConstant( entry.PhysicalIndex, rsys.InvertVertexWinding ? -1.0f : 1.0f ); break; } case AutoConstantType.AmbientLightColor: WriteRawConstant( entry.PhysicalIndex, source.AmbientLight, entry.ElementCount ); break; /* case AutoConstantType.DerivedSceneColor: WriteRawConstant(entry.PhysicalIndex, source.DerivedSceneColor, entry.ElementCount); break; case AutoConstantType.FogColor: WriteRawConstant(entry.PhysicalIndex, source.FogColor); break; */ case AutoConstantType.FogParams: WriteRawConstant( entry.PhysicalIndex, source.FogParams, entry.ElementCount ); break; /* case AutoConstantType.SurfaceAmbientColor: WriteRawConstant( entry.PhysicalIndex, source.SurfaceAmbientColor, entry.ElementCount ); break; case AutoConstantType.SurfaceDiffuseColor: WriteRawConstant( entry.PhysicalIndex, source.SurfaceDiffuseColor, entry.ElementCount ); break; case AutoConstantType.SurfaceSpecularColor: WriteRawConstant( entry.PhysicalIndex, source.SurfaceSpecularColor, entry.ElementCount ); break; case AutoConstantType.SurfaceEmissiveColor: WriteRawConstant( entry.PhysicalIndex, source.SurfaceEmissiveColor, entry.ElementCount ); break; case AutoConstantType.SurfaceShininess: WriteRawConstant( entry.PhysicalIndex, source.SurfaceShininess ); break; */ case AutoConstantType.CameraPosition: WriteRawConstant( entry.PhysicalIndex, source.CameraPosition, entry.ElementCount ); break; case AutoConstantType.Time: WriteRawConstant( entry.PhysicalIndex, source.Time*entry.FData ); break; case AutoConstantType.Time_0_X: WriteRawConstant( entry.PhysicalIndex, source.Time%entry.FData ); break; /* case AutoConstantType.CosTime_0_X: WriteRawConstant(entry.PhysicalIndex, source->getCosTime_0_X(i->fData)); break; */ case AutoConstantType.SinTime_0_X: WriteRawConstant( entry.PhysicalIndex, Utility.Sin( source.Time%entry.FData ) ); break; /* case AutoConstantType.TanTime_0_X: WriteRawConstant(entry.PhysicalIndex, source->getTanTime_0_X(i->fData)); break; case AutoConstantType.Time_0_X_Packed: WriteRawConstant(entry.PhysicalIndex, source->getTime_0_X_packed(i->fData), entry.ElementCount); break; */ case AutoConstantType.Time_0_1: WriteRawConstant( entry.PhysicalIndex, ( source.Time%1 ) ); break; /* case AutoConstantType.CosTime_0_1: WriteRawConstant(entry.PhysicalIndex, source->getCosTime_0_1(i->fData)); break; case AutoConstantType.SinTime_0_1: WriteRawConstant(entry.PhysicalIndex, source->getSinTime_0_1(i->fData)); break; case AutoConstantType.TanTime_0_1: WriteRawConstant(entry.PhysicalIndex, source->getTanTime_0_1(i->fData)); break; case AutoConstantType.Time_0_1_Packed: WriteRawConstant(entry.PhysicalIndex, source->getTime_0_1_packed(i->fData), entry.ElementCount); */ /* case AutoConstantType.Time_0_2PI: WriteRawConstant(entry.PhysicalIndex, source->getTime_0_2Pi(i->fData)); break; case AutoConstantType.CosTime_0_2PI: WriteRawConstant(entry.PhysicalIndex, source->getCosTime_0_2Pi(i->fData)); break; case AutoConstantType.SinTime_0_2PI: WriteRawConstant(entry.PhysicalIndex, source->getSinTime_0_2Pi(i->fData)); break; case AutoConstantType.TanTime_0_2PI: WriteRawConstant(entry.PhysicalIndex, source->getTanTime_0_2Pi(i->fData)); break; case AutoConstantType.Time_0_2PI_Packed: WriteRawConstant(entry.PhysicalIndex, source->getTime_0_2Pi_packed(i->fData), entry.ElementCount); break; */ /* case AutoConstantType.FrameTime: WriteRawConstant(entry.PhysicalIndex, source.FrameTime * entry.FData); break; case AutoConstantType.FPS: WriteRawConstant(entry.PhysicalIndex, source.FPS); break; case AutoConstantType.ViewportWidth: WriteRawConstant(entry.PhysicalIndex, source.ViewportWidth); break; case AutoConstantType.ViewportHeight: WriteRawConstant(entry.PhysicalIndex, source.ViewportHeight); break; case AutoConstantType.InverseViewportWidth: WriteRawConstant(entry.PhysicalIndex, source.InverseViewportWidth); break; case AutoConstantType.InverseViewportHeight: WriteRawConstant(entry.PhysicalIndex, source.InverseViewportHeight); break; case AutoConstantType.ViewportSize: WriteRawConstants( entry.PhysicalIndex, new float[] { source.ViewportWidth, source.ViewportHeight, source.InverseViewportWidth, source.InverseViewportHeight }, entry.ElementCount ); break; case AutoConstantType.TexelOffsets: { var rsys = Root.Instance.RenderSystem; WriteRawConstants( entry.PhysicalIndex, new float[] { rsys.HorizontalTexelOffset, rsys.VerticalTexelOffset, rsys.HorizontalTexelOffset * source.InverseViewportWidth, rsys.VerticalTexelOffset * source.InverseViewportHeight }, entry.ElementCount ); } break; case AutoConstantType.TextureSize: WriteRawConstant(entry.PhysicalIndex, source.GetTextureSize(entry.Data), entry.ElementCount); break; case AutoConstantType.InverseTextureSize: WriteRawConstant(entry.PhysicalIndex, source.GetInverseTextureSize(entry.Data), entry.ElementCount); break; case AutoConstantType.PackedTextureSize: WriteRawConstant(entry.PhysicalIndex, source.GetPackedTextureSize(entry.Data), entry.ElementCount); break; case AutoConstantType.SceneDepthRange: WriteRawConstant(entry.PhysicalIndex, source.SceneDepthRange, entry.ElementCount); break; */ case AutoConstantType.ViewDirection: WriteRawConstant( entry.PhysicalIndex, source.ViewDirection ); break; case AutoConstantType.ViewSideVector: WriteRawConstant( entry.PhysicalIndex, source.ViewSideVector ); break; case AutoConstantType.ViewUpVector: WriteRawConstant( entry.PhysicalIndex, source.ViewUpVector ); break; /* case AutoConstantType.FOV: WriteRawConstant(entry.PhysicalIndex, source.FOV); break; */ case AutoConstantType.NearClipDistance: WriteRawConstant( entry.PhysicalIndex, source.NearClipDistance ); break; case AutoConstantType.FarClipDistance: WriteRawConstant( entry.PhysicalIndex, source.FarClipDistance ); break; case AutoConstantType.PassNumber: WriteRawConstant( entry.PhysicalIndex, (float)source.PassNumber ); break; case AutoConstantType.PassIterationNumber: // this is actually just an initial set-up, it's bound separately, so still global WriteRawConstant( entry.PhysicalIndex, 0.0f ); _activePassIterationIndex = entry.PhysicalIndex; break; /* case AutoConstantType.TextureMatrix: WriteRawConstant(entry.PhysicalIndex, source.GetTextureTransformMatrix(entry.Data), entry.ElementCount); break; case AutoConstantType.LODCameraPosition: WriteRawConstant(entry.PhysicalIndex, source.LodCameraPosition, entry.ElementCount); break; case AutoConstantType.TextureWorldViewProjMatrix: // can also be updated in lights WriteRawConstant(entry.PhysicalIndex, source.GetTextureWorldViewProjMatrix(entry.Data), entry.ElementCount); break; case AutoConstantType.TextureWorldViewProjMatrixArray: for (var l = 0; l < entry.Data; ++l) { // can also be updated in lights WriteRawConstant(entry.PhysicalIndex + l * entry.ElementCount, source.GetTextureWorldViewProjMatrix(l), entry.ElementCount); } break; case AutoConstantType.SpotLightViewProjMatrix: WriteRawConstant(entry.PhysicalIndex, source.GetSpotlightWorldViewProjMatrix(entry.Data), entry.ElementCount); break; */ case AutoConstantType.LightPositionObjectSpace: vec4 = source.GetLightAs4DVector(entry.Data); vec3 = new Vector3(vec4.x, vec4.y, vec4.z); if( vec4.w > 0.0f ) { // point light vec3 = source.InverseWorldMatrix.TransformAffine(vec3); } else { // directional light // We need the inverse of the inverse transpose source.InverseTransposeWorldMatrix.Inverse().Extract3x3Matrix(out m3); vec3 = (m3 * vec3); vec3.Normalize(); } WriteRawConstant(entry.PhysicalIndex, new Vector4(vec3.x, vec3.y, vec3.z, vec4.w), entry.ElementCount); break; /* case AutoConstantType.LightDirectionObjectSpace: // We need the inverse of the inverse transpose source.InverseTransposeWorldMatrix.Inverse().Extract3x3Matrix(out m3); vec3 = m3 * source.GetLightDirection(entry.Data); vec3.Normalize(); // Set as 4D vector for compatibility WriteRawConstant(entry.PhysicalIndex, new Vector4(vec3.x, vec3.y, vec3.z, 0.0f), entry.ElementCount); break; case AutoConstantType.LightDistanceObjectSpace: vec3 = source.InverseWorldMatrix.TransformAffine(source.GetLightPosition(entry.Data)); WriteRawConstant(entry.PhysicalIndex, vec3.Length); break; */ case AutoConstantType.LightPositionObjectSpaceArray: // We need the inverse of the inverse transpose source.InverseTransposeWorldMatrix.Inverse().Extract3x3Matrix(out m3); for (var l = 0; l < entry.Data; ++l) { vec4 = source.GetLightAs4DVector(l); vec3 = new Vector3(vec4.x, vec4.y, vec4.z); if( vec4.w > 0.0f ) { // point light vec3 = source.InverseWorldMatrix.TransformAffine(vec3); } else { // directional light vec3 = (m3 * vec3); vec3.Normalize(); } WriteRawConstant(entry.PhysicalIndex + l*entry.ElementCount, new Vector4(vec3.x, vec3.y, vec3.z, vec4.w), entry.ElementCount); } break; /* case AutoConstantType.LightDirectionObjectSpaceArray: // We need the inverse of the inverse transpose source.InverseTransposeWorldMatrix.Inverse().Extract3x3Matrix(out m3); for (var l = 0; l < entry.Data; ++l) { vec3 = m3 * source.GetLightDirection(l); vec3.Normalize(); WriteRawConstant(entry.PhysicalIndex + l*entry.ElementCount, new Vector4(vec3.x, vec3.y, vec3.z, 0.0f), entry.ElementCount); } break; case AutoConstantType.LightDistanceObjectSpaceArray: for (var l = 0; l < entry.Data; ++l) { vec3 = source.InverseWorldMatrix.TransformAffine(source.GetLightPosition(l)); WriteRawConstant(entry.PhysicalIndex + l*entry.ElementCount, vec3.Length); } break;*/ case AutoConstantType.WorldMatrix: WriteRawConstant( entry.PhysicalIndex, source.WorldMatrix, entry.ElementCount ); break; case AutoConstantType.InverseWorldMatrix: WriteRawConstant( entry.PhysicalIndex, source.InverseWorldMatrix, entry.ElementCount ); break; /* case AutoConstantType.TransposeWorldMatrix: WriteRawConstant( entry.PhysicalIndex, source.TransposeWorldMatrix, entry.ElementCount ); break; case AutoConstantType.InverseTransposeWorldMatrix: WriteRawConstant( entry.PhysicalIndex, source.InverseTransposeWorldMatrix, entry.ElementCount ); break; case AutoConstantType.WorldMatrixArray3x4: // Loop over matrices pMatrix = source->getWorldMatrixArray(); numMatrices = source->getWorldMatrixCount(); index = entry.PhysicalIndex; for ( m = 0; m < numMatrices; ++m ) { WriteRawConstants( index, ( *pMatrix )[ 0 ], 12 ); index += 12; ++pMatrix; } break; */ case AutoConstantType.WorldMatrixArray: WriteRawConstant( entry.PhysicalIndex, source.WorldMatrixArray, source.WorldMatrixCount ); break; case AutoConstantType.WorldViewMatrix: WriteRawConstant( entry.PhysicalIndex, source.WorldViewMatrix, entry.ElementCount ); break; case AutoConstantType.InverseWorldViewMatrix: WriteRawConstant( entry.PhysicalIndex, source.InverseWorldViewMatrix, entry.ElementCount ); break; /* case AutoConstantType.TransposeWorldViewMatrix: WriteRawConstant( entry.PhysicalIndex, source.TransposeWorldViewMatrix, entry.ElementCount ); break; */ case AutoConstantType.InverseTransposeWorldViewMatrix: WriteRawConstant( entry.PhysicalIndex, source.InverseTransposeWorldViewMatrix, entry.ElementCount ); break; case AutoConstantType.WorldViewProjMatrix: WriteRawConstant( entry.PhysicalIndex, source.WorldViewProjMatrix, entry.ElementCount ); break; /* case AutoConstantType.InverseWorldViewProjMatrix: WriteRawConstant( entry.PhysicalIndex, source.InverseWorldViewProjMatrix, entry.ElementCount ); break; case AutoConstantType.TransposeWorldViewProjMatrix: WriteRawConstant( entry.PhysicalIndex, source.TransposeWorldViewProjMatrix, entry.ElementCount ); break; case AutoConstantType.InverseTransposeWorldViewProjMatrix: WriteRawConstant( entry.PhysicalIndex, source.InverseTransposeWorldViewProjMatrix, entry.ElementCount ); break; */ case AutoConstantType.CameraPositionObjectSpace: WriteRawConstant( entry.PhysicalIndex, source.CameraPositionObjectSpace, entry.ElementCount ); break; /* case AutoConstantType.LODCameraPositionObjectSpace: WriteRawConstant( entry.PhysicalIndex, source.LodCameraPositionObjectSpace, entry.ElementCount ); break; */ case AutoConstantType.Custom: case AutoConstantType.AnimationParametric: source.CurrentRenderable.UpdateCustomGpuParameter( entry, this ); break; /* case AutoConstantType.LightCustom: source.UpdateLightCustomGpuParameter( entry, this ); break; case AutoConstantType.LightCount: WriteRawConstant( entry.PhysicalIndex, source.LightCount ); break; */ case AutoConstantType.LightDiffuseColor: WriteRawConstant( entry.PhysicalIndex, source.GetLightDiffuseColor( entry.Data ), entry.ElementCount ); break; case AutoConstantType.LightSpecularColor: WriteRawConstant( entry.PhysicalIndex, source.GetLightSpecularColor( entry.Data ), entry.ElementCount ); break; case AutoConstantType.LightPosition: // Get as 4D vector, works for directional lights too // Use element count in case uniform slot is smaller WriteRawConstant( entry.PhysicalIndex, source.GetLightAs4DVector( entry.Data ), entry.ElementCount ); break; /* case AutoConstantType.LightDirection: vec3 = source.GetLightDirection( entry.Data ); // Set as 4D vector for compatibility // Use element count in case uniform slot is smaller WriteRawConstant( entry.PhysicalIndex, new Vector4( vec3.x, vec3.y, vec3.z, 1.0f ), entry.ElementCount ); break;*/ case AutoConstantType.LightPositionViewSpace: WriteRawConstant( entry.PhysicalIndex, source.ViewMatrix.TransformAffine( source.GetLightAs4DVector( entry.Data ) ), entry.ElementCount ); break; /* case AutoConstantType.LightDirectionViewSpace: source.InverseTransposeViewMatrix.Extract3x3Matrix( m3 ); // inverse transpose in case of scaling vec3 = m3*source->getLightDirection( entry.Data ); vec3.normalise(); // Set as 4D vector for compatibility WriteRawConstant( entry.PhysicalIndex, Vector4( vec3.x, vec3.y, vec3.z, 0.0f ), entry.ElementCount ); break; case AutoConstantType.ShadowExtrusionDistance: // extrusion is in object-space, so we have to rescale by the inverse // of the world scaling to deal with scaled objects source.WorldMatrix.Extract3x3Matrix( m3 ); WriteRawConstant( entry.PhysicalIndex, source.ShadowExtrusionDistance/ Math.Sqrt( Utility.Max( Utility.Max(m3.GetColumn(0).squaredLength(), m3.GetColumn( 1 ).squaredLength() ), m3.GetColumn( 2 ).squaredLength() ) ) ); break; case AutoConstantType.ShadowSceneDepthRange: WriteRawConstant( entry.PhysicalIndex, source.GetShadowSceneDepthRange( entry.Data ) ); break; case AutoConstantType.ShadowColor: WriteRawConstant( entry.PhysicalIndex, source.ShadowColor(), entry.ElementCount ); break; */ case AutoConstantType.LightPowerScale: WriteRawConstant( entry.PhysicalIndex, source.GetLightPowerScale( entry.Data ) ); break; /* case AutoConstantType.LightDiffuseColorPowerScaled: WriteRawConstant( entry.PhysicalIndex, source.GetLightDiffuseColorWithPower( entry.Data ), entry.ElementCount ); break; case AutoConstantType.LightSpecularColorPowerScaled: WriteRawConstant( entry.PhysicalIndex, source.GetLightSpecularColorWithPower( entry.Data ), entry.ElementCount ); break; case AutoConstantType.LightNumber: WriteRawConstant( entry.PhysicalIndex, source.GetLightNumber( entry.Data ) ); break; case AutoConstantType.LightCastsShadows: WriteRawConstant( entry.PhysicalIndex, source.GetLightCastsShadows( entry.Data ) ); break; case AutoConstantType.LightAttenuation: WriteRawConstant( entry.PhysicalIndex, source.GetLightAttenuation( entry.Data ), entry.ElementCount ); break; case AutoConstantType.SpotLightParams: WriteRawConstant( entry.PhysicalIndex, source.GetSpotlightParams( entry.Data ), entry.ElementCount ); break; case AutoConstantType.LightDiffuseColorArray: for ( var l = 0; l < entry.Data; ++l ) WriteRawConstant( entry.PhysicalIndex + l*entry.ElementCount, source.GetLightDiffuseColor( l ), entry.ElementCount ); break; case AutoConstantType.LightSpecularColorArray: for ( var l = 0; l < entry.Data; ++l ) WriteRawConstant( entry.PhysicalIndex + l*entry.ElementCount, source.GetLightSpecularColor( l ), entry.ElementCount ); break; case AutoConstantType.LightDiffuseColorPowerScaledArray: for ( var l = 0; l < entry.Data; ++l ) WriteRawConstant( entry.PhysicalIndex + l*entry.ElementCount, source.GetLightDiffuseColorWithPower( l ), entry.ElementCount ); break; case AutoConstantType.LightSpecularColorPowerScaledArray: for ( var l = 0; l < entry.Data; ++l ) WriteRawConstant( entry.PhysicalIndex + l*entry.ElementCount, source.GetLightSpecularColorWithPower( l ), entry.ElementCount ); break; case AutoConstantType.LightPositionArray: // Get as 4D vector, works for directional lights too for ( var l = 0; l < entry.Data; ++l ) WriteRawConstant( entry.PhysicalIndex + l*entry.ElementCount, source.GetLightAs4DVector( l ), entry.ElementCount ); break; case AutoConstantType.LightDirectionArray: for ( var l = 0; l < entry.Data; ++l ) { vec3 = source.GetLightDirection( l ); // Set as 4D vector for compatibility WriteRawConstant( entry.PhysicalIndex + l*entry.ElementCount, Vector4( vec3.x, vec3.y, vec3.z, 0.0f ), entry.ElementCount ); } break; case AutoConstantType.LightPositionViewSpaceArray: for ( var l = 0; l < entry.Data; ++l ) WriteRawConstant( entry.PhysicalIndex + l*entry.ElementCount, source.ViewMatrix.TransformAffine( source.GetLightAs4DVector( l ) ), entry.ElementCount ); break; case AutoConstantType.LightDirectionViewSpaceArray: source.InverseTransposeViewMatrix().Extract3x3Matrix( m3 ); for ( var l = 0; l < entry.Data; ++l ) { vec3 = m3*source.GetLightDirection( l ); vec3.Normalize(); // Set as 4D vector for compatibility WriteRawConstant( entry.PhysicalIndex + l*entry.ElementCount, Vector4( vec3.x, vec3.y, vec3.z, 0.0f ), entry.ElementCount ); } break;*/ case AutoConstantType.LightPowerScaleArray: for ( var l = 0; l < entry.Data; ++l ) WriteRawConstant( entry.PhysicalIndex + l*entry.ElementCount, source.GetLightPowerScale( l ) ); break; /* case AutoConstantType.LightAttenuationArray: for ( var l = 0; l < entry.Data; ++l ) { WriteRawConstant( entry.PhysicalIndex + l*entry.ElementCount, source.GetLightAttenuation( l ), entry.ElementCount ); } break; case AutoConstantType.SpotLightParamsArray: for ( var l = 0; l < entry.Data; ++l ) { WriteRawConstant( entry.PhysicalIndex + l*entry.ElementCount, source.GetSpotlightParams( l ), entry.ElementCount ); } break; case AutoConstantType.DerivedLightDiffuseColor: WriteRawConstant( entry.PhysicalIndex, source.GetLightDiffuseColorWithPower( entry.Data )* sourceSurfaceDiffuseColor, entry.ElementCount ); break; case AutoConstantType.DerivedLightSpecularColor: WriteRawConstant( entry.PhysicalIndex, source.GetLightSpecularColorWithPower( entry.Data )* source.SurfaceSpecularColor, entry.ElementCount ); break; case AutoConstantType.DerivedLightDiffuseColorArray: for ( var l = 0; l < entry.Data; ++l ) { WriteRawConstant( entry.PhysicalIndex + l*entry.ElementCount, source.GetLightDiffuseColorWithPower( l )* source.SurfaceDiffuseColor, entry.ElementCount ); } break; case AutoConstantType.DerivedLightSpecularColorArray: for ( var l = 0; l < entry.Data; ++l ) { WriteRawConstant( entry.PhysicalIndex + l*entry.ElementCount, source.GetLightSpecularColorWithPower( l )* source.SurfaceSpecularColor, entry.ElementCount ); } break; case AutoConstantType.TextureViewProjMatrix: // can also be updated in lights WriteRawConstant( entry.PhysicalIndex, source.GetTextureViewProjMatrix( entry.Data ), entry.ElementCount ); break; case AutoConstantType.TextureViewProjMatrixArray: for ( var l = 0; l < entry.Data; ++l ) { // can also be updated in lights WriteRawConstant( entry.PhysicalIndex + l*entry.ElementCount, source.GetTextureViewProjMatrix( l ), entry.ElementCount ); } break; case AutoConstantType.SpotLightViewProjMatrix: WriteRawConstant( entry.PhysicalIndex, source.GetSpotlightViewProjMatrix( entry.Data ), entry.ElementCount ); break; case AutoConstantType.SpotLightViewProjMatrixArray: for ( var l = 0; l < entry.Data; ++l ) { // can also be updated in lights WriteRawConstant( entry.PhysicalIndex + l*entry.ElementCount, source.GetSpotlightViewProjMatrix( l ), entry.ElementCount ); } break;*/ default: throw new NotImplementedException(); } } }