Facepunch / garrysmod-requests

Feature requests for Garry's Mod
86 stars 24 forks source link

Raise limit for point_flesh_effect_target entities #1461

Open Gmod4phun opened 5 years ago

Gmod4phun commented 5 years ago

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 through g_FleshProxyTargets.Count()

robotboy655 commented 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.

Gmod4phun commented 5 years ago

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_pMaterialParamFleshEffectCenterRadiusis 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.

Gmod4phun commented 5 years ago

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 );
    }
}
robotboy655 commented 5 years ago

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.

Gmod4phun commented 5 years ago

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.
pivotman319-owo commented 5 years ago

here's a version with raised limits

i hate the occasional hacky spaghetti code of source 2013 at times

Gmod4phun commented 5 years ago

It would be wiser to rewrite the code to be dynamic. Nobody is gonna do that anytime soon tho :P

willox commented 5 years ago

The vertexlitgeneric shaders do not have the parameters that you are referencing in your code ($FleshEffectCenterRadius5 through FleshEffectCenterRadius32.)

I assume it is untested.

Gmod4phun commented 5 years ago

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 :(

pivotman319-owo commented 5 years ago

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.

thegrb93 commented 5 years ago

Cuz all they needed it for was the alyx meat scene.

GrahamBest commented 5 years ago

I don't understand this,

https://github.com/danielmm8888/TF2Classic/blob/master/src/game/client/episodic/flesh_internal_material_proxy.cpp#L138

It's only supposed to support 4?

Can I get some clarification haha? 😄

pivotman319-owo commented 5 years ago

@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.