Foliage Vertex Shader

I’ve started working on a unity scene that’s going to involve a bit of shader, modelling and vfx work.

Today I worked on the foliage vertex shader. Its a pretty simple shader, with a sine wave doing a little wobble and two colour inputs to create a gradated albedo.

552bd2ffa88be7336fefc0d9a1734540.gif

I picked up a couple of nice things on how to recalculate lighting and normal information fromĀ this tutorial by Hugo Scott-Slade.

Getting correct light info is actually very simple – you just need to add vertex:vert addshadow to your pragma. Initially I had it as vertex: vert and nothing worked, so worth noting that the lack of space is important!

#pragma surface surf Standard fullforwardshadows vertex:vert addshadow

To recalculate the normals, I started with a function that returns the new position that the vertex is going to be in.

I used this function with the vertex plus the tangent, then the vertex plus the bitangent, to approximate what the new tangent and bitanget will be.

Image result for normal tangent bitangent
Image from learnopengl.com showing the normal, tangent and bitangent.
0538d3ec517f37820a69932b7333edc6.gif
Tested the recalculated normal on this metallic sphere – note h ow the specular highlight moves.

The appdata_full struct provided me with the tangent, and I got the bitangent by crossing the tangent and the normal.

Once I had the new tangent and bitangents, I crossed them to get the new normal and set that as the vert’s normal.

//creates new verts to approximate new position for normal recalculation

float3 getNewVertPosition(float3 p, float vertexColor) {
p.x += (sin(_Time.y * _SpeedX + p.y) * _AmountX) * vertexColor;
p.y += (sin(_Time.y * _SpeedY + p.y) * _AmountY) * vertexColor;
p.z += (sin(_Time.y * _SpeedZ + p.y) * _AmountZ) * vertexColor;
return p;
}

void vert (inout appdata_full v) {

//Change Vert Normal

float3 bitangent = cross(v.normal, v.tangent);
float3 position = getNewVertPosition(v.vertex, v.color.r);
float3 positionTangent = getNewVertPosition(v.vertex + v.tangent * 0.01, v.color.r);
float3 positionBitangent = getNewVertPosition(v.vertex + bitangent * 0.01, v.color.r);

float3 newTangent = positionTangent – position;
float3 newBitangent = positionBitangent – position;

float3 newNormal = cross(newTangent, newBitangent);
v.normal = newNormal;

 

Sim’Py Framework

I’ve been playing a lot of simulation style games recently and its made me interested in the idea of making one again. This is something I’ve wanted to do for a while, but have generally got too caught up in the system without a good story, or vice versa.

To prevent that happening, I decided to write a framework so that when I did feel like writing I could jump right in, and I could satisfy the coding interest until I got to that point. This framework is written in python and extends the functionality of Ren’Py, a visual novel engine.

1

Stat and Relationship Systems

The sort of game I’m interested in making is one like Long Live The Queen or Magical Diary, where you build stats that factor into events within the game.

591133785bafe3158054d8fe

I built a stat class that handles the display name of the stat, its current value and has functions for incrementing and decrimenting the stat. I then made a stat manager, which takes stat objects and does things like compares them with one another or against a value.

2

I then built a relationship class, which is similar to the stat, but has additional variables such as “is_romantic”. This allows for the player to have a relationship value with this character, but also to track weather the relationship is platonic or romantic, eventually locking this choice based on the points gained in each throughout the game. For example, the player could have completed every scene with one character, maxing out their relationship points, but weather they chose to be flirty or not during dialog options will change the value of is_romantic, changing the scenes the player sees.

This is similar to Persona, where you can have a max social link that is platonic or romantic.

maxresdefault

Date/Time System

To create stat building and the daily event style gameplay, I made a date/time system. I have a class that tracks the current day, time and calendar, as well as ren’py labels that check the time and date and jump to the correct events. To check which events should be played, I have a dictionary that is populated during run time. Instead of checking every day if certain vars are true and then playing the event if so (a common way to track events in ren’py), I add the event to the dictionary when the inciting event occurs, with the day as the key and the time and label to jump to in a list as the value. When the system recognizes a day that is in the dictionary, it then checks the time until it sees the correct time, and displays the event.

43

Proper Nouns

The other thing I added was a file called “Proper Nouns”. In here I’m storing all character, place and object names as variables, with the codename as the variable name. This just makes things easier to develop and edit. I don’t need to worry about getting anything correct first time and don’t have to edit the code of the game to change the writing.

Having these in place makes writing a game like this much more manageable, and sets up base systems that are not likely to change. Ren’py is a fun engine to use, but without a bit of extra python love, debugging and editing can get really tough. Hopefully this has alleviated some of those issues!