Unidad: vale la pena calcular el búfer de profundidad incorporado (no tenga en cuenta el valor de profundidad de _CameraDephtTexutre, CameraDepthNormalTexture)


Propósito

Memorándum


Valor de escritura profunda incorporado

Debido a que escribí algunos experimentos antes, descubrí que el valor SV_Depth y el valor codificado en _CameraDepthTexture, CameraDepthNormalTexture y después de la decodificación, aún no pueden coincidir con la relación de profundidad

Así que sospecho que la forma en que vale la pena calcular el búfer de profundidad no es la forma en que es en absoluto

Encontré esta pregunta de stackoverflow después de: ¿Cómo se escribe la profundidad z en un sombreador?

El valor original en el búfer de profundidad se calcula así:


struct fragmentOutput {
    
    
	float4 color : SV_Target;
	float zvalue : SV_Depth;
};

fragmentOutput frag(inputType ...) 
{
    
    
	fragmentOutput o = ....;
	...
	//convert position to clip space, read depth
	float4 clip_pos = mul(UNITY_MATRIX_VP, float4(ray_pos, 1.0));
	o.zvalue = clip_pos.z / clip_pos.w;
	...
	return o;
}

Arriba float zvalue : SV_Depthestá el valor de profundidad de escritura al que debemos prestar atención

También lo encontré a través del enlace del respondedor: El método de cálculo de compute_ depth :

float compute_depth(float4 clippos)
{
    
    
#if defined(SHADER_TARGET_GLSL) || defined(SHADER_API_GLES) || defined(SHADER_API_GLES3)
    return ((clippos.z / clippos.w) + 1.0) * 0.5;
#else
    return clippos.z / clippos.w;
#endif
}

Luego eché un vistazo a este repositorio de github y escribí: Con respecto a la visualización mixta de raymarch y mesh (geometría) en unidad, entonces debes usar escritura profunda, leer y juzgar la prueba de profundidad.

El siguiente es el lugar de la aplicación: El lugar de la aplicación de compute_ depth - la clave es el cálculo de la profundidad escrito en el GBuffero.depth = compute_depth(mul(UNITY_MATRIX_VP, float4(ray_pos, 1.0)));

struct gbuffer_out
{
    
    
    half4 diffuse           : SV_Target0; // RT0: diffuse color (rgb), occlusion (a)
    half4 spec_smoothness   : SV_Target1; // RT1: spec color (rgb), smoothness (a)
    half4 normal            : SV_Target2; // RT2: normal (rgb), --unused, very low precision-- (a) 
    half4 emission          : SV_Target3; // RT3: emission (rgb), --unused-- (a)
    float depth             : SV_Depth;
};


gbuffer_out frag_gbuffer(vs_out v)
{
    
    
#if UNITY_UV_STARTS_AT_TOP
    v.spos.y *= -1.0;
#endif
    float time = _Time.y;
    float2 pos = v.spos.xy;
    pos.x *= _ScreenParams.x / _ScreenParams.y;

    float num_steps = 1.0;
    float last_distance = 0.0;
    float total_distance = _ProjectionParams.y;
    float3 ray_pos;
    float3 normal;
    if(g_enable_adaptive) {
    
    
        float3 cam_pos      = get_camera_position();
        float3 cam_forward  = get_camera_forward();
        float3 cam_up       = get_camera_up();
        float3 cam_right    = get_camera_right();
        float  cam_focal_len= get_camera_focal_length();
        float3 ray_dir = normalize(cam_right*pos.x + cam_up*pos.y + cam_forward*cam_focal_len);

        total_distance = tex2D(g_depth, v.spos.xy*0.5+0.5).x;
        ray_pos = cam_pos + ray_dir * total_distance;
        normal = guess_normal(ray_pos);
        //normal = float3(0.0, 0.0, 1.0);
    }
    else {
    
    
        raymarching(pos, MAX_MARCH_SINGLE_GBUFFER_PASS, total_distance, num_steps, last_distance, ray_pos);
        normal = guess_normal(ray_pos);
    }

    float glow = 0.0;
    if(g_enable_glowline) {
    
    
        glow += max((modc(length(ray_pos)-time*1.5, 10.0)-9.0)*2.5, 0.0);
        float2 p = pattern(ray_pos.xz*0.5);
        if(p.x<1.3) {
    
     glow = 0.0; }
    }
    glow += max(1.0-abs(dot(-get_camera_forward(), normal)) - 0.4, 0.0) * 1.0;
    
    float c = total_distance*0.01;
    float4 color = float4( c + float3(0.02, 0.02, 0.025)*num_steps*0.4, 1.0 );
    color.xyz += float3(0.5, 0.5, 0.75)*glow;

    float3 emission = float3(0.7, 0.7, 1.0)*glow*0.6;

    gbuffer_out o;
    o.diffuse = float4(0.75, 0.75, 0.80, 1.0);
    o.spec_smoothness = float4(0.2, 0.2, 0.2, 0.5);
    o.normal = float4(normal*0.5+0.5, 1.0);
    o.emission = g_hdr ? float4(emission, 1.0) : exp2(float4(-emission, 1.0));
    o.depth = compute_depth(mul(UNITY_MATRIX_VP, float4(ray_pos, 1.0))); // 应用的地方在这里
    return o;
}

Después de que descubrí que el método de escritura en github es factible,
utilicé la búsqueda regular de sublime para buscar:compute.*depth

UnityCG.cgincHay una sección de este tipo de COMPUTE_XXXDEPTH en , y luego eché un vistazo más de cerca a los comentarios: ayudantes de textura de procesamiento de profundidad

OK, es textura de renderizado de profundidad

// Depth render texture helpers
#define DECODE_EYEDEPTH(i) LinearEyeDepth(i)
#define COMPUTE_EYEDEPTH(o) o = -UnityObjectToViewPos( v.vertex ).z
#define COMPUTE_DEPTH_01 -(UnityObjectToViewPos( v.vertex ).z * _ProjectionParams.w)
#define COMPUTE_VIEW_NORMAL normalize(mul((float3x3)UNITY_MATRIX_IT_MV, v.normal))

Esta escritura se usa para escribir _CameraDepthTexture, _CameraDepthNormalTexture

Pero si desea utilizar el valor SV_Depth para compararlo con el valor de DepthRenderTexture, entonces será mejor que comprenda cómo se calculan sus valores antes de realizar la comparación. Si se calculan de diferentes maneras, entonces debe haber un problema con la comparación directa.

Entonces necesitamos convertir algunos valores en consecuencia antes de compararlos:


Resumir

Supongo que te gusta

Origin blog.csdn.net/linjf520/article/details/122103809
Recomendado
Clasificación