| 975 | } |
| 976 | |
| 977 | void VolumetricFog::prepRenderImage(SceneRenderState *state) |
| 978 | { |
| 979 | if (!mShapeLoaded || mFogDensity <= 0.0f || mResizing) |
| 980 | return; |
| 981 | |
| 982 | if (!state->isDiffusePass()) |
| 983 | { |
| 984 | if (!state->isReflectPass()) |
| 985 | return; |
| 986 | } |
| 987 | |
| 988 | PROFILE_SCOPE(VolumetricFog_prepRenderImage); |
| 989 | |
| 990 | ShapeBase* control = dynamic_cast<ShapeBase*>(conn->getControlObject()); |
| 991 | if (!control || (control->getWaterCoverage() >= 0.9f && !mIgnoreWater)) |
| 992 | return; |
| 993 | |
| 994 | camPos = state->getCameraPosition(); |
| 995 | F32 dist = (camPos - getBoxCenter()).len(); |
| 996 | F32 scaleFactor = dist * mInvScale; |
| 997 | if (scaleFactor <= 0.0f) |
| 998 | { |
| 999 | if (mCurDetailLevel != 0) |
| 1000 | UpdateBuffers(0); |
| 1001 | } |
| 1002 | const F32 pixelScale = state->getViewport().extent.y / 300.0f; |
| 1003 | |
| 1004 | mPixelSize = (mRadius / scaleFactor) * state->getWorldToScreenScale().y * pixelScale; |
| 1005 | if (mPixelSize < mMinDisplaySize) |
| 1006 | return; |
| 1007 | if (mNumDetailLevels > 1) |
| 1008 | { |
| 1009 | if ((mCurDetailLevel < mNumDetailLevels - 1) && (det_size[mCurDetailLevel].det_size > mPixelSize)) |
| 1010 | UpdateBuffers(mCurDetailLevel + 1); |
| 1011 | else if (mCurDetailLevel > 0) |
| 1012 | { |
| 1013 | if (mPixelSize >= det_size[mCurDetailLevel - 1].det_size) |
| 1014 | UpdateBuffers(mCurDetailLevel - 1); |
| 1015 | } |
| 1016 | } |
| 1017 | |
| 1018 | if (state->isReflectPass() && mReflect) |
| 1019 | { |
| 1020 | ObjectRenderInst *ri = state->getRenderPass()->allocInst<ObjectRenderInst>(); |
| 1021 | ri->renderDelegate.bind(this, &VolumetricFog::reflect_render); |
| 1022 | ri->type = RenderPassManager::RIT_VolumetricFog; |
| 1023 | ri->translucentSort = true; |
| 1024 | ri->sortDistSq = getRenderWorldBox().getSqDistanceToPoint(camPos); |
| 1025 | if (dist < 1.0f) |
| 1026 | ri->defaultKey = 1; |
| 1027 | else |
| 1028 | ri->defaultKey = U32(dist); |
| 1029 | state->getRenderPass()->addInst(ri); |
| 1030 | return; |
| 1031 | } |
| 1032 | else if (state->isDiffusePass()) |
| 1033 | { |
| 1034 | viewDist = state->getFarPlane(); |
nothing calls this directly
no test coverage detected