Open Gmod4phun opened 5 years ago
The shader only supports 4 points, so the shader would need to be changed, which ain't happening anytime soon, and it cannot be infinite, so I am not sure there's a point in bothering looking into this further.
Maybe I could change it to be 4 per entity, rather than 4 points in total, but it would affect performance, and you should be able to just recreate the entire entity and the matproxy in Lua anyway. All it takes is just setting the 6 shader params through the proxy, you can even name it something custom to not interfere with the default one.
Changing what you are suggesting will simply result in crashing when you have 5 or more points.
It is kinda misleading, some more code would need to be changed, but not much. The issue is not just the loop part, the thing is that the whole naming of m_pMaterialParamFleshEffectCenterRadius
is wrong, because the first 3 values are the origin pos of the effect and not the radius, and only the 4th value is the radius. They pretty much fucked the logic on this and used the same iterator variable for the targets, which is dumb (would not be surprised if this was a last moment change, as it always is with Valve). When I get the time I can try to correct the code so it properl yloops through all the entities.
Unless I screwed something up, this should work
void CFleshInteriorMaterialProxy::OnBind( C_BaseEntity *pEnt )
{
IMaterialVar *pParams[] =
{
m_pMaterialParamFleshEffectCenterRadius1,
m_pMaterialParamFleshEffectCenterRadius2,
m_pMaterialParamFleshEffectCenterRadius3,
m_pMaterialParamFleshEffectCenterRadius4
};
float vEffectCenterRadius[4];
for ( int i = 0; i < g_FleshProxyTargets.Count(); i++ ) // we want to loop through all the targets
{
// Clear the target
vEffectCenterRadius[0] = vEffectCenterRadius[1] = vEffectCenterRadius[2] = vEffectCenterRadius[3] = 0.0f;
// Setup the target
if ( g_FleshProxyTargets[i]->IsAbsQueriesValid() )
{
Vector vecAbsOrigin = g_FleshProxyTargets[i]->GetAbsOrigin();
vEffectCenterRadius[0] = vecAbsOrigin.x;
vEffectCenterRadius[1] = vecAbsOrigin.y;
vEffectCenterRadius[2] = vecAbsOrigin.z;
vEffectCenterRadius[3] = g_FleshProxyTargets[i]->GetRadius();
}
for ( int j = 0; j < ARRAYSIZE( pParams ); j++ ) // set the params now
{
// Set the value either way
pParams[j] = vEffectCenterRadius[j];
}
}
// Subsurface texture. NOTE: This texture bleeds through the color of the flesh texture so expect
// to have to set this brighter than white to really see the subsurface texture glow through.
if ( m_pMaterialParamFleshSubsurfaceTint != NULL )
{
float vSubsurfaceTintColor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
// !!! Test code. REPLACE ME!
// vSubsurfaceTintColor[0] = vSubsurfaceTintColor[1] = vSubsurfaceTintColor[2] = sinf( gpGlobals->curtime * 3.0f ) + 1.0f; // * 0.5f + 0.5f;
m_pMaterialParamFleshSubsurfaceTint->SetVecValue( vSubsurfaceTintColor, 4 );
}
}
The code you provided will set all 4 points of every mat proxy to the last g_FleshProxyTargets on the list, you realize this right? It also won't compile because you are trying to assign a float value to a 4D vector.
The only way to make this work as I see is to find 4 closest points to pEnt
's origin in g_FleshProxyTargets and then use those 4 points, but it will be a lot slower. I also do not know how it will affect the Ep2 scene.
You are right, my bad. After examining the code further, I now understand, I got confused by what is also written on the wiki. What a retarded way to do this though.
The wiki, last part: https://developer.valvesoftware.com/wiki/$flesh
$flesheffectcenterradius<1/2/3/4> "[<x float> <y float> <z float> <radius float>]"
This is how the position of [point_flesh_effect_target]s is communicated to the shader. The flesh effect target functionality is applied at the specified world location using the specified radius. The FleshInterior proxy sets these to the first 4 effect targets it finds, or [0 0 0 0] if not present/active.
here's a version with raised limits
i hate the occasional hacky spaghetti code of source 2013 at times
It would be wiser to rewrite the code to be dynamic. Nobody is gonna do that anytime soon tho :P
The vertexlitgeneric shaders do not have the parameters that you are referencing in your code ($FleshEffectCenterRadius5
through FleshEffectCenterRadius32
.)
I assume it is untested.
Yeah there is alot more code that would be required to change in order to raise the limits. Why didnt Valve make it dynamic in the first place :(
That would be the case, unfortunately.
I'm going to assume the Flesh material proxy was rushed before the ep2 orangebox engine release; especially since there's just enough $FleshEffectCenterRadiusX
values and repeated code in order to cover the entire ep2/models/alyx_interior.mdl file.
Cuz all they needed it for was the alyx meat scene.
I don't understand this,
It's only supposed to support 4?
Can I get some clarification haha? 😄
@Verideth Currently, the flesh proxy only supports a max limit of four points.
It's possible to raise the limit in both the vertexlitgeneric shaders and the flesh proxy cpp.
Currently, only 4 of those are affecting entities at a time because the code was not thought through properly (good job, Valve)
Source
I believe it only loops through the first 4 flesh effect targets because
ARRAYSIZE( pParams )
is 4, instead it should loop throughg_FleshProxyTargets.Count()