How Can I Use a Viewport Texture in a Visual Shader?

Godot Version

4.2

Question

How do you use a Viewport Texture in a Visual Shader? No amount of making any resource local seems to help and the only solution anyone had online referenced a visual shader node that no longer exists.

Is it even possible to use a viewport texture in a visual shader???

I did a quick test and it works fine. I had to set the material Local to Scene to true.

Here’s a self-container tscn using the icon.svg

test.tscn
[gd_scene load_steps=8 format=3 uid="uid://bkyai5vw3e5ek"]

[ext_resource type="Texture2D" uid="uid://caxnlrbgg5dij" path="res://icon.svg" id="1_qin7n"]

[sub_resource type="VisualShaderNodeTexture2DParameter" id="VisualShaderNodeTexture2DParameter_ak4jk"]
parameter_name = "tex"
texture_type = 1

[sub_resource type="VisualShaderNodeTexture" id="VisualShaderNodeTexture_pldqs"]
expanded_output_ports = [0]
source = 5

[sub_resource type="VisualShaderNodeInput" id="VisualShaderNodeInput_op10t"]
input_name = "uv"

[sub_resource type="VisualShader" id="VisualShader_j6skl"]
code = "shader_type canvas_item;
render_mode blend_mix;

uniform sampler2D tex : source_color;



void fragment() {
// Input:4
	vec2 n_out4p0 = UV;


	vec4 n_out3p0;
// Texture2D:3
	n_out3p0 = texture(tex, n_out4p0);
	float n_out3p4 = n_out3p0.a;


// Output:0
	COLOR.rgb = vec3(n_out3p0.xyz);
	COLOR.a = n_out3p4;


}
"
mode = 1
flags/light_only = false
nodes/fragment/0/position = Vector2(1160, 160)
nodes/fragment/2/node = SubResource("VisualShaderNodeTexture2DParameter_ak4jk")
nodes/fragment/2/position = Vector2(80, 280)
nodes/fragment/3/node = SubResource("VisualShaderNodeTexture_pldqs")
nodes/fragment/3/position = Vector2(620, 160)
nodes/fragment/4/node = SubResource("VisualShaderNodeInput_op10t")
nodes/fragment/4/position = Vector2(60, 80)
nodes/fragment/connections = PackedInt32Array(2, 0, 3, 2, 3, 4, 0, 1, 3, 0, 0, 0, 4, 0, 3, 0)

[sub_resource type="ViewportTexture" id="ViewportTexture_43gp4"]
viewport_path = NodePath("SubViewport")

[sub_resource type="ShaderMaterial" id="ShaderMaterial_soip4"]
resource_local_to_scene = true
shader = SubResource("VisualShader_j6skl")
shader_parameter/tex = SubResource("ViewportTexture_43gp4")

[node name="TestViewportTextureVisualShader" type="Node"]

[node name="ColorRect" type="ColorRect" parent="."]
material = SubResource("ShaderMaterial_soip4")
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2

[node name="SubViewport" type="SubViewport" parent="."]

[node name="Sprite2D" type="Sprite2D" parent="SubViewport"]
texture = ExtResource("1_qin7n")

[node name="Sprite2D2" type="Sprite2D" parent="SubViewport"]
position = Vector2(385, 215)
texture = ExtResource("1_qin7n")

Thanks for the replay! I eventually figured out my problem was I didn’t realize the camera had to be a child of the view port in order to render the view port texture in the first place. That took me an embarrassingly long time to actually figure out even while staring at yours wondering why yours worked but mine didn’t sad trombone sound. Brain lock is a hell of a thing to deal with, oof.

Thank you for the help!

So, for those few poor souls as prone to brain-lock as I, yes it’s possible to use a viewport texture in a visual shader. Just make sure the camera rendering the viewport texture is a child of the sub-viewport. That probably goes for all viewport renderings I guess.