Skip to content

Commit

Permalink
Render To Texture (Blit) - example for URP
Browse files Browse the repository at this point in the history
  • Loading branch information
przemyslawzaworski authored Dec 15, 2023
1 parent 26d1020 commit 3c8d3a1
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 0 deletions.
75 changes: 75 additions & 0 deletions URP/RenderToTextureURP.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RenderToTextureURP : MonoBehaviour
{
public Rendering RenderMode = Rendering.DirectX;
[Range(1.0f, 2.0f)] public float Contrast = 1.0f;
[Range(0.0f, 1.0f)] public float Radius = 1.0f;
[SerializeField] private GameObject _GameObject;
[SerializeField] private Shader _Shader;
[SerializeField] private Texture _Source;
private Material _Material;
private Mesh _Mesh;
private RenderTexture _Destination;

public enum Rendering {DirectX, OpenGL}

Mesh GenerateQuad()
{
Mesh mesh = new Mesh();
Vector3[] vertices = new Vector3[4]
{
new Vector3(-1f, -1f, 0f),
new Vector3( 1f, -1f, 0f),
new Vector3(-1f, 1f, 0f),
new Vector3( 1f, 1f, 0f),
};
mesh.vertices = vertices;
int[] triangles = new int[6] {0, 3, 1, 3, 0, 2};
mesh.triangles = triangles;
Vector2[] uv = new Vector2[4]
{
new Vector2(0f, 0f),
new Vector2(1f, 0f),
new Vector2(0f, 1f),
new Vector2(1f, 1f)
};
mesh.uv = uv;
return mesh;
}

void RenderToTexture (Texture source, RenderTexture destination, Mesh mesh, Material material, string name)
{
material.SetTexture(name, source);
RenderTexture renderTexture = RenderTexture.active;
RenderTexture.active = destination;
material.SetPass(0);
Graphics.DrawMeshNow(mesh, Vector3.zero, Quaternion.identity);
RenderTexture.active = renderTexture;
}

void Start()
{
_Material = new Material(_Shader);
_Mesh = GenerateQuad();
_Destination = new RenderTexture(_Source.width, _Source.height, 0, RenderTextureFormat.ARGB32);
_GameObject.GetComponent<MeshRenderer>().material.mainTexture = _Destination;
}

void Update()
{
Shader.SetGlobalFloat("_BokehContrast", Contrast);
Shader.SetGlobalFloat("_BokehRadius", Radius);
Shader.SetGlobalInt("_BokehRenderMode", RenderMode == Rendering.DirectX ? 0 : 1);
RenderToTexture (_Source, _Destination, _Mesh, _Material, "_Texture");
}

void OnDestroy()
{
Destroy(_Material);
Destroy(_Mesh);
_Destination.Release();
}
}
55 changes: 55 additions & 0 deletions URP/RenderToTextureURP.shader
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
Shader "RenderToTextureURP"
{
SubShader
{
Pass
{
ZTest Off
ZWrite Off
Cull Off
HLSLPROGRAM
#pragma vertex VSMain
#pragma fragment PSMain

Texture2D _Texture;
SamplerState sampler_linear_repeat;
float _BokehRadius, _BokehContrast;
int _BokehRenderMode;

// Bokeh Disc effect by Dave Hoskins
float3 Bokeh(Texture2D surface, SamplerState state, float2 uv, float radius, float contrast)
{
float3 accumulation = float3(0.0, 0.0, 0.0);
float3 divider = accumulation;
float spread = 1.0;
int samples = 128;
float2 angle = float2(0.0, radius * 0.01 / sqrt(float(samples)));
float2x2 rotation = float2x2(cos(2.3999632), sin(2.3999632), -sin(2.3999632), cos(2.3999632));
for (int j = 0; j < samples; j++)
{
spread += 1.0 / spread;
angle = mul(angle, rotation);
float3 color = surface.Sample(state, uv + (spread - 1.0) * angle).xyz;
color = (contrast > 1.0) ? color * color * contrast : color;
float3 bokeh = pow(color, float3(4.0, 4.0, 4.0));
accumulation += color * bokeh;
divider += bokeh;
}
return accumulation / divider;
}

float4 VSMain (float4 vertex : POSITION, inout float2 uv : TEXCOORD0) : SV_POSITION
{
uv.y = (_BokehRenderMode == 0) ? 1.0 - uv.y : uv.y;
return vertex;
}

float4 PSMain (float4 vertex : SV_POSITION, float2 uv : TEXCOORD0) : SV_Target
{
float3 color = Bokeh(_Texture, sampler_linear_repeat, uv, _BokehRadius, _BokehContrast);
return float4(color, 1.0);
}
ENDHLSL
}
}
}

0 comments on commit 3c8d3a1

Please sign in to comment.