Skip to content

Commit 0809039

Browse files
Bake normals to texture - Conservative Rasterization with Geometry Shaders
1 parent 0460142 commit 0809039

File tree

2 files changed

+158
-0
lines changed

2 files changed

+158
-0
lines changed

BakeTexture.cs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
Resolution = Dilation
3+
256 = 2px
4+
512 = 4px
5+
1024 = 8px
6+
2048 = 16px
7+
4096 = 32 px
8+
8192 = 64 px
9+
*/
10+
using UnityEngine;
11+
12+
public class BakeTexture : MonoBehaviour
13+
{
14+
public Mesh SourceMesh;
15+
public Shader BakeTextureShader;
16+
public int Resolution = 2048;
17+
public float Dilation = 16;
18+
public Rendering RenderMode = Rendering.DirectX;
19+
20+
public enum Rendering
21+
{
22+
DirectX,
23+
OpenGL
24+
}
25+
26+
void Start()
27+
{
28+
if (SourceMesh != null)
29+
{
30+
RenderTexture renderTexture = new RenderTexture(Resolution, Resolution, 32, RenderTextureFormat.ARGB32);
31+
renderTexture.filterMode = FilterMode.Trilinear;
32+
renderTexture.Create();
33+
Material material = new Material(BakeTextureShader);
34+
RenderTexture currentTexture = RenderTexture.active;
35+
RenderTexture.active = renderTexture;
36+
GL.Clear(true, true, Color.black, 1.0f);
37+
material.SetInt("_TextureSize", Resolution);
38+
material.SetFloat("_Dilation", Dilation);
39+
material.SetInt("_RenderMode", RenderMode == Rendering.DirectX ? 0 : 1);
40+
material.SetPass(0);
41+
Graphics.DrawMeshNow(SourceMesh, Vector3.zero, Quaternion.identity);
42+
Texture2D texture = new Texture2D(Resolution, Resolution, TextureFormat.ARGB32, false, false);
43+
texture.ReadPixels( new Rect(0, 0, Resolution, Resolution), 0, 0);
44+
RenderTexture.active = currentTexture;
45+
byte[] bytes = texture.EncodeToPNG();
46+
System.IO.File.WriteAllBytes(System.IO.Path.Combine(Application.dataPath, "Texture.png"), bytes);
47+
Destroy(material);
48+
Destroy(texture);
49+
renderTexture.Release();
50+
}
51+
}
52+
}

BakeTexture.shader

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
// Conservative Rasterization with Geometry Shaders: https://action-io.com/rd/conservative-rasterization/
2+
// Translated from GLSL to HLSL by Przemyslaw Zaworski
3+
4+
Shader "Bake Texture"
5+
{
6+
SubShader
7+
{
8+
Pass
9+
{
10+
ZWrite On
11+
Cull Off
12+
HLSLPROGRAM
13+
#pragma vertex VSMain
14+
#pragma geometry GSMain
15+
#pragma fragment PSMain
16+
17+
float _Dilation;
18+
int _TextureSize;
19+
int _RenderMode;
20+
21+
struct Interpolators
22+
{
23+
float4 vertex : SV_Position;
24+
float2 uv : TEXCOORD0;
25+
float4 color : NORMAL;
26+
};
27+
28+
Interpolators VSMain(float4 vertex:POSITION, float2 uv:TEXCOORD0, float4 color : NORMAL)
29+
{
30+
Interpolators IN;
31+
float2 texcoord = uv.xy;
32+
texcoord.y = (_RenderMode == 0) ? 1.0 - texcoord.y : texcoord.y;
33+
texcoord = texcoord * 2.0 - 1.0;
34+
IN.uv = uv;
35+
IN.vertex = float4(texcoord, 0.0, 1.0);
36+
IN.color = color;
37+
return IN;
38+
}
39+
40+
void Emit(float4 position, float2 uv, float4 color, inout TriangleStream<Interpolators> stream, float depth)
41+
{
42+
Interpolators IN;
43+
depth = (_RenderMode == 0) ? depth : -1.0 * depth;
44+
IN.vertex = float4(position.xy, depth, position.w);
45+
IN.uv = uv;
46+
IN.color = color;
47+
stream.Append(IN);
48+
}
49+
50+
[maxvertexcount(21)]
51+
void GSMain(triangle Interpolators input[3], inout TriangleStream<Interpolators> stream)
52+
{
53+
float pixel = (1.0 / (float)_TextureSize) * _Dilation;
54+
float4 vertices[3];
55+
for (int i = 0; i < 3; i++)
56+
{
57+
int i0 = i, i1 = (i + 1) % 3u, i2 = (i + 2) % 3u;
58+
float4 lp0 = input[i0].vertex;
59+
float4 lp1 = input[i1].vertex;
60+
float4 lp2 = input[i2].vertex;
61+
float2 v0 = normalize(lp0.xy - lp1.xy);
62+
float2 v1 = normalize(lp2.xy - lp1.xy);
63+
float2 mixed = -normalize((v0 + v1)/ 2.0);
64+
float angle = atan2(v0.y, v0.x) - atan2(mixed.y, mixed.x);
65+
float vlength = abs(pixel / sin(angle));
66+
float2 offs = mixed * float2(vlength, vlength);
67+
vertices[i1] = float4(lp1.xy + offs, 0, 1);
68+
}
69+
Emit(input[0].vertex, input[0].uv, input[0].color, stream, 0.0007);
70+
Emit(input[1].vertex, input[1].uv, input[1].color, stream, 0.0007);
71+
Emit(input[2].vertex, input[2].uv, input[2].color, stream, 0.0007);
72+
stream.RestartStrip();
73+
Emit(input[1].vertex, input[1].uv, input[1].color, stream, 0.0006);
74+
Emit(vertices[2], input[2].uv, input[2].color, stream, 0.0006);
75+
Emit(input[2].vertex, input[2].uv, input[2].color, stream, 0.0006);
76+
stream.RestartStrip();
77+
Emit(input[2].vertex, input[2].uv, input[2].color, stream, 0.0005);
78+
Emit(vertices[2], input[2].uv, input[2].color, stream, 0.0005);
79+
Emit(input[0].vertex, input[0].uv, input[0].color, stream, 0.0005);
80+
stream.RestartStrip();
81+
Emit(input[0].vertex, input[0].uv, input[0].color, stream, 0.0004);
82+
Emit(vertices[2], input[2].uv, input[2].color, stream, 0.0004);
83+
Emit(vertices[0], input[0].uv, input[0].color, stream, 0.0004);
84+
stream.RestartStrip();
85+
Emit(input[0].vertex, input[0].uv, input[0].color, stream, 0.0003);
86+
Emit(vertices[0], input[0].uv, input[0].color, stream, 0.0003);
87+
Emit(input[1].vertex, input[1].uv, input[1].color, stream, 0.0003);
88+
stream.RestartStrip();
89+
Emit(input[1].vertex, input[1].uv, input[1].color, stream, 0.0002);
90+
Emit(vertices[0], input[0].uv, input[0].color, stream, 0.0002);
91+
Emit(vertices[1], input[1].uv, input[1].color, stream, 0.0002);
92+
stream.RestartStrip();
93+
Emit(input[1].vertex, input[1].uv, input[1].color, stream, 0.0001);
94+
Emit(vertices[1], input[1].uv, input[1].color, stream, 0.0001);
95+
Emit(vertices[2], input[2].uv, input[2].color, stream, 0.0001);
96+
stream.RestartStrip();
97+
}
98+
99+
float4 PSMain (Interpolators IN) : SV_TARGET
100+
{
101+
return float4(IN.color.rgb, 1.0);
102+
}
103+
ENDHLSL
104+
}
105+
}
106+
}

0 commit comments

Comments
 (0)