Clay Engine: Support vertex normals (smooth shading), no face normals yet.

This commit is contained in:
Clément Foucault 2017-02-15 13:32:35 +01:00
parent b0c125bcd3
commit 310593def1
5 changed files with 61 additions and 14 deletions

View File

@ -36,6 +36,7 @@ void BKE_mesh_batch_cache_dirty(struct Mesh *me);
void BKE_mesh_batch_cache_free(struct Mesh *me);
struct Batch *BKE_mesh_batch_cache_get_all_edges(struct Mesh *me);
struct Batch *BKE_mesh_batch_cache_get_all_triangles(struct Mesh *me);
struct Batch *BKE_mesh_batch_cache_get_triangles_with_normals(struct Mesh *me);
struct Batch *BKE_mesh_batch_cache_get_all_verts(struct Mesh *me);
struct Batch *BKE_mesh_batch_cache_get_fancy_edges(struct Mesh *me);
struct Batch *BKE_mesh_batch_cache_get_overlay_edges(struct Mesh *me);

View File

@ -231,6 +231,7 @@ typedef struct MeshBatchCache {
Batch *all_edges;
Batch *all_triangles;
Batch *triangles_with_normals; /* owns its vertex buffer */
Batch *fancy_edges; /* owns its vertex buffer (not shared) */
Batch *overlay_edges; /* owns its vertex buffer */
@ -401,6 +402,10 @@ void BKE_mesh_batch_cache_free(Mesh *me)
if (cache->edges_in_order) ElementList_discard(cache->edges_in_order);
if (cache->triangles_in_order) ElementList_discard(cache->triangles_in_order);
if (cache->triangles_with_normals) {
Batch_discard_all(cache->triangles_with_normals);
}
if (cache->fancy_edges) {
Batch_discard_all(cache->fancy_edges);
}
@ -437,6 +442,57 @@ Batch *BKE_mesh_batch_cache_get_all_triangles(Mesh *me)
return cache->all_triangles;
}
Batch *BKE_mesh_batch_cache_get_triangles_with_normals(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
if (cache->triangles_with_normals == NULL) {
static VertexFormat format = { 0 };
static unsigned pos_id, nor_id;
unsigned int vidx = 0;
if (format.attrib_ct == 0) {
/* initialize vertex format */
pos_id = add_attrib(&format, "pos", GL_FLOAT, 3, KEEP_FLOAT);
nor_id = add_attrib(&format, "nor", GL_SHORT, 3, NORMALIZE_INT_TO_FLOAT);
}
const MVert *verts = mesh_render_get_array_vert(me);
const int tessface_ct = mesh_render_get_num_faces(me);
MFace *tessfaces = mesh_render_get_array_face(me);
VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
VertexBuffer_allocate_data(vbo, tessface_ct * 2 * 3); /* up to 2 triangles per tessface */
for (int i = 0; i < tessface_ct; ++i) {
const MFace *tess = tessfaces + i;
/* TODO get real face normals */
setAttrib(vbo, nor_id, vidx, &verts[tess->v1].no);
setAttrib(vbo, pos_id, vidx++, &verts[tess->v1].co);
setAttrib(vbo, nor_id, vidx, &verts[tess->v2].no);
setAttrib(vbo, pos_id, vidx++, &verts[tess->v2].co);
setAttrib(vbo, nor_id, vidx, &verts[tess->v3].no);
setAttrib(vbo, pos_id, vidx++, &verts[tess->v3].co);
if (tess->v4) {
setAttrib(vbo, nor_id, vidx, &verts[tess->v1].no);
setAttrib(vbo, pos_id, vidx++, &verts[tess->v1].co);
setAttrib(vbo, nor_id, vidx, &verts[tess->v3].no);
setAttrib(vbo, pos_id, vidx++, &verts[tess->v3].co);
setAttrib(vbo, nor_id, vidx, &verts[tess->v4].no);
setAttrib(vbo, pos_id, vidx++, &verts[tess->v4].co);
}
}
VertexBuffer_resize_data(vbo, vidx+1);
cache->triangles_with_normals = Batch_create(GL_TRIANGLES, vbo, NULL);
}
return cache->triangles_with_normals;
}
Batch *BKE_mesh_batch_cache_get_all_verts(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);

View File

@ -609,7 +609,7 @@ static void CLAY_create_cache(CLAY_PassList *passes, CLAY_StorageList *stl, cons
/* Clay Pass */
{
passes->clay_pass = DRW_pass_create("Clay Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS);
passes->clay_pass = DRW_pass_create("Clay Pass", DRW_STATE_WRITE_COLOR);
stl->storage->ubo_current_id = 0;
}

View File

@ -62,13 +62,6 @@ vec3 get_view_space_from_depth(in vec2 uvcoords, in float depth)
}
}
/* TODO remove this when switching to geometric normals */
vec3 calculate_view_space_normal(in vec3 viewposition)
{
vec3 normal = cross(normalize(dFdx(viewposition)), dfdy_sign * normalize(dFdy(viewposition)));
return normalize(normal);
}
#ifdef USE_HSV
void rgb_to_hsv(vec3 rgb, out vec3 outcol)
{
@ -167,15 +160,12 @@ void main() {
vec2 screenco = vec2(gl_FragCoord.xy) / screenres;
float depth = texture(depthtex, screenco).r;
vec3 position = get_view_space_from_depth(screenco, depth);
vec3 normal = calculate_view_space_normal(position);
/* Manual Depth test */
/* Doing this test earlier gives problem with dfdx calculations
* TODO move this before when we have proper geometric normals */
if (gl_FragCoord.z > depth + 1e-5)
discard;
vec3 position = get_view_space_from_depth(screenco, depth);
#ifdef USE_ROTATION
/* Rotate texture coordinates */
vec2 rotY = vec2(-matcap_rotation.y, matcap_rotation.x);

View File

@ -668,7 +668,7 @@ Batch *DRW_cache_surface_get(Object *ob)
BLI_assert(ob->type == OB_MESH);
Mesh *me = ob->data;
surface = BKE_mesh_batch_cache_get_all_triangles(me);
surface = BKE_mesh_batch_cache_get_triangles_with_normals(me);
return surface;
}