//---------------------------------------------------------------------------- void Smoke2D::CreateAdjustVelocityEffect (VisualEffect*& effect, VisualEffectInstance*& instance) { PixelShader* pshader = new0 PixelShader("Wm5.AdjustVelocity2", 1, 1, 1, 2, false); pshader->SetInput(0, "vertexTCoord", Shader::VT_FLOAT2, Shader::VS_TEXCOORD0); pshader->SetOutput(0, "pixelColor", Shader::VT_FLOAT4, Shader::VS_COLOR0); pshader->SetConstant(0, "SpaceParam", 1); pshader->SetSampler(0, "StateSampler", Shader::ST_2D); pshader->SetSampler(1, "PoissonSampler", Shader::ST_2D); pshader->SetBaseRegisters(msAdjustVelocityPRegisters); pshader->SetTextureUnits(msAdjustVelocityPTextureUnits); pshader->SetPrograms(msAdjustVelocityPPrograms); mIP->CreateEffect(pshader, effect, instance); ShaderFloat* spaceParamConstant = new0 ShaderFloat(1); float* spaceParam = spaceParamConstant->GetData(); spaceParam[0] = mDx; spaceParam[1] = mDy; spaceParam[2] = mHalfDivDx; spaceParam[3] = mHalfDivDy; instance->SetPixelConstant(0, "SpaceParam", spaceParamConstant); instance->SetPixelTexture(0, "StateSampler", mIP->GetTarget(1)->GetColorTexture(0)); instance->SetPixelTexture(0, "PoissonSampler", mIP->GetTarget(0)->GetColorTexture(0)); }
//---------------------------------------------------------------------------- void ShaderParameters::UpdateConstants (const Renderable* renderable, const Camera* camera) { ShaderFloatPtr* constants = mConstants; for (int i = 0; i < mNumConstants; ++i, ++constants) { ShaderFloat* constant = *constants; if (constant->AllowUpdater()) { constant->Update(renderable, camera); } } }
//---------------------------------------------------------------------------- void GpuGaussianBlur2::SetBlurInput () { VisualEffectInstance* instance = mIP->GetMainEffectInstance(); float dCol = mIP->GetColSpacing(); float dRow = mIP->GetRowSpacing(); ShaderFloat* deltaConstant = new0 ShaderFloat(1); float* delta = deltaConstant->GetData(); delta[0] = dCol; delta[1] = dRow; instance->SetPixelConstant(0, "Delta", deltaConstant); ShaderFloat* weightConstant = new0 ShaderFloat(1); float* weight = weightConstant->GetData(); weight[0] = 0.01f; // = kappa*DeltaT/DeltaX^2 weight[1] = 0.01f; // = kappa*DeltaT/DeltaY^2 weight[2] = 1.0f - 2.0f*weight[0] - 2.0f*weight[1]; // must be positive instance->SetPixelConstant(0, "Weight", weightConstant); }
//---------------------------------------------------------------------------- PlanarShadowEffect::PlanarShadowEffect (int numPlanes, Node* shadowCaster) : mNumPlanes(numPlanes), mShadowCaster(shadowCaster) { mPlanes = new1<TriMeshPtr>(mNumPlanes); mProjectors = new1<LightPtr>(mNumPlanes); mShadowColors = new1<Float4>(mNumPlanes); mAlphaState = new0 AlphaState(); mDepthState = new0 DepthState(); mStencilState = new0 StencilState(); mMaterial = new0 Material(); mMaterialEffect = new0 MaterialEffect(); mMaterialEffectInstance = mMaterialEffect->CreateInstance(mMaterial); // The material diffuse color changes per plane on every draw call. ShaderFloat* sfloat = mMaterialEffectInstance->GetVertexConstant(0, "MaterialDiffuse"); sfloat->EnableUpdater(); }
//---------------------------------------------------------------------------- void Smoke2D::CreatePoissonSolverEffect (VisualEffect*& effect, VisualEffectInstance*& instance) { PixelShader* pshader = new0 PixelShader("Wm5.PoissonSolver2", 1, 1, 2, 2, false); pshader->SetInput(0, "vertexTCoord", Shader::VT_FLOAT2, Shader::VS_TEXCOORD0); pshader->SetOutput(0, "pixelColor", Shader::VT_FLOAT4, Shader::VS_COLOR0); pshader->SetConstant(0, "SpaceParam", 1); pshader->SetConstant(1, "EpsilonParam", 1); pshader->SetSampler(0, "DivergenceSampler", Shader::ST_2D); pshader->SetSampler(1, "PoissonSampler", Shader::ST_2D); pshader->SetBaseRegisters(msPoissonSolverPRegisters); pshader->SetTextureUnits(msPoissonSolverPTextureUnits); pshader->SetPrograms(msPoissonSolverPPrograms); mIP->CreateEffect(pshader, effect, instance); ShaderFloat* spaceParamConstant = new0 ShaderFloat(1); float* spaceParam = spaceParamConstant->GetData(); spaceParam[0] = mDx; spaceParam[1] = mDy; instance->SetPixelConstant(0, "SpaceParam", spaceParamConstant); ShaderFloat* epsilonParamConstant = new0 ShaderFloat(1); float* epsilonParam = epsilonParamConstant->GetData(); epsilonParam[0] = mEpsilonX; epsilonParam[1] = mEpsilonY; epsilonParam[2] = mEpsilon0; instance->SetPixelConstant(0, "EpsilonParam", epsilonParamConstant); instance->SetPixelTexture(0, "DivergenceSampler", mIP->GetTarget(2)->GetColorTexture(0)); instance->SetPixelTexture(0, "PoissonSampler", mIP->GetTarget(0)->GetColorTexture(0)); }
//---------------------------------------------------------------------------- void Smoke2D::CreateFluidUpdateEffect (VisualEffect*& effect, VisualEffectInstance*& instance) { PixelShader* pshader = new0 PixelShader("Wm5.FluidUpdate2", 1, 1, 3, 3, false); pshader->SetInput(0, "vertexTCoord", Shader::VT_FLOAT2, Shader::VS_TEXCOORD0); pshader->SetOutput(0, "pixelColor", Shader::VT_FLOAT4, Shader::VS_COLOR0); pshader->SetConstant(0, "SpaceParam", 1); pshader->SetConstant(1, "TimeParam", 1); pshader->SetConstant(2, "ViscParam", 1); pshader->SetSampler(0, "StateSampler", Shader::ST_2D); pshader->SetSampler(1, "AdvectionSampler", Shader::ST_2D); pshader->SetSampler(2, "SourceSampler", Shader::ST_2D); pshader->SetFilter(1, Shader::SF_LINEAR); pshader->SetBaseRegisters(msFluidUpdatePRegisters); pshader->SetTextureUnits(msFluidUpdatePTextureUnits); pshader->SetPrograms(msFluidUpdatePPrograms); mIP->CreateEffect(pshader, effect, instance); ShaderFloat* spaceParamConstant = new0 ShaderFloat(1); float* spaceParam = spaceParamConstant->GetData(); spaceParam[0] = mDx; spaceParam[1] = mDy; spaceParam[2] = 1.0f/(float)mIMax; spaceParam[3] = 1.0f/(float)mJMax; instance->SetPixelConstant(0, "SpaceParam", spaceParamConstant); ShaderFloat* timeParamConstant = new0 ShaderFloat(1); float* timeParam = timeParamConstant->GetData(); timeParam[0] = mDtDivDx; timeParam[1] = mDtDivDy; timeParam[2] = mDt; instance->SetPixelConstant(0, "TimeParam", timeParamConstant); ShaderFloat* viscParamConstant = new0 ShaderFloat(1); float* viscParam = viscParamConstant->GetData(); viscParam[0] = mDenLambdaX; viscParam[1] = mDenLambdaY; viscParam[2] = mVelLambdaX; viscParam[3] = mVelLambdaY; instance->SetPixelConstant(0, "ViscParam", viscParamConstant); mSourceTexture = new0 Texture2D(Texture::TF_A32B32G32R32F, mIMaxP1, mJMaxP1, 1); ComputeSource(); instance->SetPixelTexture(0, "StateSampler", mIP->GetTarget(1)->GetColorTexture(0)); instance->SetPixelTexture(0, "AdvectionSampler", mIP->GetTarget(4)->GetColorTexture(0)); instance->SetPixelTexture(0, "SourceSampler", mSourceTexture); mRenderer->Bind(mSourceTexture); }
//---------------------------------------------------------------------------- void MaterialInstance::_CopyParams(ShaderParameters *from, ShaderParameters *to) { int fromNumConstans = from->GetNumConstants(); for (int i = 0; i < fromNumConstans; i++) { ShaderFloat *fromFloat = from->GetConstant(i); if (fromFloat) { const std::string &fromConstName = from->GetConstantName(i); ShaderFloat *toFloat = to->GetConstant(fromConstName); if (toFloat) { int fromNumRegisters = fromFloat->GetNumRegisters(); if (fromNumRegisters == toFloat->GetNumRegisters()) { for (int r = 0; r < fromNumRegisters; r++) { toFloat->SetRegister(r, fromFloat->GetRegister(r)); } } else { assertion(false, "numRegist doest not be the same.\n"); } } } } int fromNumSamples = from->GetNumTextures(); for (int i = 0; i < fromNumSamples; i++) { const std::string &fromSampleName = from->GetSampleName(i); Texture *texture = from->GetTexture(i); if (texture) { to->_SetTexture(fromSampleName, texture); } } }
//---------------------------------------------------------------------------- void GpuGaussianBlur3::SetBlurInput () { VisualEffectInstance* instance = mIP->GetMainEffectInstance(); int bound0M1 = mIP->GetBound0() - 1; int bound1M1 = mIP->GetBound1() - 1; int bound2M1 = mIP->GetBound2() - 1; float dCol = mIP->GetColSpacing(); float dRow = mIP->GetRowSpacing(); ShaderFloat* deltaConstant = new0 ShaderFloat(1); float* delta = deltaConstant->GetData(); delta[0] = dCol; delta[1] = 0.0f; delta[2] = 0.0f; delta[3] = dRow; instance->SetPixelConstant(0, "Delta", deltaConstant); ShaderFloat* weightConstant = new0 ShaderFloat(1); float* weight = weightConstant->GetData(); weight[0] = 0.01f; // = kappa*DeltaT/DeltaX^2 weight[1] = 0.01f; // = kappa*DeltaT/DeltaY^2 weight[2] = 0.01f; // = kappa*DeltaT/DeltaZ^2 weight[3] = 1.0f - 2.0f*(weight[0] + weight[1] + weight[2]); // w[3] > 0 instance->SetPixelConstant(0, "Weight", weightConstant); Texture2D* offsetTexture = new Texture2D(Texture::TF_A32B32G32R32F, 1024, 1024, 1); Float4* offset = (Float4*)offsetTexture->GetData(0); memset(offset, 0, 1024*1024*sizeof(Float4)); // Interior voxels. The offsets at the boundary are all zero, so the // finite differences are incorrect at those locations. However, the // boundary effect will overwrite those voxels, so it is irrelevant // about the finite difference approximations at those locations. for (int z = 1; z < bound2M1; ++z) { for (int y = 1; y < bound1M1; ++y) { for (int x = 1; x < bound0M1; ++x) { // Get the 2D location of the voxel. int u, v; mIP->Map3Dto2D(x, y, z, u, v); // Get the 2D location of the z+ neighbor. int upos, vpos; mIP->Map3Dto2D(x, y, z+1, upos, vpos); // Get the 2D location of the z- neighbor. int uneg, vneg; mIP->Map3Dto2D(x, y, z-1, uneg, vneg); Float4& color = offset[mIP->Index(u, v)]; color[0] = (upos - u)*dCol; color[1] = (vpos - v)*dRow; color[2] = (uneg - u)*dCol; color[3] = (vneg - v)*dRow; } } } instance->SetPixelTexture(0, "OffsetSampler", offsetTexture); }
//---------------------------------------------------------------------------- void ShadowMaps::CreateShaders () { // Create the shader constants. Some of these are shared. // Create the light projector. Projector* projector = new0 Projector(Camera::PM_DEPTH_ZERO_TO_ONE); projector->SetFrustum(60.0f, 1.0f, 0.1f, 100.0f); APoint projPosition(4.0f, 4.0f, 4.0f); AVector projDVector(-1.0f, -1.0f, -1.0f); projDVector.Normalize(); AVector projUVector(-1.0f, -1.0f, 2.0f); projUVector.Normalize(); AVector projRVector = projDVector.Cross(projUVector); projector->SetFrame(projPosition, projDVector, projUVector, projRVector); // For SMSceneEffect and SMUnlitEffect. ProjectorMatrixConstant* lightPVMatrix = new0 ProjectorMatrixConstant(projector, false, 0); ShaderFloat* lightBSMatrixUnlit = new0 ShaderFloat(4); ShaderFloat* lightBSMatrixScene = new0 ShaderFloat(4); ShaderFloat* screenBSMatrix = new0 ShaderFloat(4); const float* src; if (VertexShader::GetProfile() == VertexShader::VP_ARBVP1) { src = (const float*)Projector::BiasScaleMatrix[1]; memcpy(lightBSMatrixUnlit->GetData(), src, 16*sizeof(float)); memcpy(lightBSMatrixScene->GetData(), src, 16*sizeof(float)); memcpy(screenBSMatrix->GetData(), src, 16*sizeof(float)); } else { src = (const float*)Projector::BiasScaleMatrix[0]; memcpy(lightBSMatrixUnlit->GetData(), src, 16*sizeof(float)); memcpy(screenBSMatrix->GetData(), src, 16*sizeof(float)); src = (const float*)Projector::BiasScaleMatrix[1]; memcpy(lightBSMatrixScene->GetData(), src, 16*sizeof(float)); } // For SMSceneEffect. ProjectorWorldPositionConstant* lightWorldPosition = new0 ProjectorWorldPositionConstant(projector); ShaderFloat* lightColor = new0 ShaderFloat(1); (*lightColor)[0] = 1.0f; (*lightColor)[1] = 1.0f; (*lightColor)[2] = 1.0f; (*lightColor)[3] = 1.0f; // For SMUnlitEffect. ShaderFloat* depthBiasConstant = new0 ShaderFloat(1); (*depthBiasConstant)[0] = 0.1f; ShaderFloat* texelSizeConstant = new0 ShaderFloat(1); (*texelSizeConstant)[0] = 1.0f/(float)mScreenTargetSize; (*texelSizeConstant)[1] = 1.0f/(float)mScreenTargetSize; // For SMBlurEffect. const int numRegisters = 11; ShaderFloat* weights = new0 ShaderFloat(numRegisters); ShaderFloat* hOffsets = new0 ShaderFloat(numRegisters); ShaderFloat* vOffsets = new0 ShaderFloat(numRegisters); // Compute the weights. They must sum to 1. Float4* weightsData = (Float4*)weights->GetData(); const float stdDev = 1.0f; const float invTwoVariance = 1.0f/(2.0f*stdDev*stdDev); float totalWeight = 0.0f; int i, j; for (i = 0, j = -numRegisters/2; i < numRegisters; ++i, ++j) { float weight = Mathf::Exp(-j*j*invTwoVariance); weightsData[i] = Float4(weight, weight, weight, 0.0f); totalWeight += weight; } float invTotalWeight = 1.0f/totalWeight; for (i = 0; i < numRegisters; ++i) { weightsData[i][0] *= invTotalWeight; weightsData[i][1] *= invTotalWeight; weightsData[i][2] *= invTotalWeight; } // Compute the horizontal and vertical offsets. Float4* hOffsetsData = (Float4*)hOffsets->GetData(); Float4* vOffsetsData = (Float4*)vOffsets->GetData(); float uDelta = 1.0f/(float)GetWidth(); float vDelta = 1.0f/(float)GetHeight(); for (i = 0, j = -numRegisters/2; i < numRegisters; ++i, ++j) { hOffsetsData[i] = Float4(j*uDelta, 0.0f, 0.0f, 0.0f); vOffsetsData[i] = Float4(0.0f, j*vDelta, 0.0f, 0.0f); } // Create the scene effect. std::string effectFile = Environment::GetPathR("SMScene.wmfx"); SMSceneEffect* sceneEffect = new0 SMSceneEffect(effectFile); std::string stoneName = Environment::GetPathR("Stone.wmtf"); Texture2D* stoneTexture = Texture2D::LoadWMTF(stoneName); std::string ballName = Environment::GetPathR("BallTexture.wmtf"); Texture2D* ballTexture = Texture2D::LoadWMTF(ballName); std::string projectedName = Environment::GetPathR("Magician.wmtf"); Texture2D* projectedTexture = Texture2D::LoadWMTF(projectedName); mPlaneSceneInstance = sceneEffect->CreateInstance(lightWorldPosition, lightPVMatrix, lightBSMatrixScene, screenBSMatrix, lightColor, stoneTexture, mVBlurTarget->GetColorTexture(0), projectedTexture); mSphereSceneInstance = sceneEffect->CreateInstance(lightWorldPosition, lightPVMatrix, lightBSMatrixScene, screenBSMatrix, lightColor, ballTexture, mVBlurTarget->GetColorTexture(0), projectedTexture); // Create the shadow effect. effectFile = Environment::GetPathR("SMShadow.wmfx"); mShadowEffect = new0 SMShadowEffect(effectFile, lightPVMatrix); // Create the unlit effect. effectFile = Environment::GetPathR("SMUnlit.wmfx"); mUnlitEffect = new0 SMUnlitEffect(effectFile, lightPVMatrix, lightBSMatrixUnlit, depthBiasConstant, texelSizeConstant, mShadowTarget->GetColorTexture(0)); // Create the blur effect and instantiate for horizontal and vertical // blurring. effectFile = Environment::GetPathR("SMBlur.wmfx"); SMBlurEffect* blurEffect = new0 SMBlurEffect(effectFile); mHBlurInstance = blurEffect->CreateInstance(weights, hOffsets, mUnlitTarget->GetColorTexture(0)); mVBlurInstance = blurEffect->CreateInstance(weights, vOffsets, mHBlurTarget->GetColorTexture(0)); }