gpt4 book ai didi

unity3d - 在 Unity 的新后处理堆栈的着色器中获取世界位置?

转载 作者:行者123 更新时间:2023-12-04 14:38:45 25 4
gpt4 key购买 nike

Unity 新的 PostProcessing 着色器框架中的一个如何获得相关像素的绝对 xyz 世界位置?非常感谢!

Shader "Hidden/Filter/Test" {
HLSLINCLUDE
#include "../../PostProcessing/Shaders/StdLib.hlsl"
TEXTURE2D_SAMPLER2D(_MainTex, sampler_MainTex);
float4 Frag(VaryingsDefault i) : SV_Target {
float4 color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.texcoordStereo);

// what's the world position of this color pixel ...?

return color;
}
ENDHLSL
SubShader {
Cull Off ZWrite Off ZTest Always
Pass {
HLSLPROGRAM
#pragma vertex VertDefault
#pragma fragment Frag
ENDHLSL
}
}
}

最佳答案

Lece 在您的评论中说得对:

You're missing an #include "UnityCG.cginc" which is require for most in-built features including access to UNITY_* macros.


但问题是当您使用 "UnityCG.cginc" 时PostProcessing stack 2 confilict with the same functions in Unity built-in shader.so 我决定在标准着色器 unity 中找到它:
Unity Archive shader您可以找到 UNITY_MATRIX_MVPStandard\CGIncludes\UnityShaderVariables.cginc
#define UNITY_MATRIX_MVP mul(unity_MatrixVP, unity_ObjectToWorld)

使用世界空间
Shader "Hidden/Filter/Test" {
HLSLINCLUDE
#include "../../PostProcessing/Shaders/StdLib.hlsl"
#define UNITY_MATRIX_MVP mul(unity_MatrixVP, unity_ObjectToWorld)

TEXTURE2D_SAMPLER2D(_MainTex, sampler_MainTex);

struct v2f {
float4 vertex : SV_POSITION;
float3 worldPos : TEXCOORD0;
float2 texcoord : TEXCOORD1;
float2 texcoordStereo : TEXCOORD2;
};

struct appdata {
float4 vertex : POSITION;
};

v2f VertDefault(appdata v) {
v2f o;

o.worldPos = mul (unity_ObjectToWorld, v.vertex);
o.vertex = float4(v.vertex.xy, 0.0, 1.0);
o.texcoord = TransformTriangleVertexToUV(v.vertex.xy);

#if UNITY_UV_STARTS_AT_TOP
o.texcoord = o.texcoord * float2(1.0, -1.0) + float2(0.0, 1.0);
#endif

o.texcoordStereo = TransformStereoScreenSpaceTex(o.texcoord, 1.0);
return o;
}

float4 Frag(v2f i) : SV_Target {
float worldPos = i.worldPos;

float4 color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.texcoordStereo);

return float4(i.worldPos,1);
}


ENDHLSL
SubShader {
Cull Off ZWrite Off ZTest Always
Pass {
HLSLPROGRAM
#pragma vertex VertDefault
#pragma fragment Frag


ENDHLSL
}
}
}

将世界位置添加到 StdLib.hlsl
您也可以将 worldpos 添加到 StdLib.hlsl ,您可以在 PostProcessing-2\Assets\PostProcessing\Shaders 中找到它然后更改这些行:
我修了 StdLib.hlsl我把 here
#define UNITY_MATRIX_MVP mul(unity_MatrixVP, unity_ObjectToWorld)

struct VaryingsDefault
{
float4 vertex : SV_POSITION;
float2 texcoord : TEXCOORD0;
float2 texcoordStereo : TEXCOORD1;
float3 worldPos : TEXCOORD2;
};

VaryingsDefault VertDefault(AttributesDefault v)
{
VaryingsDefault o;
o.vertex = float4(v.vertex.xy, 0.0, 1.0);
o.texcoord = TransformTriangleVertexToUV(v.vertex.xy);
o.worldPos = mul (unity_ObjectToWorld, v.vertex);

#if UNITY_UV_STARTS_AT_TOP
o.texcoord = o.texcoord * float2(1.0, -1.0) + float2(0.0, 1.0);
#endif

o.texcoordStereo = TransformStereoScreenSpaceTex(o.texcoord, 1.0);

return o;
}
以这种方式使用世界空间很容易!
Shader "Hidden/Filter/Test" {
HLSLINCLUDE
#include "../../PostProcessing/Shaders/StdLib.hlsl"

float4 Frag(VaryingsDefault i) : SV_Target {
return float4(i.worldPos,1);//Using World Position!
}


ENDHLSL
SubShader {
Cull Off ZWrite Off ZTest Always
Pass {
HLSLPROGRAM
#pragma vertex VertDefault
#pragma fragment Frag


ENDHLSL
}
}
}

更新
Image
https://www.youtube.com/watch?v=uMOOcmp6FrM
将此脚本附加到您的相机:
    using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DepthBuffToWorldPosDemo : MonoBehaviour
{
public Material material;
private new Camera camera;
private new Transform transform;

private void Start()
{
camera = GetComponent<Camera>();
transform = GetComponent<Transform>();
}

void OnRenderImage(RenderTexture source, RenderTexture destination)
{

// NOTE: code was ported from: https://gamedev.stackexchange.com/questions/131978/shader-reconstructing-position-from-depth-in-vr-through-projection-matrix

var p = GL.GetGPUProjectionMatrix(camera.projectionMatrix, false);
p[2, 3] = p[3, 2] = 0.0f;
p[3, 3] = 1.0f;
var clipToWorld = Matrix4x4.Inverse(p * camera.worldToCameraMatrix) * Matrix4x4.TRS(new Vector3(0, 0, -p[2,2]), Quaternion.identity, Vector3.one);
material.SetMatrix("clipToWorld", clipToWorld);

Graphics.Blit(source, destination, material);

}

}
您可以使用 Unity 着色器或后处理着色器
统一着色器:
Shader "Hidden/DepthBuffToWorldPos"
{

SubShader
{
Cull Off ZWrite Off ZTest Always

Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 5.0

#include "UnityCG.cginc"

struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};

struct v2f
{
float2 uv : TEXCOORD0;
float3 worldDirection : TEXCOORD1;
float4 vertex : SV_POSITION;
};

float4x4 clipToWorld;

v2f vert (appdata v)
{
v2f o;

o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;

float4 clip = float4(o.vertex.xy, 0.0, 1.0);
o.worldDirection = mul(clipToWorld, clip) - _WorldSpaceCameraPos;

return o;
}

sampler2D_float _CameraDepthTexture;
float4 _CameraDepthTexture_ST;

float4 frag (v2f i) : SV_Target
{
float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv.xy);
depth = LinearEyeDepth(depth);
float3 worldspace = i.worldDirection * depth + _WorldSpaceCameraPos;

float4 color = float4(worldspace, 1.0);
return color;
}
ENDCG
}
}
}
后处理堆栈着色器
Shader "Hidden/Filter/Test" {
HLSLINCLUDE
#include "../../PostProcessing/Shaders/StdLib.hlsl"
#define UNITY_MATRIX_MVP mul(unity_MatrixVP, unity_ObjectToWorld)
#include "HLSLSupport.cginc"
#pragma fragmentoption ARB_precision_hint_nicest

TEXTURE2D_SAMPLER2D(_MainTex, sampler_MainTex);
float4x4 clipToWorld;



struct v2f {
float4 vertex : SV_POSITION;
float3 worldDirection : TEXCOORD0;
float3 screenPos : TEXCOORD1;
float2 texcoord : TEXCOORD2;
float2 texcoordStereo : TEXCOORD3;

};

struct appdata {
float4 vertex : POSITION;
};

sampler2D_float _CameraDepthTexture;
float4 _CameraDepthTexture_ST;

v2f VertDefault(appdata v) {
v2f o;

o.vertex = float4(v.vertex.xy, 0.0, 1.0);
o.texcoord = TransformTriangleVertexToUV(v.vertex.xy);

float4 clip = float4(o.vertex.xy, 0.0, 1.0);
o.worldDirection = mul(clipToWorld, clip) - _WorldSpaceCameraPos;

#if UNITY_UV_STARTS_AT_TOP
o.texcoord = o.texcoord * float2(1.0, -1.0) + float2(0.0, 1.0);
#endif

// Correct flip when rendering with a flipped projection matrix.
// (I've observed this differing between the Unity scene & game views)
o.screenPos.y *= _ProjectionParams.x;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.screenPos = o.vertex.xyw;

o.texcoordStereo = TransformStereoScreenSpaceTex(o.texcoord, 1.0);
return o;
}

float4 Frag(v2f i) : SV_Target {
float2 screenUV = (i.screenPos.xy / i.screenPos.z) * 0.5f + 0.5f;
float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,screenUV);
depth = LinearEyeDepth(depth);
float3 worldspace = i.worldDirection * depth + _WorldSpaceCameraPos;

float4 color = float4(worldspace, 1.0);
return color;
}


ENDHLSL
SubShader {
Cull Off ZWrite Off ZTest Always
Pass {
HLSLPROGRAM
#pragma vertex VertDefault
#pragma fragment Frag


ENDHLSL
}
}
}

将世界位置添加到 StdLib.hlsl
StdLibFixed.hlsl
#define UNITY_MATRIX_MVP mul(unity_MatrixVP, unity_ObjectToWorld)
#include "HLSLSupport.cginc"
#pragma fragmentoption ARB_precision_hint_nicest

float4x4 clipToWorld;


struct VaryingsDefault
{
float4 vertex : SV_POSITION;
float3 worldDirection : TEXCOORD0;
float3 screenPos : TEXCOORD1;
float2 texcoord : TEXCOORD2;
float2 texcoordStereo : TEXCOORD3;
};



sampler2D_float _CameraDepthTexture;
float4 _CameraDepthTexture_ST;



VaryingsDefault VertDefault(AttributesDefault v)
{
VaryingsDefault o;

o.vertex = float4(v.vertex.xy, 0.0, 1.0);
o.texcoord = TransformTriangleVertexToUV(v.vertex.xy);

float4 clip = float4(o.vertex.xy, 0.0, 1.0);
o.worldDirection = mul(clipToWorld, clip) - _WorldSpaceCameraPos;

#if UNITY_UV_STARTS_AT_TOP
o.texcoord = o.texcoord * float2(1.0, -1.0) + float2(0.0, 1.0);
#endif

// Correct flip when rendering with a flipped projection matrix.
// (I've observed this differing between the Unity scene & game views)
o.screenPos.y *= _ProjectionParams.x;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.screenPos = o.vertex.xyw;


o.texcoordStereo = TransformStereoScreenSpaceTex(o.texcoord, 1.0);
return o;
}
以这种方式使用世界空间很容易!
Shader "Hidden/Filter/Test" {
HLSLINCLUDE
#include "../StdLib.hlsl"


float4 Frag(v2f i) : SV_Target {
float2 screenUV = (i.screenPos.xy / i.screenPos.z) * 0.5f + 0.5f;
float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,screenUV);
depth = LinearEyeDepth(depth);
float3 worldspace = i.worldDirection * depth + _WorldSpaceCameraPos;

float4 color = float4(worldspace, 1.0);
return color;
}


ENDHLSL
SubShader {
Cull Off ZWrite Off ZTest Always
Pass {
HLSLPROGRAM
#pragma vertex VertDefault
#pragma fragment Frag


ENDHLSL
}
}
}

关于unity3d - 在 Unity 的新后处理堆栈的着色器中获取世界位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49453696/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com