Question by
Reahreic · Aug 14, 2017 at 12:41 PM ·
shadervrrendertextureoutlinerender texture
PostProcess Outline Shader GVR alignment
Cross post from my Friday forum post as to date there's been 30+ views but no responses yet and time is running out for me. (Thank you for your consideration)
(https://forum.unity3d.com/threads/postprocess-outline-shader-gvr-alignment.487815/)
I've been working on implementing a post processing outline shader that i can use on the Google Daydream (GVR) Platform (among others) and have run into a problem that i can't seem to resolve.
My outlined objects display correctly in the editor, however once deployed to a daydream compatible phone, the outline is rendered offset along the z axis about halfway between the camera and target object.
Project Settings:
Multi Pass Stereo Rendering
Forward Rendering
Shader
Shader "Hidden/Test"
{
Properties
{
_MainTex ("Main Texture",2D) = "black"{}
_SceneTex("Scene Texture",2D) = "black"{}
}
SubShader
{
// No culling or depth
//Cull Off ZWrite Off ZTest Always
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex ;
sampler2D _SceneTex;
float2 _MainTex_TexelSize;
struct v2f{
float4 pos : POSITION;
float2 uv : TEXCOORD0;
};
v2f vert (appdata_base v){
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = o.pos.xy / 2 + 0.5;
return o;
}
half4 frag (v2f i) : COLOR{
if(tex2D(_MainTex , i.uv.xy).r > 0){
return tex2D(_SceneTex , i.uv.xy);
}
float colorInt = 0;
int thickness = 8;
for(int k = 0; k < thickness; k++){
for(int j = 0; j < thickness; j++){
colorInt += tex2D( _MainTex , i.uv.xy + float2(( k - thickness / 2) * _MainTex_TexelSize.x, (j - thickness / 2) * _MainTex_TexelSize.y)).r;
}
}
return colorInt * half4(0,1,1,1) + tex2D(_SceneTex , i.uv.xy);
}
ENDCG
}
}
}
OutlinePostEffect
using UnityEngine;
using System.Collections.Generic;
using UnityEngine.Rendering;
using UnityEngine.VR;
public class OutlinePostEffect :MonoBehaviour {
public AppManager appManager;
public Camera bufferCamera;
[Space(20)]
public Shader outlineShader;
public Shader outlineBufferShader;
public LayerMask layerMask;
private Material outlineMaterial;
private RenderTexture renderTexture;
private bool isReady = false;
void Start() {
//Configure bufferCam rendering path on outline camera
bufferCamera.cullingMask = layerMask.value;
bufferCamera.renderingPath = RenderingPath.Forward;
MakeRT();
outlineMaterial = new Material(outlineShader);
isReady = true;
}
private void MakeRT() {
if(VRSettings.eyeTextureWidth <= 0) {
renderTexture = new RenderTexture(Screen.width, Screen.height, 0, RenderTextureFormat.R8);
} else {
renderTexture = new RenderTexture(VRSettings.eyeTextureWidth, VRSettings.eyeTextureHeight, 0, RenderTextureFormat.R8);
}
renderTexture.antiAliasing = 2;
renderTexture.anisoLevel = 0;
renderTexture.depth = 0;
renderTexture.useMipMap = false;
renderTexture.filterMode = FilterMode.Bilinear;
//put it to video memory
renderTexture.Create();
}
void OnRenderImage(RenderTexture source, RenderTexture destination) {
if(!isReady) { return; }
//set the camera's target texture when rendering
bufferCamera.targetTexture = renderTexture;
outlineMaterial.SetTexture("_SceneTex", source);
//render all objects this camera can render, but with our custom shader.
bufferCamera.RenderWithShader(outlineBufferShader, "");
//copy the RT to the final image
Graphics.Blit(renderTexture, destination, outlineMaterial);
//release the temporary RT
//renderTexture.Release();
}
}
Comment