Skip to content

Instantly share code, notes, and snippets.

View slembcke's full-sized avatar
👣
Gruntled

Scott Lembcke slembcke

👣
Gruntled
View GitHub Profile
@slembcke
slembcke / CullOBB.c
Last active December 9, 2020 14:43
/*
* Used for culling tiles in a map renderer I wrote.
* All tiles used geometry in the [-1, 1] range, and their mvp matrix would get precalculated.
* So it was simply a matter of seeing if their projected OBB overlapped with the screen's clip space.
* Returns true if the cube is visible. (false positives for near misses due to conservative w-value)
*/
static inline bool MapTileFrustumCull(const mat4 mvp){
// Clip space center of the cube is the last column of the matrix.
vec4 c = {mvp.m[12], mvp.m[13], mvp.m[14], mvp.m[15]};
// Clip space extents are the component wise absolute values of the first three columns.
@slembcke
slembcke / FourierLights.hlsl
Created January 21, 2020 22:54
Fourier lighting code
struct FragOutput {
half4 a0 : SV_TARGET0;
half4 a1 : SV_TARGET1;
half4 b1 : SV_TARGET2;
half4 a2 : SV_TARGET3;
half4 b2 : SV_TARGET4;
};
// Double angle formula derived from the trig identity.
float2 DoubleAngle(float2 n){
@slembcke
slembcke / mulx.c
Last active October 30, 2019 04:28
Signed 16.16 fixed point multiply.
static inline fixed mulx_fast(fixed x, fixed y){return (fixed){(x.asint >> 8) * (y.asint >> 8)};}
static inline fixed mulx(fixed x, fixed y){
bool neg = (x.asint ^ y.asint) < 0;
union {
u32 asint;
struct {u16 hi, lo;};
} _x, _y;
if(x.asint >= 0) _x.asint = x.asint; else _x.asint = -x.asint;
00000204 <start>:
204: 1039 00a1 0001 moveb a10001 <VDP_REG_DMA_SRC2+0xa06901>,%d0
20a: 0200 000f andib #15,%d0
20e: 6700 000c beqw 21c <start+0x18>
212: 23fc 04fd 1e0d movel #83697165,a14000 <VDP_REG_DMA_SRC2+0xa0a900>
218: 00a1 4000
21c: 4a79 00c0 0004 tstw c00004 <VDP_CTRL>
222: 41f9 00c0 0004 lea c00004 <VDP_CTRL>,%a0
228: 30bc 8004 movew #-32764,%a0@
22c: 30bc 8144 movew #-32444,%a0@
@slembcke
slembcke / screenspace.shader
Last active September 3, 2019 15:29
Screenspace coordinates
CGPROGRAM
// Pass a clean copy of the VP matrix.
// Shader.SetGlobalMatrix("_MyMatrixVP", Camera.current.projectionMatrix*Camera.current.worldToCameraMatrix);
// Unity applies poorly documented magic to UNITY_MATRIX_VP that you don't want.
float4x4 _MyMatrixVP;
struct VertexOutput {
// Pass the screen space coordinate as a new varying.
// Don't re-use SV_POSITION in your frag shader, it only works on non-DirectX platforms IIRC.
float4 screenSpace : TEXCOORD1;
@slembcke
slembcke / ProjectedBounds.cs
Last active April 29, 2019 18:16
Calculate a bounded mvp matrix for an object.
using UnityEngine;
[ExecuteInEditMode]
public class ProjectedBounds : MonoBehaviour {
private Transform _transform;
private Renderer _renderer;
private Mesh _mesh;
private MaterialPropertyBlock _block;
private void Start(){
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
static const size_t COUNT = 64*(1<<20);
typedef float FLOAT_T;
@slembcke
slembcke / anisotropy.hlsl
Created January 30, 2019 03:43
Anisotropic reflections
// 'coord.y' is the clip space y-coordinate of the pixel on the water.
// 'ray0.y/ray0.w' is the clip space y-coordinate of the reflected pixel.
// The basic idea is near the horizion where the reflected point is close to the water,
// you should have a strong reflection. The further it gets from the horizon the more it should be blurred vertically.
// The result is pretty good. :D
float aniso = _SSRAniso*abs(coord.y - ray0.y/ray0.w);
float2 ddy_uv = max(ddy(uv), float2(0, aniso));
...
float4 color = tex2Dgrad(_CameraColorTexture, uv, ddx(uv), ddy_uv);
@slembcke
slembcke / decompress_lz4.s
Created October 28, 2018 07:10
GBZ80 Lz4 decompression function progress.
section "lz4-data", hram
token: db ; Most recently read token.
backref: dw
; NOTES:
; dst/src is always stored in de/hl
section "lz4-code", rom0
@slembcke
slembcke / FlickerExample.txt
Created August 24, 2018 21:53
Code snippets for my flicker issue.
static void px_ppu_sync_off(){
px_mask &= ~PX_MASK_RENDER_ENABLE;
px_wait_nmi();
// Without these I get a few garbage lines at the top of the screen
waitvsync();
waitvsync();
}
static void px_ppu_sync_on(){